dpi-detector/utils/network.py
Kirill Minovsky d3ebede4e7 feat(scanner): improve IP identification and classification (N/A)
- Added get_fake_ip_type utility for network address validation
- Integrated IP classification logic into tls_scanner
- Added support for detecting ISP, Fake-IP, and local network ranges
- Updated scan results to display specific statuses for detected IPs
2026-04-24 15:11:33 +03:00

58 lines
No EOL
2 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import asyncio
import socket
import ipaddress
from typing import Optional
async def get_resolved_ip(domain: str, family: int = socket.AF_INET) -> Optional[str]:
"""
Резолвит домен в IP-адрес. До 2 попыток при сбое.
family: socket.AF_INET для IPv4, socket.AF_INET6 для IPv6.
Использует системный DNS — если провайдер подменяет системный резолвер,
но не прямой UDP/53, stub_ips из DNS-теста не совпадут с resolved_ip.
"""
loop = asyncio.get_running_loop()
for attempt in range(2):
try:
addrs = await loop.getaddrinfo(
domain, 443, family=family, type=socket.SOCK_STREAM
)
if addrs:
return addrs[0][4][0]
except Exception:
if attempt == 0:
await asyncio.sleep(0.2)
continue
break
return None
def get_fake_ip_type(ip_str: str) -> str:
"""
Возвращает:
'fakeip' - (198.18.0.0/15)
'isp' - для сетей провайдера (CGNAT)
'local' - для локальных сетей (LAN, localhost, нули)
None - если это обычный публичный IP
"""
if not ip_str:
return None
try:
ip = ipaddress.ip_address(ip_str)
if not isinstance(ip, ipaddress.IPv4Address):
return None
# 198.18.0.0/15 — Fake-IP
if ip in ipaddress.ip_network('198.18.0.0/15'):
return "fakeip"
# 100.64.0.0/10 — Carrier-Grade NAT (заглушки провайдер)
if ip in ipaddress.ip_network('100.64.0.0/10'):
return "isp"
# Локальные сети (10.x, 192.168.x, 172.16.x, Loopback, нули)
if ip.is_loopback or ip.is_private or ip.is_link_local or ip.is_unspecified:
return "local"
return None
except ValueError:
return None