根据Scapy上的ICMPv6类型创建IPv6更新plen字段

时间:2013-03-31 07:53:17

标签: python scapy

在我的程序中,我使用scapy来创建/解析数据包,但实际的程序是用C ++编写的。由于用户只需要ICMPv6的前几个字段对所有ICMPv6数据包都相同,我在C ++端创建了一个ICMPv6类(使用ICMPv6Unknown)。

我的问题是虽然它们可以在ICMPv6的字段中正常工作,但IPv6中的plen字段根据我在ICMPv6标头中放入的类型无法正确更新。

我不确定我可以在IPv6类中编辑什么来根据接下来的ICMPv6类型更改字段,现在它可以:

    def post_build(self, p, pay):
    p += pay
    if self.plen is None:
        l = len(p) - 40
        p = p[:4]+struct.pack("!H", l)+p[6:]
    return p

由于ICMPv6Unknown返回len为4,因此它失败,因此它不会根据我的类型字段更改大小。我知道Ether会根据字段更改类型,但我无法为ICMPv6重现此内容

2 个答案:

答案 0 :(得分:0)

为了解决这个问题,我在下面的方法中添加了一个不使用len(p)的if,以下列方式:

    def post_build(self, p, pay):
    p += pay
    if self.plen is None:
        if self.nh == 58:
            icmp_type = ord(pay[0])
            l = icmpv6_len(icmp_type)
            print "len is: " + str(l)
    else:
    l = len(p) - 40
        p = p[:4]+struct.pack("!H", l)+p[6:]
    return p

其中icmpv6_len静态返回类型的长度。

答案 1 :(得分:0)

我通过重载build_payload()解决了这个问题:

def build_payload(self):
        if isinstance(self.payload, ICMPv6Unknown): 
            icmp_type = ord(str(self.payload)[0]) 
            icmp_class = eval(icmp6typescls[icmp_type]) 
            if self.payload.haslayer(Raw): #create actual class from the first 2 fields of the ICMPv6Unknown (type and code, ignoring the checksum) and add the other layers if there are any
                self.payload = icmp_class(str(self.payload[0])[0:2]) / self.payload[1:]
        else:
                self.payload = icmp_class(str(self.payload[0])[0:2])
        return super(IPv6 ,self).build_payload()

这基本上将ICMPv6Unknown图层中的前两个字段重新解析为我们想要的图层。