from scapy.layers.l2 import ARP, Ether from scapy.sendrecv import srp import netifaces from netaddr import IPNetwork class NetworkScanner: """Иницилазицая сетевого сканера""" def __init__(self, interface=None): """Инициализация параметров интерфейсов """ 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'] def _create_arp_packet(self, target_ip): """Создание пакета ARP для отправки""" arp = ARP(pdst=target_ip) ether = Ether(dst="ff:ff:ff:ff:ff:ff") return ether/arp 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): result = srp(packet, timeout=timeout, iface=self.interface, verbose=0)[0] for _, received in result: client = {'ip': received.psrc, 'mac': received.hwsrc} if client not in clients: # Избегаем дублирования клиентов clients.append(client) all_clients.extend(clients) # Добавляет все локальные IP-адреса интерфейса как клиенты for ip_info in self.ip_info: local_client = {'ip': ip_info['addr'], 'mac': self.local_mac} 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("Доступные устройства в сети:") print("IP" + " "*18+"MAC") for client in sorted(clients, key=lambda x: x['ip']): print(f"{client['ip']:<16} {client['mac']}") if __name__ == "__main__": scanner = NetworkScanner() clients = scanner.scan_network() scanner.print_clients(clients)