1 /* Copyright (C) 1991-2022 Free Software Foundation, Inc. 2 This file is part of the GNU C Library. 3 4 The GNU C Library is free software; you can redistribute it and/or 5 modify it under the terms of the GNU Lesser General Public 6 License as published by the Free Software Foundation; either 7 version 2.1 of the License, or (at your option) any later version. 8 9 The GNU C Library is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 Lesser General Public License for more details. 13 14 You should have received a copy of the GNU Lesser General Public 15 License along with the GNU C Library; if not, see 16 <https://www.gnu.org/licenses/>. */ 17 18 #ifndef _NETINET_ICMP6_H 19 #define _NETINET_ICMP6_H 1 20 21 #include <inttypes.h> 22 #include <string.h> 23 #include <sys/types.h> 24 #include <netinet/in.h> 25 26 #define ICMP6_FILTER 1 27 28 #define ICMP6_FILTER_BLOCK 1 29 #define ICMP6_FILTER_PASS 2 30 #define ICMP6_FILTER_BLOCKOTHERS 3 31 #define ICMP6_FILTER_PASSONLY 4 32 33 struct icmp6_filter 34 { 35 uint32_t icmp6_filt[8]; 36 }; 37 38 struct icmp6_hdr 39 { 40 uint8_t icmp6_type; /* type field */ 41 uint8_t icmp6_code; /* code field */ 42 uint16_t icmp6_cksum; /* checksum field */ 43 union 44 { 45 uint32_t icmp6_un_data32[1]; /* type-specific field */ 46 uint16_t icmp6_un_data16[2]; /* type-specific field */ 47 uint8_t icmp6_un_data8[4]; /* type-specific field */ 48 } icmp6_dataun; 49 }; 50 51 #define icmp6_data32 icmp6_dataun.icmp6_un_data32 52 #define icmp6_data16 icmp6_dataun.icmp6_un_data16 53 #define icmp6_data8 icmp6_dataun.icmp6_un_data8 54 #define icmp6_pptr icmp6_data32[0] /* parameter prob */ 55 #define icmp6_mtu icmp6_data32[0] /* packet too big */ 56 #define icmp6_id icmp6_data16[0] /* echo request/reply */ 57 #define icmp6_seq icmp6_data16[1] /* echo request/reply */ 58 #define icmp6_maxdelay icmp6_data16[0] /* mcast group membership */ 59 60 #define ICMP6_DST_UNREACH 1 61 #define ICMP6_PACKET_TOO_BIG 2 62 #define ICMP6_TIME_EXCEEDED 3 63 #define ICMP6_PARAM_PROB 4 64 65 #define ICMP6_INFOMSG_MASK 0x80 /* all informational messages */ 66 67 #define ICMP6_ECHO_REQUEST 128 68 #define ICMP6_ECHO_REPLY 129 69 #define MLD_LISTENER_QUERY 130 70 #define MLD_LISTENER_REPORT 131 71 #define MLD_LISTENER_REDUCTION 132 72 #define ICMPV6_EXT_ECHO_REQUEST 160 73 #define ICMPV6_EXT_ECHO_REPLY 161 74 75 #define ICMP6_DST_UNREACH_NOROUTE 0 /* no route to destination */ 76 #define ICMP6_DST_UNREACH_ADMIN 1 /* communication with destination */ 77 /* administratively prohibited */ 78 #define ICMP6_DST_UNREACH_BEYONDSCOPE 2 /* beyond scope of source address */ 79 #define ICMP6_DST_UNREACH_ADDR 3 /* address unreachable */ 80 #define ICMP6_DST_UNREACH_NOPORT 4 /* bad port */ 81 82 #define ICMP6_TIME_EXCEED_TRANSIT 0 /* Hop Limit == 0 in transit */ 83 #define ICMP6_TIME_EXCEED_REASSEMBLY 1 /* Reassembly time out */ 84 85 #define ICMP6_PARAMPROB_HEADER 0 /* erroneous header field */ 86 #define ICMP6_PARAMPROB_NEXTHEADER 1 /* unrecognized Next Header */ 87 #define ICMP6_PARAMPROB_OPTION 2 /* unrecognized IPv6 option */ 88 89 #define ICMP6_FILTER_WILLPASS(type, filterp) \ 90 ((((filterp)->icmp6_filt[(type) >> 5]) & (1U << ((type) & 31))) == 0) 91 92 #define ICMP6_FILTER_WILLBLOCK(type, filterp) \ 93 ((((filterp)->icmp6_filt[(type) >> 5]) & (1U << ((type) & 31))) != 0) 94 95 #define ICMP6_FILTER_SETPASS(type, filterp) \ 96 ((((filterp)->icmp6_filt[(type) >> 5]) &= ~(1U << ((type) & 31)))) 97 98 #define ICMP6_FILTER_SETBLOCK(type, filterp) \ 99 ((((filterp)->icmp6_filt[(type) >> 5]) |= (1U << ((type) & 31)))) 100 101 #define ICMP6_FILTER_SETPASSALL(filterp) \ 102 memset (filterp, 0, sizeof (struct icmp6_filter)); 103 104 #define ICMP6_FILTER_SETBLOCKALL(filterp) \ 105 memset (filterp, 0xFF, sizeof (struct icmp6_filter)); 106 107 #define ND_ROUTER_SOLICIT 133 108 #define ND_ROUTER_ADVERT 134 109 #define ND_NEIGHBOR_SOLICIT 135 110 #define ND_NEIGHBOR_ADVERT 136 111 #define ND_REDIRECT 137 112 113 struct nd_router_solicit /* router solicitation */ 114 { 115 struct icmp6_hdr nd_rs_hdr; 116 /* could be followed by options */ 117 }; 118 119 #define nd_rs_type nd_rs_hdr.icmp6_type 120 #define nd_rs_code nd_rs_hdr.icmp6_code 121 #define nd_rs_cksum nd_rs_hdr.icmp6_cksum 122 #define nd_rs_reserved nd_rs_hdr.icmp6_data32[0] 123 124 struct nd_router_advert /* router advertisement */ 125 { 126 struct icmp6_hdr nd_ra_hdr; 127 uint32_t nd_ra_reachable; /* reachable time */ 128 uint32_t nd_ra_retransmit; /* retransmit timer */ 129 /* could be followed by options */ 130 }; 131 132 #define nd_ra_type nd_ra_hdr.icmp6_type 133 #define nd_ra_code nd_ra_hdr.icmp6_code 134 #define nd_ra_cksum nd_ra_hdr.icmp6_cksum 135 #define nd_ra_curhoplimit nd_ra_hdr.icmp6_data8[0] 136 #define nd_ra_flags_reserved nd_ra_hdr.icmp6_data8[1] 137 #define ND_RA_FLAG_MANAGED 0x80 138 #define ND_RA_FLAG_OTHER 0x40 139 #define ND_RA_FLAG_HOME_AGENT 0x20 140 #define nd_ra_router_lifetime nd_ra_hdr.icmp6_data16[1] 141 142 struct nd_neighbor_solicit /* neighbor solicitation */ 143 { 144 struct icmp6_hdr nd_ns_hdr; 145 struct in6_addr nd_ns_target; /* target address */ 146 /* could be followed by options */ 147 }; 148 149 #define nd_ns_type nd_ns_hdr.icmp6_type 150 #define nd_ns_code nd_ns_hdr.icmp6_code 151 #define nd_ns_cksum nd_ns_hdr.icmp6_cksum 152 #define nd_ns_reserved nd_ns_hdr.icmp6_data32[0] 153 154 struct nd_neighbor_advert /* neighbor advertisement */ 155 { 156 struct icmp6_hdr nd_na_hdr; 157 struct in6_addr nd_na_target; /* target address */ 158 /* could be followed by options */ 159 }; 160 161 #define nd_na_type nd_na_hdr.icmp6_type 162 #define nd_na_code nd_na_hdr.icmp6_code 163 #define nd_na_cksum nd_na_hdr.icmp6_cksum 164 #define nd_na_flags_reserved nd_na_hdr.icmp6_data32[0] 165 #if __BYTE_ORDER == __BIG_ENDIAN 166 #define ND_NA_FLAG_ROUTER 0x80000000 167 #define ND_NA_FLAG_SOLICITED 0x40000000 168 #define ND_NA_FLAG_OVERRIDE 0x20000000 169 #else /* __BYTE_ORDER == __LITTLE_ENDIAN */ 170 #define ND_NA_FLAG_ROUTER 0x00000080 171 #define ND_NA_FLAG_SOLICITED 0x00000040 172 #define ND_NA_FLAG_OVERRIDE 0x00000020 173 #endif 174 175 struct nd_redirect /* redirect */ 176 { 177 struct icmp6_hdr nd_rd_hdr; 178 struct in6_addr nd_rd_target; /* target address */ 179 struct in6_addr nd_rd_dst; /* destination address */ 180 /* could be followed by options */ 181 }; 182 183 #define nd_rd_type nd_rd_hdr.icmp6_type 184 #define nd_rd_code nd_rd_hdr.icmp6_code 185 #define nd_rd_cksum nd_rd_hdr.icmp6_cksum 186 #define nd_rd_reserved nd_rd_hdr.icmp6_data32[0] 187 188 struct nd_opt_hdr /* Neighbor discovery option header */ 189 { 190 uint8_t nd_opt_type; 191 uint8_t nd_opt_len; /* in units of 8 octets */ 192 /* followed by option specific data */ 193 }; 194 195 #define ND_OPT_SOURCE_LINKADDR 1 196 #define ND_OPT_TARGET_LINKADDR 2 197 #define ND_OPT_PREFIX_INFORMATION 3 198 #define ND_OPT_REDIRECTED_HEADER 4 199 #define ND_OPT_MTU 5 200 #define ND_OPT_RTR_ADV_INTERVAL 7 201 #define ND_OPT_HOME_AGENT_INFO 8 202 203 struct nd_opt_prefix_info /* prefix information */ 204 { 205 uint8_t nd_opt_pi_type; 206 uint8_t nd_opt_pi_len; 207 uint8_t nd_opt_pi_prefix_len; 208 uint8_t nd_opt_pi_flags_reserved; 209 uint32_t nd_opt_pi_valid_time; 210 uint32_t nd_opt_pi_preferred_time; 211 uint32_t nd_opt_pi_reserved2; 212 struct in6_addr nd_opt_pi_prefix; 213 }; 214 215 #define ND_OPT_PI_FLAG_ONLINK 0x80 216 #define ND_OPT_PI_FLAG_AUTO 0x40 217 #define ND_OPT_PI_FLAG_RADDR 0x20 218 219 struct nd_opt_rd_hdr /* redirected header */ 220 { 221 uint8_t nd_opt_rh_type; 222 uint8_t nd_opt_rh_len; 223 uint16_t nd_opt_rh_reserved1; 224 uint32_t nd_opt_rh_reserved2; 225 /* followed by IP header and data */ 226 }; 227 228 struct nd_opt_mtu /* MTU option */ 229 { 230 uint8_t nd_opt_mtu_type; 231 uint8_t nd_opt_mtu_len; 232 uint16_t nd_opt_mtu_reserved; 233 uint32_t nd_opt_mtu_mtu; 234 }; 235 236 struct mld_hdr 237 { 238 struct icmp6_hdr mld_icmp6_hdr; 239 struct in6_addr mld_addr; /* multicast address */ 240 }; 241 242 #define mld_type mld_icmp6_hdr.icmp6_type 243 #define mld_code mld_icmp6_hdr.icmp6_code 244 #define mld_cksum mld_icmp6_hdr.icmp6_cksum 245 #define mld_maxdelay mld_icmp6_hdr.icmp6_data16[0] 246 #define mld_reserved mld_icmp6_hdr.icmp6_data16[1] 247 248 #define ICMP6_ROUTER_RENUMBERING 138 249 250 struct icmp6_router_renum /* router renumbering header */ 251 { 252 struct icmp6_hdr rr_hdr; 253 uint8_t rr_segnum; 254 uint8_t rr_flags; 255 uint16_t rr_maxdelay; 256 uint32_t rr_reserved; 257 }; 258 259 #define rr_type rr_hdr.icmp6_type 260 #define rr_code rr_hdr.icmp6_code 261 #define rr_cksum rr_hdr.icmp6_cksum 262 #define rr_seqnum rr_hdr.icmp6_data32[0] 263 264 /* Router renumbering flags */ 265 #define ICMP6_RR_FLAGS_TEST 0x80 266 #define ICMP6_RR_FLAGS_REQRESULT 0x40 267 #define ICMP6_RR_FLAGS_FORCEAPPLY 0x20 268 #define ICMP6_RR_FLAGS_SPECSITE 0x10 269 #define ICMP6_RR_FLAGS_PREVDONE 0x08 270 271 struct rr_pco_match /* match prefix part */ 272 { 273 uint8_t rpm_code; 274 uint8_t rpm_len; 275 uint8_t rpm_ordinal; 276 uint8_t rpm_matchlen; 277 uint8_t rpm_minlen; 278 uint8_t rpm_maxlen; 279 uint16_t rpm_reserved; 280 struct in6_addr rpm_prefix; 281 }; 282 283 /* PCO code values */ 284 #define RPM_PCO_ADD 1 285 #define RPM_PCO_CHANGE 2 286 #define RPM_PCO_SETGLOBAL 3 287 288 struct rr_pco_use /* use prefix part */ 289 { 290 uint8_t rpu_uselen; 291 uint8_t rpu_keeplen; 292 uint8_t rpu_ramask; 293 uint8_t rpu_raflags; 294 uint32_t rpu_vltime; 295 uint32_t rpu_pltime; 296 uint32_t rpu_flags; 297 struct in6_addr rpu_prefix; 298 }; 299 300 #define ICMP6_RR_PCOUSE_RAFLAGS_ONLINK 0x20 301 #define ICMP6_RR_PCOUSE_RAFLAGS_AUTO 0x10 302 303 #if __BYTE_ORDER == __BIG_ENDIAN 304 # define ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME 0x80000000 305 # define ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME 0x40000000 306 #elif __BYTE_ORDER == __LITTLE_ENDIAN 307 # define ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME 0x80 308 # define ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME 0x40 309 #endif 310 311 struct rr_result /* router renumbering result message */ 312 { 313 uint16_t rrr_flags; 314 uint8_t rrr_ordinal; 315 uint8_t rrr_matchedlen; 316 uint32_t rrr_ifid; 317 struct in6_addr rrr_prefix; 318 }; 319 320 #if __BYTE_ORDER == __BIG_ENDIAN 321 # define ICMP6_RR_RESULT_FLAGS_OOB 0x0002 322 # define ICMP6_RR_RESULT_FLAGS_FORBIDDEN 0x0001 323 #elif __BYTE_ORDER == __LITTLE_ENDIAN 324 # define ICMP6_RR_RESULT_FLAGS_OOB 0x0200 325 # define ICMP6_RR_RESULT_FLAGS_FORBIDDEN 0x0100 326 #endif 327 328 /* Mobile IPv6 extension: Advertisement Interval. */ 329 struct nd_opt_adv_interval 330 { 331 uint8_t nd_opt_adv_interval_type; 332 uint8_t nd_opt_adv_interval_len; 333 uint16_t nd_opt_adv_interval_reserved; 334 uint32_t nd_opt_adv_interval_ival; 335 }; 336 337 /* Mobile IPv6 extension: Home Agent Info. */ 338 struct nd_opt_home_agent_info 339 { 340 uint8_t nd_opt_home_agent_info_type; 341 uint8_t nd_opt_home_agent_info_len; 342 uint16_t nd_opt_home_agent_info_reserved; 343 uint16_t nd_opt_home_agent_info_preference; 344 uint16_t nd_opt_home_agent_info_lifetime; 345 }; 346 347 #endif /* netinet/icmpv6.h */ 348