简体   繁体   English

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

[英]Making IPv6 update plen field according to ICMPv6 type on Scapy

In my program I use scapy to create/parse packets, but the actual program is in C++. 在我的程序中,我使用scapy创建/解析数据包,但实际程序是C ++。 Since the users only needed the first few fields of ICMPv6 which are the same for all ICMPv6 packets, I created a single ICMPv6 class (using ICMPv6Unknown) on the C++ side. 由于用户只需要与所有ICMPv6数据包相同的ICMPv6的前几个字段,因此我在C ++端创建了一个ICMPv6类(使用ICMPv6Unknown)。

My problem is that although they can work fine with the fields of ICMPv6, the plen field in IPv6 does not update correctly according to the type I put in the ICMPv6 header. 我的问题是,尽管它们可以与ICMPv6的字段配合使用,但是IPv6中的plen字段无法根据我放入ICMPv6标头中的类型正确更新。

I am not sure what can i edit in the IPv6 class to make it change the field according to what ICMPv6 type is next, right now it does: 我不确定我可以在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

Which fails because ICMPv6Unknown returns len of 4, so it doesn't change size according to my type field. 失败是因为ICMPv6Unknown返回len的4,所以它不会根据我的type字段更改大小。 I know that Ether changes type according to fields but i couldn't reproduce this for ICMPv6 我知道以太会根据字段更改类型,但是我无法为ICMPv6复制它

To solve this I added an if to IPv6 that does not use len(p) in this case, in the following way: 为了解决这个问题,我在这种情况下向IPv6添加了一个if,它不使用len(p),方式如下:

    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

where icmpv6_len statically returns the length of the type. 其中icmpv6_len静态返回类型的长度。

I solved this by overloading build_payload() thus: 我通过重载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()

This basically re-parses the first two fields in the ICMPv6Unknown layer as the layer that we want. 基本上,这会将ICMPv6Unknown层中的前两个字段重新解析为所需的层。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM