1/*
2 * Copyright (c) 2000-2014 Apple Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28/*
29 * Copyright (c) 1982, 1986, 1990, 1993
30 *	The Regents of the University of California.  All rights reserved.
31 *
32 * Redistribution and use in source and binary forms, with or without
33 * modification, are permitted provided that the following conditions
34 * are met:
35 * 1. Redistributions of source code must retain the above copyright
36 *    notice, this list of conditions and the following disclaimer.
37 * 2. Redistributions in binary form must reproduce the above copyright
38 *    notice, this list of conditions and the following disclaimer in the
39 *    documentation and/or other materials provided with the distribution.
40 * 3. All advertising materials mentioning features or use of this software
41 *    must display the following acknowledgement:
42 *	This product includes software developed by the University of
43 *	California, Berkeley and its contributors.
44 * 4. Neither the name of the University nor the names of its contributors
45 *    may be used to endorse or promote products derived from this software
46 *    without specific prior written permission.
47 *
48 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58 * SUCH DAMAGE.
59 *
60 *	@(#)in_pcb.h	8.1 (Berkeley) 6/10/93
61 * $FreeBSD: src/sys/netinet/in_pcb.h,v 1.32.2.4 2001/08/13 16:26:17 ume Exp $
62 */
63/*
64 * NOTICE: This file was modified by SPARTA, Inc. in 2007 to introduce
65 * support for mandatory and extensible security protections.  This notice
66 * is included in support of clause 2.2 (b) of the Apple Public License,
67 * Version 2.0.
68 */
69
70#ifndef _NETINET_IN_PCB_H_
71#define	_NETINET_IN_PCB_H_
72#include <sys/appleapiopts.h>
73
74#include <sys/types.h>
75#include <sys/queue.h>
76#ifdef BSD_KERNEL_PRIVATE
77#include <sys/bitstring.h>
78#include <sys/tree.h>
79#include <kern/locks.h>
80#include <kern/zalloc.h>
81#endif /* BSD_KERNEL_PRIVATE */
82
83#include <netinet6/ipsec.h> /* for IPSEC */
84#if NECP
85#include <net/necp.h>
86#endif
87
88#if IPSEC
89#include <netinet6/ipsec.h> /* for IPSEC */
90#endif
91
92#ifdef BSD_KERNEL_PRIVATE
93/*
94 * struct inpcb is the common protocol control block structure used in most
95 * IP transport protocols.
96 *
97 * Pointers to local and foreign host table entries, local and foreign socket
98 * numbers, and pointers up (to a socket structure) and down (to a
99 * protocol-specific control block) are stored here.
100 */
101LIST_HEAD(inpcbhead, inpcb);
102LIST_HEAD(inpcbporthead, inpcbport);
103#endif /* BSD_KERNEL_PRIVATE */
104typedef	u_quad_t	inp_gen_t;
105
106/*
107 * PCB with AF_INET6 null bind'ed laddr can receive AF_INET input packet.
108 * So, AF_INET6 null laddr is also used as AF_INET null laddr, by utilizing
109 * the following structure.
110 */
111struct in_addr_4in6 {
112	u_int32_t	ia46_pad32[3];
113	struct	in_addr	ia46_addr4;
114};
115
116#ifdef BSD_KERNEL_PRIVATE
117/*
118 * NB: the zone allocator is type-stable EXCEPT FOR THE FIRST TWO LONGS
119 * of the structure.  Therefore, it is important that the members in
120 * that position not contain any information which is required to be
121 * stable.
122 */
123struct	icmp6_filter;
124#if CONFIG_MACF_NET
125struct	label;
126#endif
127struct ifnet;
128
129struct inp_stat {
130	u_int64_t	rxpackets;
131	u_int64_t	rxbytes;
132	u_int64_t	txpackets;
133	u_int64_t	txbytes;
134};
135
136/*
137 * struct inpcb captures the network layer state for TCP, UDP and raw IPv6
138 * and IPv6 sockets.  In the case of TCP, further per-connection state is
139 * hung off of inp_ppcb most of the time.
140 */
141struct inpcb {
142	decl_lck_mtx_data(, inpcb_mtx);	/* inpcb per-socket mutex */
143	LIST_ENTRY(inpcb) inp_hash;	/* hash list */
144	LIST_ENTRY(inpcb) inp_list;	/* list for all PCBs of this proto */
145	void	*inp_ppcb;		/* pointer to per-protocol pcb */
146	struct inpcbinfo *inp_pcbinfo;	/* PCB list info */
147	struct socket *inp_socket;	/* back pointer to socket */
148	LIST_ENTRY(inpcb) inp_portlist;	/* list for this PCB's local port */
149	RB_ENTRY(inpcb) infc_link;	/* link for flowhash RB tree */
150	struct inpcbport *inp_phd;	/* head of this list */
151	inp_gen_t inp_gencnt;		/* generation count of this instance */
152	int	inp_hash_element;	/* array index of pcb's hash list */
153	int	inp_wantcnt;		/* wanted count; atomically updated */
154	int	inp_state;		/* state (INUSE/CACHED/DEAD) */
155	u_short	inp_fport;		/* foreign port */
156	u_short	inp_lport;		/* local port */
157	u_int32_t inp_flags;		/* generic IP/datagram flags */
158	u_int32_t inp_flags2;		/* generic IP/datagram flags #2 */
159	u_int32_t inp_flow;		/* IPv6 flow information */
160
161	u_char	inp_sndinprog_cnt;	/* outstanding send operations */
162	u_char	inp_vflag;		/* INP_IPV4 or INP_IPV6 */
163
164	u_char inp_ip_ttl;		/* time to live proto */
165	u_char inp_ip_p;		/* protocol proto */
166
167	struct ifnet *inp_boundifp;	/* interface for INP_BOUND_IF */
168	struct ifnet *inp_last_outifp;	/* last known outgoing interface */
169	u_int32_t inp_flowhash;		/* flow hash */
170
171	/* Protocol-dependent part */
172	union {
173		/* foreign host table entry */
174		struct in_addr_4in6 inp46_foreign;
175		struct in6_addr inp6_foreign;
176	} inp_dependfaddr;
177	union {
178		/* local host table entry */
179		struct in_addr_4in6 inp46_local;
180		struct in6_addr inp6_local;
181	} inp_dependladdr;
182	union {
183		/* placeholder for routing entry */
184		struct route inp4_route;
185		struct route_in6 inp6_route;
186	} inp_dependroute;
187	struct {
188		/* type of service proto */
189		u_char inp4_ip_tos;
190		/* IP options */
191		struct mbuf *inp4_options;
192		/* IP multicast options */
193		struct ip_moptions *inp4_moptions;
194	} inp_depend4;
195	struct {
196		/* IP options */
197		struct mbuf *inp6_options;
198		/* IP6 options for outgoing packets */
199		struct	ip6_pktopts *inp6_outputopts;
200		/* IP multicast options */
201		struct	ip6_moptions *inp6_moptions;
202		/* ICMPv6 code type filter */
203		struct	icmp6_filter *inp6_icmp6filt;
204		/* IPV6_CHECKSUM setsockopt */
205		int	inp6_cksum;
206		short	inp6_hops;
207	} inp_depend6;
208
209	caddr_t inp_saved_ppcb;		/* place to save pointer while cached */
210#if CONFIG_MACF_NET
211	struct label *inp_label;	/* MAC label */
212#endif
213#if IPSEC
214	struct inpcbpolicy *inp_sp;	/* for IPSec */
215#endif /* IPSEC */
216#if NECP
217	struct {
218		char *inp_domain;
219		char *inp_account;
220	} inp_necp_attributes;
221	struct necp_inpcb_result inp_policyresult;
222#endif
223	struct inp_stat	*inp_stat;
224	struct inp_stat	*inp_cstat;	/* cellular data */
225	struct inp_stat	*inp_wstat;	/* Wi-Fi data */
226	struct inp_stat	*inp_Wstat;	/* Wired data */
227	u_int8_t inp_stat_store[sizeof (struct inp_stat) + sizeof (u_int64_t)];
228	u_int8_t inp_cstat_store[sizeof (struct inp_stat) + sizeof (u_int64_t)];
229	u_int8_t inp_wstat_store[sizeof (struct inp_stat) + sizeof (u_int64_t)];
230	u_int8_t inp_Wstat_store[sizeof (struct inp_stat) + sizeof (u_int64_t)];
231	uint32_t inp_nstat_refcnt __attribute__((aligned(4)));
232};
233
234#define	INP_ADD_STAT(_inp, _cnt_cellular, _cnt_wifi, _cnt_wired, _a, _n)\
235do {									\
236	locked_add_64(&((_inp)->inp_stat->_a), (_n));			\
237	if (_cnt_cellular)						\
238		locked_add_64(&((_inp)->inp_cstat->_a), (_n));		\
239	if (_cnt_wifi)							\
240		locked_add_64(&((_inp)->inp_wstat->_a), (_n));		\
241	if (_cnt_wired)							\
242		locked_add_64(&((_inp)->inp_Wstat->_a), (_n));		\
243} while (0);
244#endif /* BSD_KERNEL_PRIVATE */
245
246/*
247 * Interface exported to userland by various protocols which use
248 * inpcbs.  Hack alert -- only define if struct xsocket is in scope.
249 */
250#pragma pack(4)
251
252#if defined(__LP64__)
253struct _inpcb_list_entry {
254    u_int32_t	le_next;
255    u_int32_t	le_prev;
256};
257#define	_INPCB_PTR(x)		u_int32_t
258#define	_INPCB_LIST_ENTRY(x)	struct _inpcb_list_entry
259#else /* !__LP64__ */
260#define	_INPCB_PTR(x)		x
261#define	_INPCB_LIST_ENTRY(x)	LIST_ENTRY(x)
262#endif /* !__LP64__ */
263
264#ifdef XNU_KERNEL_PRIVATE
265/*
266 * This is a copy of the inpcb as it shipped in Panther. This structure
267 * is filled out in a copy function. This allows the inpcb to change
268 * without breaking userland tools.
269 *
270 * CAUTION: Many fields may not be filled out. Fewer may be filled out
271 * in the future. Code defensively.
272 */
273struct inpcb_compat {
274#else
275struct inpcbinfo;
276struct inpcbport;
277struct mbuf;
278struct ip6_pktopts;
279struct ip6_moptions;
280struct icmp6_filter;
281struct inpcbpolicy;
282
283struct inpcb {
284#endif /* KERNEL_PRIVATE */
285	_INPCB_LIST_ENTRY(inpcb) inp_hash;	/* hash list */
286	struct in_addr reserved1;		/* reserved */
287	struct in_addr reserved2;		/* reserved */
288	u_short	inp_fport;			/* foreign port */
289	u_short	inp_lport;			/* local port */
290	_INPCB_LIST_ENTRY(inpcb) inp_list;	/* list for all peer PCBs */
291	_INPCB_PTR(caddr_t) inp_ppcb;		/* per-protocol pcb */
292	_INPCB_PTR(struct inpcbinfo *) inp_pcbinfo;	/* PCB list info */
293	_INPCB_PTR(void *) inp_socket;	/* back pointer to socket */
294	u_char nat_owner;		/* Used to NAT TCP/UDP traffic */
295	u_int32_t nat_cookie;		/* Cookie stored and returned to NAT */
296	_INPCB_LIST_ENTRY(inpcb) inp_portlist;	/* this PCB's local port list */
297	_INPCB_PTR(struct inpcbport *) inp_phd; /* head of this list */
298	inp_gen_t inp_gencnt;		/* generation count of this instance */
299	int inp_flags;			/* generic IP/datagram flags */
300	u_int32_t inp_flow;
301
302	u_char inp_vflag;
303
304	u_char inp_ip_ttl;		/* time to live proto */
305	u_char inp_ip_p;		/* protocol proto */
306	/* protocol dependent part */
307	union {
308		/* foreign host table entry */
309		struct in_addr_4in6 inp46_foreign;
310		struct in6_addr inp6_foreign;
311	} inp_dependfaddr;
312	union {
313		/* local host table entry */
314		struct in_addr_4in6 inp46_local;
315		struct in6_addr inp6_local;
316	} inp_dependladdr;
317	union {
318		/* placeholder for routing entry */
319		u_char inp4_route[20];
320		u_char inp6_route[32];
321	} inp_dependroute;
322	struct {
323		/* type of service proto */
324		u_char inp4_ip_tos;
325		/* IP options */
326		_INPCB_PTR(struct mbuf *) inp4_options;
327		/* IP multicast options */
328		_INPCB_PTR(struct ip_moptions *) inp4_moptions;
329	} inp_depend4;
330
331	struct {
332		/* IP options */
333		_INPCB_PTR(struct mbuf *) inp6_options;
334		u_int8_t inp6_hlim;
335		u_int8_t unused_uint8_1;
336		ushort unused_uint16_1;
337		/* IP6 options for outgoing packets */
338		_INPCB_PTR(struct ip6_pktopts *) inp6_outputopts;
339		/* IP multicast options */
340		_INPCB_PTR(struct ip6_moptions *) inp6_moptions;
341		/* ICMPv6 code type filter */
342		_INPCB_PTR(struct icmp6_filter *) inp6_icmp6filt;
343		/* IPV6_CHECKSUM setsockopt */
344		int	inp6_cksum;
345		u_short	inp6_ifindex;
346		short	inp6_hops;
347	} inp_depend6;
348
349	int hash_element;		/* Array index of pcb's hash list */
350	_INPCB_PTR(caddr_t) inp_saved_ppcb; /* pointer while cached */
351	_INPCB_PTR(struct inpcbpolicy *) inp_sp;
352	u_int32_t	reserved[3];	/* reserved */
353};
354
355struct	xinpcb {
356	u_int32_t	xi_len;		/* length of this structure */
357#ifdef XNU_KERNEL_PRIVATE
358	struct	inpcb_compat xi_inp;
359#else
360	struct	inpcb xi_inp;
361#endif
362	struct	xsocket xi_socket;
363	u_quad_t	xi_alignment_hack;
364};
365
366struct inpcb64_list_entry {
367    u_int64_t   le_next;
368    u_int64_t   le_prev;
369};
370
371struct	xinpcb64 {
372	u_int64_t	xi_len;		/* length of this structure */
373	u_int64_t	xi_inpp;
374	u_short		inp_fport;	/* foreign port */
375	u_short		inp_lport;	/* local port */
376	struct inpcb64_list_entry inp_list; /* list for all PCBs */
377	u_int64_t	inp_ppcb;	/* ptr to per-protocol PCB */
378	u_int64_t	inp_pcbinfo;	/* PCB list info */
379	struct inpcb64_list_entry inp_portlist;	/* this PCB's local port list */
380	u_int64_t	inp_phd;	/* head of this list */
381	inp_gen_t	inp_gencnt;	/* current generation count */
382	int		inp_flags;	/* generic IP/datagram flags */
383	u_int32_t	inp_flow;
384	u_char		inp_vflag;
385	u_char		inp_ip_ttl;	/* time to live */
386	u_char		inp_ip_p;	/* protocol */
387	union {				/* foreign host table entry */
388		struct  in_addr_4in6	inp46_foreign;
389		struct  in6_addr	inp6_foreign;
390	} inp_dependfaddr;
391	union {				/* local host table entry */
392		struct  in_addr_4in6	inp46_local;
393		struct  in6_addr	inp6_local;
394	} inp_dependladdr;
395	struct {
396		u_char	inp4_ip_tos;	/* type of service */
397	} inp_depend4;
398	struct {
399		u_int8_t inp6_hlim;
400		int	inp6_cksum;
401		u_short	inp6_ifindex;
402		short	inp6_hops;
403	} inp_depend6;
404	struct  xsocket64 xi_socket;
405	u_quad_t	xi_alignment_hack;
406};
407
408#ifdef PRIVATE
409struct xinpcb_list_entry {
410    u_int64_t   le_next;
411    u_int64_t   le_prev;
412};
413
414struct	xinpcb_n {
415	u_int32_t	xi_len;		/* length of this structure */
416	u_int32_t	xi_kind;	/* XSO_INPCB */
417	u_int64_t	xi_inpp;
418	u_short		inp_fport;	/* foreign port */
419	u_short		inp_lport;	/* local port */
420	u_int64_t	inp_ppcb;	/* pointer to per-protocol pcb */
421	inp_gen_t	inp_gencnt;	/* generation count of this instance */
422	int		inp_flags;	/* generic IP/datagram flags */
423	u_int32_t	inp_flow;
424	u_char		inp_vflag;
425	u_char		inp_ip_ttl;	/* time to live */
426	u_char		inp_ip_p;	/* protocol */
427	union {				/* foreign host table entry */
428		struct in_addr_4in6	inp46_foreign;
429		struct in6_addr		inp6_foreign;
430	} inp_dependfaddr;
431	union {				/* local host table entry */
432		struct in_addr_4in6	inp46_local;
433		struct in6_addr		inp6_local;
434	} inp_dependladdr;
435	struct {
436		u_char	inp4_ip_tos;	/* type of service */
437	} inp_depend4;
438	struct {
439		u_int8_t inp6_hlim;
440		int	inp6_cksum;
441		u_short	inp6_ifindex;
442		short	inp6_hops;
443	} inp_depend6;
444	u_int32_t		inp_flowhash;
445	u_int32_t	inp_flags2;
446};
447#endif /* PRIVATE */
448
449struct	xinpgen {
450	u_int32_t	xig_len;	/* length of this structure */
451	u_int		xig_count;	/* number of PCBs at this time */
452	inp_gen_t	xig_gen;	/* generation count at this time */
453	so_gen_t	xig_sogen;	/* current socket generation count */
454};
455
456#pragma pack()
457
458/*
459 * These defines are for use with the inpcb.
460 */
461#define	INP_IPV4	0x1
462#define	INP_IPV6	0x2
463#define	inp_faddr	inp_dependfaddr.inp46_foreign.ia46_addr4
464#define	inp_laddr	inp_dependladdr.inp46_local.ia46_addr4
465#define	in6p_faddr	inp_dependfaddr.inp6_foreign
466#define	in6p_laddr	inp_dependladdr.inp6_local
467
468#ifdef BSD_KERNEL_PRIVATE
469#define	inp_route	inp_dependroute.inp4_route
470#define	inp_ip_tos	inp_depend4.inp4_ip_tos
471#define	inp_options	inp_depend4.inp4_options
472#define	inp_moptions	inp_depend4.inp4_moptions
473#define	in6p_route	inp_dependroute.inp6_route
474#define	in6p_ip6_hlim	inp_depend6.inp6_hlim
475#define	in6p_hops	inp_depend6.inp6_hops	/* default hop limit */
476#define	in6p_ip6_nxt	inp_ip_p
477#define	in6p_vflag	inp_vflag
478#define	in6p_options	inp_depend6.inp6_options
479#define	in6p_outputopts	inp_depend6.inp6_outputopts
480#define	in6p_moptions	inp_depend6.inp6_moptions
481#define	in6p_icmp6filt	inp_depend6.inp6_icmp6filt
482#define	in6p_cksum	inp_depend6.inp6_cksum
483#define	in6p_ifindex	inp_depend6.inp6_ifindex
484#define	in6p_flags	inp_flags
485#define	in6p_flags2	inp_flags2
486#define	in6p_socket	inp_socket
487#define	in6p_lport	inp_lport
488#define	in6p_fport	inp_fport
489#define	in6p_ppcb	inp_ppcb
490#define	in6p_state	inp_state
491#define	in6p_wantcnt	inp_wantcnt
492#define	in6p_last_outifp inp_last_outifp
493#define	in6pcb		inpcb
494#if IPSEC
495#define	in6p_sp		inp_sp
496#endif /* IPSEC */
497
498struct inpcbport {
499	LIST_ENTRY(inpcbport) phd_hash;
500	struct inpcbhead phd_pcblist;
501	u_short phd_port;
502};
503
504struct intimercount {
505	u_int32_t intimer_lazy;	/* lazy requests for timer scheduling */
506	u_int32_t intimer_fast; /* fast requests, can be coalesced */
507	u_int32_t intimer_nodelay; /* fast requests, never coalesced */
508};
509
510typedef void (*inpcb_timer_func_t)(struct inpcbinfo *);
511
512/*
513 * Global data structure for each high-level protocol (UDP, TCP, ...) in both
514 * IPv4 and IPv6.  Holds inpcb lists and information for managing them.  Each
515 * pcbinfo is protected by a RW lock: ipi_lock.
516 *
517 * All INPCB pcbinfo entries are linked together via ipi_entry.
518 */
519struct inpcbinfo {
520	/*
521	 * Glue to all PCB infos, as well as garbage collector and
522	 * timer callbacks, protected by inpcb_lock.  Callout request
523	 * counts are atomically updated.
524	 */
525	TAILQ_ENTRY(inpcbinfo)	ipi_entry;
526	inpcb_timer_func_t	ipi_gc;
527	inpcb_timer_func_t	ipi_timer;
528	struct intimercount	ipi_gc_req;
529	struct intimercount	ipi_timer_req;
530
531	/*
532	 * Per-protocol lock protecting pcb list, pcb count, etc.
533	 */
534	lck_rw_t		*ipi_lock;
535
536	/*
537	 * List and count of pcbs on the protocol.
538	 */
539	struct inpcbhead	*ipi_listhead;
540	uint32_t		ipi_count;
541
542	/*
543	 * Count of pcbs marked with INP2_TIMEWAIT flag.
544	 */
545	uint32_t		ipi_twcount;
546
547	/*
548	 * Generation count -- incremented each time a connection is
549	 * allocated or freed.
550	 */
551	uint64_t		ipi_gencnt;
552
553	/*
554	 * Fields associated with port lookup and allocation.
555	 */
556	uint16_t		ipi_lastport;
557	uint16_t		ipi_lastlow;
558	uint16_t		ipi_lasthi;
559
560	/*
561	 * Zone from which inpcbs are allocated for this protocol.
562	 */
563	struct zone		*ipi_zone;
564
565	/*
566	 * Per-protocol hash of pcbs, hashed by local and foreign
567	 * addresses and port numbers.
568	 */
569	struct inpcbhead	*ipi_hashbase;
570	u_long			ipi_hashmask;
571
572	/*
573	 * Per-protocol hash of pcbs, hashed by only local port number.
574	 */
575	struct inpcbporthead	*ipi_porthashbase;
576	u_long			ipi_porthashmask;
577
578	/*
579	 * Misc.
580	 */
581	lck_attr_t		*ipi_lock_attr;
582	lck_grp_t		*ipi_lock_grp;
583	lck_grp_attr_t		*ipi_lock_grp_attr;
584};
585
586#define	INP_PCBHASH(faddr, lport, fport, mask) \
587	(((faddr) ^ ((faddr) >> 16) ^ ntohs((lport) ^ (fport))) & (mask))
588#define	INP_PCBPORTHASH(lport, mask) \
589	(ntohs((lport)) & (mask))
590
591#define	INP_IS_FLOW_CONTROLLED(_inp_) \
592	((_inp_)->inp_flags & INP_FLOW_CONTROLLED)
593#define	INP_IS_FLOW_SUSPENDED(_inp_) \
594	(((_inp_)->inp_flags & INP_FLOW_SUSPENDED) ||	\
595	((_inp_)->inp_socket->so_flags & SOF_SUSPENDED))
596#define	INP_WAIT_FOR_IF_FEEDBACK(_inp_) \
597	(((_inp_)->inp_flags & (INP_FLOW_CONTROLLED | INP_FLOW_SUSPENDED)) != 0)
598
599#define INP_NO_CELLULAR(_inp) \
600	((_inp)->inp_flags & INP_NO_IFT_CELLULAR)
601#define INP_NO_EXPENSIVE(_inp) \
602	((_inp)->inp_flags2 & INP2_NO_IFF_EXPENSIVE)
603#define	INP_AWDL_UNRESTRICTED(_inp) \
604	((_inp)->inp_flags2 & INP2_AWDL_UNRESTRICTED)
605
606#endif /* BSD_KERNEL_PRIVATE */
607
608/*
609 * Flags for inp_flags.
610 *
611 * Some of these are publicly defined for legacy reasons, as they are
612 * (unfortunately) used by certain applications to determine, at compile
613 * time, whether or not the OS supports certain features.
614 */
615#ifdef BSD_KERNEL_PRIVATE
616#define	INP_RECVOPTS		0x00000001 /* receive incoming IP options */
617#define	INP_RECVRETOPTS		0x00000002 /* receive IP options for reply */
618#define	INP_RECVDSTADDR		0x00000004 /* receive IP dst address */
619#define	INP_HDRINCL		0x00000008 /* user supplies entire IP header */
620#define	INP_HIGHPORT		0x00000010 /* user wants "high" port binding */
621#define	INP_LOWPORT		0x00000020 /* user wants "low" port binding */
622#endif /* BSD_KERNEL_PRIVATE */
623
624#define	INP_ANONPORT		0x00000040 /* port chosen for user */
625
626#ifdef BSD_KERNEL_PRIVATE
627#define	INP_RECVIF		0x00000080 /* receive incoming interface */
628#define	INP_MTUDISC		0x00000100 /* unused */
629#define	INP_STRIPHDR		0x00000200 /* strip hdrs in raw_ip (for OT) */
630#define	INP_RECV_ANYIF		0x00000400 /* don't restrict inbound iface */
631#define	INP_INADDR_ANY		0x00000800 /* local address wasn't specified */
632#define	INP_IN6ADDR_ANY		INP_INADDR_ANY
633#define	INP_RECVTTL		0x00001000 /* receive incoming IP TTL */
634#define	INP_UDP_NOCKSUM		0x00002000 /* turn off outbound UDP checksum */
635#define	INP_BOUND_IF		0x00004000 /* bind socket to an interface */
636#endif /* BSD_KERNEL_PRIVATE */
637
638#define	IN6P_IPV6_V6ONLY	0x00008000 /* restrict AF_INET6 socket for v6 */
639
640#ifdef BSD_KERNEL_PRIVATE
641#define	IN6P_PKTINFO		0x00010000 /* receive IP6 dst and I/F */
642#define	IN6P_HOPLIMIT		0x00020000 /* receive hoplimit */
643#define	IN6P_HOPOPTS		0x00040000 /* receive hop-by-hop options */
644#define	IN6P_DSTOPTS		0x00080000 /* receive dst options after rthdr */
645#define	IN6P_RTHDR		0x00100000 /* receive routing header */
646#define	IN6P_RTHDRDSTOPTS	0x00200000 /* receive dstoptions before rthdr */
647#define	IN6P_TCLASS		0x00400000 /* receive traffic class value */
648#define	IN6P_AUTOFLOWLABEL	0x00800000 /* attach flowlabel automatically */
649#endif /* BSD_KERNEL_PRIVATE */
650
651#define	IN6P_BINDV6ONLY		0x01000000 /* do not grab IPv4 traffic */
652
653#ifdef BSD_KERNEL_PRIVATE
654#define	IN6P_RFC2292		0x02000000 /* used RFC2292 API on the socket */
655#define	IN6P_MTU		0x04000000 /* receive path MTU */
656#define	INP_PKTINFO		0x08000000 /* rcv and snd PKTINFO for IPv4 */
657#define	INP_FLOW_SUSPENDED	0x10000000 /* flow suspended */
658#define	INP_NO_IFT_CELLULAR	0x20000000 /* do not use cellular interface */
659#define	INP_FLOW_CONTROLLED	0x40000000 /* flow controlled */
660#define	INP_FC_FEEDBACK		0x80000000 /* got interface flow adv feedback */
661
662#define	INP_CONTROLOPTS	\
663	(INP_RECVOPTS|INP_RECVRETOPTS|INP_RECVDSTADDR|INP_RECVIF|INP_RECVTTL| \
664	INP_PKTINFO|IN6P_PKTINFO|IN6P_HOPLIMIT|IN6P_HOPOPTS|IN6P_DSTOPTS| \
665	IN6P_RTHDR|IN6P_RTHDRDSTOPTS|IN6P_TCLASS|IN6P_RFC2292|IN6P_MTU)
666
667#define	INP_UNMAPPABLEOPTS \
668	(IN6P_HOPOPTS|IN6P_DSTOPTS|IN6P_RTHDR| IN6P_TCLASS|IN6P_AUTOFLOWLABEL)
669
670/*
671 * Flags for inp_flags2.
672 *
673 * Overflowed INP flags; use INP2 prefix to avoid misuse.
674 */
675#define	INP2_TIMEWAIT		0x00000001 /* in TIMEWAIT */
676#define	INP2_IN_FCTREE		0x00000002 /* in inp_fc_tree */
677#define	INP2_WANT_APP_POLICY	0x00000004 /* necp app policy check is desired */
678#define	INP2_NO_IFF_EXPENSIVE	0x00000008 /* do not use expensive interface */
679#define	INP2_INHASHLIST		0x00000010 /* pcb is in inp_hash list */
680#define	INP2_AWDL_UNRESTRICTED	0x00000020 /* AWDL restricted mode allowed */
681
682/*
683 * Flags passed to in_pcblookup*() functions.
684 */
685#define	INPLOOKUP_WILDCARD	1
686
687#define	sotoinpcb(so)	((struct inpcb *)(so)->so_pcb)
688#define	sotoin6pcb(so)	sotoinpcb(so)
689
690struct sysctl_req;
691
692extern int ipport_lowfirstauto;
693extern int ipport_lowlastauto;
694extern int ipport_firstauto;
695extern int ipport_lastauto;
696extern int ipport_hifirstauto;
697extern int ipport_hilastauto;
698
699/* freshly allocated PCB, it's in use */
700#define	INPCB_STATE_INUSE	0x1
701/* this pcb is sitting in a a cache */
702#define	INPCB_STATE_CACHED	0x2
703/* should treat as gone, will be garbage collected and freed */
704#define	INPCB_STATE_DEAD	0x3
705
706/* marked as ready to be garbaged collected, should be treated as not found */
707#define	WNT_STOPUSING		0xffff
708/* that pcb is being acquired, do not recycle this time */
709#define	WNT_ACQUIRE		0x1
710/* release acquired mode, can be garbage collected when wantcnt is null */
711#define	WNT_RELEASE		0x2
712
713extern void in_pcbinit(void);
714extern void in_pcbinfo_attach(struct inpcbinfo *);
715extern int in_pcbinfo_detach(struct inpcbinfo *);
716
717/* type of timer to be scheduled by inpcb_gc_sched and inpcb_timer_sched */
718enum {
719	INPCB_TIMER_LAZY = 0x1,
720	INPCB_TIMER_FAST,
721	INPCB_TIMER_NODELAY
722};
723extern void inpcb_gc_sched(struct inpcbinfo *, u_int32_t type);
724extern void inpcb_timer_sched(struct inpcbinfo *, u_int32_t type);
725
726extern void in_losing(struct inpcb *);
727extern void in_rtchange(struct inpcb *, int);
728extern int in_pcballoc(struct socket *, struct inpcbinfo *, struct proc *);
729extern int in_pcbbind(struct inpcb *, struct sockaddr *, struct proc *);
730extern int in_pcbconnect(struct inpcb *, struct sockaddr *, struct proc *,
731    unsigned int, struct ifnet **);
732extern void in_pcbdetach(struct inpcb *);
733extern void in_pcbdispose(struct inpcb *);
734extern void in_pcbdisconnect(struct inpcb *);
735extern int in_pcbinshash(struct inpcb *, int);
736extern int in_pcbladdr(struct inpcb *, struct sockaddr *, struct in_addr *,
737    unsigned int, struct ifnet **);
738extern struct inpcb *in_pcblookup_local(struct inpcbinfo *, struct in_addr,
739    u_int, int);
740extern struct inpcb *in_pcblookup_local_and_cleanup(struct inpcbinfo *,
741    struct in_addr, u_int, int);
742extern struct inpcb *in_pcblookup_hash(struct inpcbinfo *, struct in_addr,
743    u_int, struct in_addr, u_int, int, struct ifnet *);
744extern int in_pcblookup_hash_exists(struct inpcbinfo *, struct in_addr,
745    u_int, struct in_addr, u_int, int, uid_t *, gid_t *, struct ifnet *);
746extern void in_pcbnotifyall(struct inpcbinfo *, struct in_addr, int,
747    void (*)(struct inpcb *, int));
748extern void in_pcbrehash(struct inpcb *);
749extern int in_getpeeraddr(struct socket *, struct sockaddr **);
750extern int in_getpeeraddr_s(struct socket *, struct sockaddr_storage *);
751extern int in_getsockaddr(struct socket *, struct sockaddr **);
752extern int in_getsockaddr_s(struct socket *, struct sockaddr_storage *);
753extern int in_pcb_checkstate(struct inpcb *, int, int);
754extern void in_pcbremlists(struct inpcb *);
755extern void inpcb_to_compat(struct inpcb *, struct inpcb_compat *);
756extern void inpcb_to_xinpcb64(struct inpcb *, struct xinpcb64 *);
757extern int get_pcblist_n(short, struct sysctl_req *, struct inpcbinfo *);
758#define	INPCB_GET_PORTS_USED_WILDCARDOK	0x1
759#define	INPCB_GET_PORTS_USED_NOWAKEUPOK	0x2
760extern void inpcb_get_ports_used(u_int32_t, int, u_int32_t, bitstr_t *,
761    struct inpcbinfo *);
762#define	INPCB_OPPORTUNISTIC_THROTTLEON	0x0001
763#define	INPCB_OPPORTUNISTIC_SETCMD	0x0002
764extern uint32_t inpcb_count_opportunistic(unsigned int, struct inpcbinfo *,
765    u_int32_t);
766extern uint32_t inpcb_find_anypcb_byaddr(struct ifaddr *, struct inpcbinfo *);
767extern void inp_route_copyout(struct inpcb *, struct route *);
768extern void inp_route_copyin(struct inpcb *, struct route *);
769extern int inp_bindif(struct inpcb *, unsigned int, struct ifnet **);
770extern void inp_set_nocellular(struct inpcb *);
771extern void inp_clear_nocellular(struct inpcb *);
772extern void inp_set_noexpensive(struct inpcb *);
773extern void inp_set_awdl_unrestricted(struct inpcb *);
774extern boolean_t inp_get_awdl_unrestricted(struct inpcb *);
775extern void inp_clear_awdl_unrestricted(struct inpcb *);
776#if NECP
777extern void inp_update_necp_policy(struct inpcb *, struct sockaddr *, struct sockaddr *, u_int);
778extern void inp_set_want_app_policy(struct inpcb *);
779extern void inp_clear_want_app_policy(struct inpcb *);
780#endif /* NECP */
781extern u_int32_t inp_calc_flowhash(struct inpcb *);
782extern void inp_reset_fc_state(struct inpcb *);
783extern int inp_set_fc_state(struct inpcb *, int advcode);
784extern void inp_fc_unthrottle_tcp(struct inpcb *);
785extern void inp_flowadv(uint32_t);
786extern int inp_flush(struct inpcb *, int);
787extern int inp_findinpcb_procinfo(struct inpcbinfo *, uint32_t, struct so_procinfo *);
788extern void inp_get_soprocinfo(struct inpcb *, struct so_procinfo *);
789extern int inp_update_policy(struct inpcb *);
790extern boolean_t inp_restricted_recv(struct inpcb *, struct ifnet *);
791extern boolean_t inp_restricted_send(struct inpcb *, struct ifnet *);
792#endif /* BSD_KERNEL_PRIVATE */
793#ifdef KERNEL_PRIVATE
794/* exported for PPP */
795extern void inp_clear_INP_INADDR_ANY(struct socket *);
796#endif /* KERNEL_PRIVATE */
797#endif /* !_NETINET_IN_PCB_H_ */
798