2  * Copyright (c) 2000-2019 Apple Inc. All rights reserved. 
   4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 
   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. 
  15  * Please obtain a copy of the License at 
  16  * http://www.opensource.apple.com/apsl/ and read it before using this file. 
  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. 
  26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 
  29  * Copyright (c) 1982, 1986, 1990, 1993 
  30  *      The Regents of the University of California.  All rights reserved. 
  32  * Redistribution and use in source and binary forms, with or without 
  33  * modification, are permitted provided that the following conditions 
  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. 
  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 
  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 $ 
  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, 
  70 #ifndef _NETINET_IN_PCB_H_ 
  71 #define _NETINET_IN_PCB_H_ 
  72 #include <sys/appleapiopts.h> 
  74 #include <sys/types.h> 
  75 #include <sys/queue.h> 
  76 #ifdef BSD_KERNEL_PRIVATE 
  77 #include <sys/bitstring.h> 
  79 #include <kern/locks.h> 
  80 #include <kern/zalloc.h> 
  81 #include <netinet/in_stat.h> 
  82 #endif /* BSD_KERNEL_PRIVATE */ 
  85 #include <netinet6/ipsec.h> /* for IPSEC */ 
  93 #ifdef BSD_KERNEL_PRIVATE 
  95  * struct inpcb is the common protocol control block structure used in most 
  96  * IP transport protocols. 
  98  * Pointers to local and foreign host table entries, local and foreign socket 
  99  * numbers, and pointers up (to a socket structure) and down (to a 
 100  * protocol-specific control block) are stored here. 
 102 LIST_HEAD(inpcbhead
, inpcb
); 
 103 LIST_HEAD(inpcbporthead
, inpcbport
); 
 104 #endif /* BSD_KERNEL_PRIVATE */ 
 105 typedef u_quad_t        inp_gen_t
; 
 108  * PCB with AF_INET6 null bind'ed laddr can receive AF_INET input packet. 
 109  * So, AF_INET6 null laddr is also used as AF_INET null laddr, by utilizing 
 110  * the following structure. 
 112 struct in_addr_4in6 
{ 
 113         u_int32_t       ia46_pad32
[3]; 
 114         struct  in_addr ia46_addr4
; 
 117 #ifdef BSD_KERNEL_PRIVATE 
 119  * NB: the zone allocator is type-stable EXCEPT FOR THE FIRST TWO LONGS 
 120  * of the structure.  Therefore, it is important that the members in 
 121  * that position not contain any information which is required to be 
 138  * struct inpcb captures the network layer state for TCP, UDP and raw IPv6 
 139  * and IPv6 sockets.  In the case of TCP, further per-connection state is 
 140  * hung off of inp_ppcb most of the time. 
 143         decl_lck_mtx_data(, inpcb_mtx
); /* inpcb per-socket mutex */ 
 144         LIST_ENTRY(inpcb
) inp_hash
;     /* hash list */ 
 145         LIST_ENTRY(inpcb
) inp_list
;     /* list for all PCBs of this proto */ 
 146         void    *inp_ppcb
;              /* pointer to per-protocol pcb */ 
 147         struct inpcbinfo 
*inp_pcbinfo
;  /* PCB list info */ 
 148         struct socket 
*inp_socket
;      /* back pointer to socket */ 
 149         LIST_ENTRY(inpcb
) inp_portlist
; /* list for this PCB's local port */ 
 150         RB_ENTRY(inpcb
) infc_link
;      /* link for flowhash RB tree */ 
 151         struct inpcbport 
*inp_phd
;      /* head of this list */ 
 152         inp_gen_t inp_gencnt
;           /* generation count of this instance */ 
 153         int     inp_hash_element
;       /* array index of pcb's hash list */ 
 154         int     inp_wantcnt
;            /* wanted count; atomically updated */ 
 155         int     inp_state
;              /* state (INUSE/CACHED/DEAD) */ 
 156         u_short inp_fport
;              /* foreign port */ 
 157         u_short inp_lport
;              /* local port */ 
 158         u_int32_t inp_flags
;            /* generic IP/datagram flags */ 
 159         u_int32_t inp_flags2
;           /* generic IP/datagram flags #2 */ 
 160         u_int32_t inp_flow
;             /* IPv6 flow information */ 
 162         u_char  inp_sndinprog_cnt
;      /* outstanding send operations */ 
 163         uint32_t inp_sndingprog_waiters
;/* waiters for outstanding send */ 
 164         u_char  inp_vflag
;              /* INP_IPV4 or INP_IPV6 */ 
 166         u_char inp_ip_ttl
;              /* time to live proto */ 
 167         u_char inp_ip_p
;                /* protocol proto */ 
 169         struct ifnet 
*inp_boundifp
;     /* interface for INP_BOUND_IF */ 
 170         struct ifnet 
*inp_last_outifp
;  /* last known outgoing interface */ 
 171         u_int32_t inp_flowhash
;         /* flow hash */ 
 173         /* Protocol-dependent part */ 
 175                 /* foreign host table entry */ 
 176                 struct in_addr_4in6 inp46_foreign
; 
 177                 struct in6_addr inp6_foreign
; 
 180                 /* local host table entry */ 
 181                 struct in_addr_4in6 inp46_local
; 
 182                 struct in6_addr inp6_local
; 
 185                 /* placeholder for routing entry */ 
 186                 struct route inp4_route
; 
 187                 struct route_in6 inp6_route
; 
 190                 /* type of service proto */ 
 193                 struct mbuf 
*inp4_options
; 
 194                 /* IP multicast options */ 
 195                 struct ip_moptions 
*inp4_moptions
; 
 199                 struct mbuf 
*inp6_options
; 
 200                 /* IP6 options for outgoing packets */ 
 201                 struct  ip6_pktopts 
*inp6_outputopts
; 
 202                 /* IP multicast options */ 
 203                 struct  ip6_moptions 
*inp6_moptions
; 
 204                 /* ICMPv6 code type filter */ 
 205                 struct  icmp6_filter 
*inp6_icmp6filt
; 
 206                 /* IPV6_CHECKSUM setsockopt */ 
 211         caddr_t inp_saved_ppcb
;         /* place to save pointer while cached */ 
 213         struct label 
*inp_label
;        /* MAC label */ 
 216         struct inpcbpolicy 
*inp_sp
;     /* for IPsec */ 
 222         } inp_necp_attributes
