Home | History | Annotate | Line # | Download | only in netinet
      1 /*	$NetBSD: in_pcb.h,v 1.76 2022/11/04 09:03:20 ozaki-r Exp $	*/
      2 
      3 /*
      4  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
      5  * All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  * 3. Neither the name of the project nor the names of its contributors
     16  *    may be used to endorse or promote products derived from this software
     17  *    without specific prior written permission.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
     20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
     23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     29  * SUCH DAMAGE.
     30  */
     31 
     32 /*
     33  * Copyright (c) 1982, 1986, 1990, 1993
     34  *	The Regents of the University of California.  All rights reserved.
     35  *
     36  * Redistribution and use in source and binary forms, with or without
     37  * modification, are permitted provided that the following conditions
     38  * are met:
     39  * 1. Redistributions of source code must retain the above copyright
     40  *    notice, this list of conditions and the following disclaimer.
     41  * 2. Redistributions in binary form must reproduce the above copyright
     42  *    notice, this list of conditions and the following disclaimer in the
     43  *    documentation and/or other materials provided with the distribution.
     44  * 3. 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  */
     62 
     63 #ifndef _NETINET_IN_PCB_H_
     64 #define _NETINET_IN_PCB_H_
     65 
     66 #include <sys/types.h>
     67 
     68 #include <net/route.h>
     69 
     70 #include <netinet/in.h>
     71 #include <netinet/ip.h>
     72 #include <netinet/ip6.h>
     73 
     74 typedef int (*pcb_overudp_cb_t)(struct mbuf **, int, struct socket *,
     75     struct sockaddr *, void *);
     76 
     77 struct ip_moptions;
     78 struct mbuf;
     79 struct icmp6_filter;
     80 
     81 /*
     82  * Common structure pcb for internet protocol implementation.
     83  * Here are stored pointers to local and foreign host table
     84  * entries, local and foreign socket numbers, and pointers
     85  * up (to a socket structure) and down (to a protocol-specific)
     86  * control block.
     87  */
     88 
     89 struct inpcb {
     90 	LIST_ENTRY(inpcb) inp_hash;
     91 	LIST_ENTRY(inpcb) inp_lhash;
     92 	TAILQ_ENTRY(inpcb) inp_queue;
     93 	int	  inp_af;		/* address family - AF_INET or AF_INET6 */
     94 	void *	  inp_ppcb;		/* pointer to per-protocol pcb */
     95 	int	  inp_state;		/* bind/connect state */
     96 #define	INP_ATTACHED		0
     97 #define	INP_BOUND		1
     98 #define	INP_CONNECTED		2
     99 	int       inp_portalgo;
    100 	struct	  socket *inp_socket;	/* back pointer to socket */
    101 	struct	  inpcbtable *inp_table;
    102 	struct	  inpcbpolicy *inp_sp;	/* security policy */
    103 	struct route	inp_route;	/* placeholder for routing entry */
    104 	in_port_t	inp_fport;	/* foreign port */
    105 	in_port_t	inp_lport;	/* local port */
    106 	int	 	inp_flags;	/* generic IP/datagram flags */
    107 	struct mbuf	*inp_options;	/* IP options */
    108 	bool		inp_bindportonsend;
    109 
    110 	/* We still need it for IPv6 due to v4-mapped addresses */
    111 	struct ip_moptions *inp_moptions;	/* IPv4 multicast options */
    112 
    113 	pcb_overudp_cb_t	inp_overudp_cb;
    114 	void		*inp_overudp_arg;
    115 };
    116 
    117 struct in4pcb {
    118 	struct inpcb	in4p_pcb;
    119 	struct ip	in4p_ip;
    120 	int		in4p_errormtu;	/* MTU of last xmit status = EMSGSIZE */
    121 	uint8_t		in4p_ip_minttl;
    122 	struct in_addr	in4p_prefsrcip; /* preferred src IP when wild  */
    123 };
    124 
    125 #define in4p_faddr(inpcb)	(((struct in4pcb *)(inpcb))->in4p_ip.ip_dst)
    126 #define in4p_laddr(inpcb)	(((struct in4pcb *)(inpcb))->in4p_ip.ip_src)
    127 #define const_in4p_faddr(inpcb)	(((const struct in4pcb *)(inpcb))->in4p_ip.ip_dst)
    128 #define const_in4p_laddr(inpcb)	(((const struct in4pcb *)(inpcb))->in4p_ip.ip_src)
    129 #define in4p_ip(inpcb)		(((struct in4pcb *)(inpcb))->in4p_ip)
    130 #define in4p_errormtu(inpcb)	(((struct in4pcb *)(inpcb))->in4p_errormtu)
    131 #define in4p_ip_minttl(inpcb)	(((struct in4pcb *)(inpcb))->in4p_ip_minttl)
    132 #define in4p_prefsrcip(inpcb)	(((struct in4pcb *)(inpcb))->in4p_prefsrcip)
    133 
    134 struct in6pcb {
    135 	struct inpcb	in6p_pcb;
    136 	struct ip6_hdr	in6p_ip6;
    137 	int		in6p_hops;	/* default IPv6 hop limit */
    138 	int		in6p_cksum;	/* IPV6_CHECKSUM setsockopt */
    139 	struct icmp6_filter	*in6p_icmp6filt;
    140 	struct ip6_pktopts	*in6p_outputopts; /* IP6 options for outgoing packets */
    141 	struct ip6_moptions *in6p_moptions;	/* IPv6 multicast options */
    142 };
    143 
    144 #define in6p_faddr(inpcb)	(((struct in6pcb *)(inpcb))->in6p_ip6.ip6_dst)
    145 #define in6p_laddr(inpcb)	(((struct in6pcb *)(inpcb))->in6p_ip6.ip6_src)
    146 #define const_in6p_faddr(inpcb)	(((const struct in6pcb *)(inpcb))->in6p_ip6.ip6_dst)
    147 #define const_in6p_laddr(inpcb)	(((const struct in6pcb *)(inpcb))->in6p_ip6.ip6_src)
    148 #define in6p_ip6(inpcb)		(((struct in6pcb *)(inpcb))->in6p_ip6)
    149 #define in6p_flowinfo(inpcb)	(((struct in6pcb *)(inpcb))->in6p_ip6.ip6_flow)
    150 #define const_in6p_flowinfo(inpcb)	(((const struct in6pcb *)(inpcb))->in6p_ip6.ip6_flow)
    151 #define in6p_hops6(inpcb)	(((struct in6pcb *)(inpcb))->in6p_hops)
    152 #define in6p_cksum(inpcb)	(((struct in6pcb *)(inpcb))->in6p_cksum)
    153 #define in6p_icmp6filt(inpcb)	(((struct in6pcb *)(inpcb))->in6p_icmp6filt)
    154 #define in6p_outputopts(inpcb)	(((struct in6pcb *)(inpcb))->in6p_outputopts)
    155 #define in6p_moptions(inpcb)	(((struct in6pcb *)(inpcb))->in6p_moptions)
    156 
    157 LIST_HEAD(inpcbhead, inpcb);
    158 
    159 /* flags in inp_flags: */
    160 #define	INP_RECVOPTS		0x0001	/* receive incoming IP options */
    161 #define	INP_RECVRETOPTS		0x0002	/* receive IP options for reply */
    162 #define	INP_RECVDSTADDR		0x0004	/* receive IP dst address */
    163 #define	INP_HDRINCL		0x0008	/* user supplies entire IP header */
    164 #define	INP_HIGHPORT		0x0010	/* (unused; FreeBSD compat) */
    165 #define	INP_LOWPORT		0x0020	/* user wants "low" port binding */
    166 #define	INP_ANONPORT		0x0040	/* port chosen for user */
    167 #define	INP_RECVIF		0x0080	/* receive incoming interface */
    168 /* XXX should move to an UDP control block */
    169 #define INP_ESPINUDP		0x0100	/* ESP over UDP for NAT-T */
    170 #define INP_ESPINUDP_NON_IKE	0x0200	/* ESP over UDP for NAT-T */
    171 #define INP_NOHEADER		0x0400	/* Kernel removes IP header
    172 					 * before feeding a packet
    173 					 * to the raw socket user.
    174 					 * The socket user will
    175 					 * not supply an IP header.
    176 					 * Cancels INP_HDRINCL.
    177 					 */
    178 #define	INP_RECVTTL		0x0800	/* receive incoming IP TTL */
    179 #define	INP_RECVPKTINFO		0x1000	/* receive IP dst if/addr */
    180 #define	INP_BINDANY		0x2000	/* allow bind to any address */
    181 #define	INP_CONTROLOPTS		(INP_RECVOPTS|INP_RECVRETOPTS|INP_RECVDSTADDR|\
    182 				INP_RECVIF|INP_RECVTTL|INP_RECVPKTINFO)
    183 
    184 /*
    185  * Flags for IPv6 in inp_flags
    186  * We define KAME's original flags in higher 16 bits as much as possible
    187  * for compatibility with *bsd*s.
    188  */
    189 #define IN6P_RECVOPTS		0x00001000 /* receive incoming IP6 options */
    190 #define IN6P_RECVRETOPTS	0x00002000 /* receive IP6 options for reply */
    191 #define IN6P_RECVDSTADDR	0x00004000 /* receive IP6 dst address */
    192 #define IN6P_IPV6_V6ONLY	0x00008000 /* restrict AF_INET6 socket for v6 */
    193 #define IN6P_PKTINFO		0x00010000 /* receive IP6 dst and I/F */
    194 #define IN6P_HOPLIMIT		0x00020000 /* receive hoplimit */
    195 #define IN6P_HOPOPTS		0x00040000 /* receive hop-by-hop options */
    196 #define IN6P_DSTOPTS		0x00080000 /* receive dst options after rthdr */
    197 #define IN6P_RTHDR		0x00100000 /* receive routing header */
    198 #define IN6P_RTHDRDSTOPTS	0x00200000 /* receive dstoptions before rthdr */
    199 #define IN6P_TCLASS		0x00400000 /* traffic class */
    200 #define IN6P_BINDANY		0x00800000 /* allow bind to any address */
    201 #define IN6P_HIGHPORT		0x01000000 /* user wants "high" port binding */
    202 #define IN6P_LOWPORT		0x02000000 /* user wants "low" port binding */
    203 #define IN6P_ANONPORT		0x04000000 /* port chosen for user */
    204 #define IN6P_FAITH		0x08000000 /* accept FAITH'ed connections */
    205 /* XXX should move to an UDP control block */
    206 #define IN6P_ESPINUDP		INP_ESPINUDP /* ESP over UDP for NAT-T */
    207 
    208 #define IN6P_RFC2292		0x40000000 /* RFC2292 */
    209 #define IN6P_MTU		0x80000000 /* use minimum MTU */
    210 
    211 #define IN6P_CONTROLOPTS	(IN6P_PKTINFO|IN6P_HOPLIMIT|IN6P_HOPOPTS|\
    212 				 IN6P_DSTOPTS|IN6P_RTHDR|IN6P_RTHDRDSTOPTS|\
    213 				 IN6P_TCLASS|IN6P_RFC2292|\
    214 				 IN6P_MTU)
    215 
    216 #define	sotoinpcb(so)		((struct inpcb *)(so)->so_pcb)
    217 #define soaf(so) 		(so->so_proto->pr_domain->dom_family)
    218 #define	inp_lock(inp)		solock((inp)->inp_socket)
    219 #define	inp_unlock(inp)		sounlock((inp)->inp_socket)
    220 #define	inp_locked(inp)		solocked((inp)->inp_socket)
    221 
    222 TAILQ_HEAD(inpcbqueue, inpcb);
    223 
    224 struct vestigial_hooks;
    225 
    226 /* It's still referenced by kvm users */
    227 struct inpcbtable {
    228 	struct	  inpcbqueue inpt_queue;
    229 	struct	  inpcbhead *inpt_porthashtbl;
    230 	struct	  inpcbhead *inpt_bindhashtbl;
    231 	struct	  inpcbhead *inpt_connecthashtbl;
    232 	u_long	  inpt_porthash;
    233 	u_long	  inpt_bindhash;
    234 	u_long	  inpt_connecthash;
    235 	in_port_t inpt_lastport;
    236 	in_port_t inpt_lastlow;
    237 
    238 	struct vestigial_hooks *vestige;
    239 };
    240 #define inpt_lasthi inpt_lastport
    241 
    242 #ifdef _KERNEL
    243 
    244 #include <sys/kauth.h>
    245 #include <sys/queue.h>
    246 
    247 struct lwp;
    248 struct rtentry;
    249 struct sockaddr_in;
    250 struct socket;
    251 struct vestigial_inpcb;
    252 
    253 void	inpcb_losing(struct inpcb *);
    254 int	inpcb_create(struct socket *, void *);
    255 int	inpcb_bindableaddr(const struct inpcb *, struct sockaddr_in *,
    256     kauth_cred_t);
    257 int	inpcb_bind(void *, struct sockaddr_in *, struct lwp *);
    258 int	inpcb_connect(void *, struct sockaddr_in *, struct lwp *);
    259 void	inpcb_destroy(void *);
    260 void	inpcb_disconnect(void *);
    261 void	inpcb_init(struct inpcbtable *, int, int);
    262 struct inpcb *
    263 	inpcb_lookup_local(struct inpcbtable *,
    264 			  struct in_addr, u_int, int, struct vestigial_inpcb *);
    265 struct inpcb *
    266 	inpcb_lookup_bound(struct inpcbtable *,
    267 	    struct in_addr, u_int);
    268 struct inpcb *
    269 	inpcb_lookup(struct inpcbtable *,
    270 			     struct in_addr, u_int, struct in_addr, u_int,
    271 			     struct vestigial_inpcb *);
    272 int	inpcb_notify(struct inpcbtable *, struct in_addr, u_int,
    273 	    struct in_addr, u_int, int, void (*)(struct inpcb *, int));
    274 void	inpcb_notifyall(struct inpcbtable *, struct in_addr, int,
    275 	    void (*)(struct inpcb *, int));
    276 void	inpcb_purgeif0(struct inpcbtable *, struct ifnet *);
    277 void	inpcb_purgeif(struct inpcbtable *, struct ifnet *);
    278 void	in_purgeifmcast(struct ip_moptions *, struct ifnet *);
    279 void	inpcb_set_state(struct inpcb *, int);
    280 void	inpcb_rtchange(struct inpcb *, int);
    281 void	inpcb_fetch_peeraddr(struct inpcb *, struct sockaddr_in *);
    282 void	inpcb_fetch_sockaddr(struct inpcb *, struct sockaddr_in *);
    283 struct rtentry *
    284 	inpcb_rtentry(struct inpcb *);
    285 void	inpcb_rtentry_unref(struct rtentry *, struct inpcb *);
    286 
    287 void	in6pcb_init(struct inpcbtable *, int, int);
    288 int	in6pcb_bind(void *, struct sockaddr_in6 *, struct lwp *);
    289 int	in6pcb_connect(void *, struct sockaddr_in6 *, struct lwp *);
    290 void	in6pcb_destroy(struct inpcb *);
    291 void	in6pcb_disconnect(struct inpcb *);
    292 struct	inpcb *in6pcb_lookup_local(struct inpcbtable *, struct in6_addr *,
    293 				   u_int, int, struct vestigial_inpcb *);
    294 int	in6pcb_notify(struct inpcbtable *, const struct sockaddr *,
    295 	u_int, const struct sockaddr *, u_int, int, void *,
    296 	void (*)(struct inpcb *, int));
    297 void	in6pcb_purgeif0(struct inpcbtable *, struct ifnet *);
    298 void	in6pcb_purgeif(struct inpcbtable *, struct ifnet *);
    299 void	in6pcb_set_state(struct inpcb *, int);
    300 void	in6pcb_rtchange(struct inpcb *, int);
    301 void	in6pcb_fetch_peeraddr(struct inpcb *, struct sockaddr_in6 *);
    302 void	in6pcb_fetch_sockaddr(struct inpcb *, struct sockaddr_in6 *);
    303 
    304 /* in in6_src.c */
    305 int	in6pcb_selecthlim(struct inpcb *, struct ifnet *);
    306 int	in6pcb_selecthlim_rt(struct inpcb *);
    307 int	in6pcb_set_port(struct sockaddr_in6 *, struct inpcb *, struct lwp *);
    308 
    309 extern struct rtentry *
    310 	in6pcb_rtentry(struct inpcb *);
    311 extern void
    312 	in6pcb_rtentry_unref(struct rtentry *, struct inpcb *);
    313 extern struct inpcb *in6pcb_lookup(struct inpcbtable *,
    314 					    const struct in6_addr *, u_int, const struct in6_addr *, u_int, int,
    315 					    struct vestigial_inpcb *);
    316 extern struct inpcb *in6pcb_lookup_bound(struct inpcbtable *,
    317 	const struct in6_addr *, u_int, int);
    318 
    319 static inline void
    320 inpcb_register_overudp_cb(struct inpcb *inp, pcb_overudp_cb_t cb, void *arg)
    321 {
    322 
    323 	inp->inp_overudp_cb = cb;
    324 	inp->inp_overudp_arg = arg;
    325 }
    326 
    327 /* compute hash value for foreign and local in6_addr and port */
    328 #define IN6_HASH(faddr, fport, laddr, lport) 			\
    329 	(((faddr)->s6_addr32[0] ^ (faddr)->s6_addr32[1] ^	\
    330 	  (faddr)->s6_addr32[2] ^ (faddr)->s6_addr32[3] ^	\
    331 	  (laddr)->s6_addr32[0] ^ (laddr)->s6_addr32[1] ^	\
    332 	  (laddr)->s6_addr32[2] ^ (laddr)->s6_addr32[3])	\
    333 	 + (fport) + (lport))
    334 
    335 // from in_pcb_hdr.h
    336 struct vestigial_inpcb;
    337 struct in6_addr;
    338 
    339 /* Hooks for vestigial pcb entries.
    340  * If vestigial entries exist for a table (TCP only)
    341  * the vestigial pointer is set.
    342  */
    343 typedef struct vestigial_hooks {
    344 	/* IPv4 hooks */
    345 	void	*(*init_ports4)(struct in_addr, u_int, int);
    346 	int	(*next_port4)(void *, struct vestigial_inpcb *);
    347 	int	(*lookup4)(struct in_addr, uint16_t,
    348 			   struct in_addr, uint16_t,
    349 			   struct vestigial_inpcb *);
    350 	/* IPv6 hooks */
    351 	void	*(*init_ports6)(const struct in6_addr*, u_int, int);
    352 	int	(*next_port6)(void *, struct vestigial_inpcb *);
    353 	int	(*lookup6)(const struct in6_addr *, uint16_t,
    354 			   const struct in6_addr *, uint16_t,
    355 			   struct vestigial_inpcb *);
    356 } vestigial_hooks_t;
    357 
    358 #endif	/* _KERNEL */
    359 
    360 #endif	/* !_NETINET_IN_PCB_H_ */
    361