Ejemplo n.º 1
0
		/// <summary>
		///		Log a new IP packet.
		/// </summary>
		/// <param name="packet">
		///		The packet to log.
		///	</param>
		public void LogPacket (IpV4Packet packet)
		{
			lock (m_logger.XmlWriter)
			{
				// <IpV4Header>
				m_logger.XmlWriter.WriteStartElement ("IpV4Header");

					m_logger.XmlWriter.WriteElementString ("SourceAddress",		packet.SourceAddress.ToString());
					m_logger.XmlWriter.WriteElementString ("DestinationAddress",packet.DestinationAddress.ToString());
					m_logger.XmlWriter.WriteElementString ("TransportProtocol",	packet.TransportProtocol.ToString());
					m_logger.XmlWriter.WriteElementString ("TimeToLive",		packet.TimeToLive.ToString());
					m_logger.XmlWriter.WriteElementString ("Identification",	packet.Identification.ToString());
					m_logger.XmlWriter.WriteElementString ("Checksum",			packet.Checksum.ToString());
					
					// <LengthFields>
					m_logger.XmlWriter.WriteStartElement ("IpLengthFields");
						m_logger.XmlWriter.WriteElementString ("TotalLength",	packet.TotalLength + " bytes");
						m_logger.XmlWriter.WriteElementString ("HeaderLength",	packet.HeaderLength + " bytes");
						m_logger.XmlWriter.WriteElementString ("OptionsLength",	(packet.TotalLength - (packet.Padding != null ? packet.Padding.Length : 0) - (packet.Data != null ? packet.Data.Length : 0) - 0x14) + " bytes");
						m_logger.XmlWriter.WriteElementString ("PaddingLength",	(packet.Padding != null ? packet.Padding.Length : 0) + " bytes");
						m_logger.XmlWriter.WriteElementString ("DataLength",	(packet.Data != null ? packet.Data.Length : 0) + " bytes");
					m_logger.XmlWriter.WriteEndElement ();
					// </LengthFields>
					
					// <Fragmentation>
					m_logger.XmlWriter.WriteStartElement ("Fragmentation");
						m_logger.XmlWriter.WriteElementString ("Fragments",		packet.Fragments.ToString());
						m_logger.XmlWriter.WriteElementString ("DontFragment",	packet.ControlFlags.DontFragment.ToString());
						m_logger.XmlWriter.WriteElementString ("MoreFragments",	packet.ControlFlags.MoreFragments.ToString());
						m_logger.XmlWriter.WriteElementString ("Offset",		packet.ControlFlags.Offset.ToString());
					m_logger.XmlWriter.WriteEndElement ();
					// </Fragmentation>
					
					// <TypeOfService>
					m_logger.XmlWriter.WriteStartElement ("TypeOfService");
						m_logger.XmlWriter.WriteElementString ("Precedence",	packet.TypeOfService.Precedence.ToString());
						m_logger.XmlWriter.WriteElementString ("Delay",			packet.TypeOfService.Delay.ToString());
						m_logger.XmlWriter.WriteElementString ("Reliability",	packet.TypeOfService.Reliability.ToString());
						m_logger.XmlWriter.WriteElementString ("Throughput",	packet.TypeOfService.Throughput.ToString());
					m_logger.XmlWriter.WriteEndElement ();
					// </TypeOfService>
					
					if (packet.Options != null)
					{
						// <Options>
						m_logger.XmlWriter.WriteStartElement ("IpOptions");
						
							foreach (IpV4Option option in packet.Options)
							{
								// <Option>
								m_logger.XmlWriter.WriteStartElement ("Option");
									m_logger.XmlWriter.WriteElementString ("Class",	option.Class.ToString());
									m_logger.XmlWriter.WriteElementString ("Type",	option.OptionType.ToString());
									m_logger.XmlWriter.WriteElementString ("Length",option.Length + " bytes");
									m_logger.XmlWriter.WriteElementString ("Copied",option.IsCopied.ToString());
									
									#region Specific Options
									
									switch (option.OptionType)
									{
										case IpV4OptionNumber.EndOfOptions:
											break;
										case IpV4OptionNumber.InternetTimestamp:
										
											IpV4TimeStampOption option1 = new IpV4TimeStampOption (option);
											
											m_logger.XmlWriter.WriteElementString ("TimestampType",	option1.OptionType.ToString());
											m_logger.XmlWriter.WriteElementString ("Overflow",		option1.Overflow.ToString());
											m_logger.XmlWriter.WriteElementString ("Pointer",			option1.Pointer.ToString());

											
											
											break;
										case IpV4OptionNumber.LooseSourceRouting:
										
											IpV4RoutingOption option2 = new IpV4RoutingOption (option);
											
											m_logger.XmlWriter.WriteElementString ("Pointer",			option2.Pointer.ToString());
										
											
											
											break;
										case IpV4OptionNumber.NoOperation:
											break;
										case IpV4OptionNumber.RecordRoute:
										
											IpV4RoutingOption option3 = new IpV4RoutingOption (option);
											
											m_logger.XmlWriter.WriteElementString ("Pointer",			option3.Pointer.ToString());
										
											
											
											break;
										case IpV4OptionNumber.Security:
											
											IpV4SecurityOption option4 = new IpV4SecurityOption (option);
										
											m_logger.XmlWriter.WriteElementString ("SecurityLevel",			option4.SecurityLevel.ToString());
											m_logger.XmlWriter.WriteElementString ("Compartment",				option4.Compartment.ToString());
											m_logger.XmlWriter.WriteElementString ("HandlingRestrictions",	option4.HandlingRestrictions.ToString());
											m_logger.XmlWriter.WriteElementString ("TransmissionControlCode",	option4.TransmissionControlCode.ToString());
										
											break;
										case IpV4OptionNumber.StreamId:
										
											IpV4StreamIdentifierOption option5 = new IpV4StreamIdentifierOption (option);
											
											m_logger.XmlWriter.WriteElementString ("StreamIdentifier",	option5.StreamIdentifier.ToString());
										
											break;
										case IpV4OptionNumber.StrictSourceRouting:
										
											IpV4RoutingOption option6 = new IpV4RoutingOption (option);
											
											m_logger.XmlWriter.WriteElementString ("Pointer",			option6.Pointer.ToString());
										
											
											
											break;
									}
									
									#endregion
									
								m_logger.XmlWriter.WriteEndElement ();
								// </Option>
							}
							
						m_logger.XmlWriter.WriteEndElement ();
						// </Options>
					}

				m_logger.XmlWriter.WriteEndElement ();
				// </IpV4Header>
			}
		}