; 
 223         struct necp_inpcb_result inp_policyresult
; 
 224         uuid_t necp_client_uuid
; 
 225         necp_client_flow_cb necp_cb
; 
 227         u_char 
*inp_keepalive_data
;     /* for keepalive offload */ 
 228         u_int8_t inp_keepalive_datalen
; /* keepalive data length */ 
 229         u_int8_t inp_keepalive_type
;    /* type of application */ 
 230         u_int16_t inp_keepalive_interval
; /* keepalive interval */ 
 231         uint32_t inp_nstat_refcnt 
__attribute__((aligned(4))); 
 232         struct inp_stat 
*inp_stat
; 
 233         struct inp_stat 
*inp_cstat
;     /* cellular data */ 
 234         struct inp_stat 
*inp_wstat
;     /* Wi-Fi data */ 
 235         struct inp_stat 
*inp_Wstat
;     /* Wired data */ 
 236         u_int8_t inp_stat_store
[sizeof(struct inp_stat
) + sizeof(u_int64_t
)]; 
 237         u_int8_t inp_cstat_store
[sizeof(struct inp_stat
) + sizeof(u_int64_t
)]; 
 238         u_int8_t inp_wstat_store
[sizeof(struct inp_stat
) + sizeof(u_int64_t
)]; 
 239         u_int8_t inp_Wstat_store
[sizeof(struct inp_stat
) + sizeof(u_int64_t
)]; 
 240         activity_bitmap_t inp_nw_activity
; 
 241         u_int64_t inp_start_timestamp
; 
 243         char inp_last_proc_name
[MAXCOMLEN 
+ 1]; 
 244         char inp_e_proc_name
