for循环卡在列表中的第一项-python
我想创建脚本从ARP协议中提取IP和MAC地址(被动扫描) 我在debian上使用了python3.8和scapy2.4.4。 我使用的代码返回所有地址,但我希望它打印出IP/MAC而不重复,因此我创建了一个列表,以检查MAC之前是否已注册,如果未注册,它将添加到列表中并显示在输出中。 但是for循环卡在列表的第一项,然后所有的mac都被打印出来了 守则:for循环卡在列表中的第一项-python,python,loops,scapy,sniffer,Python,Loops,Scapy,Sniffer,我想创建脚本从ARP协议中提取IP和MAC地址(被动扫描) 我在debian上使用了python3.8和scapy2.4.4。 我使用的代码返回所有地址,但我希望它打印出IP/MAC而不重复,因此我创建了一个列表,以检查MAC之前是否已注册,如果未注册,它将添加到列表中并显示在输出中。 但是for循环卡在列表的第一项,然后所有的mac都被打印出来了 守则: from scapy.all import * print("-"*33,"\nIP\t\tMac Addre
from scapy.all import *
print("-"*33,"\nIP\t\tMac Address\n","-"*33)
mac_list = [1]
def arp_display(pkt):
if ((pkt[ARP].op == 2 ) or (pkt[ARP].op == 1 )):
new_mac = pkt[ARP].hwsrc
for i in mac_list :
if ( i != new_mac):
mac_list.append(new_mac)
return f"{pkt[ARP].psrc} {pkt[ARP].hwsrc} "
sniff(prn=arp_display, filter="arp", store=0, iface='eth0')
我尝试使用以下代码打印(I)值、新MAC值和列表值:
from scapy.all import *
print("-"*33,"\nIP\t\tMac Address\n","-"*33)
mac_list = [1]
def arp_display(pkt):
if ((pkt[ARP].op == 2 ) or (pkt[ARP].op == 1 )): #is-at (response)
new_mac = pkt[ARP].hwsrc
for i in mac_list :
print("i=",i)
print("New MAC", new_mac)
print("List=", mac_list)
if ( i != new_mac):
mac_list.append(new_mac)
return f"{pkt[ARP].psrc} {pkt[ARP].hwsrc} "
sniff(prn=arp_display, filter="arp", store=0, iface='eth0')
结果是:
---------------------------------
IP Mac Address
---------------------------------
i= 1
New MAC 3c:95:09:77:86:01
List= [1]
192.168.60.2 3c:95:09:77:86:01
i= 1
New MAC 00:0c:29:de:7b:39
List= [1, '3c:95:09:77:86:01']
192.168.60.3 00:0c:29:de:7b:39
i= 1
New MAC 3c:47:11:bf:84:f2
List= [1, '3c:95:09:77:86:01', '00:0c:29:de:7b:39']
192.168.60.1 3c:47:11:bf:84:f2
i= 1
New MAC 00:0c:29:de:7b:39
List= [1, '3c:95:09:77:86:01', '00:0c:29:de:7b:39', '3c:47:11:bf:84:f2']
192.168.60.3 00:0c:29:de:7b:39
正如您所看到的,列表中有项目,但for循环在第一个循环中卡住了。您没有发布
sniff
的功能,因此很难说您是如何获得输出的。但是,我猜,sniff
运行了几次arp\u display
,每次for循环只执行一次迭代I=1
,其中1是mac\u列表的第一个元素
每次运行时,mac\u list
都会变长。请参见arp\u display
部分,其中您将附加到mac\u列表中
?您还可以返回
,它退出for循环和函数。就像每次跑步一样,i!=新的_mac
在第一次迭代时为true,其中i=1
,因此您可以在i=1
处继续退出for循环
我不确定您希望如何修复它,但通常我会避免在for循环中迭代将追加到列表(或任何其他iterable)中。列表可能会越来越长,因此在程序内存耗尽之前for循环永远不会结束。1
永远不会等于MAC地址,因此每次迭代,如果(i!=new\u MAC):
将为真,然后从该正文返回,这将阻止进一步的迭代
只需使用集合
。集合不能包含重复项,因此您无需担心重复项:
mac_set = set() # A set instead of a list
def arp_display(pkt):
if ((pkt[ARP].op == 2) or (pkt[ARP].op == 1)): #is-at (response)
new_mac = pkt[ARP].hwsrc
mac_set.add(new_mac) # add instead of append
return f"{pkt[ARP].psrc} {pkt[ARP].hwsrc} "
但这并不能维持秩序,因为集合是无序的。@batwannab如果你是对的,返回值在错误的位置,我试图将其从for循环中写入,然后我得到了正确的结果
第二个错误是循环函数分别传递所有元素,如果新项(new\u mac
)与循环函数传递到的元素(mac\u list
)不匹配,则添加新项(new\u mac
)的值,为了避免此问题,我添加了Double
变量,因此,当循环函数通过列表项(mac_list
)时,如果不匹配,它将添加值0
,否则将添加值1
,然后中断循环函数
因此,我们已经确定新的MAC地址是否在列表中
最终代码如下:
from scapy.all import *
print("-"*33,"\nIP\t\tMac Address\n","-"*33)
mac_list = ['1']
output = ""
def arp_display(pkt):
if ((pkt[ARP].op == 2 ) or (pkt[ARP].op == 1 )): #is-at (response)
new_mac = str(pkt[ARP].hwsrc)
double = 0
for i in mac_list :
if ( i != new_mac ):
double = 0
else:
double = 1
break
if(double == 0):
mac_list.append(new_mac)
output = f"{pkt[ARP].psrc} {pkt[ARP].hwsrc} "
else:
output = None
return output
sniff(prn=arp_display, filter="arp", store=0, iface='eth0')
是的,arp\u display
函数在服务器上运行一段时间,因此我将mac\u列表
置于功能之外,以避免丢失旧项目。我需要arp\u display
功能添加新项目并显示它们。如果您正在查找mac_列表
,您将看到它不是空的,并且包含其他项,我不会在for循环中使用这些项,以避免在输出上重复使用mac