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
浙公网安备 33010602011771号