Beispiel #1
0
		/// <summary>
		///		Serlialize this routing option into something which
		///		can be passed to an IpV4Packet class.
		/// </summary>
		/// <returns>	
		///		An IpV4Option class which can be passed to an IpV4Packet.
		///	</returns>
		public IpV4Option Serialize ()
		{
			IpV4Option newOption = new IpV4Option ();
			
			// fill in basic fields
			newOption.Class			= IpV4OptionClass.DebuggingAndMeasurement;
			newOption.OptionType	= IpV4OptionNumber.InternetTimestamp;
			newOption.IsCopied		= false;
			newOption.Length		= (m_timestamps.Length * (m_type == IpV4TimestampType.TimestampAndAddress ? 8 : 4)) + 4;
			newOption.Data			= new byte[newOption.Length - 2];
				
			// first copy in the pointer
			newOption.Data[0] = (byte)m_pointer;
			
			// then the overflow and type
			newOption.Data[1] =  (byte)(m_overflow << 4);
			newOption.Data[1] |= (byte)m_type;
			
			// loop through each field and add that
			for (int i = 0; i < m_timestamps.Length; i++)
			{
				if (m_type == IpV4TimestampType.TimestampAndAddress)
				{
				
					Array.Copy (m_addressstamps[i].GetAddressBytes (), 0, newOption.Data, (i * 8) + 2, 4);
					Array.Copy (BitConverter.GetBytes (m_timestamps[i]), 0, newOption.Data, (i * 8) + 6, 4);
				}	
				else
				{
					Array.Copy (BitConverter.GetBytes (m_timestamps[i]), 0, newOption.Data, (i * 4) + 2, 4);
				}
			}
			
			return newOption;
		}
Beispiel #2
0
		/// <summary>
		///		Serlialize this routing option into something which
		///		can be passed to an IpV4Packet class.
		/// </summary>
		/// <returns>	
		///		An IpV4Option class which can be passed to an IpV4Packet.
		///	</returns>
		public IpV4Option Serialize ()
		{
			IpV4Option newOption = new IpV4Option ();
			
			// fill in basic fields
			newOption.Class			= IpV4OptionClass.Control;
			newOption.OptionType	= IpV4OptionNumber.StreamId;
			newOption.IsCopied		= true;
			newOption.Length		= 4;
			newOption.Data			= new byte[2];
			
			// copy in the stream id
			newOption.Data = BitConverter.GetBytes (m_id);
			
			return newOption;
		}
Beispiel #3
0
		/// <summary>
		///		Create a new time stamp option.
		/// </summary>
		/// <param name="option">
		///		The option to parse.
		///	</param>
		/// <exception cref="ArgumentNullException">
		///		The option argument is null.
		///	</exception>
		/// <exception cref="ArgumentException">
		///		The option argument is not a timestamp option.
		///	</exception>
		public IpV4TimeStampOption (IpV4Option option)
		{
			if (option == null)
			{
				throw new ArgumentNullException ("option");
			}
		
			if (option.OptionType != IpV4OptionNumber.InternetTimestamp)
			{
				throw new ArgumentException ("The option passed was not compatible with this class. This class accepts timestamp options only", "option");
			}
			
			// extract the pointer
			m_pointer = (byte)option.Data[0];
			
			// extract the overflow field
			m_overflow = (byte)((option.Data[1] & 0xf0) >> 4);
			
			// extract the type
			m_type = (IpV4TimestampType)(option.Data[1] & 0xf);

			// calculate how many fields there are and allocate space
			int numberStamps = (option.Data.Length - 2) / 4;
			
			if (m_type == IpV4TimestampType.TimestampAndAddress)
			{
				numberStamps /= 2;
				m_addressstamps = new IPAddress[numberStamps];
			}
			
			m_timestamps = new uint[numberStamps];
			
			// extract the time stamps and addresses
			for (int i = 0; i < numberStamps; i++)
			{
				if (m_type == IpV4TimestampType.TimestampAndAddress)
				{
					uint address = BitConverter.ToUInt32 (option.Data, (i * 8) + 2);
					m_addressstamps[i] = new IPAddress ((long)address);
					
					m_timestamps[i] = BitConverter.ToUInt32 (option.Data, (i * 8) + 6);
				}
				else
				{
					m_timestamps[i] = BitConverter.ToUInt32 (option.Data, (i * 4) + 2);
				}
			}
		}
