重建分段的IP数据包 - python

时间:2016-01-15 13:14:37

标签: python networking scapy netfilter

我正在尝试使用python,scapy和netfilter队列来编写一个小的“防火墙”,该队列也处理没有已知到达顺序的碎片数据包。 所以我想把数据包保存在按IP头ID值排序的字典中,每个条目都是一个元组列表 - 数据包偏移量和netfilter队列数据包对象本身(所以当决定判决时我可以放弃或接受) 。 遇到的问题是在将新数据包附加到字典中的列表之后,看起来数据包的有效负载也附加到所有其他数据包。我已经查了一下,我认为它与不变性有关,但无法解决任何好的解决方案。 我是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')

任何帮助都会非常感激!

1 个答案:

答案 0 :(得分:0)

事实证明,netfilter队列对象有效负载字段是指向网络驱动程序中缓冲区的指针。因此,接收缓冲区的每个数据包都会根据id继续附加有效负载。 我所做的是保持对原始有效载荷的scapy对象的引用并获得所需的结果。

相关问题