/// <summary> /// Whenever a new IP packet arrives it should be passed to this method. /// If the packet is fragmented it will be buffered until all of the other /// fragments have arrived, then it will be pieced back together into a whole /// packet. /// </summary> /// <param name="packet"> /// The packet which has arrived. /// </param> public void HandleNewPacket(IpV4Packet packet) { #region Check for Packets we don't need to parse // first thing we do is check if this packet is whole or not if (packet.ControlFlags.Offset == 0 && !packet.ControlFlags.MoreFragments) { // it's whole so our job is done already. Just forward it on. if (IpV4PacketArrived != null) IpV4PacketArrived (packet); return; } #endregion // at this point we know the packet is a fragment. Now what we want to do // is check through the array list to see if it belongs to any other fragments. // If so, we store the index in the array list of the other packets for further // processing. If not, we add it to a new item in the array list and store the new // index for further processing. #region Get Packet Index int index = -1; for (int i = 0; i < m_packets.Count; i++) { IpV4Packet p = (IpV4Packet)((IpFragmentsType)m_packets[i]).Fragments[0]; // we check if fragments belong by comparing their identification field, the // source and destination address, and the transport protocol if (p.Identification == packet.Identification && p.TransportProtocol == packet.TransportProtocol && p.SourceAddress == packet.SourceAddress && p.DestinationAddress == packet.DestinationAddress) { index = i; break; } } // if the index is still -1 then this is a new fragment if (index == -1) { // create and add a new fragments entry to the packets array IpFragmentsType newFragment = new IpFragmentsType(); index = m_packets.Add (newFragment); } #endregion // now we now need to add the new fragment to the packet array. #region Add Fragment IpFragmentsType currentPacket = (IpFragmentsType)m_packets[index]; currentPacket.Fragments.Add (packet); #endregion // now we check if this packet has the More Fragments bit not set. // This indicates that it is the last fragment. // HOWEVER, since ip packets may arrive out of order, this does not mean we have all // the fragments yet. But since it is the last packet, it does let us know how much // data we are waiting on so we can identify when we have all the fragments. // so calculate how much data we are waiting on and check if we have recieved it all. #region Calculate Total Packet Size and Check For Completion // calculate data currently recieved currentPacket.CurrentDataSize += packet.TotalLength - packet.HeaderLength; if (!packet.ControlFlags.MoreFragments) { // the total length of all the data is caculated by adding the offset on to the data // length of this packet, since it's the last one. currentPacket.TotalDataSize = packet.ControlFlags.Offset + packet.TotalLength - packet.HeaderLength; } // if we have recieved all the data then bingo, we have all the fragments // so reassemble them into a complete packet and remove these uneeded fragments if (currentPacket.CurrentDataSize == currentPacket.TotalDataSize) { IpV4Packet[] fragments = new IpV4Packet[currentPacket.Fragments.Count]; for (int i = 0; i < fragments.Length; i++) { fragments[i] = (IpV4Packet)currentPacket.Fragments[i]; } IpV4Packet WholePacket = new IpV4Packet (fragments); if (IpV4PacketArrived != null) IpV4PacketArrived (WholePacket); m_packets.RemoveAt (index); } #endregion }
/// <summary> /// Whenever a new IP packet arrives it should be passed to this method. /// If the packet is fragmented it will be buffered until all of the other /// fragments have arrived, then it will be pieced back together into a whole /// packet. /// </summary> /// <param name="packet"> /// The packet which has arrived. /// </param> public void HandleNewPacket(IpV4Packet packet) { #region Check for Packets we don't need to parse // first thing we do is check if this packet is whole or not if (packet.ControlFlags.Offset == 0 && !packet.ControlFlags.MoreFragments) { // it's whole so our job is done already. Just forward it on. if (IpV4PacketArrived != null) { IpV4PacketArrived(packet); } return; } #endregion // at this point we know the packet is a fragment. Now what we want to do // is check through the array list to see if it belongs to any other fragments. // If so, we store the index in the array list of the other packets for further // processing. If not, we add it to a new item in the array list and store the new // index for further processing. #region Get Packet Index int index = -1; for (int i = 0; i < m_packets.Count; i++) { IpV4Packet p = (IpV4Packet)((IpFragmentsType)m_packets[i]).Fragments[0]; // we check if fragments belong by comparing their identification field, the // source and destination address, and the transport protocol if (p.Identification == packet.Identification && p.TransportProtocol == packet.TransportProtocol && p.SourceAddress == packet.SourceAddress && p.DestinationAddress == packet.DestinationAddress) { index = i; break; } } // if the index is still -1 then this is a new fragment if (index == -1) { // create and add a new fragments entry to the packets array IpFragmentsType newFragment = new IpFragmentsType(); index = m_packets.Add(newFragment); } #endregion // now we now need to add the new fragment to the packet array. #region Add Fragment IpFragmentsType currentPacket = (IpFragmentsType)m_packets[index]; currentPacket.Fragments.Add(packet); #endregion // now we check if this packet has the More Fragments bit not set. // This indicates that it is the last fragment. // HOWEVER, since ip packets may arrive out of order, this does not mean we have all // the fragments yet. But since it is the last packet, it does let us know how much // data we are waiting on so we can identify when we have all the fragments. // so calculate how much data we are waiting on and check if we have recieved it all. #region Calculate Total Packet Size and Check For Completion // calculate data currently recieved currentPacket.CurrentDataSize += packet.TotalLength - packet.HeaderLength; if (!packet.ControlFlags.MoreFragments) { // the total length of all the data is caculated by adding the offset on to the data // length of this packet, since it's the last one. currentPacket.TotalDataSize = packet.ControlFlags.Offset + packet.TotalLength - packet.HeaderLength; } // if we have recieved all the data then bingo, we have all the fragments // so reassemble them into a complete packet and remove these uneeded fragments if (currentPacket.CurrentDataSize == currentPacket.TotalDataSize) { IpV4Packet[] fragments = new IpV4Packet[currentPacket.Fragments.Count]; for (int i = 0; i < fragments.Length; i++) { fragments[i] = (IpV4Packet)currentPacket.Fragments[i]; } IpV4Packet WholePacket = new IpV4Packet(fragments); if (IpV4PacketArrived != null) { IpV4PacketArrived(WholePacket); } m_packets.RemoveAt(index); } #endregion }