NetworkPackets.IPPacket.Translate C# (CSharp) Method

Translate() public static method

If we're not creating a packet from scratch, this will keep its integrity and transform UDP and TCP headers as well (due to their checksums being dependent on source and destination ip addresses.
public static Translate ( MemBlock Packet, MemBlock SourceIP, MemBlock DestinationIP ) : MemBlock
Packet MemBlock The packet to translate.
SourceIP MemBlock The new source ip.
DestinationIP MemBlock The new destination ip.
return MemBlock
    public static MemBlock Translate(MemBlock Packet, MemBlock SourceIP,
                                     MemBlock DestinationIP) {
      byte[] new_packet = new byte[Packet.Length];
      Packet.CopyTo(new_packet, 0);
      int length = (Packet[0] & 0xF) * 4;
      SourceIP.CopyTo(new_packet, 12);
      // Do not copy over multicast addresses!
      if(new_packet[16] < 224 || new_packet[16] > 239) {
        DestinationIP.CopyTo(new_packet, 16);
      }
      // Zero out the checksum so we don't use it in our future calculations
      new_packet[10] = 0;
      new_packet[11] = 0;
      MemBlock header = MemBlock.Reference(new_packet, 0, length);
      int checksum = GenerateChecksum(header);
      new_packet[10] = (byte) ((checksum >> 8) & 0xFF);
      new_packet[11] = (byte) (checksum & 0xFF);
      Protocols p = (Protocols) Packet[9];

      bool fragment = ((Packet[6] & 0x1F) | Packet[7]) != 0;

      if(p == Protocols.Udp && !fragment) {
        // Zero out the checksum to disable it
        new_packet[length + 6] = 0;
        new_packet[length + 7] = 0;
      }
      else if(p == Protocols.Tcp && !fragment) {
        // Zero out the checksum so we don't use it in our future calculations
        new_packet[length + 16] = 0;
        new_packet[length + 17] = 0;
        MemBlock payload = MemBlock.Reference(new_packet).Slice(length);
        MemBlock pseudoheader = IPPacket.MakePseudoHeader(SourceIP,
            DestinationIP, (byte) Protocols.Tcp, (ushort) (Packet.Length - 20));
        checksum = IPPacket.GenerateChecksum(payload, pseudoheader);
        new_packet[length + 16] = (byte) ((checksum >> 8) & 0xFF);
        new_packet[length + 17] = (byte) (checksum & 0xFF);
      }
      return MemBlock.Reference(new_packet);
    }