/** * <summary>Implements the ITranslator portion for ManagedAddress..., takes an * IP Packet, based upon who the originating Brunet Sender was, changes who * the packet was sent from and then switches the destination address to the * local nodes address. Takes incomming packets only.</summary> * <param name="packet">The IP Packet to translate.</param> * <param name="from">The Brunet address the packet was sent from.</param> * <returns>The translated IP Packet.</returns> */ public MemBlock Translate(MemBlock packet, Address from) { UpdateCounter(_rx_counters, from); MemBlock source_ip = _addr_ip[from]; if (source_ip == null) { throw new Exception("Invalid mapping " + from + "."); } // Attempt to translate a packet IPPacket ipp = new IPPacket(packet); // hdr is everything in the packet up to the source IP, dest IP, "options" // and data MemBlock hdr = packet.Slice(0, 12); // Pull the "fragment" info from the header. If it is not fragmented, we // can deal with the packet. DNS packets should never be sent as fragments bool fragment = ((hdr[6] & 0x1F) | hdr[7]) != 0; //should there be a field in the IPPacket class for this? MemBlock dest_ip = ipp.DestinationIP; byte dest_ip_first_byte = dest_ip[0]; bool is_multicast = dest_ip_first_byte > 223 && dest_ip_first_byte < 240; //multicast addresses are 224.0.0.0 through 239.255.255.255 if (ipp.Protocol == IPPacket.Protocols.Udp && !fragment) //simple UDP { UdpPacket udpp = new UdpPacket(ipp.Payload); foreach (IProtocolTranslator <UdpPacket> i in _udp_translators) { if (i.MatchesProtocol(udpp)) { udpp = i.Translate(udpp, source_ip, ipp.SourceIP, ipp.DestinationIP); return(new IPPacket(ipp.Protocol, source_ip, is_multicast? ipp.DestinationIP: _local_ip, hdr, udpp.ICPacket).Packet); } } } //fallback return(IPPacket.Translate(packet, source_ip, is_multicast? ipp.DestinationIP: _local_ip )); }