Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scapy : IPv6 Packet is receiving as Raw Packet

Tags:

ipv6

scapy

I am trying establish TCP handshake for IPv6. SYN packet is sent. SYN/ACK is received at interface.

I did hexdump of the packet received and also pkt.show(). I got the following output:

hexdump(pkt)
    0000   00 30 48 FA 2C 4D 64 64  9B 75 60 01 81 00 00 01   .0H.,Mdd.u`.....
    0010   81 00 00 01 88 64 11 00  00 01 00 42 00 57 60 00   .....d.....B.W`.
    0020   00 00 00 18 06 40 20 11  00 01 00 00 00 00 00 00   .....@ .........
    0030   00 00 00 00 00 01 20 11  00 01 00 00 00 00 00 00   ...... .........
    0040   00 00 00 00 00 02 00 50  A1 F0 00 00 00 01 00 00   .......P........
    0050   00 01 60 12 FF FE B5 CA  00 00 02 04 05 98         ..`...........

    pkt.show()
    ###[ Ethernet ]###
      dst       = 00:30:48:fa:2c:4d
      src       = 64:64:9b:75:60:01
      type      = 0x8100
    ###[ 802.1Q ]###
     prio      = 0L
     id        = 0L
     vlan      = 1L
     type      = 0x8100
    ###[ 802.1Q ]###
        prio      = 0L
        id        = 0L
        vlan      = 1L
        type      = 0x8864
    ###[ PPP over Ethernet ]###
           version   = 1L
           type      = 1L
           code      = Session
           sessionid = 0x1
           len       = 66
    ###[ PPP Link Layer ]###
              proto     = Internet Protocol version 6 [Hinden]
    ###[ Raw ]###
                 load      = '`\x00\x00\x00\x00\x18\x06@   \x11\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01 \x11\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00P\xa1\xf0\x00\x00\x00\x01\x00\x00\x00\x01`\x12\xff\xfe\xb5\xca\x00\x00\x02\x04\x05\x98'

Why IPv6 packet is coming as raw packet?

like image 934
user1385290 Avatar asked Dec 11 '25 19:12

user1385290


1 Answers

This looks like a bug in Scapy, probably in the PPP disector. Some diagnostics and a workaround follow.

We can reproduce your bug with:

import binascii

input=binascii.unhexlify("003048FA2C4D64649B756001810000018100000188641100000100420057600000000018064020110001000000000000000000000001201100010000000000000000000000020050A1F000000001000000016012FFFEB5CA000002040598")

from scapy.all import Ether

pkt1=Ether(input)

# Stops at "RAW" after PPP transport
pkt1.show()

If we take it a bit further and inspect the Raw layer it looks like a real IPv6 packet though. We can validate this using scapy by doing:

import binascii

input=binascii.unhexlify("003048FA2C4D64649B756001810000018100000188641100000100420057600000000018064020110001000000000000000000000001201100010000000000000000000000020050A1F000000001000000016012FFFEB5CA000002040598")

from scapy.all import Ether, IPv6, Raw

pkt1=Ether(input)

# Check the rest of the parsing makes sense:
pkt2=IPv6(pkt1[Raw].load)

# Pkt2 is just the IPv6 bit now
pkt2.show()

Finally we can take this to its logical conclusion and use this to generate a Scapy packet with all the right layers:

import binascii

input=binascii.unhexlify("003048FA2C4D64649B756001810000018100000188641100000100420057600000000018064020110001000000000000000000000001201100010000000000000000000000020050A1F000000001000000016012FFFEB5CA000002040598")

from scapy.all import Ether, IPv6, Raw

pkt1=Ether(input)
pkt2=IPv6(pkt1[Raw].load)

del pkt1[Raw]
pkt1=(pkt1/pkt2)
pkt1.show()

Which then gives us:

###[ Ethernet ]###
  dst       = 00:30:48:fa:2c:4d
  src       = 64:64:9b:75:60:01
  type      = n_802_1Q
###[ 802.1Q ]###
     prio      = 0L
     id        = 0L
     vlan      = 1L
     type      = n_802_1Q
###[ 802.1Q ]###
        prio      = 0L
        id        = 0L
        vlan      = 1L
        type      = PPP_SES
###[ PPP over Ethernet ]###
           version   = 1L
           type      = 1L
           code      = Session
           sessionid = 0x1
           len       = 66
###[ PPP Link Layer ]###
              proto     = Internet Protocol version 6 [Hinden]
###[ IPv6 ]###
                 version   = 6L
                 tc        = 0L
                 fl        = 0L
                 plen      = 24
                 nh        = TCP
                 hlim      = 64
                 src       = 2011:1::1
                 dst       = 2011:1::2
###[ TCP ]###
                    sport     = http
                    dport     = 41456
                    seq       = 1
                    ack       = 1
                    dataofs   = 6L
                    reserved  = 0L
                    flags     = SA
                    window    = 65534
                    chksum    = 0xb5ca
                    urgptr    = 0
                    options   = [('MSS', 1432)]

A better workaround though is to tell Scapy about the relationship between the layers themselves, using the following:

import binascii

input=binascii.unhexlify("003048FA2C4D64649B756001810000018100000188641100000100420057600000000018064020110001000000000000000000000001201100010000000000000000000000020050A1F000000001000000016012FFFEB5CA000002040598")

from scapy.all import Ether, IPv6, PPP, bind_layers

bind_layers( PPP,           IPv6,            proto=0x0057)

# Now works correctly out the box
pkt1=Ether(input)
pkt1.show()

This call to bind_layers should be in scapy/layers/ppp.py if you felt like writing a proper patch.

like image 194
Flexo Avatar answered Dec 15 '25 19:12

Flexo



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!