在上述代码中,行 1 创建了一个 IP 对象,每个 IP 头部字段都有一个类属性。我们可以使用 a 或 ls(IP) 来查看所有属性名称和它们的值。我们也可以用 a.show() 和 IP.show() 来做同样的事情。行 2 显示了如何设置目标 IP 地址字段。如果某个字段未被设置,则会使用默认值。
>>> ls(a)
version : BitField (4 bits) = 4 (4)
ihl : BitField (4 bits) = None (None)
tos : XByteField = 0 (0)
len : ShortField = None (None)
id : ShortField = 1 (1)
flags : FlagsField (3 bits) = <Flag 0 ()> (<Flag 0 ()>)
frag : BitField (13 bits) = 0 (0)
ttl : ByteField = 64 (64)
proto : ByteEnumField = 0 (0)
chksum : XShortField = None (None)
src : SourceIPField = '127.0.0.1' (None)
dst : DestIPField = '127.0.0.1' (None)
options : PacketListField = [] ([])
行 3 创建了一个 ICMP 对象。默认类型是 echo 请求。在 行 4 中,我们将 a 和 b 相结合以形成一个新的对象。/ 操作符被 IP 类重载,因此它不再表示除法,而是意味着将 b 作为 a 的负载字段并相应地修改 a 的字段。结果我们得到了一个代表 ICMP 包的新对象。我们现在可以使用 行 5 的 send()
发送这个包。请根据示例代码做出必要的更改,并演示你能够伪造 ICMP echo 请求包。