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