Milad
Milad

Reputation: 11

Get values from custom packet in IP option fields in scapy

I want to get the value of some fields in my scapy code for receiving packets, but I don't know how to do it exactly. When I print the value, I get the error that the layer is not defined or AttributeError: 'NoneType' object has no attribute 'proto'

class TELEMETRY(IPOption):
    name = "TELEMETRY"
    option = 31
    fields_desc = [ _IPOption_HDR,
            ByteField("length", 2),
            Emph(SourceIPField("src", "dst")),
            Emph(DestIPField("dst", "127.0.0.1")),
            ShortEnumField("sport", 20, TCP_SERVICES),
            ShortEnumField("dport", 80, TCP_SERVICES),
            ByteEnumField("proto", 0, IP_PROTOS),
            BitField("timeTaken", 0, 32),
            BitField("egress_timestamp", 0, 48),
            BitField("enqQdepth", 0, 19),
            BitField("deqQdepth", 0, 19),
            BitField("padding", 0, 2) ]

I can access the IP packet within the code blow but when I want to access the telemetry fields in my custom fields, I get error AttributeError: 'NoneType' object has no attribute 'proto'

def handle_pkt(pkt):
    
        
        ip_src=pkt[IP].src
        ip_dst=pkt[IP].dst
        ip_ver=pkt[IP].version
        ip_id=pkt[IP].id
        telemetry = pkt.getlayer(TELEMETRY)
        

        print ip_src,ip_dst,ip_ver,ip_id, telemetry.proto
        os.system(" echo %s %s %s %s %s| nc localhost 6666" % (ip_src,ip_dst,ip_ver,ip_id,telemetry.proto))

Here is the result of pkt.show2()

niffing on h4-eth0
got a packet
###[ Ethernet ]### 
 dst       = 08:00:00:00:02:00
 src       = ff:ff:ff:ff:ff:ff
 type      = IPv4
###[ IP ]### 
    version   = 4
    ihl       = 13
    tos       = 0x0
    len       = 172
    id        = 1
    flags     = 
    frag      = 0
    ttl       = 63
    proto     = tcp
    chksum    = 0x5efb
    src       = 192.168.1.1
    dst       = 192.168.3.3
    \options   \
     |###[ TELEMETRY ]### 
     |  copy_flag = 0
     |  optclass  = control
     |  option    = 31
     |  length    = 32
     |  src       = 192.168.1.1
     |  dst       = 192.168.3.3
     |  sport     = 64314
     |  dport     = 1234
     |  proto     = tcp
     |  timeTaken = 11
     |  egress_timestamp= 7740314797
     |  enqQdepth = 0
     |  deqQdepth = 0
     |  padding   = 0
###[ TCP ]### 
       sport     = 64314
       dport     = 1234
       seq       = 0
       ack       = 0
       dataofs   = 5
       reserved  = 0
       flags     = S
       window    = 8192
       chksum    = 0x2d40
       urgptr    = 0
       options   = ''

Any idea would be appreciated. :)

Upvotes: 1

Views: 1443

Answers (1)

fgagnaire
fgagnaire

Reputation: 898

getlayer

works when you want to get a sub layer. In you case, you want to get a layer inside a list. (IP.options is a list of layers)

the solution is then:

telemetry = pkt[IP].options[0]

now, for the option list might be empty for a variaty of reason, so you might want to:

if len(pkt[IP].options):
    telemetry = pkt[IP].options[0]
else:
    pass
    # deal with it

Carcigenicate Also pointed out that you might have more of those options in your packet, you may want to deal with that too.

Upvotes: 2

Related Questions