Ejemplo n.º 2
0
        /// <summary>
        ///		Create a new generic error ICMP packet.
        /// </summary>
        /// <param name="packet">
        ///		The ICMP packet to parse.
        ///	</param>
        /// <exception cref="ArgumentNullException">
        ///		If the packet is null then an argument null exception occurs.
        ///	</exception>
        public void Constructor(IcmpPacket packet)
        {
            if (packet == null)
            {
                throw new ArgumentNullException ("packet");
            }

            // discard the unused field
            byte[] tempBuffer = new byte[packet.Data.Length - 4];
            Array.Copy (packet.Data, 4, tempBuffer, 0, tempBuffer.Length);

            // parse out the packet data
            m_badPacket = new IpV4Packet (tempBuffer);
        }
Ejemplo n.º 3
0
		/// <summary>
		///		Whenever a new IP packet arrives it should be passed to this method.
		///		If the packet is to be filtered out it will be ignored otherwise the
		///		IpV4PacketArrived will be raised with the packet
		/// </summary>
		/// <param name="packet">
		///		The packet which has arrived.
		///	</param>
		public void HandleNewPacket(IpV4Packet packet)
		{
			bool match = true;
		
			// check the source address filter
			foreach (string filter in m_sourceAddressFilter)
			{
				if (!IpV4Filter.IsMatch (packet.SourceAddress.ToString(), filter))
				{
					match = false;
					break;
				}
			}
			
			// if no match then exit
			if (!match)
			{
				return;
			}
			
			// check the destination address filter
			foreach (string filter in m_destAddressFilter)
			{
				if (!IpV4Filter.IsMatch (packet.DestinationAddress.ToString(), filter))
				{
					match = false;
					break;
				}
			}
			
			// if no match then exit
			if (!match)
			{
				return;
			}
			
			// if we get here then the packet has passed through the filter and we
			// raise the event
			if (IpV4PacketArrived != null)
			{
				IpV4PacketArrived (packet);
			}
			
		}