Beispiel #4
0
		/// <summary>
		///		Serlialize this routing option into something which
		///		can be passed to an IpV4Packet class.
		/// </summary>
		/// <param name="optionType">
		///		There are 3 types of routing option: loose source, strict source and record.
		///	</param>
		/// <returns>	
		///		An IpV4Option class which can be passed to an IpV4Packet.
		///	</returns>
		///	<exception cref="ArgumentException">
		///		The option type is not a routing option.
		///	</exception>
		public IpV4Option Serialize (IpV4OptionNumber optionType)
		{
			IpV4Option newOption = new IpV4Option ();
			
			if (optionType != IpV4OptionNumber.LooseSourceRouting &&
				optionType != IpV4OptionNumber.StrictSourceRouting &&
				optionType != IpV4OptionNumber.RecordRoute)
			{
				throw new ArgumentException ("The option type must be a routing option (strict source routing, loose source routing or record route", "option");
			}
			
			// fill in basic fields
			newOption.Class			= IpV4OptionClass.Control;
			newOption.OptionType	= optionType;
			newOption.IsCopied		= true;
			newOption.Length		= (m_routeData.Length * 4) + 3;
			newOption.Data			= new byte[(m_routeData.Length * 4) + 1];
			
			// fill in the pointer
			newOption.Data [0] = (byte)m_pointer;
			
			// fill in the route data
			for (int i = 0; i < m_routeData.Length; i++)
			{
				Array.Copy (m_routeData[i].GetAddressBytes (), 0, newOption.Data, (i * 4) + 1, 4);
			}
			
			return newOption;
		}
Beispiel #5
0
		/// <summary>
		///		Create a new stream identifier option.
		/// </summary>
		/// <param name="option">
		///		The option to parse.
		///	</param>
		public IpV4StreamIdentifierOption (IpV4Option option)
		{
			if (option == null)
			{
				throw new ArgumentNullException ("option");
			}
		
			if (option.OptionType != IpV4OptionNumber.StreamId)
			{
				throw new ArgumentException ("The option passed was not compatible with this class. This class accepts stream id options only", "option");
			}
			
			// extract the stream id
			m_id = BitConverter.ToUInt16 (option.Data, 0);
		}
Beispiel #6
0
		/// <summary>
		///		Create a new routing option.
		/// </summary>
		/// <param name="option">
		///		The option to parse.
		///	</param>
		/// <exception cref="ArgumentNullException">
		///		The option argument is null.
		///	</exception>
		/// <exception cref="ArgumentException">
		///		The option argument is not a routing option.
		///	</exception>
		public IpV4RoutingOption (IpV4Option option)
		{
			if (option == null)
			{
				throw new ArgumentNullException ("option");
			}
		
			if (option.OptionType != IpV4OptionNumber.LooseSourceRouting &&
				option.OptionType != IpV4OptionNumber.StrictSourceRouting &&
				option.OptionType != IpV4OptionNumber.RecordRoute)
			{
				throw new ArgumentException ("The option passed was not compatible with this class. This class accepts routing options only", "option");
			}
			
			// read the pointer
			m_pointer = (byte)option.Data[0];
			
			// get the number of addresses in the route
			// and allocate enough space
			int routeSize = (option.Length - 3) / 4;
			m_routeData = new IPAddress[routeSize];
			
			// extract each address from the data
			for (int i = 0; i < m_routeData.Length; i++)
			{
				uint address = BitConverter.ToUInt32 (option.Data, i * 4 + 1);
				m_routeData[i] = new IPAddress ((long)address);
			}
		}
