如何通过 Scapy 设置 TCP 选项(时间戳和 SAckOk)?
How to set TCP options (Timestamp and SAckOk) via Scapy?
我想通过 Scapy 生成的每个数据包都有以下信息,它是 tcpdump 输出:
1509472682.813373 MAC1 > MAC2, ethertype IPv4 (0x0800), length 74: (tos 0x0, ttl 64, id 64271, offset 0, flags [DF], proto TCP (6), length 60)
IP1.port1 > IP2.port2: Flags [S], cksum 0x4a0b (incorrect -> 0xe5b4), seq 1763588570, win 65535, options [mss 1460,sackOK,TS val 1098453 ecr 0,nop,wscale 6], length 0
我已经生成了如下的 TCP
数据包,但是当我通过 wireshark 检查它们时,似乎根本没有设置 Timestamp
选项并且 Sack
也没有设置,因为我有所期待。
for r in (("mss","MSS"), ("sackOK","SAck"), ("nop","NOP"), ("TS ", "Timestamps "), ("val", "TSval"), ("ecr", "TSecr"), ("wscale","WScale")):
opt = opt.replace(*r)
opt=opt.split(",")
for op in opt:
op = op.split()
if len(op) == 2:
options.append((op[0],int(op[1])))
elif op[0] == "Timestamps": ## Need some modification, so that Scapy do not ignore it.
options.append((op[0],(int(op[2]),int(op[4]))))
elif op[0] == "SAck": ## How to set SAck option to be SAck Permitted?
options.append((op[0], ''))
else: # NOP
options.append((op[0], ()))
ip = ether/IP(src=ipsrc, dst=ipdst, len=ipLen, tos=frameTos, ttl=frameTtl, offset=frameOffset, id=frameId, flags=frameFlags, proto=protocol.lower())
if ack_n is None:
pkt = ip / TCP(sport=srcport, dport=dstport , flags=frameFlag, seq=int(seq_n), chksum=cksum, window=win, options=options) / secrets.token_bytes(frameLen-54)
else:
pkt = ip / TCP(sport=srcport, dport=dstport , flags=frameFlag, seq=int(seq_n), ack=ack_n, chksum=cksum, window=win, options=options) / secrets.token_bytes(frameLen-54)
pkt.time = frametime
wrpcap(output, pkt, append=True)
这是传递到数据包选项字段的内容,我在开头提供了它的信息:
[('MSS', 1460), ('SAck', ''), ('Timestamps', (1098453, 0)), ('NOP', ()), ('WScale', 6)]
但是当我通过Wireshark检查数据包时没有设置Timestamps
选项,似乎Scapy忽略了它,并且没有像我预期的那样设置SAck
选项
Wireshark 中此数据包选项字段如下所示:
这是我的预期:
所以这里的问题是:
- 如何设置
timestamps
,让Scapy不忽略?
- 如何设置
SAck
,使其标记为允许。
编辑 1:
我已经解决了 SAck
的问题,我应该把它作为 ('SAckOK', '')
终于找到我设置错误的地方了:
正如我在第一次编辑中提到的,要设置允许的选择性确认,我应该将选项作为元组传递给 ('SAckOK', '')
。
要设置 timestamp
我应该在内部元组中将选项作为 ('Timestamp', (1098453, 0))
传递给选项,第一个参数是 Val
,第二个参数是 Ecr
。
我想通过 Scapy 生成的每个数据包都有以下信息,它是 tcpdump 输出:
1509472682.813373 MAC1 > MAC2, ethertype IPv4 (0x0800), length 74: (tos 0x0, ttl 64, id 64271, offset 0, flags [DF], proto TCP (6), length 60)
IP1.port1 > IP2.port2: Flags [S], cksum 0x4a0b (incorrect -> 0xe5b4), seq 1763588570, win 65535, options [mss 1460,sackOK,TS val 1098453 ecr 0,nop,wscale 6], length 0
我已经生成了如下的 TCP
数据包,但是当我通过 wireshark 检查它们时,似乎根本没有设置 Timestamp
选项并且 Sack
也没有设置,因为我有所期待。
for r in (("mss","MSS"), ("sackOK","SAck"), ("nop","NOP"), ("TS ", "Timestamps "), ("val", "TSval"), ("ecr", "TSecr"), ("wscale","WScale")):
opt = opt.replace(*r)
opt=opt.split(",")
for op in opt:
op = op.split()
if len(op) == 2:
options.append((op[0],int(op[1])))
elif op[0] == "Timestamps": ## Need some modification, so that Scapy do not ignore it.
options.append((op[0],(int(op[2]),int(op[4]))))
elif op[0] == "SAck": ## How to set SAck option to be SAck Permitted?
options.append((op[0], ''))
else: # NOP
options.append((op[0], ()))
ip = ether/IP(src=ipsrc, dst=ipdst, len=ipLen, tos=frameTos, ttl=frameTtl, offset=frameOffset, id=frameId, flags=frameFlags, proto=protocol.lower())
if ack_n is None:
pkt = ip / TCP(sport=srcport, dport=dstport , flags=frameFlag, seq=int(seq_n), chksum=cksum, window=win, options=options) / secrets.token_bytes(frameLen-54)
else:
pkt = ip / TCP(sport=srcport, dport=dstport , flags=frameFlag, seq=int(seq_n), ack=ack_n, chksum=cksum, window=win, options=options) / secrets.token_bytes(frameLen-54)
pkt.time = frametime
wrpcap(output, pkt, append=True)
这是传递到数据包选项字段的内容,我在开头提供了它的信息:
[('MSS', 1460), ('SAck', ''), ('Timestamps', (1098453, 0)), ('NOP', ()), ('WScale', 6)]
但是当我通过Wireshark检查数据包时没有设置Timestamps
选项,似乎Scapy忽略了它,并且没有像我预期的那样设置SAck
选项
Wireshark 中此数据包选项字段如下所示:
这是我的预期:
所以这里的问题是:
- 如何设置
timestamps
,让Scapy不忽略? - 如何设置
SAck
,使其标记为允许。
编辑 1:
我已经解决了 SAck
的问题,我应该把它作为 ('SAckOK', '')
终于找到我设置错误的地方了:
正如我在第一次编辑中提到的,要设置允许的选择性确认,我应该将选项作为元组传递给 ('SAckOK', '')
。
要设置 timestamp
我应该在内部元组中将选项作为 ('Timestamp', (1098453, 0))
传递给选项,第一个参数是 Val
,第二个参数是 Ecr
。