Ejemplo n.º 4
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="data">
        ///	
        ///	</param>
        private void NewPacket(byte[] data)
        {
            // store the time the packet arrived
            m_stop = Environment.TickCount;

            // parse out the ip header
            IpV4Packet ipPacket = new IpV4Packet (data);

            // double check to make sure this is an icmp packet
            if (ipPacket.TransportProtocol != ProtocolType.Icmp)
            {
                return;
            }

            // parse out the icmp packet
            IcmpPacket icmpPacket = new IcmpPacket (ipPacket.Data);

            // if this is an echo reply
            if (icmpPacket.MessageType == IcmpMessageType.EchoReply)
            {
                // deserialize the packet
                IcmpEcho echo = new IcmpEcho (icmpPacket);

                // if this packet matches our identifier, and destination address
                if (echo.Identifier == m_id &&
                    ipPacket.SourceAddress.Equals (m_remoteAddress))
                {
                    // disable the timeout timer
                    m_timer.Enabled = false;

                    // raise the event
                    if (PingReply != null)
                    {
                        PingReply (ipPacket, icmpPacket, (int)((uint)m_stop - (uint)m_start));
                    }

                    // reset the id back to 0 so we can resume sending packets.
                    m_id = 0;

                    // signal the wait event
                    m_waitObject.Set ();
                }
            }
        }
Ejemplo n.º 5
0
		/// <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
		}
Ejemplo n.º 6
0
        /// <summary>
        ///		Send the next request in order to find the next hop.
        /// </summary>
        private void SendRequest()
        {
            // generate a 32 byte payload
            string data = new string ('x', 32);
            byte[] payload = System.Text.ASCIIEncoding.ASCII.GetBytes (data);

            // fill in ip header fields
            IpV4Packet ipPacket = new IpV4Packet ();
            ipPacket.DestinationAddress = m_remoteAddress;
            ipPacket.SourceAddress		= m_localAddress;
            ipPacket.TransportProtocol	= ProtocolType.Icmp;
            ipPacket.TimeToLive = m_ttl;

            // save the identification
            m_ipId = ipPacket.Identification;

            // add routing options if any
            if (m_route != null)
            {
                ipPacket.Options = new IpV4Option[2];

                ipPacket.Options[0] = m_route.Serialize (m_strictRouting ? IpV4OptionNumber.StrictSourceRouting : IpV4OptionNumber.LooseSourceRouting);

                ipPacket.Options[1] = new IpV4Option ();
                ipPacket.Options[1].OptionType = IpV4OptionNumber.EndOfOptions;
                ipPacket.Options[1].IsCopied = false;
                ipPacket.Options[1].Length = 1;
                ipPacket.Options[1].Class = IpV4OptionClass.Control;
                ipPacket.Options[1].Data = null;
            }

            // create a new echo packet
            IcmpEcho echo = new IcmpEcho ();
            echo.Identifier = m_id;
            echo.Data = payload;

            // serialize the icmp packet
            IcmpPacket icmpPacket = echo.Serialize (false);
            ipPacket.Data = icmpPacket.Serialize ();

            if (m_fragment)
            {
                IpV4Packet[] fragments = ipPacket.Fragment (8);

                // send each fragment
                for (int i = 0; i < fragments.Length; i++)
                {
                    byte[] packet = fragments[i].Serialize ();
                    m_socket.SendTo (packet, 0, packet.Length, SocketFlags.None, new IPEndPoint (fragments[i].DestinationAddress, 0));
                }
            }
            else
            {
                // send the ip packet
                byte[] packet = ipPacket.Serialize ();
                m_socket.SendTo (packet, 0, packet.Length, SocketFlags.None, new IPEndPoint (ipPacket.DestinationAddress, 0));
            }

            // grab the current time
            m_start = Environment.TickCount;

            // start the timeout timer
            m_timer.Enabled = true;
        }
