diff --git a/networking/ethernet.py b/networking/ethernet.py index f4b81fc..1525eb4 100644 --- a/networking/ethernet.py +++ b/networking/ethernet.py @@ -11,7 +11,7 @@ def __init__(self, raw_data): self.dest_mac = get_mac_addr(dest) self.src_mac = get_mac_addr(src) - self.proto = socket.htons(prototype) + self.proto = int(prototype) self.data = raw_data[14:] diff --git a/networking/icmpv6.py b/networking/icmpv6.py new file mode 100644 index 0000000..d5b89c5 --- /dev/null +++ b/networking/icmpv6.py @@ -0,0 +1,26 @@ +from networking.icmpv6_messages import ICMPv6Messages + +class ICMPv6: + + def __init__(self, raw_data): + + self.messages = ICMPv6Messages() + self.icmpv6_data = raw_data[:8] + self.type = self.icmpv6_data[0] + self.code = self.icmpv6_data[1] + self.checksum = self.icmpv6_data[2] << 8 | self.icmpv6_data[3] + self.message_body = self.icmpv6_data[5:8] + self.data = raw_data[8:] + + def __str__(self): + result = '\t - ICMPv6 Packet:\n' + result += f'\t\t - Type: {self.type}, Type Name: {self.messages.icmp6_types[self.type]}\n' + result += f'\t\t - Code: {self.code}' + try: + result += f'\t\t - Code Name: {self.messages.icmp6_codes[self.type][self.code]}\n' + except: + result += '\n' + result += f'\t\t - Checksum: {self.checksum}\n' + result += f'\t\t - ICMPv6 Data: {self.data}\n' + + return result \ No newline at end of file diff --git a/networking/icmpv6_messages.py b/networking/icmpv6_messages.py new file mode 100644 index 0000000..cb5d3a8 --- /dev/null +++ b/networking/icmpv6_messages.py @@ -0,0 +1,73 @@ +class ICMPv6Messages(): + + def __init__(self): + + self.icmp6_types = { + 1: "Destination unreachable", + 2: "Packet too big", + 3: "Time exceeded", + 4: "Parameter problem", + 100: "Private Experimentation", + 101: "Private Experimentation", + 128: "Echo Request", + 129: "Echo Reply", + 130: "MLD Query", + 131: "MLD Report", + 132: "MLD Done", + 133: "Router Solicitation", + 134: "Router Advertisement", + 135: "Neighbor Solicitation", + 136: "Neighbor Advertisement", + 137: "Redirect Message", + 138: "Router Renumbering", + 139: "ICMP Node Information Query", + 140: "ICMP Node Information Response", + 141: "Inverse Neighbor Discovery Solicitation Message", + 142: "Inverse Neighbor Discovery Advertisement Message", + 143: "MLD Report Version 2", + 144: "Home Agent Address Discovery Request Message", + 145: "Home Agent Address Discovery Reply Message", + 146: "Mobile Prefix Solicitation", + 147: "Mobile Prefix Advertisement", + 148: "Certification Path Solicitation", + 149: "Certification Path Advertisement", + 151: "Multicast Router Advertisement", + 152: "Multicast Router Solicitation", + 153: "Multicast Router Termination", + 155: "RPL Control Message", + 200: "Private Experimentation", + 201: "Private Experimentation" + } + + self.icmp6_codes = { + 1: { + 0: "No route to destination", + 1: "Communication with destination administratively prohibited", + 2: "Beyond scope of source address", + 3: "Address unreachable", + 4: "Port unreachable", + 5: "source address failed ingress/egress policy", + 6: "reject route to destination", + 7: "Error in Source Routing Header" + }, + 3: { + 0: 'hop limit exceeded in transit', + 1: 'fragment reassembly time exceeded' + }, + 4: { + 0: 'erroneous header field encountered', + 1: 'unrecognized Next Header type encountered', + 2: 'unrecognized IPv6 option encountered' + }, + # 130: "MLD Query", # TODO + 138: { + 0: 'Router Renumbering Command', + 1: 'Router Renumbering Result', + 255: 'Sequence Number Reset' + }, + 139: { + 0: 'The Data field contains an IPv6 address which is the Subject of this Query.', + 1: 'The Data field contains a name which is the Subject of this Query, or is empty, as in the case of a NOOP.', + 2: 'The Data field contains an IPv4 address which is the Subject of this Query.' + } + } \ No newline at end of file diff --git a/networking/ipv6.py b/networking/ipv6.py new file mode 100644 index 0000000..777ff49 --- /dev/null +++ b/networking/ipv6.py @@ -0,0 +1,29 @@ +from socket import * +import ipaddress + + +class IPv6: + + def __init__(self, raw_data, addr): + + self.ipv6_data = raw_data[:40] + self.version = self.ipv6_data[0] >> 4 + self.trafic_class = self.ipv6_data[0] << 4 | self.ipv6_data[1] >> 4 + self.flow_label = ((self.ipv6_data[1] & 0x00FF) << 16) | (self.ipv6_data[2] << 8) | self.ipv6_data[3] + self.payload_len = (self.ipv6_data[4] << 8) | self.ipv6_data[5] + self.next_header = self.ipv6_data[6] + self.hop_limit = self.ipv6_data[7] + self.src = ipaddress.IPv6Address(self.ipv6_data[8:24]) + self.dest = ipaddress.IPv6Address(self.ipv6_data[24:40]) + self.data = raw_data[40:] + + def __str__(self): + + return ( + '\t - IPv6 Packet:\n' + f'\t\t - Version: {self.version}, Trafic Class: {self.trafic_class},\n' + f'\t\t - Flow Label : {self.flow_label}, Payload lenght: {self.payload_len},\n' + f'\t\t - Next Header: {self.next_header}, Hop Limit: {self.hop_limit},\n' + f'\t\t - Source: {self.src}\n' + f'\t\t - Destination: {self.dest}\n' + ) \ No newline at end of file diff --git a/sniffer.py b/sniffer.py index 116cc6c..c303663 100644 --- a/sniffer.py +++ b/sniffer.py @@ -7,6 +7,8 @@ from networking.udp import UDP from networking.pcap import Pcap from networking.http import HTTP +from networking.ipv6 import IPv6 +from networking.icmpv6 import ICMPv6 TAB_1 = '\t - ' TAB_2 = '\t\t - ' @@ -32,7 +34,7 @@ def main(): print(TAB_1 + 'Destination: {}, Source: {}, Protocol: {}'.format(eth.dest_mac, eth.src_mac, eth.proto)) # IPv4 - if eth.proto == 8: + if eth.proto == 2048: ipv4 = IPv4(eth.data) print(TAB_1 + 'IPv4 Packet:') print(TAB_2 + 'Version: {}, Header Length: {}, TTL: {},'.format(ipv4.version, ipv4.header_length, ipv4.ttl)) @@ -83,11 +85,21 @@ def main(): print(TAB_1 + 'Other IPv4 Data:') print(format_multi_line(DATA_TAB_2, ipv4.data)) + #IPv6 + elif eth.proto == 34525: + ipv6 = IPv6(eth.data, addr) + print(str(ipv6)) + + # ICMPv6 + if ipv6.next_header == 58: + icmpv6 = ICMPv6(ipv6.data) + print(str(icmpv6)) + else: + print('Other IPv6 Data:') + print(format_multi_line(DATA_TAB_2, ipv6.data)) else: print('Ethernet Data:') print(format_multi_line(DATA_TAB_1, eth.data)) - pcap.close() - main()