| 1 | /*	$NetBSD: in6_var.h,v 1.108 2025/06/27 21:36:23 andvar Exp $	*/ |
| 2 | /*	$KAME: in6_var.h,v 1.81 2002/06/08 11:16:51 itojun Exp $	*/ |
| 3 | |
| 4 | /* |
| 5 | * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. |
| 6 | * All rights reserved. |
| 7 | * |
| 8 | * Redistribution and use in source and binary forms, with or without |
| 9 | * modification, are permitted provided that the following conditions |
| 10 | * are met: |
| 11 | * 1. Redistributions of source code must retain the above copyright |
| 12 | * notice, this list of conditions and the following disclaimer. |
| 13 | * 2. Redistributions in binary form must reproduce the above copyright |
| 14 | * notice, this list of conditions and the following disclaimer in the |
| 15 | * documentation and/or other materials provided with the distribution. |
| 16 | * 3. Neither the name of the project nor the names of its contributors |
| 17 | * may be used to endorse or promote products derived from this software |
| 18 | * without specific prior written permission. |
| 19 | * |
| 20 | * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND |
| 21 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 22 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| 23 | * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE |
| 24 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
| 25 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
| 26 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
| 27 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
| 28 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
| 29 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 30 | * SUCH DAMAGE. |
| 31 | */ |
| 32 | |
| 33 | /* |
| 34 | * Copyright (c) 1985, 1986, 1993 |
| 35 | *	The Regents of the University of California. All rights reserved. |
| 36 | * |
| 37 | * Redistribution and use in source and binary forms, with or without |
| 38 | * modification, are permitted provided that the following conditions |
| 39 | * are met: |
| 40 | * 1. Redistributions of source code must retain the above copyright |
| 41 | * notice, this list of conditions and the following disclaimer. |
| 42 | * 2. Redistributions in binary form must reproduce the above copyright |
| 43 | * notice, this list of conditions and the following disclaimer in the |
| 44 | * documentation and/or other materials provided with the distribution. |
| 45 | * 3. Neither the name of the University nor the names of its contributors |
| 46 | * may be used to endorse or promote products derived from this software |
| 47 | * without specific prior written permission. |
| 48 | * |
| 49 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
| 50 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 51 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| 52 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
| 53 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
| 54 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
| 55 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
| 56 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
| 57 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
| 58 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 59 | * SUCH DAMAGE. |
| 60 | * |
| 61 | *	@(#)in_var.h	8.1 (Berkeley) 6/10/93 |
| 62 | */ |
| 63 | |
| 64 | #ifndef _NETINET6_IN6_VAR_H_ |
| 65 | #define _NETINET6_IN6_VAR_H_ |
| 66 | |
| 67 | #include <sys/callout.h> |
| 68 | #include <sys/ioccom.h> |
| 69 | |
| 70 | /* |
| 71 | * Interface address, Internet version. One of these structures |
| 72 | * is allocated for each interface with an Internet address. |
| 73 | * The ifaddr structure contains the protocol-independent part |
| 74 | * of the structure and is assumed to be first. |
| 75 | */ |
| 76 | |
| 77 | /* |
| 78 | * pltime/vltime are just for future reference (required to implements 2 |
| 79 | * hour rule for hosts). they should never be modified by nd6_timeout or |
| 80 | * anywhere else. |
| 81 | *	userland -> kernel: accept pltime/vltime |
| 82 | *	kernel -> userland: throw up everything |
| 83 | *	in kernel: modify preferred/expire only |
| 84 | */ |
| 85 | struct in6_addrlifetime { |
| 86 | 	time_t ia6t_expire;	/* valid lifetime expiration time */ |
| 87 | 	time_t ia6t_preferred;	/* preferred lifetime expiration time */ |
| 88 | 	u_int32_t ia6t_vltime;	/* valid lifetime */ |
| 89 | 	u_int32_t ia6t_pltime;	/* prefix lifetime */ |
| 90 | }; |
| 91 | |
| 92 | struct lltable; |
| 93 | struct nd_kifinfo; |
| 94 | struct in6_ifextra { |
| 95 | 	struct in6_ifstat *in6_ifstat; |
| 96 | 	struct icmp6_ifstat *icmp6_ifstat; |
| 97 | 	struct nd_kifinfo *nd_ifinfo; |
| 98 | 	struct scope6_id *scope6_id; |
| 99 | 	struct lltable *lltable; |
| 100 | }; |
| 101 | |
| 102 | LIST_HEAD(in6_multihead, in6_multi); |
| 103 | struct	in6_ifaddr { |
| 104 | 	struct	ifaddr ia_ifa;		/* protocol-independent info */ |
| 105 | #define	ia_ifp		ia_ifa.ifa_ifp |
| 106 | #define ia_flags	ia_ifa.ifa_flags |
| 107 | 	struct	sockaddr_in6 ia_addr;	/* interface address */ |
| 108 | 	struct	sockaddr_in6 ia_net;	/* network number of interface */ |
| 109 | 	struct	sockaddr_in6 ia_dstaddr; /* space for destination addr */ |
| 110 | 	struct	sockaddr_in6 ia_prefixmask; /* prefix mask */ |
| 111 | 	u_int32_t ia_plen;		/* prefix length */ |
| 112 | 	/* DEPRECATED. Keep it to avoid breaking kvm(3) users */ |
| 113 | 	struct	in6_ifaddr *ia_next;	/* next in6 list of IP6 addresses */ |
| 114 | 	/* DEPRECATED. Keep it to avoid breaking kvm(3) users */ |
| 115 | 	struct	in6_multihead _ia6_multiaddrs; |
| 116 | 					/* list of multicast addresses */ |
| 117 | 	int	ia6_flags; |
| 118 | |
| 119 | 	struct in6_addrlifetime ia6_lifetime; |
| 120 | 	time_t	ia6_createtime; /* the creation time of this address, which is |
| 121 | 				 * currently used for temporary addresses only. |
| 122 | 				 */ |
| 123 | 	time_t	ia6_updatetime; |
| 124 | |
| 125 | 	/* multicast addresses joined from the kernel */ |
| 126 | 	LIST_HEAD(, in6_multi_mship) ia6_memberships; |
| 127 | |
| 128 | #ifdef _KERNEL |
| 129 | 	struct pslist_entry	ia6_pslist_entry; |
| 130 | #endif |
| 131 | }; |
| 132 | |
| 133 | #ifdef _KERNEL |
| 134 | static __inline void |
| 135 | ia6_acquire(struct in6_ifaddr *ia, struct psref *psref) |
| 136 | { |
| 137 | |
| 138 | 	KASSERT(ia != NULL); |
| 139 | 	ifa_acquire(&ia->ia_ifa, psref); |
| 140 | } |
| 141 | |
| 142 | static __inline void |
| 143 | ia6_release(struct in6_ifaddr *ia, struct psref *psref) |
| 144 | { |
| 145 | |
| 146 | 	if (ia == NULL) |
| 147 | 		return; |
| 148 | 	ifa_release(&ia->ia_ifa, psref); |
| 149 | } |
| 150 | #endif |
| 151 | |
| 152 | /* control structure to manage address selection policy */ |
| 153 | struct in6_addrpolicy { |
| 154 | 	struct sockaddr_in6 addr; /* prefix address */ |
| 155 | 	struct sockaddr_in6 addrmask; /* prefix mask */ |
| 156 | 	int preced;		/* precedence */ |
| 157 | 	int label;		/* matching label */ |
| 158 | 	u_quad_t use;		/* statistics */ |
| 159 | }; |
| 160 | |
| 161 | /* |
| 162 | * IPv6 interface statistics, as defined in RFC2465 Ipv6IfStatsEntry (p12). |
| 163 | */ |
| 164 | struct in6_ifstat { |
| 165 | 	u_quad_t ifs6_in_receive;	/* # of total input datagram */ |
| 166 | 	u_quad_t ifs6_in_hdrerr;	/* # of datagrams with invalid hdr */ |
| 167 | 	u_quad_t ifs6_in_toobig;	/* # of datagrams exceeded MTU */ |
| 168 | 	u_quad_t ifs6_in_noroute;	/* # of datagrams with no route */ |
| 169 | 	u_quad_t ifs6_in_addrerr;	/* # of datagrams with invalid dst */ |
| 170 | 	u_quad_t ifs6_in_protounknown;	/* # of datagrams with unknown proto */ |
| 171 | 					/* NOTE: increment on final dst if */ |
| 172 | 	u_quad_t ifs6_in_truncated;	/* # of truncated datagrams */ |
| 173 | 	u_quad_t ifs6_in_discard;	/* # of discarded datagrams */ |
| 174 | 					/* NOTE: fragment timeout is not here */ |
| 175 | 	u_quad_t ifs6_in_deliver;	/* # of datagrams delivered to ULP */ |
| 176 | 					/* NOTE: increment on final dst if */ |
| 177 | 	u_quad_t ifs6_out_forward;	/* # of datagrams forwarded */ |
| 178 | 					/* NOTE: increment on outgoing if */ |
| 179 | 	u_quad_t ifs6_out_request;	/* # of outgoing datagrams from ULP */ |
| 180 | 					/* NOTE: does not include forwards */ |
| 181 | 	u_quad_t ifs6_out_discard;	/* # of discarded datagrams */ |
| 182 | 	u_quad_t ifs6_out_fragok;	/* # of datagrams fragmented */ |
| 183 | 	u_quad_t ifs6_out_fragfail;	/* # of datagrams failed on fragment */ |
| 184 | 	u_quad_t ifs6_out_fragcreat;	/* # of fragment datagrams */ |
| 185 | 					/* NOTE: this is # after fragment */ |
| 186 | 	u_quad_t ifs6_reass_reqd;	/* # of incoming fragmented packets */ |
| 187 | 					/* NOTE: increment on final dst if */ |
| 188 | 	u_quad_t ifs6_reass_ok;		/* # of reassembled packets */ |
| 189 | 					/* NOTE: this is # after reass */ |
| 190 | 					/* NOTE: increment on final dst if */ |
| 191 | 	u_quad_t ifs6_reass_fail;	/* # of reass failures */ |
| 192 | 					/* NOTE: may not be packet count */ |
| 193 | 					/* NOTE: increment on final dst if */ |
| 194 | 	u_quad_t ifs6_in_mcast;		/* # of inbound multicast datagrams */ |
| 195 | 	u_quad_t ifs6_out_mcast;	/* # of outbound multicast datagrams */ |
| 196 | }; |
| 197 | |
| 198 | /* |
| 199 | * ICMPv6 interface statistics, as defined in RFC2466 Ipv6IfIcmpEntry. |
| 200 | * XXX: I'm not sure if this file is the right place for this structure... |
| 201 | */ |
| 202 | struct icmp6_ifstat { |
| 203 | 	/* |
| 204 | 	 * Input statistics |
| 205 | 	 */ |
| 206 | 	/* ipv6IfIcmpInMsgs, total # of input messages */ |
| 207 | 	u_quad_t ifs6_in_msg; |
| 208 | 	/* ipv6IfIcmpInErrors, # of input error messages */ |
| 209 | 	u_quad_t ifs6_in_error; |
| 210 | 	/* ipv6IfIcmpInDestUnreachs, # of input dest unreach errors */ |
| 211 | 	u_quad_t ifs6_in_dstunreach; |
| 212 | 	/* ipv6IfIcmpInAdminProhibs, # of input administratively prohibited errs */ |
| 213 | 	u_quad_t ifs6_in_adminprohib; |
| 214 | 	/* ipv6IfIcmpInTimeExcds, # of input time exceeded errors */ |
| 215 | 	u_quad_t ifs6_in_timeexceed; |
| 216 | 	/* ipv6IfIcmpInParmProblems, # of input parameter problem errors */ |
| 217 | 	u_quad_t ifs6_in_paramprob; |
| 218 | 	/* ipv6IfIcmpInPktTooBigs, # of input packet too big errors */ |
| 219 | 	u_quad_t ifs6_in_pkttoobig; |
| 220 | 	/* ipv6IfIcmpInEchos, # of input echo requests */ |
| 221 | 	u_quad_t ifs6_in_echo; |
| 222 | 	/* ipv6IfIcmpInEchoReplies, # of input echo replies */ |
| 223 | 	u_quad_t ifs6_in_echoreply; |
| 224 | 	/* ipv6IfIcmpInRouterSolicits, # of input router solicitations */ |
| 225 | 	u_quad_t ifs6_in_routersolicit; |
| 226 | 	/* ipv6IfIcmpInRouterAdvertisements, # of input router advertisements */ |
| 227 | 	u_quad_t ifs6_in_routeradvert; |
| 228 | 	/* ipv6IfIcmpInNeighborSolicits, # of input neighbor solicitations */ |
| 229 | 	u_quad_t ifs6_in_neighborsolicit; |
| 230 | 	/* ipv6IfIcmpInNeighborAdvertisements, # of input neighbor advertisements */ |
| 231 | 	u_quad_t ifs6_in_neighboradvert; |
| 232 | 	/* ipv6IfIcmpInRedirects, # of input redirects */ |
| 233 | 	u_quad_t ifs6_in_redirect; |
| 234 | 	/* ipv6IfIcmpInGroupMembQueries, # of input MLD queries */ |
| 235 | 	u_quad_t ifs6_in_mldquery; |
| 236 | 	/* ipv6IfIcmpInGroupMembResponses, # of input MLD reports */ |
| 237 | 	u_quad_t ifs6_in_mldreport; |
| 238 | 	/* ipv6IfIcmpInGroupMembReductions, # of input MLD done */ |
| 239 | 	u_quad_t ifs6_in_mlddone; |
| 240 | |
| 241 | 	/* |
| 242 | 	 * Output statistics. We should solve unresolved routing problem... |
| 243 | 	 */ |
| 244 | 	/* ipv6IfIcmpOutMsgs, total # of output messages */ |
| 245 | 	u_quad_t ifs6_out_msg; |
| 246 | 	/* ipv6IfIcmpOutErrors, # of output error messages */ |
| 247 | 	u_quad_t ifs6_out_error; |
| 248 | 	/* ipv6IfIcmpOutDestUnreachs, # of output dest unreach errors */ |
| 249 | 	u_quad_t ifs6_out_dstunreach; |
| 250 | 	/* ipv6IfIcmpOutAdminProhibs, # of output administratively prohibited errs */ |
| 251 | 	u_quad_t ifs6_out_adminprohib; |
| 252 | 	/* ipv6IfIcmpOutTimeExcds, # of output time exceeded errors */ |
| 253 | 	u_quad_t ifs6_out_timeexceed; |
| 254 | 	/* ipv6IfIcmpOutParmProblems, # of output parameter problem errors */ |
| 255 | 	u_quad_t ifs6_out_paramprob; |
| 256 | 	/* ipv6IfIcmpOutPktTooBigs, # of output packet too big errors */ |
| 257 | 	u_quad_t ifs6_out_pkttoobig; |
| 258 | 	/* ipv6IfIcmpOutEchos, # of output echo requests */ |
| 259 | 	u_quad_t ifs6_out_echo; |
| 260 | 	/* ipv6IfIcmpOutEchoReplies, # of output echo replies */ |
| 261 | 	u_quad_t ifs6_out_echoreply; |
| 262 | 	/* ipv6IfIcmpOutRouterSolicits, # of output router solicitations */ |
| 263 | 	u_quad_t ifs6_out_routersolicit; |
| 264 | 	/* ipv6IfIcmpOutRouterAdvertisements, # of output router advertisements */ |
| 265 | 	u_quad_t ifs6_out_routeradvert; |
| 266 | 	/* ipv6IfIcmpOutNeighborSolicits, # of output neighbor solicitations */ |
| 267 | 	u_quad_t ifs6_out_neighborsolicit; |
| 268 | 	/* ipv6IfIcmpOutNeighborAdvertisements, # of output neighbor advertisements */ |
| 269 | 	u_quad_t ifs6_out_neighboradvert; |
| 270 | 	/* ipv6IfIcmpOutRedirects, # of output redirects */ |
| 271 | 	u_quad_t ifs6_out_redirect; |
| 272 | 	/* ipv6IfIcmpOutGroupMembQueries, # of output MLD queries */ |
| 273 | 	u_quad_t ifs6_out_mldquery; |
| 274 | 	/* ipv6IfIcmpOutGroupMembResponses, # of output MLD reports */ |
| 275 | 	u_quad_t ifs6_out_mldreport; |
| 276 | 	/* ipv6IfIcmpOutGroupMembReductions, # of output MLD done */ |
| 277 | 	u_quad_t ifs6_out_mlddone; |
| 278 | }; |
| 279 | |
| 280 | /* |
| 281 | * If you make changes that change the size of in6_ifreq, |
| 282 | * make sure you fix compat/netinet6/in6_var.h |
| 283 | */ |
| 284 | struct	in6_ifreq { |
| 285 | 	char	ifr_name[IFNAMSIZ]; |
| 286 | 	union { |
| 287 | 		struct	sockaddr_in6 ifru_addr; |
| 288 | 		struct	sockaddr_in6 ifru_dstaddr; |
| 289 | 		short	ifru_flags; |
| 290 | 		int	ifru_flags6; |
| 291 | 		int	ifru_metric; |
| 292 | 		void *	ifru_data; |
| 293 | 		struct in6_addrlifetime ifru_lifetime; |
| 294 | 		struct in6_ifstat ifru_stat; |
| 295 | 		struct icmp6_ifstat ifru_icmp6stat; |
| 296 | 	} ifr_ifru; |
| 297 | }; |
| 298 | |
| 299 | struct	in6_aliasreq { |
| 300 | 	char	ifra_name[IFNAMSIZ]; |
| 301 | 	struct	sockaddr_in6 ifra_addr; |
| 302 | 	struct	sockaddr_in6 ifra_dstaddr; |
| 303 | 	struct	sockaddr_in6 ifra_prefixmask; |
| 304 | 	int	ifra_flags; |
| 305 | 	struct in6_addrlifetime ifra_lifetime; |
| 306 | }; |
| 307 | |
| 308 | /* |
| 309 | * Given a pointer to an in6_ifaddr (ifaddr), |
| 310 | * return a pointer to the addr as a sockaddr_in6 |
| 311 | */ |
| 312 | #define IA6_IN6(ia)	(&((ia)->ia_addr.sin6_addr)) |
| 313 | #define IA6_DSTIN6(ia)	(&((ia)->ia_dstaddr.sin6_addr)) |
| 314 | #define IA6_MASKIN6(ia)	(&((ia)->ia_prefixmask.sin6_addr)) |
| 315 | #define IA6_SIN6(ia)	(&((ia)->ia_addr)) |
| 316 | #define IA6_DSTSIN6(ia)	(&((ia)->ia_dstaddr)) |
| 317 | #define IFA_IN6(x)	(&((struct sockaddr_in6 *)((x)->ifa_addr))->sin6_addr) |
| 318 | #define IFA_DSTIN6(x)	(&((struct sockaddr_in6 *)((x)->ifa_dstaddr))->sin6_addr) |
| 319 | |
| 320 | #ifdef _KERNEL |
| 321 | #define IN6_ARE_MASKED_ADDR_EQUAL(d, a, m)	(	\ |
| 322 | 	(((d)->s6_addr32[0] ^ (a)->s6_addr32[0]) & (m)->s6_addr32[0]) == 0 && \ |
| 323 | 	(((d)->s6_addr32[1] ^ (a)->s6_addr32[1]) & (m)->s6_addr32[1]) == 0 && \ |
| 324 | 	(((d)->s6_addr32[2] ^ (a)->s6_addr32[2]) & (m)->s6_addr32[2]) == 0 && \ |
| 325 | 	(((d)->s6_addr32[3] ^ (a)->s6_addr32[3]) & (m)->s6_addr32[3]) == 0 ) |
| 326 | #endif |
| 327 | |
| 328 | #define SIOCSIFADDR_IN6		 _IOW('i', 12, struct in6_ifreq) |
| 329 | #define SIOCGIFADDR_IN6		_IOWR('i', 33, struct in6_ifreq) |
| 330 | |
| 331 | #ifdef _KERNEL |
| 332 | /* |
| 333 | * SIOCSxxx ioctls should be unused (see comments in in6.c), but |
| 334 | * we do not shift numbers for binary compatibility. |
| 335 | */ |
| 336 | #define SIOCSIFDSTADDR_IN6	 _IOW('i', 14, struct in6_ifreq) |
| 337 | #define SIOCSIFNETMASK_IN6	 _IOW('i', 22, struct in6_ifreq) |
| 338 | #endif |
| 339 | |
| 340 | #define SIOCGIFDSTADDR_IN6	_IOWR('i', 34, struct in6_ifreq) |
| 341 | #define SIOCGIFNETMASK_IN6	_IOWR('i', 37, struct in6_ifreq) |
| 342 | |
| 343 | #define SIOCDIFADDR_IN6		 _IOW('i', 25, struct in6_ifreq) |
| 344 | /* 26 was OSIOCAIFADDR_IN6 */ |
| 345 | |
| 346 | /* 70 was OSIOCSIFPHYADDR_IN6 */ |
| 347 | #define	SIOCGIFPSRCADDR_IN6	_IOWR('i', 71, struct in6_ifreq) |
| 348 | #define	SIOCGIFPDSTADDR_IN6	_IOWR('i', 72, struct in6_ifreq) |
| 349 | |
| 350 | #define SIOCGIFAFLAG_IN6	_IOWR('i', 73, struct in6_ifreq) |
| 351 | |
| 352 | /* |
| 353 | * 74 was SIOCGDRLST_IN6 |
| 354 | * 75 was SIOCGPRLST_IN6 |
| 355 | * 76 was OSIOCGIFINFO_IN6 |
| 356 | * 77 was SIOCSNDFLUSH_IN6 |
| 357 | */ |
| 358 | #define SIOCGNBRINFO_IN6	_IOWR('i', 78, struct in6_nbrinfo) |
| 359 | /* |
| 360 | * 79 was SIOCSPFXFLUSH_IN6 |
| 361 | * 80 was SIOCSRTRFLUSH_IN6 |
| 362 | * 81 was SIOCGIFALIFETIME_IN6 |
| 363 | */ |
| 364 | #if 0 |
| 365 | /* withdrawn - do not reuse number 82 */ |
| 366 | #define SIOCSIFALIFETIME_IN6	_IOWR('i', 82, struct in6_ifreq) |
| 367 | #endif |
| 368 | #define SIOCGIFSTAT_IN6		_IOWR('i', 83, struct in6_ifreq) |
| 369 | #define SIOCGIFSTAT_ICMP6	_IOWR('i', 84, struct in6_ifreq) |
| 370 | |
| 371 | /* |
| 372 | * 85 was SIOCSDEFIFACE_IN6 |
| 373 | * 86 was SIOCGDEFIFACE_IN6 |
| 374 | * 87 was OSIOCSIFINFO_FLAGS |
| 375 | * 100 was SIOCSIFPREFIX_IN6 |
| 376 | * 101 was SIOCGIFPREFIX_IN6 |
| 377 | * 102 was SIOCDIFPREFIX_IN6 |
| 378 | * 103 was SIOCAIFPREFIX_IN6 |
| 379 | * 104 was SIOCCIFPREFIX_IN6 |
| 380 | * 105 was SIOCSGIFPREFIX_IN6 |
| 381 | */ |
| 382 | #define SIOCGIFALIFETIME_IN6	_IOWR('i', 106, struct in6_ifreq) |
| 383 | #define SIOCAIFADDR_IN6		_IOW('i', 107, struct in6_aliasreq) |
| 384 | /* 108 was OSIOCGIFINFO_IN6_90 |
| 385 | * 109 was OSIOCSIFINFO_IN6_90 */ |
| 386 | #define SIOCSIFPHYADDR_IN6 _IOW('i', 110, struct in6_aliasreq) |
| 387 | /* 110 - 112 are defined in net/if_pppoe.h */ |
| 388 | #define SIOCGIFINFO_IN6		_IOWR('i', 113, struct in6_ndireq) |
| 389 | #define SIOCSIFINFO_IN6		_IOWR('i', 114, struct in6_ndireq) |
| 390 | #define SIOCSIFINFO_FLAGS	_IOWR('i', 115, struct in6_ndireq) |
| 391 | |
| 392 | /* XXX: Someone decided to switch to 'u' here for unknown reasons! */ |
| 393 | #define SIOCGETSGCNT_IN6	_IOWR('u', 106, \ |
| 394 | 				 struct sioc_sg_req6) /* get s,g pkt cnt */ |
| 395 | #define SIOCGETMIFCNT_IN6	_IOWR('u', 107, \ |
| 396 | 				 struct sioc_mif_req6) /* get pkt cnt per if */ |
| 397 | #define SIOCAADDRCTL_POLICY	_IOW('u', 108, struct in6_addrpolicy) |
| 398 | #define SIOCDADDRCTL_POLICY	_IOW('u', 109, struct in6_addrpolicy) |
| 399 | |
| 400 | #define IN6_IFF_ANYCAST		0x01	/* anycast address */ |
| 401 | #define IN6_IFF_TENTATIVE	0x02	/* tentative address */ |
| 402 | #define IN6_IFF_DUPLICATED	0x04	/* DAD detected duplicate */ |
| 403 | #define IN6_IFF_DETACHED	0x08	/* may be detached from the link */ |
| 404 | #define IN6_IFF_DEPRECATED	0x10	/* deprecated address */ |
| 405 | #define IN6_IFF_NODAD		0x20	/* don't perform DAD on this address |
| 406 | 					 * (used only at first SIOC* call) |
| 407 | 					 */ |
| 408 | #define IN6_IFF_AUTOCONF	0x40	/* autoconfigurable address. */ |
| 409 | #define IN6_IFF_TEMPORARY	0x80	/* temporary (anonymous) address. */ |
| 410 | |
| 411 | #define IN6_IFFBITS \ |
| 412 | "\020\1ANYCAST\2TENTATIVE\3DUPLICATED\4DETACHED\5DEPRECATED\6NODAD" \ |
| 413 | "\7AUTOCONF\10TEMPORARY" |
| 414 | |
| 415 | |
| 416 | /* do not input/output */ |
| 417 | #define IN6_IFF_NOTREADY (IN6_IFF_TENTATIVE|IN6_IFF_DUPLICATED) |
| 418 | |
| 419 | #ifdef _KERNEL |
| 420 | #define IN6_ARE_SCOPE_CMP(a,b) ((a)-(b)) |
| 421 | #define IN6_ARE_SCOPE_EQUAL(a,b) ((a)==(b)) |
| 422 | #endif |
| 423 | |
| 424 | #ifdef _KERNEL |
| 425 | |
| 426 | #include <sys/mutex.h> |
| 427 | #include <sys/pserialize.h> |
| 428 | |
| 429 | #include <net/pktqueue.h> |
| 430 | |
| 431 | extern pktqueue_t *ip6_pktq; |
| 432 | |
| 433 | MALLOC_DECLARE(M_IP6OPT); |
| 434 | |
| 435 | extern struct pslist_head	in6_ifaddr_list; |
| 436 | extern kmutex_t			in6_ifaddr_lock; |
| 437 | |
| 438 | #define IN6_ADDRLIST_ENTRY_INIT(__ia) \ |
| 439 | 	PSLIST_ENTRY_INIT((__ia), ia6_pslist_entry) |
| 440 | #define IN6_ADDRLIST_ENTRY_DESTROY(__ia) \ |
| 441 | 	PSLIST_ENTRY_DESTROY((__ia), ia6_pslist_entry) |
| 442 | #define IN6_ADDRLIST_READER_EMPTY() \ |
| 443 | 	(PSLIST_READER_FIRST(&in6_ifaddr_list, struct in6_ifaddr, \ |
| 444 | 	 ia6_pslist_entry) == NULL) |
| 445 | #define IN6_ADDRLIST_READER_FIRST() \ |
| 446 | 	PSLIST_READER_FIRST(&in6_ifaddr_list, struct in6_ifaddr, \ |
| 447 | 	 ia6_pslist_entry) |
| 448 | #define IN6_ADDRLIST_READER_NEXT(__ia) \ |
| 449 | 	PSLIST_READER_NEXT((__ia), struct in6_ifaddr, ia6_pslist_entry) |
| 450 | #define IN6_ADDRLIST_READER_FOREACH(__ia) \ |
| 451 | 	PSLIST_READER_FOREACH((__ia), &in6_ifaddr_list, \ |
| 452 | 	 struct in6_ifaddr, ia6_pslist_entry) |
| 453 | #define IN6_ADDRLIST_WRITER_INSERT_HEAD(__ia) \ |
| 454 | 	PSLIST_WRITER_INSERT_HEAD(&in6_ifaddr_list, (__ia), ia6_pslist_entry) |
| 455 | #define IN6_ADDRLIST_WRITER_REMOVE(__ia) \ |
| 456 | 	PSLIST_WRITER_REMOVE((__ia), ia6_pslist_entry) |
| 457 | #define IN6_ADDRLIST_WRITER_FOREACH(__ia) \ |
| 458 | 	PSLIST_WRITER_FOREACH((__ia), &in6_ifaddr_list, struct in6_ifaddr, \ |
| 459 | 	 ia6_pslist_entry) |
| 460 | #define IN6_ADDRLIST_WRITER_FIRST() \ |
| 461 | 	PSLIST_WRITER_FIRST(&in6_ifaddr_list, struct in6_ifaddr, \ |
| 462 | 	 ia6_pslist_entry) |
| 463 | #define IN6_ADDRLIST_WRITER_NEXT(__ia) \ |
| 464 | 	PSLIST_WRITER_NEXT((__ia), struct in6_ifaddr, ia6_pslist_entry) |
| 465 | #define IN6_ADDRLIST_WRITER_INSERT_AFTER(__ia, __new) \ |
| 466 | 	PSLIST_WRITER_INSERT_AFTER((__ia), (__new), ia6_pslist_entry) |
| 467 | #define IN6_ADDRLIST_WRITER_EMPTY() \ |
| 468 | 	(PSLIST_WRITER_FIRST(&in6_ifaddr_list, struct in6_ifaddr, \ |
| 469 | 	 ia6_pslist_entry) == NULL) |
| 470 | #define IN6_ADDRLIST_WRITER_INSERT_TAIL(__new)				\ |
| 471 | 	do {								\ |
| 472 | 		if (IN6_ADDRLIST_WRITER_EMPTY()) {			\ |
| 473 | 			IN6_ADDRLIST_WRITER_INSERT_HEAD((__new));	\ |
| 474 | 		} else {						\ |
| 475 | 			struct in6_ifaddr *__ia;			\ |
| 476 | 			IN6_ADDRLIST_WRITER_FOREACH(__ia) {		\ |
| 477 | 				if (IN6_ADDRLIST_WRITER_NEXT(__ia) == NULL) { \ |
| 478 | 					IN6_ADDRLIST_WRITER_INSERT_AFTER(__ia,\ |
| 479 | 					 (__new));			\ |
| 480 | 					break;				\ |
| 481 | 				}					\ |
| 482 | 			}						\ |
| 483 | 		}							\ |
| 484 | 	} while (0) |
| 485 | |
| 486 | #define in6_ifstat_inc(ifp, tag) \ |
| 487 | do {								\ |
| 488 | 	if (ifp)						\ |
| 489 | 		((struct in6_ifextra *)((ifp)->if_afdata[AF_INET6]))->in6_ifstat->tag++; \ |
| 490 | } while (/*CONSTCOND*/ 0) |
| 491 | |
| 492 | extern const struct in6_addr zeroin6_addr; |
| 493 | extern const u_char inet6ctlerrmap[]; |
| 494 | extern bool in6_present; |
| 495 | #endif /* _KERNEL */ |
| 496 | |
| 497 | /* |
| 498 | * Multi-cast membership entry. One for each group/ifp that a PCB |
| 499 | * belongs to. |
| 500 | */ |
| 501 | struct in6_multi_mship { |
| 502 | 	struct	in6_multi *i6mm_maddr;	/* Multicast address pointer */ |
| 503 | 	LIST_ENTRY(in6_multi_mship) i6mm_chain; /* multicast options chain */ |
| 504 | }; |
| 505 | |
| 506 | struct	in6_multi { |
| 507 | 	LIST_ENTRY(in6_multi) in6m_entry; /* list glue */ |
| 508 | 	struct	in6_addr in6m_addr;	/* IP6 multicast address */ |
| 509 | 	struct	ifnet *in6m_ifp;	/* back pointer to ifnet */ |
| 510 | 	/* DEPRECATED. Keep it to avoid breaking kvm(3) users */ |
| 511 | 	struct	in6_ifaddr *_in6m_ia;	/* back pointer to in6_ifaddr */ |
| 512 | 	u_int	in6m_refcount;		/* # membership claims by sockets */ |
| 513 | 	u_int	in6m_state;		/* state of the membership */ |
| 514 | 	int	in6m_timer;		/* delay to send the 1st report */ |
| 515 | 	struct timeval in6m_timer_expire; /* when the timer expires */ |
| 516 | 	callout_t in6m_timer_ch; |
| 517 | }; |
| 518 | |
| 519 | #define IN6M_TIMER_UNDEF -1 |
| 520 | |
| 521 | |
| 522 | #ifdef _KERNEL |
| 523 | /* flags to in6_update_ifa */ |
| 524 | #define IN6_IFAUPDATE_DADDELAY	0x1 /* first time to configure an address */ |
| 525 | |
| 526 | #if 0 |
| 527 | /* |
| 528 | * Macros for looking up the in6_multi_mship record for a given IP6 multicast |
| 529 | * address on a given interface. If no matching record is found, "imm" |
| 530 | * returns NULL. |
| 531 | */ |
| 532 | static __inline struct in6_multi_mship * |
| 533 | in6_lookup_mship(struct in6_addr *addr, struct ifnet *ifp, |
| 534 | struct ip6_moptions *imop) |
| 535 | { |
| 536 | 	struct in6_multi_mship *imm; |
| 537 | |
| 538 | 	LIST_FOREACH(imm, &imop->im6o_memberships, i6mm_chain) { |
| 539 | 		if (imm->i6mm_maddr->in6m_ifp != ifp) |
| 540 | 		 	continue; |
| 541 | 		if (IN6_ARE_ADDR_EQUAL(&imm->i6mm_maddr->in6m_addr, |
| 542 | 		 addr)) |
| 543 | 			break; |
| 544 | 	} |
| 545 | 	return imm; |
| 546 | } |
| 547 | |
| 548 | #define IN6_LOOKUP_MSHIP(__addr, __ifp, __imop, __imm)			\ |
| 549 | /* struct in6_addr __addr; */						\ |
| 550 | /* struct ifnet *__ifp; */						\ |
| 551 | /* struct ip6_moptions *__imop */					\ |
| 552 | /* struct in6_multi_mship *__imm; */					\ |
| 553 | do {									\ |
| 554 | 	(__imm) = in6_lookup_mship(&(__addr), (__ifp), (__imop));	\ |
| 555 | } while (/*CONSTCOND*/ 0) |
| 556 | #endif |
| 557 | |
| 558 | void	in6_init(void); |
| 559 | |
| 560 | void	in6_multi_lock(int); |
| 561 | void	in6_multi_unlock(void); |
| 562 | bool	in6_multi_locked(int); |
| 563 | struct in6_multi * |
| 564 | 	in6_lookup_multi(const struct in6_addr *, const struct ifnet *); |
| 565 | bool	in6_multi_group(const struct in6_addr *, const struct ifnet *); |
| 566 | void	in6_purge_multi(struct ifnet *); |
| 567 | struct	in6_multi *in6_addmulti(struct in6_addr *, struct ifnet *, |
| 568 | 	int *, int); |
| 569 | void	in6_delmulti(struct in6_multi *); |
| 570 | void	in6_delmulti_locked(struct in6_multi *); |
| 571 | void	in6_lookup_and_delete_multi(const struct in6_addr *, |
| 572 | 	 const struct ifnet *); |
| 573 | struct in6_multi_mship *in6_joingroup(struct ifnet *, struct in6_addr *, |
| 574 | 	int *, int); |
| 575 | int	in6_leavegroup(struct in6_multi_mship *); |
| 576 | int	in6_mask2len(struct in6_addr *, u_char *); |
| 577 | int	in6_control(struct socket *, u_long, void *, struct ifnet *); |
| 578 | int	in6_update_ifa(struct ifnet *, struct in6_aliasreq *, int); |
| 579 | void	in6_purgeaddr(struct ifaddr *); |
| 580 | void	in6_purgeif(struct ifnet *); |
| 581 | void	*in6_domifattach(struct ifnet *); |
| 582 | void	in6_domifdetach(struct ifnet *, void *); |
| 583 | void	in6_ifremlocal(struct ifaddr *); |
| 584 | void	in6_ifaddlocal(struct ifaddr *); |
| 585 | struct in6_ifaddr * |
| 586 | 	in6ifa_ifpforlinklocal(const struct ifnet *, int); |
| 587 | struct in6_ifaddr * |
| 588 | 	in6ifa_ifpforlinklocal_psref(const struct ifnet *, int, struct psref *); |
| 589 | struct in6_ifaddr * |
| 590 | 	in6ifa_ifpwithaddr(const struct ifnet *, const struct in6_addr *); |
| 591 | struct in6_ifaddr * |
| 592 | 	in6ifa_ifpwithaddr_psref(const struct ifnet *, const struct in6_addr *, |
| 593 | 	 struct psref *); |
| 594 | struct in6_ifaddr *in6ifa_ifwithaddr(const struct in6_addr *, uint32_t); |
| 595 | struct ifaddr * |
| 596 | 	in6ifa_first_lladdr(const struct ifnet *); |
| 597 | struct ifaddr * |
| 598 | 	in6ifa_first_lladdr_psref(const struct ifnet *, struct psref *); |
| 599 | |
| 600 | int	in6_matchlen(struct in6_addr *, struct in6_addr *); |
| 601 | void	in6_prefixlen2mask(struct in6_addr *, int); |
| 602 | void	in6_purge_mcast_references(struct in6_multi *); |
| 603 | |
| 604 | int	ip6flow_fastforward(struct mbuf **); /* IPv6 fast forward routine */ |
| 605 | |
| 606 | int in6_src_ioctl(u_long, void *); |
| 607 | int	in6_is_addr_deprecated(struct sockaddr_in6 *); |
| 608 | struct in6pcb; |
| 609 | |
| 610 | #define	LLTABLE6(ifp)	(((struct in6_ifextra *)(ifp)->if_afdata[AF_INET6])->lltable) |
| 611 | |
| 612 | void	in6_sysctl_multicast_setup(struct sysctllog **); |
| 613 | |
| 614 | #endif /* _KERNEL */ |
| 615 | |
| 616 | #endif /* !_NETINET6_IN6_VAR_H_ */ |