public static IPPacketIdentifier Create(ushort key, IPHeader ipHeader, SystemModule module) { var id = new IPPacketIdentifier(key, ipHeader, module); id._timer = new Timer { Interval = 1000 }; id._timer.Elapsed += (s, e) => { id._ttl--; if (id._ttl == 0) { Log.Write("IPPacketIdentifier", "Timeout", string.Format("addr={0}, id={1}", id.Daddr.StandardFormat, id.Key)); id._timer.Stop(); module.KillIPPacketIdentifier(id); } }; return id; }
private List<PacketData> CreatePacketData(PacketData packetData, Handler layer3Handler, Value[] parameterArray, out IPHeader baseIPHeader, out IPPacketIdentifier id) { const int ipMtu = 1500; var list = new List<PacketData>(); var ipHeader = (IPHeader)layer3Handler.Build(parameterArray); baseIPHeader = ipHeader; var headerLength = ipHeader.VersionIHL * 5; ipHeader.TotalLength = (ushort)((ipHeader.VersionIHL * 5) + packetData.Length); id = CreateIPPacketIdentifier(ipHeader); ipHeader.Identification = id.Key; var remainingData = packetData.Data; var totalTransmitCount = remainingData.Count; ushort fragmentOffset = 0; while (remainingData.Count > 0) { if (remainingData.Count + headerLength > ipMtu) { var firstFragmentSize = ipMtu - ipHeader.InternetHeaderLength; var blockCount = (int)Math.Floor((double)firstFragmentSize / 8); var copyCount = blockCount * 8; var pendingTransmitData = new List<byte>(remainingData.GetRange(0, copyCount)); remainingData = new List<byte>(remainingData.GetRange(copyCount, remainingData.Count - copyCount)); ipHeader.FlagsFragmentOffset = (ushort)((fragmentOffset >> 3) | 0x2000); Log.Write("SYSTEM", "IPFRAGMENT", fragmentOffset.ToString()); fragmentOffset += (ushort)copyCount; ipHeader.TotalLength = (ushort)((ipHeader.VersionIHL * 5) + copyCount); //++ contains MF bit //ipHeader.FlagsFragmentOffset = (ushort)(ipHeader.FlagsFragmentOffset << 3); var segmentData = PacketData.Create(pendingTransmitData); segmentData = layer3Handler.GetBytes(ipHeader, segmentData); list.Add(segmentData); } else { var pendingTransmitData = remainingData; ipHeader.FlagsFragmentOffset = (ushort)(fragmentOffset >> 3); //ipHeader.FlagsFragmentOffset = (ushort)(fragmentOffset); Log.Write("SYSTEM", "IPFRAGMENT", fragmentOffset.ToString()); //ipHeader.FlagsFragmentOffset = (ushort)(ipHeader.FlagsFragmentOffset << 3); ipHeader.TotalLength = (ushort)((ipHeader.VersionIHL * 5) + remainingData.Count); var segmentData = PacketData.Create(pendingTransmitData); segmentData = layer3Handler.GetBytes(ipHeader, segmentData); list.Add(segmentData); remainingData.Clear(); } } return list; }
internal void KillIPPacketIdentifier(IPPacketIdentifier ipPacketIdentifier) { lock (_ipPacketIdentifierLock) { _ipPacketIdentifierMap[ipPacketIdentifier.Daddr].Data.Remove(ipPacketIdentifier.Key); } }