Beispiel #7
0
		/// <summary>
		///		Serlialize this routing option into something which
		///		can be passed to an IpV4Packet class.
		/// </summary>
		/// <returns>	
		///		An IpV4Option class which can be passed to an IpV4Packet.
		///	</returns>
		public IpV4Option Serialize ()
		{
			IpV4Option newOption = new IpV4Option ();
			
			// fill in basic fields
			newOption.Class			= IpV4OptionClass.Control;
			newOption.OptionType	= IpV4OptionNumber.Security;
			newOption.IsCopied		= true;
			newOption.Length		= 11;
			newOption.Data			= new byte[9];
			
			// fill in the security bytes
			newOption.Data[0] =		(byte)((int)m_level & 0x00ff);
			newOption.Data[1] =		(byte)(((int)m_level & 0xff00) >> 8);

			// fill in the compartment bytes
			newOption.Data[2] =		(byte)(m_compartment & 0x00ff);
			newOption.Data[3] =		(byte)((m_compartment & 0xff00) >> 8);
			
			// fill in the handling bytes
			newOption.Data[4] =		(byte)(m_handling & 0x00ff);
			newOption.Data[5] =		(byte)((m_handling & 0xff00) >> 8);
			
			// fill in the transmission control code bytes
			newOption.Data[6] =		(byte)((m_tcc & 0xff0000) >> 16);
			newOption.Data[7] =		(byte)((m_tcc & 0x00ff00) >> 8);
			newOption.Data[8] =		(byte)(m_tcc & 0x0000ff);
			
			return newOption;
		}
Beispiel #8
0
		/// <summary>
		///		Create a new security option.
		/// </summary>
		/// <param name="option">
		///		The option to parse.
		///	</param>
		/// <exception cref="ArgumentNullException">
		///		The option argument is null.
		///	</exception>
		/// <exception cref="ArgumentException">
		///		The option argument is not a security option.
		///	</exception>
		public IpV4SecurityOption (IpV4Option option)
		{
			if (option == null)
			{
				throw new ArgumentNullException ("option");
			}
		
			if (option.OptionType != IpV4OptionNumber.Security)
			{
				throw new ArgumentException ("The option passed was not compatible with this class. This class accepts security options only", "option");
			}
			
			// extract the security level field
			m_level = (IpV4SecurityLevelType) BitConverter.ToUInt16 (option.Data, 0);
			
			// extract the compartment field
			m_compartment = BitConverter.ToUInt16 (option.Data, 2);
			
			// extract the handling restrictions field
			m_handling = BitConverter.ToUInt16 (option.Data, 4);
			
			// extract the 24 bits of the transmission control code
			
			m_tcc = (uint)(option.Data[6] << 0x10);
			m_tcc |= (uint)(option.Data[7] << 0x08);
			m_tcc |= option.Data[8];
			
		}
Beispiel #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;
		}
