#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import requests
import re
import time
from multiprocessing.dummy import Pool as ThreadPool
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
import urllib3

urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

# =============================
# BUILD STRONG SESSION (urllib3)
# =============================
def build_session():
    session = requests.Session()

    retry = Retry(
        total=5,
        connect=5,
        read=5,
        backoff_factor=0.5,
        status_forcelist=[429, 500, 502, 503, 504],
        allowed_methods=["GET"]
    )

    adapter = HTTPAdapter(
        max_retries=retry,
        pool_connections=100,
        pool_maxsize=100
    )

    session.mount("http://", adapter)
    session.mount("https://", adapter)

    return session

SESSION = build_session()

# =============================
# ASKDNS
# =============================
def askdns(ip):
    try:
        headers = {
            'User-Agent': 'Mozilla/5.0 (Linux; Android 11) AppleWebKit/537.36 Chrome/109 Mobile Safari/537.36'
        }

        response = SESSION.get(
            f'https://askdns.com/ip/{ip}',
            headers=headers,
            timeout=30,
            verify=False
        )

        if response.status_code == 200:
            content = response.text
            if 'Domain Name' in content:
                domains = re.findall(r'<a href="/domain/(.*?)">', content)
                with open('revip.txt', 'a') as f:
                    for domain in domains:
                        print(f"[ASKDNS] {ip} -> {domain}")
                        f.write(domain + '\n')
            else:
                print(f"[ASKDNS] NO DATA {ip}")
        else:
            print(f"[ASKDNS] HTTP {response.status_code} {ip}")

    except Exception as e:
        print(f"[ASKDNS ERROR] {ip} -> {e}")

# =============================
# RAPID DNS
# =============================
def rapid(ip):
    try:
        headers = {
            'User-Agent': 'Mozilla/5.0 (Linux; Android 11) AppleWebKit/537.36 Chrome/109 Mobile Safari/537.36'
        }

        response = SESSION.get(
            f'https://rapiddns.io/s/{ip}?full=1&down=1#result',
            headers=headers,
            timeout=30,
            verify=False
        )

        if response.status_code == 200:
            content = response.text
            domains = re.findall(
                r'<td>(?!\-)(?:[a-zA-Z\d\-]{0,62}[a-zA-Z\d]\.){1,126}[a-zA-Z]{2,63}</td>',
                content
            )

            with open('revip.txt', 'a') as f:
                for domain in domains:
                    clean = domain.replace('<td>', '').replace('</td>', '')
                    clean = clean.replace('www.', '').replace('ftp.', '').replace('mail.', '')
                    print(f"[RAPID] {ip} -> {clean}")
                    f.write(clean + '\n')
        else:
            print(f"[RAPID] HTTP {response.status_code} {ip}")

    except Exception as e:
        print(f"[RAPID ERROR] {ip} -> {e}")

# =============================
# WEBSCAN
# =============================
def webscan(ip):
    try:
        response = SESSION.get(
            f"https://api.webscan.cc/?action=query&ip={ip}",
            timeout=15,
            verify=False
        )

        if response.status_code == 200:
            domains = re.findall(r'"domain": "(.*?)"', response.text)[3:]
            with open('revip.txt', 'a') as f:
                for domain in domains:
                    if not domain.startswith(('ftp.', 'mail.', 'cpanel.', 'webmail.', 'ns1.', 'ns2.')):
                        print(f"[WEBSCAN] {ip} -> {domain}")
                        f.write(domain + '\n')
        else:
            print(f"[WEBSCAN] HTTP {response.status_code} {ip}")

    except Exception as e:
        print(f"[WEBSCAN ERROR] {ip} -> {e}")

# =============================
# REVIP COMBINED
# =============================
def revip(ip):
    time.sleep(0.2)  # anti DNS burst
    rapid(ip)
    askdns(ip)
    webscan(ip)

# =============================
# MAIN
# =============================
def main():
    try:
        list_path = input("Enter your list: ").strip()
        THREAD = int(input("Thread: ").strip())

        with open(list_path, 'r', encoding='utf-8') as f:
            ips = f.read().splitlines()

        pool = ThreadPool(THREAD)
        pool.map(revip, ips)
        pool.close()
        pool.join()

        print("\n[✓] DONE - saved to revip.txt")

    except KeyboardInterrupt:
        print("\n[!] Interrupted")
    except Exception as e:
        print("ERROR:", e)

if __name__ == "__main__":
    main()