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