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