Ejemplo n.º 7
0
        /// <summary>
        ///		Send a new ping packet.
        /// </summary>
        /// <param name="destination">
        ///		The address to send the packet to.
        ///	</param>	
        /// <param name="payload">
        ///		The data to send in the ping.
        ///	</param>
        /// <param name="async">
        ///		If this is true, SendPing will return immediately otherwise it will wait
        ///	</param>
        /// <param name="timeOutTime">
        ///		The number of milliseconds before the reply times out.
        ///	</param>
        /// <exception cref="ObjectDisposedException">
        ///		If the class has been disposed then an ObjectDisposedException will be thrown.
        ///	</exception>
        /// <exception cref="Exception">
        ///		If the class is already waiting for a ping reply then an exception will be thrown.
        ///		Use the CancelPing method first.
        ///	</exception>
        public void SendPing(IPAddress destination, byte[] payload, bool async, double timeOutTime)
        {
            if (m_disposed)
            {
                throw new ObjectDisposedException (this.ToString(), "This object has already been disposed");
            }

            // check if a ping is already in process
            if (m_id != 0)
            {
                throw new Exception ("A ping request is already in process. Either wait for the reply, or cancel the request first");
            }

            Random random = new Random ();
            IcmpEcho echo = new IcmpEcho ();

            // generate random identifier and sequence number
            echo.Identifier			= (ushort)random.Next (ushort.MaxValue);
            echo.SequenceNumber		= (ushort)random.Next (ushort.MaxValue);

            m_id = echo.Identifier;
            m_remoteAddress = destination;
            m_timer.Interval = timeOutTime;

            // store the payload
            echo.Data = payload;

            // build the icmp header
            IcmpPacket icmpHeader = echo.Serialize (false);

            // build the ip header
            IpV4Packet ipHeader = new IpV4Packet ();

            ipHeader.TransportProtocol	= ProtocolType.Icmp;
            ipHeader.SourceAddress		= m_networkInterface;
            ipHeader.DestinationAddress	= destination;
            ipHeader.Data				= icmpHeader.Serialize ();

            if (m_fragment)
            {
                IpV4Packet[] fragments = ipHeader.Fragment (8);

                // send each fragment
                for (int i = 0; i < fragments.Length; i++)
                {
                    byte[] packet = fragments[i].Serialize ();
                    m_socket.SendTo (packet, 0, packet.Length, SocketFlags.None, new IPEndPoint (fragments[i].DestinationAddress, 0));
                }
            }
            else
            {
                // send the packet
                byte[] packet = ipHeader.Serialize ();
                m_socket.SendTo (packet, 0, packet.Length, SocketFlags.None, new IPEndPoint (ipHeader.DestinationAddress, 0));
            }

            // save the time and  start the timeout timer
            m_start = Environment.TickCount;
            m_timer.Enabled = true;

            // wait for the reply
            m_waitObject.Reset ();

            if (!async)
            {
                m_waitObject.WaitOne ();
            }
        }
Ejemplo n.º 8
0
        /// <summary>
        ///		This event occurs whenever a new packet arrives.
        /// </summary>
        /// <param name="data">
        ///		The data in the packet.
        ///	</param>
        private void NewPacket(byte[] data)
        {
            if (!m_working)
            {
                return;
            }

            // store the time the packet arrived
            m_stop = Environment.TickCount;

            // parse out the ip header
            IpV4Packet ipPacket = new IpV4Packet (data);

            // double check to make sure this is an icmp packet
            if (ipPacket.TransportProtocol != ProtocolType.Icmp)
            {
                return;
            }

            // parse out the icmp packet
            IcmpPacket icmpPacket = new IcmpPacket (ipPacket.Data);

            // if this is an echo reply
            if (icmpPacket.MessageType == IcmpMessageType.EchoReply)
            {
                #region Reply From Destination

                // deserialize the packet
                IcmpEcho echo = new IcmpEcho (icmpPacket);

                // if this packet matches our identifier, and destination address
                if (echo.Identifier == m_id)
                {
                    // disable the timeout timer
                    m_timer.Enabled = false;

                    // raise the event
                    if (RouteUpdate != null)
                    {
                        RouteUpdate (ipPacket.SourceAddress, (int)((uint)m_stop - (uint)m_start), m_ttl);
                    }

                    // raise the event
                    if (TraceFinished != null)
                    {
                        TraceFinished ();
                    }

                    // signal the wait event
                    m_waitObject.Set ();

                    // allow new trace routes
                    m_working = false;
                }

                #endregion
            }

            // if the time to live exceeded then we have a new hop
            else if (icmpPacket.MessageType == IcmpMessageType.TimeExceeded)
            {
                #region Reply From Router

                IcmpTimeExceeded icmpTimeExceeded = new IcmpTimeExceeded (icmpPacket);

                // make sure this packet is for us
                if (m_ipId != icmpTimeExceeded.BadPacket.Identification)
                {
                    return;
                }

                // disable the timeout timer
                m_timer.Enabled = false;

                // raise the event
                if (RouteUpdate != null && m_working)
                {
                    RouteUpdate (ipPacket.SourceAddress, (int)((uint)m_stop - (uint)m_start), m_ttl);
                }

                // increment the time to live.
                m_ttl++;

                // if the max hop count is exceeded
                if (m_ttl > m_maxHops)
                {
                    // disable the timeout timer
                    m_timer.Enabled = false;

                    // allow new trace routes
                    m_working = false;

                    // raise the event
                    if (MaxHopsExceeded != null)
                    {
                        MaxHopsExceeded ();
                    }

                    // signal the wait event
                    m_waitObject.Set ();
                }
                else
                {
                    // send the next request
                    SendRequest ();
                }

                #endregion
            }
        }
