python实现arp扫描
局域网扫描,局域网存货ip快速扫描
安装:
pip install scapy
1、以前的写法:单线程(不推荐)
from scapy.all import * import sys, getopt, socket def get_local_net(): # 获取网段。如:192.168.50 try: s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.connect(('8.8.8.8', 80)) # 获取本机ip。如:192.168.50.110 ip = s.getsockname()[0] ippre_list = ip.split(r".") ippre_list.pop() # 获取网段字串。如:192.168.50 ipnet = '.'.join(ippre_list) except Exception: ipnet = False finally: s.close() return ipnet def get_vlan_ip_and_mac(locnet, start_num=1, end_num=255): # 通过arp协议扫描,发现本网段存活ip和mac result = [] localnet = locnet scansum = int(end_num) - int(start_num) + 1 print("%s.%s - %s.%s 共计 %s 个被扫描ip" % (localnet, start_num, localnet, end_num, scansum)) print() counter = 1 # 如果无法识别本网段,则退出扫描 if not localnet: print("扫描终止:无法识别本网段。") return result for ipFix in range(start_num, end_num + 1): # 构造本网段的ip。如:192.168.50.20 ip = localnet + "." + str(ipFix) # 组合协议包 # 通过 '/' 可叠加多个协议层(左底层到右上层),如Ether()/IP()/UDP()/DNS() arpPkt = Ether(dst="ff:ff:ff:ff:ff:ff") / ARP(pdst=ip) # 发送arp请求,并获取响应结果。设置1s超时。 res = srp1(arpPkt, timeout=1, verbose=0) # 如果ip存活 if res: print("%3d --> %s %s" % (counter, ip, res.hwsrc)) result.append({"localIP": res.psrc, "mac": res.hwsrc}) counter += 1 # 如果ip不存活 else: print("%3d --> %s" % (counter, ip)) counter += 1 return result if __name__ == '__main__': locnet = get_local_net() print("一、开始扫描本网段(%s.xx)活动的ip" % locnet) # 扫描ip起始和终止范围 start_num = 126 end_num = 135 # 开始扫描 result = get_vlan_ip_and_mac(locnet, start_num, end_num) print() print("二、Mac表汇总清单(活动ip共计 %s个):" % len(result)) for dic in result: print(dic)
2、推荐的写法:多线程(推荐)
from scapy.all import * import threading ip_list = [] mac_list = [] def ScanIp(ip): pkt = Ether(dst="ff:ff:ff:ff:ff:ff") / ARP(pdst=ip) try: res = srp1(pkt, timeout=10, verbose=0) if res.psrc == ip: # print('IP MAC') print('%-14s %s' % (res.psrc, res.hwsrc)) ip_list.append(res.psrc) mac_list.append(res.hwsrc) # my_thread_id = threading.current_thread().ident # 获取当前线程id print("{0}{1} 子线程结束".format(' ' * 60, threading.current_thread().ident)) except: pass if __name__ == '__main__': # ARP().show() # 自动获取当前网段 tip = ARP().psrc tip = tip[:(len(tip) - tip[::-1].find('.'))] # 192.168.50. print(tip) # ScanIp("192.168.50.12") thread_list = [] for i in range(1, 256): ip = tip + str(i) Go = threading.Thread(target=ScanIp, args=(ip,)) thread_list.append(Go) Go.start() # 在这里统一执行线程等待的方法 for Go in thread_list: Go.join() print('=' * 100) # 将存活的ip清单,按照最后一位数字排序 ip_sort_list = sorted(ip_list, key=lambda ip: int(ip.rpartition('.')[-1])) print('存活ip个数:%s' % len(ip_sort_list)) for ip in ip_sort_list: print(ip)
方法2