public void Send(ICopyable data) { /* * Assemble an AHPacket: */ if (_header == null) { AHHeader ahh = new AHHeader(_hops, _ttl, _source, _dest, _options); _header = MemBlock.Copy(new CopyList(PType.Protocol.AH, ahh)); _header_length = _header.Length; } byte[] ah_packet; int packet_length; int packet_offset; //Try to get the shared BufferAllocator, useful when //we don't know how big the data is, which in general //is just as expensive as doing a CopyTo... BufferAllocator ba = Interlocked.Exchange <BufferAllocator>(ref _buf_alloc, null); if (ba != null) { try { ah_packet = ba.Buffer; packet_offset = ba.Offset; int tmp_off = packet_offset; tmp_off += _header.CopyTo(ah_packet, packet_offset); tmp_off += data.CopyTo(ah_packet, tmp_off); packet_length = tmp_off - packet_offset; ba.AdvanceBuffer(packet_length); } catch (System.Exception x) { throw new SendException(false, "could not write the packet, is it too big?", x); } finally { //Put the BA back Interlocked.Exchange <BufferAllocator>(ref _buf_alloc, ba); } } else { //Oh well, someone else is using the buffer, just go ahead //and allocate new memory: packet_offset = 0; packet_length = _header_length + data.Length; ah_packet = new byte[packet_length]; int off_to_data = _header.CopyTo(ah_packet, 0); data.CopyTo(ah_packet, off_to_data); } MemBlock mb_packet = MemBlock.Reference(ah_packet, packet_offset, packet_length); /* * Now we announce this packet, the AHHandler will * handle routing it for us */ _n.HandleData(mb_packet, _from, this); }
public void HandleData(MemBlock packet, ISender from, object node) { _message_count++; long stop_time, rt_ticks = -10000; if ( !from.Equals(node)) { if (packet[0] == 0) { //log.Debug("Echo Response:"); stop_time = System.DateTime.Now.Ticks; int received_uid = NumberSerializer.ReadInt(packet, 1); if(uid_starttime.ContainsKey(received_uid)){ rt_ticks = stop_time - (long)EchoTester.uid_starttime[received_uid]; } double rt_ms = (double) rt_ticks/10000.0; uid_brunetpingtime.Add(received_uid, rt_ms); Console.WriteLine("Packet ID = {0}, Round-trip = {1}", received_uid, rt_ms); } else { //log.Debug("Echo Request:"); } //log.Debug(packet.ToString()); //System.Console.WriteLine("{0}", packet.ToString()); if (packet[0] > 0) { //Send a reply back, this is a request byte[] new_payload = new byte[ packet.Length ]; packet.CopyTo(new_payload, 0); new_payload[0] = (byte) 0; from.Send(new CopyList(PType.Protocol.Echo, MemBlock.Reference(new_payload))); } } }
/// <summary> /// Finds an available IP range on the system /// </summary> /// <param name="networkdevice">Device to be ignored</param> /// <param name="startip">Device to be ignored</param> /// <returns>Return IP to use</returns> public static MemBlock GetNetwork(string networkdevice, MemBlock startip) { MemBlock netip = startip; ArrayList used_networks = new ArrayList(); IPHostEntry entry = System.Net.Dns.GetHostEntry(String.Empty); foreach (IPAddress ip in entry.AddressList) { byte[] address = ip.GetAddressBytes(); address[2] = 0; address[3] = 0; used_networks.Add(MemBlock.Reference(address)); } while (used_networks.Contains(netip)) { byte[] tmp = new byte[netip.Length]; netip.CopyTo(tmp, 0); if (tmp[1] == 0) { throw new Exception("Out of Addresses!"); } tmp[1] -= 1; netip = MemBlock.Reference(tmp); } return(netip); }
override protected bool HandleIncoming(MemBlock data, out MemBlock app_data) { app_data = null; int count = 0; lock (_buffer_sync) { if (data != null) { data.CopyTo(_buffer, 0); _read.Write(_buffer, data.Length); } count = _ssl.Read(_buffer, _buffer.Length); if (count > 0) { app_data = MemBlock.Copy(_buffer, 0, count); } } if (app_data != null) { // If the read was successful, Dtls has received an incoming data // message and decrypted it return(true); } else { SslError error = _ssl.GetError(count); if (error == SslError.SSL_ERROR_WANT_READ) { if (SslState == SslState.OK) { UpdateState(States.Active); // In the SslCtx verify, there's no way to get the underlying Sender _ch.Verify(RemoteCertificate, Sender); } HandleWouldBlock(); } else if (error == SslError.SSL_ERROR_SSL) { var ose = new OpenSslException(); Close("Received unrecoverable error: " + ose.ToString()); throw ose; } else if (error == SslError.SSL_ERROR_ZERO_RETURN) { Close("Received clean close notification"); } else { ProtocolLog.WriteIf(ProtocolLog.SecurityExceptions, "Receive other: " + error); } } return(false); }
/// <summary>Create a new Attribute.</summary> public Attribute(AttributeType type, MemBlock value) { Type = type; Value = value; byte[] data = new byte[4 + value.Length]; NumberSerializer.WriteUShort((ushort)type, data, 0); NumberSerializer.WriteUShort((ushort)value.Length, data, 2); value.CopyTo(data, 4); Data = MemBlock.Reference(data); }
protected byte[] GenToken(MemBlock key) { RNGCryptoServiceProvider provider = new RNGCryptoServiceProvider(); byte[] token = new byte[20]; provider.GetBytes(token); byte[] res = new byte[40]; key.CopyTo(res, 0); token.CopyTo(res, 20); return(res); }
public DhcpPacket(byte op, MemBlock xid, MemBlock ciaddr, MemBlock yiaddr, MemBlock siaddr, MemBlock chaddr, Dictionary <OptionTypes, MemBlock> Options) { this.op = op; this.xid = xid; this.ciaddr = ciaddr; this.yiaddr = yiaddr; this.siaddr = siaddr; this.chaddr = chaddr; this.Options = Options; byte[] header = new byte[240]; header[0] = op; header[1] = 1; header[2] = (byte)chaddr.Length; header[3] = 0; xid.CopyTo(header, 4); for (int i = 8; i < 12; i++) { header[i] = 0; } ciaddr.CopyTo(header, 12); yiaddr.CopyTo(header, 16); siaddr.CopyTo(header, 20); for (int i = 24; i < 28; i++) { header[i] = 0; } chaddr.CopyTo(header, 28); for (int i = 34; i < 236; i++) { header[i] = 0; } magic_key.CopyTo(header, 236); _icpacket = new CopyList(MemBlock.Reference(header)); foreach (KeyValuePair <OptionTypes, MemBlock> kvp in Options) { MemBlock value = kvp.Value; byte[] tmp = new byte[2]; tmp[0] = (byte)kvp.Key; tmp[1] = (byte)value.Length; _icpacket = new CopyList(_icpacket, MemBlock.Reference(tmp), value); } byte [] end = new byte[1] { 255 }; /* End of Options */ _icpacket = new CopyList(_icpacket, MemBlock.Reference(end)); }
///<summary>Encrypts the packet given a SymmetricEncryption.</summary> public void Encrypt(SymmetricEncryption se) { byte[] to_encrypt = new byte[4 + _data.Length + _signature.Length]; int pos = 0; NumberSerializer.WriteInt(_data.Length, to_encrypt, pos); pos += 4; _data.CopyTo(to_encrypt, pos); pos += _data.Length; _signature.CopyTo(to_encrypt, pos); _encrypted_data = se.EncryptData(to_encrypt); _update_icpacket = true; }
public static MemBlock MakePseudoHeader(MemBlock source_address, MemBlock destination_address, byte protocol, ushort length) { byte[] pseudoheader = new byte[source_address.Length + destination_address.Length + 4]; int pos = 0; source_address.CopyTo(pseudoheader, pos); pos += source_address.Length; destination_address.CopyTo(pseudoheader, pos); pos += destination_address.Length; pseudoheader[++pos] = protocol; NumberSerializer.WriteUShort(length, pseudoheader, ++pos); return(MemBlock.Reference(pseudoheader)); }
/** * <summary>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.</summary> * <param name="Packet">The packet to translate.</param> * <param name="SourceIP">The new source ip.</param> * <param name="DestinationIP">The new destination ip.</param> */ 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)); }
public static ManagedDhcpServer GetManagedDhcpServer(MemBlock ip, MemBlock netmask) { DHCPConfig config = new DHCPConfig(); config.LeaseTime = 3200; config.Netmask = Utils.MemBlockToString(netmask, '.'); config.IPBase = Utils.MemBlockToString(ip, '.'); config.ReservedIPs = new DHCPConfig.ReservedIP[1]; config.ReservedIPs[0] = new DHCPConfig.ReservedIP(); byte[] local_ip = new byte[4]; ip.CopyTo(local_ip, 0); local_ip[3] = 2; config.ReservedIPs[0].IPBase = Utils.BytesToString(local_ip, '.'); config.ReservedIPs[0].Mask = "255.255.255.255"; return new ManagedDhcpServer(config); }
public static ManagedDhcpServer GetManagedDhcpServer(MemBlock ip, MemBlock netmask) { DHCPConfig config = new DHCPConfig(); config.LeaseTime = 3200; config.Netmask = Utils.MemBlockToString(netmask, '.'); config.IPBase = Utils.MemBlockToString(ip, '.'); config.ReservedIPs = new DHCPConfig.ReservedIP[1]; config.ReservedIPs[0] = new DHCPConfig.ReservedIP(); byte[] local_ip = new byte[4]; ip.CopyTo(local_ip, 0); local_ip[3] = 2; config.ReservedIPs[0].IPBase = Utils.BytesToString(local_ip, '.'); config.ReservedIPs[0].Mask = "255.255.255.255"; return(new ManagedDhcpServer(config)); }
public void Incoming() { Random rand = new Random(); byte[] local_cookie = new byte[SecurityControlMessage.CookieLength]; byte[] remote_cookie = new byte[SecurityControlMessage.CookieLength]; byte[] dhe = new byte[144]; byte[] cas = new byte[120]; byte[] cert = new byte[100]; RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(); HashAlgorithm hash = new SHA1CryptoServiceProvider(); rand.NextBytes(local_cookie); rand.NextBytes(remote_cookie); rand.NextBytes(dhe); rand.NextBytes(cas); rand.NextBytes(cert); MemBlock mlocal_cookie = MemBlock.Reference(local_cookie); MemBlock mremote_cookie = MemBlock.Reference(remote_cookie); MemBlock mdhe = MemBlock.Reference(dhe); MemBlock mcert = MemBlock.Reference(cert); MemBlock mcas = MemBlock.Reference(cas); List <MemBlock> lcas = new List <MemBlock>(); for (int i = 0; i < cas.Length; i += SecurityControlMessage.CALength) { lcas.Add(MemBlock.Reference(mcas.Slice(i, SecurityControlMessage.CALength))); } int length = 4 + 4 + 4 + 2 * SecurityControlMessage.CookieLength + 4 + cas.Length + 4 + dhe.Length + 4 + cert.Length; byte[] b = new byte[length]; int pos = 0; NumberSerializer.WriteInt(5, b, pos); pos += 4; NumberSerializer.WriteInt(12345, b, pos); pos += 4; NumberSerializer.WriteInt((int)SecurityControlMessage.MessageType.DHEWithCertificateAndCAs, b, pos); pos += 4; local_cookie.CopyTo(b, pos); pos += SecurityControlMessage.CookieLength; remote_cookie.CopyTo(b, pos); pos += SecurityControlMessage.CookieLength; NumberSerializer.WriteInt(dhe.Length, b, pos); pos += 4; dhe.CopyTo(b, pos); pos += dhe.Length; NumberSerializer.WriteInt(cert.Length, b, pos); pos += 4; cert.CopyTo(b, pos); pos += cert.Length; NumberSerializer.WriteInt(cas.Length, b, pos); pos += 4; mcas.CopyTo(b, pos); pos += cas.Length; byte[] signature = rsa.SignData(b, hash); byte[] nb = new byte[b.Length + signature.Length]; b.CopyTo(nb, 0); signature.CopyTo(nb, b.Length); MemBlock packet = MemBlock.Reference(nb); // check SecurityControlMessage scm = new SecurityControlMessage(packet); Assert.AreEqual(5, scm.Version, "Version"); Assert.AreEqual(12345, scm.SPI, "SPI"); Assert.AreEqual(SecurityControlMessage.MessageType.DHEWithCertificateAndCAs, scm.Type, "Type"); Assert.AreEqual(mlocal_cookie, scm.LocalCookie, "LocalCookie"); Assert.AreEqual(mremote_cookie, scm.RemoteCookie, "RemoteCookie"); Assert.AreEqual(mdhe, scm.DHE, "DHE"); Assert.AreEqual(mcert, scm.Certificate, "Certificate"); int contains = 0; foreach (MemBlock ca in scm.CAs) { if (scm.CAs.Contains(ca)) { contains++; } } Assert.AreEqual(contains, lcas.Count, "Contains CAs"); Assert.IsTrue(scm.Verify(rsa, hash), "Signature"); Assert.AreEqual(packet, scm.Packet, "Packet"); // change a few things around and check again! scm.Version = 0; SecurityControlMessage scm1 = new SecurityControlMessage(scm.Packet); scm1.Sign(rsa, hash); Assert.AreEqual(scm1.Version, scm.Version, "Version 1"); Assert.AreEqual(scm1.SPI, scm.SPI, "SPI 1"); Assert.AreEqual(scm1.Type, scm.Type, "Type 1"); Assert.AreEqual(scm1.LocalCookie, scm.LocalCookie, "LocalCookie 1"); Assert.AreEqual(scm1.RemoteCookie, scm.RemoteCookie, "RemoteCookie 1"); Assert.AreEqual(mdhe, scm.DHE, "DHE 1"); Assert.AreEqual(mcert, scm.Certificate, "Certificate 1"); contains = 0; foreach (MemBlock ca in scm.CAs) { if (scm.CAs.Contains(ca)) { contains++; } } Assert.AreEqual(contains, lcas.Count, "Contains CAs 1"); Assert.IsTrue(scm1.Signature != scm.Signature, "Signature 1"); Assert.AreEqual(scm1.Packet.Slice(4, scm1.Signature.Length), scm.Packet.Slice(4, scm.Signature.Length), "Packet 1"); }
///<summary>Writes the packet.</summary> protected void UpdatePacket() { try { int data_length = 0; bool write_cas = false; bool write_dhe = false; bool write_cert = false; bool write_hash = false; bool require_signature = true; switch (_type) { case MessageType.NoSuchSA: require_signature = false; break; case MessageType.Cookie: require_signature = false; break; case MessageType.CookieResponse: require_signature = false; data_length = 4 + _cas.Count * CALength; write_cas = true; break; case MessageType.DHEWithCertificate: data_length = 4 + _dhe.Length + 4 + _certificate.Length; write_cert = true; write_dhe = true; break; case MessageType.DHEWithCertificateAndCAs: data_length = 4 + _dhe.Length + 4 + _certificate.Length + 4 + _cas.Count * CALength; write_cas = true; write_dhe = true; write_cert = true; break; case MessageType.Confirm: data_length = 4 + _hash.Length; write_hash = true; break; } int length = 4 + 4 + 4 + 2 * CookieLength + data_length; if (require_signature) { length += _signature.Length; } byte[] b = new byte[length]; int pos = 0; NumberSerializer.WriteInt(_version, b, pos); pos += 4; NumberSerializer.WriteInt(_spi, b, pos); pos += 4; NumberSerializer.WriteInt((int)_type, b, pos); pos += 4; if (_local_cookie == null) { EmptyCookie.CopyTo(b, pos); } else { _local_cookie.CopyTo(b, pos); } pos += CookieLength; if (_remote_cookie == null) { EmptyCookie.CopyTo(b, pos); } else { _remote_cookie.CopyTo(b, pos); } pos += CookieLength; if (write_dhe) { NumberSerializer.WriteInt(_dhe.Length, b, pos); pos += 4; _dhe.CopyTo(b, pos); pos += _dhe.Length; } if (write_cert) { NumberSerializer.WriteInt(_certificate.Length, b, pos); pos += 4; _certificate.CopyTo(b, pos); pos += _certificate.Length; } if (write_cas) { NumberSerializer.WriteInt(_cas.Count * CALength, b, pos); pos += 4; foreach (MemBlock ca in _cas) { ca.CopyTo(b, pos); pos += CALength; } } if (write_hash) { NumberSerializer.WriteInt(_hash.Length, b, pos); pos += 4; _hash.CopyTo(b, pos); pos += _hash.Length; } if (require_signature) { _signature.CopyTo(b, pos); } _packet = MemBlock.Reference(b); } catch (Exception e) { throw new Exception("Missing data for SecurityControlMessage!"); } _update_packet = false; }
/** * This method converts the objects compatible in AdrConvertor to * objects that compatible in XMLRPC.NET library. * byte[], MemBlock -> byte[] -> string(base64) * other array -> array ( elements converted) * IDictionary -> XmlRpcStruct (key -> string) * IList -> array * float -> double * long, ulong -> string * AdrException -> XmlRpcFaultException (w/ errorCode added) * Exception -> Exception (converted by XmlRpcFaultException by xmlrpc.net) * ISender -> string (using ToString()) * short, ushort, uint, byte, sbyte -> int * null -> string.Empty */ public static object Adr2XmlRpc(object o, out bool modified) { object retval; if (o == null) { /* * If null is returned when the method is not recursively called by itself, * it is OK because XmlRpc.Net will convert it to string.Empty. * If not, the null element's outer data structure like Array and IDictionary, * which themselves allow null elements, might not be handled correctly: * XmlRpc.Net can't serialize IDictionary and Array with null elements. * So we return s.Empty directly from here */ retval = string.Empty; modified = true; return(retval); } System.Type t = o.GetType(); // byte arrays are converted to base64 strings in XmlRpc // so we treat it as a special case of array if (t == typeof(byte[])) { retval = o; modified = false; } // convert each element else if (t.IsArray) { ArrayList list = new ArrayList((ICollection)o); bool m; modified = false; for (int i = 0; i < list.Count; i++) { list[i] = Adr2XmlRpc(list[i], out m); if (m == true) { modified = true; } } retval = list.ToArray(); } //IDictionary -> XmlRpcStruct (string key) else if (o is IDictionary) { modified = true; XmlRpcStruct xrs = new XmlRpcStruct(); IDictionary dict = o as IDictionary; IDictionaryEnumerator my_en = dict.GetEnumerator(); while (my_en.MoveNext()) { object key = Adr2XmlRpc(my_en.Key); /* * XmlRpcStruct requires keys to be strings, we just use ToString() to generate * strings. */ string str_key = key.ToString(); object val = Adr2XmlRpc(my_en.Value); xrs.Add(str_key, val); } retval = xrs; } //XmlRpcSerializer doesn't recognize lists //IList -> Array else if (o is IList) { modified = true; //list -> array ArrayList list = new ArrayList((ICollection)o); for (int i = 0; i < list.Count; i++) { list[i] = Adr2XmlRpc(list[i]); } retval = list.ToArray(); } //Memblock -> byte[] else if (o is MemBlock) { modified = true; MemBlock mb = (MemBlock)o; byte[] b = new byte[mb.Length]; mb.CopyTo(b, 0); retval = b; } //float -> double else if (t == typeof(Single)) { retval = Convert.ToDouble(o); modified = true; } else if (t == typeof(short) || t == typeof(ushort) || t == typeof(uint) || t == typeof(byte) || t == typeof(sbyte)) { retval = Convert.ToInt32(o); modified = true; } //long-> string else if (t == typeof(long) || t == typeof(ulong)) { retval = Convert.ToString(o); modified = true; } //AdrException is different from others that it has a code that can //be assigned to XmlRpcFaultException else if (o is AdrException) { AdrException e = (AdrException)o; StringBuilder sb = new StringBuilder(); sb.AppendLine(string.Format("{0}", e.ToString())); retval = new XmlRpcFaultException(e.Code, sb.ToString()); modified = true; } //Still exceptions, XmlRpc.net converts it to XmlRpcFaultException else if (o is Exception) { Exception e = (Exception)o; StringBuilder sb = new StringBuilder(); sb.AppendLine(string.Format("{0}", e.ToString())); retval = new Exception(sb.ToString()); modified = true; } else if (o is ISender) { ISender s = (ISender)o; retval = s.ToString(); modified = true; } else { retval = o; modified = false; } return(retval); }
public int CopyTo(byte[] dst, int offset) { return(_data.CopyTo(dst, offset)); }
protected byte[] GenToken(MemBlock key) { RNGCryptoServiceProvider provider = new RNGCryptoServiceProvider(); byte[] token = new byte[20]; provider.GetBytes(token); byte[] res = new byte[40]; key.CopyTo(res, 0); token.CopyTo(res, 20); return res; }
public static MemBlock MakePseudoHeader(MemBlock source_address, MemBlock destination_address, byte protocol, ushort length) { byte[] pseudoheader = new byte[source_address.Length + destination_address.Length + 4]; int pos = 0; source_address.CopyTo(pseudoheader, pos); pos += source_address.Length; destination_address.CopyTo(pseudoheader, pos); pos += destination_address.Length; pseudoheader[++pos] = protocol; NumberSerializer.WriteUShort(length, pseudoheader, ++pos); return MemBlock.Reference(pseudoheader); }
public DhcpPacket(byte op, MemBlock xid, MemBlock ciaddr, MemBlock yiaddr, MemBlock siaddr, MemBlock chaddr, Dictionary<OptionTypes, MemBlock> Options) { this.op = op; this.xid = xid; this.ciaddr = ciaddr; this.yiaddr = yiaddr; this.siaddr = siaddr; this.chaddr = chaddr; this.Options = Options; byte[] header = new byte[240]; header[0] = op; header[1] = 1; header[2] = (byte) chaddr.Length; header[3] = 0; xid.CopyTo(header, 4); for(int i = 8; i < 12; i++) { header[i] = 0; } ciaddr.CopyTo(header, 12); yiaddr.CopyTo(header, 16); siaddr.CopyTo(header, 20); for(int i = 24; i < 28; i++) { header[i] = 0; } chaddr.CopyTo(header, 28); for(int i = 34; i < 236; i++) { header[i] = 0; } magic_key.CopyTo(header, 236); _icpacket = new CopyList(MemBlock.Reference(header)); foreach(KeyValuePair<OptionTypes, MemBlock> kvp in Options) { MemBlock value = kvp.Value; byte[] tmp = new byte[2]; tmp[0] = (byte) kvp.Key; tmp[1] = (byte) value.Length; _icpacket = new CopyList(_icpacket, MemBlock.Reference(tmp), value); } byte []end = new byte[1]{255}; /* End of Options */ _icpacket = new CopyList(_icpacket, MemBlock.Reference(end)); }
/** <summary>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.</summary> <param name="Packet">The packet to translate.</param> <param name="SourceIP">The new source ip.</param> <param name="DestinationIP">The new destination ip.</param> */ 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); }