Ejemplo n.º 9
0
		/// <summary>
		///		The fragment method will turn this IP packet into several using fragmentation.
		/// </summary>
		/// <param name="maximumTransmissionUnit">
		///		The maximum size of the data in each fragment. The maximum transmission unit must
		///		be a multiple of 8. For example 8, 16, 24, 32 etc.
		///	</param>
		/// <returns>
		///		This method returns an array of fragmented IP packets which can be sent over the
		///		network.
		/// </returns>
		///	<exception cref="ArgumentException">
		///		The MTU (maximum Transmission Unit) must be a multiple of 8 bytes
		///	</exception>
		public IpV4Packet[] Fragment (int maximumTransmissionUnit)
		{
		
			if (maximumTransmissionUnit % 8 != 0 && maximumTransmissionUnit > 0)
			{
				throw new ArgumentException ("The MTU (maximum Transmission Unit) must be a multiple of 8 bytes", "maximumTransmissionUnit");
			}
		
			// calculate how many fragments of the maximum transmission unit size we need
			int fragmentCount = m_data.Length / maximumTransmissionUnit;
			
			// and if the data doesn't exactly divide up into the maximum transmission unit
			// size then add a new fragment for the bit on the end
			if (m_data.Length % maximumTransmissionUnit != 0)
			{
				fragmentCount++;
			}
			
			// allocate space for the fragments
			IpV4Packet[] fragments = new IpV4Packet[fragmentCount];
			
			// build each fragment
			for (int i = 0; i < fragments.Length; i++)
			{
				fragments[i] = new IpV4Packet ();

				fragments[i].SourceAddress		= m_sourceAddress;
				fragments[i].DestinationAddress = m_destAddress;
				fragments[i].Identification		= m_id;
				fragments[i].HeaderLength		= 0x14;
				fragments[i].TimeToLive			= m_ttl;
				fragments[i].TransportProtocol	= m_protocol;
				fragments[i].TypeOfService		= m_tos;
				fragments[i].Version			= 0x04;
				
				#region Add Options
				
				// if there are options...
				if (m_options != null)
				{
					
					int optionsLength = 0;
				
					// if this is the first fragment, simply copy in all the options.
					if (i == 0)
					{
						fragments[i].Options = new IpV4Option[m_options.Length];
						m_options.CopyTo (fragments[i].Options, 0);
						
						// calculate the size in bytes of the options field
						for (int j = 0; j < m_options.Length; j++)
						{
							optionsLength += m_options[j].Length;
						}
					}
					
					// if not, copy in the ones which have the copy flag set
					else
					{
						for (int j = 0; j < m_options.Length; j++)
						{
							if (m_options[j].IsCopied)
							{
							
								if (fragments[i].Options == null)
								{
									fragments[i].Options = new IpV4Option[1];
								}
								else
								{
									// add this new option to the array
									IpV4Option[] tempOptions = new IpV4Option[fragments[i].Options.Length];
									Array.Copy (fragments[i].Options, 0, tempOptions, 0, fragments[i].Options.Length);
									
									fragments[i].Options = new IpV4Option[fragments[i].Options.Length + 1];
									Array.Copy (tempOptions, 0,  fragments[i].Options, 0, tempOptions.Length);
								}
								
								fragments[i].Options[fragments[i].Options.Length - 1] = m_options[j];
									
								// calculate the new size of the options
								optionsLength += m_options[j].Length;
							}
						}
					}
					
					fragments[i].HeaderLength += (ushort)optionsLength;
					
					// if we need padding to end the header on a 32 bit boundary
					if (optionsLength % 4 != 0)
					{
						// then add padding!
						fragments[i].Padding = new byte[4 - (optionsLength % 4)];
						
						fragments[i].HeaderLength += (ushort)(4 - (optionsLength % 4));
					}
				}
				
				
				#endregion
				
				// calculate the offset
				fragments[i].ControlFlags.Offset = (ushort)(i * maximumTransmissionUnit);
				
				// set up the control flags
				fragments[i].ControlFlags.MoreFragments = (i < fragments.Length - 1);
				fragments[i].ControlFlags.DontFragment = false;
			
				// copy the data into the buffer at the correct offset
				if ((i < fragments.Length - 1) || m_data.Length % maximumTransmissionUnit == 0)
				{
					fragments[i].Data = new byte[maximumTransmissionUnit];
					Array.Copy (m_data, fragments[i].ControlFlags.Offset, fragments[i].Data, 0, maximumTransmissionUnit);
				}
				else
				{
					fragments[i].Data = new byte[m_data.Length % maximumTransmissionUnit];
					Array.Copy (m_data, fragments[i].ControlFlags.Offset, fragments[i].Data, 0, m_data.Length % maximumTransmissionUnit);
				}
				
				// and finally the total size
				fragments[i].TotalLength = (ushort)(fragments[i].HeaderLength + fragments[i].Data.Length);
			}
			
			return fragments;
		}
