为什么 Scapy 重新计算碎片大小?
Why Scapy recalculates fragmentation size?
我正在尝试将 120 字节的 IP 负载分成 100 字节。但是,在输出中我得到了两个数据包,一个是 138 字节,另一个是 50 字节(以太网和 IP header 大小分别为 14 字节和 20 字节)。在第一个数据包数据偏移量从 0 到 103 开始,第二个数据包数据偏移量从 104 到 119 开始。首先我不明白为什么它以这种方式工作。为了理解,我试图查看 layers/inet.py line 552 中定义的片段函数的来源。
Scapy 重新计算碎片大小如下:
def fragment(self, fragsize=1480):
"""Fragment IP datagrams"""
fragsize = (fragsize + 7) // 8 * 8 # <- RECALCULATION OF FRAGMENT SIZE
lst = []
fnb = 0
fl = self
while fl.underlayer is not None:
fnb += 1
fl = fl.underlayer
for p in fl:
s = raw(p[fnb].payload)
nb = (len(s) + fragsize - 1) // fragsize
for i in range(nb):
q = p.copy()
del(q[fnb].payload)
del(q[fnb].chksum)
del(q[fnb].len)
if i != nb - 1:
q[fnb].flags |= 1
q[fnb].frag += i * fragsize // 8
r = conf.raw_layer(load=s[i * fragsize:(i + 1) * fragsize])
r.overload_fields = p[fnb].payload.overload_fields.copy()
q.add_payload(r)
lst.append(q)
return lst
有人可以解释为什么这样做吗?
N.B:
- 以太网 header 大小 14 字节
- IPv4 header 大小 20 字节
见https://github.com/secdev/scapy/issues/2424#issuecomment-576879663
来自 https://www.rfc-editor.org/rfc/rfc791#section-3.2(第 25 页,顶部):
If an internet datagram is fragmented, its data portion must be broken on 8 octet boundaries.
要回答您的问题,片段大小必须是 8 的倍数。
104是8的倍数,不是100
我正在尝试将 120 字节的 IP 负载分成 100 字节。但是,在输出中我得到了两个数据包,一个是 138 字节,另一个是 50 字节(以太网和 IP header 大小分别为 14 字节和 20 字节)。在第一个数据包数据偏移量从 0 到 103 开始,第二个数据包数据偏移量从 104 到 119 开始。首先我不明白为什么它以这种方式工作。为了理解,我试图查看 layers/inet.py line 552 中定义的片段函数的来源。
Scapy 重新计算碎片大小如下:
def fragment(self, fragsize=1480):
"""Fragment IP datagrams"""
fragsize = (fragsize + 7) // 8 * 8 # <- RECALCULATION OF FRAGMENT SIZE
lst = []
fnb = 0
fl = self
while fl.underlayer is not None:
fnb += 1
fl = fl.underlayer
for p in fl:
s = raw(p[fnb].payload)
nb = (len(s) + fragsize - 1) // fragsize
for i in range(nb):
q = p.copy()
del(q[fnb].payload)
del(q[fnb].chksum)
del(q[fnb].len)
if i != nb - 1:
q[fnb].flags |= 1
q[fnb].frag += i * fragsize // 8
r = conf.raw_layer(load=s[i * fragsize:(i + 1) * fragsize])
r.overload_fields = p[fnb].payload.overload_fields.copy()
q.add_payload(r)
lst.append(q)
return lst
有人可以解释为什么这样做吗?
N.B:
- 以太网 header 大小 14 字节
- IPv4 header 大小 20 字节
见https://github.com/secdev/scapy/issues/2424#issuecomment-576879663
来自 https://www.rfc-editor.org/rfc/rfc791#section-3.2(第 25 页,顶部):
If an internet datagram is fragmented, its data portion must be broken on 8 octet boundaries.
要回答您的问题,片段大小必须是 8 的倍数。 104是8的倍数,不是100