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