/// <summary> /// Serlialize this routing option into something which /// can be passed to a TcpPacket class. /// </summary> /// <returns> /// An InternetProtocolOption class which can be passed to an IpV4Packet. /// </returns> public TcpOption Serialize() { TcpOption newOption = new TcpOption(); newOption.OptionType = TcpOptionNumber.MaximumSegmentSize; newOption.Length = 4; newOption.Data = BitConverter.GetBytes(m_maxSegmentSize); return(newOption); }
/// <summary> /// Create a new max segment size 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 max segment size option. /// </exception> public TcpMaxSegmentSizeOption(TcpOption option) { if (option == null) { throw new ArgumentNullException("option"); } if (option.OptionType != TcpOptionNumber.MaximumSegmentSize) { throw new ArgumentException("The option passed was not compatible with this class. This class accepts max segment size options only", "option"); } m_maxSegmentSize = BitConverter.ToUInt16(option.Data, 0); }
/// <summary> /// Create a new max segment size 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 max segment size option. /// </exception> public TcpMaxSegmentSizeOption(TcpOption option) { if (option == null) { throw new ArgumentNullException ("option"); } if (option.OptionType != TcpOptionNumber.MaximumSegmentSize) { throw new ArgumentException ("The option passed was not compatible with this class. This class accepts max segment size options only", "option"); } m_maxSegmentSize = BitConverter.ToUInt16 (option.Data, 0); }
/// <summary> /// Create a new Tcp packet. /// </summary> /// <param name="data"> /// The byte array representing the Tcp packet. /// </param> public TcpPacket (byte[] data) { int position = 0; #region Basic Fields // first extract the source port, remembering to convert it to host order m_sourcePort = (ushort)IPAddress.NetworkToHostOrder (BitConverter.ToInt16 (data, position)); position += 2; // same with the destination port m_destPort = (ushort)IPAddress.NetworkToHostOrder (BitConverter.ToInt16 (data, position)); position += 2; // now extract the sequence number, again converting to host order m_sequenceNumber = (uint)IPAddress.NetworkToHostOrder (BitConverter.ToInt32 (data, position)); position += 4; // same witht he acknowledgment number m_acknowledgmentNumber = (uint)IPAddress.NetworkToHostOrder (BitConverter.ToInt32 (data, position)); position += 4; // copy out the data offset. This is the upper 3 bits of the next byte // we also multiply it by 4 since this the value returned is the number of // 32 bit words. m_offset = (ushort)((data[position] >> 4) * 4); position++; // now extract the flags field. These are stored in the lower 6 bits of the next byte m_flags = (byte)(data[position] & 0x3f); position++; // copy out the window field and convert it to host order m_window = (ushort)IPAddress.NetworkToHostOrder (BitConverter.ToInt16 (data, position)); position += 2; // same again for the checksum m_checksum = (ushort)IPAddress.NetworkToHostOrder (BitConverter.ToInt16 (data, position)); position += 2; // and the same for the urgent pointer m_urgentPointer = (ushort)IPAddress.NetworkToHostOrder (BitConverter.ToInt16 (data, position)); position += 2; #endregion #region Options and Padding // a header length of more than 20 bytes indicates that there are some options if (m_offset > 0x14) { // create a new buffer of the correct size and copy the options into it byte[] optionsAndPadding = new byte[m_offset - 0x14]; Array.Copy (data, position, optionsAndPadding, 0, optionsAndPadding.Length); // go through each byte of the options for (int i = 0; i < optionsAndPadding.Length;) { TcpOption option = new TcpOption (); // fill in basic fields option.OptionType = (TcpOptionNumber)optionsAndPadding[i]; i++; #region Fill in Basic Option Fields if (option.OptionType == TcpOptionNumber.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 != TcpOptionNumber.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 TcpOption[1]; } else { TcpOption[] tempOptions = new TcpOption[m_options.Length]; Array.Copy (m_options, 0, tempOptions, 0, m_options.Length); m_options = new TcpOption[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 == TcpOptionNumber.EndOfOptions) { break; } } position += optionsAndPadding.Length; } #endregion // now check if there is any data if (data.Length > m_offset) { // allocate a new buffer for it and copy the data in to the buffer m_data = new byte[data.Length - m_offset]; Array.Copy (data, position, m_data, 0, m_data.Length); } }
/// <summary> /// Create a new Tcp packet. /// </summary> /// <param name="data"> /// The byte array representing the Tcp packet. /// </param> public TcpPacket(byte[] data) { int position = 0; #region Basic Fields // first extract the source port, remembering to convert it to host order m_sourcePort = (ushort)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(data, position)); position += 2; // same with the destination port m_destPort = (ushort)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(data, position)); position += 2; // now extract the sequence number, again converting to host order m_sequenceNumber = (uint)IPAddress.NetworkToHostOrder(BitConverter.ToInt32(data, position)); position += 4; // same witht he acknowledgment number m_acknowledgmentNumber = (uint)IPAddress.NetworkToHostOrder(BitConverter.ToInt32(data, position)); position += 4; // copy out the data offset. This is the upper 3 bits of the next byte // we also multiply it by 4 since this the value returned is the number of // 32 bit words. m_offset = (ushort)((data[position] >> 4) * 4); position++; // now extract the flags field. These are stored in the lower 6 bits of the next byte m_flags = (byte)(data[position] & 0x3f); position++; // copy out the window field and convert it to host order m_window = (ushort)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(data, position)); position += 2; // same again for the checksum m_checksum = (ushort)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(data, position)); position += 2; // and the same for the urgent pointer m_urgentPointer = (ushort)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(data, position)); position += 2; #endregion #region Options and Padding // a header length of more than 20 bytes indicates that there are some options if (m_offset > 0x14) { // create a new buffer of the correct size and copy the options into it byte[] optionsAndPadding = new byte[m_offset - 0x14]; Array.Copy(data, position, optionsAndPadding, 0, optionsAndPadding.Length); // go through each byte of the options for (int i = 0; i < optionsAndPadding.Length;) { TcpOption option = new TcpOption(); // fill in basic fields option.OptionType = (TcpOptionNumber)optionsAndPadding[i]; i++; #region Fill in Basic Option Fields if (option.OptionType == TcpOptionNumber.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 != TcpOptionNumber.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 TcpOption[1]; } else { TcpOption[] tempOptions = new TcpOption[m_options.Length]; Array.Copy(m_options, 0, tempOptions, 0, m_options.Length); m_options = new TcpOption[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 == TcpOptionNumber.EndOfOptions) { break; } } position += optionsAndPadding.Length; } #endregion // now check if there is any data if (data.Length > m_offset) { // allocate a new buffer for it and copy the data in to the buffer m_data = new byte[data.Length - m_offset]; Array.Copy(data, position, m_data, 0, m_data.Length); } }
/// <summary> /// Serlialize this routing option into something which /// can be passed to a TcpPacket class. /// </summary> /// <returns> /// An InternetProtocolOption class which can be passed to an IpV4Packet. /// </returns> public TcpOption Serialize () { TcpOption newOption = new TcpOption (); newOption.OptionType = TcpOptionNumber.MaximumSegmentSize; newOption.Length = 4; newOption.Data = BitConverter.GetBytes (m_maxSegmentSize); return newOption; }