new tool
[hband-tools.git] / admin-tools / dhcpdiscover
blob3676443736d6d0aec9228151870fe1e2479652c0
1 #!/usr/bin/env python
3 from __future__ import print_function
4 import random
5 from scapy.all import conf, Ether, IP, UDP, BOOTP, DHCP, DHCPTypes, sendp, srp, mac2str, str2mac, get_if_hwaddr
6 import sys
7 import re
10 def fmt_dhcpoptval(name, val):
11 if name == 'message-type':
12 val = DHCPTypes[int(val)]
13 return esc_nonprint(val)
15 def fmt_bootpfield(bootp, name, val):
16 if name == 'chaddr':
17 val = str2mac(val[0:bootp.hlen])
18 elif name in ['sname', 'file']:
19 val = val[0:val.find('\x00')]
20 return esc_nonprint(val)
22 def esc_nonprint(s):
23 return re.sub(r'[\x00-\x1F\\\x7F-\xFF]', lambda m: "\\x%02X" % ord(m.group(0)), s)
25 def stringy(x):
26 if isinstance(x, str):
27 return x
28 elif isinstance(x, bytes):
29 # latin1 decodes any octet.
30 return x.decode('iso-8859-1')
31 elif isinstance(x, int):
32 return str(x)
33 return str(x)
36 if len(sys.argv) < 2 or sys.argv[1] == '--help':
37 print("""Usage: dhcpdiscover <IFACE> [<TIMEOUT>]
38 send DHCP discover messages on the IFACE interface,
39 and print response message's details, if gets one within TIMEOUT seconds.
40 It does not configure any interface, nor store state, nor go into daemon.
41 """, end='')
42 sys.exit(1)
44 iface = sys.argv[1]
45 try:
46 timeout = float(sys.argv[2])
47 except:
48 timeout = 1.0
50 packet = (
51 Ether(dst="ff:ff:ff:ff:ff:ff") /
52 IP(src="0.0.0.0", dst="255.255.255.255") /
53 UDP(sport=68, dport=67) /
54 BOOTP(chaddr=mac2str(get_if_hwaddr(iface)), xid=random.randint(1, 2**32-1)) /
55 DHCP(options=[("message-type", "discover"), "end"])
58 conf.checkIPaddr = False
59 ans, unans = srp(packet, iface=iface, verbose=0, timeout=timeout, nofilter=1)
61 try:
62 reply = ans.res[0][1]
63 except IndexError:
64 print("no reply", file=sys.stderr)
65 sys.exit(2)
67 bootp_msg = reply.getlayer(BOOTP)
68 dhcp_msg = reply.getlayer(DHCP)
70 print(''.join(["%s\t%s\n" % (field, fmt_bootpfield(bootp_msg, field, stringy(val))) for field, val in bootp_msg.fields.items()]), end='')
72 #dhcp_options = dict([x for x in dhcp_msg.options if isinstance(x, tuple)])
73 #dhcp_message_type = DHCPTypes[dhcp_options['message-type']]
74 dhcp_options = [x for x in dhcp_msg.options if isinstance(x, tuple) and len(x) == 2]
75 print(''.join(["option.%s\t%s\n" % (optname, fmt_dhcpoptval(optname, stringy(optval))) for optname, optval in dhcp_options]), end='')