如何在 scapy 中打印字段偏移量?

问题描述 投票:0回答:2

我有一个

scapy
协议和一个数据包。

就像“第一步”说的那样,很容易打印一个包含字段的数据包,以及数据包的二进制转储:

>>> a=Ether()/IP(dst="www.slashdot.org")/TCP()/"GET /index.html HTTP/1.0 \n\n"
>>> a
<Ether  type=IPv4 |<IP  frag=0 proto=6 dst=Net("www.slashdot.org/32") |<TCP  
|<Raw  load='GET /index.html HTTP/1.0 \n\n' |>
>>>
>>> hexdump(a)
0000  FF FF FF FF FF FF 02 42 AC 1F 80 3C 08 00 45 00  .......B...<..E.
0010  00 43 00 01 00 00 40 06 C9 F0 AC 1F 80 3C 68 12  .C....@......<h.
0020  1C 56 00 14 00 50 00 00 00 00 00 00 00 00 50 02  .V...P........P.
0030  20 00 0C EE 00 00 47 45 54 20 2F 69 6E 64 65 78   .....GET /index
0040  2E 68 74 6D 6C 20 48 54 54 50 2F 31 2E 30 20 0A  .html HTTP/1.0 .
0050  0A                                               .
>>>

现在,我想知道,例如,

dport
中的
TCP
字段有什么偏移量。或者所有层中的所有字段。

我可以用

scapy
打印它们吗?有没有一种方法可以适用于所有协议,包括自定义协议?

python scapy
2个回答
1
投票

有趣的问题。我不相信目前有任何内置的方法可以做到这一点,而且我真的想不出一个用例。

最接近的东西,纯粹为了提供信息,可能是:

>>> rfc(TCP)
 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|             SPORT             |             DPORT             |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                              SEQ                              |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                              ACK                              |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|DATAOFS|RESER|      FLAGS      |             WINDOW            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|             CHKSUM            |             URGPTR            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|            OPTIONS            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

                             Fig. TCP

但是如果你真的想要一个数值,匹配一个字段从第一个字节开始的偏移量,你自己做起来并不难,比如:

def calc_offset(packet, layer, field):
    """Calculate the offset of a field, in a packet"""
    offset = 0
    while packet:  # for each payload
        for fld in packet.fields_desc:  # for each field
            if fld.name == field and isinstance(packet, layer):
                return int(offset)
            offset += fld.i2len(packet, packet.getfieldval(fld.name))  # add length
        packet = packet.payload
    return -1

在你的例子中:

>>> a=Ether()/IP(dst="www.slashdot.org")/TCP()/"GET /index.html HTTP/1.0 \n\n"
>>> calc_offset(a, TCP, "dport")
36
>>> struct.unpack("!H", bytes(a)[36:36+2])[0]
80
>>> a.dport
80

希望这有帮助


0
投票

为了完整起见,这里有一个函数来获取/打印所有字段的偏移量。

def field_offsets(packet):
    offsets = []
    offset = 0
    while packet:
        for field in packet.fields_desc:
            offsets.append((f'{packet.name}.{field.name}', offset))
            offset += math.ceil(field.i2len(packet, packet.getfieldval(field.name)))
        packet = packet.payload
    return offsets
for (f, o) in field_offsets(a):
    print(f'{f}: {o}')

Ethernet.dst: 0
Ethernet.src: 6
Ethernet.type: 12
IP.version: 14
IP.ihl: 15
IP.tos: 16
IP.len: 17
IP.id: 19
IP.flags: 21
IP.frag: 22
IP.ttl: 24
IP.proto: 25
IP.chksum: 26
IP.src: 28
IP.dst: 32
IP.options: 36
TCP.sport: 36
TCP.dport: 38
TCP.seq: 40
TCP.ack: 44
TCP.dataofs: 48
TCP.reserved: 49
TCP.flags: 50
TCP.window: 52
TCP.chksum: 54
TCP.urgptr: 56
TCP.options: 58
Raw.load: 58
© www.soinside.com 2019 - 2024. All rights reserved.