gonets/SRV/services/arp_service.py

71 lines
2.7 KiB
Python
Raw Normal View History

2025-06-09 14:43:25 +05:00
from scapy.layers.l2 import ARP, Ether
from scapy.sendrecv import srp
import netifaces
from netaddr import IPNetwork
2025-06-20 11:22:54 +05:00
2025-06-09 14:43:25 +05:00
class NetworkScanner:
"""Иницилазицая сетевого сканера"""
2025-06-20 11:22:54 +05:00
2025-06-09 14:43:25 +05:00
def __init__(self, interface=None):
2025-06-20 11:22:54 +05:00
"""Инициализация параметров интерфейсов"""
self.interface = (
interface or netifaces.gateways()["default"][netifaces.AF_INET][1])
self.ip_info = netifaces.ifaddresses(self.interface).get(
netifaces.AF_INET, [])
self.networks = [
IPNetwork(f"{ip['addr']}/{ip['netmask']}") for ip in self.ip_info
]
self.local_mac = netifaces.ifaddresses(
self.interface)[netifaces.AF_LINK][0]["addr"]
2025-06-09 14:43:25 +05:00
def _create_arp_packet(self, target_ip):
"""Создание пакета ARP для отправки"""
arp = ARP(pdst=target_ip)
ether = Ether(dst="ff:ff:ff:ff:ff:ff")
2025-06-20 11:22:54 +05:00
return ether / arp
2025-06-09 14:43:25 +05:00
def scan_network(self, attempts=3, timeout=2):
"""Подготовка к сканированию сети"""
all_clients = []
for network in self.networks:
target_ip = f"{network.network}/{network.prefixlen}"
packet = self._create_arp_packet(target_ip)
clients = []
for _ in range(attempts):
2025-06-20 11:22:54 +05:00
result = srp(packet,
timeout=timeout,
iface=self.interface,
verbose=0)[0]
2025-06-09 14:43:25 +05:00
for _, received in result:
2025-06-20 11:22:54 +05:00
client = {"ip": received.psrc, "mac": received.hwsrc}
2025-06-09 14:43:25 +05:00
if client not in clients: # Избегаем дублирования клиентов
clients.append(client)
all_clients.extend(clients)
# Добавляет все локальные IP-адреса интерфейса как клиенты
for ip_info in self.ip_info:
2025-06-20 11:22:54 +05:00
local_client = {"ip": ip_info["addr"], "mac": self.local_mac}
2025-06-09 14:43:25 +05:00
if local_client not in all_clients:
all_clients.append(local_client)
# Удаление дубликатов
unique_clients = {tuple(client.items()) for client in all_clients}
return [dict(client) for client in unique_clients]
def print_clients(self, clients):
"""Лист адресов клиентов"""
print("Доступные устройства в сети:")
2025-06-20 11:22:54 +05:00
print("IP" + " " * 18 + "MAC")
for client in sorted(clients, key=lambda x: x["ip"]):
2025-06-09 14:43:25 +05:00
print(f"{client['ip']:<16} {client['mac']}")
2025-06-20 11:22:54 +05:00
2025-06-09 14:43:25 +05:00
if __name__ == "__main__":
scanner = NetworkScanner()
clients = scanner.scan_network()
scanner.print_clients(clients)