使用Scapy删除重复的IP地址

问题描述

我有一个脚本来侦听传入的流量,并在数据包上线时仅输出字符串“ IP 1.1.1.1 53”,但是现在我正在对IP进行IP解析,因此我需要访问“ ip_src”变量,并且在每个IP上仅进行一次地理位置定位,而不是一遍又一遍地解析相同的IP。我当前的代码是:

#!/usr/bin/python3
from scapy.all import *
import ipinfo

def print_summary(pkt):
  if IP in pkt:
     ip_src=pkt[IP].src
  if UDP in pkt:
     udp_sport=pkt[UDP].sport
     access_token = ''
     handler = ipinfo.getHandler(access_token)
     match = handler.getDetails(ip_src)
     c = match.details.get('city')
     s = match.details.get('region')
     strang = ("IP " + str(ip_src) + " " + str(udp_sport) + " " + str(c) + "," + str(s))
     print(strang)

sniff(filter="",prn=print_summary)

如您所见,“ print_summary”函数由“ prn”调用,每个pkt都会调用函数。我基本上想模仿uniq和sort的功能,因为它们可以成功地从文件中过滤出重复项,但是我希望将它们全部合并在一个脚本中。

编辑-尝试Set():

因此使用代码

from scapy.all import *

def print_summary(pkt):
  if IP in pkt:
     ip_src=pkt[IP].src
  if UDP in pkt:
     udp_sport=pkt[UDP].sport
     lines_set = set(ip_src)
     strang = ("IP " + str(ip_src) + " " + str(udp_sport))
     if ip_src not in lines_set:
        for line in lines_set:
           print(line)
sniff(filter="",prn=print_summary)

我得到输出:(在终端中,每个字符都有一个尾随换行符)

2 . 3 5 8 0 1 2 . 4 8 0 1 . 6

解决方法

这将添加一个set变量,以跟踪您已经看到的地址。

#!/usr/bin/python3
from scapy.all import *
import ipinfo
 
seen = set()
 
def print_summary(pkt):
  if IP in pkt:
     ip_src=pkt[IP].src
     if UDP in pkt and ip_src not in seen:
         seen.add(ip_src)
         udp_sport=pkt[UDP].sport
         access_token = ''
         handler = ipinfo.getHandler(access_token)
         match = handler.getDetails(ip_src)
         c = match.details.get('city')
         s = match.details.get('region')
         strang = ("IP " + str(ip_src) + " " + str(udp_sport) + " " + str(c) + "," + str(s))
         print(strang)
 
sniff(filter="ip",prn=print_summary)

我还更改了第二个if的缩进,以避免在某种程度上您收到没有IP成员的数据包时进行回溯;尽管我也更新了filter表达式,以期希望它一开始就不会发生。