1 // Copyright (c) 2003-2010 Christopher M. Kohlhoff
2 // Modifications (c) 2011 by Guilherme Maciel Ferreira / Intra2net AG
4 // Distributed under the Boost Software License, Version 1.0.
5 // (See accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt)
7 #include "ip/ipv6header.h"
9 #include <boost/foreach.hpp>
10 #include <boost/scoped_array.hpp>
12 #include "boost_assert_handler.h"
15 using boost::asio::ip::address_v6;
16 using boost::asio::ip::address;
17 using boost::scoped_array;
19 //-----------------------------------------------------------------------------
21 //-----------------------------------------------------------------------------
23 static const size_t Ipv6HeaderSizeInBytes = 40;
26 * @brief Default constructor.
28 Ipv6Header::Ipv6Header() :
29 IpHeader( Ipv6HeaderSizeInBytes )
31 // encode a 6 into the first 4 bits
32 Payload.encode1(0, 0, 0);
33 Payload.encode1(0, 1, 1);
34 Payload.encode1(0, 2, 1);
35 Payload.encode1(0, 3, 0);
39 * @brief Get the IP version.
41 * The Version field keeps track of which version of the protocol the
44 * @return The 4-bits representing the Version field.
46 uint8_t Ipv6Header::get_version() const
48 return ( Payload[ 0 ] >> 4 ) & 0x0F;
51 uint16_t Ipv6Header::get_header_length() const
52 { return static_cast<uint16_t>(40); }
54 uint16_t Ipv6Header::get_total_length() const
56 // the compiler converts anything smaller than int to int when adding
57 // which results in a warning when assigning the result to uint16
58 return static_cast<uint16_t>( get_payload_length() + 40 );
61 // in IPv6, this corresponds to the "HOP limit"
62 uint8_t Ipv6Header::get_time_to_live() const
63 { return get_hop_limit(); }
66 * @brief Get the Differentiated Services, originally called Traffic Class.
68 * The Differentiated Services field is used to provide QoS.
70 * @return The 8-bits representing the Differentiated Services.
72 uint8_t Ipv6Header::get_differentiated_services() const
74 uint16_t first_word = static_cast<uint16_t>( (Payload[ 0 ] << 8) | Payload[ 1 ] );
75 uint8_t differentiated_services = static_cast<uint8_t>( (first_word & 0x0FF0) >> 4 );
77 return differentiated_services;
81 * @brief Get the Flow Label field.
83 * The Flow Label field provides a way for a source and destination to mark
84 * groups of packets that have the same requirements and should be treated in
85 * the same way by the network.
87 * @return The 32-bits representing the Flow Label.
89 uint32_t Ipv6Header::get_flow_label() const
91 uint32_t flow_label = Payload.decode32( 0, 3 );
92 return ( flow_label & 0xFFFFF );
96 * @brief Get the Payload Length in bytes.
98 * This field tells how many bytes follow the 40-byte fixed length IPv6 header.
100 * @return The 16-bits representing the amount of bytes that follow the IPv6
101 * header, at most 65,535 bytes.
103 uint16_t Ipv6Header::get_payload_length() const
105 return Payload.decode16( 4, 5 );
109 * @brief Get the Next Header field.
111 * The Next Header field tells which of the extension headers, if any, follow
112 * this one. If this header is the last IP header, this field tells which
113 * transport protocol handler (e.g. TCP, UDP) to pass the packet to.
115 * @return An 8-bits number identifying the next header that follows this one.
117 uint8_t Ipv6Header::get_next_header() const
123 * @brief Get the Hop Limit field.
125 * The Hop Limit field is used to keep packets from living forever, it is
126 * decremented at each router the packet pass.
128 * @return An 8-bits number representing the amount of hops left before
129 * discarding this packet.
131 uint8_t Ipv6Header::get_hop_limit() const
137 * @brief Get the source address.
139 * The Source Address field indicates the source network host address.
141 * @brief The source address.
143 address Ipv6Header::get_source_address() const
145 address_v6::bytes_type address; // 16 bytes
146 BOOST_ASSERT( 16 == address_v6::bytes_type::size() );
149 size_t header_byte_index = 8;
150 BOOST_FOREACH( unsigned char &byte, address )
152 byte = Payload[ header_byte_index ];
156 BOOST_ASSERT( 24 == header_byte_index );
158 return address_v6( address );
162 * @brief Get the destination address.
164 * The Destination Address field indicates the destination network host address.
166 * @return The destination address.
168 address Ipv6Header::get_destination_address() const
170 address_v6::bytes_type address; // 16 bytes
171 BOOST_ASSERT( 16 == address_v6::bytes_type::size() );
174 size_t header_byte_index = 24;
175 BOOST_FOREACH( unsigned char &byte, address )
177 byte = Payload[ header_byte_index ];
181 BOOST_ASSERT( 40 == header_byte_index );
183 return address_v6( address );
191 // read the first 40 bytes (mandatory for IPv6 header) from the input stream
192 // and stores in the buffer object
193 (void) header.Payload.read( is );
195 if ( header.get_version() != 6 )
197 is.setstate( ios::failbit );