22##########################################################
33# ZTP (DHCP+TFTP+HTTP service)
44# Created by: Zdolinski Artur
5- # Version: 0.6 [20200925 ]
5+ # Version: 0.6a [20200927 ]
66#
77# if you need - you can disable cache (__pycache__)
88# > bash# export PYTHONDONTWRITEBYTECODE=1
3434os .environ ['PYTHONUNBUFFERED' ] = '1'
3535conf .sniff_promisc = True
3636
37+
38+ # handle_dhcp_packet(packet)
39+ # get_option(dhcp_options, key)
40+ # threaded(fn)
41+ # handler(signal_received, frame)
42+ # chaddr_to_mac(chaddr)
43+ # op43(text_value)
44+
3745def handle_dhcp_packet (packet ):
3846 if DHCP in packet :
3947 # Write PCAP File if needed
@@ -52,7 +60,7 @@ def handle_dhcp_packet(packet):
5260 chaddr = packet [BOOTP ].chaddr
5361 src_mac = packet [Ether ].src
5462 dhcp_src_mac = chaddr_to_mac (chaddr )
55-
63+
5664 # Direction
5765 if packet [Ether ].src == kwargs ['my_mac' ]:
5866 direction = colored (kwargs ['interface' ]+ "| ->[Snd]" , 'green' )
@@ -74,7 +82,7 @@ def handle_dhcp_packet(packet):
7482
7583 # Match DHCP Message Type = Replay (2)
7684 elif DHCP_message_type == 2 :
77- subnet_mask = get_option (packet [DHCP ].options , 'subnet_mask' )
85+ # subnet_mask = get_option(packet[DHCP].options, 'subnet_mask')
7886 lease_time = get_option (packet [DHCP ].options , 'lease_time' )
7987 router = get_option (packet [DHCP ].options , 'router' )
8088 name_server = get_option (packet [DHCP ].options , 'name_server' )
@@ -102,7 +110,11 @@ def handle_dhcp_packet(packet):
102110 # Match DHCP Message Type = Ack (5)
103111 elif DHCP_message_type == 5 :
104112 print (direction + colored ('[Ack][' + str (hex (xid ))+ '] ' , 'yellow' ) + "DHCP Server " + packet [IP ].src + " (" + src_mac + ") acked " + packet [BOOTP ].yiaddr )
105-
113+
114+ # Match DHCP Message Type = Release (7)
115+ elif DHCP_message_type == 7 :
116+ print (direction + colored ('[Release][' + str (hex (xid ))+ '] ' , 'red' ) + 'DHCP Release from (' + dhcp_src_mac + ') - IP: ' + str (packet [BOOTP ].ciaddr ) )
117+
106118 # Match DHCP Message Type = Inform (8)
107119 elif DHCP_message_type == 8 :
108120 vendor_class_id = get_option (packet [DHCP ].options , 'vendor_class_id' )
@@ -155,6 +167,26 @@ def chaddr_to_mac(chaddr):
155167 mac_format_fix = ":" .join (map ("{0:0>2}" .format , mac_format .split (':' )))
156168 return str (mac_format_fix )
157169
170+ def op43 (text_value ):
171+ ret = b""
172+ xparam = text_value .replace (" " ,"" ).split ("," )
173+ for param in xparam :
174+ p = param .split (":" )
175+ try :
176+ p [1 ]
177+ except :
178+ return
179+ tag = int (p [0 ])
180+ value = p [1 ]
181+ ret += struct .pack ("BB" , tag , len (str (value ))) + str (value ).encode ()
182+ ret += struct .pack ("B" , 255 )
183+ return (ret )
184+
185+ # DhcpResponder
186+ # -> __init__(self)
187+ # -> get_parameters(self, path)
188+ # -> send_offer(self, packet, offer)
189+ # -> send_ack(self, packet, offer)
158190class DhcpResponder (object ):
159191 def __init__ (self ):
160192 pass
@@ -282,6 +314,11 @@ def send_ack(self, packet, offer):
282314 packet = ethernet / ip / udp / bootp / dhcp
283315 sendp (packet , iface = kwargs ['interface' ], verbose = False )
284316
317+
318+ # HttpServer(object)
319+ # -> __init__(self, port=80, **kwargs)
320+ # -> start(self)
321+ # -> stop(self)
285322class HttpServer (object ):
286323 def __init__ (self , port = 80 , ** kwargs ):
287324 self .port = int (kwargs ['port_http' ])
@@ -315,6 +352,10 @@ def stop(self):
315352 self .httpd .shutdown ()
316353 return
317354
355+ # TftpServer(object)
356+ # -> __init__(self, port=69, **kwargs)
357+ # -> stop(self)
358+ # -> start(self)
318359class TftpServer (object ):
319360 def __init__ (self , port = 69 , ** kwargs ):
320361 self .port = int (kwargs ['port_tftp' ])
@@ -335,21 +376,9 @@ def start(self):
335376 except OSError :
336377 print (colored ('[Warning] ' , 'red' ) + 'TFTP ' + str (self .my_ip )+ ':' + str (self .port )+ ' port in use' )
337378
338- def op43 (text_value ):
339- ret = b""
340- xparam = text_value .replace (" " ,"" ).split ("," )
341- for param in xparam :
342- p = param .split (":" )
343- try :
344- p [1 ]
345- except :
346- return
347- tag = int (p [0 ])
348- value = p [1 ]
349- ret += struct .pack ("BB" , tag , len (str (value ))) + str (value ).encode ()
350- ret += struct .pack ("B" , 255 )
351- return (ret )
352-
379+ ############
380+ ### MAIN ###
381+ ############
353382if __name__ == "__main__" :
354383 signal (SIGINT , handler )
355384 while True :
0 commit comments