From 01e5134e3d7eb491aee2c84df99f70769ffc035e Mon Sep 17 00:00:00 2001 From: Guilherme Maciel Ferreira Date: Thu, 25 Aug 2011 22:07:17 -0300 Subject: [PATCH] Replaced the raw byte array by a MessagePayload object, this class provides methods to handle decoding of network words --- src/ip/ipv4header.cpp | 84 +++++++++++++++++++++++------------------------- src/ip/ipv4header.h | 7 ++-- 2 files changed, 43 insertions(+), 48 deletions(-) diff --git a/src/ip/ipv4header.cpp b/src/ip/ipv4header.cpp index 22bca50..655063e 100644 --- a/src/ip/ipv4header.cpp +++ b/src/ip/ipv4header.cpp @@ -8,8 +8,11 @@ #include +#include + using namespace std; using boost::asio::ip::address_v4; +using boost::scoped_array; //----------------------------------------------------------------------------- // Ipv4Header @@ -17,19 +20,25 @@ using boost::asio::ip::address_v4; static const size_t Ipv4HeaderSizeInBytes = 20; -Ipv4Header::Ipv4Header() +Ipv4Header::Ipv4Header() : + Payload( Ipv4HeaderSizeInBytes ) { - fill( Payload, Payload + sizeof(Payload), 0 ); } uint8_t Ipv4Header::get_version() const { - return ( Payload[ 0 ] >> 4 ) & 0xF; + return ( Payload[ 0 ] >> 4 ) & 0x0F; } uint16_t Ipv4Header::get_header_length() const { - return static_cast( (Payload[ 0 ] & 0xF) * 4 ); + // The Internet Header Length tells the number of 32-bit words in the + // header. Since an IPv4 header may contain a variable number of options, + // this field specifies the size of the header (this also coincides with + // the offset to the data). The minimum value for this field is 5 (RFC 791), + // which is a length of 5×32 = 160 bits = 20 bytes. Being a 4-bit value, + // the maximum length is 15 words (15×32 bits) or 480 bits = 60 bytes. + return static_cast( (Payload[ 0 ] & 0x0F) * 4 ); } uint8_t Ipv4Header::get_type_of_service() const @@ -39,12 +48,12 @@ uint8_t Ipv4Header::get_type_of_service() const uint16_t Ipv4Header::get_total_length() const { - return decode( 2, 3 ); + return Payload.decode16( 2, 3 ); } uint16_t Ipv4Header::get_identification() const { - return decode( 4, 5 ); + return Payload.decode16( 4, 5 ); } bool Ipv4Header::dont_fragment() const @@ -59,7 +68,7 @@ bool Ipv4Header::more_fragments() const uint16_t Ipv4Header::get_fragment_offset() const { - return decode( 6, 7 ) & 0x1FFF; + return Payload.decode16( 6, 7 ) & 0x1FFF; } uint8_t Ipv4Header::get_time_to_live() const @@ -74,29 +83,21 @@ uint8_t Ipv4Header::get_protocol() const uint16_t Ipv4Header::get_header_checksum() const { - return decode( 10, 11 ); + return Payload.decode16( 10, 11 ); } address_v4 Ipv4Header::get_source_address() const { - address_v4::bytes_type bytes = { { - Payload[ 12 ], - Payload[ 13 ], - Payload[ 14 ], - Payload[ 15 ] - } }; - return address_v4( bytes ); + uint32_t address = Payload.decode32( 12, 15 ); + + return address_v4( address ); } address_v4 Ipv4Header::get_destination_address() const { - address_v4::bytes_type bytes = { { - Payload[ 16 ], - Payload[ 17 ], - Payload[ 18 ], - Payload[ 19 ] - } }; - return address_v4( bytes ); + uint32_t address = Payload.decode32( 16, 19 ); + + return address_v4( address ); } istream &operator>>( @@ -104,37 +105,32 @@ istream &operator>>( Ipv4Header &header ) { - (void) is.read( - reinterpret_cast ( header.Payload ), - Ipv4HeaderSizeInBytes - ); + // read the first 20 bytes (mandatory for IP header) from the input stream + // and stores in the buffer object + header.Payload.read( is ); if ( header.get_version() != 4 ) + { is.setstate( ios::failbit ); - streamsize options_length = - (streamsize) header.get_header_length() - - Ipv4HeaderSizeInBytes; - if ( options_length < 0 || 40 < options_length ) + } + + // read the consecutive N bytes (for options field) from the input stream + // and stores in the buffer object + streamsize options_length = (streamsize) header.get_header_length() - + Ipv4HeaderSizeInBytes; + if ( ( options_length < 0 ) || ( 40 < options_length ) ) { is.setstate( ios::failbit ); } else { - (void) is.read( - reinterpret_cast ( header.Payload ) + - Ipv4HeaderSizeInBytes, - options_length - ); - } + scoped_array options_data(new uint8_t[options_length]); + char *options_data_array = reinterpret_cast( options_data.get() ); - return is; -} - -uint16_t Ipv4Header::decode( int left_byte, int right_byte ) const -{ - uint32_t value = ( Payload[ left_byte ] << 8 ) + Payload[ right_byte ]; + is.read( options_data_array, options_length ); - BOOST_ASSERT( value <= numeric_limits::max() ); + header.Payload.append( options_data.get(), options_length ); + } - return static_cast( value ); + return is; } diff --git a/src/ip/ipv4header.h b/src/ip/ipv4header.h index 4f07b3e..f7811c5 100644 --- a/src/ip/ipv4header.h +++ b/src/ip/ipv4header.h @@ -11,6 +11,8 @@ #include +#include "host/messagepayload.h" + //----------------------------------------------------------------------------- // Ipv4Header //----------------------------------------------------------------------------- @@ -76,10 +78,7 @@ public: ); private: - uint16_t decode( int left_byte, int right_byte ) const; - -private: - uint8_t Payload[ 60 ]; + MessagePayload Payload; }; -- 1.7.1