1
2
3 """Dynamic Host Configuration Protocol."""
4 from __future__ import print_function
5 from __future__ import absolute_import
6
7 import struct
8
9 from . import arp
10 from . import dpkt
11 from .compat import compat_ord
12
13 DHCP_OP_REQUEST = 1
14 DHCP_OP_REPLY = 2
15
16 DHCP_MAGIC = 0x63825363
17
18
19 DHCP_OPT_NETMASK = 1
20 DHCP_OPT_TIMEOFFSET = 2
21 DHCP_OPT_ROUTER = 3
22 DHCP_OPT_TIMESERVER = 4
23 DHCP_OPT_NAMESERVER = 5
24 DHCP_OPT_DNS_SVRS = 6
25 DHCP_OPT_LOGSERV = 7
26 DHCP_OPT_COOKIESERV = 8
27 DHCP_OPT_LPRSERV = 9
28 DHCP_OPT_IMPSERV = 10
29 DHCP_OPT_RESSERV = 11
30 DHCP_OPT_HOSTNAME = 12
31 DHCP_OPT_BOOTFILESIZE = 13
32 DHCP_OPT_DUMPFILE = 14
33 DHCP_OPT_DOMAIN = 15
34 DHCP_OPT_SWAPSERV = 16
35 DHCP_OPT_ROOTPATH = 17
36 DHCP_OPT_EXTENPATH = 18
37 DHCP_OPT_IPFORWARD = 19
38 DHCP_OPT_SRCROUTE = 20
39 DHCP_OPT_POLICYFILTER = 21
40 DHCP_OPT_MAXASMSIZE = 22
41 DHCP_OPT_IPTTL = 23
42 DHCP_OPT_MTUTIMEOUT = 24
43 DHCP_OPT_MTUTABLE = 25
44 DHCP_OPT_MTUSIZE = 26
45 DHCP_OPT_LOCALSUBNETS = 27
46 DHCP_OPT_BROADCASTADDR = 28
47 DHCP_OPT_DOMASKDISCOV = 29
48 DHCP_OPT_MASKSUPPLY = 30
49 DHCP_OPT_DOROUTEDISC = 31
50 DHCP_OPT_ROUTERSOLICIT = 32
51 DHCP_OPT_STATICROUTE = 33
52 DHCP_OPT_TRAILERENCAP = 34
53 DHCP_OPT_ARPTIMEOUT = 35
54 DHCP_OPT_ETHERENCAP = 36
55 DHCP_OPT_TCPTTL = 37
56 DHCP_OPT_TCPKEEPALIVE = 38
57 DHCP_OPT_TCPALIVEGARBAGE = 39
58 DHCP_OPT_NISDOMAIN = 40
59 DHCP_OPT_NISSERVERS = 41
60 DHCP_OPT_NISTIMESERV = 42
61 DHCP_OPT_VENDSPECIFIC = 43
62 DHCP_OPT_NBNS = 44
63 DHCP_OPT_NBDD = 45
64 DHCP_OPT_NBTCPIP = 46
65 DHCP_OPT_NBTCPSCOPE = 47
66 DHCP_OPT_XFONT = 48
67 DHCP_OPT_XDISPLAYMGR = 49
68 DHCP_OPT_REQ_IP = 50
69 DHCP_OPT_LEASE_SEC = 51
70 DHCP_OPT_OPTIONOVERLOAD = 52
71 DHCP_OPT_MSGTYPE = 53
72 DHCP_OPT_SERVER_ID = 54
73 DHCP_OPT_PARAM_REQ = 55
74 DHCP_OPT_MESSAGE = 56
75 DHCP_OPT_MAXMSGSIZE = 57
76 DHCP_OPT_RENEWTIME = 58
77 DHCP_OPT_REBINDTIME = 59
78 DHCP_OPT_VENDOR_ID = 60
79 DHCP_OPT_CLIENT_ID = 61
80 DHCP_OPT_NISPLUSDOMAIN = 64
81 DHCP_OPT_NISPLUSSERVERS = 65
82 DHCP_OPT_MOBILEIPAGENT = 68
83 DHCP_OPT_SMTPSERVER = 69
84 DHCP_OPT_POP3SERVER = 70
85 DHCP_OPT_NNTPSERVER = 71
86 DHCP_OPT_WWWSERVER = 72
87 DHCP_OPT_FINGERSERVER = 73
88 DHCP_OPT_IRCSERVER = 74
89 DHCP_OPT_STSERVER = 75
90 DHCP_OPT_STDASERVER = 76
91
92
93 DHCPDISCOVER = 1
94 DHCPOFFER = 2
95 DHCPREQUEST = 3
96 DHCPDECLINE = 4
97 DHCPACK = 5
98 DHCPNAK = 6
99 DHCPRELEASE = 7
100 DHCPINFORM = 8
101
102
103 -class DHCP(dpkt.Packet):
104 """Dynamic Host Configuration Protocol.
105
106 TODO: Longer class information....
107
108 Attributes:
109 __hdr__: Header fields of DHCP.
110 TODO.
111 """
112
113 __hdr__ = (
114 ('op', 'B', DHCP_OP_REQUEST),
115 ('hrd', 'B', arp.ARP_HRD_ETH),
116 ('hln', 'B', 6),
117 ('hops', 'B', 0),
118 ('xid', 'I', 0xdeadbeef),
119 ('secs', 'H', 0),
120 ('flags', 'H', 0),
121 ('ciaddr', 'I', 0),
122 ('yiaddr', 'I', 0),
123 ('siaddr', 'I', 0),
124 ('giaddr', 'I', 0),
125 ('chaddr', '16s', 16 * b'\x00'),
126 ('sname', '64s', 64 * b'\x00'),
127 ('file', '128s', 128 * b'\x00'),
128 ('magic', 'I', DHCP_MAGIC),
129 )
130 opts = (
131 (DHCP_OPT_MSGTYPE, chr(DHCPDISCOVER)),
132 (DHCP_OPT_PARAM_REQ, ''.join(map(chr, (DHCP_OPT_REQ_IP,
133 DHCP_OPT_ROUTER,
134 DHCP_OPT_NETMASK,
135 DHCP_OPT_DNS_SVRS))))
136 )
137
141
144
146 """Return packed options string."""
147 if not self.opts:
148 return b''
149 l = []
150 for t, data in self.opts:
151 l.append(struct.pack("BB%is"%len(data), t, len(data), data))
152 l.append(b'\xff')
153 return b''.join(l)
154
156 dpkt.Packet.unpack(self, buf)
157 self.chaddr = self.chaddr[:self.hln]
158 buf = self.data
159 l = []
160 while buf:
161 t = compat_ord(buf[0])
162 if t == 0xff:
163 buf = buf[1:]
164 break
165 elif t == 0:
166 buf = buf[1:]
167 else:
168 n = compat_ord(buf[1])
169 l.append((t, buf[2:2 + n]))
170 buf = buf[2 + n:]
171 self.opts = l
172 self.data = buf
173
174
176 s = b'\x01\x01\x06\x00\xadS\xc8c\xb8\x87\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02U\x82\xf3\xa6\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00c\x82Sc5\x01\x01\xfb\x01\x01=\x07\x01\x00\x02U\x82\xf3\xa62\x04\n\x00\x01e\x0c\tGuinevere<\x08MSFT 5.07\n\x01\x0f\x03\x06,./\x1f!+\xff\x00\x00\x00\x00\x00'
177 dhcp = DHCP(s)
178 assert (s == bytes(dhcp))
179 assert isinstance(dhcp.chaddr, bytes)
180 assert isinstance(dhcp.sname, bytes)
181 assert isinstance(dhcp.file, bytes)
182
183
184 dhcp = DHCP()
185 assert isinstance(dhcp.chaddr, bytes)
186 assert isinstance(dhcp.sname, bytes)
187 assert isinstance(dhcp.file, bytes)
188
189 if __name__ == '__main__':
190 test_dhcp()
191 print('Tests Successful...')
192