Ejemplo n.º 10
0
		/// <summary>
		///		Create a new IPv4 packet.
		/// </summary>
		/// <param name="packetFragments">
		///		The fragments from a fragmented packet which will be peiced together
		///		into a whole single packet.
		///	</param>
		public IpV4Packet (IpV4Packet[] packetFragments)
		{
			
			int index = 0;

			// get the index of the first packet fragment
			for (int i = 0; i < packetFragments.Length; i++)
			{
				if (packetFragments[i].ControlFlags.Offset == 0)
				{
					index = i;
					break;
				}
			}
			
			// copy fields over from the first packet
			m_version				= 0x04;
			m_destAddress			= packetFragments[index].DestinationAddress;
			m_headerLength			= packetFragments[index].HeaderLength;
			m_id					= packetFragments[index].Identification;
			m_protocol				= packetFragments[index].TransportProtocol;
			m_sourceAddress			= packetFragments[index].SourceAddress;
			m_ttl					= packetFragments[index].TimeToLive;
			m_tos.Precedence		= packetFragments[index].TypeOfService.Precedence;
			m_tos.Delay				= packetFragments[index].TypeOfService.Delay;
			m_tos.Throughput		= packetFragments[index].TypeOfService.Throughput;
			m_tos.Reliability		= packetFragments[index].TypeOfService.Reliability;
			m_icf.DontFragment		= false;
			m_icf.MoreFragments		= false;
			m_icf.Offset			= 0;
			m_fragments				= (byte)packetFragments.Length;
			
			if (packetFragments[index].Options != null)
			{
				m_options = new IpV4Option [packetFragments[index].Options.Length];
				packetFragments[index].Options.CopyTo (m_options, 0);			
			}

			if (packetFragments[index].Padding != null)
			{
				m_padding = new byte [packetFragments[index].Padding.Length];
				packetFragments[index].Padding.CopyTo (m_padding, 0);
			}
			
			
			// calculate the total size of the packet. We need to do this first so we have
			// enough space in the buffer for all the fragments because there is no guarantee
			// of the order, so we can't just resize it dynamically each time we process a 
			// new fragment. It could go anywhere in the buffer.
			m_totalLength = m_headerLength;
						
			for (int i = 0; i < packetFragments.Length; i++)
			{
				m_totalLength += (ushort) packetFragments[i].Data.Length;
			}

			// ok now allocate enough space
			m_data = new byte[m_totalLength - m_headerLength];

			// now loop through each fragment, and copy it's data into the buffer
			for (int i = 0; i < packetFragments.Length; i++)
			{
				Array.Copy (packetFragments[i].Data, 0, m_data, packetFragments[i].ControlFlags.Offset, packetFragments[i].Data.Length);
			}
		}
