From 28e570cf4261c0d631c71b71644005ba62db0c39 Mon Sep 17 00:00:00 2001 From: Adriano Date: Fri, 23 Oct 2020 11:50:01 -0700 Subject: [PATCH 01/29] feat: reading IPv6 header successfully! --- Packet-Sniffer.py | 144 ++++++++++++++++++++++++++++++---------------- 1 file changed, 95 insertions(+), 49 deletions(-) diff --git a/Packet-Sniffer.py b/Packet-Sniffer.py index 82918fe..5b84f08 100644 --- a/Packet-Sniffer.py +++ b/Packet-Sniffer.py @@ -24,55 +24,101 @@ def main(): print(TAB_1 + 'Destination: {}, Source: {}, Protocol: {}'.format(dest_mac, src_mac, eth_proto)) if eth_proto == 8: - (version, header_length, ttl, proto, src, target, data) = ipv4_Packet(data) - print(TAB_1 + "IPV4 Packet:") - print(TAB_2 + 'Version: {}, Header Length: {}, TTL: {}'.format(version, header_length, ttl)) - print(TAB_3 + 'protocol: {}, Source: {}, Target: {}'.format(proto, src, target)) - - # ICMP - if proto == 1: - icmp_type, code, checksum, data = icmp_packet(data) - print(TAB_1 + 'ICMP Packet:') - print(TAB_2 + 'Type: {}, Code: {}, Checksum: {},'.format(icmp_type, code, checksum)) - print(TAB_2 + 'ICMP Data:') - print(format_output_line(DATA_TAB_3, data)) - - # TCP - elif proto == 6: - src_port, dest_port, sequence, acknowledgment, flag_urg, flag_ack, flag_psh, flag_rst, flag_syn, flag_fin = struct.unpack( - '! H H L L H H H H H H', raw_data[:24]) - print(TAB_1 + 'TCP Segment:') - print(TAB_2 + 'Source Port: {}, Destination Port: {}'.format(src_port, dest_port)) - print(TAB_2 + 'Sequence: {}, Acknowledgment: {}'.format(sequence, acknowledgment)) - print(TAB_2 + 'Flags:') - print(TAB_3 + 'URG: {}, ACK: {}, PSH: {}'.format(flag_urg, flag_ack, flag_psh)) - print(TAB_3 + 'RST: {}, SYN: {}, FIN:{}'.format(flag_rst, flag_syn, flag_fin)) - - if len(data) > 0: - # HTTP - if src_port == 80 or dest_port == 80: - print(TAB_2 + 'HTTP Data:') - try: - http = HTTP(data) - http_info = str(http.data).split('\n') - for line in http_info: - print(DATA_TAB_3 + str(line)) - except: - print(format_output_line(DATA_TAB_3, data)) - else: - print(TAB_2 + 'TCP Data:') - print(format_output_line(DATA_TAB_3, data)) - # UDP - elif proto == 17: - src_port, dest_port, length, data = udp_seg(data) - print(TAB_1 + 'UDP Segment:') - print(TAB_2 + 'Source Port: {}, Destination Port: {}, Length: {}'.format(src_port, dest_port, length)) - - # Other IPv4 - else: - print(TAB_1 + 'Other IPv4 Data:') - print(format_output_line(DATA_TAB_2, data)) - + pass + # (version, header_length, ttl, proto, src, target, data) = ipv4_Packet(data) + # print(TAB_1 + "IPV4 Packet:") + # print(TAB_2 + 'Version: {}, Header Length: {}, TTL: {}'.format(version, header_length, ttl)) + # print(TAB_3 + 'protocol: {}, Source: {}, Target: {}'.format(proto, src, target)) + + # # ICMP + # if proto == 1: + # icmp_type, code, checksum, data = icmp_packet(data) + # print(TAB_1 + 'ICMP Packet:') + # print(TAB_2 + 'Type: {}, Code: {}, Checksum: {},'.format(icmp_type, code, checksum)) + # print(TAB_2 + 'ICMP Data:') + # print(format_output_line(DATA_TAB_3, data)) + + # # TCP + # elif proto == 6: + # src_port, dest_port, sequence, acknowledgment, flag_urg, flag_ack, flag_psh, flag_rst, flag_syn, flag_fin = struct.unpack( + # '! H H L L H H H H H H', raw_data[:24]) + # print(TAB_1 + 'TCP Segment:') + # print(TAB_2 + 'Source Port: {}, Destination Port: {}'.format(src_port, dest_port)) + # print(TAB_2 + 'Sequence: {}, Acknowledgment: {}'.format(sequence, acknowledgment)) + # print(TAB_2 + 'Flags:') + # print(TAB_3 + 'URG: {}, ACK: {}, PSH: {}'.format(flag_urg, flag_ack, flag_psh)) + # print(TAB_3 + 'RST: {}, SYN: {}, FIN:{}'.format(flag_rst, flag_syn, flag_fin)) + + # if len(data) > 0: + # # HTTP + # if src_port == 80 or dest_port == 80: + # print(TAB_2 + 'HTTP Data:') + # try: + # http = HTTP(data) + # http_info = str(http.data).split('\n') + # for line in http_info: + # print(DATA_TAB_3 + str(line)) + # except: + # print(format_output_line(DATA_TAB_3, data)) + # else: + # print(TAB_2 + 'TCP Data:') + # print(format_output_line(DATA_TAB_3, data)) + # # UDP + # elif proto == 17: + # src_port, dest_port, length, data = udp_seg(data) + # print(TAB_1 + 'UDP Segment:') + # print(TAB_2 + 'Source Port: {}, Destination Port: {}, Length: {}'.format(src_port, dest_port, length)) + + # # Other IPv4 + # else: + # print(TAB_1 + 'Other IPv4 Data:') + # print(format_output_line(DATA_TAB_2, data)) + elif(eth_proto == 56710): + print("IPV6") + print("eth prot {}".format(eth_proto)) + print(data[:1]) + print("\ndata\n") + print(data) + first_32_bits, \ + payload_length,\ + next_header, \ + hop_limit = struct.unpack('! IHBB', data[:8]) + # version = struct.unpack('! B', data[:1]) + + version = first_32_bits >> 28 + traffic_class = (first_32_bits >> 20) & 255 + flow_label = first_32_bits & 1048575 + + # flow_label + # BITS + #4+8+20+16+8+8 + + print("First word") + print(bin(first_32_bits)) + print("Version") + print(version) + print("Traffic Class") + print(bin(traffic_class)) + print("Flow Label") + print(bin(flow_label)) + print("Payload Length") + print(bin(payload_length)) + print("Next Header") + print(next_header) + proto = next_header + print("Hop Limit") + print(bin(hop_limit)) + + # version = data[0] + # print(version) + # print("Not Converted") + # print(bin(version)) + # version = version >> 4 + # print("Converted") + # print(version) + input() + # version, traffic_class, flow_label, payload_length,next_header, hop_limit = struct.unpack('! H', data[:40]) + # ttl, proto, src, target = struct.unpack('! 8x B B 2x 4s 4s', data[:20]) else: print('Ethernet Data:') print(format_output_line(DATA_TAB_1, data)) From 17d5c76540e09172499acc041e2a2946a5385df9 Mon Sep 17 00:00:00 2001 From: Adriano Date: Fri, 23 Oct 2020 12:00:46 -0700 Subject: [PATCH 02/29] feat: reading src/dst ipv6 address --- Packet-Sniffer.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Packet-Sniffer.py b/Packet-Sniffer.py index 5b84f08..c742c63 100644 --- a/Packet-Sniffer.py +++ b/Packet-Sniffer.py @@ -109,6 +109,13 @@ def main(): print("Hop Limit") print(bin(hop_limit)) + src_address = socket.inet_ntop(socket.AF_INET6, data[8:24]) + dst_address = socket.inet_ntop(socket.AF_INET6, data[24:40]) + + print("Source Address") + print(src_address) + print("Dest Address") + print(dst_address) # version = data[0] # print(version) # print("Not Converted") From d5157d9dd613e2845c77f64c0313c95685155d04 Mon Sep 17 00:00:00 2001 From: Adriano Date: Fri, 23 Oct 2020 12:06:57 -0700 Subject: [PATCH 03/29] feat: barebones protocols recognition --- Packet-Sniffer.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/Packet-Sniffer.py b/Packet-Sniffer.py index c742c63..b5a97d3 100644 --- a/Packet-Sniffer.py +++ b/Packet-Sniffer.py @@ -116,6 +116,31 @@ def main(): print(src_address) print("Dest Address") print(dst_address) + + + #@TODO: Put UDP and TCP here as well (from IPv4 above) + + #Hop-by-Hop Options + if(next_header == 0 ): + pass + #Fragment + elif(next_header == 44 ): + pass + #Destination Options + elif(next_header == 60 ): + pass + #Routing + elif(next_header == 43 ): + pass + #Authentication + elif(next_header == 51 ): + pass + #Encapsulating Security Payload + elif(next_header == 50 ): + pass + #ICMPv6 + elif(next_header == 58 ): + pass # version = data[0] # print(version) # print("Not Converted") From 76e3c2c21ef0ecc092f9a7c7750212fddf8624f0 Mon Sep 17 00:00:00 2001 From: Adriano Date: Fri, 23 Oct 2020 13:49:51 -0700 Subject: [PATCH 04/29] feat: hop-by-hop options --- Packet-Sniffer.py | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/Packet-Sniffer.py b/Packet-Sniffer.py index b5a97d3..e417df9 100644 --- a/Packet-Sniffer.py +++ b/Packet-Sniffer.py @@ -117,29 +117,31 @@ def main(): print("Dest Address") print(dst_address) - + data = data[40:] #@TODO: Put UDP and TCP here as well (from IPv4 above) + # ORDER DEFINED ON RFC8200 #Hop-by-Hop Options if(next_header == 0 ): - pass - #Fragment - elif(next_header == 44 ): - pass + next_header, data = hop_by_hop_options(data) + # pass #Destination Options - elif(next_header == 60 ): + if(next_header == 60 ): pass #Routing - elif(next_header == 43 ): + if(next_header == 43 ): + pass + #Fragment + if(next_header == 44 ): pass #Authentication - elif(next_header == 51 ): + if(next_header == 51 ): pass #Encapsulating Security Payload - elif(next_header == 50 ): + if(next_header == 50 ): pass #ICMPv6 - elif(next_header == 58 ): + if(next_header == 58 ): pass # version = data[0] # print(version) @@ -156,6 +158,17 @@ def main(): print(format_output_line(DATA_TAB_1, data)) +def hop_by_hop_options(data): + next_header, header_length = struct.unpack('! B B', data[:2]) + print("Next header") + print(next_header) + print("Header Length") + print(header_length) + # print("Options") + # print(options) + input() + return (next_header, data) + # Unpack Ethernet Frame def ethernet_frame(data): From 16d6b33738a9ae696cf27aacb33abd1146fbb033 Mon Sep 17 00:00:00 2001 From: Adriano Date: Fri, 23 Oct 2020 14:15:16 -0700 Subject: [PATCH 05/29] feat: hop by hop FIXED calculation of data --- Packet-Sniffer.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/Packet-Sniffer.py b/Packet-Sniffer.py index e417df9..33b5d2b 100644 --- a/Packet-Sniffer.py +++ b/Packet-Sniffer.py @@ -166,9 +166,32 @@ def hop_by_hop_options(data): print(header_length) # print("Options") # print(options) + + ''' + BY DEFINITION ON https://tools.ietf.org/html/rfc8200#section-4.3 + Hdr Ext Len 8-bit unsigned integer. Length of the + Hop-by-Hop Options header in 8-octet units, + not including the first 8 octets. + + + That is: 1 octet = 8 bits (1 byte) + as it uses 8 octets by default for the number in Hdr Ext len, + from that logic we have: + Hdr Ext Len * 8 + As it does not include the first 8 octets, we have + to add to it + Hdr Ext Len * 8 + 8 + ''' + + data = data[:hdr_ext_len_converter(header_length)] input() return (next_header, data) +def hdr_ext_len_converter(octets): + return hdr_ext_len_converter_raw(octets, 8) + +def hdr_ext_len_converter_raw(octets, default_octet_number=8): + return int(octets*default_octet_number+8) # Unpack Ethernet Frame def ethernet_frame(data): From 497a281be3be952fa1c66ca023d4839379ce8c9e Mon Sep 17 00:00:00 2001 From: Adriano Date: Fri, 23 Oct 2020 14:16:32 -0700 Subject: [PATCH 06/29] feat: destination options --- Packet-Sniffer.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/Packet-Sniffer.py b/Packet-Sniffer.py index 33b5d2b..d8b9454 100644 --- a/Packet-Sniffer.py +++ b/Packet-Sniffer.py @@ -127,7 +127,7 @@ def main(): # pass #Destination Options if(next_header == 60 ): - pass + next_header, data = destination_options(data) #Routing if(next_header == 43 ): pass @@ -193,6 +193,19 @@ def hdr_ext_len_converter(octets): def hdr_ext_len_converter_raw(octets, default_octet_number=8): return int(octets*default_octet_number+8) +def destination_options(data): + next_header, header_length = struct.unpack('! B B', data[:2]) + print("Next header") + print(next_header) + print("Header Length") + print(header_length) + + # header length uses the same definition as HOP BY HOP options + + data = data[:hdr_ext_len_converter(header_length)] + input() + return (next_header, data) + # Unpack Ethernet Frame def ethernet_frame(data): dest_mac, src_mac, proto = struct.unpack('! 6s 6s H', data[:14]) From cdf99477c26b4f3ae16185dae3ed4da883303441 Mon Sep 17 00:00:00 2001 From: Adriano Date: Fri, 23 Oct 2020 14:22:01 -0700 Subject: [PATCH 07/29] feat: routing header --- Packet-Sniffer.py | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/Packet-Sniffer.py b/Packet-Sniffer.py index d8b9454..fed5fe4 100644 --- a/Packet-Sniffer.py +++ b/Packet-Sniffer.py @@ -130,7 +130,8 @@ def main(): next_header, data = destination_options(data) #Routing if(next_header == 43 ): - pass + next_header, data = routing_header(data) + #Fragment if(next_header == 44 ): pass @@ -206,6 +207,24 @@ def destination_options(data): input() return (next_header, data) +def routing_header(data): + next_header, header_length, routing_type, segments_left = struct.unpack('! B B B B', data[:4]) + print("Next header") + print(next_header) + print("Header Length") + print(header_length) + print("Routing Type") + print(routing_type) + print("Segments Left") + print(segments_left) + + # header length uses the same definition as HOP BY HOP options + + data = data[:hdr_ext_len_converter(header_length)] + input() + return (next_header, data) + + # Unpack Ethernet Frame def ethernet_frame(data): dest_mac, src_mac, proto = struct.unpack('! 6s 6s H', data[:14]) From b362dfa16fa923435e719f3264bd15ab8dd70d02 Mon Sep 17 00:00:00 2001 From: Adriano Date: Fri, 23 Oct 2020 14:32:23 -0700 Subject: [PATCH 08/29] feat: fragment header --- Packet-Sniffer.py | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/Packet-Sniffer.py b/Packet-Sniffer.py index fed5fe4..4ce5787 100644 --- a/Packet-Sniffer.py +++ b/Packet-Sniffer.py @@ -134,7 +134,7 @@ def main(): #Fragment if(next_header == 44 ): - pass + next_header, data = fragment_header(data) #Authentication if(next_header == 51 ): pass @@ -224,6 +224,31 @@ def routing_header(data): input() return (next_header, data) +def fragment_header(data): + next_header, reserved, offset_res_flag_word, identification = struct.unpack('! B B H I', data[:8]) + # 8 + 8 + 13 + 2 + 1 + 32 + fragment_offset = offset_res_flag_word >> 3 + res = offset_res_flag_word & 6 + m_flag = offset_res_flag_word & 1 + print("Next header") + print(next_header) + print("Reserved") + print(reserved) + print("Fragment Offset") + print(fragment_offset) + print("Res") + print(res) + print("M Flag") + print(m_flag) + print("Identification") + print(identification) + + data = data[8:] + input() + return (next_header,data) + + + # Unpack Ethernet Frame def ethernet_frame(data): From c9119a6534b6eec608262373c73c439e0bcaf40f Mon Sep 17 00:00:00 2001 From: Adriano Date: Fri, 23 Oct 2020 14:43:22 -0700 Subject: [PATCH 09/29] feat: auth header --- Packet-Sniffer.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/Packet-Sniffer.py b/Packet-Sniffer.py index 4ce5787..f32aa30 100644 --- a/Packet-Sniffer.py +++ b/Packet-Sniffer.py @@ -137,6 +137,7 @@ def main(): next_header, data = fragment_header(data) #Authentication if(next_header == 51 ): + next_header, data = authentication_header(data) pass #Encapsulating Security Payload if(next_header == 50 ): @@ -191,6 +192,9 @@ def hop_by_hop_options(data): def hdr_ext_len_converter(octets): return hdr_ext_len_converter_raw(octets, 8) +def hdr_ext_len_converter_4_octets(octets): + return hdr_ext_len_converter_raw(octets, 4) + def hdr_ext_len_converter_raw(octets, default_octet_number=8): return int(octets*default_octet_number+8) @@ -248,6 +252,24 @@ def fragment_header(data): return (next_header,data) +# Defined on https://tools.ietf.org/html/rfc4302 +def authentication_header(data): + next_header, payload_length, reserved, spi, sequence_number = struct.unpack('! B B H I I', data[:12]) + print("Next header") + print(next_header) + print("Payload Length") + print(payload_length) + print("Reserved") + print(reserved) + print("Security Parameters Index") + print(spi) + print("Sequence Number Field) + print(sequence_number) + data = data[:hdr_ext_len_converter_4_octets(payload_length)] + input() + + return (next_header, data) + # Unpack Ethernet Frame From abe523cdddf8a7f6fbb1f60e1f7c0b37c1153efa Mon Sep 17 00:00:00 2001 From: Adriano Date: Fri, 23 Oct 2020 14:55:10 -0700 Subject: [PATCH 10/29] feat: encapsuling header + no next header --- Packet-Sniffer.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Packet-Sniffer.py b/Packet-Sniffer.py index f32aa30..c216380 100644 --- a/Packet-Sniffer.py +++ b/Packet-Sniffer.py @@ -138,10 +138,12 @@ def main(): #Authentication if(next_header == 51 ): next_header, data = authentication_header(data) - pass + #Encapsulating Security Payload if(next_header == 50 ): - pass + next_header, data = encapsuling_header(data) + if(next_header == 59) : + print("No next header") #ICMPv6 if(next_header == 58 ): pass @@ -270,7 +272,8 @@ def authentication_header(data): return (next_header, data) - +def encapsuling_header(data): + return (59, data) # returns a no next header, as this one is hard as heck to calculate :). More info on: https://tools.ietf.org/html/rfc4303 # Unpack Ethernet Frame def ethernet_frame(data): From a34fe9534c8a82f5e19180d512730f027a46bee3 Mon Sep 17 00:00:00 2001 From: Adriano Date: Fri, 23 Oct 2020 15:06:58 -0700 Subject: [PATCH 11/29] feat: ICMPv6 and ICMPv4 fixed --- Packet-Sniffer.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/Packet-Sniffer.py b/Packet-Sniffer.py index c216380..9772af5 100644 --- a/Packet-Sniffer.py +++ b/Packet-Sniffer.py @@ -32,11 +32,7 @@ def main(): # # ICMP # if proto == 1: - # icmp_type, code, checksum, data = icmp_packet(data) - # print(TAB_1 + 'ICMP Packet:') - # print(TAB_2 + 'Type: {}, Code: {}, Checksum: {},'.format(icmp_type, code, checksum)) - # print(TAB_2 + 'ICMP Data:') - # print(format_output_line(DATA_TAB_3, data)) + # icmp_packet_template_method(data) # # TCP # elif proto == 6: @@ -146,7 +142,8 @@ def main(): print("No next header") #ICMPv6 if(next_header == 58 ): - pass + # Defined on https://tools.ietf.org/html/rfc4443#page-3 <--- The same as ICMPv4 :) + icmp_packet_template_method(data) # version = data[0] # print(version) # print("Not Converted") @@ -275,6 +272,7 @@ def authentication_header(data): def encapsuling_header(data): return (59, data) # returns a no next header, as this one is hard as heck to calculate :). More info on: https://tools.ietf.org/html/rfc4303 + # Unpack Ethernet Frame def ethernet_frame(data): dest_mac, src_mac, proto = struct.unpack('! 6s 6s H', data[:14]) @@ -299,6 +297,13 @@ def ipv4(addr): return '.'.join(map(str, addr)) +def icmp_packet_template_method(data): + icmp_type, code, checksum, data = icmp_packet(data) + print(TAB_1 + 'ICMP Packet:') + print(TAB_2 + 'Type: {}, Code: {}, Checksum: {},'.format(icmp_type, code, checksum)) + print(TAB_2 + 'ICMP Data:') + print(format_output_line(DATA_TAB_3, data)) + # Unpacks for any ICMP Packet def icmp_packet(data): icmp_type, code, checksum = struct.unpack('! B B H', data[:4]) From a4ccf2a8d2a521104a95a9ba5d1bc057cd8642fa Mon Sep 17 00:00:00 2001 From: Adriano Date: Fri, 23 Oct 2020 15:14:12 -0700 Subject: [PATCH 12/29] refactor: TCP to have a template method --- Packet-Sniffer.py | 49 +++++++++++++++++++++++++---------------------- 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/Packet-Sniffer.py b/Packet-Sniffer.py index 9772af5..23380ad 100644 --- a/Packet-Sniffer.py +++ b/Packet-Sniffer.py @@ -36,29 +36,7 @@ def main(): # # TCP # elif proto == 6: - # src_port, dest_port, sequence, acknowledgment, flag_urg, flag_ack, flag_psh, flag_rst, flag_syn, flag_fin = struct.unpack( - # '! H H L L H H H H H H', raw_data[:24]) - # print(TAB_1 + 'TCP Segment:') - # print(TAB_2 + 'Source Port: {}, Destination Port: {}'.format(src_port, dest_port)) - # print(TAB_2 + 'Sequence: {}, Acknowledgment: {}'.format(sequence, acknowledgment)) - # print(TAB_2 + 'Flags:') - # print(TAB_3 + 'URG: {}, ACK: {}, PSH: {}'.format(flag_urg, flag_ack, flag_psh)) - # print(TAB_3 + 'RST: {}, SYN: {}, FIN:{}'.format(flag_rst, flag_syn, flag_fin)) - - # if len(data) > 0: - # # HTTP - # if src_port == 80 or dest_port == 80: - # print(TAB_2 + 'HTTP Data:') - # try: - # http = HTTP(data) - # http_info = str(http.data).split('\n') - # for line in http_info: - # print(DATA_TAB_3 + str(line)) - # except: - # print(format_output_line(DATA_TAB_3, data)) - # else: - # print(TAB_2 + 'TCP Data:') - # print(format_output_line(DATA_TAB_3, data)) + # tcp_template_method(raw_data, data) # # UDP # elif proto == 17: # src_port, dest_port, length, data = udp_seg(data) @@ -309,6 +287,31 @@ def icmp_packet(data): icmp_type, code, checksum = struct.unpack('! B B H', data[:4]) return icmp_type, code, checksum, data[4:] + +def tcp_template_method(raw_data, data): + src_port, dest_port, sequence, acknowledgment, flag_urg, flag_ack, flag_psh, flag_rst, flag_syn, flag_fin = struct.unpack('! H H L L H H H H H H', raw_data[:24]) + print(TAB_1 + 'TCP Segment:') + print(TAB_2 + 'Source Port: {}, Destination Port: {}'.format(src_port, dest_port)) + print(TAB_2 + 'Sequence: {}, Acknowledgment: {}'.format(sequence, acknowledgment)) + print(TAB_2 + 'Flags:') + print(TAB_3 + 'URG: {}, ACK: {}, PSH: {}'.format(flag_urg, flag_ack, flag_psh)) + print(TAB_3 + 'RST: {}, SYN: {}, FIN:{}'.format(flag_rst, flag_syn, flag_fin)) + + if len(data) > 0: + # HTTP + if src_port == 80 or dest_port == 80: + print(TAB_2 + 'HTTP Data:') + try: + http = HTTP(data) + http_info = str(http.data).split('\n') + for line in http_info: + print(DATA_TAB_3 + str(line)) + except: + print(format_output_line(DATA_TAB_3, data)) + else: + print(TAB_2 + 'TCP Data:') + print(format_output_line(DATA_TAB_3, data)) + # Unpacks for any TCP Packet def tcp_seg(data): (src_port, destination_port, sequence, acknowledgenment, offset_reserv_flag) = struct.unpack('! H H L L H', data[:14]) From 163378c374db994628f51898330be966e0c692e6 Mon Sep 17 00:00:00 2001 From: Adriano Date: Fri, 23 Oct 2020 15:14:44 -0700 Subject: [PATCH 13/29] feat: TCP in ipv6 --- Packet-Sniffer.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Packet-Sniffer.py b/Packet-Sniffer.py index 23380ad..3c71614 100644 --- a/Packet-Sniffer.py +++ b/Packet-Sniffer.py @@ -122,6 +122,10 @@ def main(): if(next_header == 58 ): # Defined on https://tools.ietf.org/html/rfc4443#page-3 <--- The same as ICMPv4 :) icmp_packet_template_method(data) + + # TCP + if(next_header == 6): + tcp_template_method(raw_data, data) # version = data[0] # print(version) # print("Not Converted") From f1471d6e3fcf06614f22fbd07063451eb64acc4c Mon Sep 17 00:00:00 2001 From: Adriano Date: Fri, 23 Oct 2020 15:15:29 -0700 Subject: [PATCH 14/29] refactor: UDP to have a template method --- Packet-Sniffer.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Packet-Sniffer.py b/Packet-Sniffer.py index 3c71614..732ea46 100644 --- a/Packet-Sniffer.py +++ b/Packet-Sniffer.py @@ -39,9 +39,7 @@ def main(): # tcp_template_method(raw_data, data) # # UDP # elif proto == 17: - # src_port, dest_port, length, data = udp_seg(data) - # print(TAB_1 + 'UDP Segment:') - # print(TAB_2 + 'Source Port: {}, Destination Port: {}, Length: {}'.format(src_port, dest_port, length)) + # udp_template_method(data) # # Other IPv4 # else: @@ -316,6 +314,11 @@ def tcp_template_method(raw_data, data): print(TAB_2 + 'TCP Data:') print(format_output_line(DATA_TAB_3, data)) +def udp_template_method(data): + src_port, dest_port, length, data = udp_seg(data) + print(TAB_1 + 'UDP Segment:') + print(TAB_2 + 'Source Port: {}, Destination Port: {}, Length: {}'.format(src_port, dest_port, length)) + # Unpacks for any TCP Packet def tcp_seg(data): (src_port, destination_port, sequence, acknowledgenment, offset_reserv_flag) = struct.unpack('! H H L L H', data[:14]) From 96a45a92072e86a8759939e80f146957f9eddee9 Mon Sep 17 00:00:00 2001 From: Adriano Date: Fri, 23 Oct 2020 15:16:05 -0700 Subject: [PATCH 15/29] feat: UDP in ipv6 --- Packet-Sniffer.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Packet-Sniffer.py b/Packet-Sniffer.py index 732ea46..e217e83 100644 --- a/Packet-Sniffer.py +++ b/Packet-Sniffer.py @@ -124,6 +124,9 @@ def main(): # TCP if(next_header == 6): tcp_template_method(raw_data, data) + + if(next_header == 17): + udp_template_method(data) # version = data[0] # print(version) # print("Not Converted") From 0ace140a2ca336116f09148449c5a52c1b3a60cd Mon Sep 17 00:00:00 2001 From: Adriano Date: Fri, 23 Oct 2020 15:17:09 -0700 Subject: [PATCH 16/29] refactor: code cleanup --- Packet-Sniffer.py | 61 ++++++++++++++++++----------------------------- 1 file changed, 23 insertions(+), 38 deletions(-) diff --git a/Packet-Sniffer.py b/Packet-Sniffer.py index e217e83..3495bef 100644 --- a/Packet-Sniffer.py +++ b/Packet-Sniffer.py @@ -24,27 +24,26 @@ def main(): print(TAB_1 + 'Destination: {}, Source: {}, Protocol: {}'.format(dest_mac, src_mac, eth_proto)) if eth_proto == 8: - pass - # (version, header_length, ttl, proto, src, target, data) = ipv4_Packet(data) - # print(TAB_1 + "IPV4 Packet:") - # print(TAB_2 + 'Version: {}, Header Length: {}, TTL: {}'.format(version, header_length, ttl)) - # print(TAB_3 + 'protocol: {}, Source: {}, Target: {}'.format(proto, src, target)) - - # # ICMP - # if proto == 1: - # icmp_packet_template_method(data) - - # # TCP - # elif proto == 6: - # tcp_template_method(raw_data, data) - # # UDP - # elif proto == 17: - # udp_template_method(data) - - # # Other IPv4 - # else: - # print(TAB_1 + 'Other IPv4 Data:') - # print(format_output_line(DATA_TAB_2, data)) + (version, header_length, ttl, proto, src, target, data) = ipv4_Packet(data) + print(TAB_1 + "IPV4 Packet:") + print(TAB_2 + 'Version: {}, Header Length: {}, TTL: {}'.format(version, header_length, ttl)) + print(TAB_3 + 'protocol: {}, Source: {}, Target: {}'.format(proto, src, target)) + + # ICMP + if proto == 1: + icmp_packet_template_method(data) + + # TCP + elif proto == 6: + tcp_template_method(raw_data, data) + # UDP + elif proto == 17: + udp_template_method(data) + + # Other IPv4 + else: + print(TAB_1 + 'Other IPv4 Data:') + print(format_output_line(DATA_TAB_2, data)) elif(eth_proto == 56710): print("IPV6") print("eth prot {}".format(eth_proto)) @@ -55,16 +54,11 @@ def main(): payload_length,\ next_header, \ hop_limit = struct.unpack('! IHBB', data[:8]) - # version = struct.unpack('! B', data[:1]) - + version = first_32_bits >> 28 traffic_class = (first_32_bits >> 20) & 255 flow_label = first_32_bits & 1048575 - # flow_label - # BITS - #4+8+20+16+8+8 - print("First word") print(bin(first_32_bits)) print("Version") @@ -90,7 +84,6 @@ def main(): print(dst_address) data = data[40:] - #@TODO: Put UDP and TCP here as well (from IPv4 above) # ORDER DEFINED ON RFC8200 #Hop-by-Hop Options @@ -127,16 +120,8 @@ def main(): if(next_header == 17): udp_template_method(data) - # version = data[0] - # print(version) - # print("Not Converted") - # print(bin(version)) - # version = version >> 4 - # print("Converted") - # print(version) - input() - # version, traffic_class, flow_label, payload_length,next_header, hop_limit = struct.unpack('! H', data[:40]) - # ttl, proto, src, target = struct.unpack('! 8x B B 2x 4s 4s', data[:20]) + + else: print('Ethernet Data:') print(format_output_line(DATA_TAB_1, data)) From afae27189763dad578caca13ebd5f15998498d96 Mon Sep 17 00:00:00 2001 From: Adriano Date: Fri, 23 Oct 2020 15:19:08 -0700 Subject: [PATCH 17/29] refactor: IPv6 header separated into function --- Packet-Sniffer.py | 74 +++++++++++++++++++++++------------------------ 1 file changed, 36 insertions(+), 38 deletions(-) diff --git a/Packet-Sniffer.py b/Packet-Sniffer.py index 3495bef..6abd427 100644 --- a/Packet-Sniffer.py +++ b/Packet-Sniffer.py @@ -45,45 +45,8 @@ def main(): print(TAB_1 + 'Other IPv4 Data:') print(format_output_line(DATA_TAB_2, data)) elif(eth_proto == 56710): - print("IPV6") - print("eth prot {}".format(eth_proto)) - print(data[:1]) - print("\ndata\n") - print(data) - first_32_bits, \ - payload_length,\ - next_header, \ - hop_limit = struct.unpack('! IHBB', data[:8]) - version = first_32_bits >> 28 - traffic_class = (first_32_bits >> 20) & 255 - flow_label = first_32_bits & 1048575 - - print("First word") - print(bin(first_32_bits)) - print("Version") - print(version) - print("Traffic Class") - print(bin(traffic_class)) - print("Flow Label") - print(bin(flow_label)) - print("Payload Length") - print(bin(payload_length)) - print("Next Header") - print(next_header) - proto = next_header - print("Hop Limit") - print(bin(hop_limit)) - - src_address = socket.inet_ntop(socket.AF_INET6, data[8:24]) - dst_address = socket.inet_ntop(socket.AF_INET6, data[24:40]) - - print("Source Address") - print(src_address) - print("Dest Address") - print(dst_address) - - data = data[40:] + next_header, data = ipv6_header(data) # ORDER DEFINED ON RFC8200 #Hop-by-Hop Options @@ -126,6 +89,41 @@ def main(): print('Ethernet Data:') print(format_output_line(DATA_TAB_1, data)) +def ipv6_header(data): + print("IPV6") + first_32_bits, \ + payload_length,\ + next_header, \ + hop_limit = struct.unpack('! IHBB', data[:8]) + + version = first_32_bits >> 28 + traffic_class = (first_32_bits >> 20) & 255 + flow_label = first_32_bits & 1048575 + + print("Version") + print(version) + print("Traffic Class") + print(traffic_class) + print("Flow Label") + print(flow_label) + print("Payload Length") + print(payload_length) + print("Next Header") + print(next_header) + proto = next_header + print("Hop Limit") + print(bin(hop_limit)) + + src_address = socket.inet_ntop(socket.AF_INET6, data[8:24]) + dst_address = socket.inet_ntop(socket.AF_INET6, data[24:40]) + + print("Source Address") + print(src_address) + print("Dest Address") + print(dst_address) + + data = data[40:] + return (next_header, data) def hop_by_hop_options(data): next_header, header_length = struct.unpack('! B B', data[:2]) From 38849c797c6865d2a01bede74967ba37a5d38bfd Mon Sep 17 00:00:00 2001 From: Adriano Date: Fri, 23 Oct 2020 15:20:00 -0700 Subject: [PATCH 18/29] comment: RFC for IPv6 ext header order --- Packet-Sniffer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Packet-Sniffer.py b/Packet-Sniffer.py index 6abd427..c9374fe 100644 --- a/Packet-Sniffer.py +++ b/Packet-Sniffer.py @@ -48,7 +48,7 @@ def main(): next_header, data = ipv6_header(data) - # ORDER DEFINED ON RFC8200 + # ORDER DEFINED ON RFC8200 - https://tools.ietf.org/html/rfc8200 #Hop-by-Hop Options if(next_header == 0 ): next_header, data = hop_by_hop_options(data) From 3d7af5a10f84b9ed9ff74d82258e99e92c44d23c Mon Sep 17 00:00:00 2001 From: Adriano Date: Fri, 23 Oct 2020 15:20:53 -0700 Subject: [PATCH 19/29] comment: yes commenting yes --- Packet-Sniffer.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Packet-Sniffer.py b/Packet-Sniffer.py index c9374fe..3aeb137 100644 --- a/Packet-Sniffer.py +++ b/Packet-Sniffer.py @@ -23,7 +23,7 @@ def main(): print('\n Ethernet Frame: ') print(TAB_1 + 'Destination: {}, Source: {}, Protocol: {}'.format(dest_mac, src_mac, eth_proto)) - if eth_proto == 8: + if eth_proto == 8: # IPv4 (version, header_length, ttl, proto, src, target, data) = ipv4_Packet(data) print(TAB_1 + "IPV4 Packet:") print(TAB_2 + 'Version: {}, Header Length: {}, TTL: {}'.format(version, header_length, ttl)) @@ -44,7 +44,7 @@ def main(): else: print(TAB_1 + 'Other IPv4 Data:') print(format_output_line(DATA_TAB_2, data)) - elif(eth_proto == 56710): + elif(eth_proto == 56710): # IPv6 next_header, data = ipv6_header(data) @@ -81,6 +81,7 @@ def main(): if(next_header == 6): tcp_template_method(raw_data, data) + # UDP if(next_header == 17): udp_template_method(data) From ce009681c4d2553ce2bd7f2226491d7a8b740bb7 Mon Sep 17 00:00:00 2001 From: Adriano Date: Fri, 6 Nov 2020 06:16:23 -0800 Subject: [PATCH 20/29] feat: making stuff being printable-friendly --- Packet-Sniffer.py | 96 ++++++++++++++--------------------------------- 1 file changed, 29 insertions(+), 67 deletions(-) diff --git a/Packet-Sniffer.py b/Packet-Sniffer.py index 3aeb137..e6b6b9a 100644 --- a/Packet-Sniffer.py +++ b/Packet-Sniffer.py @@ -101,39 +101,20 @@ def ipv6_header(data): traffic_class = (first_32_bits >> 20) & 255 flow_label = first_32_bits & 1048575 - print("Version") - print(version) - print("Traffic Class") - print(traffic_class) - print("Flow Label") - print(flow_label) - print("Payload Length") - print(payload_length) - print("Next Header") - print(next_header) - proto = next_header - print("Hop Limit") - print(bin(hop_limit)) - src_address = socket.inet_ntop(socket.AF_INET6, data[8:24]) dst_address = socket.inet_ntop(socket.AF_INET6, data[24:40]) - print("Source Address") - print(src_address) - print("Dest Address") - print(dst_address) - + print(TAB_1 + "IPV6 Packet:") + print(TAB_2 + "Version: {}, Traffic Class: {}, Flow Label: {}".format(version, traffic_class, flow_label)) + print(TAB_2 + "Payload Length: {}, Next Header: {}, Hop Limit: {}".format(payload_length, next_header, hop_by_hop_options)) + print(TAB_3 + "Source Address: {}".format(src_address)) + print(TAB_3 + "Destination Address: {}".format(dst_address)) + data = data[40:] return (next_header, data) def hop_by_hop_options(data): next_header, header_length = struct.unpack('! B B', data[:2]) - print("Next header") - print(next_header) - print("Header Length") - print(header_length) - # print("Options") - # print(options) ''' BY DEFINITION ON https://tools.ietf.org/html/rfc8200#section-4.3 @@ -151,8 +132,10 @@ def hop_by_hop_options(data): Hdr Ext Len * 8 + 8 ''' + print(TAB_1 + "Hop-by-hop options:") + print(TAB_2 + "Next Header: {}, Header Length: {}".format(next_header, header_length)) + data = data[:hdr_ext_len_converter(header_length)] - input() return (next_header, data) def hdr_ext_len_converter(octets): @@ -166,10 +149,9 @@ def hdr_ext_len_converter_raw(octets, default_octet_number=8): def destination_options(data): next_header, header_length = struct.unpack('! B B', data[:2]) - print("Next header") - print(next_header) - print("Header Length") - print(header_length) + + print(TAB_1 + "Destination options:") + print(TAB_2 + "Next Header: {}, Header Length: {}".format(next_header, header_length)) # header length uses the same definition as HOP BY HOP options @@ -179,64 +161,44 @@ def destination_options(data): def routing_header(data): next_header, header_length, routing_type, segments_left = struct.unpack('! B B B B', data[:4]) - print("Next header") - print(next_header) - print("Header Length") - print(header_length) - print("Routing Type") - print(routing_type) - print("Segments Left") - print(segments_left) # header length uses the same definition as HOP BY HOP options + print(TAB_1 + "Routing Header:") + print(TAB_2 + "Header Length: {}, Routing Type: {}, Segments Left: {}".format(next_header, routing_type,segments_left)) + data = data[:hdr_ext_len_converter(header_length)] - input() return (next_header, data) def fragment_header(data): next_header, reserved, offset_res_flag_word, identification = struct.unpack('! B B H I', data[:8]) - # 8 + 8 + 13 + 2 + 1 + 32 + fragment_offset = offset_res_flag_word >> 3 res = offset_res_flag_word & 6 m_flag = offset_res_flag_word & 1 - print("Next header") - print(next_header) - print("Reserved") - print(reserved) - print("Fragment Offset") - print(fragment_offset) - print("Res") - print(res) - print("M Flag") - print(m_flag) - print("Identification") - print(identification) + + + print(TAB_1 + "Fragment Header:") + print(TAB_2 + 'Next Header: {}, Reserved: {}, Fragment Offset: {}'.format(next_header, reserved, fragment_offset)) + print(TAB_3 + 'Res: {}, M Flag: {}, Identification: {}'.format(res, m_flag, identification)) data = data[8:] - input() return (next_header,data) # Defined on https://tools.ietf.org/html/rfc4302 def authentication_header(data): next_header, payload_length, reserved, spi, sequence_number = struct.unpack('! B B H I I', data[:12]) - print("Next header") - print(next_header) - print("Payload Length") - print(payload_length) - print("Reserved") - print(reserved) - print("Security Parameters Index") - print(spi) - print("Sequence Number Field) - print(sequence_number) + print(TAB_1 + "Authentication Header:") + print(TAB_2 + 'Next Header: {}, Payload Length: {}, Reserved: {}'.format(next_header, payload_length, reserved)) + print(TAB_3 + 'Security Parameters Index: {}, Sequence Number Field: {}'.format(spi, sequence_number)) + data = data[:hdr_ext_len_converter_4_octets(payload_length)] - input() return (next_header, data) def encapsuling_header(data): + print("No next header") return (59, data) # returns a no next header, as this one is hard as heck to calculate :). More info on: https://tools.ietf.org/html/rfc4303 @@ -308,8 +270,8 @@ def udp_template_method(data): # Unpacks for any TCP Packet def tcp_seg(data): - (src_port, destination_port, sequence, acknowledgenment, offset_reserv_flag) = struct.unpack('! H H L L H', data[:14]) - offset = (offset_reserv_flag >> 12) * 4 + (src_port, destination_port, sequence, acknowledgement, offset_reserved_flag) = struct.unpack('! H H L L H', data[:14]) + offset = (offset_reserved_flag >> 12) * 4 flag_urg = (offset_reserved_flag & 32) >> 5 flag_ack = (offset_reserved_flag & 32) >>4 flag_psh = (offset_reserved_flag & 32) >> 3 @@ -317,7 +279,7 @@ def tcp_seg(data): flag_syn = (offset_reserved_flag & 32) >> 1 flag_fin = (offset_reserved_flag & 32) >> 1 - return src_port, dest_port, sequence, acknowledgement, flag_urg, flag_ack, flag_psh, flag_rst, flag_syn, flag_fin, data[offset:] + return src_port, destination_port, sequence, acknowledgement, flag_urg, flag_ack, flag_psh, flag_rst, flag_syn, flag_fin, data[offset:] # Unpacks for any UDP Packet From 8b4fa3f67f241c904201217274912dd31d569aad Mon Sep 17 00:00:00 2001 From: Adriano Date: Fri, 6 Nov 2020 07:48:37 -0800 Subject: [PATCH 21/29] feat: fixed some protocols and added ARP because why not --- Packet-Sniffer.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/Packet-Sniffer.py b/Packet-Sniffer.py index e6b6b9a..cbe7885 100644 --- a/Packet-Sniffer.py +++ b/Packet-Sniffer.py @@ -20,10 +20,11 @@ def main(): raw_data, addr = conn.recvfrom(65536) dest_mac, src_mac, eth_proto, data = ethernet_frame(raw_data) - print('\n Ethernet Frame: ') - print(TAB_1 + 'Destination: {}, Source: {}, Protocol: {}'.format(dest_mac, src_mac, eth_proto)) + print(TAB_1 + '\n Ethernet Frame: ') + print(TAB_2 + 'Destination: {}, Source: {}, Protocol: {}'.format(dest_mac, src_mac, eth_proto)) if eth_proto == 8: # IPv4 + (version, header_length, ttl, proto, src, target, data) = ipv4_Packet(data) print(TAB_1 + "IPV4 Packet:") print(TAB_2 + 'Version: {}, Header Length: {}, TTL: {}'.format(version, header_length, ttl)) @@ -85,7 +86,8 @@ def main(): if(next_header == 17): udp_template_method(data) - + elif(eth_proto==1544): # ARP + print(TAB_1 + " --- ARP Protocol ---") else: print('Ethernet Data:') print(format_output_line(DATA_TAB_1, data)) @@ -106,7 +108,7 @@ def ipv6_header(data): print(TAB_1 + "IPV6 Packet:") print(TAB_2 + "Version: {}, Traffic Class: {}, Flow Label: {}".format(version, traffic_class, flow_label)) - print(TAB_2 + "Payload Length: {}, Next Header: {}, Hop Limit: {}".format(payload_length, next_header, hop_by_hop_options)) + print(TAB_2 + "Payload Length: {}, Next Header: {}, Hop Limit: {}".format(payload_length, next_header, hop_limit)) print(TAB_3 + "Source Address: {}".format(src_address)) print(TAB_3 + "Destination Address: {}".format(dst_address)) @@ -156,7 +158,6 @@ def destination_options(data): # header length uses the same definition as HOP BY HOP options data = data[:hdr_ext_len_converter(header_length)] - input() return (next_header, data) def routing_header(data): @@ -205,6 +206,7 @@ def encapsuling_header(data): # Unpack Ethernet Frame def ethernet_frame(data): dest_mac, src_mac, proto = struct.unpack('! 6s 6s H', data[:14]) + print(" REAL PROTOCOL - {}".format(proto)) return get_mac_addr(dest_mac), get_mac_addr(src_mac), socket.htons(proto), data[14:] # Format MAC Address From 78e54a63a86e629191ac160f3742795e3d7065c4 Mon Sep 17 00:00:00 2001 From: 11808s8 Date: Sat, 7 Nov 2020 10:38:39 -0800 Subject: [PATCH 22/29] feat: refactoring structure of the module --- Packet-Sniffer.py | 249 ++---------------- __pycache__/format_packets.cpython-36.pyc | Bin 0 -> 971 bytes __pycache__/ipv4_packets.cpython-36.pyc | Bin 0 -> 641 bytes __pycache__/ipv6_packets.cpython-36.pyc | Bin 0 -> 3499 bytes .../multiple_protocol_methods.cpython-36.pyc | Bin 0 -> 3031 bytes format_packets.py | 19 ++ ipv4_packets.py | 13 + ipv6_packets.py | 113 ++++++++ multiple_protocol_methods.py | 77 ++++++ 9 files changed, 241 insertions(+), 230 deletions(-) create mode 100644 __pycache__/format_packets.cpython-36.pyc create mode 100644 __pycache__/ipv4_packets.cpython-36.pyc create mode 100644 __pycache__/ipv6_packets.cpython-36.pyc create mode 100644 __pycache__/multiple_protocol_methods.cpython-36.pyc create mode 100644 format_packets.py create mode 100644 ipv4_packets.py create mode 100644 ipv6_packets.py create mode 100644 multiple_protocol_methods.py diff --git a/Packet-Sniffer.py b/Packet-Sniffer.py index cbe7885..f3d0a08 100644 --- a/Packet-Sniffer.py +++ b/Packet-Sniffer.py @@ -3,43 +3,37 @@ import socket import struct import textwrap - -TAB_1 = '\t - ' -TAB_2 = '\t\t - ' -TAB_3 = '\t\t\t - ' -TAB_4 = '\t\t\t\t - ' - -DATA_TAB_1 = '\t ' -DATA_TAB_2 = '\t\t ' -DATA_TAB_3 = '\t\t\t ' -DATA_TAB_4 = '\t\t\t\t ' +import ipv4_packets +import ipv6_packets +import multiple_protocol_methods +from format_packets import * def main(): conn = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.ntohs(3)) while True: raw_data, addr = conn.recvfrom(65536) - dest_mac, src_mac, eth_proto, data = ethernet_frame(raw_data) + dest_mac, src_mac, eth_proto, data = multiple_protocol_methods.ethernet_frame(raw_data) print(TAB_1 + '\n Ethernet Frame: ') print(TAB_2 + 'Destination: {}, Source: {}, Protocol: {}'.format(dest_mac, src_mac, eth_proto)) if eth_proto == 8: # IPv4 - (version, header_length, ttl, proto, src, target, data) = ipv4_Packet(data) + (version, header_length, ttl, proto, src, target, data) = ipv4_packets.ipv4_Packet(data) print(TAB_1 + "IPV4 Packet:") print(TAB_2 + 'Version: {}, Header Length: {}, TTL: {}'.format(version, header_length, ttl)) print(TAB_3 + 'protocol: {}, Source: {}, Target: {}'.format(proto, src, target)) # ICMP if proto == 1: - icmp_packet_template_method(data) + multiple_protocol_methods.icmp_packet_template_method(data) # TCP elif proto == 6: - tcp_template_method(raw_data, data) + multiple_protocol_methods.tcp_template_method(raw_data, data) # UDP elif proto == 17: - udp_template_method(data) + multiple_protocol_methods.udp_template_method(data) # Other IPv4 else: @@ -47,44 +41,44 @@ def main(): print(format_output_line(DATA_TAB_2, data)) elif(eth_proto == 56710): # IPv6 - next_header, data = ipv6_header(data) + next_header, data = ipv6_packets.ipv6_header(data) # ORDER DEFINED ON RFC8200 - https://tools.ietf.org/html/rfc8200 #Hop-by-Hop Options if(next_header == 0 ): - next_header, data = hop_by_hop_options(data) + next_header, data = ipv6_packets.hop_by_hop_options(data) # pass #Destination Options if(next_header == 60 ): - next_header, data = destination_options(data) + next_header, data = ipv6_packets.destination_options(data) #Routing if(next_header == 43 ): - next_header, data = routing_header(data) + next_header, data = ipv6_packets.routing_header(data) #Fragment if(next_header == 44 ): - next_header, data = fragment_header(data) + next_header, data = ipv6_packets.fragment_header(data) #Authentication if(next_header == 51 ): - next_header, data = authentication_header(data) + next_header, data = ipv6_packets.authentication_header(data) #Encapsulating Security Payload if(next_header == 50 ): - next_header, data = encapsuling_header(data) + next_header, data = ipv6_packets.encapsuling_header(data) if(next_header == 59) : print("No next header") #ICMPv6 if(next_header == 58 ): # Defined on https://tools.ietf.org/html/rfc4443#page-3 <--- The same as ICMPv4 :) - icmp_packet_template_method(data) + multiple_protocol_methods.icmp_packet_template_method(data) # TCP if(next_header == 6): - tcp_template_method(raw_data, data) + multiple_protocol_methods.tcp_template_method(raw_data, data) # UDP if(next_header == 17): - udp_template_method(data) + multiple_protocol_methods.udp_template_method(data) elif(eth_proto==1544): # ARP print(TAB_1 + " --- ARP Protocol ---") @@ -92,211 +86,6 @@ def main(): print('Ethernet Data:') print(format_output_line(DATA_TAB_1, data)) -def ipv6_header(data): - print("IPV6") - first_32_bits, \ - payload_length,\ - next_header, \ - hop_limit = struct.unpack('! IHBB', data[:8]) - - version = first_32_bits >> 28 - traffic_class = (first_32_bits >> 20) & 255 - flow_label = first_32_bits & 1048575 - - src_address = socket.inet_ntop(socket.AF_INET6, data[8:24]) - dst_address = socket.inet_ntop(socket.AF_INET6, data[24:40]) - - print(TAB_1 + "IPV6 Packet:") - print(TAB_2 + "Version: {}, Traffic Class: {}, Flow Label: {}".format(version, traffic_class, flow_label)) - print(TAB_2 + "Payload Length: {}, Next Header: {}, Hop Limit: {}".format(payload_length, next_header, hop_limit)) - print(TAB_3 + "Source Address: {}".format(src_address)) - print(TAB_3 + "Destination Address: {}".format(dst_address)) - - data = data[40:] - return (next_header, data) - -def hop_by_hop_options(data): - next_header, header_length = struct.unpack('! B B', data[:2]) - - ''' - BY DEFINITION ON https://tools.ietf.org/html/rfc8200#section-4.3 - Hdr Ext Len 8-bit unsigned integer. Length of the - Hop-by-Hop Options header in 8-octet units, - not including the first 8 octets. - - - That is: 1 octet = 8 bits (1 byte) - as it uses 8 octets by default for the number in Hdr Ext len, - from that logic we have: - Hdr Ext Len * 8 - As it does not include the first 8 octets, we have - to add to it - Hdr Ext Len * 8 + 8 - ''' - - print(TAB_1 + "Hop-by-hop options:") - print(TAB_2 + "Next Header: {}, Header Length: {}".format(next_header, header_length)) - - data = data[:hdr_ext_len_converter(header_length)] - return (next_header, data) - -def hdr_ext_len_converter(octets): - return hdr_ext_len_converter_raw(octets, 8) - -def hdr_ext_len_converter_4_octets(octets): - return hdr_ext_len_converter_raw(octets, 4) - -def hdr_ext_len_converter_raw(octets, default_octet_number=8): - return int(octets*default_octet_number+8) - -def destination_options(data): - next_header, header_length = struct.unpack('! B B', data[:2]) - - print(TAB_1 + "Destination options:") - print(TAB_2 + "Next Header: {}, Header Length: {}".format(next_header, header_length)) - - # header length uses the same definition as HOP BY HOP options - - data = data[:hdr_ext_len_converter(header_length)] - return (next_header, data) - -def routing_header(data): - next_header, header_length, routing_type, segments_left = struct.unpack('! B B B B', data[:4]) - - # header length uses the same definition as HOP BY HOP options - - print(TAB_1 + "Routing Header:") - print(TAB_2 + "Header Length: {}, Routing Type: {}, Segments Left: {}".format(next_header, routing_type,segments_left)) - - data = data[:hdr_ext_len_converter(header_length)] - return (next_header, data) - -def fragment_header(data): - next_header, reserved, offset_res_flag_word, identification = struct.unpack('! B B H I', data[:8]) - - fragment_offset = offset_res_flag_word >> 3 - res = offset_res_flag_word & 6 - m_flag = offset_res_flag_word & 1 - - - print(TAB_1 + "Fragment Header:") - print(TAB_2 + 'Next Header: {}, Reserved: {}, Fragment Offset: {}'.format(next_header, reserved, fragment_offset)) - print(TAB_3 + 'Res: {}, M Flag: {}, Identification: {}'.format(res, m_flag, identification)) - - data = data[8:] - return (next_header,data) - - -# Defined on https://tools.ietf.org/html/rfc4302 -def authentication_header(data): - next_header, payload_length, reserved, spi, sequence_number = struct.unpack('! B B H I I', data[:12]) - print(TAB_1 + "Authentication Header:") - print(TAB_2 + 'Next Header: {}, Payload Length: {}, Reserved: {}'.format(next_header, payload_length, reserved)) - print(TAB_3 + 'Security Parameters Index: {}, Sequence Number Field: {}'.format(spi, sequence_number)) - - data = data[:hdr_ext_len_converter_4_octets(payload_length)] - - return (next_header, data) - -def encapsuling_header(data): - print("No next header") - return (59, data) # returns a no next header, as this one is hard as heck to calculate :). More info on: https://tools.ietf.org/html/rfc4303 - - -# Unpack Ethernet Frame -def ethernet_frame(data): - dest_mac, src_mac, proto = struct.unpack('! 6s 6s H', data[:14]) - print(" REAL PROTOCOL - {}".format(proto)) - return get_mac_addr(dest_mac), get_mac_addr(src_mac), socket.htons(proto), data[14:] - - # Format MAC Address -def get_mac_addr(bytes_addr): - bytes_str = map('{:02x}'.format, bytes_addr) - mac_addr = ':'.join(bytes_str).upper() - return mac_addr - -# Unpack IPv4 Packets Recieved -def ipv4_Packet(data): - version_header_len = data[0] - version = version_header_len >> 4 - header_len = (version_header_len & 15) * 4 - ttl, proto, src, target = struct.unpack('! 8x B B 2x 4s 4s', data[:20]) - return version, header_len, ttl, proto, ipv4(src), ipv4(target), data[header_len:] - -# Returns Formatted IP Address -def ipv4(addr): - return '.'.join(map(str, addr)) - - -def icmp_packet_template_method(data): - icmp_type, code, checksum, data = icmp_packet(data) - print(TAB_1 + 'ICMP Packet:') - print(TAB_2 + 'Type: {}, Code: {}, Checksum: {},'.format(icmp_type, code, checksum)) - print(TAB_2 + 'ICMP Data:') - print(format_output_line(DATA_TAB_3, data)) - -# Unpacks for any ICMP Packet -def icmp_packet(data): - icmp_type, code, checksum = struct.unpack('! B B H', data[:4]) - return icmp_type, code, checksum, data[4:] - - -def tcp_template_method(raw_data, data): - src_port, dest_port, sequence, acknowledgment, flag_urg, flag_ack, flag_psh, flag_rst, flag_syn, flag_fin = struct.unpack('! H H L L H H H H H H', raw_data[:24]) - print(TAB_1 + 'TCP Segment:') - print(TAB_2 + 'Source Port: {}, Destination Port: {}'.format(src_port, dest_port)) - print(TAB_2 + 'Sequence: {}, Acknowledgment: {}'.format(sequence, acknowledgment)) - print(TAB_2 + 'Flags:') - print(TAB_3 + 'URG: {}, ACK: {}, PSH: {}'.format(flag_urg, flag_ack, flag_psh)) - print(TAB_3 + 'RST: {}, SYN: {}, FIN:{}'.format(flag_rst, flag_syn, flag_fin)) - - if len(data) > 0: - # HTTP - if src_port == 80 or dest_port == 80: - print(TAB_2 + 'HTTP Data:') - try: - http = HTTP(data) - http_info = str(http.data).split('\n') - for line in http_info: - print(DATA_TAB_3 + str(line)) - except: - print(format_output_line(DATA_TAB_3, data)) - else: - print(TAB_2 + 'TCP Data:') - print(format_output_line(DATA_TAB_3, data)) - -def udp_template_method(data): - src_port, dest_port, length, data = udp_seg(data) - print(TAB_1 + 'UDP Segment:') - print(TAB_2 + 'Source Port: {}, Destination Port: {}, Length: {}'.format(src_port, dest_port, length)) - -# Unpacks for any TCP Packet -def tcp_seg(data): - (src_port, destination_port, sequence, acknowledgement, offset_reserved_flag) = struct.unpack('! H H L L H', data[:14]) - offset = (offset_reserved_flag >> 12) * 4 - flag_urg = (offset_reserved_flag & 32) >> 5 - flag_ack = (offset_reserved_flag & 32) >>4 - flag_psh = (offset_reserved_flag & 32) >> 3 - flag_rst = (offset_reserved_flag & 32) >> 2 - flag_syn = (offset_reserved_flag & 32) >> 1 - flag_fin = (offset_reserved_flag & 32) >> 1 - - return src_port, destination_port, sequence, acknowledgement, flag_urg, flag_ack, flag_psh, flag_rst, flag_syn, flag_fin, data[offset:] - - -# Unpacks for any UDP Packet -def udp_seg(data): - src_port, dest_port, size = struct.unpack('! H H 2x H', data[:8]) - return src_port, dest_port, size, data[8:] - -# Formats the output line -def format_output_line(prefix, string, size=80): - size -= len(prefix) - if isinstance(string, bytes): - string = ''.join(r'\x{:02x}'.format(byte) for byte in string) - if size % 2: - size-= 1 - return '\n'.join([prefix + line for line in textwrap.wrap(string, size)]) main() diff --git a/__pycache__/format_packets.cpython-36.pyc b/__pycache__/format_packets.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b2735b5256533485d24ceaf106eb874ecc995c44 GIT binary patch literal 971 zcmaJnF&mILS4uw@$zM+|Yy zFei*~hdG=w%3bDik9oYtYP`+^9$sPQ^9KVIHRd#EwwiM{sK5&>)&MI9M4L7WP(=Z4 zwAs8lhJuMHZxiAEPnt)LhHeiMhR$9EdtgwAkBUPW`W*sEip%9D6_(E z5k}{PV@M-&|K04%%iX=%@+iXE8x>+2tB7dQ-evUTrAmJwVdhxJowH(^c498FI4?R$ z!L$6dQ(mgGBLCxU+1FMXC!bQ)l6f{7rJ{3Oky^*rJJ@(_siEb{c6qrDdZ%fg&PvhW zGL4%lD4IXr5Q_^{UZ~+D%hPsmQY7(2_S?4^H->#<1kgDAO9%?SN3i8Km{TJ~eTlC@ zh{xy~Ii~|VUo~VzgkfuHiWoUck&d!i6%!sr)?sgwNtG1SvR{4ERQ1sO*?)VyO^H11 zOwwG3napyj;yg*UYebfsj*BeUzDj56vxrMgjg1^pH~n~02~b;8naxw%DXt<_Q~Ke* z)fSX?wJH@o$n-=_HlJ<>M(p)UX)k8Mu{00%@=OF+9 literal 0 HcmV?d00001 diff --git a/__pycache__/ipv4_packets.cpython-36.pyc b/__pycache__/ipv4_packets.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..be3a1cd39cf5536261b4b2158fbcaa249b43f435 GIT binary patch literal 641 zcmYjPyKdVs6ul(%s+;tMECDjOqXtJnnju5c1j%j$$R-pJ2$7EE+LA!hK~hkY(_bmj zF~7sLKmh+jr(Q~FVN&-{_vn!KL4DfaADuk^ES?C!Z`c_W-!IVg5rP0gmXL#>f;~b` zL?A+3sUSCyMq5?P#bLsV!R<1EEC|Bv)IR;Dj#+mczBEO{r$)B+5Pwu=gIx} zRO7QfKt5$I(nhUIx|PTo3Hc3+vM?2Bki3AKdGn7(~8qJwgDI;M^leM7=}r|7G~@cu{{D{)-?B zFus}C>W#lXI(6h2+Y>CBs&;I}TP(|{l(>Kkq57f*@cmUW!XBFTKM0WCPninQ=_B{V a&L-az<#)Q|^QsZ+rTpS^(mtt#CCOiqVVDU3 literal 0 HcmV?d00001 diff --git a/__pycache__/ipv6_packets.cpython-36.pyc b/__pycache__/ipv6_packets.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fc816e58cd526963bd19a38b2d7cb4dfb4338633 GIT binary patch literal 3499 zcmcguTW=dh6yA$>y>{%RO>=3Wlr12EtEN#?sH%c`Ng+z4VxlJM!wPA&@vM^#&aRmq zx6NWpNGX2>iGRQk;b~uaK>iE7l<&;g8#hf`9uT&6&d%90bMBX$^?LR9zkc;s&uiMB z+QiSq`+YoVjD=}T?`S&&jgIc=5*nVtOjdfKc_y=%4On7j<^Wo(!m5BayU1#+{zCW4 zY?{pg*vI~G!Hpk`xr`Q5p1gtS*TWc&0!BcDKxqh|T(&-()DjplpLp<$!eQhPj0ze zLF2kmy$avyerG*zhePV&rs6zql_+Gndj3U=$j9Sgiy5g?6YeNIqXBQA5%ezO*u(F$UDG1U#*+;L(k#xpHtToEKg7cgb zn@`g+L(4f@P>r;FexGrl{0OJ|tt5u;M93Q^zd$7OL{e8q8o6D%M=g{i`7Akp_sAzO zl8o{xC61bYaki$<8RvBV0d|G?sN9eVrTK_ZXfT9+Ov!09IekK5S~^oSp9jzI(N0<- z6zM5x`1?5e1)h|wrs;D3FWC-DIMLAgWd%M2ICXn|`D}?k_mwcWab(Q+3LPg!T2d0c z5G<4?2awWzeGZCKEWDz+i5zVhoMiCkSlAAF9if=`aqn<9)^A8^}|M%m2cq=(wRH*N{pE!7()^7xuNrr9~_hN@|7hkJ)% zEK-oQW#f2PvMcLZC#fy1=he7k?+aY*)zi_n$oIB5ZQAKEt*Qx|5PxLVOC^*`%Jffw zE38WWwXo{X*u2fEeUwT$P+;Pb!vtm?HB6w0+M^avMYODnXx}PE0Rtn111yGylK}xf zFpB0sF07SiHnRVQyD2ktNck}&DTh>;vUBS^kd`g{vHDt}eH^ACe;P97iQ>R_?RJVO zfg1m(AW>hxb=Nz=o_gP8@K}VAK{j&2z0+y4kg4IEI4yTD6iDXYTq61TK=^I&@Si1| zdDGD=OuU))NFQI3=O*Yq`%oS^?cft)<>4K0Pe}w#r`CwSDcd5o#H+v-o+kShp6+0C zhNrFZ=s2+6kU<#mUh$~~pO)a~$#z*jqg~p~Y)WMnyy|WaYY-q?c+eC3WN&5d!ksr> zbLUw@8vIwdIJ>9toTbcb)bnXIe~!m9Ww9xIlT(+R9c1m2c9OkL)^1s9WE4uJ q71z9{3H+@XoK%6Ei$8`3pSpot5G`A2m$N;se(eNL(01x9WpDHtVf;+oHtr4F(Wekn8#2yf+JgRrenUIf z9~lWt^u&-lH-<)R9J6D_G-<|YA$3S=XpU0bd_OX`Kxj-;6MWNJ_Ru-iLKtxybnbo+rAcV$}M_he_>?RC1G z3m6BzLrCh=j&&vMLi-fM$naphLGhgjWD0crb)JkM)FceW;VGhsLp% z=&=sR8aq?_S>xX7)8tRqfCG$iHxvcTOU+?0@Kb9NhMuS!ZTH(F=|#$I?P7-E>9%v~ zOXZkMT*h?aK!Bj9J1x^rNjKZ+8M-tvA~o!iJu)+jB${NP340MbP=rYXy9ZHX9rQ5f zw9m06ZF*0#=UPUZ@+TXgH*1-*8`GuMQRp?mlRLGIfS;lRuXh+t#!5eR)r3v3paC+K z2EB3E$xcv^%Tueh{$b~>tXa(*bv2__Cz!}^B0Hmj@1^eMdTYHywrh1$lxSvAttGL8 z)C6I?)am60E~pU};p|n!OQg6(;$;#P5_2bi9bK}BXdZD?kful3iGE~F4p9uf zkK}Q|23<-LiJ4f5ofHx$DJE`Gk~%nWdfK`)xjD2H8}ytFq_dziW9xWcXV1oMUck5= z7h-3|Azj+sfwmaCacQP4P@M4Mq4^^dtFg}ALp}O6HmHSW5qmLtDO>lbAsw<#%CZ=j zhc4m^ITZcM(_3+6Q~PEisluK{tH(K?AOH5H_NC_EWEx!;K4*b924EZS56 zuBFDv^V=q^k{ZZES%_ItI2uTClZmjhV3HB&cN>nsY#jPT(G3qWG_4) z<27tOdL2Szw-Mh9xG2)E>s9?Kkj@;$zRMPw4ISct6_yvr|9y=7_q3|$g*;IHVsnl{ zZ~ZF@-KlMR{=Ph*bFW)zVZy^sbt#3E+YhW94NANhY?q@xI2*1ue0Gtq(MAzpo{Q9Gk#SjtjuW96P{n zj*GyhIgDVY)Pz)oRFkEaxEyP-oqyAmP@deKX=yHi1(od+Dw*O{LNyYUbx+g)rOy)z zpfd@%qG&D1h3(74=sctq$Hg0@zVw{a9wmeJLeTF=_?Qr0Gzu~%>!bC)jOg?4r_XNvy+t4?m_v(=|4Q1n4@ z#vgfsno%k>qrvoi(1|rn+s6I8LXoCk%2H1eIIZSIJ*)kZ`p8n>FRI$Ail*XD5l_9N pT6NAr%2o6!lsfN@13npf@6qu^3lI)M*fAX2DL9T}Ig3EmzW~9WwIKii literal 0 HcmV?d00001 diff --git a/format_packets.py b/format_packets.py new file mode 100644 index 0000000..5ab4054 --- /dev/null +++ b/format_packets.py @@ -0,0 +1,19 @@ + +TAB_1 = '\t - ' +TAB_2 = '\t\t - ' +TAB_3 = '\t\t\t - ' +TAB_4 = '\t\t\t\t - ' + +DATA_TAB_1 = '\t ' +DATA_TAB_2 = '\t\t ' +DATA_TAB_3 = '\t\t\t ' +DATA_TAB_4 = '\t\t\t\t ' + +# Formats the output line +def format_output_line(prefix, string, size=80): + size -= len(prefix) + if isinstance(string, bytes): + string = ''.join(r'\x{:02x}'.format(byte) for byte in string) + if size % 2: + size-= 1 + return '\n'.join([prefix + line for line in textwrap.wrap(string, size)]) diff --git a/ipv4_packets.py b/ipv4_packets.py new file mode 100644 index 0000000..0f0c9c0 --- /dev/null +++ b/ipv4_packets.py @@ -0,0 +1,13 @@ +import struct + +# Unpack IPv4 Packets Recieved +def ipv4_Packet(data): + version_header_len = data[0] + version = version_header_len >> 4 + header_len = (version_header_len & 15) * 4 + ttl, proto, src, target = struct.unpack('! 8x B B 2x 4s 4s', data[:20]) + return version, header_len, ttl, proto, ipv4(src), ipv4(target), data[header_len:] + +# Returns Formatted IP Address +def ipv4(addr): + return '.'.join(map(str, addr)) \ No newline at end of file diff --git a/ipv6_packets.py b/ipv6_packets.py new file mode 100644 index 0000000..3af381a --- /dev/null +++ b/ipv6_packets.py @@ -0,0 +1,113 @@ +from format_packets import * +import struct +import socket + +def ipv6_header(data): + + first_32_bits, \ + payload_length,\ + next_header, \ + hop_limit = struct.unpack('! IHBB', data[:8]) + + version = first_32_bits >> 28 + traffic_class = (first_32_bits >> 20) & 255 + flow_label = first_32_bits & 1048575 + + src_address = socket.inet_ntop(socket.AF_INET6, data[8:24]) + dst_address = socket.inet_ntop(socket.AF_INET6, data[24:40]) + + print(TAB_1 + "IPV6 Packet:") + print(TAB_2 + "Version: {}, Traffic Class: {}, Flow Label: {}".format(version, traffic_class, flow_label)) + print(TAB_2 + "Payload Length: {}, Next Header: {}, Hop Limit: {}".format(payload_length, next_header, hop_limit)) + print(TAB_3 + "Source Address: {}".format(src_address)) + print(TAB_3 + "Destination Address: {}".format(dst_address)) + + data = data[40:] + return (next_header, data) + +def hop_by_hop_options(data): + next_header, header_length = struct.unpack('! B B', data[:2]) + + ''' + BY DEFINITION ON https://tools.ietf.org/html/rfc8200#section-4.3 + Hdr Ext Len 8-bit unsigned integer. Length of the + Hop-by-Hop Options header in 8-octet units, + not including the first 8 octets. + + + That is: 1 octet = 8 bits (1 byte) + as it uses 8 octets by default for the number in Hdr Ext len, + from that logic we have: + Hdr Ext Len * 8 + As it does not include the first 8 octets, we have + to add to it + Hdr Ext Len * 8 + 8 + ''' + + print(TAB_1 + "Hop-by-hop options:") + print(TAB_2 + "Next Header: {}, Header Length: {}".format(next_header, header_length)) + + data = data[:hdr_ext_len_converter(header_length)] + return (next_header, data) + +def hdr_ext_len_converter(octets): + return hdr_ext_len_converter_raw(octets, 8) + +def hdr_ext_len_converter_4_octets(octets): + return hdr_ext_len_converter_raw(octets, 4) + +def hdr_ext_len_converter_raw(octets, default_octet_number=8): + return int(octets*default_octet_number+8) + +def destination_options(data): + next_header, header_length = struct.unpack('! B B', data[:2]) + + print(TAB_1 + "Destination options:") + print(TAB_2 + "Next Header: {}, Header Length: {}".format(next_header, header_length)) + + # header length uses the same definition as HOP BY HOP options + + data = data[:hdr_ext_len_converter(header_length)] + return (next_header, data) + +def routing_header(data): + next_header, header_length, routing_type, segments_left = struct.unpack('! B B B B', data[:4]) + + # header length uses the same definition as HOP BY HOP options + + print(TAB_1 + "Routing Header:") + print(TAB_2 + "Header Length: {}, Routing Type: {}, Segments Left: {}".format(next_header, routing_type,segments_left)) + + data = data[:hdr_ext_len_converter(header_length)] + return (next_header, data) + +def fragment_header(data): + next_header, reserved, offset_res_flag_word, identification = struct.unpack('! B B H I', data[:8]) + + fragment_offset = offset_res_flag_word >> 3 + res = offset_res_flag_word & 6 + m_flag = offset_res_flag_word & 1 + + + print(TAB_1 + "Fragment Header:") + print(TAB_2 + 'Next Header: {}, Reserved: {}, Fragment Offset: {}'.format(next_header, reserved, fragment_offset)) + print(TAB_3 + 'Res: {}, M Flag: {}, Identification: {}'.format(res, m_flag, identification)) + + data = data[8:] + return (next_header,data) + + +# Defined on https://tools.ietf.org/html/rfc4302 +def authentication_header(data): + next_header, payload_length, reserved, spi, sequence_number = struct.unpack('! B B H I I', data[:12]) + print(TAB_1 + "Authentication Header:") + print(TAB_2 + 'Next Header: {}, Payload Length: {}, Reserved: {}'.format(next_header, payload_length, reserved)) + print(TAB_3 + 'Security Parameters Index: {}, Sequence Number Field: {}'.format(spi, sequence_number)) + + data = data[:hdr_ext_len_converter_4_octets(payload_length)] + + return (next_header, data) + +def encapsuling_header(data): + print("No next header") + return (59, data) # returns a no next header, as this one is hard as heck to calculate :). More info on: https://tools.ietf.org/html/rfc4303 diff --git a/multiple_protocol_methods.py b/multiple_protocol_methods.py new file mode 100644 index 0000000..8c18b2e --- /dev/null +++ b/multiple_protocol_methods.py @@ -0,0 +1,77 @@ +import struct +import socket +from format_packets import * + +# Unpack Ethernet Frame +def ethernet_frame(data): + dest_mac, src_mac, proto = struct.unpack('! 6s 6s H', data[:14]) + return get_mac_addr(dest_mac), get_mac_addr(src_mac), socket.htons(proto), data[14:] + + # Format MAC Address +def get_mac_addr(bytes_addr): + bytes_str = map('{:02x}'.format, bytes_addr) + mac_addr = ':'.join(bytes_str).upper() + return mac_addr + + + +def icmp_packet_template_method(data): + icmp_type, code, checksum, data = icmp_packet(data) + print(TAB_1 + 'ICMP Packet:') + print(TAB_2 + 'Type: {}, Code: {}, Checksum: {},'.format(icmp_type, code, checksum)) + print(TAB_2 + 'ICMP Data:') + print(format_output_line(DATA_TAB_3, data)) + +# Unpacks for any ICMP Packet +def icmp_packet(data): + icmp_type, code, checksum = struct.unpack('! B B H', data[:4]) + return icmp_type, code, checksum, data[4:] + + +def tcp_template_method(raw_data, data): + src_port, dest_port, sequence, acknowledgment, flag_urg, flag_ack, flag_psh, flag_rst, flag_syn, flag_fin = struct.unpack('! H H L L H H H H H H', raw_data[:24]) + print(TAB_1 + 'TCP Segment:') + print(TAB_2 + 'Source Port: {}, Destination Port: {}'.format(src_port, dest_port)) + print(TAB_2 + 'Sequence: {}, Acknowledgment: {}'.format(sequence, acknowledgment)) + print(TAB_2 + 'Flags:') + print(TAB_3 + 'URG: {}, ACK: {}, PSH: {}'.format(flag_urg, flag_ack, flag_psh)) + print(TAB_3 + 'RST: {}, SYN: {}, FIN:{}'.format(flag_rst, flag_syn, flag_fin)) + + if len(data) > 0: + # HTTP + if src_port == 80 or dest_port == 80: + print(TAB_2 + 'HTTP Data:') + try: + http = HTTP(data) + http_info = str(http.data).split('\n') + for line in http_info: + print(DATA_TAB_3 + str(line)) + except: + print(format_output_line(DATA_TAB_3, data)) + else: + print(TAB_2 + 'TCP Data:') + print(format_output_line(DATA_TAB_3, data)) + +def udp_template_method(data): + src_port, dest_port, length, data = udp_seg(data) + print(TAB_1 + 'UDP Segment:') + print(TAB_2 + 'Source Port: {}, Destination Port: {}, Length: {}'.format(src_port, dest_port, length)) + +# Unpacks for any TCP Packet +def tcp_seg(data): + (src_port, destination_port, sequence, acknowledgement, offset_reserved_flag) = struct.unpack('! H H L L H', data[:14]) + offset = (offset_reserved_flag >> 12) * 4 + flag_urg = (offset_reserved_flag & 32) >> 5 + flag_ack = (offset_reserved_flag & 32) >>4 + flag_psh = (offset_reserved_flag & 32) >> 3 + flag_rst = (offset_reserved_flag & 32) >> 2 + flag_syn = (offset_reserved_flag & 32) >> 1 + flag_fin = (offset_reserved_flag & 32) >> 1 + + return src_port, destination_port, sequence, acknowledgement, flag_urg, flag_ack, flag_psh, flag_rst, flag_syn, flag_fin, data[offset:] + + +# Unpacks for any UDP Packet +def udp_seg(data): + src_port, dest_port, size = struct.unpack('! H H 2x H', data[:8]) + return src_port, dest_port, size, data[8:] \ No newline at end of file From ef109fc7f7cdb90871d02d4e80d73eb6136583ce Mon Sep 17 00:00:00 2001 From: 11808s8 Date: Wed, 9 Dec 2020 10:41:51 -0800 Subject: [PATCH 23/29] feat: add textwrap module --- __pycache__/format_packets.cpython-36.pyc | Bin 971 -> 991 bytes .../multiple_protocol_methods.cpython-36.pyc | Bin 3031 -> 2984 bytes format_packets.py | 1 + 3 files changed, 1 insertion(+) diff --git a/__pycache__/format_packets.cpython-36.pyc b/__pycache__/format_packets.cpython-36.pyc index b2735b5256533485d24ceaf106eb874ecc995c44..060702f3ed88f38a259aee95dba2e358df1c9b56 100644 GIT binary patch delta 352 zcmYjMJx_!{5Z&2@g+saI@GG&hrM`<=kc+6bjh8F7A;#eh2^_dUVr=yv@Jsw1R@c&8 zVdY=2a)4-VH}l?P-kaIkPit%8)ODTUbQ3w8u`jlB1m#y0*V#iA z<#komRn!e1H)rC=J0Xh?n*PdsM;{P1H)6I_&TY5|qeXZfO?UE{?)<|t|0@qK*g=+K SoyKz@N9hsR+<^Z6vG@fXJ4ZDD delta 348 zcmYjMJ5Izf5cSy3XG0>b0PP*p(CkVStX2e3(-0_35g{gvA|;z(ClZ2|3!vPAo^x=6 zG!zt6Twp6E2?9KtH#2(A&*OLJ&AFThfp_%zl5Byo5BBc}>W?YS0Rb|_5ELL+9EB1n zl|)NfXe%2X<)Duf^qxSuxO2|J;1y>8R{IEdFm1n}IJC$__YiU|sdO^WHfac*UFme4 z-4C3$iP?I~JTvu8SyZdN_L-+wey_Jpt+UN-Cr$Q{j!vL^X1LVtu1j59*GbvbRZ}Ou zc|fG;6%2gvU>{rxJ)`+71Wn&%;iSC~i@5Vnqc}?9=p>n|zkV@j$HjivA768qMTt$G Pt~j}vDS?C`_)itzw^ByD diff --git a/__pycache__/multiple_protocol_methods.cpython-36.pyc b/__pycache__/multiple_protocol_methods.cpython-36.pyc index 2e955d8a1cf63447a93d5c1f73ebe9b3a324fc9d..e6e79bbece0167ef81078c201bf184ba308afc20 100644 GIT binary patch delta 634 zcmZ9J%}X0W7{+(@V|I48o7h;B_*n%h4ZYM4G>7z{UId}^&{HoVtfNVFlVx^ts1!UD zJct*0d-EuW7eUCMqEHwR)SCy-LJ!4xO=)9b-`@_i?>x`*&i*Q#7W}y|^pEaNst>`T ze?%(q-pj+a?+!@wJNZF0O-<{oeRwlCZGGJFrY09sd{*x=hGCQ(MN=u-kyNzZOlr{< zRLC+3VVCUrwr()U2oYI$X?|jgZnQ*PldxgVOo#fDcmm1@suAc)abb`bBtry+bAK2v z&EtY{647W%<$PXRuFiB{vmyrv)|+>p?pIzTij%7RmT+Z9t#z(gROiuF+K#&(T_d=% zCP@zdSi1{&N{k}L5aWoxNJDyWL|6K6jG<1)UNi^t*jzvq5jprxM~Me{cS^JD?)A;4 z24$qP@i^J8NnVY)thd%*!>xN!?pM-sC0jgYdyCQ~jW2YYH#cRyHy+%xB3bNEj}dK| z_2c66?8-&Uly823pZ@;Jb3tXNjUC=AhgNeMYr6hVi#w%2;Pk?UTJWlz#U=hAF@eAf e60?YTL`s&Z*d)wO4%SGJ zXb;}X96c7qlb2k@f53wW4}}52Tk+;Q%vKD0`joZEF_O1RKE3Q z<&l1LiKA6n8*2~4#cW&Rj(lk>+|1#HyB#IHP`v6fWk%hYDH^p|w43&mtU^{seldJf zl0S^$3P$lc#1+I<#Dt(S*w7<20oVgCkKdVh^=XvCD~Kw>k>Bk(l9MO)JkWIxCOT6k z5rHiC#a0wsUD zN%g#T Date: Wed, 9 Dec 2020 10:56:57 -0800 Subject: [PATCH 24/29] feat: Facelift on the README.md doc --- README.md | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b274a63..7f87c3a 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,38 @@ ## Overview -Packet Sniffer created in Python 3. Allows you to monitor traffic running through local network. Allows the user to be able to view Source of the packets, Target host and the type of protocol used e.g. UDP/TCP. +Packet Sniffer created in Python 3. +It allows you to monitor traffic running through local network. Allows the user to be able to view Source of the packets, Target host and the type of protocol used e.g. UDP,TCP, ICMP. More on the details subsection ## Requirement - - Python 3.x + - Python 3.6.9 (untested with others, be my guest :) ) - Privileged/Administrative Rights - Linux or Windows Operating System + +## Usage + +On linux: +```bash +sudo python3 Packet-Sniffer.py +``` + +On Windows: + To be defined + +## Details + +Protocols recognized: IPv4, IPv6, ARP +Within IPv4: TCP, UDP, ICMP. +Within IPv6: TCP, UDP, ICMPv6, Hop-by-Hop Options, Destination options, Routing, Fragment, Authentication, Encapsuling Header ( This one is just a dummy recognition as of now :) ) + +The original package has been broken down into a more structured approach, separating responsibilities from IPv4/IPv6 packets into their own files, as well as shared protocols into a file to be used by both. The Packet-Sniffer.py could use a few more cleanups since we have some outputs there still. + +The output formatting is a bit on the nose and needs refactoring, since it's not optimal the way it's done now. + +IPv6 next header order is based on RFC8200 [1]. Other RFCs are referenced throughout the code. + + +** The Python 3 sockets library, for capturing the packets, is using AF_PACKET for capturing both internet protocols. Beware of that, since there are AF_INET/AF_INET6 for specific protocols (IPv4 only, IPv6 only) and your use case might not fit. More on: [2] + +[1] https://tools.ietf.org/html/rfc8200 +[2] https://docs.python.org/3/library/socket.html From d4f9c7918d4d7b4dcd5d42a42be958572599b63e Mon Sep 17 00:00:00 2001 From: 11808s8 Date: Wed, 9 Dec 2020 10:58:35 -0800 Subject: [PATCH 25/29] refactor: I'm not a pro on .md, excuse me --- README.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 7f87c3a..bf760f5 100644 --- a/README.md +++ b/README.md @@ -22,18 +22,20 @@ On Windows: ## Details -Protocols recognized: IPv4, IPv6, ARP -Within IPv4: TCP, UDP, ICMP. +Protocols recognized: IPv4, IPv6, ARP
+Within IPv4: TCP, UDP, ICMP.
Within IPv6: TCP, UDP, ICMPv6, Hop-by-Hop Options, Destination options, Routing, Fragment, Authentication, Encapsuling Header ( This one is just a dummy recognition as of now :) ) -The original package has been broken down into a more structured approach, separating responsibilities from IPv4/IPv6 packets into their own files, as well as shared protocols into a file to be used by both. The Packet-Sniffer.py could use a few more cleanups since we have some outputs there still. +The original package has been broken down into a more structured approach, separating responsibilities from IPv4/IPv6 packets into their own files, as well as shared protocols into a file to be used by both. +The Packet-Sniffer.py could use a few more cleanups since we have some outputs there still. The output formatting is a bit on the nose and needs refactoring, since it's not optimal the way it's done now. IPv6 next header order is based on RFC8200 [1]. Other RFCs are referenced throughout the code. -** The Python 3 sockets library, for capturing the packets, is using AF_PACKET for capturing both internet protocols. Beware of that, since there are AF_INET/AF_INET6 for specific protocols (IPv4 only, IPv6 only) and your use case might not fit. More on: [2] +* The Python 3 sockets library, for capturing the packets, is using AF_PACKET for capturing both internet protocols. Beware of that, since there are AF_INET/AF_INET6 for specific protocols (IPv4 only, IPv6 only) and your use case might not fit. More on: [2] + +[1] https://tools.ietf.org/html/rfc8200 -[1] https://tools.ietf.org/html/rfc8200 [2] https://docs.python.org/3/library/socket.html From b2b7a98fcd06a751aa5116cae7b9a541078889d5 Mon Sep 17 00:00:00 2001 From: 11808s8 Date: Wed, 9 Dec 2020 11:02:31 -0800 Subject: [PATCH 26/29] feat: simple .gitignore file --- .gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..763624e --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +__pycache__/* \ No newline at end of file From 3a1fe74f9352b24da8f24ddaf2192b0e13f4239c Mon Sep 17 00:00:00 2001 From: 11808s8 Date: Wed, 9 Dec 2020 11:03:23 -0800 Subject: [PATCH 27/29] refactor: exclude __pycache__ generated files --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 763624e..ba0430d 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -__pycache__/* \ No newline at end of file +__pycache__/ \ No newline at end of file From 7b710cbc0e4a538c90e44706f780a2ac60162623 Mon Sep 17 00:00:00 2001 From: 11808s8 Date: Wed, 9 Dec 2020 11:05:02 -0800 Subject: [PATCH 28/29] refactor: actually removing the pycache folder :) --- __pycache__/format_packets.cpython-36.pyc | Bin 991 -> 0 bytes __pycache__/ipv4_packets.cpython-36.pyc | Bin 641 -> 0 bytes __pycache__/ipv6_packets.cpython-36.pyc | Bin 3499 -> 0 bytes .../multiple_protocol_methods.cpython-36.pyc | Bin 2984 -> 0 bytes 4 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 __pycache__/format_packets.cpython-36.pyc delete mode 100644 __pycache__/ipv4_packets.cpython-36.pyc delete mode 100644 __pycache__/ipv6_packets.cpython-36.pyc delete mode 100644 __pycache__/multiple_protocol_methods.cpython-36.pyc diff --git a/__pycache__/format_packets.cpython-36.pyc b/__pycache__/format_packets.cpython-36.pyc deleted file mode 100644 index 060702f3ed88f38a259aee95dba2e358df1c9b56..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 991 zcmaJfgc5ZzsW#5PFG`zM~OlH5Ob1(j9wqs96$Q--nT5fbc+}A%;GBfkK9W02EKb z%+be(3(U|M+AQ&VgwZK6bCX%{VfyXO*7kI95M$+!NZh_On$b!!N09i6R?~Qr>j5@I<0u`ktVLEaMA4fbzylXt1~&svm$MG^KzKvqSwCNvC`EmEr7z&UqZML zdknAG0CTLRs4ws(2(gKNkW;sB=QBgbgzGy~u5O~`sCYWcrY6U0khzMwc_!qroK!u1 zoZ;xB*^B>jyxkJ}%E{A0MVZJ7A(LX5Do=|nlshi7LIpCN%C9`Bl&fv*@P_8&3&}xk z<%(>UTBg`!3@Nq#Z}&A#t_}v_I*#xL4&dRN@Ev2WrHUi2MN!_--n+p|3)>cUs0r?> wXn*f$Z(s}V{B3&Y@7(iu&GA+%{m0y?rh@LIWM_HW)Au9R!34y`=D9)V5B*{2O8@`> diff --git a/__pycache__/ipv4_packets.cpython-36.pyc b/__pycache__/ipv4_packets.cpython-36.pyc deleted file mode 100644 index be3a1cd39cf5536261b4b2158fbcaa249b43f435..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 641 zcmYjPyKdVs6ul(%s+;tMECDjOqXtJnnju5c1j%j$$R-pJ2$7EE+LA!hK~hkY(_bmj zF~7sLKmh+jr(Q~FVN&-{_vn!KL4DfaADuk^ES?C!Z`c_W-!IVg5rP0gmXL#>f;~b` zL?A+3sUSCyMq5?P#bLsV!R<1EEC|Bv)IR;Dj#+mczBEO{r$)B+5Pwu=gIx} zRO7QfKt5$I(nhUIx|PTo3Hc3+vM?2Bki3AKdGn7(~8qJwgDI;M^leM7=}r|7G~@cu{{D{)-?B zFus}C>W#lXI(6h2+Y>CBs&;I}TP(|{l(>Kkq57f*@cmUW!XBFTKM0WCPninQ=_B{V a&L-az<#)Q|^QsZ+rTpS^(mtt#CCOiqVVDU3 diff --git a/__pycache__/ipv6_packets.cpython-36.pyc b/__pycache__/ipv6_packets.cpython-36.pyc deleted file mode 100644 index fc816e58cd526963bd19a38b2d7cb4dfb4338633..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3499 zcmcguTW=dh6yA$>y>{%RO>=3Wlr12EtEN#?sH%c`Ng+z4VxlJM!wPA&@vM^#&aRmq zx6NWpNGX2>iGRQk;b~uaK>iE7l<&;g8#hf`9uT&6&d%90bMBX$^?LR9zkc;s&uiMB z+QiSq`+YoVjD=}T?`S&&jgIc=5*nVtOjdfKc_y=%4On7j<^Wo(!m5BayU1#+{zCW4 zY?{pg*vI~G!Hpk`xr`Q5p1gtS*TWc&0!BcDKxqh|T(&-()DjplpLp<$!eQhPj0ze zLF2kmy$avyerG*zhePV&rs6zql_+Gndj3U=$j9Sgiy5g?6YeNIqXBQA5%ezO*u(F$UDG1U#*+;L(k#xpHtToEKg7cgb zn@`g+L(4f@P>r;FexGrl{0OJ|tt5u;M93Q^zd$7OL{e8q8o6D%M=g{i`7Akp_sAzO zl8o{xC61bYaki$<8RvBV0d|G?sN9eVrTK_ZXfT9+Ov!09IekK5S~^oSp9jzI(N0<- z6zM5x`1?5e1)h|wrs;D3FWC-DIMLAgWd%M2ICXn|`D}?k_mwcWab(Q+3LPg!T2d0c z5G<4?2awWzeGZCKEWDz+i5zVhoMiCkSlAAF9if=`aqn<9)^A8^}|M%m2cq=(wRH*N{pE!7()^7xuNrr9~_hN@|7hkJ)% zEK-oQW#f2PvMcLZC#fy1=he7k?+aY*)zi_n$oIB5ZQAKEt*Qx|5PxLVOC^*`%Jffw zE38WWwXo{X*u2fEeUwT$P+;Pb!vtm?HB6w0+M^avMYODnXx}PE0Rtn111yGylK}xf zFpB0sF07SiHnRVQyD2ktNck}&DTh>;vUBS^kd`g{vHDt}eH^ACe;P97iQ>R_?RJVO zfg1m(AW>hxb=Nz=o_gP8@K}VAK{j&2z0+y4kg4IEI4yTD6iDXYTq61TK=^I&@Si1| zdDGD=OuU))NFQI3=O*Yq`%oS^?cft)<>4K0Pe}w#r`CwSDcd5o#H+v-o+kShp6+0C zhNrFZ=s2+6kU<#mUh$~~pO)a~$#z*jqg~p~Y)WMnyy|WaYY-q?c+eC3WN&5d!ksr> zbLUw@8vIwdIJ>9toTbcb)bnXIe~!m9Ww9xIlT(+R9c1m2c9OkL)^1s9WE4uJ q1e*5O_e7w(HE0vsICcnCW6$ts0 z%=|RK_n}8GfiS{opET2vHYq%7eXT*5&Ws;OQ)ec#U^G~c*)We&hGK(?z?((7%C7=8wH3;G81=q?aJdX&)^kD&diT_j`e zrJm44OLU>dbWDM2K=qyx>tmGD7(uy?0bA(Xqx@3kPK5uhNg0-_n$n5{AGU?GhJM&; z@5|z@C)`1+?Y0=>FdMY@Jt56K5%^KnkOpgsmb94{DJhwYcpJr~8S+2`zY$)7b>H<@ z_JV=8(qg>Z@`IIjz`FkKN_Zgl0{@V^oIWn&ww_py{BEb?@s+v~TCS(uos2se_C+`B zd#>819rWFS2aB=jW_TdW06p%*!8^P)@K9qBs*cc0l+VF9Rj3XR*p))B0uW%+9w=(8 zC6sABrNo{-CJ87qRhjj+c5C%b@{ZQv`ud<1N~;s_K}$%Z7j%7T4#UvnRlVtacObk- z>8+VhG3d5wA1YI6CMBqQj>iOlBM|~Zi?mD?Z+h5c)~|z%AaGFn(nu|y5CQgP^aAiG zVjV7E#5C5x_WBI>2%EyftD-z3a6MytRD87Yb-j{myEa;C9E4u2@;13q*$CJn+Vk4` z(Qu&nBS*ck32soU=47GU9)xacLiB;I56;q9f8gFuhgCig2bc4y%G_Wm!l7{cUEh<= z=6Yk@McK8g!Sg7VSE~s)gEYWrJZZPHy-z4lUY^<472Y81w}hAZ1nw9)KnOhpYCR8~ zqpeR@>`j>Y=deoE`FlSR<(sMy%3S9ZMJf#-|b=;NJW z$lG3}9&nL{z$Rq5uHO>fz@KtQ@WQL1=eM)qSa0w9!Rx-q(p4aIM%KfAYd5NmEl<0`<~x4a22UTCQ3uhjKY3baCAO?5lD4T+PwAJ#k`(M*qG8o zP=d^>G_Rl?Ww&mYAu-R~SlS)9tvlqq8G`8yh0$JycqB3u9rzjQbm4G&LWIpcQn%}O z0%>4oI1w!JtZ0WPWBemHdh`hpLa#x5FF?acKd+Uwc|aPqA@&`*NG;$&{I7!K>G6LD zX8wC(Rqh1^wfJmv#)WSGD;K&^dE)uIVh`;O6*xC!p&NO-rRT~Vw36j2s0K)VgWYq6K35b zNiM?%U^~M(!1)Z@fSnBI0T*U41T&^4NJWrp($o?cV-j20Crbeel(Ri5%mgsU+C3=( z;phO93KGn^6E%V9bAkbMEFqVaTXR%l^9*`)7ShVc`E_K^9r?6}$)LFqbUG1yPjD~t z`1c-j(aEKia`~t54!?n983|SpzJlZylH;jf=Foe=ykEdvgr$klt6+_prg8kVn_A{r z+5dml$w_s#`UVP=4Qn6MM^>PwE+vhqJ31M3d<|ZE4E?A=A*WhMQ%?@CEN4YMt^Sev z(o$bAs@ig_Xe#cM Date: Thu, 10 Dec 2020 12:16:32 -0800 Subject: [PATCH 29/29] comment: doc linking to WHY a hardcoded number is read for IPv6 packet identification --- Packet-Sniffer.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Packet-Sniffer.py b/Packet-Sniffer.py index f3d0a08..19089c7 100644 --- a/Packet-Sniffer.py +++ b/Packet-Sniffer.py @@ -39,7 +39,9 @@ def main(): else: print(TAB_1 + 'Other IPv4 Data:') print(format_output_line(DATA_TAB_2, data)) - elif(eth_proto == 56710): # IPv6 + elif(eth_proto == 56710): # IPv6 - It is 56710 as htons converts it FROM 34525 + # (the original value read - which is 86DD in HEX and indicates the packet being IPv6 + # - more info on https://tools.ietf.org/html/rfc2464#section-3) next_header, data = ipv6_packets.ipv6_header(data)