libtins  4.5
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 <algorithm>
34 #include <vector>
35 #include <tins/macros.h>
36 #include <tins/pdu.h>
37 #include <tins/ipv6_address.h>
38 #include <tins/pdu_option.h>
39 #include <tins/endianness.h>
40 #include <tins/small_uint.h>
41 #include <tins/hw_address.h>
42 #include <tins/small_uint.h>
43 #include <tins/icmp_extension.h>
44 #include <tins/cxxstd.h>
45 
46 namespace Tins {
47 namespace Memory {
48 
49 class InputMemoryStream;
50 class OutputMemoryStream;
51 
52 } // memory
53 
58 class TINS_API ICMPv6 : public PDU {
59 public:
63  static const PDU::PDUType pdu_flag = PDU::ICMPv6;
64 
68  enum Types {
69  DEST_UNREACHABLE = 1,
70  PACKET_TOOBIG = 2,
71  TIME_EXCEEDED = 3,
72  PARAM_PROBLEM = 4,
73  ECHO_REQUEST = 128,
74  ECHO_REPLY = 129,
75  MGM_QUERY = 130,
76  MGM_REPORT = 131,
77  MGM_REDUCTION = 132,
78  ROUTER_SOLICIT = 133,
79  ROUTER_ADVERT = 134,
80  NEIGHBOUR_SOLICIT = 135,
81  NEIGHBOUR_ADVERT = 136,
82  REDIRECT = 137,
83  ROUTER_RENUMBER = 138,
84  NI_QUERY = 139,
85  NI_REPLY = 140,
86  MLD2_REPORT = 143,
87  DHAAD_REQUEST = 144,
88  DHAAD_REPLY = 145,
89  MOBILE_PREFIX_SOLICIT = 146,
90  MOBILE_PREFIX_ADVERT = 147,
91  CERT_PATH_SOLICIT = 148,
92  CERT_PATH_ADVERT = 149,
93  MULTICAST_ROUTER_ADVERT = 151,
94  MULTICAST_ROUTER_SOLICIT = 152,
95  MULTICAST_ROUTER_TERMINATE = 153,
96  RPL_CONTROL_MSG = 155,
97  EXTENDED_ECHO_REQUEST = 160,
98  EXTENDED_ECHO_REPLY = 161
99  };
100 
104  enum OptionTypes {
105  SOURCE_ADDRESS = 1,
106  TARGET_ADDRESS,
107  PREFIX_INFO,
108  REDIRECT_HEADER,
109  MTU,
110  NBMA_SHORT_LIMIT,
111  ADVERT_INTERVAL,
112  HOME_AGENT_INFO,
113  S_ADDRESS_LIST,
114  T_ADDRESS_LIST,
115  CGA,
116  RSA_SIGN,
117  TIMESTAMP,
118  NONCE,
119  TRUST_ANCHOR,
120  CERTIFICATE,
121  IP_PREFIX,
122  NEW_ROUTER_PREFIX,
123  LINK_ADDRESS,
124  NAACK,
125  MAP = 23,
126  ROUTE_INFO,
127  RECURSIVE_DNS_SERV,
128  RA_FLAGS_EXT,
129  HANDOVER_KEY_REQ,
130  HANDOVER_KEY_REPLY,
131  HANDOVER_ASSIST_INFO,
132  MOBILE_NODE_ID,
133  DNS_SEARCH_LIST,
134  PROXY_SIGNATURE,
135  ADDRESS_REG,
136  SIXLOWPAN_CONTEXT,
137  AUTHORITATIVE_BORDER_ROUTER,
138  CARD_REQUEST = 138,
139  CARD_REPLY
140  };
141 
146 
151 
156 
160  typedef std::vector<option> options_type;
161 
166  typedef std::vector<uint16_t> new_ha_info_type;
167 
171  struct addr_list_type {
172  typedef std::vector<ipaddress_type> addresses_type;
173 
174  uint8_t reserved[6];
175  addresses_type addresses;
176 
177  addr_list_type(const addresses_type& addresses = addresses_type())
178  : addresses(addresses) {
179  std::fill(reserved, reserved + sizeof(reserved), static_cast<uint8_t>(0));
180  }
181 
182  static addr_list_type from_option(const option& opt);
183  };
184 
188  typedef std::vector<uint8_t> nonce_type;
189 
193  typedef std::pair<uint16_t, uint32_t> mtu_type;
194 
199  struct naack_type {
200  uint8_t code, status;
201  uint8_t reserved[4];
202 
203  naack_type(uint8_t code = 0, uint8_t status = 0)
204  : code(code), status(status) {
205  std::fill(reserved, reserved + 4, static_cast<uint8_t>(0));
206  }
207 
208  static naack_type from_option(const option& opt);
209  };
210 
214  struct lladdr_type {
215  typedef std::vector<uint8_t> address_type;
216 
217  uint8_t option_code;
218  address_type address;
219 
226  lladdr_type(uint8_t option_code = 0,
227  const address_type& address = address_type())
228  : option_code(option_code), address(address) {
229 
230  }
231 
241  lladdr_type(uint8_t option_code, const hwaddress_type& address)
242  : option_code(option_code), address(address.begin(), address.end()) {
243 
244  }
245 
246  static lladdr_type from_option(const option& opt);
247  };
248 
253  uint8_t prefix_len;
254  small_uint<1> A, L;
255  uint32_t valid_lifetime,
256  preferred_lifetime,
257  reserved2;
258  ipaddress_type prefix;
259 
260  prefix_info_type(uint8_t prefix_len = 0,
261  small_uint<1> A = 0,
262  small_uint<1> L = 0,
263  uint32_t valid_lifetime = 0,
264  uint32_t preferred_lifetime = 0,
265  const ipaddress_type& prefix = ipaddress_type())
266  : prefix_len(prefix_len), A(A), L(L), valid_lifetime(valid_lifetime),
267  preferred_lifetime(preferred_lifetime), reserved2(0), prefix(prefix) { }
268 
269  static prefix_info_type from_option(const option& opt);
270  };
271 
275  struct rsa_sign_type {
276  typedef std::vector<uint8_t> signature_type;
277 
278  uint8_t key_hash[16];
279  signature_type signature;
280 
299  template <typename RAIterator, typename ForwardIterator>
300  rsa_sign_type(RAIterator hash, ForwardIterator start, ForwardIterator end)
301  : signature(start, end) {
302  std::copy(hash, hash + sizeof(key_hash), key_hash);
303  }
304 
317  template <typename RAIterator>
318  rsa_sign_type(RAIterator hash, const signature_type& sign)
319  : signature(sign) {
320  std::copy(hash, hash + sizeof(key_hash), key_hash);
321  }
322 
329  std::fill(key_hash, key_hash + sizeof(key_hash), static_cast<uint8_t>(0));
330  }
331 
332  static rsa_sign_type from_option(const option& opt);
333  };
334 
338  struct ip_prefix_type {
339  uint8_t option_code, prefix_len;
340  ipaddress_type address;
341 
342  ip_prefix_type(uint8_t option_code = 0,
343  uint8_t prefix_len = 0,
344  const ipaddress_type& address = ipaddress_type())
345  : option_code(option_code), prefix_len(prefix_len), address(address)
346  {}
347 
348  static ip_prefix_type from_option(const option& opt);
349  };
350 
354  struct map_type {
355  small_uint<4> dist, pref;
356  small_uint<1> r;
357  uint32_t valid_lifetime;
358  ipaddress_type address;
359 
360  map_type(small_uint<4> dist = 0,
361  small_uint<4> pref = 0,
362  small_uint<1> r = 0,
363  uint32_t valid_lifetime = 0,
364  const ipaddress_type& address = ipaddress_type())
365  : dist(dist), pref(pref), r(r), valid_lifetime(valid_lifetime),
366  address(address) { }
367 
368  static map_type from_option(const option& opt);
369  };
370 
375  typedef std::vector<uint8_t> prefix_type;
376 
377  uint8_t prefix_len;
378  small_uint<2> pref;
379  uint32_t route_lifetime;
380  prefix_type prefix;
381 
382  route_info_type(uint8_t prefix_len = 0,
383  small_uint<2> pref = 0,
384  uint32_t route_lifetime = 0,
385  const prefix_type& prefix = prefix_type())
386  : prefix_len(prefix_len), pref(pref), route_lifetime(route_lifetime),
387  prefix(prefix) { }
388 
389  static route_info_type from_option(const option& opt);
390  };
391 
396  typedef std::vector<ipaddress_type> servers_type;
397 
398  uint32_t lifetime;
399  servers_type servers;
400 
401  recursive_dns_type(uint32_t lifetime = 0,
402  const servers_type& servers = servers_type())
403  : lifetime(lifetime), servers(servers) {}
404 
405  static recursive_dns_type from_option(const option& opt);
406  };
407 
412  typedef std::vector<uint8_t> key_type;
413 
414  small_uint<4> AT;
415  key_type key;
416 
418  const key_type& key = key_type())
419  : AT(AT), key(key) { }
420 
421  static handover_key_req_type from_option(const option& opt);
422  };
423 
428  uint16_t lifetime;
429 
430  handover_key_reply_type(uint16_t lifetime = 0,
431  small_uint<4> AT = 0,
432  const key_type& key = key_type())
433  : handover_key_req_type(AT, key), lifetime(lifetime) { }
434 
435  static handover_key_reply_type from_option(const option& opt);
436  };
437 
442  typedef std::vector<uint8_t> hai_type;
443 
444  uint8_t option_code;
445  hai_type hai;
446 
447  handover_assist_info_type(uint8_t option_code=0,
448  const hai_type& hai = hai_type())
449  : option_code(option_code), hai(hai) { }
450 
451  static handover_assist_info_type from_option(const option& opt);
452  };
453 
458  typedef std::vector<uint8_t> mn_type;
459 
460  uint8_t option_code;
461  mn_type mn;
462 
463  mobile_node_id_type(uint8_t option_code=0,
464  const mn_type& mn = mn_type())
465  : option_code(option_code), mn(mn) { }
466 
467  static mobile_node_id_type from_option(const option& opt);
468  };
469 
474  typedef std::vector<std::string> domains_type;
475 
476  uint32_t lifetime;
477  domains_type domains;
478 
479  dns_search_list_type(uint32_t lifetime = 0,
480  const domains_type& domains = domains_type())
481  : lifetime(lifetime), domains(domains) { }
482 
483  static dns_search_list_type from_option(const option& opt);
484  };
485 
489  struct timestamp_type {
490  uint8_t reserved[6];
491  uint64_t timestamp;
492 
493  timestamp_type(uint64_t timestamp = 0)
494  : timestamp(timestamp) {
495  std::fill(reserved, reserved + sizeof(reserved), static_cast<uint8_t>(0));
496  }
497 
498  static timestamp_type from_option(const option& opt);
499  };
500 
505  uint8_t limit, reserved1;
506  uint32_t reserved2;
507 
508  shortcut_limit_type(uint8_t limit = 0)
509  : limit(limit), reserved1(), reserved2() {
510 
511  }
512 
513  static shortcut_limit_type from_option(const option& opt);
514  };
515 
520  uint16_t reserved;
521  uint32_t interval;
522 
523  new_advert_interval_type(uint32_t interval = 0)
524  : reserved(), interval(interval) {
525 
526  }
527 
528  static new_advert_interval_type from_option(const option& opt);
529  };
530 
535  typedef std::vector<ipaddress_type> sources_type;
536  typedef std::vector<uint8_t> aux_data_type;
537 
538  multicast_address_record(uint8_t type = 0) : type(type) { }
539 
540  multicast_address_record(const uint8_t* buffer, uint32_t total_sz);
541  void serialize(uint8_t* buffer, uint32_t total_sz) const;
542  uint32_t size() const;
543 
544  uint8_t type;
545  ipaddress_type multicast_address;
546  sources_type sources;
547  aux_data_type aux_data;
548  };
549 
550  /*
551  * The type used to store all multicast address records in a packet
552  */
553  typedef std::vector<multicast_address_record> multicast_address_records_list;
554 
555  /*
556  * The type used to store all source address (from Multicast
557  * Listener Query messages) in a packet
558  */
559  typedef std::vector<ipaddress_type> sources_list;
560 
569  ICMPv6(Types tp = ECHO_REQUEST);
570 
582  ICMPv6(const uint8_t* buffer, uint32_t total_sz);
583 
584  // Getters
585 
590  Types type() const {
591  return static_cast<Types>(header_.type);
592  }
593 
598  uint8_t code() const {
599  return header_.code;
600  }
601 
606  uint16_t checksum() const {
607  return Endian::be_to_host(header_.cksum);
608  }
609 
614  uint16_t identifier() const {
615  return Endian::be_to_host(header_.u_echo.identifier);
616  }
617 
622  uint16_t sequence() const {
623  return Endian::be_to_host(header_.u_echo.sequence);
624  }
625 
630  small_uint<1> override() const {
631  return header_.u_nd_advt.override;
632  }
633 
639  return header_.u_nd_advt.solicited;
640  }
641 
647  return header_.u_nd_advt.router;
648  }
649 
654  uint8_t hop_limit() const {
655  return header_.u_nd_ra.hop_limit;
656  }
657 
662  uint16_t maximum_response_code() const {
663  return Endian::be_to_host(header_.u_echo.identifier);
664  }
665 
671  return header_.u_nd_ra.router_pref;
672  }
673 
679  return header_.u_nd_ra.home_agent;
680  }
681 
687  return header_.u_nd_ra.other;
688  }
689 
695  return header_.u_nd_ra.managed;
696  }
697 
702  uint16_t router_lifetime() const {
703  return Endian::be_to_host(header_.u_nd_ra.router_lifetime);
704  }
705 
710  uint32_t reachable_time() const {
711  return Endian::be_to_host(reach_time_);
712  }
713 
718  uint32_t retransmit_timer() const {
719  return Endian::be_to_host(retrans_timer_);
720  }
721 
726  const ipaddress_type& target_addr() const {
727  return target_address_;
728  }
729 
734  const ipaddress_type& dest_addr() const {
735  return dest_address_;
736  }
737 
746  return multicast_address_;
747  }
748 
753  const options_type& options() const {
754  return options_;
755  }
756 
762  uint8_t length() const {
763  return header_.rfc4884.length;
764  }
765 
769  const multicast_address_records_list& multicast_address_records() const {
770  return multicast_records_;
771  }
772 
779  const sources_list& sources() const {
780  return sources_;
781  }
782 
790  return mlqm_.supress;
791  }
792 
799  small_uint<3> qrv() const {
800  return mlqm_.qrv;
801  }
802 
809  uint8_t qqic() const {
810  return mlqm_.qqic;
811  }
812 
813  // Setters
814 
819  void type(Types new_type);
820 
825  void code(uint8_t new_code);
826 
831  void checksum(uint16_t new_cksum);
832 
837  void identifier(uint16_t new_identifier);
838 
843  void sequence(uint16_t new_sequence);
844 
849  void override(small_uint<1> new_override);
850 
855  void solicited(small_uint<1> new_solicited);
856 
861  void router(small_uint<1> new_router);
862 
867  void hop_limit(uint8_t new_hop_limit);
868 
873  void maximum_response_code(uint16_t maximum_response_code);
874 
879  void router_pref(small_uint<2> new_router_pref);
880 
885  void home_agent(small_uint<1> new_home_agent);
886 
891  void other(small_uint<1> new_other);
892 
897  void managed(small_uint<1> new_managed);
898 
903  void router_lifetime(uint16_t new_router_lifetime);
904 
909  void target_addr(const ipaddress_type& new_target_addr);
910 
915  void dest_addr(const ipaddress_type& new_dest_addr);
916 
924  void multicast_addr(const ipaddress_type& new_multicast_addr);
925 
930  void reachable_time(uint32_t new_reachable_time);
931 
936  void retransmit_timer(uint32_t new_retrans_timer);
937 
943  void multicast_address_records(const multicast_address_records_list& records);
944 
950  void sources(const sources_list& new_sources);
951 
957  void supress(small_uint<1> value);
958 
964  void qrv(small_uint<3> value);
965 
971  void qqic(uint8_t value);
972 
978  PDUType pdu_type() const { return pdu_flag; }
979 
985  bool has_target_addr() const {
986  return type() == NEIGHBOUR_SOLICIT ||
987  type() == NEIGHBOUR_ADVERT ||
988  type() == REDIRECT;
989  }
990 
996  bool has_dest_addr() const {
997  return type() == REDIRECT;
998  }
999 
1008  void add_option(const option& option);
1009 
1010  #if TINS_IS_CXX11
1019  internal_add_option(option);
1020  options_.push_back(std::move(option));
1021  }
1022  #endif
1023 
1033  bool remove_option(OptionTypes type);
1034 
1041  uint32_t header_size() const;
1042 
1050  uint32_t trailer_size() const;
1051 
1058  return extensions_;
1059  }
1060 
1067  return extensions_;
1068  }
1069 
1073  bool has_extensions() const {
1074  return !extensions_.extensions().empty();
1075  }
1076 
1092  void use_length_field(bool value);
1093 
1101  bool matches_response(const uint8_t* ptr, uint32_t total_sz) const;
1102 
1112  const option* search_option(OptionTypes type) const;
1113 
1117  ICMPv6* clone() const {
1118  return new ICMPv6(*this);
1119  }
1120 
1130  void use_mldv2(bool value);
1131 
1132  // ****************************************************************
1133  // Option setters
1134  // ****************************************************************
1135 
1141  void source_link_layer_addr(const hwaddress_type& addr);
1142 
1148  void target_link_layer_addr(const hwaddress_type& addr);
1149 
1155  void prefix_info(prefix_info_type info);
1156 
1162  void redirect_header(const byte_array& data);
1163 
1169  void mtu(const mtu_type& value);
1170 
1176  void shortcut_limit(const shortcut_limit_type& value);
1177 
1183  void new_advert_interval(const new_advert_interval_type& value);
1184 
1190  void new_home_agent_info(const new_ha_info_type& value);
1191 
1197  void source_addr_list(const addr_list_type& value);
1198 
1204  void target_addr_list(const addr_list_type& value);
1205 
1211  void rsa_signature(const rsa_sign_type& value);
1212 
1218  void timestamp(const timestamp_type& value);
1219 
1225  void nonce(const nonce_type& value);
1226 
1232  void ip_prefix(const ip_prefix_type& value);
1233 
1239  void link_layer_addr(lladdr_type value);
1240 
1246  void naack(const naack_type& value);
1247 
1253  void map(const map_type& value);
1254 
1260  void route_info(const route_info_type& value);
1261 
1267  void recursive_dns_servers(const recursive_dns_type& value);
1268 
1274  void handover_key_request(const handover_key_req_type& value);
1275 
1281  void handover_key_reply(const handover_key_reply_type& value);
1282 
1288  void handover_assist_info(const handover_assist_info_type& value);
1289 
1295  void mobile_node_identifier(const mobile_node_id_type& value);
1296 
1302  void dns_search_list(const dns_search_list_type& value);
1303 
1304  // ****************************************************************
1305  // Option getters
1306  // ****************************************************************
1307 
1314  hwaddress_type source_link_layer_addr() const;
1315 
1322  hwaddress_type target_link_layer_addr() const;
1323 
1330  prefix_info_type prefix_info() const;
1331 
1338  byte_array redirect_header() const;
1339 
1346  mtu_type mtu() const;
1347 
1354  shortcut_limit_type shortcut_limit() const;
1355 
1362  new_advert_interval_type new_advert_interval() const;
1363 
1370  new_ha_info_type new_home_agent_info() const;
1371 
1378  addr_list_type source_addr_list() const;
1379 
1386  addr_list_type target_addr_list() const;
1387 
1394  rsa_sign_type rsa_signature() const;
1395 
1402  timestamp_type timestamp() const;
1403 
1410  nonce_type nonce() const;
1411 
1418  ip_prefix_type ip_prefix() const;
1419 
1426  lladdr_type link_layer_addr() const;
1427 
1435  naack_type naack() const;
1436 
1443  map_type map() const;
1444 
1451  route_info_type route_info() const;
1452 
1459  recursive_dns_type recursive_dns_servers() const;
1460 
1467  handover_key_req_type handover_key_request() const;
1468 
1475  handover_key_reply_type handover_key_reply() const;
1476 
1483  handover_assist_info_type handover_assist_info() const;
1484 
1491  mobile_node_id_type mobile_node_identifier() const;
1492 
1499  dns_search_list_type dns_search_list() const;
1500 private:
1501  TINS_BEGIN_PACK
1502  struct icmp6_header {
1503  uint8_t type;
1504  uint8_t code;
1505  uint16_t cksum;
1506  union {
1507  struct {
1508  uint16_t identifier;
1509  uint16_t sequence;
1510  } u_echo;
1511 
1512  struct {
1513  #if TINS_IS_LITTLE_ENDIAN
1514  uint32_t reserved:5,
1515  override:1,
1516  solicited:1,
1517  router:1,
1518  reserved2:24;
1519  #else
1520  uint32_t router:1,
1521  solicited:1,
1522  override:1,
1523  reserved:29;
1524  #endif
1525  } u_nd_advt;
1526  struct {
1527  uint8_t hop_limit;
1528  #if TINS_IS_LITTLE_ENDIAN
1529  uint8_t reserved:3,
1530  router_pref:2,
1531  home_agent:1,
1532  other:1,
1533  managed:1;
1534  #else
1535  uint8_t managed:1,
1536  other:1,
1537  home_agent:1,
1538  router_pref:2,
1539  reserved:3;
1540  #endif
1541  uint16_t router_lifetime;
1542  } u_nd_ra;
1543  struct {
1544  uint8_t length;
1545  uint8_t unused[3];
1546  } rfc4884;
1547  // Multicast Listener Report Message (mld2)
1548  struct {
1549  uint16_t reserved;
1550  uint16_t record_count;
1551  } mlrm2;
1552  };
1553  } TINS_END_PACK;
1554 
1555  TINS_BEGIN_PACK
1556  struct multicast_listener_query_message_fields {
1557  uint8_t reserved:4,
1558  supress:1,
1559  qrv:3;
1560  uint8_t qqic;
1561  } TINS_END_PACK;
1562 
1563  void internal_add_option(const option& option);
1564  void write_serialization(uint8_t* buffer, uint32_t total_sz);
1565  bool has_options() const;
1566  void write_option(const option& opt, Memory::OutputMemoryStream& stream);
1567  void parse_options(Memory::InputMemoryStream& stream);
1568  void add_addr_list(uint8_t type, const addr_list_type& value);
1569  addr_list_type search_addr_list(OptionTypes type) const;
1570  options_type::const_iterator search_option_iterator(OptionTypes type) const;
1571  options_type::iterator search_option_iterator(OptionTypes type);
1572  void try_parse_extensions(Memory::InputMemoryStream& stream);
1573  bool are_extensions_allowed() const;
1574  uint32_t get_adjusted_inner_pdu_size() const;
1575  uint8_t get_option_padding(uint32_t data_size);
1576 
1577  template <template <typename> class Functor>
1578  const option* safe_search_option(OptionTypes opt, uint32_t size) const {
1579  const option* option = search_option(opt);
1580  if (!option || Functor<uint32_t>()(option->data_size(), size)) {
1581  throw option_not_found();
1582  }
1583  return option;
1584  }
1585 
1586  template <typename T>
1587  T search_and_convert(OptionTypes type) const {
1588  const option* opt = search_option(type);
1589  if (!opt) {
1590  throw option_not_found();
1591  }
1592  return opt->to<T>();
1593  }
1594 
1595  icmp6_header header_;
1596  ipaddress_type target_address_;
1597  ipaddress_type dest_address_;
1598  ipaddress_type multicast_address_;
1599  options_type options_;
1600  uint32_t options_size_;
1601  uint32_t reach_time_, retrans_timer_;
1602  multicast_address_records_list multicast_records_;
1603  multicast_listener_query_message_fields mlqm_;
1604  sources_list sources_;
1605  ICMPExtensionsStructure extensions_;
1606  bool use_mldv2_;
1607 };
1608 
1609 } // Tins
1610 
1611 #endif // TINS_ICMPV6_H
Class that represents an ICMP extensions structure.
Definition: icmp_extension.h:161
Represents an ICMPv6 PDU.
Definition: icmpv6.h:58
const ipaddress_type & dest_addr() const
Getter for the destination address field.
Definition: icmpv6.h:734
void add_option(option &&option)
Adds an ICMPv6 option.
Definition: icmpv6.h:1018
small_uint< 1 > solicited() const
Getter for the solicited field.
Definition: icmpv6.h:638
IPv6Address ipaddress_type
Definition: icmpv6.h:145
PDUOption< uint8_t, ICMPv6 > option
Definition: icmpv6.h:155
small_uint< 1 > home_agent() const
Getter for the home_agent field.
Definition: icmpv6.h:678
Types type() const
Getter for the type field.
Definition: icmpv6.h:590
HWAddress< 6 > hwaddress_type
Definition: icmpv6.h:150
small_uint< 2 > router_pref() const
Getter for the router_pref field.
Definition: icmpv6.h:670
small_uint< 1 > managed() const
Getter for the managed field.
Definition: icmpv6.h:694
uint8_t hop_limit() const
Getter for the hop limit field.
Definition: icmpv6.h:654
uint32_t reachable_time() const
Getter for the reachable_time field.
Definition: icmpv6.h:710
std::vector< uint16_t > new_ha_info_type
The type used to store the new home agent information option data.
Definition: icmpv6.h:166
small_uint< 1 > router() const
Getter for the router field.
Definition: icmpv6.h:646
Types
Definition: icmpv6.h:68
uint8_t qqic() const
Getter for the Querier's Query Interval Code field.
Definition: icmpv6.h:809
const ICMPExtensionsStructure & extensions() const
Getter for the extensions field.
Definition: icmpv6.h:1057
PDUType pdu_type() const
Getter for the PDU's type.
Definition: icmpv6.h:978
uint32_t retransmit_timer() const
Getter for the retransmit_timer field.
Definition: icmpv6.h:718
uint16_t router_lifetime() const
Getter for the router_lifetime field.
Definition: icmpv6.h:702
ICMPv6 * clone() const
Definition: icmpv6.h:1117
bool has_extensions() const
Indicates whether this object contains ICMP extensions.
Definition: icmpv6.h:1073
std::vector< option > options_type
Definition: icmpv6.h:160
bool has_target_addr() const
Checks whether this ICMPv6 object has a target_addr field.
Definition: icmpv6.h:985
small_uint< 1 > supress() const
Getter for the Suppress Router-Side Processing field.
Definition: icmpv6.h:789
uint16_t checksum() const
Getter for the cksum field.
Definition: icmpv6.h:606
uint16_t identifier() const
Getter for the identifier field.
Definition: icmpv6.h:614
uint8_t length() const
Getter for the length field.
Definition: icmpv6.h:762
uint16_t sequence() const
Getter for the sequence field.
Definition: icmpv6.h:622
small_uint< 3 > qrv() const
Getter for the Querier's Robustnes Variable field.
Definition: icmpv6.h:799
const multicast_address_records_list & multicast_address_records() const
Getter for the multicast address records field.
Definition: icmpv6.h:769
OptionTypes
Definition: icmpv6.h:104
const ipaddress_type & multicast_addr() const
Getter for the multicast address field.
Definition: icmpv6.h:745
std::pair< uint16_t, uint32_t > mtu_type
Definition: icmpv6.h:193
ICMPExtensionsStructure & extensions()
Getter for the extensions field.
Definition: icmpv6.h:1066
const options_type & options() const
Getter for the ICMPv6 options.
Definition: icmpv6.h:753
small_uint< 1 > other() const
Getter for the other field.
Definition: icmpv6.h:686
const ipaddress_type & target_addr() const
Getter for the target address field.
Definition: icmpv6.h:726
uint16_t maximum_response_code() const
Getter for the maximum response code field.
Definition: icmpv6.h:662
std::vector< uint8_t > nonce_type
Definition: icmpv6.h:188
const sources_list & sources() const
Getter for the multicast address records field.
Definition: icmpv6.h:779
uint8_t code() const
Getter for the code field.
Definition: icmpv6.h:598
bool has_dest_addr() const
Checks whether this ICMPv6 object has a target_addr field.
Definition: icmpv6.h:996
Definition: ipv6_address.h:45
Represents a PDU option field.
Definition: pdu_option.h:201
Base class for protocol data units.
Definition: pdu.h:107
PDUType
Enum which identifies each type of PDU.
Definition: pdu.h:127
The Tins namespace.
Definition: address_range.h:38
std::vector< uint8_t > byte_array
Definition: pdu.h:45
Definition: icmpv6.h:171
Definition: icmpv6.h:473
Definition: icmpv6.h:411
Definition: icmpv6.h:338
The type used to store the link layer address option data.
Definition: icmpv6.h:214
lladdr_type(uint8_t option_code, const hwaddress_type &address)
Constructor taking an option code and hwaddress_type.
Definition: icmpv6.h:241
lladdr_type(uint8_t option_code=0, const address_type &address=address_type())
Definition: icmpv6.h:226
Definition: icmpv6.h:354
Definition: icmpv6.h:457
The type used to store the neighbour advertisement acknowledgement option data.
Definition: icmpv6.h:199
Definition: icmpv6.h:252
Definition: icmpv6.h:395
Definition: icmpv6.h:374
Definition: icmpv6.h:275
rsa_sign_type(RAIterator hash, const signature_type &sign)
Constructs a rsa_sign_type object.
Definition: icmpv6.h:318
rsa_sign_type()
Default constructs a rsa_sign_type.
Definition: icmpv6.h:328
rsa_sign_type(RAIterator hash, ForwardIterator start, ForwardIterator end)
Constructs a rsa_sign_type object.
Definition: icmpv6.h:300
Definition: icmpv6.h:504
Definition: icmpv6.h:489