ipv6_header.hpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. //
  2. // ipv6_header.hpp
  3. // ~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
  6. //
  7. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  8. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  9. //
  10. #ifndef __ASIO2_IPV6_HEADER_HPP__
  11. #define __ASIO2_IPV6_HEADER_HPP__
  12. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  13. #pragma once
  14. #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
  15. #include <algorithm>
  16. #include <asio2/external/asio.hpp>
  17. // Packet header for IPv6.
  18. //
  19. // The wire format of an IPv6 header is:
  20. //
  21. // The 'ECN' is 2 bits
  22. //
  23. // +-------+---------+---+---------+------------------------------+ ---
  24. // | | | E | | ^
  25. // |version| DS | C | flow label | |
  26. // | (4) | (6) | N | (20) | |
  27. // +-------+---------+---+---------+---------------+--------------+ |
  28. // | | | | |
  29. // | payload length | next header | hop limit | |
  30. // | (16) | (8) | (8) | |
  31. // +---------------+---------------+------------------------------+ 40 bytes
  32. // | | |
  33. // | source IPv6 address | |
  34. // | (128) | |
  35. // +--------------------------------------------------------------+ |
  36. // | | |
  37. // | destination IPv6 address | |
  38. // | (128) | v
  39. // +--------------------------------------------------------------+ ---
  40. namespace asio2::detail
  41. {
  42. class ipv6_header
  43. {
  44. public:
  45. ipv6_header()
  46. {
  47. std::fill(rep_, rep_ + sizeof(rep_), static_cast<unsigned char>(0));
  48. }
  49. inline unsigned char version() const { return (rep_[0] >> 4) & 0xF; }
  50. inline unsigned short identification() const { return decode(4, 5); }
  51. inline unsigned char next_header() const { return rep_[6]; }
  52. inline unsigned char hop_limit() const { return rep_[7]; }
  53. inline asio::ip::address_v6 source_address() const
  54. {
  55. asio::ip::address_v6::bytes_type bytes =
  56. {
  57. {
  58. rep_[8], rep_[9], rep_[10], rep_[11],
  59. rep_[12], rep_[13], rep_[14], rep_[15],
  60. rep_[16], rep_[17], rep_[18], rep_[19],
  61. rep_[20], rep_[21], rep_[22], rep_[23]
  62. }
  63. };
  64. return asio::ip::address_v6(bytes);
  65. }
  66. inline asio::ip::address_v6 destination_address() const
  67. {
  68. asio::ip::address_v6::bytes_type bytes =
  69. {
  70. {
  71. rep_[24], rep_[25], rep_[26], rep_[27],
  72. rep_[28], rep_[29], rep_[30], rep_[31],
  73. rep_[32], rep_[33], rep_[34], rep_[35],
  74. rep_[36], rep_[37], rep_[38], rep_[39]
  75. }
  76. };
  77. return asio::ip::address_v6(bytes);
  78. }
  79. friend std::istream& operator>>(std::istream& is, ipv6_header& header)
  80. {
  81. is.read(reinterpret_cast<char*>(header.rep_), 40);
  82. if (header.version() != 6)
  83. is.setstate(std::ios::failbit);
  84. return is;
  85. }
  86. private:
  87. inline unsigned short decode(int a, int b) const
  88. {
  89. return (unsigned short)((rep_[a] << 8) + rep_[b]);
  90. }
  91. //struct IPv6hdr {
  92. // unsigned int ver : 4;
  93. // unsigned int traf_class : 8;
  94. // unsigned int flow_lab : 20;
  95. // unsigned int length : 16;
  96. // unsigned int next_header : 8;
  97. // unsigned int hop_limit : 8;
  98. // unsigned char src_addr[16];
  99. // unsigned char dest_addr[16];
  100. //};
  101. unsigned char rep_[40];
  102. };
  103. }
  104. #endif // __ASIO2_IPV6_HEADER_HPP__