[英]How to read whole ip layer and tcp layer from a packet when using scapy?
当收到带有 scapy 的 ICMP Destination unreachable (Fragmentation required ICMP TYPE=3 CODE=4) 消息时,我正在做 TCP 重传行为测试。
测试流程如下:
1.建立与服务器的TCP连接
2. TCP建立时向服务器发送HTTP GET请求
3. 当 HTTP 响应返回时
4.发送一个ICMP type 3 code 4消息到s small MTU set的服务器
问题是 ICMP TYPE=3 CODE=4 消息包括该 HTTP 响应数据包的 IP 标头和部分 TCP 标头(srt、dst 和 seq 号)。 目前,我只是从该 HTTP 响应数据包中读取每个参数(如 IP 标识、片段标记、ttl 等)。 问题是:有什么方法可以从该数据包中读取整个 IP 和 TCP 标头:
ICMP(TYPE=3 CODE=4)/IP Header/TCP Header
希望以下内容会有所帮助:
>>> pkt = ICMP()/IP()/TCP()
>>> ip_header = pkt.getlayer(IP)
>>> ip_header
<IP frag=0 proto=tcp |<TCP |>>
>>>
要仅检索 IP 标头:
>>> pkt = Ether()/IP()/TCP()
>>> ip = pkt.getlayer(IP)
>>> ip
<IP frag=0 proto=tcp |<TCP |>>
>>> ip.remove_payload()
>>> ip
<IP |>
>>>
我将数据包对象转换为 dict 对象,以使我的解析生活更轻松。 代码:
from scapy.all import *
from cStringIO import StringIO
import sys
class Capturing(list):
"""
This class will capture sys.out.
More info:
http://stackoverflow.com/questions/16571150/how-to-capture-stdout-output-from-a-python-function-call
"""
def __enter__(self):
self._stdout = sys.stdout
sys.stdout = self._stringio = StringIO()
return self
def __exit__(self, *args):
self.extend(self._stringio.getvalue().splitlines())
del self._stringio # free up some memory
sys.stdout = self._stdout
class PacketDict(dict):
"""
This class will convert packet into a dict by using the result of packet.show2(). Furthermore the original
packet will be also saved as attribute '.packet'.
More class functions could be added, currently only support 'haslayer()'.
Scapy version: scapy-2.3.3
"""
def __init__(self, pkt):
self.packet = pkt
self.__packet_to_dict()
def __extract_key(self, line):
a = line.lstrip("###[ ").rstrip(" ]### ")
return a
def __extract_value_to_dict(self, line):
if line.find("=") > -1:
b = line.replace(" ","")
a = b.split("=")
return {a[0]: a[1]}
return {line.replace(" ",""): None}
def __packet_to_dict(self):
with Capturing() as packet_in_list:
self.packet.show2()
current_dict = self
for line in packet_in_list:
if line.strip() != "":
line = line.replace("|","")
if line.find('###[') > -1:
key = self.__extract_key(line)
current_dict[key] = {}
current_dict = current_dict[key]
continue
current_dict.update(self.__extract_value_to_dict(line))
def haslayer(self, pkt_cls):
return self.packet.haslayer(pkt_cls)
if __name__ == "__main__":
packet_list = rdpcap("/media/sf_ubshare/pcap/test.pcap")
for packet in packet_list:
a = PacketDict(packet)
print a['Ethernet']['IP']['ihl']
print a.haslayer('ISAKMP')
输出:
/usr/bin/python2.7 /home/yuanzhi/workspace/scaptest/scaptest.py
5L
1
字典将如下所示:
{
"Ethernet": {
"src": "5e:22:73:12:50:02",
"dst": "6e:30:96:e3:a0:6c",
"type": "0x800",
"IP": {
"frag": "0L",
"src": "1.0.3.0",
"UDP": {
"dport": "isakmp",
"ISAKMP": {
"resp_cookie": "'\\xb5A\\x06\\xef\\x126~\\x95'",
"exch_type": "identityprot.",
"length": "204",
"version": "0x10",
"flags": "",
"init_cookie": "'2\\x12\\xbda\\xee\\xa8\\xba\\xa6'",
"ISAKMP SA": {
"IKE proposal": {
"SPI": "''",
"length": "44",
"IKE Transform": {
"length": "36",
"num": "0",
"transforms": "[('Encryption','AES-CBC'),('KeyLength',256),('Hash','SHA'),('Authentication','PSK'),('GroupDesc','1024MODPgr'),('LifeType','Seconds'),('LifeDuration',43200)]",
"ISAKMP Vendor ID": {......
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.