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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With