public void injectRemotePacket(ref byte[] data, PhysicalAddress dstMAC, PhysicalAddress srcMAC, ref xbs_node sending_node) { Packet p = null; ARPPacket p_arp = null; IPv4Packet p_ipv4 = null; ICMPv4Packet p_icmp = null; UdpPacket p_udp = null; TcpPacket p_tcp = null; IPAddress source_IP = null; int srcMac_hash = srcMAC.GetHashCode(); // collect all injected source MACs. sniffer needs this to filter packets out lock (injected_macs_hash) { if (!injected_macs_hash.Contains(srcMac_hash)) { injected_macs_hash.Add(srcMac_hash); addMacToKnownMacListFromRemoteNodes(srcMAC); } } if (sending_node != null) { if (sending_node.addXbox(srcMAC)) { node_list.listHasJustChanged(); } } try { p = Packet.ParsePacket(LinkLayers.Ethernet, data); } catch (PcapException pcex) { #if DEBUG xbs_messages.addDebugMessage("!! ERROR! parse packet failed in injectRemotePacket (1): " + pcex.ToString(), xbs_message_sender.SNIFFER, xbs_message_type.ERROR); #endif return; } catch (NotImplementedException niex) { #if DEBUG xbs_messages.addDebugMessage("!! ERROR! parse packet failed in injectRemotePacket (2): " + niex.ToString(), xbs_message_sender.SNIFFER, xbs_message_type.ERROR); #endif return; } // DETERMINE PACKET TYPE if (p.PayloadPacket is IPv4Packet) { p_ipv4 = p.PayloadPacket as IPv4Packet; source_IP = p_ipv4.SourceAddress; if (p_ipv4.PayloadPacket is UdpPacket) { p_udp = p_ipv4.PayloadPacket as UdpPacket; } else if (p_ipv4.PayloadPacket is TcpPacket) { p_tcp = p_ipv4.PayloadPacket as TcpPacket; } } else if (p.PayloadPacket is ARPPacket) { p_arp = p.PayloadPacket as ARPPacket; source_IP = p_arp.SenderProtocolAddress; } else if (p.PayloadPacket is ICMPv4Packet) { p_icmp = p.PayloadPacket as ICMPv4Packet; } else { // UNKNOWN OR UNSUPPORTED PACKET TYPE #if DEBUG //xbs_messages.addDebugMessage("?? WARNING! unknown incoming packet type: " + p.ToString(), xbs_message_sender.SNIFFER, xbs_message_type.WARNING); #endif return; } // filter packet if needed if (is_injected_packet_to_be_filtered(ref p_arp, ref p_ipv4, ref p_udp, ref p_tcp)) { #if DEBUG xbs_messages.addDebugMessage("i> filtered packet: " + p, xbs_message_sender.SNIFFER); #endif return; } // add IP to device from node if (sending_node != null && source_IP != null) { if (sending_node.addIPtoXbox(srcMAC, source_IP)) { #if DEBUG xbs_messages.addDebugMessage("i> added new IP " + source_IP + " to xbox " + srcMAC + " for node " + sending_node, xbs_message_sender.SNIFFER); #endif node_list.listHasJustChanged(); } } #if DEBUG xbs_messages.addDebugMessage("i> " + p, xbs_message_sender.SNIFFER); #endif if (NAT.NAT_enabled) { #if DEBUG System.Diagnostics.Stopwatch stopWatch = new System.Diagnostics.Stopwatch(); stopWatch.Start(); #endif EthernetPacketType p_type = NAT.NAT_incoming_packet_PacketDotNet(ref data, dstMAC, srcMAC, ref p, ref p_ipv4, ref p_arp); #if DEBUG stopWatch.Stop(); if (p_type == EthernetPacketType.IpV4) { xbs_sniffer_statistics.NAT_callCount++; if (xbs_sniffer_statistics.NAT_callCount > 1) { xbs_sniffer_statistics.NAT_timeInCode += (UInt64)stopWatch.ElapsedTicks; UInt32 average = (UInt32)(xbs_sniffer_statistics.NAT_timeInCode / (xbs_sniffer_statistics.NAT_callCount - 1)); double average_ms = new TimeSpan(average).TotalMilliseconds; xbs_messages.addDebugMessage("- NAT time: " + stopWatch.ElapsedTicks + "t/" + stopWatch.ElapsedMilliseconds + "ms | NAT count: " + (xbs_sniffer_statistics.NAT_callCount - 1) + " Total Time: " + xbs_sniffer_statistics.NAT_timeInCode + "t=> Average " + average + "t / " + average_ms + "ms", xbs_message_sender.SNIFFER); } } p = Packet.ParsePacket(LinkLayers.Ethernet, data); xbs_messages.addDebugMessage("i> " + p, xbs_message_sender.SNIFFER); #endif } // inject the packet try { pdev.SendPacket(data, data.Length); } catch (PcapException pex) { xbs_messages.addInfoMessage("!! error while injecting packet from " + srcMAC + " to " + dstMAC + " (" + data.Length + ") : " + pex.Message, xbs_message_sender.SNIFFER, xbs_message_type.FATAL_ERROR); } catch (ArgumentException aex) { xbs_messages.addInfoMessage("!! error while injecting packet from " + srcMAC + " to " + dstMAC + " (" + data.Length + ") : " + aex.Message, xbs_message_sender.SNIFFER, xbs_message_type.FATAL_ERROR); } }