Beispiel #10
0
		/// <summary>
		///		Create a new IPv4 packet.
		/// </summary>
		/// <param name="data">
		///		The byte array representing the IP packet.
		///	</param>
		public IpV4Packet (byte[] data)
		{
			int position = 0;
			
			#region Basic Fields
			
			// extract the version field from the first 4 bits of the packet
			m_version			= Convert.ToByte ((data[position] >> 4));
			
			// extract the header length field from the next 4 bits. This is the number
			// of 32 bit words so multiply by 4 to get the number of 8 bit words..i.e..bytes
			m_headerLength		= Convert.ToByte ((data[position] & 0x0f) * 4);
			position++;
			
			// extract the precedence from the next 3 bits
			m_tos.Precedence	= (IpV4PrecedenceType)	(data[position] >> 5);
			
			// then extract the delay, throughput and reliability bits
			m_tos.Delay			= (IpV4DelayType)		((data[position] & 0x10) >> 4);
			m_tos.Throughput	= (IpV4ThroughputType)	((data[position] & 0x8) >> 3); 
			m_tos.Reliability	= (IpV4ReliabilityType)	((data[position] & 0x4) >> 2); 
			position++;
			
			// get the total length (remembering to convert it to host order)
			m_totalLength		= (ushort)(IPAddress.NetworkToHostOrder (BitConverter.ToInt16 (data, position)));
			position += 2;
			
			// same with the identification field
			m_id				= (ushort)(IPAddress.NetworkToHostOrder (BitConverter.ToInt16	(data, position)));
			position += 2;
			
			// extract the internet control flags
			m_icf.DontFragment	= ((data[position] & 0x40) >> 6) == 1;
			m_icf.MoreFragments	= ((data[position] & 0x20) >> 5) == 1;
			
			// and the fragmentation offsent (remember to convert to host order)
			m_icf.Offset	= (ushort)(IPAddress.NetworkToHostOrder ((Convert.ToInt16 (BitConverter.ToInt16 (data, position) & 0x1fff))) * 8);
			position += 2;
			
			// the time to live is just in a single byte
			m_ttl			= data[position];
			position++;
			
			// as is the protocol
			m_protocol		= (ProtocolType)(data[position]);
			position++;
			
			// the checksum
			m_checksum		= (ushort)(IPAddress.NetworkToHostOrder (BitConverter.ToInt16 (data, position)));
			position += 2;
			
			// now copy in the source address
			m_sourceAddress	= new IPAddress (BitConverter.ToUInt32 (data, position));
			position += 4;
			
			// and the destination address
			m_destAddress	= new IPAddress (BitConverter.ToUInt32 (data, position));
			position += 4;
			
			#endregion
			
			#region Options and Padding
			
			// check if there are any options (if the header length is greater than the
			// smallest, 0x14 bytes)
			if (m_headerLength > 0x14)
			{
				// create a new buffer of the correct size and copy the options into it
				byte[] optionsAndPadding = new byte[m_headerLength - 0x14];
				Array.Copy (data, position, optionsAndPadding, 0, optionsAndPadding.Length);
				
				// go through each byte of the options
				for (int i = 0; i < optionsAndPadding.Length;)
				{
					IpV4Option option = new IpV4Option ();
					
					// fill in basic fields
					option.OptionType	= (IpV4OptionNumber)optionsAndPadding[i];
					i++;
					
					#region Fill in Basic Option Fields
					
					if (option.OptionType == IpV4OptionNumber.EndOfOptions)
					{
						// copy the padding field out of the header
						if (optionsAndPadding.Length - i > 0)
						{
							m_padding = new byte[optionsAndPadding.Length - i];
							Array.Copy (optionsAndPadding, i, m_padding, 0, m_padding.Length);
						}
						
						// add this option to the array
						option.Length = 1;
					}
					else if (option.OptionType != IpV4OptionNumber.NoOperation)
					{
						// copy out the length field
						option.Length = (int)(optionsAndPadding[i]);
						option.Data = new byte[option.Length - 2];

						// copy the actual data out of the packet
						i++;	
						Array.Copy (optionsAndPadding, i, option.Data, 0, option.Data.Length);
						
						// add this new option to the array
						i += option.Data.Length;
					}
					else
					{
						option.Length = 1;
					}
					
					#endregion
					
					#region Add Option
					
					if (m_options == null)
					{
						m_options = new IpV4Option[1];
					}
					else
					{
						IpV4Option[] tempOptions = new IpV4Option[m_options.Length];
						Array.Copy (m_options, 0, tempOptions, 0, m_options.Length);
						
						m_options = new IpV4Option[m_options.Length + 1];
						Array.Copy (tempOptions, 0,  m_options, 0, tempOptions.Length);
						
						m_options[m_options.Length - 1] = option;
					}
			
					m_options[m_options.Length - 1] = option;
					
					#endregion
							
					if (option.OptionType == IpV4OptionNumber.EndOfOptions)
					{
						break;
					}
				}
	
				position += optionsAndPadding.Length;
			}
			
			#endregion
			
			// now check if there is any data (which there should be)
			if (data.Length > m_headerLength)
			{
				// allocate a new buffer for it and copy the data in to the buffer
				m_data = new byte[data.Length - m_headerLength];
				Array.Copy (data, position, m_data, 0, m_data.Length);
			}
		}