def phrx_ether(self, ether_packet_rx): """ Handle inbound Ethernet packets """ # Validate Ethernet packet sanity if ether_packet_rx.sanity_check_failed: return self.logger.debug(f"{ether_packet_rx.tracker} - {ether_packet_rx}") # Check if received packet matches any of stack MAC addresses if ether_packet_rx.ether_dst not in { self.mac_unicast, *self.mac_multicast, self.mac_broadcast }: self.logger.opt(ansi=True).debug( f"{ether_packet_rx.tracker} - Ethernet packet not destined for this stack, droping" ) return if ether_packet_rx.ether_type == ps_ether.ETHER_TYPE_ARP and config.ip4_support: self.phrx_arp(ether_packet_rx, ps_arp.ArpPacket(ether_packet_rx)) return if ether_packet_rx.ether_type == ps_ether.ETHER_TYPE_IP4 and config.ip4_support: self.phrx_ip4(ps_ip4.Ip4Packet(ether_packet_rx)) return if ether_packet_rx.ether_type == ps_ether.ETHER_TYPE_IP6 and config.ip6_support: self.phrx_ip6(ps_ip6.Ip6Packet(ether_packet_rx)) return
def phrx_ether(self, ether_packet_rx): """ Handle inbound Ethernet packets """ self.logger.debug(f"{ether_packet_rx.tracker} - {ether_packet_rx}") # Check if received packet uses valid Ethernet II format if ether_packet_rx.ether_type < ps_ether.ETHER_TYPE_MIN: self.logger.opt(ansi=True).debug(f"{ether_packet_rx.tracker} - Packet doesn't comply with the Ethernet II standard, droping") return # Check if received packet matches any of stack MAC addresses if ether_packet_rx.ether_dst not in {*self.stack_mac_unicast, *self.stack_mac_multicast, *self.stack_mac_broadcast}: self.logger.opt(ansi=True).debug(f"{ether_packet_rx.tracker} - Ethernet packet not destined for this stack, droping") return if ( ether_packet_rx.ether_type == ps_ether.ETHER_TYPE_ARP and stack.ip4_support and ps_arp.preliminary_sanity_check(ether_packet_rx.raw_data, ether_packet_rx.tracker, self.logger) ): self.phrx_arp(ether_packet_rx, ps_arp.ArpPacket(ether_packet_rx)) return if ( ether_packet_rx.ether_type == ps_ether.ETHER_TYPE_IP4 and stack.ip4_support and ps_ip4.preliminary_sanity_check(ether_packet_rx.raw_data, ether_packet_rx.tracker, self.logger) ): self.phrx_ip4(ps_ip4.Ip4Packet(ether_packet_rx)) return if ( ether_packet_rx.ether_type == ps_ether.ETHER_TYPE_IP6 and stack.ip6_support and ps_ip6.preliminary_sanity_check(ether_packet_rx.raw_data, ether_packet_rx.tracker, self.logger) ): self.phrx_ip6(ps_ip6.Ip6Packet(ether_packet_rx)) return
__send_out_packet() return # Send out packet if we are able to obtain destinaton MAC from ICMPv6 ND cache if mac_address := stack.icmp6_nd_cache.find_entry( ip6_packet_tx.ip6_dst): ether_packet_tx.ether_dst = mac_address self.logger.debug( f"{ether_packet_tx.tracker} - Resolved destiantion IPv6 {ip6_packet_tx.ip6_dst} to MAC {ether_packet_tx.ether_dst}" ) __send_out_packet() return # Check if we can obtain destination MAC based on IPv4 header data if ether_packet_tx.ether_type == ps_ether.ETHER_TYPE_IP4: ip4_packet_tx = ps_ip4.Ip4Packet(ether_packet_tx) # Send out packet if its destinied to limited broadcast addresses if ip4_packet_tx.ip4_dst == IPv4Address("255.255.255.255"): ether_packet_tx.ether_dst = "ff:ff:ff:ff:ff:ff" self.logger.debug( f"{ether_packet_tx.tracker} - Resolved destiantion IPv4 {ip4_packet_tx.ip4_dst} to MAC {ether_packet_tx.ether_dst}" ) __send_out_packet() return # Send out packet if its destinied to directed broadcast or network addresses (in relation to its source address) for stack_ip4_address in self.stack_ip4_address: if stack_ip4_address.ip == ip4_packet_tx.ip4_src: if ip4_packet_tx.ip4_dst in { stack_ip4_address.network[0],
def main(): while True: raw_packet_rx = raw_socket.recv(2048) ether_packet_rx = ps_ether.EtherPacket(raw_packet_rx) if ether_packet_rx.ether_type == ps_ether.ETHER_TYPE_ARP: arp_packet_rx = ps_arp.ArpPacket(ether_packet_rx) print("-" * 160) print(ether_packet_rx) print(arp_packet_rx) print("-" * 160) continue if ether_packet_rx.ether_type == ps_ether.ETHER_TYPE_IP6: ip6_packet_rx = ps_ip6.Ip6Packet(ether_packet_rx) if ip6_packet_rx.ip6_next == ps_ip6.IP6_NEXT_HEADER_ICMP6: icmp6_packet_rx = ps_icmp6.Icmp6Packet(ip6_packet_rx) print("-" * 160) print(ether_packet_rx) print(ip6_packet_rx) print(icmp6_packet_rx) print("-" * 160) continue print("-" * 160) print(ether_packet_rx) print(ip6_packet_rx) continue if ether_packet_rx.ether_type == ps_ether.ETHER_TYPE_IP6: ip4_packet_rx = ps_ip4.Ip4Packet(ether_packet_rx) if ip4_packet_rx.ip4_proto == ps_ip4.IP4_PROTO_ICMP4: icmp4_packet_rx = ps_icmp4.Icmp4Packet(ip4_packet_rx) print("-" * 160) print(ether_packet_rx) print(ip4_packet_rx) print(icmp4_packet_rx) print("-" * 160) continue if ip4_packet_rx.ip4_proto == ps_ip4.IP4_PROTO_UDP: udp_packet_rx = ps_udp.UdpPacket(ip4_packet_rx) print("-" * 160) print(ether_packet_rx) print(ip4_packet_rx) print(udp_packet_rx) print("-" * 160) continue if ip4_packet_rx.ip4_proto == ps_ip4.IP4_PROTO_TCP: tcp_packet_rx = ps_tcp.TcpPacket(ip4_packet_rx) if 22 in {tcp_packet_rx.tcp_dport, tcp_packet_rx.tcp_sport}: continue print("-" * 160) print(ether_packet_rx) print(ip4_packet_rx) print(tcp_packet_rx) print("-" * 160) continue print("-" * 160) print(ether_packet_rx) print(ip4_packet_rx) print("-" * 160) continue print("-" * 160) print(ether_packet_rx)
def phtx_ip4(self, child_packet, ip4_dst, ip4_src): """ Handle outbound IP packets """ # Check if IPv4 protocol support is enabled, if not then silently drop the packet if not stack.ip4_support: return # Make sure source and destination addresses are the right object type ip4_src = IPv4Address(ip4_src) ip4_dst = IPv4Address(ip4_dst) # Validate source address ip4_src = validate_src_ip4_address(self, ip4_src, ip4_dst) if not ip4_src: return # Validate destination address ip4_dst = validate_dst_ip4_address(self, ip4_dst) if not ip4_dst: return # Generate new IPv4 ID self.ip4_packet_id += 1 if self.ip4_packet_id > 65535: self.ip4_packet_id = 1 # Check if packet can be sent out without fragmentation, if so send it out if ps_ip4.IP4_HEADER_LEN + len(child_packet.raw_packet) <= stack.mtu: ip4_packet_tx = ps_ip4.Ip4Packet(ip4_src=ip4_src, ip4_dst=ip4_dst, ip4_packet_id=self.ip4_packet_id, child_packet=child_packet) self.logger.debug(f"{ip4_packet_tx.tracker} - {ip4_packet_tx}") self.phtx_ether(child_packet=ip4_packet_tx) return # Fragment packet and send all fragments out self.logger.debug( "Packet exceedes available MTU, IP fragmentation needed...") if child_packet.protocol == "ICMPv4": ip4_proto = ps_ip4.IP4_PROTO_ICMP4 raw_data = child_packet.get_raw_packet() if child_packet.protocol in {"UDP", "TCP"}: ip4_proto = ps_ip4.IP4_PROTO_UDP if child_packet.protocol == "UDP" else ps_ip4.IP4_PROTO_TCP raw_data = child_packet.get_raw_packet( struct.pack( "! 4s 4s BBH", socket.inet_aton(ip4_src), socket.inet_aton(ip4_dst), 0, ip4_proto, len(child_packet.raw_packet), )) raw_data_mtu = (stack.mtu - ps_ether.ETHER_HEADER_LEN - ps_ip4.IP4_HEADER_LEN) & 0b1111111111111000 raw_data_fragments = [ raw_data[_:raw_data_mtu + _] for _ in range(0, len(raw_data), raw_data_mtu) ] pointer = 0 offset = 0 for raw_data_fragment in raw_data_fragments: ip4_packet_tx = ps_ip4.Ip4Packet( ip4_src=ip4_src, ip4_dst=ip4_dst, ip4_proto=ip4_proto, ip4_packet_id=self.ip4_packet_id, ip4_frag_mf=pointer < len(raw_data_fragments) - 1, ip4_frag_offset=offset, raw_data=raw_data_fragment, tracker=child_packet.tracker, ) pointer += 1 offset += len(raw_data_fragment) self.logger.debug(f"{ip4_packet_tx.tracker} - {ip4_packet_tx}") self.phtx_ether(child_packet=ip4_packet_tx) return