libtins  4.0
icmpv6.h
1 /*
2  * Copyright (c) 2017, Matias Fontanini
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  * * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * * Redistributions in binary form must reproduce the above
12  * copyright notice, this list of conditions and the following disclaimer
13  * in the documentation and/or other materials provided with the
14  * distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  *
28  */
29 
30 #ifndef TINS_ICMPV6_H
31 #define TINS_ICMPV6_H
32 
33 #include <vector>
34 #include <tins/macros.h>
35 #include <tins/pdu.h>
36 #include <tins/ipv6_address.h>
37 #include <tins/pdu_option.h>
38 #include <tins/endianness.h>
39 #include <tins/small_uint.h>
40 #include <tins/hw_address.h>
41 #include <tins/small_uint.h>
42 #include <tins/icmp_extension.h>
43 #include <tins/cxxstd.h>
44 
45 namespace Tins {
46 namespace Memory {
47 
48 class InputMemoryStream;
49 class OutputMemoryStream;
50 
51 } // memory
52 
57 class TINS_API ICMPv6 : public PDU {
58 public:
62  static const PDU::PDUType pdu_flag = PDU::ICMPv6;
63 
67  enum Types {
68  DEST_UNREACHABLE = 1,
69  PACKET_TOOBIG = 2,
70  TIME_EXCEEDED = 3,
71  PARAM_PROBLEM = 4,
72  ECHO_REQUEST = 128,
73  ECHO_REPLY = 129,
74  MGM_QUERY = 130,
75  MGM_REPORT = 131,
76  MGM_REDUCTION = 132,
77  ROUTER_SOLICIT = 133,
78  ROUTER_ADVERT = 134,
79  NEIGHBOUR_SOLICIT = 135,
80  NEIGHBOUR_ADVERT = 136,
81  REDIRECT = 137,
82  ROUTER_RENUMBER = 138,
83  NI_QUERY = 139,
84  NI_REPLY = 140,
85  MLD2_REPORT = 143,
86  DHAAD_REQUEST = 144,
87  DHAAD_REPLY = 145,
88  MOBILE_PREFIX_SOLICIT = 146,
89  MOBILE_PREFIX_ADVERT = 147,
90  CERT_PATH_SOLICIT = 148,
91  CERT_PATH_ADVERT = 149,
92  MULTICAST_ROUTER_ADVERT = 151,
93  MULTICAST_ROUTER_SOLICIT = 152,
94  MULTICAST_ROUTER_TERMINATE = 153,
95  RPL_CONTROL_MSG = 155
96  };
97 
101  enum OptionTypes {
102  SOURCE_ADDRESS = 1,
103  TARGET_ADDRESS,
104  PREFIX_INFO,
105  REDIRECT_HEADER,
106  MTU,
107  NBMA_SHORT_LIMIT,
108  ADVERT_INTERVAL,
109  HOME_AGENT_INFO,
110  S_ADDRESS_LIST,
111  T_ADDRESS_LIST,
112  CGA,
113  RSA_SIGN,
114  TIMESTAMP,
115  NONCE,
116  TRUST_ANCHOR,
117  CERTIFICATE,
118  IP_PREFIX,
119  NEW_ROUTER_PREFIX,
120  LINK_ADDRESS,
121  NAACK,
122  MAP = 23,
123  ROUTE_INFO,
124  RECURSIVE_DNS_SERV,
125  RA_FLAGS_EXT,
126  HANDOVER_KEY_REQ,
127  HANDOVER_KEY_REPLY,
128  HANDOVER_ASSIST_INFO,
129  MOBILE_NODE_ID,
130  DNS_SEARCH_LIST,
131  PROXY_SIGNATURE,
132  ADDRESS_REG,
133  SIXLOWPAN_CONTEXT,
134  AUTHORITATIVE_BORDER_ROUTER,
135  CARD_REQUEST = 138,
136  CARD_REPLY
137  };
138 
143 
148 
153 
157  typedef std::vector<option> options_type;
158 
163  typedef std::vector<uint16_t> new_ha_info_type;
164 
168  struct addr_list_type {
169  typedef std::vector<ipaddress_type> addresses_type;
170 
171  uint8_t reserved[6];
172  addresses_type addresses;
173 
174  addr_list_type(const addresses_type& addresses = addresses_type())
175  : addresses(addresses) {
176  std::fill(reserved, reserved + sizeof(reserved), 0);
177  }
178 
179  static addr_list_type from_option(const option& opt);
180  };
181 
185  typedef std::vector<uint8_t> nonce_type;
186 
190  typedef std::pair<uint16_t, uint32_t> mtu_type;
191 
196  struct naack_type {
197  uint8_t code, status;
198  uint8_t reserved[4];
199 
200  naack_type(uint8_t code = 0, uint8_t status = 0)
201  : code(code), status(status) {
202  std::fill(reserved, reserved + 4, 0);
203  }
204 
205  static naack_type from_option(const option& opt);
206  };
207 
211  struct lladdr_type {
212  typedef std::vector<uint8_t> address_type;
213 
214  uint8_t option_code;
215  address_type address;
216 
223  lladdr_type(uint8_t option_code = 0,
224  const address_type& address = address_type())
225  : option_code(option_code), address(address) {
226 
227  }
228 
238  lladdr_type(uint8_t option_code, const hwaddress_type& address)
239  : option_code(option_code), address(address.begin(), address.end()) {
240 
241  }
242 
243  static lladdr_type from_option(const option& opt);
244  };
245 
250  uint8_t prefix_len;
251  small_uint<1> A, L;
252  uint32_t valid_lifetime,
253  preferred_lifetime,
254  reserved2;
255  ipaddress_type prefix;
256 
257  prefix_info_type(uint8_t prefix_len = 0,
258  small_uint<1> A = 0,
259  small_uint<1> L = 0,
260  uint32_t valid_lifetime = 0,
261  uint32_t preferred_lifetime = 0,
262  const ipaddress_type& prefix = ipaddress_type())
263  : prefix_len(prefix_len), A(A), L(L), valid_lifetime(valid_lifetime),
264  preferred_lifetime(preferred_lifetime), reserved2(0), prefix(prefix) { }
265 
266  static prefix_info_type from_option(const option& opt);
267  };
268 
272  struct rsa_sign_type {
273  typedef std::vector<uint8_t> signature_type;
274 
275  uint8_t key_hash[16];
276  signature_type signature;
277 
296  template <typename RAIterator, typename ForwardIterator>
297  rsa_sign_type(RAIterator hash, ForwardIterator start, ForwardIterator end)
298  : signature(start, end) {
299  std::copy(hash, hash + sizeof(key_hash), key_hash);
300  }
301 
314  template <typename RAIterator>
315  rsa_sign_type(RAIterator hash, const signature_type& sign)
316  : signature(sign) {
317  std::copy(hash, hash + sizeof(key_hash), key_hash);
318  }
319 
326  std::fill(key_hash, key_hash + sizeof(key_hash), 0);
327  }
328 
329  static rsa_sign_type from_option(const option& opt);
330  };
331 
335  struct ip_prefix_type {
336  uint8_t option_code, prefix_len;
337  ipaddress_type address;
338 
339  ip_prefix_type(uint8_t option_code = 0,
340  uint8_t prefix_len = 0,
341  const ipaddress_type& address = ipaddress_type())
342  : option_code(option_code), prefix_len(prefix_len), address(address)
343  {}
344 
345  static ip_prefix_type from_option(const option& opt);
346  };
347 
351  struct map_type {
352  small_uint<4> dist, pref;
353  small_uint<1> r;
354  uint32_t valid_lifetime;
355  ipaddress_type address;
356 
357  map_type(small_uint<4> dist = 0,
358  small_uint<4> pref = 0,
359  small_uint<1> r = 0,
360  uint32_t valid_lifetime = 0,
361  const ipaddress_type& address = ipaddress_type())
362  : dist(dist), pref(pref), r(r), valid_lifetime(valid_lifetime),
363  address(address) { }
364 
365  static map_type from_option(const option& opt);
366  };
367 
372  typedef std::vector<uint8_t> prefix_type;
373 
374  uint8_t prefix_len;
375  small_uint<2> pref;
376  uint32_t route_lifetime;
377  prefix_type prefix;
378 
379  route_info_type(uint8_t prefix_len = 0,
380  small_uint<2> pref = 0,
381  uint32_t route_lifetime = 0,
382  const prefix_type& prefix = prefix_type())
383  : prefix_len(prefix_len), pref(pref), route_lifetime(route_lifetime),
384  prefix(prefix) { }
385 
386  static route_info_type from_option(const option& opt);
387  };
388 
393  typedef std::vector<ipaddress_type> servers_type;
394 
395  uint32_t lifetime;
396  servers_type servers;
397 
398  recursive_dns_type(uint32_t lifetime = 0,
399  const servers_type& servers = servers_type())
400  : lifetime(lifetime), servers(servers) {}
401 
402  static recursive_dns_type from_option(const option& opt);
403  };
404 
409  typedef std::vector<uint8_t> key_type;
410 
411  small_uint<4> AT;
412  key_type key;
413 
415  const key_type& key = key_type())
416  : AT(AT), key(key) { }
417 
418  static handover_key_req_type from_option(const option& opt);
419  };
420 
425  uint16_t lifetime;
426 
427  handover_key_reply_type(uint16_t lifetime = 0,
428  small_uint<4> AT = 0,
429  const key_type& key = key_type())
430  : handover_key_req_type(AT, key), lifetime(lifetime) { }
431 
432  static handover_key_reply_type from_option(const option& opt);
433  };
434 
439  typedef std::vector<uint8_t> hai_type;
440 
441  uint8_t option_code;
442  hai_type hai;
443 
444  handover_assist_info_type(uint8_t option_code=0,
445  const hai_type& hai = hai_type())
446  : option_code(option_code), hai(hai) { }
447 
448  static handover_assist_info_type from_option(const option& opt);
449  };
450 
455  typedef std::vector<uint8_t> mn_type;
456 
457  uint8_t option_code;
458  mn_type mn;
459 
460  mobile_node_id_type(uint8_t option_code=0,
461  const mn_type& mn = mn_type())
462  : option_code(option_code), mn(mn) { }
463 
464  static mobile_node_id_type from_option(const option& opt);
465  };
466 
471  typedef std::vector<std::string> domains_type;
472 
473  uint32_t lifetime;
474  domains_type domains;
475 
476  dns_search_list_type(uint32_t lifetime = 0,
477  const domains_type& domains = domains_type())
478  : lifetime(lifetime), domains(domains) { }
479 
480  static dns_search_list_type from_option(const option& opt);
481  };
482 
486  struct timestamp_type {
487  uint8_t reserved[6];
488  uint64_t timestamp;
489 
490  timestamp_type(uint64_t timestamp = 0)
491  : timestamp(timestamp) {
492  std::fill(reserved, reserved + sizeof(reserved), 0);
493  }
494 
495  static timestamp_type from_option(const option& opt);
496  };
497 
502  uint8_t limit, reserved1;
503  uint32_t reserved2;
504 
505  shortcut_limit_type(uint8_t limit = 0)
506  : limit(limit), reserved1(), reserved2() {
507 
508  }
509 
510  static shortcut_limit_type from_option(const option& opt);
511  };
512 
517  uint16_t reserved;
518  uint32_t interval;
519 
520  new_advert_interval_type(uint32_t interval = 0)
521  : reserved(), interval(interval) {
522 
523  }
524 
525  static new_advert_interval_type from_option(const option& opt);
526  };
527 
532  typedef std::vector<ipaddress_type> sources_type;
533  typedef std::vector<uint8_t> aux_data_type;
534 
535  multicast_address_record(uint8_t type = 0) : type(type) { }
536 
537  multicast_address_record(const uint8_t* buffer, uint32_t total_sz);
538  void serialize(uint8_t* buffer, uint32_t total_sz) const;
539  uint32_t size() const;
540 
541  uint8_t type;
542  ipaddress_type multicast_address;
543  sources_type sources;
544  aux_data_type aux_data;
545  };
546 
547  /*
548  * The type used to store all multicast address records in a packet
549  */
550  typedef std::vector<multicast_address_record> multicast_address_records_list;
551 
552  /*
553  * The type used to store all source address (from Multicast
554  * Listener Query messages) in a packet
555  */
556  typedef std::vector<ipaddress_type> sources_list;
557 
566  ICMPv6(Types tp = ECHO_REQUEST);
567 
579  ICMPv6(const uint8_t* buffer, uint32_t total_sz);
580 
581  // Getters
582 
587  Types type() const {
588  return static_cast<Types>(header_.type);
589  }
590 
595  uint8_t code() const {
596  return header_.code;
597  }
598 
603  uint16_t checksum() const {
604  return Endian::be_to_host(header_.cksum);
605  }
606 
611  uint16_t identifier() const {
612  return Endian::be_to_host(header_.u_echo.identifier);
613  }
614 
619  uint16_t sequence() const {
620  return Endian::be_to_host(header_.u_echo.sequence);
621  }
622 
627  small_uint<1> override() const {
628  return header_.u_nd_advt.override;
629  }
630 
636  return header_.u_nd_advt.solicited;
637  }
638 
644  return header_.u_nd_advt.router;
645  }
646 
651  uint8_t hop_limit() const {
652  return header_.u_nd_ra.hop_limit;
653  }
654 
659  uint16_t maximum_response_code() const {
660  return Endian::be_to_host(header_.u_echo.identifier);
661  }
662 
668  return header_.u_nd_ra.router_pref;
669  }
670 
676  return header_.u_nd_ra.home_agent;
677  }
678 
684  return header_.u_nd_ra.other;
685  }
686 
692  return header_.u_nd_ra.managed;
693  }
694 
699  uint16_t router_lifetime() const {
700  return Endian::be_to_host(header_.u_nd_ra.router_lifetime);
701  }
702 
707  uint32_t reachable_time() const {
708  return Endian::be_to_host(reach_time_);
709  }
710 
715  uint32_t retransmit_timer() const {
716  return Endian::be_to_host(retrans_timer_);
717  }
718 
723  const ipaddress_type& target_addr() const {
724  return target_address_;
725  }
726 
731  const ipaddress_type& dest_addr() const {
732  return dest_address_;
733  }
734 
742  const ipaddress_type& multicast_addr() const {
743  return multicast_address_;
744  }
745 
750  const options_type& options() const {
751  return options_;
752  }
753 
759  uint8_t length() const {
760  return header_.rfc4884.length;
761  }
762 
766  const multicast_address_records_list& multicast_address_records() const {
767  return multicast_records_;
768  }
769 
776  const sources_list& sources() const {
777  return sources_;
778  }
779 
787  return mlqm_.supress;
788  }
789 
796  small_uint<3> qrv() const {
797  return mlqm_.qrv;
798  }
799 
806  uint8_t qqic() const {
807  return mlqm_.qqic;
808  }
809 
810  // Setters
811 
816  void type(Types new_type);
817 
822  void code(uint8_t new_code);
823 
828  void checksum(uint16_t new_cksum);
829 
834  void identifier(uint16_t new_identifier);
835 
840  void sequence(uint16_t new_sequence);
841 
846  void override(small_uint<1> new_override);
847 
852  void solicited(small_uint<1> new_solicited);
853 
858  void router(small_uint<1> new_router);
859 
864  void hop_limit(uint8_t new_hop_limit);
865 
870  void maximum_response_code(uint16_t maximum_response_code);
871 
876  void router_pref(small_uint<2> new_router_pref);
877 
882  void home_agent(small_uint<1> new_home_agent);
883 
888  void other(small_uint<1> new_other);
889 
894  void managed(small_uint<1> new_managed);
895 
900  void router_lifetime(uint16_t new_router_lifetime);
901 
906  void target_addr(const ipaddress_type& new_target_addr);
907 
912  void dest_addr(const ipaddress_type& new_dest_addr);
913 
921  void multicast_addr(const ipaddress_type& new_multicast_addr);
922 
927  void reachable_time(uint32_t new_reachable_time);
928 
933  void retransmit_timer(uint32_t new_retrans_timer);
934 
940  void multicast_address_records(const multicast_address_records_list& records);
941 
947  void sources(const sources_list& new_sources);
948 
954  void supress(small_uint<1> value);
955 
961  void qrv(small_uint<3> value);
962 
968  void qqic(uint8_t value);
969 
975  PDUType pdu_type() const { return pdu_flag; }
976 
982  bool has_target_addr() const {
983  return type() == NEIGHBOUR_SOLICIT ||
984  type() == NEIGHBOUR_ADVERT ||
985  type() == REDIRECT;
986  }
987 
993  bool has_dest_addr() const {
994  return type() == REDIRECT;
995  }
996 
1005  void add_option(const option& option);
1006 
1007  #if TINS_IS_CXX11
1008 
1015  void add_option(option &&option) {
1016  internal_add_option(option);
1017  options_.push_back(std::move(option));
1018  }
1019  #endif
1020 
1030  bool remove_option(OptionTypes type);
1031 
1038  uint32_t header_size() const;
1039 
1047  uint32_t trailer_size() const;
1048 
1055  return extensions_;
1056  }
1057 
1064  return extensions_;
1065  }
1066 
1070  bool has_extensions() const {
1071  return !extensions_.extensions().empty();
1072  }
1073 
1089  void use_length_field(bool value);
1090 
1098  bool matches_response(const uint8_t* ptr, uint32_t total_sz) const;
1099 
1109  const option* search_option(OptionTypes type) const;
1110 
1114  ICMPv6* clone() const {
1115  return new ICMPv6(*this);
1116  }
1117 
1127  void use_mldv2(bool value);
1128 
1129  // ****************************************************************
1130  // Option setters
1131  // ****************************************************************
1132 
1138  void source_link_layer_addr(const hwaddress_type& addr);
1139 
1145  void target_link_layer_addr(const hwaddress_type& addr);
1146 
1152  void prefix_info(prefix_info_type info);
1153 
1159  void redirect_header(const byte_array& data);
1160 
1166  void mtu(const mtu_type& value);
1167 
1173  void shortcut_limit(const shortcut_limit_type& value);
1174 
1180  void new_advert_interval(const new_advert_interval_type& value);
1181 
1187  void new_home_agent_info(const new_ha_info_type& value);
1188 
1194  void source_addr_list(const addr_list_type& value);
1195 
1201  void target_addr_list(const addr_list_type& value);
1202 
1208  void rsa_signature(const rsa_sign_type& value);
1209 
1215  void timestamp(const timestamp_type& value);
1216 
1222  void nonce(const nonce_type& value);
1223 
1229  void ip_prefix(const ip_prefix_type& value);
1230 
1236  void link_layer_addr(lladdr_type value);
1237 
1243  void naack(const naack_type& value);
1244 
1250  void map(const map_type& value);
1251 
1257  void route_info(const route_info_type& value);
1258 
1264  void recursive_dns_servers(const recursive_dns_type& value);
1265 
1271  void handover_key_request(const handover_key_req_type& value);
1272 
1278  void handover_key_reply(const handover_key_reply_type& value);
1279 
1285  void handover_assist_info(const handover_assist_info_type& value);
1286 
1292  void mobile_node_identifier(const mobile_node_id_type& value);
1293 
1299  void dns_search_list(const dns_search_list_type& value);
1300 
1301  // ****************************************************************
1302  // Option getters
1303  // ****************************************************************
1304 
1311  hwaddress_type source_link_layer_addr() const;
1312 
1319  hwaddress_type target_link_layer_addr() const;
1320 
1327  prefix_info_type prefix_info() const;
1328 
1335  byte_array redirect_header() const;
1336 
1343  mtu_type mtu() const;
1344 
1351  shortcut_limit_type shortcut_limit() const;
1352 
1359  new_advert_interval_type new_advert_interval() const;
1360 
1367  new_ha_info_type new_home_agent_info() const;
1368 
1375  addr_list_type source_addr_list() const;
1376 
1383  addr_list_type target_addr_list() const;
1384 
1391  rsa_sign_type rsa_signature() const;
1392 
1399  timestamp_type timestamp() const;
1400 
1407  nonce_type nonce() const;
1408 
1415  ip_prefix_type ip_prefix() const;
1416 
1423  lladdr_type link_layer_addr() const;
1424 
1432  naack_type naack() const;
1433 
1440  map_type map() const;
1441 
1448  route_info_type route_info() const;
1449 
1456  recursive_dns_type recursive_dns_servers() const;
1457 
1464  handover_key_req_type handover_key_request() const;
1465 
1472  handover_key_reply_type handover_key_reply() const;
1473 
1480  handover_assist_info_type handover_assist_info() const;
1481 
1488  mobile_node_id_type mobile_node_identifier() const;
1489 
1496  dns_search_list_type dns_search_list() const;
1497 private:
1498  TINS_BEGIN_PACK
1499  struct icmp6_header {
1500  uint8_t type;
1501  uint8_t code;
1502  uint16_t cksum;
1503  union {
1504  struct {
1505  uint16_t identifier;
1506  uint16_t sequence;
1507  } u_echo;
1508 
1509  struct {
1510  #if TINS_IS_LITTLE_ENDIAN
1511  uint32_t reserved:5,
1512  override:1,
1513  solicited:1,
1514  router:1,
1515  reserved2:24;
1516  #else
1517  uint32_t router:1,
1518  solicited:1,
1519  override:1,
1520  reserved:29;
1521  #endif
1522  } u_nd_advt;
1523  struct {
1524  uint8_t hop_limit;
1525  #if TINS_IS_LITTLE_ENDIAN
1526  uint8_t reserved:3,
1527  router_pref:2,
1528  home_agent:1,
1529  other:1,
1530  managed:1;
1531  #else
1532  uint8_t managed:1,
1533  other:1,
1534  home_agent:1,
1535  router_pref:2,
1536  reserved:3;
1537  #endif
1538  uint16_t router_lifetime;
1539  } u_nd_ra;
1540  struct {
1541  uint8_t length;
1542  uint8_t unused[3];
1543  } rfc4884;
1544  // Multicast Listener Report Message (mld2)
1545  struct {
1546  uint16_t reserved;
1547  uint16_t record_count;
1548  } mlrm2;
1549  };
1550  } TINS_END_PACK;
1551 
1552  TINS_BEGIN_PACK
1553  struct multicast_listener_query_message_fields {
1554  uint8_t reserved:4,
1555  supress:1,
1556  qrv:3;
1557  uint8_t qqic;
1558  } TINS_END_PACK;
1559 
1560  void internal_add_option(const option& option);
1561  void write_serialization(uint8_t* buffer, uint32_t total_sz);
1562  bool has_options() const;
1563  void write_option(const option& opt, Memory::OutputMemoryStream& stream);
1564  void parse_options(Memory::InputMemoryStream& stream);
1565  void add_addr_list(uint8_t type, const addr_list_type& value);
1566  addr_list_type search_addr_list(OptionTypes type) const;
1567  options_type::const_iterator search_option_iterator(OptionTypes type) const;
1568  options_type::iterator search_option_iterator(OptionTypes type);
1569  void try_parse_extensions(Memory::InputMemoryStream& stream);
1570  bool are_extensions_allowed() const;
1571  uint32_t get_adjusted_inner_pdu_size() const;
1572  uint8_t get_option_padding(uint32_t data_size);
1573 
1574  template <template <typename> class Functor>
1575  const option* safe_search_option(OptionTypes opt, uint32_t size) const {
1576  const option* option = search_option(opt);
1577  if (!option || Functor<uint32_t>()(option->data_size(), size)) {
1578  throw option_not_found();
1579  }
1580  return option;
1581  }
1582 
1583  template <typename T>
1584  T search_and_convert(OptionTypes type) const {
1585  const option* opt = search_option(type);
1586  if (!opt) {
1587  throw option_not_found();
1588  }
1589  return opt->to<T>();
1590  }
1591 
1592  icmp6_header header_;
1593  ipaddress_type target_address_;
1594  ipaddress_type dest_address_;
1595  ipaddress_type multicast_address_;
1596  options_type options_;
1597  uint32_t options_size_;
1598  uint32_t reach_time_, retrans_timer_;
1599  multicast_address_records_list multicast_records_;
1600  multicast_listener_query_message_fields mlqm_;
1601  sources_list sources_;
1602  ICMPExtensionsStructure extensions_;
1603  bool use_mldv2_;
1604 };
1605 
1606 } // Tins
1607 
1608 #endif // TINS_ICMPV6_H
Definition: icmpv6.h:486
rsa_sign_type(RAIterator hash, const signature_type &sign)
Constructs a rsa_sign_type object.
Definition: icmpv6.h:315
uint16_t identifier() const
Getter for the identifier field.
Definition: icmpv6.h:611
PDUType pdu_type() const
Getter for the PDU&#39;s type.
Definition: icmpv6.h:975
const sources_list & sources() const
Getter for the multicast address records field.
Definition: icmpv6.h:776
rsa_sign_type()
Default constructs a rsa_sign_type.
Definition: icmpv6.h:325
uint32_t reachable_time() const
Getter for the reachable_time field.
Definition: icmpv6.h:707
Definition: icmpv6.h:272
OptionTypes
Definition: icmpv6.h:101
std::vector< uint8_t > byte_array
Definition: pdu.h:45
PDUType
Enum which identifies each type of PDU.
Definition: pdu.h:127
std::vector< uint16_t > new_ha_info_type
The type used to store the new home agent information option data.
Definition: icmpv6.h:163
Definition: icmpv6.h:392
Definition: icmpv6.h:408
uint32_t retransmit_timer() const
Getter for the retransmit_timer field.
Definition: icmpv6.h:715
small_uint< 2 > router_pref() const
Getter for the router_pref field.
Definition: icmpv6.h:667
Definition: icmpv6.h:501
bool has_target_addr() const
Checks whether this ICMPv6 object has a target_addr field.
Definition: icmpv6.h:982
Types type() const
Getter for the type field.
Definition: icmpv6.h:587
bool has_dest_addr() const
Checks whether this ICMPv6 object has a target_addr field.
Definition: icmpv6.h:993
Definition: icmpv6.h:249
const ipaddress_type & target_addr() const
Getter for the target address field.
Definition: icmpv6.h:723
Represents a PDU option field.
Definition: pdu_option.h:201
small_uint< 1 > managed() const
Getter for the managed field.
Definition: icmpv6.h:691
Definition: icmpv6.h:454
std::pair< uint16_t, uint32_t > mtu_type
Definition: icmpv6.h:190
Types
Definition: icmpv6.h:67
std::vector< uint8_t > nonce_type
Definition: icmpv6.h:185
uint16_t checksum() const
Getter for the cksum field.
Definition: icmpv6.h:603
Definition: icmpv6.h:470
Definition: icmpv6.h:335
std::vector< option > options_type
Definition: icmpv6.h:157
Represents an ICMPv6 PDU.
Definition: icmpv6.h:57
small_uint< 1 > supress() const
Getter for the Suppress Router-Side Processing field.
Definition: icmpv6.h:786
const multicast_address_records_list & multicast_address_records() const
Getter for the multicast address records field.
Definition: icmpv6.h:766
The type used to store the neighbour advertisement acknowledgement option data.
Definition: icmpv6.h:196
uint16_t sequence() const
Getter for the sequence field.
Definition: icmpv6.h:619
const ipaddress_type & multicast_addr() const
Getter for the multicast address field.
Definition: icmpv6.h:742
rsa_sign_type(RAIterator hash, ForwardIterator start, ForwardIterator end)
Constructs a rsa_sign_type object.
Definition: icmpv6.h:297
The Tins namespace.
Definition: address_range.h:38
T to() const
Constructs a T from this PDUOption.
Definition: pdu_option.h:389
uint16_t router_lifetime() const
Getter for the router_lifetime field.
Definition: icmpv6.h:699
small_uint< 3 > qrv() const
Getter for the Querier&#39;s Robustnes Variable field.
Definition: icmpv6.h:796
void add_option(option &&option)
Adds an ICMPv6 option.
Definition: icmpv6.h:1015
ICMPExtensionsStructure & extensions()
Getter for the extensions field.
Definition: icmpv6.h:1063
uint8_t length() const
Getter for the length field.
Definition: icmpv6.h:759
small_uint< 1 > other() const
Getter for the other field.
Definition: icmpv6.h:683
HWAddress< 6 > hwaddress_type
Definition: icmpv6.h:147
Definition: icmpv6.h:168
lladdr_type(uint8_t option_code=0, const address_type &address=address_type())
Definition: icmpv6.h:223
const options_type & options() const
Getter for the ICMPv6 options.
Definition: icmpv6.h:750
small_uint< 1 > router() const
Getter for the router field.
Definition: icmpv6.h:643
const ipaddress_type & dest_addr() const
Getter for the destination address field.
Definition: icmpv6.h:731
Definition: ipv6_address.h:45
const ICMPExtensionsStructure & extensions() const
Getter for the extensions field.
Definition: icmpv6.h:1054
PDUOption< uint8_t, ICMPv6 > option
Definition: icmpv6.h:152
Class that represents an ICMP extensions structure.
Definition: icmp_extension.h:161
Definition: icmpv6.h:351
IPv6Address ipaddress_type
Definition: icmpv6.h:142
size_t data_size() const
Retrieves the length of this option&#39;s data.
Definition: pdu_option.h:361
bool has_extensions() const
Indicates whether this object contains ICMP extensions.
Definition: icmpv6.h:1070
The type used to store the link layer address option data.
Definition: icmpv6.h:211
Definition: icmpv6.h:371
small_uint< 1 > home_agent() const
Getter for the home_agent field.
Definition: icmpv6.h:675
Base class for protocol data units.
Definition: pdu.h:107
uint16_t maximum_response_code() const
Getter for the maximum response code field.
Definition: icmpv6.h:659
Exception thrown when an option is not found.
Definition: exceptions.h:56
uint8_t hop_limit() const
Getter for the hop limit field.
Definition: icmpv6.h:651
small_uint< 1 > solicited() const
Getter for the solicited field.
Definition: icmpv6.h:635
lladdr_type(uint8_t option_code, const hwaddress_type &address)
Constructor taking an option code and hwaddress_type.
Definition: icmpv6.h:238
ICMPv6 * clone() const
Definition: icmpv6.h:1114
uint8_t qqic() const
Getter for the Querier&#39;s Query Interval Code field.
Definition: icmpv6.h:806
uint8_t code() const
Getter for the code field.
Definition: icmpv6.h:595