重建碎片化的 IP 数据包 - python

Reconstructing fragmented IP packets - python

我正在尝试使用 python、scapy 和 netfilter queue 编写一个小的 "firewall",它还可以处理没有已知到达顺序的碎片数据包。 所以我想将数据包保存在按 IP header ID 值排序的字典中,每个条目都是一个元组列表 - 数据包偏移量和 netfilter queue 数据包 object 本身(所以当判决作出时,我可以放弃或接受)。 我遇到的问题是在将新数据包附加到字典中的列表后,看起来数据包的有效负载也附加到所有其他数据包。我查了一下,我认为它与不变性有关,但没有任何好处 solution\explanation 。 我是 python 的新手,非常希望得到一些指导。 代码:

def update_fragmented_lists(scapy_packet, pkt):
    current_dict = pkt_dict[scapy_packet[IP].id]
    if len(current_dict) < 4:
        current_dict.append((scapy_packet[IP].frag, pkt))
    else:
        for frag, waiting_pkt in current_dict:
            waiting_pkt.drop()
        del(pkt_dict[scapy_packet[IP].id])


def reconstruct_packet(packet_id):
   curr_dict = pkt_dict[packet_id]
   curr_dict = sorted(curr_dict, key=get_key)
   print(curr_dict)
   if IP(curr_dict[-1][1].get_payload()).flags == 1:
       return None
   last_off = 0
   http_req = ""
   for (offset, pkt) in curr_dict:
       scapy_packet = IP(pkt.get_payload())
       if offset*8 == last_off:
           http_req += scapy_packet[Raw].load
           last_off += len(scapy_packet[Raw].load)
       else:
           http_req = None
           break
   return http_req

def handle_packet(pkt):
    scapy_packet = IP(pkt.get_payload())
    packet_id = scapy_packet[IP].id
    if (scapy_packet[IP].flags == 1) or (scapy_packet[IP].flags == 0 and           scapy_packet[IP].frag != 0):
         update_fragmented_lists(scapy_packet, pkt)
         http_req = reconstruct_packet(packet_id)
        if http_req is not None:
            if check_forbidden_suffix(http_req):
                for offset, fragmented_pkt in pkt_dict[packet_id]:
                    fragmented_pkt.accept()
            else:
                for offset, fragmented_pkt in pkt_dict[packet_id]:
                    fragmented_pkt.drop()

 pkt_dict = defaultdict(list)
 nfqueue = NetfilterQueue()
 nfqueue.bind(1, handle_packet)
 try:   
      nfqueue.run()
 except KeyboardInterrupt:
      os.system('iptables -F')
      os.system('iptables -X')

任何帮助将不胜感激!

事实证明,netfilter queue object payload字段是一个指向网络驱动中缓冲区的指针。因此,每个接收到缓冲区的数据包都会根据 id 不断附加有效负载。 我所做的是继续参考我投射的原始有效载荷的 scapy 对象并获得所需的结果。