Wed Jan 20 22:01:18 2016 UTC ()
Give proper prototype to udp_output.


(riastradh)
diff -r1.222 -r1.223 src/sys/netinet/udp_usrreq.c
diff -r1.40 -r1.41 src/sys/netinet/udp_var.h

cvs diff -r1.222 -r1.223 src/sys/netinet/udp_usrreq.c (switch to unified diff)

--- src/sys/netinet/udp_usrreq.c 2015/08/24 22:21:26 1.222
+++ src/sys/netinet/udp_usrreq.c 2016/01/20 22:01:18 1.223
@@ -1,1407 +1,1402 @@ @@ -1,1407 +1,1402 @@
1/* $NetBSD: udp_usrreq.c,v 1.222 2015/08/24 22:21:26 pooka Exp $ */ 1/* $NetBSD: udp_usrreq.c,v 1.223 2016/01/20 22:01:18 riastradh Exp $ */
2 2
3/* 3/*
4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the project nor the names of its contributors 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 16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission. 17 * without specific prior written permission.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 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 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 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 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 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE. 29 * SUCH DAMAGE.
30 */ 30 */
31 31
32/* 32/*
33 * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995 33 * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995
34 * The Regents of the University of California. All rights reserved. 34 * The Regents of the University of California. All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions 37 * modification, are permitted provided that the following conditions
38 * are met: 38 * are met:
39 * 1. Redistributions of source code must retain the above copyright 39 * 1. Redistributions of source code must retain the above copyright
40 * notice, this list of conditions and the following disclaimer. 40 * notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above copyright 41 * 2. Redistributions in binary form must reproduce the above copyright
42 * notice, this list of conditions and the following disclaimer in the 42 * notice, this list of conditions and the following disclaimer in the
43 * documentation and/or other materials provided with the distribution. 43 * documentation and/or other materials provided with the distribution.
44 * 3. Neither the name of the University nor the names of its contributors 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 45 * may be used to endorse or promote products derived from this software
46 * without specific prior written permission. 46 * without specific prior written permission.
47 * 47 *
48 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 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 49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 51 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 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 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 57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58 * SUCH DAMAGE. 58 * SUCH DAMAGE.
59 * 59 *
60 * @(#)udp_usrreq.c 8.6 (Berkeley) 5/23/95 60 * @(#)udp_usrreq.c 8.6 (Berkeley) 5/23/95
61 */ 61 */
62 62
63/* 63/*
64 * UDP protocol implementation. 64 * UDP protocol implementation.
65 * Per RFC 768, August, 1980. 65 * Per RFC 768, August, 1980.
66 */ 66 */
67 67
68#include <sys/cdefs.h> 68#include <sys/cdefs.h>
69__KERNEL_RCSID(0, "$NetBSD: udp_usrreq.c,v 1.222 2015/08/24 22:21:26 pooka Exp $"); 69__KERNEL_RCSID(0, "$NetBSD: udp_usrreq.c,v 1.223 2016/01/20 22:01:18 riastradh Exp $");
70 70
71#ifdef _KERNEL_OPT 71#ifdef _KERNEL_OPT
72#include "opt_inet.h" 72#include "opt_inet.h"
73#include "opt_compat_netbsd.h" 73#include "opt_compat_netbsd.h"
74#include "opt_ipsec.h" 74#include "opt_ipsec.h"
75#include "opt_inet_csum.h" 75#include "opt_inet_csum.h"
76#include "opt_ipkdb.h" 76#include "opt_ipkdb.h"
77#include "opt_mbuftrace.h" 77#include "opt_mbuftrace.h"
78#endif 78#endif
79 79
80#include <sys/param.h> 80#include <sys/param.h>
81#include <sys/mbuf.h> 81#include <sys/mbuf.h>
82#include <sys/once.h> 82#include <sys/once.h>
83#include <sys/protosw.h> 83#include <sys/protosw.h>
84#include <sys/socket.h> 84#include <sys/socket.h>
85#include <sys/socketvar.h> 85#include <sys/socketvar.h>
86#include <sys/systm.h> 86#include <sys/systm.h>
87#include <sys/proc.h> 87#include <sys/proc.h>
88#include <sys/domain.h> 88#include <sys/domain.h>
89#include <sys/sysctl.h> 89#include <sys/sysctl.h>
90 90
91#include <net/if.h> 91#include <net/if.h>
92#include <net/route.h> 92#include <net/route.h>
93 93
94#include <netinet/in.h> 94#include <netinet/in.h>
95#include <netinet/in_systm.h> 95#include <netinet/in_systm.h>
96#include <netinet/in_var.h> 96#include <netinet/in_var.h>
97#include <netinet/ip.h> 97#include <netinet/ip.h>
98#include <netinet/in_pcb.h> 98#include <netinet/in_pcb.h>
99#include <netinet/ip_var.h> 99#include <netinet/ip_var.h>
100#include <netinet/ip_icmp.h> 100#include <netinet/ip_icmp.h>
101#include <netinet/udp.h> 101#include <netinet/udp.h>
102#include <netinet/udp_var.h> 102#include <netinet/udp_var.h>
103#include <netinet/udp_private.h> 103#include <netinet/udp_private.h>
104 104
105#ifdef INET6 105#ifdef INET6
106#include <netinet/ip6.h> 106#include <netinet/ip6.h>
107#include <netinet/icmp6.h> 107#include <netinet/icmp6.h>
108#include <netinet6/ip6_var.h> 108#include <netinet6/ip6_var.h>
109#include <netinet6/ip6_private.h> 109#include <netinet6/ip6_private.h>
110#include <netinet6/in6_pcb.h> 110#include <netinet6/in6_pcb.h>
111#include <netinet6/udp6_var.h> 111#include <netinet6/udp6_var.h>
112#include <netinet6/udp6_private.h> 112#include <netinet6/udp6_private.h>
113#endif 113#endif
114 114
115#ifndef INET6 115#ifndef INET6
116/* always need ip6.h for IP6_EXTHDR_GET */ 116/* always need ip6.h for IP6_EXTHDR_GET */
117#include <netinet/ip6.h> 117#include <netinet/ip6.h>
118#endif 118#endif
119 119
120#ifdef IPSEC 120#ifdef IPSEC
121#include <netipsec/ipsec.h> 121#include <netipsec/ipsec.h>
122#include <netipsec/ipsec_var.h> 122#include <netipsec/ipsec_var.h>
123#include <netipsec/ipsec_private.h> 123#include <netipsec/ipsec_private.h>
124#include <netipsec/esp.h> 124#include <netipsec/esp.h>
125#ifdef INET6 125#ifdef INET6
126#include <netipsec/ipsec6.h> 126#include <netipsec/ipsec6.h>
127#endif 127#endif
128#endif /* IPSEC */ 128#endif /* IPSEC */
129 129
130#ifdef COMPAT_50 130#ifdef COMPAT_50
131#include <compat/sys/socket.h> 131#include <compat/sys/socket.h>
132#endif 132#endif
133 133
134#ifdef IPKDB 134#ifdef IPKDB
135#include <ipkdb/ipkdb.h> 135#include <ipkdb/ipkdb.h>
136#endif 136#endif
137 137
138int udpcksum = 1; 138int udpcksum = 1;
139int udp_do_loopback_cksum = 0; 139int udp_do_loopback_cksum = 0;
140 140
141struct inpcbtable udbtable; 141struct inpcbtable udbtable;
142 142
143percpu_t *udpstat_percpu; 143percpu_t *udpstat_percpu;
144 144
145#ifdef INET 145#ifdef INET
146#ifdef IPSEC 146#ifdef IPSEC
147static int udp4_espinudp (struct mbuf **, int, struct sockaddr *, 147static int udp4_espinudp (struct mbuf **, int, struct sockaddr *,
148 struct socket *); 148 struct socket *);
149#endif 149#endif
150static void udp4_sendup (struct mbuf *, int, struct sockaddr *, 150static void udp4_sendup (struct mbuf *, int, struct sockaddr *,
151 struct socket *); 151 struct socket *);
152static int udp4_realinput (struct sockaddr_in *, struct sockaddr_in *, 152static int udp4_realinput (struct sockaddr_in *, struct sockaddr_in *,
153 struct mbuf **, int); 153 struct mbuf **, int);
154static int udp4_input_checksum(struct mbuf *, const struct udphdr *, int, int); 154static int udp4_input_checksum(struct mbuf *, const struct udphdr *, int, int);
155#endif 155#endif
156#ifdef INET 156#ifdef INET
157static void udp_notify (struct inpcb *, int); 157static void udp_notify (struct inpcb *, int);
158#endif 158#endif
159 159
160#ifndef UDBHASHSIZE 160#ifndef UDBHASHSIZE
161#define UDBHASHSIZE 128 161#define UDBHASHSIZE 128
162#endif 162#endif
163int udbhashsize = UDBHASHSIZE; 163int udbhashsize = UDBHASHSIZE;
164 164
165/* 165/*
166 * For send - really max datagram size; for receive - 40 1K datagrams. 166 * For send - really max datagram size; for receive - 40 1K datagrams.
167 */ 167 */
168static int udp_sendspace = 9216; 168static int udp_sendspace = 9216;
169static int udp_recvspace = 40 * (1024 + sizeof(struct sockaddr_in)); 169static int udp_recvspace = 40 * (1024 + sizeof(struct sockaddr_in));
170 170
171#ifdef MBUFTRACE 171#ifdef MBUFTRACE
172struct mowner udp_mowner = MOWNER_INIT("udp", ""); 172struct mowner udp_mowner = MOWNER_INIT("udp", "");
173struct mowner udp_rx_mowner = MOWNER_INIT("udp", "rx"); 173struct mowner udp_rx_mowner = MOWNER_INIT("udp", "rx");
174struct mowner udp_tx_mowner = MOWNER_INIT("udp", "tx"); 174struct mowner udp_tx_mowner = MOWNER_INIT("udp", "tx");
175#endif 175#endif
176 176
177#ifdef UDP_CSUM_COUNTERS 177#ifdef UDP_CSUM_COUNTERS
178#include <sys/device.h> 178#include <sys/device.h>
179 179
180#if defined(INET) 180#if defined(INET)
181struct evcnt udp_hwcsum_bad = EVCNT_INITIALIZER(EVCNT_TYPE_MISC, 181struct evcnt udp_hwcsum_bad = EVCNT_INITIALIZER(EVCNT_TYPE_MISC,
182 NULL, "udp", "hwcsum bad"); 182 NULL, "udp", "hwcsum bad");
183struct evcnt udp_hwcsum_ok = EVCNT_INITIALIZER(EVCNT_TYPE_MISC, 183struct evcnt udp_hwcsum_ok = EVCNT_INITIALIZER(EVCNT_TYPE_MISC,
184 NULL, "udp", "hwcsum ok"); 184 NULL, "udp", "hwcsum ok");
185struct evcnt udp_hwcsum_data = EVCNT_INITIALIZER(EVCNT_TYPE_MISC, 185struct evcnt udp_hwcsum_data = EVCNT_INITIALIZER(EVCNT_TYPE_MISC,
186 NULL, "udp", "hwcsum data"); 186 NULL, "udp", "hwcsum data");
187struct evcnt udp_swcsum = EVCNT_INITIALIZER(EVCNT_TYPE_MISC, 187struct evcnt udp_swcsum = EVCNT_INITIALIZER(EVCNT_TYPE_MISC,
188 NULL, "udp", "swcsum"); 188 NULL, "udp", "swcsum");
189 189
190EVCNT_ATTACH_STATIC(udp_hwcsum_bad); 190EVCNT_ATTACH_STATIC(udp_hwcsum_bad);
191EVCNT_ATTACH_STATIC(udp_hwcsum_ok); 191EVCNT_ATTACH_STATIC(udp_hwcsum_ok);
192EVCNT_ATTACH_STATIC(udp_hwcsum_data); 192EVCNT_ATTACH_STATIC(udp_hwcsum_data);
193EVCNT_ATTACH_STATIC(udp_swcsum); 193EVCNT_ATTACH_STATIC(udp_swcsum);
194#endif /* defined(INET) */ 194#endif /* defined(INET) */
195 195
196#define UDP_CSUM_COUNTER_INCR(ev) (ev)->ev_count++ 196#define UDP_CSUM_COUNTER_INCR(ev) (ev)->ev_count++
197#else 197#else
198#define UDP_CSUM_COUNTER_INCR(ev) /* nothing */ 198#define UDP_CSUM_COUNTER_INCR(ev) /* nothing */
199#endif /* UDP_CSUM_COUNTERS */ 199#endif /* UDP_CSUM_COUNTERS */
200 200
201static void sysctl_net_inet_udp_setup(struct sysctllog **); 201static void sysctl_net_inet_udp_setup(struct sysctllog **);
202 202
203static int 203static int
204do_udpinit(void) 204do_udpinit(void)
205{ 205{
206 206
207 in_pcbinit(&udbtable, udbhashsize, udbhashsize); 207 in_pcbinit(&udbtable, udbhashsize, udbhashsize);
208 udpstat_percpu = percpu_alloc(sizeof(uint64_t) * UDP_NSTATS); 208 udpstat_percpu = percpu_alloc(sizeof(uint64_t) * UDP_NSTATS);
209 209
210 MOWNER_ATTACH(&udp_tx_mowner); 210 MOWNER_ATTACH(&udp_tx_mowner);
211 MOWNER_ATTACH(&udp_rx_mowner); 211 MOWNER_ATTACH(&udp_rx_mowner);
212 MOWNER_ATTACH(&udp_mowner); 212 MOWNER_ATTACH(&udp_mowner);
213 213
214 return 0; 214 return 0;
215} 215}
216 216
217void 217void
218udp_init_common(void) 218udp_init_common(void)
219{ 219{
220 static ONCE_DECL(doudpinit); 220 static ONCE_DECL(doudpinit);
221 221
222 RUN_ONCE(&doudpinit, do_udpinit); 222 RUN_ONCE(&doudpinit, do_udpinit);
223} 223}
224 224
225void 225void
226udp_init(void) 226udp_init(void)
227{ 227{
228 228
229 sysctl_net_inet_udp_setup(NULL); 229 sysctl_net_inet_udp_setup(NULL);
230 230
231 udp_init_common(); 231 udp_init_common();
232} 232}
233 233
234/* 234/*
235 * Checksum extended UDP header and data. 235 * Checksum extended UDP header and data.
236 */ 236 */
237 237
238int 238int
239udp_input_checksum(int af, struct mbuf *m, const struct udphdr *uh, 239udp_input_checksum(int af, struct mbuf *m, const struct udphdr *uh,
240 int iphlen, int len) 240 int iphlen, int len)
241{ 241{
242 242
243 switch (af) { 243 switch (af) {
244#ifdef INET 244#ifdef INET
245 case AF_INET: 245 case AF_INET:
246 return udp4_input_checksum(m, uh, iphlen, len); 246 return udp4_input_checksum(m, uh, iphlen, len);
247#endif 247#endif
248#ifdef INET6 248#ifdef INET6
249 case AF_INET6: 249 case AF_INET6:
250 return udp6_input_checksum(m, uh, iphlen, len); 250 return udp6_input_checksum(m, uh, iphlen, len);
251#endif 251#endif
252 } 252 }
253#ifdef DIAGNOSTIC 253#ifdef DIAGNOSTIC
254 panic("udp_input_checksum: unknown af %d", af); 254 panic("udp_input_checksum: unknown af %d", af);
255#endif 255#endif
256 /* NOTREACHED */ 256 /* NOTREACHED */
257 return -1; 257 return -1;
258} 258}
259 259
260#ifdef INET 260#ifdef INET
261 261
262/* 262/*
263 * Checksum extended UDP header and data. 263 * Checksum extended UDP header and data.
264 */ 264 */
265 265
266static int 266static int
267udp4_input_checksum(struct mbuf *m, const struct udphdr *uh, 267udp4_input_checksum(struct mbuf *m, const struct udphdr *uh,
268 int iphlen, int len) 268 int iphlen, int len)
269{ 269{
270 270
271 /* 271 /*
272 * XXX it's better to record and check if this mbuf is 272 * XXX it's better to record and check if this mbuf is
273 * already checked. 273 * already checked.
274 */ 274 */
275 275
276 if (uh->uh_sum == 0) 276 if (uh->uh_sum == 0)
277 return 0; 277 return 0;
278 278
279 switch (m->m_pkthdr.csum_flags & 279 switch (m->m_pkthdr.csum_flags &
280 ((m->m_pkthdr.rcvif->if_csum_flags_rx & M_CSUM_UDPv4) | 280 ((m->m_pkthdr.rcvif->if_csum_flags_rx & M_CSUM_UDPv4) |
281 M_CSUM_TCP_UDP_BAD | M_CSUM_DATA)) { 281 M_CSUM_TCP_UDP_BAD | M_CSUM_DATA)) {
282 case M_CSUM_UDPv4|M_CSUM_TCP_UDP_BAD: 282 case M_CSUM_UDPv4|M_CSUM_TCP_UDP_BAD:
283 UDP_CSUM_COUNTER_INCR(&udp_hwcsum_bad); 283 UDP_CSUM_COUNTER_INCR(&udp_hwcsum_bad);
284 goto badcsum; 284 goto badcsum;
285 285
286 case M_CSUM_UDPv4|M_CSUM_DATA: { 286 case M_CSUM_UDPv4|M_CSUM_DATA: {
287 u_int32_t hw_csum = m->m_pkthdr.csum_data; 287 u_int32_t hw_csum = m->m_pkthdr.csum_data;
288 288
289 UDP_CSUM_COUNTER_INCR(&udp_hwcsum_data); 289 UDP_CSUM_COUNTER_INCR(&udp_hwcsum_data);
290 if (m->m_pkthdr.csum_flags & M_CSUM_NO_PSEUDOHDR) { 290 if (m->m_pkthdr.csum_flags & M_CSUM_NO_PSEUDOHDR) {
291 const struct ip *ip = 291 const struct ip *ip =
292 mtod(m, const struct ip *); 292 mtod(m, const struct ip *);
293 293
294 hw_csum = in_cksum_phdr(ip->ip_src.s_addr, 294 hw_csum = in_cksum_phdr(ip->ip_src.s_addr,
295 ip->ip_dst.s_addr, 295 ip->ip_dst.s_addr,
296 htons(hw_csum + len + IPPROTO_UDP)); 296 htons(hw_csum + len + IPPROTO_UDP));
297 } 297 }
298 if ((hw_csum ^ 0xffff) != 0) 298 if ((hw_csum ^ 0xffff) != 0)
299 goto badcsum; 299 goto badcsum;
300 break; 300 break;
301 } 301 }
302 302
303 case M_CSUM_UDPv4: 303 case M_CSUM_UDPv4:
304 /* Checksum was okay. */ 304 /* Checksum was okay. */
305 UDP_CSUM_COUNTER_INCR(&udp_hwcsum_ok); 305 UDP_CSUM_COUNTER_INCR(&udp_hwcsum_ok);
306 break; 306 break;
307 307
308 default: 308 default:
309 /* 309 /*
310 * Need to compute it ourselves. Maybe skip checksum 310 * Need to compute it ourselves. Maybe skip checksum
311 * on loopback interfaces. 311 * on loopback interfaces.
312 */ 312 */
313 if (__predict_true(!(m->m_pkthdr.rcvif->if_flags & 313 if (__predict_true(!(m->m_pkthdr.rcvif->if_flags &
314 IFF_LOOPBACK) || 314 IFF_LOOPBACK) ||
315 udp_do_loopback_cksum)) { 315 udp_do_loopback_cksum)) {
316 UDP_CSUM_COUNTER_INCR(&udp_swcsum); 316 UDP_CSUM_COUNTER_INCR(&udp_swcsum);
317 if (in4_cksum(m, IPPROTO_UDP, iphlen, len) != 0) 317 if (in4_cksum(m, IPPROTO_UDP, iphlen, len) != 0)
318 goto badcsum; 318 goto badcsum;
319 } 319 }
320 break; 320 break;
321 } 321 }
322 322
323 return 0; 323 return 0;
324 324
325badcsum: 325badcsum:
326 UDP_STATINC(UDP_STAT_BADSUM); 326 UDP_STATINC(UDP_STAT_BADSUM);
327 return -1; 327 return -1;
328} 328}
329 329
330void 330void
331udp_input(struct mbuf *m, ...) 331udp_input(struct mbuf *m, ...)
332{ 332{
333 va_list ap; 333 va_list ap;
334 struct sockaddr_in src, dst; 334 struct sockaddr_in src, dst;
335 struct ip *ip; 335 struct ip *ip;
336 struct udphdr *uh; 336 struct udphdr *uh;
337 int iphlen; 337 int iphlen;
338 int len; 338 int len;
339 int n; 339 int n;
340 u_int16_t ip_len; 340 u_int16_t ip_len;
341 341
342 va_start(ap, m); 342 va_start(ap, m);
343 iphlen = va_arg(ap, int); 343 iphlen = va_arg(ap, int);
344 (void)va_arg(ap, int); /* ignore value, advance ap */ 344 (void)va_arg(ap, int); /* ignore value, advance ap */
345 va_end(ap); 345 va_end(ap);
346 346
347 MCLAIM(m, &udp_rx_mowner); 347 MCLAIM(m, &udp_rx_mowner);
348 UDP_STATINC(UDP_STAT_IPACKETS); 348 UDP_STATINC(UDP_STAT_IPACKETS);
349 349
350 /* 350 /*
351 * Get IP and UDP header together in first mbuf. 351 * Get IP and UDP header together in first mbuf.
352 */ 352 */
353 ip = mtod(m, struct ip *); 353 ip = mtod(m, struct ip *);
354 IP6_EXTHDR_GET(uh, struct udphdr *, m, iphlen, sizeof(struct udphdr)); 354 IP6_EXTHDR_GET(uh, struct udphdr *, m, iphlen, sizeof(struct udphdr));
355 if (uh == NULL) { 355 if (uh == NULL) {
356 UDP_STATINC(UDP_STAT_HDROPS); 356 UDP_STATINC(UDP_STAT_HDROPS);
357 return; 357 return;
358 } 358 }
359 KASSERT(UDP_HDR_ALIGNED_P(uh)); 359 KASSERT(UDP_HDR_ALIGNED_P(uh));
360 360
361 /* destination port of 0 is illegal, based on RFC768. */ 361 /* destination port of 0 is illegal, based on RFC768. */
362 if (uh->uh_dport == 0) 362 if (uh->uh_dport == 0)
363 goto bad; 363 goto bad;
364 364
365 /* 365 /*
366 * Make mbuf data length reflect UDP length. 366 * Make mbuf data length reflect UDP length.
367 * If not enough data to reflect UDP length, drop. 367 * If not enough data to reflect UDP length, drop.
368 */ 368 */
369 ip_len = ntohs(ip->ip_len); 369 ip_len = ntohs(ip->ip_len);
370 len = ntohs((u_int16_t)uh->uh_ulen); 370 len = ntohs((u_int16_t)uh->uh_ulen);
371 if (ip_len != iphlen + len) { 371 if (ip_len != iphlen + len) {
372 if (ip_len < iphlen + len || len < sizeof(struct udphdr)) { 372 if (ip_len < iphlen + len || len < sizeof(struct udphdr)) {
373 UDP_STATINC(UDP_STAT_BADLEN); 373 UDP_STATINC(UDP_STAT_BADLEN);
374 goto bad; 374 goto bad;
375 } 375 }
376 m_adj(m, iphlen + len - ip_len); 376 m_adj(m, iphlen + len - ip_len);
377 } 377 }
378 378
379 /* 379 /*
380 * Checksum extended UDP header and data. 380 * Checksum extended UDP header and data.
381 */ 381 */
382 if (udp4_input_checksum(m, uh, iphlen, len)) 382 if (udp4_input_checksum(m, uh, iphlen, len))
383 goto badcsum; 383 goto badcsum;
384 384
385 /* construct source and dst sockaddrs. */ 385 /* construct source and dst sockaddrs. */
386 sockaddr_in_init(&src, &ip->ip_src, uh->uh_sport); 386 sockaddr_in_init(&src, &ip->ip_src, uh->uh_sport);
387 sockaddr_in_init(&dst, &ip->ip_dst, uh->uh_dport); 387 sockaddr_in_init(&dst, &ip->ip_dst, uh->uh_dport);
388 388
389 if ((n = udp4_realinput(&src, &dst, &m, iphlen)) == -1) { 389 if ((n = udp4_realinput(&src, &dst, &m, iphlen)) == -1) {
390 UDP_STATINC(UDP_STAT_HDROPS); 390 UDP_STATINC(UDP_STAT_HDROPS);
391 return; 391 return;
392 } 392 }
393 if (m == NULL) { 393 if (m == NULL) {
394 /* 394 /*
395 * packet has been processed by ESP stuff - 395 * packet has been processed by ESP stuff -
396 * e.g. dropped NAT-T-keep-alive-packet ... 396 * e.g. dropped NAT-T-keep-alive-packet ...
397 */ 397 */
398 return; 398 return;
399 } 399 }
400 ip = mtod(m, struct ip *); 400 ip = mtod(m, struct ip *);
401#ifdef INET6 401#ifdef INET6
402 if (IN_MULTICAST(ip->ip_dst.s_addr) || n == 0) { 402 if (IN_MULTICAST(ip->ip_dst.s_addr) || n == 0) {
403 struct sockaddr_in6 src6, dst6; 403 struct sockaddr_in6 src6, dst6;
404 404
405 memset(&src6, 0, sizeof(src6)); 405 memset(&src6, 0, sizeof(src6));
406 src6.sin6_family = AF_INET6; 406 src6.sin6_family = AF_INET6;
407 src6.sin6_len = sizeof(struct sockaddr_in6); 407 src6.sin6_len = sizeof(struct sockaddr_in6);
408 src6.sin6_addr.s6_addr[10] = src6.sin6_addr.s6_addr[11] = 0xff; 408 src6.sin6_addr.s6_addr[10] = src6.sin6_addr.s6_addr[11] = 0xff;
409 memcpy(&src6.sin6_addr.s6_addr[12], &ip->ip_src, 409 memcpy(&src6.sin6_addr.s6_addr[12], &ip->ip_src,
410 sizeof(ip->ip_src)); 410 sizeof(ip->ip_src));
411 src6.sin6_port = uh->uh_sport; 411 src6.sin6_port = uh->uh_sport;
412 memset(&dst6, 0, sizeof(dst6)); 412 memset(&dst6, 0, sizeof(dst6));
413 dst6.sin6_family = AF_INET6; 413 dst6.sin6_family = AF_INET6;
414 dst6.sin6_len = sizeof(struct sockaddr_in6); 414 dst6.sin6_len = sizeof(struct sockaddr_in6);
415 dst6.sin6_addr.s6_addr[10] = dst6.sin6_addr.s6_addr[11] = 0xff; 415 dst6.sin6_addr.s6_addr[10] = dst6.sin6_addr.s6_addr[11] = 0xff;
416 memcpy(&dst6.sin6_addr.s6_addr[12], &ip->ip_dst, 416 memcpy(&dst6.sin6_addr.s6_addr[12], &ip->ip_dst,
417 sizeof(ip->ip_dst)); 417 sizeof(ip->ip_dst));
418 dst6.sin6_port = uh->uh_dport; 418 dst6.sin6_port = uh->uh_dport;
419 419
420 n += udp6_realinput(AF_INET, &src6, &dst6, m, iphlen); 420 n += udp6_realinput(AF_INET, &src6, &dst6, m, iphlen);
421 } 421 }
422#endif 422#endif
423 423
424 if (n == 0) { 424 if (n == 0) {
425 if (m->m_flags & (M_BCAST | M_MCAST)) { 425 if (m->m_flags & (M_BCAST | M_MCAST)) {
426 UDP_STATINC(UDP_STAT_NOPORTBCAST); 426 UDP_STATINC(UDP_STAT_NOPORTBCAST);
427 goto bad; 427 goto bad;
428 } 428 }
429 UDP_STATINC(UDP_STAT_NOPORT); 429 UDP_STATINC(UDP_STAT_NOPORT);
430#ifdef IPKDB 430#ifdef IPKDB
431 if (checkipkdb(&ip->ip_src, uh->uh_sport, uh->uh_dport, 431 if (checkipkdb(&ip->ip_src, uh->uh_sport, uh->uh_dport,
432 m, iphlen + sizeof(struct udphdr), 432 m, iphlen + sizeof(struct udphdr),
433 m->m_pkthdr.len - iphlen - sizeof(struct udphdr))) { 433 m->m_pkthdr.len - iphlen - sizeof(struct udphdr))) {
434 /* 434 /*
435 * It was a debugger connect packet, 435 * It was a debugger connect packet,
436 * just drop it now 436 * just drop it now
437 */ 437 */
438 goto bad; 438 goto bad;
439 } 439 }
440#endif 440#endif
441 icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_PORT, 0, 0); 441 icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_PORT, 0, 0);
442 m = NULL; 442 m = NULL;
443 } 443 }
444 444
445bad: 445bad:
446 if (m) 446 if (m)
447 m_freem(m); 447 m_freem(m);
448 return; 448 return;
449 449
450badcsum: 450badcsum:
451 m_freem(m); 451 m_freem(m);
452} 452}
453#endif 453#endif
454 454
455#ifdef INET 455#ifdef INET
456static void 456static void
457udp4_sendup(struct mbuf *m, int off /* offset of data portion */, 457udp4_sendup(struct mbuf *m, int off /* offset of data portion */,
458 struct sockaddr *src, struct socket *so) 458 struct sockaddr *src, struct socket *so)
459{ 459{
460 struct mbuf *opts = NULL; 460 struct mbuf *opts = NULL;
461 struct mbuf *n; 461 struct mbuf *n;
462 struct inpcb *inp = NULL; 462 struct inpcb *inp = NULL;
463 463
464 if (!so) 464 if (!so)
465 return; 465 return;
466 switch (so->so_proto->pr_domain->dom_family) { 466 switch (so->so_proto->pr_domain->dom_family) {
467 case AF_INET: 467 case AF_INET:
468 inp = sotoinpcb(so); 468 inp = sotoinpcb(so);
469 break; 469 break;
470#ifdef INET6 470#ifdef INET6
471 case AF_INET6: 471 case AF_INET6:
472 break; 472 break;
473#endif 473#endif
474 default: 474 default:
475 return; 475 return;
476 } 476 }
477 477
478#if defined(IPSEC) 478#if defined(IPSEC)
479 /* check AH/ESP integrity. */ 479 /* check AH/ESP integrity. */
480 if (ipsec_used && so != NULL && ipsec4_in_reject_so(m, so)) { 480 if (ipsec_used && so != NULL && ipsec4_in_reject_so(m, so)) {
481 IPSEC_STATINC(IPSEC_STAT_IN_POLVIO); 481 IPSEC_STATINC(IPSEC_STAT_IN_POLVIO);
482 if ((n = m_copypacket(m, M_DONTWAIT)) != NULL) 482 if ((n = m_copypacket(m, M_DONTWAIT)) != NULL)
483 icmp_error(n, ICMP_UNREACH, ICMP_UNREACH_ADMIN_PROHIBIT, 483 icmp_error(n, ICMP_UNREACH, ICMP_UNREACH_ADMIN_PROHIBIT,
484 0, 0); 484 0, 0);
485 return; 485 return;
486 } 486 }
487#endif /*IPSEC*/ 487#endif /*IPSEC*/
488 488
489 if ((n = m_copypacket(m, M_DONTWAIT)) != NULL) { 489 if ((n = m_copypacket(m, M_DONTWAIT)) != NULL) {
490 if (inp && (inp->inp_flags & INP_CONTROLOPTS 490 if (inp && (inp->inp_flags & INP_CONTROLOPTS
491#ifdef SO_OTIMESTAMP 491#ifdef SO_OTIMESTAMP
492 || so->so_options & SO_OTIMESTAMP 492 || so->so_options & SO_OTIMESTAMP
493#endif 493#endif
494 || so->so_options & SO_TIMESTAMP)) { 494 || so->so_options & SO_TIMESTAMP)) {
495 struct ip *ip = mtod(n, struct ip *); 495 struct ip *ip = mtod(n, struct ip *);
496 ip_savecontrol(inp, &opts, ip, n); 496 ip_savecontrol(inp, &opts, ip, n);
497 } 497 }
498 498
499 m_adj(n, off); 499 m_adj(n, off);
500 if (sbappendaddr(&so->so_rcv, src, n, 500 if (sbappendaddr(&so->so_rcv, src, n,
501 opts) == 0) { 501 opts) == 0) {
502 m_freem(n); 502 m_freem(n);
503 if (opts) 503 if (opts)
504 m_freem(opts); 504 m_freem(opts);
505 so->so_rcv.sb_overflowed++; 505 so->so_rcv.sb_overflowed++;
506 UDP_STATINC(UDP_STAT_FULLSOCK); 506 UDP_STATINC(UDP_STAT_FULLSOCK);
507 } else 507 } else
508 sorwakeup(so); 508 sorwakeup(so);
509 } 509 }
510} 510}
511#endif 511#endif
512 512
513#ifdef INET 513#ifdef INET
514static int 514static int
515udp4_realinput(struct sockaddr_in *src, struct sockaddr_in *dst, 515udp4_realinput(struct sockaddr_in *src, struct sockaddr_in *dst,
516 struct mbuf **mp, int off /* offset of udphdr */) 516 struct mbuf **mp, int off /* offset of udphdr */)
517{ 517{
518 u_int16_t *sport, *dport; 518 u_int16_t *sport, *dport;
519 int rcvcnt; 519 int rcvcnt;
520 struct in_addr *src4, *dst4; 520 struct in_addr *src4, *dst4;
521 struct inpcb_hdr *inph; 521 struct inpcb_hdr *inph;
522 struct inpcb *inp; 522 struct inpcb *inp;
523 struct mbuf *m = *mp; 523 struct mbuf *m = *mp;
524 524
525 rcvcnt = 0; 525 rcvcnt = 0;
526 off += sizeof(struct udphdr); /* now, offset of payload */ 526 off += sizeof(struct udphdr); /* now, offset of payload */
527 527
528 if (src->sin_family != AF_INET || dst->sin_family != AF_INET) 528 if (src->sin_family != AF_INET || dst->sin_family != AF_INET)
529 goto bad; 529 goto bad;
530 530
531 src4 = &src->sin_addr; 531 src4 = &src->sin_addr;
532 sport = &src->sin_port; 532 sport = &src->sin_port;
533 dst4 = &dst->sin_addr; 533 dst4 = &dst->sin_addr;
534 dport = &dst->sin_port; 534 dport = &dst->sin_port;
535 535
536 if (IN_MULTICAST(dst4->s_addr) || 536 if (IN_MULTICAST(dst4->s_addr) ||
537 in_broadcast(*dst4, m->m_pkthdr.rcvif)) { 537 in_broadcast(*dst4, m->m_pkthdr.rcvif)) {
538 /* 538 /*
539 * Deliver a multicast or broadcast datagram to *all* sockets 539 * Deliver a multicast or broadcast datagram to *all* sockets
540 * for which the local and remote addresses and ports match 540 * for which the local and remote addresses and ports match
541 * those of the incoming datagram. This allows more than 541 * those of the incoming datagram. This allows more than
542 * one process to receive multi/broadcasts on the same port. 542 * one process to receive multi/broadcasts on the same port.
543 * (This really ought to be done for unicast datagrams as 543 * (This really ought to be done for unicast datagrams as
544 * well, but that would cause problems with existing 544 * well, but that would cause problems with existing
545 * applications that open both address-specific sockets and 545 * applications that open both address-specific sockets and
546 * a wildcard socket listening to the same port -- they would 546 * a wildcard socket listening to the same port -- they would
547 * end up receiving duplicates of every unicast datagram. 547 * end up receiving duplicates of every unicast datagram.
548 * Those applications open the multiple sockets to overcome an 548 * Those applications open the multiple sockets to overcome an
549 * inadequacy of the UDP socket interface, but for backwards 549 * inadequacy of the UDP socket interface, but for backwards
550 * compatibility we avoid the problem here rather than 550 * compatibility we avoid the problem here rather than
551 * fixing the interface. Maybe 4.5BSD will remedy this?) 551 * fixing the interface. Maybe 4.5BSD will remedy this?)
552 */ 552 */
553 553
554 /* 554 /*
555 * KAME note: traditionally we dropped udpiphdr from mbuf here. 555 * KAME note: traditionally we dropped udpiphdr from mbuf here.
556 * we need udpiphdr for IPsec processing so we do that later. 556 * we need udpiphdr for IPsec processing so we do that later.
557 */ 557 */
558 /* 558 /*
559 * Locate pcb(s) for datagram. 559 * Locate pcb(s) for datagram.
560 */ 560 */
561 TAILQ_FOREACH(inph, &udbtable.inpt_queue, inph_queue) { 561 TAILQ_FOREACH(inph, &udbtable.inpt_queue, inph_queue) {
562 inp = (struct inpcb *)inph; 562 inp = (struct inpcb *)inph;
563 if (inp->inp_af != AF_INET) 563 if (inp->inp_af != AF_INET)
564 continue; 564 continue;
565 565
566 if (inp->inp_lport != *dport) 566 if (inp->inp_lport != *dport)
567 continue; 567 continue;
568 if (!in_nullhost(inp->inp_laddr)) { 568 if (!in_nullhost(inp->inp_laddr)) {
569 if (!in_hosteq(inp->inp_laddr, *dst4)) 569 if (!in_hosteq(inp->inp_laddr, *dst4))
570 continue; 570 continue;
571 } 571 }
572 if (!in_nullhost(inp->inp_faddr)) { 572 if (!in_nullhost(inp->inp_faddr)) {
573 if (!in_hosteq(inp->inp_faddr, *src4) || 573 if (!in_hosteq(inp->inp_faddr, *src4) ||
574 inp->inp_fport != *sport) 574 inp->inp_fport != *sport)
575 continue; 575 continue;
576 } 576 }
577 577
578 udp4_sendup(m, off, (struct sockaddr *)src, 578 udp4_sendup(m, off, (struct sockaddr *)src,
579 inp->inp_socket); 579 inp->inp_socket);
580 rcvcnt++; 580 rcvcnt++;
581 581
582 /* 582 /*
583 * Don't look for additional matches if this one does 583 * Don't look for additional matches if this one does
584 * not have either the SO_REUSEPORT or SO_REUSEADDR 584 * not have either the SO_REUSEPORT or SO_REUSEADDR
585 * socket options set. This heuristic avoids searching 585 * socket options set. This heuristic avoids searching
586 * through all pcbs in the common case of a non-shared 586 * through all pcbs in the common case of a non-shared
587 * port. It assumes that an application will never 587 * port. It assumes that an application will never
588 * clear these options after setting them. 588 * clear these options after setting them.
589 */ 589 */
590 if ((inp->inp_socket->so_options & 590 if ((inp->inp_socket->so_options &
591 (SO_REUSEPORT|SO_REUSEADDR)) == 0) 591 (SO_REUSEPORT|SO_REUSEADDR)) == 0)
592 break; 592 break;
593 } 593 }
594 } else { 594 } else {
595 /* 595 /*
596 * Locate pcb for datagram. 596 * Locate pcb for datagram.
597 */ 597 */
598 inp = in_pcblookup_connect(&udbtable, *src4, *sport, *dst4, 598 inp = in_pcblookup_connect(&udbtable, *src4, *sport, *dst4,
599 *dport, 0); 599 *dport, 0);
600 if (inp == 0) { 600 if (inp == 0) {
601 UDP_STATINC(UDP_STAT_PCBHASHMISS); 601 UDP_STATINC(UDP_STAT_PCBHASHMISS);
602 inp = in_pcblookup_bind(&udbtable, *dst4, *dport); 602 inp = in_pcblookup_bind(&udbtable, *dst4, *dport);
603 if (inp == 0) 603 if (inp == 0)
604 return rcvcnt; 604 return rcvcnt;
605 } 605 }
606 606
607#ifdef IPSEC 607#ifdef IPSEC
608 /* Handle ESP over UDP */ 608 /* Handle ESP over UDP */
609 if (inp->inp_flags & INP_ESPINUDP_ALL) { 609 if (inp->inp_flags & INP_ESPINUDP_ALL) {
610 struct sockaddr *sa = (struct sockaddr *)src; 610 struct sockaddr *sa = (struct sockaddr *)src;
611 611
612 switch(udp4_espinudp(mp, off, sa, inp->inp_socket)) { 612 switch(udp4_espinudp(mp, off, sa, inp->inp_socket)) {
613 case -1: /* Error, m was freeed */ 613 case -1: /* Error, m was freeed */
614 rcvcnt = -1; 614 rcvcnt = -1;
615 goto bad; 615 goto bad;
616 break; 616 break;
617 617
618 case 1: /* ESP over UDP */ 618 case 1: /* ESP over UDP */
619 rcvcnt++; 619 rcvcnt++;
620 goto bad; 620 goto bad;
621 break; 621 break;
622 622
623 case 0: /* plain UDP */ 623 case 0: /* plain UDP */
624 default: /* Unexpected */ 624 default: /* Unexpected */
625 /*  625 /*
626 * Normal UDP processing will take place  626 * Normal UDP processing will take place
627 * m may have changed. 627 * m may have changed.
628 */ 628 */
629 m = *mp; 629 m = *mp;
630 break; 630 break;
631 } 631 }
632 } 632 }
633#endif 633#endif
634 634
635 /* 635 /*
636 * Check the minimum TTL for socket. 636 * Check the minimum TTL for socket.
637 */ 637 */
638 if (mtod(m, struct ip *)->ip_ttl < inp->inp_ip_minttl) 638 if (mtod(m, struct ip *)->ip_ttl < inp->inp_ip_minttl)
639 goto bad; 639 goto bad;
640 640
641 udp4_sendup(m, off, (struct sockaddr *)src, inp->inp_socket); 641 udp4_sendup(m, off, (struct sockaddr *)src, inp->inp_socket);
642 rcvcnt++; 642 rcvcnt++;
643 } 643 }
644 644
645bad: 645bad:
646 return rcvcnt; 646 return rcvcnt;
647} 647}
648#endif 648#endif
649 649
650#ifdef INET 650#ifdef INET
651/* 651/*
652 * Notify a udp user of an asynchronous error; 652 * Notify a udp user of an asynchronous error;
653 * just wake up so that he can collect error status. 653 * just wake up so that he can collect error status.
654 */ 654 */
655static void 655static void
656udp_notify(struct inpcb *inp, int errno) 656udp_notify(struct inpcb *inp, int errno)
657{ 657{
658 inp->inp_socket->so_error = errno; 658 inp->inp_socket->so_error = errno;
659 sorwakeup(inp->inp_socket); 659 sorwakeup(inp->inp_socket);
660 sowwakeup(inp->inp_socket); 660 sowwakeup(inp->inp_socket);
661} 661}
662 662
663void * 663void *
664udp_ctlinput(int cmd, const struct sockaddr *sa, void *v) 664udp_ctlinput(int cmd, const struct sockaddr *sa, void *v)
665{ 665{
666 struct ip *ip = v; 666 struct ip *ip = v;
667 struct udphdr *uh; 667 struct udphdr *uh;
668 void (*notify)(struct inpcb *, int) = udp_notify; 668 void (*notify)(struct inpcb *, int) = udp_notify;
669 int errno; 669 int errno;
670 670
671 if (sa->sa_family != AF_INET 671 if (sa->sa_family != AF_INET
672 || sa->sa_len != sizeof(struct sockaddr_in)) 672 || sa->sa_len != sizeof(struct sockaddr_in))
673 return NULL; 673 return NULL;
674 if ((unsigned)cmd >= PRC_NCMDS) 674 if ((unsigned)cmd >= PRC_NCMDS)
675 return NULL; 675 return NULL;
676 errno = inetctlerrmap[cmd]; 676 errno = inetctlerrmap[cmd];
677 if (PRC_IS_REDIRECT(cmd)) 677 if (PRC_IS_REDIRECT(cmd))
678 notify = in_rtchange, ip = 0; 678 notify = in_rtchange, ip = 0;
679 else if (cmd == PRC_HOSTDEAD) 679 else if (cmd == PRC_HOSTDEAD)
680 ip = 0; 680 ip = 0;
681 else if (errno == 0) 681 else if (errno == 0)
682 return NULL; 682 return NULL;
683 if (ip) { 683 if (ip) {
684 uh = (struct udphdr *)((char *)ip + (ip->ip_hl << 2)); 684 uh = (struct udphdr *)((char *)ip + (ip->ip_hl << 2));
685 in_pcbnotify(&udbtable, satocsin(sa)->sin_addr, uh->uh_dport, 685 in_pcbnotify(&udbtable, satocsin(sa)->sin_addr, uh->uh_dport,
686 ip->ip_src, uh->uh_sport, errno, notify); 686 ip->ip_src, uh->uh_sport, errno, notify);
687 687
688 /* XXX mapped address case */ 688 /* XXX mapped address case */
689 } else 689 } else
690 in_pcbnotifyall(&udbtable, satocsin(sa)->sin_addr, errno, 690 in_pcbnotifyall(&udbtable, satocsin(sa)->sin_addr, errno,
691 notify); 691 notify);
692 return NULL; 692 return NULL;
693} 693}
694 694
695int 695int
696udp_ctloutput(int op, struct socket *so, struct sockopt *sopt) 696udp_ctloutput(int op, struct socket *so, struct sockopt *sopt)
697{ 697{
698 int s; 698 int s;
699 int error = 0; 699 int error = 0;
700 struct inpcb *inp; 700 struct inpcb *inp;
701 int family; 701 int family;
702 int optval; 702 int optval;
703 703
704 family = so->so_proto->pr_domain->dom_family; 704 family = so->so_proto->pr_domain->dom_family;
705 705
706 s = splsoftnet(); 706 s = splsoftnet();
707 switch (family) { 707 switch (family) {
708#ifdef INET 708#ifdef INET
709 case PF_INET: 709 case PF_INET:
710 if (sopt->sopt_level != IPPROTO_UDP) { 710 if (sopt->sopt_level != IPPROTO_UDP) {
711 error = ip_ctloutput(op, so, sopt); 711 error = ip_ctloutput(op, so, sopt);
712 goto end; 712 goto end;
713 } 713 }
714 break; 714 break;
715#endif 715#endif
716#ifdef INET6 716#ifdef INET6
717 case PF_INET6: 717 case PF_INET6:
718 if (sopt->sopt_level != IPPROTO_UDP) { 718 if (sopt->sopt_level != IPPROTO_UDP) {
719 error = ip6_ctloutput(op, so, sopt); 719 error = ip6_ctloutput(op, so, sopt);
720 goto end; 720 goto end;
721 } 721 }
722 break; 722 break;
723#endif 723#endif
724 default: 724 default:
725 error = EAFNOSUPPORT; 725 error = EAFNOSUPPORT;
726 goto end; 726 goto end;
727 } 727 }
728 728
729 729
730 switch (op) { 730 switch (op) {
731 case PRCO_SETOPT: 731 case PRCO_SETOPT:
732 inp = sotoinpcb(so); 732 inp = sotoinpcb(so);
733 733
734 switch (sopt->sopt_name) { 734 switch (sopt->sopt_name) {
735 case UDP_ENCAP: 735 case UDP_ENCAP:
736 error = sockopt_getint(sopt, &optval); 736 error = sockopt_getint(sopt, &optval);
737 if (error) 737 if (error)
738 break; 738 break;
739 739
740 switch(optval) { 740 switch(optval) {
741 case 0: 741 case 0:
742 inp->inp_flags &= ~INP_ESPINUDP_ALL; 742 inp->inp_flags &= ~INP_ESPINUDP_ALL;
743 break; 743 break;
744 744
745 case UDP_ENCAP_ESPINUDP: 745 case UDP_ENCAP_ESPINUDP:
746 inp->inp_flags &= ~INP_ESPINUDP_ALL; 746 inp->inp_flags &= ~INP_ESPINUDP_ALL;
747 inp->inp_flags |= INP_ESPINUDP; 747 inp->inp_flags |= INP_ESPINUDP;
748 break; 748 break;
749 749
750 case UDP_ENCAP_ESPINUDP_NON_IKE: 750 case UDP_ENCAP_ESPINUDP_NON_IKE:
751 inp->inp_flags &= ~INP_ESPINUDP_ALL; 751 inp->inp_flags &= ~INP_ESPINUDP_ALL;
752 inp->inp_flags |= INP_ESPINUDP_NON_IKE; 752 inp->inp_flags |= INP_ESPINUDP_NON_IKE;
753 break; 753 break;
754 default: 754 default:
755 error = EINVAL; 755 error = EINVAL;
756 break; 756 break;
757 } 757 }
758 break; 758 break;
759  759
760 default: 760 default:
761 error = ENOPROTOOPT; 761 error = ENOPROTOOPT;
762 break; 762 break;
763 } 763 }
764 break; 764 break;
765 765
766 default: 766 default:
767 error = EINVAL; 767 error = EINVAL;
768 break; 768 break;
769 } 769 }
770 770
771end: 771end:
772 splx(s); 772 splx(s);
773 return error; 773 return error;
774} 774}
775 775
776 776
777int 777int
778udp_output(struct mbuf *m, ...) 778udp_output(struct mbuf *m, struct inpcb *inp)
779{ 779{
780 struct inpcb *inp; 
781 struct udpiphdr *ui; 780 struct udpiphdr *ui;
782 struct route *ro; 781 struct route *ro;
783 int len = m->m_pkthdr.len; 782 int len = m->m_pkthdr.len;
784 int error = 0; 783 int error = 0;
785 va_list ap; 
786 784
787 MCLAIM(m, &udp_tx_mowner); 785 MCLAIM(m, &udp_tx_mowner);
788 va_start(ap, m); 
789 inp = va_arg(ap, struct inpcb *); 
790 va_end(ap); 
791 786
792 /* 787 /*
793 * Calculate data length and get a mbuf 788 * Calculate data length and get a mbuf
794 * for UDP and IP headers. 789 * for UDP and IP headers.
795 */ 790 */
796 M_PREPEND(m, sizeof(struct udpiphdr), M_DONTWAIT); 791 M_PREPEND(m, sizeof(struct udpiphdr), M_DONTWAIT);
797 if (m == 0) { 792 if (m == 0) {
798 error = ENOBUFS; 793 error = ENOBUFS;
799 goto release; 794 goto release;
800 } 795 }
801 796
802 /* 797 /*
803 * Compute the packet length of the IP header, and 798 * Compute the packet length of the IP header, and
804 * punt if the length looks bogus. 799 * punt if the length looks bogus.
805 */ 800 */
806 if (len + sizeof(struct udpiphdr) > IP_MAXPACKET) { 801 if (len + sizeof(struct udpiphdr) > IP_MAXPACKET) {
807 error = EMSGSIZE; 802 error = EMSGSIZE;
808 goto release; 803 goto release;
809 } 804 }
810 805
811 /* 806 /*
812 * Fill in mbuf with extended UDP header 807 * Fill in mbuf with extended UDP header
813 * and addresses and length put into network format. 808 * and addresses and length put into network format.
814 */ 809 */
815 ui = mtod(m, struct udpiphdr *); 810 ui = mtod(m, struct udpiphdr *);
816 ui->ui_pr = IPPROTO_UDP; 811 ui->ui_pr = IPPROTO_UDP;
817 ui->ui_src = inp->inp_laddr; 812 ui->ui_src = inp->inp_laddr;
818 ui->ui_dst = inp->inp_faddr; 813 ui->ui_dst = inp->inp_faddr;
819 ui->ui_sport = inp->inp_lport; 814 ui->ui_sport = inp->inp_lport;
820 ui->ui_dport = inp->inp_fport; 815 ui->ui_dport = inp->inp_fport;
821 ui->ui_ulen = htons((u_int16_t)len + sizeof(struct udphdr)); 816 ui->ui_ulen = htons((u_int16_t)len + sizeof(struct udphdr));
822 817
823 ro = &inp->inp_route; 818 ro = &inp->inp_route;
824 819
825 /* 820 /*
826 * Set up checksum and output datagram. 821 * Set up checksum and output datagram.
827 */ 822 */
828 if (udpcksum) { 823 if (udpcksum) {
829 /* 824 /*
830 * XXX Cache pseudo-header checksum part for 825 * XXX Cache pseudo-header checksum part for
831 * XXX "connected" UDP sockets. 826 * XXX "connected" UDP sockets.
832 */ 827 */
833 ui->ui_sum = in_cksum_phdr(ui->ui_src.s_addr, 828 ui->ui_sum = in_cksum_phdr(ui->ui_src.s_addr,
834 ui->ui_dst.s_addr, htons((u_int16_t)len + 829 ui->ui_dst.s_addr, htons((u_int16_t)len +
835 sizeof(struct udphdr) + IPPROTO_UDP)); 830 sizeof(struct udphdr) + IPPROTO_UDP));
836 m->m_pkthdr.csum_flags = M_CSUM_UDPv4; 831 m->m_pkthdr.csum_flags = M_CSUM_UDPv4;
837 m->m_pkthdr.csum_data = offsetof(struct udphdr, uh_sum); 832 m->m_pkthdr.csum_data = offsetof(struct udphdr, uh_sum);
838 } else 833 } else
839 ui->ui_sum = 0; 834 ui->ui_sum = 0;
840 ((struct ip *)ui)->ip_len = htons(sizeof (struct udpiphdr) + len); 835 ((struct ip *)ui)->ip_len = htons(sizeof (struct udpiphdr) + len);
841 ((struct ip *)ui)->ip_ttl = inp->inp_ip.ip_ttl; /* XXX */ 836 ((struct ip *)ui)->ip_ttl = inp->inp_ip.ip_ttl; /* XXX */
842 ((struct ip *)ui)->ip_tos = inp->inp_ip.ip_tos; /* XXX */ 837 ((struct ip *)ui)->ip_tos = inp->inp_ip.ip_tos; /* XXX */
843 UDP_STATINC(UDP_STAT_OPACKETS); 838 UDP_STATINC(UDP_STAT_OPACKETS);
844 839
845 return (ip_output(m, inp->inp_options, ro, 840 return (ip_output(m, inp->inp_options, ro,
846 inp->inp_socket->so_options & (SO_DONTROUTE | SO_BROADCAST), 841 inp->inp_socket->so_options & (SO_DONTROUTE | SO_BROADCAST),
847 inp->inp_moptions, inp->inp_socket)); 842 inp->inp_moptions, inp->inp_socket));
848 843
849release: 844release:
850 m_freem(m); 845 m_freem(m);
851 return (error); 846 return (error);
852} 847}
853 848
854static int 849static int
855udp_attach(struct socket *so, int proto) 850udp_attach(struct socket *so, int proto)
856{ 851{
857 struct inpcb *inp; 852 struct inpcb *inp;
858 int error; 853 int error;
859 854
860 KASSERT(sotoinpcb(so) == NULL); 855 KASSERT(sotoinpcb(so) == NULL);
861 856
862 /* Assign the lock (must happen even if we will error out). */ 857 /* Assign the lock (must happen even if we will error out). */
863 sosetlock(so); 858 sosetlock(so);
864 859
865#ifdef MBUFTRACE 860#ifdef MBUFTRACE
866 so->so_mowner = &udp_mowner; 861 so->so_mowner = &udp_mowner;
867 so->so_rcv.sb_mowner = &udp_rx_mowner; 862 so->so_rcv.sb_mowner = &udp_rx_mowner;
868 so->so_snd.sb_mowner = &udp_tx_mowner; 863 so->so_snd.sb_mowner = &udp_tx_mowner;
869#endif 864#endif
870 if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) { 865 if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) {
871 error = soreserve(so, udp_sendspace, udp_recvspace); 866 error = soreserve(so, udp_sendspace, udp_recvspace);
872 if (error) { 867 if (error) {
873 return error; 868 return error;
874 } 869 }
875 } 870 }
876 871
877 error = in_pcballoc(so, &udbtable); 872 error = in_pcballoc(so, &udbtable);
878 if (error) { 873 if (error) {
879 return error; 874 return error;
880 } 875 }
881 inp = sotoinpcb(so); 876 inp = sotoinpcb(so);
882 inp->inp_ip.ip_ttl = ip_defttl; 877 inp->inp_ip.ip_ttl = ip_defttl;
883 KASSERT(solocked(so)); 878 KASSERT(solocked(so));
884 879
885 return error; 880 return error;
886} 881}
887 882
888static void 883static void
889udp_detach(struct socket *so) 884udp_detach(struct socket *so)
890{ 885{
891 struct inpcb *inp; 886 struct inpcb *inp;
892 887
893 KASSERT(solocked(so)); 888 KASSERT(solocked(so));
894 inp = sotoinpcb(so); 889 inp = sotoinpcb(so);
895 KASSERT(inp != NULL); 890 KASSERT(inp != NULL);
896 in_pcbdetach(inp); 891 in_pcbdetach(inp);
897} 892}
898 893
899static int 894static int
900udp_accept(struct socket *so, struct sockaddr *nam) 895udp_accept(struct socket *so, struct sockaddr *nam)
901{ 896{
902 KASSERT(solocked(so)); 897 KASSERT(solocked(so));
903 898
904 panic("udp_accept"); 899 panic("udp_accept");
905 900
906 return EOPNOTSUPP; 901 return EOPNOTSUPP;
907} 902}
908 903
909static int 904static int
910udp_bind(struct socket *so, struct sockaddr *nam, struct lwp *l) 905udp_bind(struct socket *so, struct sockaddr *nam, struct lwp *l)
911{ 906{
912 struct inpcb *inp = sotoinpcb(so); 907 struct inpcb *inp = sotoinpcb(so);
913 struct sockaddr_in *sin = (struct sockaddr_in *)nam; 908 struct sockaddr_in *sin = (struct sockaddr_in *)nam;
914 int error = 0; 909 int error = 0;
915 int s; 910 int s;
916 911
917 KASSERT(solocked(so)); 912 KASSERT(solocked(so));
918 KASSERT(inp != NULL); 913 KASSERT(inp != NULL);
919 KASSERT(nam != NULL); 914 KASSERT(nam != NULL);
920 915
921 s = splsoftnet(); 916 s = splsoftnet();
922 error = in_pcbbind(inp, sin, l); 917 error = in_pcbbind(inp, sin, l);
923 splx(s); 918 splx(s);
924 919
925 return error; 920 return error;
926} 921}
927 922
928static int 923static int
929udp_listen(struct socket *so, struct lwp *l) 924udp_listen(struct socket *so, struct lwp *l)
930{ 925{
931 KASSERT(solocked(so)); 926 KASSERT(solocked(so));
932 927
933 return EOPNOTSUPP; 928 return EOPNOTSUPP;
934} 929}
935 930
936static int 931static int
937udp_connect(struct socket *so, struct sockaddr *nam, struct lwp *l) 932udp_connect(struct socket *so, struct sockaddr *nam, struct lwp *l)
938{ 933{
939 struct inpcb *inp = sotoinpcb(so); 934 struct inpcb *inp = sotoinpcb(so);
940 int error = 0; 935 int error = 0;
941 int s; 936 int s;
942 937
943 KASSERT(solocked(so)); 938 KASSERT(solocked(so));
944 KASSERT(inp != NULL); 939 KASSERT(inp != NULL);
945 KASSERT(nam != NULL); 940 KASSERT(nam != NULL);
946 941
947 s = splsoftnet(); 942 s = splsoftnet();
948 error = in_pcbconnect(inp, (struct sockaddr_in *)nam, l); 943 error = in_pcbconnect(inp, (struct sockaddr_in *)nam, l);
949 if (! error) 944 if (! error)
950 soisconnected(so); 945 soisconnected(so);
951 splx(s); 946 splx(s);
952 return error; 947 return error;
953} 948}
954 949
955static int 950static int
956udp_connect2(struct socket *so, struct socket *so2) 951udp_connect2(struct socket *so, struct socket *so2)
957{ 952{
958 KASSERT(solocked(so)); 953 KASSERT(solocked(so));
959 954
960 return EOPNOTSUPP; 955 return EOPNOTSUPP;
961} 956}
962 957
963static int 958static int
964udp_disconnect(struct socket *so) 959udp_disconnect(struct socket *so)
965{ 960{
966 struct inpcb *inp = sotoinpcb(so); 961 struct inpcb *inp = sotoinpcb(so);
967 int s; 962 int s;
968 963
969 KASSERT(solocked(so)); 964 KASSERT(solocked(so));
970 KASSERT(inp != NULL); 965 KASSERT(inp != NULL);
971 966
972 s = splsoftnet(); 967 s = splsoftnet();
973 /*soisdisconnected(so);*/ 968 /*soisdisconnected(so);*/
974 so->so_state &= ~SS_ISCONNECTED; /* XXX */ 969 so->so_state &= ~SS_ISCONNECTED; /* XXX */
975 in_pcbdisconnect(inp); 970 in_pcbdisconnect(inp);
976 inp->inp_laddr = zeroin_addr; /* XXX */ 971 inp->inp_laddr = zeroin_addr; /* XXX */
977 in_pcbstate(inp, INP_BOUND); /* XXX */ 972 in_pcbstate(inp, INP_BOUND); /* XXX */
978 splx(s); 973 splx(s);
979 974
980 return 0; 975 return 0;
981} 976}
982 977
983static int 978static int
984udp_shutdown(struct socket *so) 979udp_shutdown(struct socket *so)
985{ 980{
986 int s; 981 int s;
987 982
988 KASSERT(solocked(so)); 983 KASSERT(solocked(so));
989 984
990 s = splsoftnet(); 985 s = splsoftnet();
991 socantsendmore(so); 986 socantsendmore(so);
992 splx(s); 987 splx(s);
993 988
994 return 0; 989 return 0;
995} 990}
996 991
997static int 992static int
998udp_abort(struct socket *so) 993udp_abort(struct socket *so)
999{ 994{
1000 KASSERT(solocked(so)); 995 KASSERT(solocked(so));
1001 996
1002 panic("udp_abort"); 997 panic("udp_abort");
1003 998
1004 return EOPNOTSUPP; 999 return EOPNOTSUPP;
1005} 1000}
1006 1001
1007static int 1002static int
1008udp_ioctl(struct socket *so, u_long cmd, void *nam, struct ifnet *ifp) 1003udp_ioctl(struct socket *so, u_long cmd, void *nam, struct ifnet *ifp)
1009{ 1004{
1010 return in_control(so, cmd, nam, ifp); 1005 return in_control(so, cmd, nam, ifp);
1011} 1006}
1012 1007
1013static int 1008static int
1014udp_stat(struct socket *so, struct stat *ub) 1009udp_stat(struct socket *so, struct stat *ub)
1015{ 1010{
1016 KASSERT(solocked(so)); 1011 KASSERT(solocked(so));
1017 1012
1018 /* stat: don't bother with a blocksize. */ 1013 /* stat: don't bother with a blocksize. */
1019 return 0; 1014 return 0;
1020} 1015}
1021 1016
1022static int 1017static int
1023udp_peeraddr(struct socket *so, struct sockaddr *nam) 1018udp_peeraddr(struct socket *so, struct sockaddr *nam)
1024{ 1019{
1025 int s; 1020 int s;
1026 1021
1027 KASSERT(solocked(so)); 1022 KASSERT(solocked(so));
1028 KASSERT(sotoinpcb(so) != NULL); 1023 KASSERT(sotoinpcb(so) != NULL);
1029 KASSERT(nam != NULL); 1024 KASSERT(nam != NULL);
1030 1025
1031 s = splsoftnet(); 1026 s = splsoftnet();
1032 in_setpeeraddr(sotoinpcb(so), (struct sockaddr_in *)nam); 1027 in_setpeeraddr(sotoinpcb(so), (struct sockaddr_in *)nam);
1033 splx(s); 1028 splx(s);
1034 1029
1035 return 0; 1030 return 0;
1036} 1031}
1037 1032
1038static int 1033static int
1039udp_sockaddr(struct socket *so, struct sockaddr *nam) 1034udp_sockaddr(struct socket *so, struct sockaddr *nam)
1040{ 1035{
1041 int s; 1036 int s;
1042 1037
1043 KASSERT(solocked(so)); 1038 KASSERT(solocked(so));
1044 KASSERT(sotoinpcb(so) != NULL); 1039 KASSERT(sotoinpcb(so) != NULL);
1045 KASSERT(nam != NULL); 1040 KASSERT(nam != NULL);
1046 1041
1047 s = splsoftnet(); 1042 s = splsoftnet();
1048 in_setsockaddr(sotoinpcb(so), (struct sockaddr_in *)nam); 1043 in_setsockaddr(sotoinpcb(so), (struct sockaddr_in *)nam);
1049 splx(s); 1044 splx(s);
1050 1045
1051 return 0; 1046 return 0;
1052} 1047}
1053 1048
1054static int 1049static int
1055udp_rcvd(struct socket *so, int flags, struct lwp *l) 1050udp_rcvd(struct socket *so, int flags, struct lwp *l)
1056{ 1051{
1057 KASSERT(solocked(so)); 1052 KASSERT(solocked(so));
1058 1053
1059 return EOPNOTSUPP; 1054 return EOPNOTSUPP;
1060} 1055}
1061 1056
1062static int 1057static int
1063udp_recvoob(struct socket *so, struct mbuf *m, int flags) 1058udp_recvoob(struct socket *so, struct mbuf *m, int flags)
1064{ 1059{
1065 KASSERT(solocked(so)); 1060 KASSERT(solocked(so));
1066 1061
1067 return EOPNOTSUPP; 1062 return EOPNOTSUPP;
1068} 1063}
1069 1064
1070static int 1065static int
1071udp_send(struct socket *so, struct mbuf *m, struct sockaddr *nam, 1066udp_send(struct socket *so, struct mbuf *m, struct sockaddr *nam,
1072 struct mbuf *control, struct lwp *l) 1067 struct mbuf *control, struct lwp *l)
1073{ 1068{
1074 struct inpcb *inp = sotoinpcb(so); 1069 struct inpcb *inp = sotoinpcb(so);
1075 int error = 0; 1070 int error = 0;
1076 struct in_addr laddr; /* XXX */ 1071 struct in_addr laddr; /* XXX */
1077 int s; 1072 int s;
1078 1073
1079 KASSERT(solocked(so)); 1074 KASSERT(solocked(so));
1080 KASSERT(inp != NULL); 1075 KASSERT(inp != NULL);
1081 KASSERT(m != NULL); 1076 KASSERT(m != NULL);
1082 1077
1083 if (control && control->m_len) { 1078 if (control && control->m_len) {
1084 m_freem(control); 1079 m_freem(control);
1085 m_freem(m); 1080 m_freem(m);
1086 return EINVAL; 1081 return EINVAL;
1087 } 1082 }
1088 1083
1089 memset(&laddr, 0, sizeof laddr); 1084 memset(&laddr, 0, sizeof laddr);
1090 1085
1091 s = splsoftnet(); 1086 s = splsoftnet();
1092 if (nam) { 1087 if (nam) {
1093 laddr = inp->inp_laddr; /* XXX */ 1088 laddr = inp->inp_laddr; /* XXX */
1094 if ((so->so_state & SS_ISCONNECTED) != 0) { 1089 if ((so->so_state & SS_ISCONNECTED) != 0) {
1095 error = EISCONN; 1090 error = EISCONN;
1096 goto die; 1091 goto die;
1097 } 1092 }
1098 error = in_pcbconnect(inp, (struct sockaddr_in *)nam, l); 1093 error = in_pcbconnect(inp, (struct sockaddr_in *)nam, l);
1099 if (error) 1094 if (error)
1100 goto die; 1095 goto die;
1101 } else { 1096 } else {
1102 if ((so->so_state & SS_ISCONNECTED) == 0) { 1097 if ((so->so_state & SS_ISCONNECTED) == 0) {
1103 error = ENOTCONN; 1098 error = ENOTCONN;
1104 goto die; 1099 goto die;
1105 } 1100 }
1106 } 1101 }
1107 error = udp_output(m, inp); 1102 error = udp_output(m, inp);
1108 m = NULL; 1103 m = NULL;
1109 if (nam) { 1104 if (nam) {
1110 in_pcbdisconnect(inp); 1105 in_pcbdisconnect(inp);
1111 inp->inp_laddr = laddr; /* XXX */ 1106 inp->inp_laddr = laddr; /* XXX */
1112 in_pcbstate(inp, INP_BOUND); /* XXX */ 1107 in_pcbstate(inp, INP_BOUND); /* XXX */
1113 } 1108 }
1114 die: 1109 die:
1115 if (m) 1110 if (m)
1116 m_freem(m); 1111 m_freem(m);
1117 1112
1118 splx(s); 1113 splx(s);
1119 return error; 1114 return error;
1120} 1115}
1121 1116
1122static int 1117static int
1123udp_sendoob(struct socket *so, struct mbuf *m, struct mbuf *control) 1118udp_sendoob(struct socket *so, struct mbuf *m, struct mbuf *control)
1124{ 1119{
1125 KASSERT(solocked(so)); 1120 KASSERT(solocked(so));
1126 1121
1127 m_freem(m); 1122 m_freem(m);
1128 m_freem(control); 1123 m_freem(control);
1129 1124
1130 return EOPNOTSUPP; 1125 return EOPNOTSUPP;
1131} 1126}
1132 1127
1133static int 1128static int
1134udp_purgeif(struct socket *so, struct ifnet *ifp) 1129udp_purgeif(struct socket *so, struct ifnet *ifp)
1135{ 1130{
1136 int s; 1131 int s;
1137 1132
1138 s = splsoftnet(); 1133 s = splsoftnet();
1139 mutex_enter(softnet_lock); 1134 mutex_enter(softnet_lock);
1140 in_pcbpurgeif0(&udbtable, ifp); 1135 in_pcbpurgeif0(&udbtable, ifp);
1141 in_purgeif(ifp); 1136 in_purgeif(ifp);
1142 in_pcbpurgeif(&udbtable, ifp); 1137 in_pcbpurgeif(&udbtable, ifp);
1143 mutex_exit(softnet_lock); 1138 mutex_exit(softnet_lock);
1144 splx(s); 1139 splx(s);
1145 1140
1146 return 0; 1141 return 0;
1147} 1142}
1148 1143
1149static int 1144static int
1150sysctl_net_inet_udp_stats(SYSCTLFN_ARGS) 1145sysctl_net_inet_udp_stats(SYSCTLFN_ARGS)
1151{ 1146{
1152 1147
1153 return (NETSTAT_SYSCTL(udpstat_percpu, UDP_NSTATS)); 1148 return (NETSTAT_SYSCTL(udpstat_percpu, UDP_NSTATS));
1154} 1149}
1155 1150
1156/* 1151/*
1157 * Sysctl for udp variables. 1152 * Sysctl for udp variables.
1158 */ 1153 */
1159static void 1154static void
1160sysctl_net_inet_udp_setup(struct sysctllog **clog) 1155sysctl_net_inet_udp_setup(struct sysctllog **clog)
1161{ 1156{
1162 1157
1163 sysctl_createv(clog, 0, NULL, NULL, 1158 sysctl_createv(clog, 0, NULL, NULL,
1164 CTLFLAG_PERMANENT, 1159 CTLFLAG_PERMANENT,
1165 CTLTYPE_NODE, "inet", NULL, 1160 CTLTYPE_NODE, "inet", NULL,
1166 NULL, 0, NULL, 0, 1161 NULL, 0, NULL, 0,
1167 CTL_NET, PF_INET, CTL_EOL); 1162 CTL_NET, PF_INET, CTL_EOL);
1168 sysctl_createv(clog, 0, NULL, NULL, 1163 sysctl_createv(clog, 0, NULL, NULL,
1169 CTLFLAG_PERMANENT, 1164 CTLFLAG_PERMANENT,
1170 CTLTYPE_NODE, "udp", 1165 CTLTYPE_NODE, "udp",
1171 SYSCTL_DESCR("UDPv4 related settings"), 1166 SYSCTL_DESCR("UDPv4 related settings"),
1172 NULL, 0, NULL, 0, 1167 NULL, 0, NULL, 0,
1173 CTL_NET, PF_INET, IPPROTO_UDP, CTL_EOL); 1168 CTL_NET, PF_INET, IPPROTO_UDP, CTL_EOL);
1174 1169
1175 sysctl_createv(clog, 0, NULL, NULL, 1170 sysctl_createv(clog, 0, NULL, NULL,
1176 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 1171 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
1177 CTLTYPE_INT, "checksum", 1172 CTLTYPE_INT, "checksum",
1178 SYSCTL_DESCR("Compute UDP checksums"), 1173 SYSCTL_DESCR("Compute UDP checksums"),
1179 NULL, 0, &udpcksum, 0, 1174 NULL, 0, &udpcksum, 0,
1180 CTL_NET, PF_INET, IPPROTO_UDP, UDPCTL_CHECKSUM, 1175 CTL_NET, PF_INET, IPPROTO_UDP, UDPCTL_CHECKSUM,
1181 CTL_EOL); 1176 CTL_EOL);
1182 sysctl_createv(clog, 0, NULL, NULL, 1177 sysctl_createv(clog, 0, NULL, NULL,
1183 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 1178 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
1184 CTLTYPE_INT, "sendspace", 1179 CTLTYPE_INT, "sendspace",
1185 SYSCTL_DESCR("Default UDP send buffer size"), 1180 SYSCTL_DESCR("Default UDP send buffer size"),
1186 NULL, 0, &udp_sendspace, 0, 1181 NULL, 0, &udp_sendspace, 0,
1187 CTL_NET, PF_INET, IPPROTO_UDP, UDPCTL_SENDSPACE, 1182 CTL_NET, PF_INET, IPPROTO_UDP, UDPCTL_SENDSPACE,
1188 CTL_EOL); 1183 CTL_EOL);
1189 sysctl_createv(clog, 0, NULL, NULL, 1184 sysctl_createv(clog, 0, NULL, NULL,
1190 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 1185 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
1191 CTLTYPE_INT, "recvspace", 1186 CTLTYPE_INT, "recvspace",
1192 SYSCTL_DESCR("Default UDP receive buffer size"), 1187 SYSCTL_DESCR("Default UDP receive buffer size"),
1193 NULL, 0, &udp_recvspace, 0, 1188 NULL, 0, &udp_recvspace, 0,
1194 CTL_NET, PF_INET, IPPROTO_UDP, UDPCTL_RECVSPACE, 1189 CTL_NET, PF_INET, IPPROTO_UDP, UDPCTL_RECVSPACE,
1195 CTL_EOL); 1190 CTL_EOL);
1196 sysctl_createv(clog, 0, NULL, NULL, 1191 sysctl_createv(clog, 0, NULL, NULL,
1197 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 1192 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
1198 CTLTYPE_INT, "do_loopback_cksum", 1193 CTLTYPE_INT, "do_loopback_cksum",
1199 SYSCTL_DESCR("Perform UDP checksum on loopback"), 1194 SYSCTL_DESCR("Perform UDP checksum on loopback"),
1200 NULL, 0, &udp_do_loopback_cksum, 0, 1195 NULL, 0, &udp_do_loopback_cksum, 0,
1201 CTL_NET, PF_INET, IPPROTO_UDP, UDPCTL_LOOPBACKCKSUM, 1196 CTL_NET, PF_INET, IPPROTO_UDP, UDPCTL_LOOPBACKCKSUM,
1202 CTL_EOL); 1197 CTL_EOL);
1203 sysctl_createv(clog, 0, NULL, NULL, 1198 sysctl_createv(clog, 0, NULL, NULL,
1204 CTLFLAG_PERMANENT, 1199 CTLFLAG_PERMANENT,
1205 CTLTYPE_STRUCT, "pcblist", 1200 CTLTYPE_STRUCT, "pcblist",
1206 SYSCTL_DESCR("UDP protocol control block list"), 1201 SYSCTL_DESCR("UDP protocol control block list"),
1207 sysctl_inpcblist, 0, &udbtable, 0, 1202 sysctl_inpcblist, 0, &udbtable, 0,
1208 CTL_NET, PF_INET, IPPROTO_UDP, CTL_CREATE, 1203 CTL_NET, PF_INET, IPPROTO_UDP, CTL_CREATE,
1209 CTL_EOL); 1204 CTL_EOL);
1210 sysctl_createv(clog, 0, NULL, NULL, 1205 sysctl_createv(clog, 0, NULL, NULL,
1211 CTLFLAG_PERMANENT, 1206 CTLFLAG_PERMANENT,
1212 CTLTYPE_STRUCT, "stats", 1207 CTLTYPE_STRUCT, "stats",
1213 SYSCTL_DESCR("UDP statistics"), 1208 SYSCTL_DESCR("UDP statistics"),
1214 sysctl_net_inet_udp_stats, 0, NULL, 0, 1209 sysctl_net_inet_udp_stats, 0, NULL, 0,
1215 CTL_NET, PF_INET, IPPROTO_UDP, UDPCTL_STATS, 1210 CTL_NET, PF_INET, IPPROTO_UDP, UDPCTL_STATS,
1216 CTL_EOL); 1211 CTL_EOL);
1217} 1212}
1218#endif 1213#endif
1219 1214
1220void 1215void
1221udp_statinc(u_int stat) 1216udp_statinc(u_int stat)
1222{ 1217{
1223 1218
1224 KASSERT(stat < UDP_NSTATS); 1219 KASSERT(stat < UDP_NSTATS);
1225 UDP_STATINC(stat); 1220 UDP_STATINC(stat);
1226} 1221}
1227 1222
1228#if defined(INET) && defined(IPSEC) 1223#if defined(INET) && defined(IPSEC)
1229/* 1224/*
1230 * Returns: 1225 * Returns:
1231 * 1 if the packet was processed 1226 * 1 if the packet was processed
1232 * 0 if normal UDP processing should take place 1227 * 0 if normal UDP processing should take place
1233 * -1 if an error occurent and m was freed 1228 * -1 if an error occurent and m was freed
1234 */ 1229 */
1235static int 1230static int
1236udp4_espinudp(struct mbuf **mp, int off, struct sockaddr *src, 1231udp4_espinudp(struct mbuf **mp, int off, struct sockaddr *src,
1237 struct socket *so) 1232 struct socket *so)
1238{ 1233{
1239 size_t len; 1234 size_t len;
1240 void *data; 1235 void *data;
1241 struct inpcb *inp; 1236 struct inpcb *inp;
1242 size_t skip = 0; 1237 size_t skip = 0;
1243 size_t minlen; 1238 size_t minlen;
1244 size_t iphdrlen; 1239 size_t iphdrlen;
1245 struct ip *ip; 1240 struct ip *ip;
1246 struct m_tag *tag; 1241 struct m_tag *tag;
1247 struct udphdr *udphdr; 1242 struct udphdr *udphdr;
1248 u_int16_t sport, dport; 1243 u_int16_t sport, dport;
1249 struct mbuf *m = *mp; 1244 struct mbuf *m = *mp;
1250 1245
1251 /* 1246 /*
1252 * Collapse the mbuf chain if the first mbuf is too short 1247 * Collapse the mbuf chain if the first mbuf is too short
1253 * The longest case is: UDP + non ESP marker + ESP 1248 * The longest case is: UDP + non ESP marker + ESP
1254 */ 1249 */
1255 minlen = off + sizeof(u_int64_t) + sizeof(struct esp); 1250 minlen = off + sizeof(u_int64_t) + sizeof(struct esp);
1256 if (minlen > m->m_pkthdr.len) 1251 if (minlen > m->m_pkthdr.len)
1257 minlen = m->m_pkthdr.len; 1252 minlen = m->m_pkthdr.len;
1258 1253
1259 if (m->m_len < minlen) { 1254 if (m->m_len < minlen) {
1260 if ((*mp = m_pullup(m, minlen)) == NULL) { 1255 if ((*mp = m_pullup(m, minlen)) == NULL) {
1261 printf("udp4_espinudp: m_pullup failed\n"); 1256 printf("udp4_espinudp: m_pullup failed\n");
1262 return -1; 1257 return -1;
1263 } 1258 }
1264 m = *mp; 1259 m = *mp;
1265 } 1260 }
1266 1261
1267 len = m->m_len - off; 1262 len = m->m_len - off;
1268 data = mtod(m, char *) + off; 1263 data = mtod(m, char *) + off;
1269 inp = sotoinpcb(so); 1264 inp = sotoinpcb(so);
1270 1265
1271 /* Ignore keepalive packets */ 1266 /* Ignore keepalive packets */
1272 if ((len == 1) && (*(unsigned char *)data == 0xff)) { 1267 if ((len == 1) && (*(unsigned char *)data == 0xff)) {
1273 m_free(m); 1268 m_free(m);
1274 *mp = NULL; /* avoid any further processiong by caller ... */ 1269 *mp = NULL; /* avoid any further processiong by caller ... */
1275 return 1; 1270 return 1;
1276 } 1271 }
1277 1272
1278 /* 1273 /*
1279 * Check that the payload is long enough to hold 1274 * Check that the payload is long enough to hold
1280 * an ESP header and compute the length of encapsulation 1275 * an ESP header and compute the length of encapsulation
1281 * header to remove 1276 * header to remove
1282 */ 1277 */
1283 if (inp->inp_flags & INP_ESPINUDP) { 1278 if (inp->inp_flags & INP_ESPINUDP) {
1284 u_int32_t *st = (u_int32_t *)data; 1279 u_int32_t *st = (u_int32_t *)data;
1285 1280
1286 if ((len <= sizeof(struct esp)) || (*st == 0)) 1281 if ((len <= sizeof(struct esp)) || (*st == 0))
1287 return 0; /* Normal UDP processing */ 1282 return 0; /* Normal UDP processing */
1288 1283
1289 skip = sizeof(struct udphdr); 1284 skip = sizeof(struct udphdr);
1290 } 1285 }
1291 1286
1292 if (inp->inp_flags & INP_ESPINUDP_NON_IKE) { 1287 if (inp->inp_flags & INP_ESPINUDP_NON_IKE) {
1293 u_int32_t *st = (u_int32_t *)data; 1288 u_int32_t *st = (u_int32_t *)data;
1294 1289
1295 if ((len <= sizeof(u_int64_t) + sizeof(struct esp)) 1290 if ((len <= sizeof(u_int64_t) + sizeof(struct esp))
1296 || ((st[0] | st[1]) != 0)) 1291 || ((st[0] | st[1]) != 0))
1297 return 0; /* Normal UDP processing */ 1292 return 0; /* Normal UDP processing */
1298 1293
1299 skip = sizeof(struct udphdr) + sizeof(u_int64_t); 1294 skip = sizeof(struct udphdr) + sizeof(u_int64_t);
1300 } 1295 }
1301 1296
1302 /* 1297 /*
1303 * Get the UDP ports. They are handled in network  1298 * Get the UDP ports. They are handled in network
1304 * order everywhere in IPSEC_NAT_T code. 1299 * order everywhere in IPSEC_NAT_T code.
1305 */ 1300 */
1306 udphdr = (struct udphdr *)((char *)data - skip); 1301 udphdr = (struct udphdr *)((char *)data - skip);
1307 sport = udphdr->uh_sport; 1302 sport = udphdr->uh_sport;
1308 dport = udphdr->uh_dport; 1303 dport = udphdr->uh_dport;
1309 1304
1310 /* 1305 /*
1311 * Remove the UDP header (and possibly the non ESP marker) 1306 * Remove the UDP header (and possibly the non ESP marker)
1312 * IP header lendth is iphdrlen 1307 * IP header lendth is iphdrlen
1313 * Before: 1308 * Before:
1314 * <--- off ---> 1309 * <--- off --->
1315 * +----+------+-----+ 1310 * +----+------+-----+
1316 * | IP | UDP | ESP | 1311 * | IP | UDP | ESP |
1317 * +----+------+-----+ 1312 * +----+------+-----+
1318 * <-skip-> 1313 * <-skip->
1319 * After: 1314 * After:
1320 * +----+-----+ 1315 * +----+-----+
1321 * | IP | ESP | 1316 * | IP | ESP |
1322 * +----+-----+ 1317 * +----+-----+
1323 * <-skip-> 1318 * <-skip->
1324 */ 1319 */
1325 iphdrlen = off - sizeof(struct udphdr); 1320 iphdrlen = off - sizeof(struct udphdr);
1326 memmove(mtod(m, char *) + skip, mtod(m, void *), iphdrlen); 1321 memmove(mtod(m, char *) + skip, mtod(m, void *), iphdrlen);
1327 m_adj(m, skip); 1322 m_adj(m, skip);
1328 1323
1329 ip = mtod(m, struct ip *); 1324 ip = mtod(m, struct ip *);
1330 ip->ip_len = htons(ntohs(ip->ip_len) - skip); 1325 ip->ip_len = htons(ntohs(ip->ip_len) - skip);
1331 ip->ip_p = IPPROTO_ESP; 1326 ip->ip_p = IPPROTO_ESP;
1332 1327
1333 /* 1328 /*
1334 * We have modified the packet - it is now ESP, so we should not 1329 * We have modified the packet - it is now ESP, so we should not
1335 * return to UDP processing ...  1330 * return to UDP processing ...
1336 * 1331 *
1337 * Add a PACKET_TAG_IPSEC_NAT_T_PORT tag to remember 1332 * Add a PACKET_TAG_IPSEC_NAT_T_PORT tag to remember
1338 * the source UDP port. This is required if we want 1333 * the source UDP port. This is required if we want
1339 * to select the right SPD for multiple hosts behind  1334 * to select the right SPD for multiple hosts behind
1340 * same NAT  1335 * same NAT
1341 */ 1336 */
1342 if ((tag = m_tag_get(PACKET_TAG_IPSEC_NAT_T_PORTS, 1337 if ((tag = m_tag_get(PACKET_TAG_IPSEC_NAT_T_PORTS,
1343 sizeof(sport) + sizeof(dport), M_DONTWAIT)) == NULL) { 1338 sizeof(sport) + sizeof(dport), M_DONTWAIT)) == NULL) {
1344 printf("udp4_espinudp: m_tag_get failed\n"); 1339 printf("udp4_espinudp: m_tag_get failed\n");
1345 m_freem(m); 1340 m_freem(m);
1346 return -1; 1341 return -1;
1347 } 1342 }
1348 ((u_int16_t *)(tag + 1))[0] = sport; 1343 ((u_int16_t *)(tag + 1))[0] = sport;
1349 ((u_int16_t *)(tag + 1))[1] = dport; 1344 ((u_int16_t *)(tag + 1))[1] = dport;
1350 m_tag_prepend(m, tag); 1345 m_tag_prepend(m, tag);
1351 1346
1352#ifdef IPSEC 1347#ifdef IPSEC
1353 if (ipsec_used) 1348 if (ipsec_used)
1354 ipsec4_common_input(m, iphdrlen, IPPROTO_ESP); 1349 ipsec4_common_input(m, iphdrlen, IPPROTO_ESP);
1355 /* XXX: else */ 1350 /* XXX: else */
1356#else 1351#else
1357 esp4_input(m, iphdrlen); 1352 esp4_input(m, iphdrlen);
1358#endif 1353#endif
1359 1354
1360 /* We handled it, it shouldn't be handled by UDP */ 1355 /* We handled it, it shouldn't be handled by UDP */
1361 *mp = NULL; /* avoid free by caller ... */ 1356 *mp = NULL; /* avoid free by caller ... */
1362 return 1; 1357 return 1;
1363} 1358}
1364#endif 1359#endif
1365 1360
1366PR_WRAP_USRREQS(udp) 1361PR_WRAP_USRREQS(udp)
1367#define udp_attach udp_attach_wrapper 1362#define udp_attach udp_attach_wrapper
1368#define udp_detach udp_detach_wrapper 1363#define udp_detach udp_detach_wrapper
1369#define udp_accept udp_accept_wrapper 1364#define udp_accept udp_accept_wrapper
1370#define udp_bind udp_bind_wrapper 1365#define udp_bind udp_bind_wrapper
1371#define udp_listen udp_listen_wrapper 1366#define udp_listen udp_listen_wrapper
1372#define udp_connect udp_connect_wrapper 1367#define udp_connect udp_connect_wrapper
1373#define udp_connect2 udp_connect2_wrapper 1368#define udp_connect2 udp_connect2_wrapper
1374#define udp_disconnect udp_disconnect_wrapper 1369#define udp_disconnect udp_disconnect_wrapper
1375#define udp_shutdown udp_shutdown_wrapper 1370#define udp_shutdown udp_shutdown_wrapper
1376#define udp_abort udp_abort_wrapper 1371#define udp_abort udp_abort_wrapper
1377#define udp_ioctl udp_ioctl_wrapper 1372#define udp_ioctl udp_ioctl_wrapper
1378#define udp_stat udp_stat_wrapper 1373#define udp_stat udp_stat_wrapper
1379#define udp_peeraddr udp_peeraddr_wrapper 1374#define udp_peeraddr udp_peeraddr_wrapper
1380#define udp_sockaddr udp_sockaddr_wrapper 1375#define udp_sockaddr udp_sockaddr_wrapper
1381#define udp_rcvd udp_rcvd_wrapper 1376#define udp_rcvd udp_rcvd_wrapper
1382#define udp_recvoob udp_recvoob_wrapper 1377#define udp_recvoob udp_recvoob_wrapper
1383#define udp_send udp_send_wrapper 1378#define udp_send udp_send_wrapper
1384#define udp_sendoob udp_sendoob_wrapper 1379#define udp_sendoob udp_sendoob_wrapper
1385#define udp_purgeif udp_purgeif_wrapper 1380#define udp_purgeif udp_purgeif_wrapper
1386 1381
1387const struct pr_usrreqs udp_usrreqs = { 1382const struct pr_usrreqs udp_usrreqs = {
1388 .pr_attach = udp_attach, 1383 .pr_attach = udp_attach,
1389 .pr_detach = udp_detach, 1384 .pr_detach = udp_detach,
1390 .pr_accept = udp_accept, 1385 .pr_accept = udp_accept,
1391 .pr_bind = udp_bind, 1386 .pr_bind = udp_bind,
1392 .pr_listen = udp_listen, 1387 .pr_listen = udp_listen,
1393 .pr_connect = udp_connect, 1388 .pr_connect = udp_connect,
1394 .pr_connect2 = udp_connect2, 1389 .pr_connect2 = udp_connect2,
1395 .pr_disconnect = udp_disconnect, 1390 .pr_disconnect = udp_disconnect,
1396 .pr_shutdown = udp_shutdown, 1391 .pr_shutdown = udp_shutdown,
1397 .pr_abort = udp_abort, 1392 .pr_abort = udp_abort,
1398 .pr_ioctl = udp_ioctl, 1393 .pr_ioctl = udp_ioctl,
1399 .pr_stat = udp_stat, 1394 .pr_stat = udp_stat,
1400 .pr_peeraddr = udp_peeraddr, 1395 .pr_peeraddr = udp_peeraddr,
1401 .pr_sockaddr = udp_sockaddr, 1396 .pr_sockaddr = udp_sockaddr,
1402 .pr_rcvd = udp_rcvd, 1397 .pr_rcvd = udp_rcvd,
1403 .pr_recvoob = udp_recvoob, 1398 .pr_recvoob = udp_recvoob,
1404 .pr_send = udp_send, 1399 .pr_send = udp_send,
1405 .pr_sendoob = udp_sendoob, 1400 .pr_sendoob = udp_sendoob,
1406 .pr_purgeif = udp_purgeif, 1401 .pr_purgeif = udp_purgeif,
1407}; 1402};

