5

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?

José Tomás Tocino
  • 9,873
  • 5
  • 44
  • 78
  • 1
    I'm curious if you get helpful answers to this. I can't tell that scapy does anything more "organized" than what you're doing now. The problem is that DHCP just throws a list of options into the bootp payload. No specific options are required, and no specific ordering is required. It's possible to have multiple options of the same type (routers, DNS servers, etc), so there's no obvious dict-type framework that works. It doesn't really make sense to have more than one message-type and that's *often* going to be first but nothing says it has to be. – Gil Hamilton Dec 05 '17 at 00:38

1 Answers1

2

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.

Pierre
  • 6,047
  • 1
  • 30
  • 49