Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scapy: check the message type of a captured DHCP packet

I'm totally new to scapy, I'm trying to use it to build a DHCP monitor for my LAN. I'm using sniff to capture packets that are sent to a callback via the prn= parameter. Inside the callback, I check if the packet has the DHCP layer and then I check the type of request.

I'm currently doing it like this:

def manage(pkt):
    if pkt.haslayer(DHCP):
        req_type = [x[1] for x in pkt[DHCP].options if x[0] == 'message-type'][0]

        # Message type: request
        if req_type == 3:
            print ("Request from {}".format(pkt[Ether].src))

sniff(prn=manage, count=0, store=0)

The way I'm accessing the options in the DHCP layer is kind of awkward, but it's the only one I've come up with that works. However I believe there must be a better, more pythonic way, like via a dict or something.

What's the appropriate way of accessing those options?

like image 428
José Tomás Tocino Avatar asked Oct 28 '22 22:10

José Tomás Tocino


1 Answers

I think this is the almost the most efficient way to do what you want. I would use next() and a generator expression rather than a list, to avoid parsing the whole options list when it's not necessary:

req_type = next(opt[1] for opt in pkt[DHCP].options if isinstance(opt, tuple) and opt[0] == 'message-type')

Note that I've also added a check against the type of opt, as some are string objects.

You could use a dict() but you would then have, again, to parse the whole options list.

As a side note, the way DHCP options are handled in Scapy is a bit old and the correct way to do that now would probably be to use a PacketListField with cleaner methods to access the options.

like image 67
Pierre Avatar answered Nov 08 '22 18:11

Pierre