[MAXCOMLEN 
+ 1]; 
 247 #define INP_ADD_STAT(_inp, _cnt_cellular, _cnt_wifi, _cnt_wired, _a, _n) \ 
 249         locked_add_64(&((_inp)->inp_stat->_a), (_n));                   \ 
 251                 locked_add_64(&((_inp)->inp_cstat->_a), (_n));          \ 
 253                 locked_add_64(&((_inp)->inp_wstat->_a), (_n));          \ 
 255                 locked_add_64(&((_inp)->inp_Wstat->_a), (_n));          \ 
 257 #endif /* BSD_KERNEL_PRIVATE */ 
 260  * Interface exported to userland by various protocols which use 
 261  * inpcbs.  Hack alert -- only define if struct xsocket is in scope. 
 265 #if defined(__LP64__) 
 266 struct _inpcb_list_entry 
{ 
 270 #define _INPCB_PTR(x)           u_int32_t 
 271 #define _INPCB_LIST_ENTRY(x)    struct _inpcb_list_entry 
 272 #else /* !__LP64__ */ 
 273 #define _INPCB_PTR(x)           x 
 274 #define _INPCB_LIST_ENTRY(x)    LIST_ENTRY(x) 
 275 #endif /* !__LP64__ */ 
 277 #ifdef XNU_KERNEL_PRIVATE 
 279  * This is a copy of the inpcb as it shipped in Panther. This structure 
 280  * is filled out in a copy function. This allows the inpcb to change 
 281  * without breaking userland tools. 
 283  * CAUTION: Many fields may not be filled out. Fewer may be filled out 
 284  * in the future. Code defensively. 
 286 struct inpcb_compat 
{ 
 297 #endif /* KERNEL_PRIVATE */ 
 298         _INPCB_LIST_ENTRY(inpcb
) inp_hash
;      /* hash list */ 
 299         struct in_addr reserved1
;               /* reserved */ 
 300         struct in_addr reserved2
;               /* reserved */ 
 301         u_short inp_fport
;                      /* foreign port */ 
 302         u_short inp_lport
;                      /* local port */ 
 303         _INPCB_LIST_ENTRY(inpcb
) inp_list
;      /* list for all peer PCBs */ 
 304         _INPCB_PTR(caddr_t
) inp_ppcb
;           /* per-protocol pcb */ 
 305         _INPCB_PTR(struct inpcbinfo 
*) inp_pcbinfo
;     /* PCB list info */ 
 306         _INPCB_PTR(void *) inp_socket
;  /* back pointer to socket */ 
 307         u_char nat_owner
;               /* Used to NAT TCP/UDP traffic */ 
 308         u_int32_t nat_cookie
;           /* Cookie stored and returned to NAT */ 
 309         _INPCB_LIST_ENTRY(inpcb
) inp_portlist
;  /* this PCB's local port list */ 
 310         _INPCB_PTR(struct inpcbport 
*) inp_phd
; /* head of this list */ 
 311         inp_gen_t inp_gencnt
;           /* generation count of this instance */ 
 312         int inp_flags
;                  /* generic IP/datagram flags */ 
 317         u_char inp_ip_ttl
;              /* time to live proto */ 
 318         u_char inp_ip_p
;                /* protocol proto */ 
 319         /* protocol dependent part */ 
 321                 /* foreign host table entry */ 
 322                 struct in_addr_4in6 inp46_foreign
; 
 323                 struct in6_addr inp6_foreign
; 
 326                 /* local host table entry */ 
 327                 struct in_addr_4in6 inp46_local
; 
 328                 struct in6_addr inp6_local
; 
 331                 /* placeholder for routing entry */ 
 332                 u_char inp4_route
[20]; 
 333                 u_char inp6_route
[32]; 
 336                 /* type of service proto */ 
 339                 _INPCB_PTR(struct mbuf 
*) inp4_options
; 
 340                 /* IP multicast options */ 
 341                 _INPCB_PTR(struct ip_moptions 
*) inp4_moptions
; 
 346                 _INPCB_PTR(struct mbuf 
*) inp6_options
; 
 348                 u_int8_t unused_uint8_1
; 
 349                 ushort unused_uint16_1
; 
 350                 /* IP6 options for outgoing packets */ 
 351                 _INPCB_PTR(struct ip6_pktopts 
*) inp6_outputopts
; 
 352                 /* IP multicast options */ 
 353                 _INPCB_PTR(struct ip6_moptions 
*) inp6_moptions
; 
 354                 /* ICMPv6 code type filter */ 
 355                 _INPCB_PTR(struct icmp6_filter 
*) inp6_icmp6filt
; 
 356                 /* IPV6_CHECKSUM setsockopt */ 
 358                 u_short inp6_ifindex
; 
 362         int hash_element
;               /* Array index of pcb's hash list */ 
 363         _INPCB_PTR(caddr_t
) inp_saved_ppcb
; /* pointer while cached */ 
 364         _INPCB_PTR(struct inpcbpolicy 
*) inp_sp
; 
 365         u_int32_t       reserved
[3];    /* reserved */ 
 369         u_int32_t       xi_len
;         /* length of this structure */ 
 370 #ifdef XNU_KERNEL_PRIVATE 
 371         struct  inpcb_compat xi_inp
; 
 375         struct  xsocket xi_socket
; 
 376         u_quad_t        xi_alignment_hack
; 
 380 struct inpcb64_list_entry 
{ 
 386         u_int64_t       xi_len
;         /* length of this structure */ 
 388         u_short         inp_fport
;      /* foreign port */ 
 389         u_short         inp_lport
;      /* local port */ 
 390         struct inpcb64_list_entry inp_list
; /* list for all PCBs */ 
 391         u_int64_t       inp_ppcb
;       /* ptr to per-protocol PCB */ 
 392         u_int64_t       inp_pcbinfo
;    /* PCB list info */ 
 393         struct inpcb64_list_entry inp_portlist
; /* this PCB's local port list */ 
 394         u_int64_t       inp_phd
;        /* head of this list */ 
 395         inp_gen_t       inp_gencnt
;     /* current generation count */ 
 396         int             inp_flags
;      /* generic IP/datagram flags */ 
 399         u_char          inp_ip_ttl
;     /* time to live */ 
 400         u_char          inp_ip_p
;       /* protocol */ 
 401         union {                         /* foreign host table entry */ 
 402                 struct  in_addr_4in6    inp46_foreign
; 
 403                 struct  in6_addr        inp6_foreign
; 
 405         union {                         /* local host table entry */ 
 406                 struct  in_addr_4in6    inp46_local
; 
 407                 struct  in6_addr        inp6_local
; 
 410                 u_char  inp4_ip_tos
;    /* type of service */ 
 415                 u_short inp6_ifindex
; 
 418         struct  xsocket64 xi_socket
; 
 419         u_quad_t        xi_alignment_hack
; 
 421 #endif /* !CONFIG_EMBEDDED */ 
 424 struct xinpcb_list_entry 
{ 
 430         u_int32_t       xi_len
;         /* length of this structure */ 
 431         u_int32_t       xi_kind
;        /* XSO_INPCB */ 
 433         u_short         inp_fport
;      /* foreign port */ 
 434         u_short         inp_lport
;      /* local port */ 
 435         u_int64_t       inp_ppcb
;       /* pointer to per-protocol pcb */ 
 436         inp_gen_t       inp_gencnt
;     /* generation count of this instance */ 
 437         int             inp_flags
;      /* generic IP/datagram flags */ 
 440         u_char          inp_ip_ttl
;     /* time to live */ 
 441         u_char          inp_ip_p
;       /* protocol */ 
 442         union {                         /* foreign host table entry */ 
 443                 struct in_addr_4in6     inp46_foreign
; 
 444                 struct in6_addr         inp6_foreign
; 
 446         union {                         /* local host table entry */ 
 447                 struct in_addr_4in6     inp46_local
; 
 448                 struct in6_addr         inp6_local
; 
 451                 u_char  inp4_ip_tos
;    /* type of service */ 
 456                 u_short inp6_ifindex
; 
 459         u_int32_t               inp_flowhash
; 
 460         u_int32_t       inp_flags2
; 
 465         u_int32_t       xig_len
;        /* length of this structure */ 
 466         u_int           xig_count
;      /* number of PCBs at this time */ 
 467         inp_gen_t       xig_gen
;        /* generation count at this time */ 
 468         so_gen_t        xig_sogen
;      /* current socket generation count */ 
 474  * These defines are for use with the inpcb. 
 478 #define inp_faddr       inp_dependfaddr.inp46_foreign.ia46_addr4 
 479 #define inp_laddr       inp_dependladdr.inp46_local.ia46_addr4 
 480 #define in6p_faddr      inp_dependfaddr.inp6_foreign 
 481 #define in6p_laddr      inp_dependladdr.inp6_local 
 483 #ifdef BSD_KERNEL_PRIVATE 
 484 #define inp_route       inp_dependroute.inp4_route 
 485 #define inp_ip_tos      inp_depend4.inp4_ip_tos 
 486 #define inp_options     inp_depend4.inp4_options 
 487 #define inp_moptions    inp_depend4.inp4_moptions 
 488 #define in6p_route      inp_dependroute.inp6_route 
 489 #define in6p_ip6_hlim   inp_depend6.inp6_hlim 
 490 #define in6p_hops       inp_depend6.inp6_hops   /* default hop limit */ 
 491 #define in6p_ip6_nxt    inp_ip_p 
 492 #define in6p_vflag      inp_vflag 
 493 #define in6p_options    inp_depend6.inp6_options 
 494 #define in6p_outputopts inp_depend6.inp6_outputopts 
 495 #define in6p_moptions   inp_depend6.inp6_moptions 
 496 #define in6p_icmp6filt  inp_depend6.inp6_icmp6filt 
 497 #define in6p_cksum      inp_depend6.inp6_cksum 
 498 #define in6p_ifindex    inp_depend6.inp6_ifindex 
 499 #define in6p_flags      inp_flags 
 500 #define in6p_flags2     inp_flags2 
 501 #define in6p_socket     inp_socket 
 502 #define in6p_lport      inp_lport 
 503 #define in6p_fport      inp_fport 
 504 #define in6p_ppcb       inp_ppcb 
 505 #define in6p_state      inp_state 
 506 #define in6p_wantcnt    inp_wantcnt 
 507 #define in6p_last_outifp inp_last_outifp 
 510 #define in6p_sp         inp_sp 
 512 #define INP_INC_IFNET_STAT(_inp_, _stat_) { \ 
 513         if ((_inp_)->inp_last_outifp != NULL) { \ 
 514                 if ((_inp_)->inp_vflag & INP_IPV6) { \ 
 515                         (_inp_)->inp_last_outifp->if_ipv6_stat->_stat_++;\ 
 517                         (_inp_)->inp_last_outifp->if_ipv4_stat->_stat_++;\ 
 523         LIST_ENTRY(inpcbport
) phd_hash
; 
 524         struct inpcbhead phd_pcblist
; 
 528 struct intimercount 
{ 
 529         u_int32_t intimer_lazy
; /* lazy requests for timer scheduling */ 
 530         u_int32_t intimer_fast
; /* fast requests, can be coalesced */ 
 531         u_int32_t intimer_nodelay
; /* fast requests, never coalesced */ 
 534 typedef void (*inpcb_timer_func_t
)(struct inpcbinfo 
*); 
 537  * Global data structure for each high-level protocol (UDP, TCP, ...) in both 
 538  * IPv4 and IPv6.  Holds inpcb lists and information for managing them.  Each 
 539  * pcbinfo is protected by a RW lock: ipi_lock. 
 541  * All INPCB pcbinfo entries are linked together via ipi_entry. 
 545          * Glue to all PCB infos, as well as garbage collector and 
 546          * timer callbacks, protected by inpcb_lock.  Callout request 
 547          * counts are atomically updated. 
 549         TAILQ_ENTRY(inpcbinfo
)  ipi_entry
; 
 550         inpcb_timer_func_t      ipi_gc
; 
 551         inpcb_timer_func_t      ipi_timer
; 
 552         struct intimercount     ipi_gc_req
; 
 553         struct intimercount     ipi_timer_req
; 
 556          * Per-protocol lock protecting pcb list, pcb count, etc. 
 561          * List and count of pcbs on the protocol. 
 563         struct inpcbhead        
*ipi_listhead
; 
 567          * Count of pcbs marked with INP2_TIMEWAIT flag. 
 569         uint32_t                ipi_twcount
; 
 572          * Generation count -- incremented each time a connection is 
 573          * allocated or freed. 
 578          * Fields associated with port lookup and allocation. 
 580         uint16_t                ipi_lastport
; 
 581         uint16_t                ipi_lastlow
; 
 585          * Zone from which inpcbs are allocated for this protocol. 
 587         struct zone             
*ipi_zone
; 
 590          * Per-protocol hash of pcbs, hashed by local and foreign 
 591          * addresses and port numbers. 
 593         struct inpcbhead        
*ipi_hashbase
; 
 597          * Per-protocol hash of pcbs, hashed by only local port number. 
 599         struct inpcbporthead    
*ipi_porthashbase
; 
 600         u_long                  ipi_porthashmask
; 
 605         lck_attr_t              
*ipi_lock_attr
; 
 606         lck_grp_t               
*ipi_lock_grp
; 
 607         lck_grp_attr_t          
*ipi_lock_grp_attr
; 
 609 #define INPCBINFO_UPDATE_MSS    0x1 
 610 #define INPCBINFO_HANDLE_LQM_ABORT      0x2 
 614 #define INP_PCBHASH(faddr, lport, fport, mask) \ 
 615         (((faddr) ^ ((faddr) >> 16) ^ ntohs((lport) ^ (fport))) & (mask)) 
 616 #define INP_PCBPORTHASH(lport, mask) \ 
 617         (ntohs((lport)) & (mask)) 
 619 #define INP_IS_FLOW_CONTROLLED(_inp_) \ 
 620         ((_inp_)->inp_flags & INP_FLOW_CONTROLLED) 
 621 #define INP_IS_FLOW_SUSPENDED(_inp_) \ 
 622         (((_inp_)->inp_flags & INP_FLOW_SUSPENDED) ||   \ 
 623         ((_inp_)->inp_socket->so_flags & SOF_SUSPENDED)) 
 624 #define INP_WAIT_FOR_IF_FEEDBACK(_inp_) \ 
 625         (((_inp_)->inp_flags & (INP_FLOW_CONTROLLED | INP_FLOW_SUSPENDED)) != 0) 
 627 #define INP_NO_CELLULAR(_inp) \ 
 628         ((_inp)->inp_flags & INP_NO_IFT_CELLULAR) 
 629 #define INP_NO_EXPENSIVE(_inp) \ 
 630         ((_inp)->inp_flags2 & INP2_NO_IFF_EXPENSIVE) 
 631 #define INP_NO_CONSTRAINED(_inp) \ 
 632         ((_inp)->inp_flags2 & INP2_NO_IFF_CONSTRAINED) 
 633 #define INP_AWDL_UNRESTRICTED(_inp) \ 
 634         ((_inp)->inp_flags2 & INP2_AWDL_UNRESTRICTED) 
 635 #define INP_INTCOPROC_ALLOWED(_inp) \ 
 636         ((_inp)->inp_flags2 & INP2_INTCOPROC_ALLOWED) 
 638 #endif /* BSD_KERNEL_PRIVATE */ 
 641  * Flags for inp_flags. 
 643  * Some of these are publicly defined for legacy reasons, as they are 
 644  * (unfortunately) used by certain applications to determine, at compile 
 645  * time, whether or not the OS supports certain features. 
 647 #ifdef BSD_KERNEL_PRIVATE 
 648 #define INP_RECVOPTS            0x00000001 /* receive incoming IP options */ 
 649 #define INP_RECVRETOPTS         0x00000002 /* receive IP options for reply */ 
 650 #define INP_RECVDSTADDR         0x00000004 /* receive IP dst address */ 
 651 #define INP_HDRINCL             0x00000008 /* user supplies entire IP header */ 
 652 #define INP_HIGHPORT            0x00000010 /* user wants "high" port binding */ 
 653 #define INP_LOWPORT             0x00000020 /* user wants "low" port binding */ 
 654 #endif /* BSD_KERNEL_PRIVATE */ 
 656 #define INP_ANONPORT            0x00000040 /* port chosen for user */ 
 658 #ifdef BSD_KERNEL_PRIVATE 
 659 #define INP_RECVIF              0x00000080 /* receive incoming interface */ 
 660 #define INP_MTUDISC             0x00000100 /* unused */ 
 661 #define INP_STRIPHDR            0x00000200 /* strip hdrs in raw_ip (for OT) */ 
 662 #define INP_RECV_ANYIF          0x00000400 /* don't restrict inbound iface */ 
 663 #define INP_INADDR_ANY          0x00000800 /* local address wasn't specified */ 
 664 #define INP_IN6ADDR_ANY         INP_INADDR_ANY 
 665 #define INP_RECVTTL             0x00001000 /* receive incoming IP TTL */ 
 666 #define INP_UDP_NOCKSUM         0x00002000 /* turn off outbound UDP checksum */ 
 667 #define INP_BOUND_IF            0x00004000 /* bind socket to an interface */ 
 668 #endif /* BSD_KERNEL_PRIVATE */ 
 670 #define IN6P_IPV6_V6ONLY        0x00008000 /* restrict AF_INET6 socket for v6 */ 
 672 #ifdef BSD_KERNEL_PRIVATE 
 673 #define IN6P_PKTINFO            0x00010000 /* receive IP6 dst and I/F */ 
 674 #define IN6P_HOPLIMIT           0x00020000 /* receive hoplimit */ 
 675 #define IN6P_HOPOPTS            0x00040000 /* receive hop-by-hop options */ 
 676 #define IN6P_DSTOPTS            0x00080000 /* receive dst options after rthdr */ 
 677 #define IN6P_RTHDR              0x00100000 /* receive routing header */ 
 678 #define IN6P_RTHDRDSTOPTS       0x00200000 /* receive dstoptions before rthdr */ 
 679 #define IN6P_TCLASS             0x00400000 /* receive traffic class value */ 
 680 #define INP_RECVTOS             IN6P_TCLASS     /* receive incoming IP TOS */ 
 681 #define IN6P_AUTOFLOWLABEL      0x00800000 /* attach flowlabel automatically */ 
 682 #endif /* BSD_KERNEL_PRIVATE */ 
 684 #define IN6P_BINDV6ONLY         0x01000000 /* do not grab IPv4 traffic */ 
 686 #ifdef BSD_KERNEL_PRIVATE 
 687 #define IN6P_RFC2292            0x02000000 /* used RFC2292 API on the socket */ 
 688 #define IN6P_MTU                0x04000000 /* receive path MTU */ 
 689 #define INP_PKTINFO             0x08000000 /* rcv and snd PKTINFO for IPv4 */ 
 690 #define INP_FLOW_SUSPENDED      0x10000000 /* flow suspended */ 
 691 #define INP_NO_IFT_CELLULAR     0x20000000 /* do not use cellular interface */ 
 692 #define INP_FLOW_CONTROLLED     0x40000000 /* flow controlled */ 
 693 #define INP_FC_FEEDBACK         0x80000000 /* got interface flow adv feedback */ 
 695 #define INP_CONTROLOPTS \ 
 696         (INP_RECVOPTS|INP_RECVRETOPTS|INP_RECVDSTADDR|INP_RECVIF|INP_RECVTTL| \ 
 697         INP_PKTINFO|IN6P_PKTINFO|IN6P_HOPLIMIT|IN6P_HOPOPTS|IN6P_DSTOPTS| \ 
 698         IN6P_RTHDR|IN6P_RTHDRDSTOPTS|IN6P_TCLASS|IN6P_RFC2292|IN6P_MTU) 
 700 #define INP_UNMAPPABLEOPTS \ 
 701         (IN6P_HOPOPTS|IN6P_DSTOPTS|IN6P_RTHDR|IN6P_AUTOFLOWLABEL) 
 704  * Flags for inp_flags2. 
 706  * Overflowed INP flags; use INP2 prefix to avoid misuse. 
 708 #define INP2_TIMEWAIT           0x00000001 /* in TIMEWAIT */ 
 709 #define INP2_IN_FCTREE          0x00000002 /* in inp_fc_tree */ 
 710 #define INP2_WANT_APP_POLICY    0x00000004 /* necp app policy check is desired */ 
 711 #define INP2_NO_IFF_EXPENSIVE   0x00000008 /* do not use expensive interface */ 
 712 #define INP2_INHASHLIST         0x00000010 /* pcb is in inp_hash list */ 
 713 #define INP2_AWDL_UNRESTRICTED  0x00000020 /* AWDL restricted mode allowed */ 
 714 #define INP2_KEEPALIVE_OFFLOAD  0x00000040 /* Enable UDP or TCP keepalive offload */ 
 715 #define INP2_INTCOPROC_ALLOWED  0x00000080 /* Allow communication via internal co-processor interfaces */ 
 716 #define INP2_CONNECT_IN_PROGRESS        0x00000100 /* A connect call is in progress, so binds are intermediate steps */ 
 717 #define INP2_CLAT46_FLOW        0x00000200 /* The flow is going to use CLAT46 path */ 
 718 #define INP2_EXTERNAL_PORT      0x00000400 /* The port is registered externally, for NECP listeners */ 
 719 #define INP2_NO_IFF_CONSTRAINED 0x00000800 /* do not use constrained interface */ 
 722  * Flags passed to in_pcblookup*() functions. 
 724 #define INPLOOKUP_WILDCARD      1 
 726 #define sotoinpcb(so)   ((struct inpcb *)(so)->so_pcb) 
 727 #define sotoin6pcb(so)  sotoinpcb(so) 
 731 extern int ipport_lowfirstauto
; 
 732 extern int ipport_lowlastauto
; 
 733 extern int ipport_firstauto
; 
 734 extern int ipport_lastauto
; 
 735 extern int ipport_hifirstauto
; 
 736 extern int ipport_hilastauto
; 
 738 /* freshly allocated PCB, it's in use */ 
 739 #define INPCB_STATE_INUSE       0x1 
 740 /* this pcb is sitting in a a cache */ 
 741 #define INPCB_STATE_CACHED      0x2 
 742 /* should treat as gone, will be garbage collected and freed */ 
 743 #define INPCB_STATE_DEAD        0x3 
 745 /* marked as ready to be garbaged collected, should be treated as not found */ 
 746 #define WNT_STOPUSING           0xffff 
 747 /* that pcb is being acquired, do not recycle this time */ 
 748 #define WNT_ACQUIRE             0x1 
 749 /* release acquired mode, can be garbage collected when wantcnt is null */ 
 750 #define WNT_RELEASE             0x2 
 752 extern void in_pcbinit(void); 
 753 extern void in_pcbinfo_attach(struct inpcbinfo 
*); 
 754 extern int in_pcbinfo_detach(struct inpcbinfo 
*); 
 756 /* type of timer to be scheduled by inpcb_gc_sched and inpcb_timer_sched */ 
 758         INPCB_TIMER_LAZY 
= 0x1, 
 762 extern void inpcb_gc_sched(struct inpcbinfo 
*, u_int32_t type
); 
 763 extern void inpcb_timer_sched(struct inpcbinfo 
*, u_int32_t type
); 
 765 extern void in_losing(struct inpcb 
*); 
 766 extern void in_rtchange(struct inpcb 
*, int); 
 767 extern int in_pcballoc(struct socket 
*, struct inpcbinfo 
*, struct proc 
*); 
 768 extern int in_pcbbind(struct inpcb 
*, struct sockaddr 
*, struct proc 
*); 
 769 extern int in_pcbconnect(struct inpcb 
*, struct sockaddr 
*, struct proc 
*, 
 770     unsigned int, struct ifnet 
**); 
 771 extern void in_pcbdetach(struct inpcb 
*); 
 772 extern void in_pcbdispose(struct inpcb 
*); 
 773 extern void in_pcbdisconnect(struct inpcb 
*); 
 774 extern int in_pcbinshash(struct inpcb 
*, int); 
 775 extern int in_pcbladdr(struct inpcb 
*, struct sockaddr 
*, struct in_addr 
*, 
 776     unsigned int, struct ifnet 
**, int); 
 777 extern struct inpcb 
*in_pcblookup_local(struct inpcbinfo 
*, struct in_addr
, 
 779 extern struct inpcb 
*in_pcblookup_local_and_cleanup(struct inpcbinfo 
*, 
 780     struct in_addr
, u_int
, int); 
 781 extern struct inpcb 
*in_pcblookup_hash(struct inpcbinfo 
*, struct in_addr
, 
 782     u_int
, struct in_addr
, u_int
, int, struct ifnet 
*); 
 783 extern int in_pcblookup_hash_exists(struct inpcbinfo 
*, struct in_addr
, 
 784     u_int
, struct in_addr
, u_int
, int, uid_t 
*, gid_t 
*, struct ifnet 
*); 
 785 extern void in_pcbnotifyall(struct inpcbinfo 
*, struct in_addr
, int, 
 786     void (*)(struct inpcb 
*, int)); 
 787 extern void in_pcbrehash(struct inpcb 
*); 
 788 extern int in_getpeeraddr(struct socket 
*, struct sockaddr 
**); 
 789 extern int in_getsockaddr(struct socket 
*, struct sockaddr 
**); 
 790 extern int in_getsockaddr_s(struct socket 
*, struct sockaddr_in 
*); 
 791 extern int in_pcb_checkstate(struct inpcb 
*, int, int); 
 792 extern void in_pcbremlists(struct inpcb 
*); 
 793 extern void inpcb_to_compat(struct inpcb 
*, struct inpcb_compat 
*); 
 795 extern void inpcb_to_xinpcb64(struct inpcb 
*, struct xinpcb64 
*); 
 798 extern int get_pcblist_n(short, struct sysctl_req 
*, struct inpcbinfo 
*); 
 800 extern void inpcb_get_ports_used(u_int32_t
, int, u_int32_t
, bitstr_t 
*, 
 802 #define INPCB_OPPORTUNISTIC_THROTTLEON  0x0001 
 803 #define INPCB_OPPORTUNISTIC_SETCMD      0x0002 
 804 extern uint32_t inpcb_count_opportunistic(unsigned int, struct inpcbinfo 
*, 
 806 extern uint32_t inpcb_find_anypcb_byaddr(struct ifaddr 
*, struct inpcbinfo 
*); 
 807 extern void inp_route_copyout(struct inpcb 
*, struct route 
*); 
 808 extern void inp_route_copyin(struct inpcb 
*, struct route 
*); 
 809 extern int inp_bindif(struct inpcb 
*, unsigned int, struct ifnet 
**); 
 810 extern void inp_set_nocellular(struct inpcb 
*); 
 811 extern void inp_clear_nocellular(struct inpcb 
*); 
 812 extern void inp_set_noexpensive(struct inpcb 
*); 
 813 extern void inp_set_noconstrained(struct inpcb 
*); 
 814 extern void inp_set_awdl_unrestricted(struct inpcb 
*); 
 815 extern boolean_t 
inp_get_awdl_unrestricted(struct inpcb 
*); 
 816 extern void inp_clear_awdl_unrestricted(struct inpcb 
*); 
 817 extern void inp_set_intcoproc_allowed(struct inpcb 
*); 
 818 extern boolean_t 
inp_get_intcoproc_allowed(struct inpcb 
*); 
 819 extern void inp_clear_intcoproc_allowed(struct inpcb 
*); 
 821 extern void inp_update_necp_policy(struct inpcb 
*, struct sockaddr 
*, struct sockaddr 
*, u_int
); 
 822 extern void inp_set_want_app_policy(struct inpcb 
*); 
 823 extern void inp_clear_want_app_policy(struct inpcb 
*); 
 825 extern u_int32_t 
inp_calc_flowhash(struct inpcb 
*); 
 826 extern void inp_reset_fc_state(struct inpcb 
*); 
 827 extern int inp_set_fc_state(struct inpcb 
*, int advcode
); 
 828 extern void inp_fc_unthrottle_tcp(struct inpcb 
*); 
 829 extern void inp_flowadv(uint32_t); 
 830 extern int inp_flush(struct inpcb 
*, int); 
 831 extern int inp_findinpcb_procinfo(struct inpcbinfo 
*, uint32_t, struct so_procinfo 
*); 
 832 extern void inp_get_soprocinfo(struct inpcb 
*, struct so_procinfo 
*); 
 833 extern int inp_update_policy(struct inpcb 
*); 
 834 extern boolean_t 
inp_restricted_recv(struct inpcb 
*, struct ifnet 
*); 
 835 extern boolean_t 
inp_restricted_send(struct inpcb 
*, struct ifnet 
*); 
 836 extern void inp_incr_sndbytes_total(struct socket 
*, int); 
 837 extern void inp_decr_sndbytes_total(struct socket 
*, int); 
 838 extern void inp_count_sndbytes(struct inpcb 
*, u_int32_t
); 
 839 extern void inp_incr_sndbytes_unsent(struct socket 
*, int32_t); 
 840 extern void inp_decr_sndbytes_unsent(struct socket 
*, int32_t); 
 841 extern int32_t inp_get_sndbytes_allunsent(struct socket 
*, u_int32_t
); 
 842 extern void inp_decr_sndbytes_allunsent(struct socket 
*, u_int32_t
); 
 843 extern void inp_set_activity_bitmap(struct inpcb 
*inp
); 
 844 extern void inp_get_activity_bitmap(struct inpcb 
*inp
, activity_bitmap_t 
*b
); 
 845 extern void inp_update_last_owner(struct socket 
*so
, struct proc 
*p
, struct proc 
*ep
); 
 846 extern void inp_copy_last_owner(struct socket 
*so
, struct socket 
*head
); 
 847 #endif /* BSD_KERNEL_PRIVATE */ 
 848 #ifdef KERNEL_PRIVATE 
 849 /* exported for PPP */ 
 850 extern void inp_clear_INP_INADDR_ANY(struct socket 
*); 
 851 #endif /* KERNEL_PRIVATE */ 
 852 #endif /* !_NETINET_IN_PCB_H_ */