import ipaddress
from scapy.all import ARP, Ether, srp1, conf, get_if_addr
from concurrent.futures import ThreadPoolExecutor
# 十进制地址转点分十进制
def bytes_2_Dotted_Decimal_Notation(bytes_network):
if (bytes_network <= 0 or bytes_network >= 0xFFFFFFFF):
raise ValueError("illegal network value", hex(bytes_network))
ls = []
for _ in range(4):
ls.append(str(bytes_network & 0xFF))
bytes_network = bytes_network >> 8
ls.reverse()
return ".".join(ls)
# 点分十进制掩码转长度
def decimal_2_bit_length(netmask: int):
return sum([bin(int(i)).count('1') for i in bytes_2_Dotted_Decimal_Notation(netmask).split('.')])
# 获取本地网段
def get_local_network():
interface = conf.iface
ip = get_if_addr(interface)
for _, netmask, _, interface, address, _ in conf.route.routes:
if ip == address and netmask != 0:
return f'{ip}/{decimal_2_bit_length(netmask)}'
def scan(ip):
pkt = Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(pdst=ip)
res = srp1(pkt, timeout=6, verbose=0)
if res.psrc == ip:
print(f'[+]{res.psrc} {res.hwsrc}')
if __name__ == '__main__':
default_net = get_local_network()
input_net = input(f'请输入你要扫描的网段(默认:{default_net}):')
if input_net:
net = input_net
else:
net = default_net
pool = ThreadPoolExecutor(max_workers=255)
print("扫描开始...")
for ip in ipaddress.ip_network(net, strict=False):
pool.submit(scan, str(ip))