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);
}