cvs diff -r1.40 -r1.41 src/sys/netinet/udp_var.h (switch to unified diff)

--- src/sys/netinet/udp_var.h 2014/05/18 14:46:16 1.40
+++ src/sys/netinet/udp_var.h 2016/01/20 22:01:18 1.41
@@ -1,107 +1,107 @@ @@ -1,107 +1,107 @@
1/* $NetBSD: udp_var.h,v 1.40 2014/05/18 14:46:16 rmind Exp $ */ 1/* $NetBSD: udp_var.h,v 1.41 2016/01/20 22:01:18 riastradh Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1982, 1986, 1989, 1993 4 * Copyright (c) 1982, 1986, 1989, 1993
5 * The Regents of the University of California. All rights reserved. 5 * The Regents of the University of California. All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors 15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software 16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission. 17 * without specific prior written permission.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 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 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 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE. 29 * SUCH DAMAGE.
30 * 30 *
31 * @(#)udp_var.h 8.1 (Berkeley) 6/10/93 31 * @(#)udp_var.h 8.1 (Berkeley) 6/10/93
32 */ 32 */
33 33
34#ifndef _NETINET_UDP_VAR_H_ 34#ifndef _NETINET_UDP_VAR_H_
35#define _NETINET_UDP_VAR_H_ 35#define _NETINET_UDP_VAR_H_
36 36
37/* 37/*
38 * UDP kernel structures and variables. 38 * UDP kernel structures and variables.
39 */ 39 */
40struct udpiphdr { 40struct udpiphdr {
41 struct ipovly ui_i; /* overlaid ip structure */ 41 struct ipovly ui_i; /* overlaid ip structure */
42 struct udphdr ui_u; /* udp header */ 42 struct udphdr ui_u; /* udp header */
43} __packed; 43} __packed;
44#define ui_x1 ui_i.ih_x1 44#define ui_x1 ui_i.ih_x1
45#define ui_pr ui_i.ih_pr 45#define ui_pr ui_i.ih_pr
46#define ui_len ui_i.ih_len 46#define ui_len ui_i.ih_len
47#define ui_src ui_i.ih_src 47#define ui_src ui_i.ih_src
48#define ui_dst ui_i.ih_dst 48#define ui_dst ui_i.ih_dst
49#define ui_sport ui_u.uh_sport 49#define ui_sport ui_u.uh_sport
50#define ui_dport ui_u.uh_dport 50#define ui_dport ui_u.uh_dport
51#define ui_ulen ui_u.uh_ulen 51#define ui_ulen ui_u.uh_ulen
52#define ui_sum ui_u.uh_sum 52#define ui_sum ui_u.uh_sum
53 53
54/* 54/*
55 * UDP statistics. 55 * UDP statistics.
56 * Each counter is an unsigned 64-bit value. 56 * Each counter is an unsigned 64-bit value.
57 */ 57 */
58#define UDP_STAT_IPACKETS 0 /* total input packets */ 58#define UDP_STAT_IPACKETS 0 /* total input packets */
59#define UDP_STAT_HDROPS 1 /* packet shorter than header */ 59#define UDP_STAT_HDROPS 1 /* packet shorter than header */
60#define UDP_STAT_BADSUM 2 /* checksum error */ 60#define UDP_STAT_BADSUM 2 /* checksum error */
61#define UDP_STAT_BADLEN 3 /* data length larger than packet */ 61#define UDP_STAT_BADLEN 3 /* data length larger than packet */
62#define UDP_STAT_NOPORT 4 /* no socket on port */ 62#define UDP_STAT_NOPORT 4 /* no socket on port */
63#define UDP_STAT_NOPORTBCAST 5 /* of above, arrived as broadcast */ 63#define UDP_STAT_NOPORTBCAST 5 /* of above, arrived as broadcast */
64#define UDP_STAT_FULLSOCK 6 /* not delivered, input socket full */ 64#define UDP_STAT_FULLSOCK 6 /* not delivered, input socket full */
65#define UDP_STAT_PCBHASHMISS 7 /* input packets missing PCB hash */ 65#define UDP_STAT_PCBHASHMISS 7 /* input packets missing PCB hash */
66#define UDP_STAT_OPACKETS 8 /* total output packets */ 66#define UDP_STAT_OPACKETS 8 /* total output packets */
67 67
68#define UDP_NSTATS 9 68#define UDP_NSTATS 9
69 69
70/* 70/*
71 * Names for UDP sysctl objects 71 * Names for UDP sysctl objects
72 */ 72 */
73#define UDPCTL_CHECKSUM 1 /* checksum UDP packets */ 73#define UDPCTL_CHECKSUM 1 /* checksum UDP packets */
74#define UDPCTL_SENDSPACE 2 /* default send buffer */ 74#define UDPCTL_SENDSPACE 2 /* default send buffer */
75#define UDPCTL_RECVSPACE 3 /* default recv buffer */ 75#define UDPCTL_RECVSPACE 3 /* default recv buffer */
76#define UDPCTL_LOOPBACKCKSUM 4 /* do UDP checksum on loopback */ 76#define UDPCTL_LOOPBACKCKSUM 4 /* do UDP checksum on loopback */
77#define UDPCTL_STATS 5 /* UDP statistics */ 77#define UDPCTL_STATS 5 /* UDP statistics */
78#define UDPCTL_MAXID 7 78#define UDPCTL_MAXID 7
79 79
80#define UDPCTL_NAMES { \ 80#define UDPCTL_NAMES { \
81 { 0, 0 }, \ 81 { 0, 0 }, \
82 { "checksum", CTLTYPE_INT }, \ 82 { "checksum", CTLTYPE_INT }, \
83 { "sendspace", CTLTYPE_INT }, \ 83 { "sendspace", CTLTYPE_INT }, \
84 { "recvspace", CTLTYPE_INT }, \ 84 { "recvspace", CTLTYPE_INT }, \
85 { "do_loopback_cksum", CTLTYPE_INT }, \ 85 { "do_loopback_cksum", CTLTYPE_INT }, \
86 { "stats", CTLTYPE_STRUCT }, \ 86 { "stats", CTLTYPE_STRUCT }, \
87} 87}
88 88
89#ifdef _KERNEL 89#ifdef _KERNEL
90 90
91extern struct inpcbtable udbtable; 91extern struct inpcbtable udbtable;
92extern const struct pr_usrreqs udp_usrreqs; 92extern const struct pr_usrreqs udp_usrreqs;
93 93
94void *udp_ctlinput(int, const struct sockaddr *, void *); 94void *udp_ctlinput(int, const struct sockaddr *, void *);
95int udp_ctloutput(int, struct socket *, struct sockopt *); 95int udp_ctloutput(int, struct socket *, struct sockopt *);
96void udp_init(void); 96void udp_init(void);
97void udp_init_common(void); 97void udp_init_common(void);
98void udp_input(struct mbuf *, ...); 98void udp_input(struct mbuf *, ...);
99int udp_output(struct mbuf *, ...); 99int udp_output(struct mbuf *, struct inpcb *);
100int udp_sysctl(int *, u_int, void *, size_t *, void *, size_t); 100int udp_sysctl(int *, u_int, void *, size_t *, void *, size_t);
101 101
102int udp_input_checksum(int af, struct mbuf *, const struct udphdr *, int, 102int udp_input_checksum(int af, struct mbuf *, const struct udphdr *, int,
103 int); 103 int);
104void udp_statinc(u_int); 104void udp_statinc(u_int);
105#endif /* _KERNEL */ 105#endif /* _KERNEL */
106 106
107#endif /* !_NETINET_UDP_VAR_H_ */ 107#endif /* !_NETINET_UDP_VAR_H_ */