Создание поля IPv6 update plen в соответствии с типом ICMPv6 в Scapy

В моей программе я использую scapy для создания/анализа пакетов, но фактическая программа написана на C++. Поскольку пользователям нужны только первые несколько полей ICMPv6, которые одинаковы для всех пакетов ICMPv6, я создал один класс ICMPv6 (используя ICMPv6Unknown) на стороне C++.

Моя проблема в том, что, хотя они могут нормально работать с полями ICMPv6, поле plen в IPv6 не обновляется правильно в соответствии с типом, который я указал в заголовке 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.


person gil_bz    schedule 31.03.2013    source источник


Ответы (2)


Чтобы решить эту проблему, я добавил if в IPv6, который в данном случае не использует 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

где icmpv6_len статически возвращает длину типа.

person gil_bz    schedule 07.04.2013
comment
В конце концов, это решение оказалось проблемой, поскольку оно плохо обрабатывает полезную нагрузку. - person gil_bz; 08.04.2013

Я решил это, перегрузив 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 как уровень, который нам нужен.

person gil_bz    schedule 08.04.2013