Ejemplo n.º 11
0
        /// <summary>
        ///		Send a SYN request to the next port to check it's state.
        /// </summary>
        private void SendRequest()
        {
            m_remoteEndPoint.Port = m_ports [m_portIndex];

            // increment the local port.
            if (m_incPorts)
            {
                if (m_localEndPoint.Port == ushort.MaxValue)
                {
                    m_localEndPoint.Port = 1024;
                }

                m_localEndPoint.Port++;
            }

            IpV4Packet ipHeader = new IpV4Packet ();

            // fill in the minimal IP fields
            ipHeader.DestinationAddress = m_remoteEndPoint.Address;
            ipHeader.SourceAddress		= m_localEndPoint.Address;

            TcpPacket tcpHeader = new TcpPacket ();

            // fill in the minimal tcp fields
            tcpHeader.DestinationPort	= (ushort)m_remoteEndPoint.Port;
            tcpHeader.SourcePort		= (ushort)m_localEndPoint.Port;
            tcpHeader.SetFlag (TcpFlags.Synchronize, true);

            // send the request
            ipHeader.Data = tcpHeader.Serialize (m_localEndPoint.Address ,m_remoteEndPoint.Address);

            // send each fragment
            if (m_fragment)
            {
                IpV4Packet[] fragments = ipHeader.Fragment (8);

                for (int i = 0; i < fragments.Length; i++)
                {
                    byte[] packet = fragments[i].Serialize ();
                    m_socket.SendTo (packet, 0, packet.Length, SocketFlags.None, new IPEndPoint (fragments[i].DestinationAddress, 0));
                }
            }

            // send the packet
            else
            {
                byte[] packet = ipHeader.Serialize ();
                m_socket.SendTo (packet, 0, packet.Length, SocketFlags.None, new IPEndPoint (ipHeader.DestinationAddress, 0));
            }

            // start the time out timer
            m_timeoutTimer.Enabled = true;
        }
Ejemplo n.º 12
0
        /// <summary>
        ///		A new packet has arrived.
        /// </summary>
        /// <param name="data">
        ///		The packet.
        ///	</param>
        private void NewPacket(byte[] data)
        {
            if (!m_working)
            {
                return;
            }

            IpV4Packet ipHeader = new IpV4Packet (data);

            // check to see if this packet doesn't belong to us
            if ((!ipHeader.SourceAddress.Equals(m_remoteEndPoint.Address)) ||
                (!ipHeader.DestinationAddress.Equals(m_localEndPoint.Address)))
            {
                return;
            }

            TcpPacket tcpHeader = new TcpPacket (ipHeader.Data);

            // check to see if this packet doesn't belong to us
            if (tcpHeader.SourcePort != (ushort)m_remoteEndPoint.Port ||
                tcpHeader.DestinationPort != (ushort)m_localEndPoint.Port)
            {
                return;
            }

            // disable the timeout timer
            m_timeoutTimer.Enabled = false;

            // if this is a reset packet
            if (tcpHeader.IsFlagSet (TcpFlags.Reset))
            {
                // then the port is closed
                if (PortReply != null)
                {
                    PortReply (m_remoteEndPoint, TcpPortState.Closed);
                }
            }

            // if it's a syn ack packet
            else if (tcpHeader.IsFlagSet (TcpFlags.Synchronize) && tcpHeader.IsFlagSet (TcpFlags.Acknowledgment))
            {
                // then the port is opened
                if (PortReply != null)
                {
                    PortReply (m_remoteEndPoint, TcpPortState.Opened);
                }

                // at this point the OS will send back a reset packet to close the connection
            }

            // increment the port
            m_portIndex++;

            // check to see if the port scan is complete
            if (m_portIndex == m_ports.Length)
            {
                if (ScanComplete != null)
                {
                    ScanComplete ();
                }

                m_sendTimer = null;
                m_working = false;

                m_waitObject.Set ();

                return;
            }

            // check the next port
            if (m_sendTimer == null)
            {
                SendRequest ();
            }
            else
            {
                m_sendTimer.Enabled = true;
            }
        }