Coverage for /root/GitHubProjects/impacket/impacket/dhcp.py : 32%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# Impacket - Collection of Python classes for working with network protocols.
2#
3# SECUREAUTH LABS. Copyright (C) 2019 SecureAuth Corporation. All rights reserved.
4#
5# This software is provided under a slightly modified version
6# of the Apache Software License. See the accompanying LICENSE file
7# for more information.
8#
10from impacket import structure
11from impacket.ImpactPacket import ProtocolPacket
13class BootpPacket(ProtocolPacket, structure.Structure):
14 commonHdr = (
15 ('op','b'),
16 ('htype','b=1'), # 1 = Ether
17 ('hlen','b=len(chaddr)'),
18 ('hops','b=0'),
19 ('xid','!L=0'),
20 ('secs','!H=0'),
21 ('flags','!H=0'),
22 ('ciaddr','!L=0'),
23 ('yiaddr','!L=0'),
24 ('siaddr','!L=0'),
25 ('giaddr','!L=0'),
26 ('_chaddr','16s=chaddr'),
27 ('chaddr','_','_chaddr[:hlen]'),
28 ('sname','64s=""'),
29 ('file','128s=""'))
31 def __init__(self, data = None, alignment = 0):
32 structure.Structure.__init__(self, data, alignment)
34class DhcpPacket(ProtocolPacket, structure.Structure):
35 # DHCP: https://www.ietf.org/rfc/rfc2131.txt
36 # DHCP Options: https://www.ietf.org/rfc/rfc1533.txt
37 # good list of options: http://www.networksorcery.com/enp/protocol/bootp/options.htm
38 MAGIC_NUMBER = 0x63825363
39 BOOTREQUEST = 1
40 BOOTREPLY = 2
42 DHCPDISCOVER= 1
43 DHCPOFFER = 2
44 DHCPREQUEST = 3
45 DHCPDECLINE = 4
46 DHCPACK = 5
47 DHCPNAK = 6
48 DHCPRELEASE = 7
49 DHCPINFORM = 8
51 options = {
52 # 3. Vendor Extensions
53 'pad':(0,'_'),
54 'subnet-mask':(1,'!L'),
55 'time-offset':(2,'!L'),
56 'router':(3,'*!L'),
57 'time-server':(4,'*!L'),
58 'name-server':(5,'*!L'),
59 'domain-name-server':(6,'*!L'),
60 'log-server':(7,'*!L'),
61 'cookie-server':(8,'*!L'),
62 'lpr-server':(9,'*!L'),
63 'impress-server':(10,'*!L'),
64 'resource-locator-server':(11,'*!L'),
65 'host-name':(12,':'),
66 'boot-file-size':(13,'!H'),
67 'merit-dump-file':(14,':'),
68 'domain-name':(15,':'),
69 'swap-server':(16,':'),
70 'root-path':(17,':'),
71 'extensions-path':(18,':'),
73 # 4. IP Layer Parameters per Host
74 'ip-forwarding':(19,'B'),
75 'non-local-source-routing':(20,'B'),
76 'policy-filter':(21,'*!L'),
77 'maximum-datagram-reassembly-size':(22,'!H'),
78 'default-ip-ttl':(23,'B'),
79 'path-mtu-aging-timeout':(24,'!L'),
80 'path-mtu-plateau-table':(25,'*!H'),
82 # 5. IP Layer Parameters per Interface
83 'interface-mtu':(26,'!H'),
84 'all-subnets-are-local':(27,'B'),
85 'broadcast-address':(28,'!L'),
86 'perform-mask-discovery':(29,'B'),
87 'mask-supplier':(30,'B'),
88 'perform-router-discovery':(31,'B'),
89 'router-solicitation-address':(32,'!L'),
90 'static-route':(33,'*!L'),
92 # 6. Link Layer Parameters per Interface
93 'trailer-encapsulation':(34,'B'),
94 'arp-cache-timeout':(35,'!L'),
95 'ethernet-encapsulation':(36,'B'),
97 # 7. TCP parameters
98 'tcp-default-ttl':(37,'B'),
99 'tcp-keepalive-interval':(38,'!L'),
100 'tcp-keepalive-garbage':(39,'B'),
102 # 8. Application and Service parameters
103 'nis-domain':(40,':'),
104 'nis-servers':(41,'*!L'),
105 'ntp-servers':(42,'*!L'),
106 'vendor-specific':(43,':'),
107 'netbios-name-server':(44,'*!L'),
108 'netbios-datagrame-distribution-server':(45,'*!L'),
109 'netbios-node-type':(46,'B'),
110 'netbios-scope':(47,':'),
111 'x11-font-server':(48,'*!L'),
112 'x11-display-manager':(49,'*!L'),
115 # 9. DHCP Extensions
116 'requested-ip':(50,'!L'),
117 'lease-time':(51,'!L'),
118 'option-overload':(52,'B'),
119 'message-type':(53,'B'),
120 'server-id':(54,'!L'),
121 'parameter-request-list':(55,':'),
122 'message':(56,':'),
123 'maximum-dhcp-message-size':(57,'!H'),
124 'renewal-time':(58,'!L'),
125 'rebinding-time':(59,'!L'),
126 'vendor-class':(60,':'),
127 'client-id':(61,':'),
129 # other non-rfc1533 options
130 'slp-directory-agent':(78,':'), # https://www.ietf.org/rfc/rfc2610.txt
131 'slp-service-scope':(79,':'), # https://www.ietf.org/rfc/rfc2610.txt
132 'fully-qualified-domain-name':(81,':'), # https://www.ietf.org/rfc/rfc4702.txt
133 'default-url': (114, ':'), # text (URL) - not defined in any RFC but assigned by IANA
134 'auto-configuration':(116,'B'), # https://www.ietf.org/rfc/rfc2563.txt
135 'domain-search-list':(119,':'), # https://www.ietf.org/rfc/rfc3397.txt
136 'classless-route-121':(121, ':'), # https://www.ietf.org/rfc/rfc3442.txt
137 'classless-route-249':(249, ':'), # https://web.archive.org/web/20140205135249/support.microsoft.com/kb/121005
138 'proxy-autoconfig':(252,':'),
139 'eof':(255,'_'),
140 }
142 structure = (
143 ('cookie','!L'),
144 ('_options',':=self.packOptions(options)'),
145 ('options','_','self.unpackOptions(_options)'))
147 def __init__(self, data = None, alignment = 0):
148 structure.Structure.__init__(self, data, alignment)
150 def packOptions(self, options):
151 # options is an array of tuples: ('name',value)
153 answer = ''
154 for name, value in options:
155 code,format = self.options[name]
156 val = self.pack(format, value)
157 answer += '%c%c%s' % (code, len(val), val)
159 return answer
161 def getOptionNameAndFormat(self, optionCode):
162 for k in self.options:
163 code,format = self.options[k]
164 if code == optionCode: return k, format
165 return optionCode, ':'
167 def unpackOptions(self, options):
168 # options is a string
170 # print '%r' % options
171 answer = []
172 i = 0
173 while i < len(options)-1:
174 name, format = self.getOptionNameAndFormat(ord(options[i]))
175 # size = self.calcUnpackSize(format, options[i+1:])
176 size = ord(options[i+1])
177 # print i, name, format, size
178 value = self.unpack(format, options[i+2:i+2+size])
179 answer.append((name, value))
180 i += 2+size
182 return answer
184 def unpackParameterRequestList(self, options):
185 return [self.getOptionNameAndFormat(ord(opt))[0] for opt in options]
187 def isAskingForProxyAutodiscovery(self):
188 for opt in self.fields['options']:
189 if opt[0] == 'parameter-request-list':
190 for optCode in opt[1]:
191 if ord(optCode) == 252:
192 return True
193 return False
195 def getOptionValue(self, name):
196 for opt in self.fields['options']:
197 if opt[0] == name:
198 return opt[1]
199 return None