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