1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 /* 26 * Copyright 2024 Bill Sommerfeld <sommerfeld@hamachi.org> 27 */ 28 29 #ifndef _NETINET_ICMP6_H 30 #define _NETINET_ICMP6_H 31 32 #ifdef __cplusplus 33 extern "C" { 34 #endif 35 36 #include <sys/types.h> 37 38 /* 39 * Type and code definitions for ICMPv6. 40 * Based on RFC2292. 41 */ 42 43 #define ICMP6_INFOMSG_MASK 0x80 /* all informational messages */ 44 45 /* Minimum ICMPv6 header length. */ 46 #define ICMP6_MINLEN 8 47 48 typedef struct icmp6_hdr { 49 uint8_t icmp6_type; /* type field */ 50 uint8_t icmp6_code; /* code field */ 51 uint16_t icmp6_cksum; /* checksum field */ 52 union { 53 uint32_t icmp6_un_data32[1]; /* type-specific field */ 54 uint16_t icmp6_un_data16[2]; /* type-specific field */ 55 uint8_t icmp6_un_data8[4]; /* type-specific field */ 56 } icmp6_dataun; 57 } icmp6_t; 58 59 #define icmp6_data32 icmp6_dataun.icmp6_un_data32 60 #define icmp6_data16 icmp6_dataun.icmp6_un_data16 61 #define icmp6_data8 icmp6_dataun.icmp6_un_data8 62 #define icmp6_pptr icmp6_data32[0] /* parameter prob */ 63 #define icmp6_mtu icmp6_data32[0] /* packet too big */ 64 #define icmp6_id icmp6_data16[0] /* echo request/reply */ 65 #define icmp6_seq icmp6_data16[1] /* echo request/reply */ 66 #define icmp6_maxdelay icmp6_data16[0] /* mcast group membership */ 67 68 /* Multicast Listener Discovery messages (RFC 3542 (v1), RFC 3810 (v2)). */ 69 70 #define MLD_MINLEN 24 71 #define MLD_V2_QUERY_MINLEN 28 72 73 /* Query Header, common to v1 and v2 */ 74 typedef struct mld_hdr { 75 struct icmp6_hdr mld_icmp6_hdr; 76 struct in6_addr mld_addr; /* multicast address */ 77 } mld_hdr_t; 78 79 #define mld_type mld_icmp6_hdr.icmp6_type 80 #define mld_code mld_icmp6_hdr.icmp6_code 81 #define mld_cksum mld_icmp6_hdr.icmp6_cksum 82 #define mld_maxdelay mld_icmp6_hdr.icmp6_data16[0] 83 #define mld_reserved mld_icmp6_hdr.icmp6_data16[1] 84 85 /* MLDv2 query */ 86 typedef struct mld2q { 87 mld_hdr_t mld2q_hdr; 88 uint8_t mld2q_sqrv; /* S Flag, Q's Robustness Variable */ 89 uint8_t mld2q_qqic; /* Querier's Query Interval Code */ 90 uint16_t mld2q_numsrc; /* number of sources */ 91 } mld2q_t; 92 93 #define mld2q_type mld2q_hdr.mld_icmp6_hdr.icmp6_type 94 #define mld2q_code mld2q_hdr.mld_icmp6_hdr.icmp6_code 95 #define mld2q_cksum mld2q_hdr.mld_icmp6_hdr.icmp6_cksum 96 #define mld2q_mxrc mld2q_hdr.mld_icmp6_hdr.icmp6_data16[0] 97 #define mld2q_addr mld2q_hdr.mld_addr 98 99 #define MLD_V2_SFLAG_MASK 0x8 /* mask off s part of sqrv */ 100 #define MLD_V2_RV_MASK 0x7 /* mask off qrv part of sqrv */ 101 102 /* definitions used to extract max response delay from mrc field */ 103 #define MLD_V2_MAXRT_FPMIN 0x8000 104 #define MLD_V2_MAXRT_MANT_MASK 0x0fff 105 #define MLD_V2_MAXRT_EXP_MASK 0x7000 106 107 /* definitions used to extract querier's query interval from qqic field */ 108 #define MLD_V2_QQI_FPMIN 0x80 109 #define MLD_V2_QQI_MANT_MASK 0x0f 110 #define MLD_V2_QQI_EXP_MASK 0x70 111 112 /* MLDv2 response */ 113 typedef icmp6_t mld2r_t; 114 115 #define mld2r_type icmp6_type 116 #define mld2r_res icmp6_code 117 #define mld2r_cksum icmp6_cksum 118 #define mld2r_res1 icmp6_data16[0] 119 #define mld2r_nummar icmp6_data16[1] 120 121 /* MLDv2 multicast address record */ 122 typedef struct mld2mar { 123 uint8_t mld2mar_type; /* type of record */ 124 uint8_t mld2mar_auxlen; /* auxiliary data length */ 125 uint16_t mld2mar_numsrc; /* number of sources */ 126 struct in6_addr mld2mar_group; /* group address being reported */ 127 } mld2mar_t; 128 129 130 /* For router renumbering. */ 131 struct icmp6_router_renum { /* router renumbering header */ 132 struct icmp6_hdr rr_hdr; 133 uint8_t rr_segnum; 134 uint8_t rr_flags; 135 uint16_t rr_maxdelay; 136 uint32_t rr_reserved; 137 }; 138 139 #define rr_type rr_hdr.icmp6_type 140 #define rr_code rr_hdr.icmp6_code 141 #define rr_cksum rr_hdr.icmp6_cksum 142 #define rr_seqnum rr_hdr.icmp6_data32[0] 143 144 /* Router renumbering flags */ 145 #define ICMP6_RR_FLAGS_TEST 0x80 146 #define ICMP6_RR_FLAGS_REQRESULT 0x40 147 #define ICMP6_RR_FLAGS_FORCEAPPLY 0x20 148 #define ICMP6_RR_FLAGS_SPECSITE 0x10 149 #define ICMP6_RR_FLAGS_PREVDONE 0x08 150 151 struct rr_pco_match { /* match prefix part */ 152 uint8_t rpm_code; 153 uint8_t rpm_len; 154 uint8_t rpm_ordinal; 155 uint8_t rpm_matchlen; 156 uint8_t rpm_minlen; 157 uint8_t rpm_maxlen; 158 uint16_t rpm_reserved; 159 struct in6_addr rpm_prefix; 160 }; 161 162 /* PCO code values */ 163 #define RPM_PCO_ADD 1 164 #define RPM_PCO_CHANGE 2 165 #define RPM_PCO_SETGLOBAL 3 166 167 struct rr_pco_use { /* use prefix part */ 168 uint8_t rpu_uselen; 169 uint8_t rpu_keeplen; 170 uint8_t rpu_ramask; 171 uint8_t rpu_raflags; 172 uint32_t rpu_vltime; 173 uint32_t rpu_pltime; 174 uint32_t rpu_flags; 175 struct in6_addr rpu_prefix; 176 }; 177 178 #define ICMP6_RR_PCOUSE_RAFLAGS_ONLINK 0x20 179 #define ICMP6_RR_PCOUSE_RAFLAGS_AUTO 0x10 180 181 #ifdef _BIG_ENDIAN 182 #define ICMP_RR_PCOUSE_FLAGS_DECRVLTIME 0x80000000 183 #define ICMP_RR_PCOUSE_FLAGS_DECRPLTIME 0x40000000 184 #else /* _BIG_ENDIAN */ 185 #define ICMP_RR_PCOUSE_FLAGS_DECRVLTIME 0x80 186 #define ICMP_RR_PCOUSE_FLAGS_DECRPLTIME 0x40 187 #endif /* _BIG_ENDIAN */ 188 189 struct rr_result { /* router renumbering result message */ 190 uint16_t rrr_flags; 191 uint8_t rrr_ordinal; 192 uint8_t rrr_matchedlen; 193 uint32_t rrr_ifid; 194 struct in6_addr rrr_prefix; 195 }; 196 197 #ifdef _BIG_ENDIAN 198 #define ICMP6_RR_RESULT_FLAGS_OOB 0x0002 199 #define ICMP6_RR_RESULT_FLAGS_FORBIDDEN 0x0001 200 #else /* _BIG_ENDIAN */ 201 #define ICMP6_RR_RESULT_FLAGS_OOB 0x0200 202 #define ICMP6_RR_RESULT_FLAGS_FORBIDDEN 0x0100 203 #endif /* _BIG_ENDIAN */ 204 205 /* ICMPv6 error types */ 206 #define ICMP6_DST_UNREACH 1 207 #define ICMP6_PACKET_TOO_BIG 2 208 #define ICMP6_TIME_EXCEEDED 3 209 #define ICMP6_PARAM_PROB 4 210 211 #define ICMP6_INFOMSG_MASK 0x80 /* all informational messages */ 212 213 /* ICMPv6 query types */ 214 #define ICMP6_ECHO_REQUEST 128 215 #define ICMP6_ECHO_REPLY 129 216 217 /* 218 * ICMPv6 group membership types 219 * ICMP6_MEMBERSHIP* types are the older names for these constants and should 220 * not be used in new code. 221 */ 222 #define MLD_LISTENER_QUERY 130 223 #define ICMP6_MEMBERSHIP_QUERY 130 224 #define MLD_LISTENER_REPORT 131 225 #define ICMP6_MEMBERSHIP_REPORT 131 226 #define MLD_LISTENER_REDUCTION 132 227 #define ICMP6_MEMBERSHIP_REDUCTION 132 228 #define MLD_V2_LISTENER_REPORT 143 229 230 /* types for neighbor discovery */ 231 #define ND_ROUTER_SOLICIT 133 232 #define ND_ROUTER_ADVERT 134 233 #define ND_NEIGHBOR_SOLICIT 135 234 #define ND_NEIGHBOR_ADVERT 136 235 #define ND_REDIRECT 137 236 237 /* router renumbering */ 238 #define ICMP6_ROUTER_RENUMBERING 138 239 240 #define ICMP6_MAX_INFO_TYPE 138 241 242 #define ICMP6_IS_ERROR(x) ((x) < 128) 243 244 /* codes for ICMP6_DST_UNREACH */ 245 #define ICMP6_DST_UNREACH_NOROUTE 0 /* no route to destination */ 246 #define ICMP6_DST_UNREACH_ADMIN 1 /* communication with destination */ 247 /* administratively prohibited */ 248 #define ICMP6_DST_UNREACH_NOTNEIGHBOR 2 /* not a neighbor */ 249 #define ICMP6_DST_UNREACH_BEYONDSCOPE 2 /* beyond scope of source */ 250 #define ICMP6_DST_UNREACH_ADDR 3 /* address unreachable */ 251 #define ICMP6_DST_UNREACH_NOPORT 4 /* bad port */ 252 253 /* codes for ICMP6_TIME_EXCEEDED */ 254 #define ICMP6_TIME_EXCEED_TRANSIT 0 /* Hop Limit == 0 in transit */ 255 #define ICMP6_TIME_EXCEED_REASSEMBLY 1 /* Reassembly time out */ 256 257 /* codes for ICMP6_PARAM_PROB */ 258 #define ICMP6_PARAMPROB_HEADER 0 /* erroneous header field */ 259 #define ICMP6_PARAMPROB_NEXTHEADER 1 /* unrecognized Next Header */ 260 #define ICMP6_PARAMPROB_OPTION 2 /* unrecognized IPv6 option */ 261 262 /* Default MLD max report delay value */ 263 #define ICMP6_MAX_HOST_REPORT_DELAY 10 /* max delay for response to */ 264 /* query (in seconds) */ 265 266 typedef struct nd_router_solicit { /* router solicitation */ 267 icmp6_t nd_rs_hdr; 268 /* could be followed by options */ 269 } nd_router_solicit_t; 270 271 #define nd_rs_type nd_rs_hdr.icmp6_type 272 #define nd_rs_code nd_rs_hdr.icmp6_code 273 #define nd_rs_cksum nd_rs_hdr.icmp6_cksum 274 #define nd_rs_reserved nd_rs_hdr.icmp6_data32[0] 275 276 typedef struct nd_router_advert { /* router advertisement */ 277 icmp6_t nd_ra_hdr; 278 uint32_t nd_ra_reachable; /* reachable time */ 279 uint32_t nd_ra_retransmit; /* retransmit timer */ 280 /* could be followed by options */ 281 } nd_router_advert_t; 282 283 #define nd_ra_type nd_ra_hdr.icmp6_type 284 #define nd_ra_code nd_ra_hdr.icmp6_code 285 #define nd_ra_cksum nd_ra_hdr.icmp6_cksum 286 #define nd_ra_curhoplimit nd_ra_hdr.icmp6_data8[0] 287 #define nd_ra_flags_reserved nd_ra_hdr.icmp6_data8[1] 288 289 #define ND_RA_FLAG_OTHER 0x40 290 #define ND_RA_FLAG_MANAGED 0x80 291 292 #define nd_ra_router_lifetime nd_ra_hdr.icmp6_data16[1] 293 294 typedef struct nd_neighbor_solicit { /* neighbor solicitation */ 295 icmp6_t nd_ns_hdr; 296 struct in6_addr nd_ns_target; /* target address */ 297 /* could be followed by options */ 298 } nd_neighbor_solicit_t; 299 300 #define nd_ns_type nd_ns_hdr.icmp6_type 301 #define nd_ns_code nd_ns_hdr.icmp6_code 302 #define nd_ns_cksum nd_ns_hdr.icmp6_cksum 303 #define nd_ns_reserved nd_ns_hdr.icmp6_data32[0] 304 305 typedef struct nd_neighbor_advert { /* neighbor advertisement */ 306 icmp6_t nd_na_hdr; 307 struct in6_addr nd_na_target; /* target address */ 308 /* could be followed by options */ 309 } nd_neighbor_advert_t; 310 311 #define nd_na_type nd_na_hdr.icmp6_type 312 #define nd_na_code nd_na_hdr.icmp6_code 313 #define nd_na_cksum nd_na_hdr.icmp6_cksum 314 315 #define nd_na_flags_reserved nd_na_hdr.icmp6_data32[0] 316 317 /* 318 * The first three bits of the flgs_reserved field of the ND structure are 319 * defined in this order: 320 * Router flag 321 * Solicited flag 322 * Override flag 323 */ 324 325 /* Save valuable htonl() cycles on little-endian boxen. */ 326 327 #ifdef _BIG_ENDIAN 328 329 #define ND_NA_FLAG_ROUTER 0x80000000 330 #define ND_NA_FLAG_SOLICITED 0x40000000 331 #define ND_NA_FLAG_OVERRIDE 0x20000000 332 333 #else /* _BIG_ENDIAN */ 334 335 #define ND_NA_FLAG_ROUTER 0x80 336 #define ND_NA_FLAG_SOLICITED 0x40 337 #define ND_NA_FLAG_OVERRIDE 0x20 338 339 #endif /* _BIG_ENDIAN */ 340 341 typedef struct nd_redirect { /* redirect */ 342 icmp6_t nd_rd_hdr; 343 struct in6_addr nd_rd_target; /* target address */ 344 struct in6_addr nd_rd_dst; /* destination address */ 345 /* could be followed by options */ 346 } nd_redirect_t; 347 348 #define nd_rd_type nd_rd_hdr.icmp6_type 349 #define nd_rd_code nd_rd_hdr.icmp6_code 350 #define nd_rd_cksum nd_rd_hdr.icmp6_cksum 351 #define nd_rd_reserved nd_rd_hdr.icmp6_data32[0] 352 353 typedef struct nd_opt_hdr { /* Neighbor discovery option header */ 354 uint8_t nd_opt_type; 355 uint8_t nd_opt_len; /* in units of 8 octets */ 356 /* followed by option specific data */ 357 } nd_opt_hdr_t; 358 359 /* Neighbor discovery option types */ 360 #define ND_OPT_SOURCE_LINKADDR 1 361 #define ND_OPT_TARGET_LINKADDR 2 362 #define ND_OPT_PREFIX_INFORMATION 3 363 #define ND_OPT_REDIRECTED_HEADER 4 364 #define ND_OPT_MTU 5 365 #define ND_OPT_DNS_RESOLVER 25 366 #define ND_OPT_DNS_SEARCHLIST 31 367 368 typedef struct nd_opt_prefix_info { /* prefix information */ 369 uint8_t nd_opt_pi_type; 370 uint8_t nd_opt_pi_len; 371 uint8_t nd_opt_pi_prefix_len; 372 uint8_t nd_opt_pi_flags_reserved; 373 uint32_t nd_opt_pi_valid_time; 374 uint32_t nd_opt_pi_preferred_time; 375 uint32_t nd_opt_pi_reserved2; 376 struct in6_addr nd_opt_pi_prefix; 377 } nd_opt_prefix_info_t; 378 379 #define ND_OPT_PI_FLAG_AUTO 0x40 380 #define ND_OPT_PI_FLAG_ONLINK 0x80 381 382 typedef struct nd_opt_rd_hdr { /* redirected header */ 383 uint8_t nd_opt_rh_type; 384 uint8_t nd_opt_rh_len; 385 uint16_t nd_opt_rh_reserved1; 386 uint32_t nd_opt_rh_reserved2; 387 /* followed by IP header and data */ 388 } nd_opt_rd_hdr_t; 389 390 typedef struct nd_opt_mtu { /* MTU option */ 391 uint8_t nd_opt_mtu_type; 392 uint8_t nd_opt_mtu_len; 393 uint16_t nd_opt_mtu_reserved; 394 uint32_t nd_opt_mtu_mtu; 395 } nd_opt_mtu_t; 396 397 /* Note: the option is variable length (at least 8 bytes long) */ 398 #ifndef ND_MAX_HDW_LEN 399 #define ND_MAX_HDW_LEN 64 400 #endif 401 struct nd_opt_lla { 402 uint8_t nd_opt_lla_type; 403 uint8_t nd_opt_lla_len; /* in units of 8 octets */ 404 uint8_t nd_opt_lla_hdw_addr[ND_MAX_HDW_LEN]; 405 }; 406 407 struct nd_opt_dns_resolver { 408 uint8_t nd_opt_dnsr_type; 409 uint8_t nd_opt_dnsr_len; /* in units of 8 octets */ 410 uint16_t nd_opt_dnsr_reserved; 411 uint32_t nd_opt_dnsr_lifetime; 412 struct in6_addr nd_opt_dnsr_addr[]; 413 }; 414 415 struct nd_opt_dns_sl { 416 uint8_t nd_opt_dnss_type; 417 uint8_t nd_opt_dnss_len; /* in units of 8 octets */ 418 uint16_t nd_opt_dnss_reserved; 419 uint32_t nd_opt_dnss_lifetime; 420 uint8_t nd_opt_dnss_names[]; 421 }; 422 423 /* Neighbor discovery protocol constants */ 424 425 /* Router constants */ 426 #define ND_MAX_INITIAL_RTR_ADVERT_INTERVAL 16000 /* milliseconds */ 427 #define ND_MAX_INITIAL_RTR_ADVERTISEMENTS 3 /* transmissions */ 428 #define ND_MAX_FINAL_RTR_ADVERTISEMENTS 3 /* transmissions */ 429 #define ND_MIN_DELAY_BETWEEN_RAS 3000 /* milliseconds */ 430 #define ND_MAX_RA_DELAY_TIME 500 /* milliseconds */ 431 432 /* Host constants */ 433 #define ND_MAX_RTR_SOLICITATION_DELAY 1000 /* milliseconds */ 434 #define ND_RTR_SOLICITATION_INTERVAL 4000 /* milliseconds */ 435 #define ND_MAX_RTR_SOLICITATIONS 3 /* transmissions */ 436 437 /* Node constants */ 438 #define ND_MAX_MULTICAST_SOLICIT 3 /* transmissions */ 439 #define ND_MAX_UNICAST_SOLICIT 3 /* transmissions */ 440 #define ND_MAX_ANYCAST_DELAY_TIME 1000 /* milliseconds */ 441 #define ND_MAX_NEIGHBOR_ADVERTISEMENT 3 /* transmissions */ 442 #define ND_REACHABLE_TIME 30000 /* milliseconds */ 443 #define ND_RETRANS_TIMER 1000 /* milliseconds */ 444 #define ND_DELAY_FIRST_PROBE_TIME 5000 /* milliseconds */ 445 #define ND_MIN_RANDOM_FACTOR .5 446 #define ND_MAX_RANDOM_FACTOR 1.5 447 448 #define ND_MAX_REACHTIME 3600000 /* milliseconds */ 449 #define ND_MAX_REACHRETRANSTIME 100000 /* milliseconds */ 450 451 /* 452 * ICMPv6 type filtering for IPPROTO_ICMPV6 ICMP6_FILTER socket option 453 */ 454 #define ICMP6_FILTER 0x01 /* Set filter */ 455 456 typedef struct icmp6_filter { 457 uint32_t __icmp6_filt[8]; 458 } icmp6_filter_t; 459 460 /* Pass all ICMPv6 messages to the application */ 461 #define ICMP6_FILTER_SETPASSALL(filterp) ( \ 462 ((filterp)->__icmp6_filt[0] = 0xFFFFFFFFU), \ 463 ((filterp)->__icmp6_filt[1] = 0xFFFFFFFFU), \ 464 ((filterp)->__icmp6_filt[2] = 0xFFFFFFFFU), \ 465 ((filterp)->__icmp6_filt[3] = 0xFFFFFFFFU), \ 466 ((filterp)->__icmp6_filt[4] = 0xFFFFFFFFU), \ 467 ((filterp)->__icmp6_filt[5] = 0xFFFFFFFFU), \ 468 ((filterp)->__icmp6_filt[6] = 0xFFFFFFFFU), \ 469 ((filterp)->__icmp6_filt[7] = 0xFFFFFFFFU)) 470 471 /* ICMPv6 messages are blocked from being passed to the application */ 472 #define ICMP6_FILTER_SETBLOCKALL(filterp) ( \ 473 ((filterp)->__icmp6_filt[0] = 0x0), \ 474 ((filterp)->__icmp6_filt[1] = 0x0), \ 475 ((filterp)->__icmp6_filt[2] = 0x0), \ 476 ((filterp)->__icmp6_filt[3] = 0x0), \ 477 ((filterp)->__icmp6_filt[4] = 0x0), \ 478 ((filterp)->__icmp6_filt[5] = 0x0), \ 479 ((filterp)->__icmp6_filt[6] = 0x0), \ 480 ((filterp)->__icmp6_filt[7] = 0x0)) 481 482 /* Pass messages of a given type to the application */ 483 #define ICMP6_FILTER_SETPASS(type, filterp) \ 484 ((((filterp)->__icmp6_filt[(type) >> 5]) |= (1 << ((type) & 31)))) 485 486 /* Block messages of a given type from being passed to the application */ 487 #define ICMP6_FILTER_SETBLOCK(type, filterp) \ 488 ((((filterp)->__icmp6_filt[(type) >> 5]) &= ~(1 << ((type) & 31)))) 489 490 /* Test if message of a given type will be passed to an application */ 491 #define ICMP6_FILTER_WILLPASS(type, filterp) \ 492 ((((filterp)->__icmp6_filt[(type) >> 5]) & (1 << ((type) & 31))) != 0) 493 494 /* 495 * Test if message of a given type will blocked from 496 * being passed to an application 497 */ 498 #define ICMP6_FILTER_WILLBLOCK(type, filterp) \ 499 ((((filterp)->__icmp6_filt[(type) >> 5]) & (1 << ((type) & 31))) == 0) 500 501 #define ICMP_IOC_DEFAULT_Q (('I' << 8) + 51) 502 503 #ifdef __cplusplus 504 } 505 #endif 506 507 #endif /* _NETINET_ICMP6_H */ 508