Home | History | Annotate | Download | only in usrsctplib
      1 /*-
      2  * Copyright (c) 1982, 1986, 1990, 1993
      3  *	The Regents of the University of California.  All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      8  * 1. Redistributions of source code must retain the above copyright
      9  *    notice, this list of conditions and the following disclaimer.
     10  * 2. Redistributions in binary form must reproduce the above copyright
     11  *    notice, this list of conditions and the following disclaimer in the
     12  *    documentation and/or other materials provided with the distribution.
     13  * 4. Neither the name of the University nor the names of its contributors
     14  *    may be used to endorse or promote products derived from this software
     15  *    without specific prior written permission.
     16  *
     17  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     27  * SUCH DAMAGE.
     28  *
     29  *	@(#)in_pcb.h	8.1 (Berkeley) 6/10/93
     30  * $FreeBSD: src/sys/netinet/in_pcb.h,v 1.100.2.1 2007/12/07 05:46:08 kmacy Exp $
     31  */
     32 
     33 #ifndef _USER_INPCB_H_
     34 #define _USER_INPCB_H_
     35 
     36 #include <user_route.h> /* was <net/route.h> */
     37 
     38 #define	in6pcb		inpcb	/* for KAME src sync over BSD*'s */
     39 #define	in6p_sp		inp_sp	/* for KAME src sync over BSD*'s */
     40 struct inpcbpolicy;
     41 
     42 /*
     43  * Struct inpcb is the ommon structure pcb for the Internet Protocol
     44  * implementation.
     45  *
     46  * Pointers to local and foreign host table entries, local and foreign socket
     47  * numbers, and pointers up (to a socket structure) and down (to a
     48  * protocol-specific control block) are stored here.
     49  */
     50 LIST_HEAD(inpcbhead, inpcb);
     51 LIST_HEAD(inpcbporthead, inpcbport);
     52 
     53 /*
     54  * PCB with AF_INET6 null bind'ed laddr can receive AF_INET input packet.
     55  * So, AF_INET6 null laddr is also used as AF_INET null laddr, by utilizing
     56  * the following structure.
     57  */
     58 struct in_addr_4in6 {
     59 	u_int32_t	ia46_pad32[3];
     60 	struct	in_addr	ia46_addr4;
     61 };
     62 
     63 /*
     64  * NOTE: ipv6 addrs should be 64-bit aligned, per RFC 2553.  in_conninfo has
     65  * some extra padding to accomplish this.
     66  */
     67 struct in_endpoints {
     68 	u_int16_t	ie_fport;		/* foreign port */
     69 	u_int16_t	ie_lport;		/* local port */
     70 	/* protocol dependent part, local and foreign addr */
     71 	union {
     72 		/* foreign host table entry */
     73 		struct	in_addr_4in6 ie46_foreign;
     74 		struct	in6_addr ie6_foreign;
     75 	} ie_dependfaddr;
     76 	union {
     77 		/* local host table entry */
     78 		struct	in_addr_4in6 ie46_local;
     79 		struct	in6_addr ie6_local;
     80 	} ie_dependladdr;
     81 #define	ie_faddr	ie_dependfaddr.ie46_foreign.ia46_addr4
     82 #define	ie_laddr	ie_dependladdr.ie46_local.ia46_addr4
     83 #define	ie6_faddr	ie_dependfaddr.ie6_foreign
     84 #define	ie6_laddr	ie_dependladdr.ie6_local
     85 };
     86 
     87 /*
     88  * XXX The defines for inc_* are hacks and should be changed to direct
     89  * references.
     90  */
     91 struct in_conninfo {
     92 	u_int8_t	inc_flags;
     93 	u_int8_t	inc_len;
     94 	u_int16_t	inc_pad;	/* XXX alignment for in_endpoints */
     95 	/* protocol dependent part */
     96 	struct	in_endpoints inc_ie;
     97 };
     98 #define inc_isipv6	inc_flags	/* temp compatability */
     99 #define	inc_fport	inc_ie.ie_fport
    100 #define	inc_lport	inc_ie.ie_lport
    101 #define	inc_faddr	inc_ie.ie_faddr
    102 #define	inc_laddr	inc_ie.ie_laddr
    103 #define	inc6_faddr	inc_ie.ie6_faddr
    104 #define	inc6_laddr	inc_ie.ie6_laddr
    105 
    106 struct	icmp6_filter;
    107 
    108 struct inpcb {
    109 	LIST_ENTRY(inpcb) inp_hash;	/* hash list */
    110 	LIST_ENTRY(inpcb) inp_list;	/* list for all PCBs of this proto */
    111 	void	*inp_ppcb;		/* pointer to per-protocol pcb */
    112 	struct	inpcbinfo *inp_pcbinfo;	/* PCB list info */
    113 	struct	socket *inp_socket;	/* back pointer to socket */
    114 
    115 	u_int32_t	inp_flow;
    116 	int	inp_flags;		/* generic IP/datagram flags */
    117 
    118 	u_char	inp_vflag;		/* IP version flag (v4/v6) */
    119 #define	INP_IPV4	0x1
    120 #define	INP_IPV6	0x2
    121 #define	INP_IPV6PROTO	0x4		/* opened under IPv6 protocol */
    122 #define	INP_TIMEWAIT	0x8		/* .. probably doesn't go here */
    123 #define	INP_ONESBCAST	0x10		/* send all-ones broadcast */
    124 #define	INP_DROPPED	0x20		/* protocol drop flag */
    125 #define	INP_SOCKREF	0x40		/* strong socket reference */
    126 #define INP_CONN        0x80
    127 	u_char	inp_ip_ttl;		/* time to live proto */
    128 	u_char	inp_ip_p;		/* protocol proto */
    129 	u_char	inp_ip_minttl;		/* minimum TTL or drop */
    130 	uint32_t inp_ispare1;		/* connection id / queue id */
    131 	void	*inp_pspare[2];		/* rtentry / general use */
    132 
    133 	/* Local and foreign ports, local and foreign addr. */
    134 	struct	in_conninfo inp_inc;
    135 
    136 					/* list for this PCB's local port */
    137 	struct	label *inp_label;	/* MAC label */
    138 	struct	inpcbpolicy *inp_sp;    /* for IPSEC */
    139 
    140 	/* Protocol-dependent part; options. */
    141 	struct {
    142 		u_char	inp4_ip_tos;		/* type of service proto */
    143 		struct	mbuf *inp4_options;	/* IP options */
    144 		struct	ip_moptions *inp4_moptions; /* IP multicast options */
    145 	} inp_depend4;
    146 #define	inp_fport	inp_inc.inc_fport
    147 #define	inp_lport	inp_inc.inc_lport
    148 #define	inp_faddr	inp_inc.inc_faddr
    149 #define	inp_laddr	inp_inc.inc_laddr
    150 #define	inp_ip_tos	inp_depend4.inp4_ip_tos
    151 #define	inp_options	inp_depend4.inp4_options
    152 #define	inp_moptions	inp_depend4.inp4_moptions
    153 	struct {
    154 		/* IP options */
    155 		struct	mbuf *inp6_options;
    156 		/* IP6 options for outgoing packets */
    157 		struct	ip6_pktopts *inp6_outputopts;
    158 		/* IP multicast options */
    159 #if 0
    160 		struct	ip6_moptions *inp6_moptions;
    161 #endif
    162 		/* ICMPv6 code type filter */
    163 		struct	icmp6_filter *inp6_icmp6filt;
    164 		/* IPV6_CHECKSUM setsockopt */
    165 		int	inp6_cksum;
    166 		short	inp6_hops;
    167 	} inp_depend6;
    168 	LIST_ENTRY(inpcb) inp_portlist;
    169 	struct	inpcbport *inp_phd;	/* head of this list */
    170 #define inp_zero_size offsetof(struct inpcb, inp_gencnt)
    171 	struct mtx	inp_mtx;
    172 
    173 #define	in6p_faddr	inp_inc.inc6_faddr
    174 #define	in6p_laddr	inp_inc.inc6_laddr
    175 #define	in6p_hops	inp_depend6.inp6_hops	/* default hop limit */
    176 #define	in6p_ip6_nxt	inp_ip_p
    177 #define	in6p_flowinfo	inp_flow
    178 #define	in6p_vflag	inp_vflag
    179 #define	in6p_options	inp_depend6.inp6_options
    180 #define	in6p_outputopts	inp_depend6.inp6_outputopts
    181 #if 0
    182 #define	in6p_moptions	inp_depend6.inp6_moptions
    183 #endif
    184 #define	in6p_icmp6filt	inp_depend6.inp6_icmp6filt
    185 #define	in6p_cksum	inp_depend6.inp6_cksum
    186 #define	in6p_flags	inp_flags  /* for KAME src sync over BSD*'s */
    187 #define	in6p_socket	inp_socket  /* for KAME src sync over BSD*'s */
    188 #define	in6p_lport	inp_lport  /* for KAME src sync over BSD*'s */
    189 #define	in6p_fport	inp_fport  /* for KAME src sync over BSD*'s */
    190 #define	in6p_ppcb	inp_ppcb  /* for KAME src sync over BSD*'s */
    191 };
    192 /*
    193  * The range of the generation count, as used in this implementation, is 9e19.
    194  * We would have to create 300 billion connections per second for this number
    195  * to roll over in a year.  This seems sufficiently unlikely that we simply
    196  * don't concern ourselves with that possibility.
    197  */
    198 
    199 struct inpcbport {
    200 	LIST_ENTRY(inpcbport) phd_hash;
    201 	struct inpcbhead phd_pcblist;
    202 	u_short phd_port;
    203 };
    204 
    205 /*
    206  * Global data structure for each high-level protocol (UDP, TCP, ...) in both
    207  * IPv4 and IPv6.  Holds inpcb lists and information for managing them.
    208  */
    209 struct inpcbinfo {
    210 	/*
    211 	 * Global list of inpcbs on the protocol.
    212 	 */
    213 	struct inpcbhead	*ipi_listhead;
    214 	u_int			 ipi_count;
    215 
    216 	/*
    217 	 * Global hash of inpcbs, hashed by local and foreign addresses and
    218 	 * port numbers.
    219 	 */
    220 	struct inpcbhead	*ipi_hashbase;
    221 	u_long			 ipi_hashmask;
    222 
    223 	/*
    224 	 * Global hash of inpcbs, hashed by only local port number.
    225 	 */
    226 	struct inpcbporthead	*ipi_porthashbase;
    227 	u_long			 ipi_porthashmask;
    228 
    229 	/*
    230 	 * Fields associated with port lookup and allocation.
    231 	 */
    232 	u_short			 ipi_lastport;
    233 	u_short			 ipi_lastlow;
    234 	u_short			 ipi_lasthi;
    235 
    236 	/*
    237 	 * UMA zone from which inpcbs are allocated for this protocol.
    238 	 */
    239 	struct	uma_zone	*ipi_zone;
    240 
    241 	/*
    242 	 * Generation count--incremented each time a connection is allocated
    243 	 * or freed.
    244 	 */
    245 	struct mtx		 ipi_mtx;
    246 
    247 	/*
    248 	 * vimage 1
    249 	 * general use 1
    250 	 */
    251 	void 			*ipi_pspare[2];
    252 };
    253 
    254 #define INP_LOCK_INIT(inp, d, t) \
    255 	mtx_init(&(inp)->inp_mtx, (d), (t), MTX_DEF | MTX_RECURSE | MTX_DUPOK)
    256 #define INP_LOCK_DESTROY(inp)	mtx_destroy(&(inp)->inp_mtx)
    257 #define INP_LOCK(inp)		mtx_lock(&(inp)->inp_mtx)
    258 #define INP_UNLOCK(inp)		mtx_unlock(&(inp)->inp_mtx)
    259 #define INP_LOCK_ASSERT(inp)	mtx_assert(&(inp)->inp_mtx, MA_OWNED)
    260 #define	INP_UNLOCK_ASSERT(inp)	mtx_assert(&(inp)->inp_mtx, MA_NOTOWNED)
    261 
    262 #define INP_INFO_LOCK_INIT(ipi, d) \
    263 	mtx_init(&(ipi)->ipi_mtx, (d), NULL, MTX_DEF | MTX_RECURSE)
    264 #define INP_INFO_LOCK_DESTROY(ipi)  mtx_destroy(&(ipi)->ipi_mtx)
    265 #define INP_INFO_RLOCK(ipi)	mtx_lock(&(ipi)->ipi_mtx)
    266 #define INP_INFO_WLOCK(ipi)	mtx_lock(&(ipi)->ipi_mtx)
    267 #define INP_INFO_RUNLOCK(ipi)	mtx_unlock(&(ipi)->ipi_mtx)
    268 #define INP_INFO_WUNLOCK(ipi)	mtx_unlock(&(ipi)->ipi_mtx)
    269 #define INP_INFO_RLOCK_ASSERT(ipi)	mtx_assert(&(ipi)->ipi_mtx, MA_OWNED)
    270 #define INP_INFO_WLOCK_ASSERT(ipi)	mtx_assert(&(ipi)->ipi_mtx, MA_OWNED)
    271 #define INP_INFO_UNLOCK_ASSERT(ipi)	mtx_assert(&(ipi)->ipi_mtx, MA_NOTOWNED)
    272 
    273 #define INP_PCBHASH(faddr, lport, fport, mask) \
    274 	(((faddr) ^ ((faddr) >> 16) ^ ntohs((lport) ^ (fport))) & (mask))
    275 #define INP_PCBPORTHASH(lport, mask) \
    276 	(ntohs((lport)) & (mask))
    277 
    278 /* flags in inp_flags: */
    279 #define	INP_RECVOPTS		0x01	/* receive incoming IP options */
    280 #define	INP_RECVRETOPTS		0x02	/* receive IP options for reply */
    281 #define	INP_RECVDSTADDR		0x04	/* receive IP dst address */
    282 #define	INP_HDRINCL		0x08	/* user supplies entire IP header */
    283 #define	INP_HIGHPORT		0x10	/* user wants "high" port binding */
    284 #define	INP_LOWPORT		0x20	/* user wants "low" port binding */
    285 #define	INP_ANONPORT		0x40	/* port chosen for user */
    286 #define	INP_RECVIF		0x80	/* receive incoming interface */
    287 #define	INP_MTUDISC		0x100	/* user can do MTU discovery */
    288 #define	INP_FAITH		0x200	/* accept FAITH'ed connections */
    289 #define	INP_RECVTTL		0x400	/* receive incoming IP TTL */
    290 #define	INP_DONTFRAG		0x800	/* don't fragment packet */
    291 
    292 #define IN6P_IPV6_V6ONLY	0x008000 /* restrict AF_INET6 socket for v6 */
    293 
    294 #define	IN6P_PKTINFO		0x010000 /* receive IP6 dst and I/F */
    295 #define	IN6P_HOPLIMIT		0x020000 /* receive hoplimit */
    296 #define	IN6P_HOPOPTS		0x040000 /* receive hop-by-hop options */
    297 #define	IN6P_DSTOPTS		0x080000 /* receive dst options after rthdr */
    298 #define	IN6P_RTHDR		0x100000 /* receive routing header */
    299 #define	IN6P_RTHDRDSTOPTS	0x200000 /* receive dstoptions before rthdr */
    300 #define	IN6P_TCLASS		0x400000 /* receive traffic class value */
    301 #define	IN6P_AUTOFLOWLABEL	0x800000 /* attach flowlabel automatically */
    302 #define	IN6P_RFC2292		0x40000000 /* used RFC2292 API on the socket */
    303 #define	IN6P_MTU		0x80000000 /* receive path MTU */
    304 
    305 #define	INP_CONTROLOPTS		(INP_RECVOPTS|INP_RECVRETOPTS|INP_RECVDSTADDR|\
    306 				 INP_RECVIF|INP_RECVTTL|\
    307 				 IN6P_PKTINFO|IN6P_HOPLIMIT|IN6P_HOPOPTS|\
    308 				 IN6P_DSTOPTS|IN6P_RTHDR|IN6P_RTHDRDSTOPTS|\
    309 				 IN6P_TCLASS|IN6P_AUTOFLOWLABEL|IN6P_RFC2292|\
    310 				 IN6P_MTU)
    311 #define	INP_UNMAPPABLEOPTS	(IN6P_HOPOPTS|IN6P_DSTOPTS|IN6P_RTHDR|\
    312 				 IN6P_TCLASS|IN6P_AUTOFLOWLABEL)
    313 
    314  /* for KAME src sync over BSD*'s */
    315 #define	IN6P_HIGHPORT		INP_HIGHPORT
    316 #define	IN6P_LOWPORT		INP_LOWPORT
    317 #define	IN6P_ANONPORT		INP_ANONPORT
    318 #define	IN6P_RECVIF		INP_RECVIF
    319 #define	IN6P_MTUDISC		INP_MTUDISC
    320 #define	IN6P_FAITH		INP_FAITH
    321 #define	IN6P_CONTROLOPTS INP_CONTROLOPTS
    322 	/*
    323 	 * socket AF version is {newer than,or include}
    324 	 * actual datagram AF version
    325 	 */
    326 
    327 #define	INPLOOKUP_WILDCARD	1
    328 #define	sotoinpcb(so)	((struct inpcb *)(so)->so_pcb)
    329 #define	sotoin6pcb(so)	sotoinpcb(so) /* for KAME src sync over BSD*'s */
    330 
    331 #define	INP_SOCKAF(so) so->so_proto->pr_domain->dom_family
    332 
    333 #define	INP_CHECK_SOCKAF(so, af)	(INP_SOCKAF(so) == af)
    334 
    335 /* #ifdef _KERNEL */
    336 extern int	ipport_reservedhigh;
    337 extern int	ipport_reservedlow;
    338 extern int	ipport_lowfirstauto;
    339 extern int	ipport_lowlastauto;
    340 extern int	ipport_firstauto;
    341 extern int	ipport_lastauto;
    342 extern int	ipport_hifirstauto;
    343 extern int	ipport_hilastauto;
    344 extern struct callout ipport_tick_callout;
    345 
    346 void	in_pcbpurgeif0(struct inpcbinfo *, struct ifnet *);
    347 int	in_pcballoc(struct socket *, struct inpcbinfo *);
    348 int	in_pcbbind(struct inpcb *, struct sockaddr *, struct ucred *);
    349 int	in_pcbconnect(struct inpcb *, struct sockaddr *, struct ucred *);
    350 void	in_pcbdetach(struct inpcb *);
    351 void	in_pcbdisconnect(struct inpcb *);
    352 void	in_pcbdrop(struct inpcb *);
    353 void	in_pcbfree(struct inpcb *);
    354 int	in_pcbinshash(struct inpcb *);
    355 struct inpcb *
    356 	in_pcblookup_local(struct inpcbinfo *,
    357 	    struct in_addr, u_int, int);
    358 struct inpcb *
    359 	in_pcblookup_hash(struct inpcbinfo *, struct in_addr, u_int,
    360 	    struct in_addr, u_int, int, struct ifnet *);
    361 void	in_pcbnotifyall(struct inpcbinfo *pcbinfo, struct in_addr,
    362 	    int, struct inpcb *(*)(struct inpcb *, int));
    363 void	in_pcbrehash(struct inpcb *);
    364 void	in_pcbsetsolabel(struct socket *so);
    365 int	in_getpeeraddr(struct socket *so, struct sockaddr **nam);
    366 int	in_getsockaddr(struct socket *so, struct sockaddr **nam);
    367 void	in_pcbsosetlabel(struct socket *so);
    368 void	in_pcbremlists(struct inpcb *inp);
    369 void	ipport_tick(void *xtp);
    370 
    371 /*
    372  * Debugging routines compiled in when DDB is present.
    373  */
    374 void	db_print_inpcb(struct inpcb *inp, const char *name, int indent);
    375 
    376 /* #endif  _KERNEL */
    377 
    378 #endif /* !_NETINET_IN_PCB_H_ */
    379