1 2 /*************************************************************************** 3 * ICMPv6Header.h -- The ICMPv6Header Class represents an ICMP version 6 * 4 * packet. It contains methods to set any header field. In general, these * 5 * methods do error checkings and byte order conversion. * 6 * * 7 ***********************IMPORTANT NMAP LICENSE TERMS************************ 8 * * 9 * The Nmap Security Scanner is (C) 1996-2020 Insecure.Com LLC ("The Nmap * 10 * Project"). Nmap is also a registered trademark of the Nmap Project. * 11 * * 12 * This program is distributed under the terms of the Nmap Public Source * 13 * License (NPSL). The exact license text applying to a particular Nmap * 14 * release or source code control revision is contained in the LICENSE * 15 * file distributed with that version of Nmap or source code control * 16 * revision. More Nmap copyright/legal information is available from * 17 * https://nmap.org/book/man-legal.html, and further information on the * 18 * NPSL license itself can be found at https://nmap.org/npsl. This header * 19 * summarizes some key points from the Nmap license, but is no substitute * 20 * for the actual license text. * 21 * * 22 * Nmap is generally free for end users to download and use themselves, * 23 * including commercial use. It is available from https://nmap.org. * 24 * * 25 * The Nmap license generally prohibits companies from using and * 26 * redistributing Nmap in commercial products, but we sell a special Nmap * 27 * OEM Edition with a more permissive license and special features for * 28 * this purpose. See https://nmap.org/oem * 29 * * 30 * If you have received a written Nmap license agreement or contract * 31 * stating terms other than these (such as an Nmap OEM license), you may * 32 * choose to use and redistribute Nmap under those terms instead. * 33 * * 34 * The official Nmap Windows builds include the Npcap software * 35 * (https://npcap.org) for packet capture and transmission. It is under * 36 * separate license terms which forbid redistribution without special * 37 * permission. So the official Nmap Windows builds may not be * 38 * redistributed without special permission (such as an Nmap OEM * 39 * license). * 40 * * 41 * Source is provided to this software because we believe users have a * 42 * right to know exactly what a program is going to do before they run it. * 43 * This also allows you to audit the software for security holes. * 44 * * 45 * Source code also allows you to port Nmap to new platforms, fix bugs, * 46 * and add new features. You are highly encouraged to submit your * 47 * changes as a Github PR or by email to the dev@nmap.org mailing list * 48 * for possible incorporation into the main distribution. Unless you * 49 * specify otherwise, it is understood that you are offering us very * 50 * broad rights to use your submissions as described in the Nmap Public * 51 * Source License Contributor Agreement. This is important because we * 52 * fund the project by selling licenses with various terms, and also * 53 * because the inability to relicense code has caused devastating * 54 * problems for other Free Software projects (such as KDE and NASM). * 55 * * 56 * The free version of Nmap is distributed in the hope that it will be * 57 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * 58 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Warranties, * 59 * indemnification and commercial support are all available through the * 60 * Npcap OEM program--see https://nmap.org/oem. * 61 * * 62 ***************************************************************************/ 63 /* This code was originally part of the Nping tool. */ 64 65 #ifndef ICMPv6HEADER_H 66 #define ICMPv6HEADER_H 1 67 68 #include "ICMPHeader.h" 69 70 /******************************************************************************/ 71 /* IMPORTANT INFORMATION ON HOW TO USE THIS CLASS. */ 72 /******************************************************************************/ 73 /* This class represents an ICMPv6 messages. ICMPv6 messages may be of 74 * different types. Each type has its own header and possibly a variable 75 * length data field. Information messages have an "invoking packet" field 76 * which is the IP packet that triggered the emission of the ICMPv6 message. 77 * Other messages may contain a "data" field, like echo requests an replies. 78 * Some others may contain ICMPv6 Options. 79 * 80 * So the thing is, that this class only represents fixed-length ICMPv6 81 * headers and does NOT offer storage for ANY variable-length field. This 82 * fields may be added to the ICMPv6 header using instances of the RawData 83 * class the ICMPv6Option class or even the IPv6Header class (in those cases 84 * where a whole packet is appendend to the ICMPv6 message). 85 * 86 * So, how does this work? Let's look at some examples. 87 * 88 * 1. Imagine we need to build an ICMP echo request message that includes some 89 * arbitrary data to be echoed. We could do the following: 90 * 91 * u8 final_packet[1024]; <-- Buffer to store the resulting packet 92 * u32 final_packet_len=0; <-- Length of the resulting packet 93 * ICMPv6Header header; <-- The ICMPv6 fixed-length part 94 * RawData data; <-- The data to append to the echo message 95 * 96 * header.setType(ICMPv6_ECHO); <-- Set ICMPv6 type to "Echo request" 97 * data.store("1234567890"); <-- Store data we need to send. 98 * header.setNextElement(&data); <-- Tell ICMPv6Header what's after it 99 * header.setSum(); <-- Compute the checksum 100 * 101 * final_packet_len=header.dumpToBinaryBuffer(fina_packet, 1024); 102 * send_packet(final_packet, final_packet_len) 103 * 104 * 2. If we are sending a parameter problem message and we need to include the 105 * invoking datagram, we can call setNextElement() passing an IPv6Header 106 * pointer. 107 * 108 * u8 final_packet[1024]; <-- Buffer to store the resulting packet 109 * u32 final_packet_len=0; <-- Length of the resulting packet 110 * ICMPv6Header header; <-- The ICMPv6 fixed-length part 111 * IPv6Header ipv6; <-- The IPv6 packet that triggered ICMPv6 112 * 113 * header.setType(ICMPv6_PARAMPROB); <-- Set ICMPv6 type to "Param Problem" 114 * header.setNextElement(&ipv6); <-- Tell ICMPv6Header what's after it 115 * header.setSum(); <-- Compute the checksum 116 * 117 * Note that here we don't show how the ipv6 object is set. 118 * 119 * 3. If we are sending a router solicitation message, we'll call 120 * setNextElement() passing an IPv6Options Pointer. 121 * 122 * u8 final_packet[1024]; <-- Buffer to store the resulting packet 123 * u32 final_packet_len=0; <-- Length of the resulting packet 124 * ICMPv6Header header; <-- The ICMPv6 fixed-length part 125 * IPv6Options opts1; <-- IPv6 options 126 * IPv6Options opts2; <-- IPv6 options 127 * IPv6Options opts3; <-- IPv6 options 128 * 129 * header.setType(ICMPv6_ROUTERSOLICIT); <-- Set ICMPv6 type 130 * 131 * opts1.setXXXX(); <-- Set up the options 132 * . 133 * . 134 * . 135 * opts3.setYYYY(); 136 * 137 * opts2.setNextElement(&opts3); <-- Link the options 138 * opts1.setNextElement(&opts2); 139 * header.setNextElement(&opts1); 140 * header.setNextElement(&ipv6); <-- Link the first option to the ICMPv6 141 * header.setSum(); <-- Compute the checksum 142 * 143 * And so on... 144 * 145 */ 146 147 148 /* Packet header diagrams included in this file have been taken from the 149 * following IETF RFC documents: RFC 4443, RFC 2461, RFC 2894 */ 150 151 /* ICMP types and codes. 152 * The following types and codes have been defined by IANA. A complete list 153 * may be found at http://www.iana.org/assignments/icmpv6-parameters 154 * 155 * Definitions on the first level of indentation are ICMPv6 Types. 156 * Definitions on the second level of indentation (values enclosed in 157 * parenthesis) are ICMPv6 Codes */ 158 #define ICMPv6_UNREACH 1 /* Destination unreachable [RFC 2463, 4443] */ 159 #define ICMPv6_UNREACH_NO_ROUTE (0) /* --> No route to destination */ 160 #define ICMPv6_UNREACH_PROHIBITED (1) /* --> Communication administratively prohibited */ 161 #define ICMPv6_UNREACH_BEYOND_SCOPE (2) /* --> Beyond scope of source address [RFC4443] */ 162 #define ICMPv6_UNREACH_ADDR_UNREACH (3) /* --> Address unreachable */ 163 #define ICMPv6_UNREACH_PORT_UNREACH (4) /* --> Port unreachable */ 164 #define ICMPv6_UNREACH_SRC_ADDR_FAILED (5) /* --> Source address failed ingress/egress policy [RFC4443] */ 165 #define ICMPv6_UNREACH_REJECT_ROUTE (6) /* --> Reject route to destination [RFC4443] */ 166 #define ICMPv6_PKTTOOBIG 2 /* Packet too big [RFC 2463, 4443] */ 167 #define ICMPv6_TIMXCEED 3 /* Time exceeded [RFC 2463, 4443] */ 168 #define ICMPv6_TIMXCEED_HOP_EXCEEDED (0) /* --> Hop limit exceeded in transit */ 169 #define ICMPv6_TIMXCEED_REASS_EXCEEDED (1) /* --> Fragment reassembly time exceeded */ 170 #define ICMPv6_PARAMPROB 4 /* Parameter problem [RFC 2463, 4443] */ 171 #define ICMPv6_PARAMPROB_FIELD (0) /* --> Erroneous header field encountered */ 172 #define ICMPv6_PARAMPROB_NEXT_HDR (1) /* --> Unrecognized Next Header type encountered */ 173 #define ICMPv6_PARAMPROB_OPTION (2) /* --> Unrecognized IPv6 option encountered */ 174 #define ICMPv6_ECHO 128 /* Echo request [RFC 2463, 4443] */ 175 #define ICMPv6_ECHOREPLY 129 /* Echo reply [RFC 2463, 4443] */ 176 #define ICMPv6_GRPMEMBQUERY 130 /* Group Membership Query [RFC 2710] */ 177 #define ICMPv6_GRPMEMBREP 131 /* Group Membership Report [RFC 2710] */ 178 #define ICMPv6_GRPMEMBRED 132 /* Group Membership Reduction [RFC 2710] */ 179 #define ICMPv6_ROUTERSOLICIT 133 /* Router Solicitation [RFC 2461] */ 180 #define ICMPv6_ROUTERADVERT 134 /* Router Advertisement [RFC 2461] */ 181 #define ICMPv6_NGHBRSOLICIT 135 /* Neighbor Solicitation [RFC 2461] */ 182 #define ICMPv6_NGHBRADVERT 136 /* Neighbor Advertisement [RFC 2461] */ 183 #define ICMPv6_REDIRECT 137 /* Redirect [RFC 2461] */ 184 #define ICMPv6_RTRRENUM 138 /* Router Renumbering [RFC 2894] */ 185 #define ICMPv6_RTRRENUM_COMMAND (0) /* --> Router Renumbering Command */ 186 #define ICMPv6_RTRRENUM_RESULT (1) /* --> Router Renumbering Result */ 187 #define ICMPv6_RTRRENUM_SEQ_RESET (255) /* Sequence Number Reset */ 188 #define ICMPv6_NODEINFOQUERY 139 /* ICMP Node Information Query [RFC 4620] */ 189 #define ICMPv6_NODEINFOQUERY_IPv6ADDR (0) /* --> The Data field contains an IPv6 address */ 190 #define ICMPv6_NODEINFOQUERY_NAME (1) /* --> The Data field contains a name */ 191 #define ICMPv6_NODEINFOQUERY_IPv4ADDR (2) /* --> The Data field contains an IPv4 address */ 192 #define ICMPv6_NODEINFORESP 140 /* ICMP Node Information Response [RFC 4620] */ 193 #define ICMPv6_NODEINFORESP_SUCCESS (0) /* --> A successful reply. */ 194 #define ICMPv6_NODEINFORESP_REFUSED (1) /* --> The Responder refuses to supply the answer */ 195 #define ICMPv6_NODEINFORESP_UNKNOWN (2) /* --> The Qtype of the Query is unknown */ 196 #define ICMPv6_INVNGHBRSOLICIT 141 /* Inverse Neighbor Discovery Solicitation Message [RFC 3122] */ 197 #define ICMPv6_INVNGHBRADVERT 142 /* Inverse Neighbor Discovery Advertisement Message [RFC 3122] */ 198 #define ICMPv6_MLDV2 143 /* MLDv2 Multicast Listener Report [RFC 3810] */ 199 #define ICMPv6_AGENTDISCOVREQ 144 /* Home Agent Address Discovery Request Message [RFC 3775] */ 200 #define ICMPv6_AGENTDISCOVREPLY 145 /* Home Agent Address Discovery Reply Message [RFC 3775] */ 201 #define ICMPv6_MOBPREFIXSOLICIT 146 /* Mobile Prefix Solicitation [RFC 3775] */ 202 #define ICMPv6_MOBPREFIXADVERT 147 /* Mobile Prefix Advertisement [RFC 3775] */ 203 #define ICMPv6_CERTPATHSOLICIT 148 /* Certification Path Solicitation [RFC 3971] */ 204 #define ICMPv6_CERTPATHADVERT 149 /* Certification Path Advertisement [RFC 3971] */ 205 #define ICMPv6_EXPMOBILITY 150 /* Experimental mobility protocols [RFC 4065] */ 206 #define ICMPv6_MRDADVERT 151 /* MRD, Multicast Router Advertisement [RFC 4286] */ 207 #define ICMPv6_MRDSOLICIT 152 /* MRD, Multicast Router Solicitation [RFC 4286] */ 208 #define ICMPv6_MRDTERMINATE 153 /* MRD, Multicast Router Termination [RFC 4286] */ 209 #define ICMPv6_FMIPV6 154 /* FMIPv6 messages [RFC 5568] */ 210 211 /* Node Information parameters */ 212 /* -> Query types */ 213 #define NI_QTYPE_NOOP 0 214 #define NI_QTYPE_UNUSED 1 215 #define NI_QTYPE_NODENAME 2 216 #define NI_QTYPE_NODEADDRS 3 217 #define NI_QTYPE_IPv4ADDRS 4 218 /* -> Misc */ 219 #define NI_NONCE_LEN 8 220 221 /* Nping ICMPv6Header Class internal definitions */ 222 #define ICMPv6_COMMON_HEADER_LEN 4 223 #define ICMPv6_MIN_HEADER_LEN 8 224 #define ICMPv6_UNREACH_LEN (ICMPv6_COMMON_HEADER_LEN+4) 225 #define ICMPv6_PKTTOOBIG_LEN (ICMPv6_COMMON_HEADER_LEN+4) 226 #define ICMPv6_TIMXCEED_LEN (ICMPv6_COMMON_HEADER_LEN+4) 227 #define ICMPv6_PARAMPROB_LEN (ICMPv6_COMMON_HEADER_LEN+4) 228 #define ICMPv6_ECHO_LEN (ICMPv6_COMMON_HEADER_LEN+4) 229 #define ICMPv6_ECHOREPLY_LEN (ICMPv6_COMMON_HEADER_LEN+4) 230 #define ICMPv6_ROUTERSOLICIT_LEN (ICMPv6_COMMON_HEADER_LEN+4) 231 #define ICMPv6_ROUTERADVERT_LEN (ICMPv6_COMMON_HEADER_LEN+12) 232 #define ICMPv6_NGHBRSOLICIT_LEN (ICMPv6_COMMON_HEADER_LEN+20) 233 #define ICMPv6_NGHBRADVERT_LEN (ICMPv6_COMMON_HEADER_LEN+20) 234 #define ICMPv6_REDIRECT_LEN (ICMPv6_COMMON_HEADER_LEN+36) 235 #define ICMPv6_RTRRENUM_LEN (ICMPv6_COMMON_HEADER_LEN+12) 236 #define ICMPv6_NODEINFO_LEN (ICMPv6_COMMON_HEADER_LEN+12) 237 #define ICMPv6_MLD_LEN (ICMPv6_COMMON_HEADER_LEN+20) 238 /* This must the MAX() of all values defined above*/ 239 #define ICMPv6_MAX_MESSAGE_BODY (ICMPv6_REDIRECT_LEN-ICMPv6_COMMON_HEADER_LEN) 240 241 242 243 /* Node Information flag bitmaks */ 244 #define ICMPv6_NI_FLAG_T 0x01 245 #define ICMPv6_NI_FLAG_A 0x02 246 #define ICMPv6_NI_FLAG_C 0x04 247 #define ICMPv6_NI_FLAG_L 0x08 248 #define ICMPv6_NI_FLAG_G 0x10 249 #define ICMPv6_NI_FLAG_S 0x20 250 251 class ICMPv6Header : public ICMPHeader { 252 253 /**********************************************************************/ 254 /* COMMON ICMPv6 packet HEADER */ 255 /**********************************************************************/ 256 /* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 257 | Type | Code | Checksum | 258 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 259 | | 260 + Message Body + 261 | | */ 262 struct nping_icmpv6_hdr{ 263 u8 type; 264 u8 code; 265 u16 checksum; 266 u8 data[ICMPv6_MAX_MESSAGE_BODY]; 267 }__attribute__((__packed__)); 268 typedef struct nping_icmpv6_hdr nping_icmpv6_hdr_t; 269 270 271 /**********************************************************************/ 272 /* ICMPv6 MESSAGE SPECIFIC HEADERS */ 273 /**********************************************************************/ 274 275 /* Destination Unreachable Message 276 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 277 | Type | Code | Checksum | 278 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 279 | Unused | 280 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 281 | As much of invoking packet | 282 + as possible without the ICMPv6 packet + 283 | exceeding the minimum IPv6 MTU [IPv6] | */ 284 struct dest_unreach_msg{ 285 u32 unused; 286 //u8 invoking_pkt[?]; 287 }__attribute__((__packed__)); 288 typedef struct dest_unreach_msg dest_unreach_msg_t; 289 290 291 /* Packet Too Big Message 292 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 293 | Type | Code | Checksum | 294 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 295 | MTU | 296 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 297 | As much of invoking packet | 298 + as possible without the ICMPv6 packet + 299 | exceeding the minimum IPv6 MTU [IPv6] | */ 300 struct pkt_too_big_msg{ 301 u32 mtu; 302 //u8 invoking_pkt[?]; 303 }__attribute__((__packed__)); 304 typedef struct pkt_too_big_msg pkt_too_big_msg_t; 305 306 307 /* Time Exceeded Message 308 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 309 | Type | Code | Checksum | 310 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 311 | Unused | 312 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 313 | As much of invoking packet | 314 + as possible without the ICMPv6 packet + 315 | exceeding the minimum IPv6 MTU [IPv6] | */ 316 struct time_exceeded_msg{ 317 u32 unused; 318 //u8 invoking_pkt[?]; 319 }__attribute__((__packed__)); 320 typedef struct time_exceeded_msg time_exceeded_msg_t; 321 322 323 /* Parameter Problem Message 324 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 325 | Type | Code | Checksum | 326 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 327 | Pointer | 328 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 329 | As much of invoking packet | 330 + as possible without the ICMPv6 packet + 331 | exceeding the minimum IPv6 MTU [IPv6] | */ 332 struct parameter_problem_msg{ 333 u32 pointer; 334 //u8 invoking_pkt[?]; 335 }__attribute__((__packed__)); 336 typedef struct parameter_problem_msg parameter_problem_msg_t; 337 338 339 /* Echo Request/Response Messages 340 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 341 | Type | Code | Checksum | 342 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 343 | Identifier | Sequence Number | 344 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 345 | Data ... 346 +-+-+-+-+- */ 347 struct echo_msg{ 348 u16 id; 349 u16 seq; 350 //u8 data[?]; 351 }__attribute__((__packed__)); 352 typedef struct echo_msg echo_msg_t; 353 354 /* Router Advertisement Message 355 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 356 | Type | Code | Checksum | 357 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 358 | Cur Hop Limit |M|O|H|Prf|P|R|R| Router Lifetime | 359 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 360 | Reachable Time | 361 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 362 | Retrans Timer | 363 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 364 | Options ... 365 +-+-+-+-+-+-+-+-+-+-+-+- */ 366 struct router_advert_msg{ 367 u8 current_hop_limit; 368 u8 autoconfig_flags; /* See RFC 5175 */ 369 u16 router_lifetime; 370 u32 reachable_time; 371 u32 retransmission_timer; 372 //u8 icmpv6_options[?]; 373 }__attribute__((__packed__)); 374 typedef struct router_advert_msg router_advert_msg_t; 375 376 377 /* Router Solicitation Message 378 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 379 | Type | Code | Checksum | 380 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 381 | Reserved | 382 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 383 | Options ... 384 +-+-+-+-+-+-+-+-+-+-+-+- */ 385 struct router_solicit_msg{ 386 u32 reserved; 387 //u8 icmpv6_options[?]; 388 }__attribute__((__packed__)); 389 typedef struct router_solicit_msg router_solicit_msg_t; 390 391 392 /* Neighbor Advertisement Message 393 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 394 | Type | Code | Checksum | 395 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 396 |R|S|O| Reserved | 397 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 398 | | 399 + + 400 | | 401 + Target Address + 402 | | 403 + + 404 | | 405 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 406 | Options ... 407 +-+-+-+-+-+-+-+-+-+-+-+- */ 408 struct neighbor_advert_msg{ 409 u8 flags; 410 u8 reserved[3]; 411 u8 target_address[16]; 412 //u8 icmpv6_options[?]; 413 }__attribute__((__packed__)); 414 typedef struct neighbor_advert_msg neighbor_advert_msg_t; 415 416 417 /* Neighbor Solicitation Message 418 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 419 | Type | Code | Checksum | 420 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 421 | Reserved | 422 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 423 | | 424 + + 425 | | 426 + Target Address + 427 | | 428 + + 429 | | 430 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 431 | Options ... 432 +-+-+-+-+-+-+-+-+-+-+-+- */ 433 struct neighbor_solicit_msg{ 434 u32 reserved; 435 u8 target_address[16]; 436 //u8 icmpv6_options[?]; 437 }__attribute__((__packed__)); 438 typedef struct neighbor_solicit_msg neighbor_solicit_msg_t; 439 440 441 /* Redirect Message 442 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 443 | Type | Code | Checksum | 444 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 445 | Reserved | 446 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 447 | | 448 + + 449 | | 450 + Target Address + 451 | | 452 + + 453 | | 454 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 455 | | 456 + + 457 | | 458 + Destination Address + 459 | | 460 + + 461 | | 462 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 463 | Options ... 464 +-+-+-+-+-+-+-+-+-+-+-+- */ 465 struct redirect_msg{ 466 u32 reserved; 467 u8 target_address[16]; 468 u8 destination_address[16]; 469 //u8 icmpv6_options[?]; 470 }__attribute__((__packed__)); 471 typedef struct redirect_msg redirect_msg_t; 472 473 474 /* Router Renumbering Header 475 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 476 | Type | Code | Checksum | 477 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 478 | SequenceNumber | 479 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 480 | SegmentNumber | Flags | MaxDelay | 481 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 482 | reserved | 483 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 484 | | 485 / RR Message Body / 486 | | 487 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ 488 struct router_renumbering_msg{ 489 u32 seq; 490 u8 segment_number; 491 u8 flags; 492 u16 max_delay; 493 u32 reserved; 494 //u8 rr_msg_body[?]; 495 }__attribute__((__packed__)); 496 typedef struct router_renumbering_msg router_renumbering_msg_t; 497 498 499 /* Node Information Queries 500 0 1 2 3 501 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 502 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 503 | Type | Code | Checksum | 504 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 505 | Qtype | unused |G|S|L|C|A|T| 506 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 507 | | 508 + Nonce + 509 | | 510 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 511 | | 512 / Data / 513 | | 514 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ 515 struct nodeinfo_msg{ 516 u16 qtype; 517 u16 flags; 518 u64 nonce; 519 //u8 data[?]; 520 }__attribute__((__packed__)); 521 typedef struct nodeinfo_msg nodeinfo_msg_t; 522 523 524 /* Multicast Listener Discovery 525 0 1 2 3 526 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 527 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 528 | Type | Code | Checksum | 529 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 530 | Maximum Response Delay | Reserved | 531 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 532 | | 533 + + 534 | | 535 + Multicast Address + 536 | | 537 + + 538 | | 539 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ 540 struct mld_msg{ 541 u16 max_response_delay; 542 u16 reserved; 543 u8 mcast_address[16]; 544 }__attribute__((__packed__)); 545 typedef struct mld_msg mld_msg_t; 546 547 548 nping_icmpv6_hdr_t h; 549 550 /* Helper pointers */ 551 dest_unreach_msg_t *h_du; 552 pkt_too_big_msg_t *h_ptb; 553 time_exceeded_msg_t *h_te; 554 parameter_problem_msg_t *h_pp; 555 echo_msg_t *h_e; 556 router_advert_msg_t *h_ra; 557 router_solicit_msg_t *h_rs; 558 neighbor_advert_msg_t *h_na; 559 neighbor_solicit_msg_t *h_ns; 560 redirect_msg_t *h_r; 561 router_renumbering_msg_t *h_rr; 562 nodeinfo_msg_t *h_ni; 563 mld_msg_t *h_mld; 564 565 public: 566 ICMPv6Header(); 567 ~ICMPv6Header(); 568 void reset(); 569 u8 *getBufferPointer(); 570 int storeRecvData(const u8 *buf, size_t len); 571 int protocol_id() const; 572 int validate(); 573 int print(FILE *output, int detail) const; 574 575 /* ICMP Type */ 576 int setType(u8 val); 577 u8 getType() const; 578 bool validateType(); 579 bool validateType(u8 val); 580 581 /* Code */ 582 int setCode(u8 c); 583 u8 getCode() const; 584 bool validateCode(); 585 bool validateCode(u8 type, u8 code); 586 587 /* Checksum */ 588 int setSum(); 589 int setSum(u16 s); 590 int setSumRandom(); 591 u16 getSum() const; 592 593 int setReserved(u32 val); 594 u32 getReserved() const; 595 int setUnused(u32 val); 596 u32 getUnused() const; 597 598 int setFlags(u8 val); 599 u8 getFlags() const; 600 601 int setMTU(u32 mtu); 602 u32 getMTU() const; 603 604 /* Parameter problem */ 605 int setPointer(u32 val); 606 u32 getPointer() const; 607 608 /* Echo */ 609 int setIdentifier(u16 val); 610 u16 getIdentifier() const; 611 int setSequence(u16 val); 612 int setSequence(u32 val); 613 u32 getSequence() const; 614 615 /* Router Advertisement */ 616 int setCurrentHopLimit(u8 val); 617 u8 getCurrentHopLimit() const; 618 619 int setRouterLifetime(u16 val); 620 u16 getRouterLifetime() const; 621 622 int setReachableTime(u32 val); 623 u32 getReachableTime() const; 624 625 int setRetransmissionTimer(u32 val); 626 u32 getRetransmissionTimer() const; 627 628 int setTargetAddress(struct in6_addr addr); 629 struct in6_addr getTargetAddress() const; 630 631 int setDestinationAddress(struct in6_addr addr); 632 struct in6_addr getDestinationAddress() const; 633 634 int setSegmentNumber(u8 val); 635 u8 getSegmentNumber() const; 636 637 int setMaxDelay(u16 val); 638 u16 getMaxDelay() const; 639 640 /* Node Information Queries */ 641 int setQtype(u16 val); 642 u16 getQtype() const; 643 int setNodeInfoFlags(u16 val); 644 u16 getNodeInfoFlags() const; 645 int setG(bool flag_value=true); 646 bool getG() const; 647 int setS(bool flag_value=true); 648 bool getS() const; 649 int setL(bool flag_value=true); 650 bool getL() const; 651 int setC(bool flag_value=true); 652 bool getC() const; 653 int setA(bool flag_value=true); 654 bool getA() const; 655 int setT(bool flag_value=true); 656 bool getT() const; 657 int setNonce(u64 nonce_value); 658 int setNonce(const u8 *nonce); 659 u64 getNonce() const; 660 661 /* Multicast Listener Discovery */ 662 int setMulticastAddress(struct in6_addr addr); 663 struct in6_addr getMulticastAddress() const; 664 665 /* Misc */ 666 int getHeaderLengthFromType(u8 type) const; 667 bool isError() const; 668 const char *type2string(int type, int code) const; 669 670 }; /* End of class ICMPv6Header */ 671 672 #endif 673