udp_usrreq.c revision 1.86 1 /* $NetBSD: udp_usrreq.c,v 1.86 2001/10/24 06:04:08 itojun 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. All advertising materials mentioning features or use of this software
45 * must display the following acknowledgement:
46 * This product includes software developed by the University of
47 * California, Berkeley and its contributors.
48 * 4. Neither the name of the University nor the names of its contributors
49 * may be used to endorse or promote products derived from this software
50 * without specific prior written permission.
51 *
52 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
53 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
54 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
55 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
56 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
57 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
58 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
59 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
60 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
61 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
62 * SUCH DAMAGE.
63 *
64 * @(#)udp_usrreq.c 8.6 (Berkeley) 5/23/95
65 */
66
67 #include "opt_inet.h"
68 #include "opt_ipsec.h"
69 #include "opt_inet_csum.h"
70 #include "opt_ipkdb.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
84 #include <uvm/uvm_extern.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
100 #ifdef INET6
101 #include <netinet/ip6.h>
102 #include <netinet/icmp6.h>
103 #include <netinet6/ip6_var.h>
104 #include <netinet6/in6_pcb.h>
105 #include <netinet6/udp6_var.h>
106 #endif
107
108 #ifdef PULLDOWN_TEST
109 #ifndef INET6
110 /* always need ip6.h for IP6_EXTHDR_GET */
111 #include <netinet/ip6.h>
112 #endif
113 #endif
114
115 #include "faith.h"
116 #if defined(NFAITH) && NFAITH > 0
117 #include <net/if_faith.h>
118 #endif
119
120 #include <machine/stdarg.h>
121
122 #ifdef IPSEC
123 #include <netinet6/ipsec.h>
124 #include <netkey/key.h>
125 #endif /*IPSEC*/
126
127 #ifdef IPKDB
128 #include <ipkdb/ipkdb.h>
129 #endif
130
131 /*
132 * UDP protocol implementation.
133 * Per RFC 768, August, 1980.
134 */
135 #ifndef COMPAT_42
136 int udpcksum = 1;
137 #else
138 int udpcksum = 0; /* XXX */
139 #endif
140
141 #ifdef INET
142 static void udp4_sendup __P((struct mbuf *, int, struct sockaddr *,
143 struct socket *));
144 static int udp4_realinput __P((struct sockaddr_in *, struct sockaddr_in *,
145 struct mbuf *, int));
146 #endif
147 #ifdef INET6
148 static void udp6_sendup __P((struct mbuf *, int, struct sockaddr *,
149 struct socket *));
150 static int in6_mcmatch __P((struct in6pcb *, struct in6_addr *,
151 struct ifnet *));
152 static int udp6_realinput __P((int, struct sockaddr_in6 *,
153 struct sockaddr_in6 *, struct mbuf *, int));
154 #endif
155 #ifdef INET
156 static void udp_notify __P((struct inpcb *, int));
157 #endif
158
159 #ifndef UDBHASHSIZE
160 #define UDBHASHSIZE 128
161 #endif
162 int udbhashsize = UDBHASHSIZE;
163
164 #ifdef UDP_CSUM_COUNTERS
165 #include <sys/device.h>
166
167 struct evcnt udp_hwcsum_bad = EVCNT_INITIALIZER(EVCNT_TYPE_MISC,
168 NULL, "udp", "hwcsum bad");
169 struct evcnt udp_hwcsum_ok = EVCNT_INITIALIZER(EVCNT_TYPE_MISC,
170 NULL, "udp", "hwcsum ok");
171 struct evcnt udp_hwcsum_data = EVCNT_INITIALIZER(EVCNT_TYPE_MISC,
172 NULL, "udp", "hwcsum data");
173 struct evcnt udp_swcsum = EVCNT_INITIALIZER(EVCNT_TYPE_MISC,
174 NULL, "udp", "swcsum");
175
176 #define UDP_CSUM_COUNTER_INCR(ev) (ev)->ev_count++
177
178 #else
179
180 #define UDP_CSUM_COUNTER_INCR(ev) /* nothing */
181
182 #endif /* UDP_CSUM_COUNTERS */
183
184 void
185 udp_init()
186 {
187
188 #ifdef INET
189 in_pcbinit(&udbtable, udbhashsize, udbhashsize);
190 #endif
191
192 #ifdef UDP_CSUM_COUNTERS
193 evcnt_attach_static(&udp_hwcsum_bad);
194 evcnt_attach_static(&udp_hwcsum_ok);
195 evcnt_attach_static(&udp_hwcsum_data);
196 evcnt_attach_static(&udp_swcsum);
197 #endif /* UDP_CSUM_COUNTERS */
198 }
199
200 #ifdef INET
201 void
202 #if __STDC__
203 udp_input(struct mbuf *m, ...)
204 #else
205 udp_input(m, va_alist)
206 struct mbuf *m;
207 va_dcl
208 #endif
209 {
210 va_list ap;
211 struct sockaddr_in src, dst;
212 struct ip *ip;
213 struct udphdr *uh;
214 int iphlen, proto;
215 int len;
216 int n;
217
218 va_start(ap, m);
219 iphlen = va_arg(ap, int);
220 proto = va_arg(ap, int);
221 va_end(ap);
222
223 udpstat.udps_ipackets++;
224
225 #ifndef PULLDOWN_TEST
226 /*
227 * Strip IP options, if any; should skip this,
228 * make available to user, and use on returned packets,
229 * but we don't yet have a way to check the checksum
230 * with options still present.
231 */
232 if (iphlen > sizeof (struct ip)) {
233 ip_stripoptions(m, (struct mbuf *)0);
234 iphlen = sizeof(struct ip);
235 }
236 #else
237 /*
238 * we may enable the above code if we save and pass IPv4 options
239 * to the userland.
240 */
241 #endif
242
243 /*
244 * Get IP and UDP header together in first mbuf.
245 */
246 ip = mtod(m, struct ip *);
247 #ifndef PULLDOWN_TEST
248 if (m->m_len < iphlen + sizeof(struct udphdr)) {
249 if ((m = m_pullup(m, iphlen + sizeof(struct udphdr))) == 0) {
250 udpstat.udps_hdrops++;
251 return;
252 }
253 ip = mtod(m, struct ip *);
254 }
255 uh = (struct udphdr *)((caddr_t)ip + iphlen);
256 #else
257 IP6_EXTHDR_GET(uh, struct udphdr *, m, iphlen, sizeof(struct udphdr));
258 if (uh == NULL) {
259 udpstat.udps_hdrops++;
260 return;
261 }
262 #endif
263
264 /* destination port of 0 is illegal, based on RFC768. */
265 if (uh->uh_dport == 0)
266 goto bad;
267
268 /*
269 * Make mbuf data length reflect UDP length.
270 * If not enough data to reflect UDP length, drop.
271 */
272 len = ntohs((u_int16_t)uh->uh_ulen);
273 if (ip->ip_len != iphlen + len) {
274 if (ip->ip_len < iphlen + len || len < sizeof(struct udphdr)) {
275 udpstat.udps_badlen++;
276 goto bad;
277 }
278 m_adj(m, iphlen + len - ip->ip_len);
279 }
280
281 /*
282 * Checksum extended UDP header and data.
283 */
284 if (uh->uh_sum) {
285 switch (m->m_pkthdr.csum_flags &
286 ((m->m_pkthdr.rcvif->if_csum_flags_rx & M_CSUM_UDPv4) |
287 M_CSUM_TCP_UDP_BAD | M_CSUM_DATA)) {
288 case M_CSUM_UDPv4|M_CSUM_TCP_UDP_BAD:
289 UDP_CSUM_COUNTER_INCR(&udp_hwcsum_bad);
290 goto badcsum;
291
292 case M_CSUM_UDPv4|M_CSUM_DATA:
293 UDP_CSUM_COUNTER_INCR(&udp_hwcsum_data);
294 if ((m->m_pkthdr.csum_data ^ 0xffff) != 0)
295 goto badcsum;
296 break;
297
298 case M_CSUM_UDPv4:
299 /* Checksum was okay. */
300 UDP_CSUM_COUNTER_INCR(&udp_hwcsum_ok);
301 break;
302
303 default:
304 /* Need to compute it ourselves. */
305 UDP_CSUM_COUNTER_INCR(&udp_swcsum);
306 if (in4_cksum(m, IPPROTO_UDP, iphlen, len) != 0)
307 goto badcsum;
308 break;
309 }
310 }
311
312 /* construct source and dst sockaddrs. */
313 bzero(&src, sizeof(src));
314 src.sin_family = AF_INET;
315 src.sin_len = sizeof(struct sockaddr_in);
316 bcopy(&ip->ip_src, &src.sin_addr, sizeof(src.sin_addr));
317 src.sin_port = uh->uh_sport;
318 bzero(&dst, sizeof(dst));
319 dst.sin_family = AF_INET;
320 dst.sin_len = sizeof(struct sockaddr_in);
321 bcopy(&ip->ip_dst, &dst.sin_addr, sizeof(dst.sin_addr));
322 dst.sin_port = uh->uh_dport;
323
324 n = udp4_realinput(&src, &dst, m, iphlen);
325 #ifdef INET6
326 if (IN_MULTICAST(ip->ip_dst.s_addr) || n == 0) {
327 struct sockaddr_in6 src6, dst6;
328
329 bzero(&src6, sizeof(src6));
330 src6.sin6_family = AF_INET6;
331 src6.sin6_len = sizeof(struct sockaddr_in6);
332 src6.sin6_addr.s6_addr[10] = src6.sin6_addr.s6_addr[11] = 0xff;
333 bcopy(&ip->ip_src, &src6.sin6_addr.s6_addr[12],
334 sizeof(ip->ip_src));
335 src6.sin6_port = uh->uh_sport;
336 bzero(&dst6, sizeof(dst6));
337 dst6.sin6_family = AF_INET6;
338 dst6.sin6_len = sizeof(struct sockaddr_in6);
339 dst6.sin6_addr.s6_addr[10] = dst6.sin6_addr.s6_addr[11] = 0xff;
340 bcopy(&ip->ip_dst, &dst6.sin6_addr.s6_addr[12],
341 sizeof(ip->ip_dst));
342 dst6.sin6_port = uh->uh_dport;
343
344 n += udp6_realinput(AF_INET, &src6, &dst6, m, iphlen);
345 }
346 #endif
347
348 if (n == 0) {
349 if (m->m_flags & (M_BCAST | M_MCAST)) {
350 udpstat.udps_noportbcast++;
351 goto bad;
352 }
353 udpstat.udps_noport++;
354 #ifdef IPKDB
355 if (checkipkdb(&ip->ip_src, uh->uh_sport, uh->uh_dport,
356 m, iphlen + sizeof(struct udphdr),
357 m->m_pkthdr.len - iphlen - sizeof(struct udphdr))) {
358 /*
359 * It was a debugger connect packet,
360 * just drop it now
361 */
362 goto bad;
363 }
364 #endif
365 icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_PORT, 0, 0);
366 m = NULL;
367 }
368
369 bad:
370 if (m)
371 m_freem(m);
372 return;
373
374 badcsum:
375 m_freem(m);
376 udpstat.udps_badsum++;
377 }
378 #endif
379
380 #ifdef INET6
381 int
382 udp6_input(mp, offp, proto)
383 struct mbuf **mp;
384 int *offp, proto;
385 {
386 struct mbuf *m = *mp;
387 int off = *offp;
388 struct sockaddr_in6 src, dst;
389 struct ip6_hdr *ip6;
390 struct udphdr *uh;
391 u_int32_t plen, ulen;
392
393 #ifndef PULLDOWN_TEST
394 IP6_EXTHDR_CHECK(m, off, sizeof(struct udphdr), IPPROTO_DONE);
395 #endif
396 ip6 = mtod(m, struct ip6_hdr *);
397
398 #if defined(NFAITH) && 0 < NFAITH
399 if (faithprefix(&ip6->ip6_dst)) {
400 /* send icmp6 host unreach? */
401 m_freem(m);
402 return IPPROTO_DONE;
403 }
404 #endif
405
406 udp6stat.udp6s_ipackets++;
407
408 /* check for jumbogram is done in ip6_input. we can trust pkthdr.len */
409 plen = m->m_pkthdr.len - off;
410 #ifndef PULLDOWN_TEST
411 uh = (struct udphdr *)((caddr_t)ip6 + off);
412 #else
413 IP6_EXTHDR_GET(uh, struct udphdr *, m, off, sizeof(struct udphdr));
414 if (uh == NULL) {
415 ip6stat.ip6s_tooshort++;
416 return IPPROTO_DONE;
417 }
418 #endif
419 ulen = ntohs((u_short)uh->uh_ulen);
420 /*
421 * RFC2675 section 4: jumbograms will have 0 in the UDP header field,
422 * iff payload length > 0xffff.
423 */
424 if (ulen == 0 && plen > 0xffff)
425 ulen = plen;
426
427 if (plen != ulen) {
428 udp6stat.udp6s_badlen++;
429 goto bad;
430 }
431
432 /* destination port of 0 is illegal, based on RFC768. */
433 if (uh->uh_dport == 0)
434 goto bad;
435
436 /* Be proactive about malicious use of IPv4 mapped address */
437 if (IN6_IS_ADDR_V4MAPPED(&ip6->ip6_src) ||
438 IN6_IS_ADDR_V4MAPPED(&ip6->ip6_dst)) {
439 /* XXX stat */
440 goto bad;
441 }
442
443 /*
444 * Checksum extended UDP header and data.
445 */
446 if (uh->uh_sum == 0)
447 udp6stat.udp6s_nosum++;
448 else if (in6_cksum(m, IPPROTO_UDP, off, ulen) != 0) {
449 udp6stat.udp6s_badsum++;
450 goto bad;
451 }
452
453 /*
454 * Construct source and dst sockaddrs.
455 * Note that ifindex (s6_addr16[1]) is already filled.
456 */
457 bzero(&src, sizeof(src));
458 src.sin6_family = AF_INET6;
459 src.sin6_len = sizeof(struct sockaddr_in6);
460 /* KAME hack: recover scopeid */
461 (void)in6_recoverscope(&src, &ip6->ip6_src, m->m_pkthdr.rcvif);
462 src.sin6_port = uh->uh_sport;
463 bzero(&dst, sizeof(dst));
464 dst.sin6_family = AF_INET6;
465 dst.sin6_len = sizeof(struct sockaddr_in6);
466 /* KAME hack: recover scopeid */
467 (void)in6_recoverscope(&dst, &ip6->ip6_dst, m->m_pkthdr.rcvif);
468 dst.sin6_port = uh->uh_dport;
469
470 if (udp6_realinput(AF_INET6, &src, &dst, m, off) == 0) {
471 if (m->m_flags & M_MCAST) {
472 udp6stat.udp6s_noportmcast++;
473 goto bad;
474 }
475 udp6stat.udp6s_noport++;
476 icmp6_error(m, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOPORT, 0);
477 m = NULL;
478 }
479
480 bad:
481 if (m)
482 m_freem(m);
483 return IPPROTO_DONE;
484 }
485 #endif
486
487 #ifdef INET
488 static void
489 udp4_sendup(m, off, src, so)
490 struct mbuf *m;
491 int off; /* offset of data portion */
492 struct sockaddr *src;
493 struct socket *so;
494 {
495 struct mbuf *opts = NULL;
496 struct mbuf *n;
497 struct inpcb *inp = NULL;
498 #ifdef INET6
499 struct in6pcb *in6p = NULL;
500 #endif
501
502 if (!so)
503 return;
504 switch (so->so_proto->pr_domain->dom_family) {
505 case AF_INET:
506 inp = sotoinpcb(so);
507 break;
508 #ifdef INET6
509 case AF_INET6:
510 in6p = sotoin6pcb(so);
511 break;
512 #endif
513 default:
514 return;
515 }
516
517 #ifdef IPSEC
518 /* check AH/ESP integrity. */
519 if (so != NULL && ipsec4_in_reject_so(m, so)) {
520 ipsecstat.in_polvio++;
521 return;
522 }
523 #endif /*IPSEC*/
524
525 if ((n = m_copy(m, 0, M_COPYALL)) != NULL) {
526 if (inp && (inp->inp_flags & INP_CONTROLOPTS
527 || so->so_options & SO_TIMESTAMP)) {
528 struct ip *ip = mtod(n, struct ip *);
529 ip_savecontrol(inp, &opts, ip, n);
530 }
531
532 m_adj(n, off);
533 if (sbappendaddr(&so->so_rcv, src, n,
534 opts) == 0) {
535 m_freem(n);
536 if (opts)
537 m_freem(opts);
538 udpstat.udps_fullsock++;
539 } else
540 sorwakeup(so);
541 }
542 }
543 #endif
544
545 #ifdef INET6
546 static void
547 udp6_sendup(m, off, src, so)
548 struct mbuf *m;
549 int off; /* offset of data portion */
550 struct sockaddr *src;
551 struct socket *so;
552 {
553 struct mbuf *opts = NULL;
554 struct mbuf *n;
555 struct in6pcb *in6p = NULL;
556
557 if (!so)
558 return;
559 if (so->so_proto->pr_domain->dom_family != AF_INET6)
560 return;
561 in6p = sotoin6pcb(so);
562
563 #ifdef IPSEC
564 /* check AH/ESP integrity. */
565 if (so != NULL && ipsec6_in_reject_so(m, so)) {
566 ipsec6stat.in_polvio++;
567 return;
568 }
569 #endif /*IPSEC*/
570
571 if ((n = m_copy(m, 0, M_COPYALL)) != NULL) {
572 if (in6p && (in6p->in6p_flags & IN6P_CONTROLOPTS
573 || in6p->in6p_socket->so_options & SO_TIMESTAMP)) {
574 struct ip6_hdr *ip6 = mtod(n, struct ip6_hdr *);
575 ip6_savecontrol(in6p, &opts, ip6, n);
576 }
577
578 m_adj(n, off);
579 if (sbappendaddr(&so->so_rcv, src, n, opts) == 0) {
580 m_freem(n);
581 if (opts)
582 m_freem(opts);
583 udp6stat.udp6s_fullsock++;
584 } else
585 sorwakeup(so);
586 }
587 }
588 #endif
589
590 #ifdef INET
591 static int
592 udp4_realinput(src, dst, m, off)
593 struct sockaddr_in *src;
594 struct sockaddr_in *dst;
595 struct mbuf *m;
596 int off; /* offset of udphdr */
597 {
598 u_int16_t *sport, *dport;
599 int rcvcnt;
600 struct in_addr *src4, *dst4;
601 struct inpcb *inp;
602
603 rcvcnt = 0;
604 off += sizeof(struct udphdr); /* now, offset of payload */
605
606 if (src->sin_family != AF_INET || dst->sin_family != AF_INET)
607 goto bad;
608
609 src4 = &src->sin_addr;
610 sport = &src->sin_port;
611 dst4 = &dst->sin_addr;
612 dport = &dst->sin_port;
613
614 if (IN_MULTICAST(dst4->s_addr) ||
615 in_broadcast(*dst4, m->m_pkthdr.rcvif)) {
616 struct inpcb *last;
617 /*
618 * Deliver a multicast or broadcast datagram to *all* sockets
619 * for which the local and remote addresses and ports match
620 * those of the incoming datagram. This allows more than
621 * one process to receive multi/broadcasts on the same port.
622 * (This really ought to be done for unicast datagrams as
623 * well, but that would cause problems with existing
624 * applications that open both address-specific sockets and
625 * a wildcard socket listening to the same port -- they would
626 * end up receiving duplicates of every unicast datagram.
627 * Those applications open the multiple sockets to overcome an
628 * inadequacy of the UDP socket interface, but for backwards
629 * compatibility we avoid the problem here rather than
630 * fixing the interface. Maybe 4.5BSD will remedy this?)
631 */
632
633 /*
634 * KAME note: usually we drop udpiphdr from mbuf here.
635 * we need udpiphdr for IPsec processing so we do that later.
636 */
637 /*
638 * Locate pcb(s) for datagram.
639 */
640 for (inp = udbtable.inpt_queue.cqh_first;
641 inp != (struct inpcb *)&udbtable.inpt_queue;
642 inp = inp->inp_queue.cqe_next) {
643 if (inp->inp_lport != *dport)
644 continue;
645 if (!in_nullhost(inp->inp_laddr)) {
646 if (!in_hosteq(inp->inp_laddr, *dst4))
647 continue;
648 }
649 if (!in_nullhost(inp->inp_faddr)) {
650 if (!in_hosteq(inp->inp_faddr, *src4) ||
651 inp->inp_fport != *sport)
652 continue;
653 }
654
655 last = inp;
656 udp4_sendup(m, off, (struct sockaddr *)src,
657 inp->inp_socket);
658 rcvcnt++;
659
660 /*
661 * Don't look for additional matches if this one does
662 * not have either the SO_REUSEPORT or SO_REUSEADDR
663 * socket options set. This heuristic avoids searching
664 * through all pcbs in the common case of a non-shared
665 * port. It assumes that an application will never
666 * clear these options after setting them.
667 */
668 if ((inp->inp_socket->so_options &
669 (SO_REUSEPORT|SO_REUSEADDR)) == 0)
670 break;
671 }
672 } else {
673 /*
674 * Locate pcb for datagram.
675 */
676 inp = in_pcblookup_connect(&udbtable, *src4, *sport, *dst4, *dport);
677 if (inp == 0) {
678 ++udpstat.udps_pcbhashmiss;
679 inp = in_pcblookup_bind(&udbtable, *dst4, *dport);
680 if (inp == 0)
681 return rcvcnt;
682 }
683
684 udp4_sendup(m, off, (struct sockaddr *)src, inp->inp_socket);
685 rcvcnt++;
686 }
687
688 bad:
689 return rcvcnt;
690 }
691 #endif
692
693 #ifdef INET6
694 static int
695 in6_mcmatch(in6p, ia6, ifp)
696 struct in6pcb *in6p;
697 struct in6_addr *ia6;
698 struct ifnet *ifp;
699 {
700 struct ip6_moptions *im6o = in6p->in6p_moptions;
701 struct in6_multi_mship *imm;
702
703 if (im6o == NULL)
704 return 0;
705
706 for (imm = im6o->im6o_memberships.lh_first; imm != NULL;
707 imm = imm->i6mm_chain.le_next) {
708 if ((ifp == NULL ||
709 imm->i6mm_maddr->in6m_ifp == ifp) &&
710 IN6_ARE_ADDR_EQUAL(&imm->i6mm_maddr->in6m_addr,
711 ia6))
712 return 1;
713 }
714 return 0;
715 }
716
717 static int
718 udp6_realinput(af, src, dst, m, off)
719 int af; /* af on packet */
720 struct sockaddr_in6 *src;
721 struct sockaddr_in6 *dst;
722 struct mbuf *m;
723 int off; /* offset of udphdr */
724 {
725 u_int16_t sport, dport;
726 int rcvcnt;
727 struct in6_addr src6, dst6;
728 const struct in_addr *dst4;
729 struct in6pcb *in6p;
730
731 rcvcnt = 0;
732 off += sizeof(struct udphdr); /* now, offset of payload */
733
734 if (af != AF_INET && af != AF_INET6)
735 goto bad;
736 if (src->sin6_family != AF_INET6 || dst->sin6_family != AF_INET6)
737 goto bad;
738
739 in6_embedscope(&src6, src, NULL, NULL);
740 sport = src->sin6_port;
741 in6_embedscope(&dst6, dst, NULL, NULL);
742 dport = dst->sin6_port;
743 dst4 = (struct in_addr *)&dst->sin6_addr.s6_addr32[12];
744
745 if (IN6_IS_ADDR_MULTICAST(&dst6) ||
746 (af == AF_INET && IN_MULTICAST(dst4->s_addr))) {
747 struct in6pcb *last;
748 /*
749 * Deliver a multicast or broadcast datagram to *all* sockets
750 * for which the local and remote addresses and ports match
751 * those of the incoming datagram. This allows more than
752 * one process to receive multi/broadcasts on the same port.
753 * (This really ought to be done for unicast datagrams as
754 * well, but that would cause problems with existing
755 * applications that open both address-specific sockets and
756 * a wildcard socket listening to the same port -- they would
757 * end up receiving duplicates of every unicast datagram.
758 * Those applications open the multiple sockets to overcome an
759 * inadequacy of the UDP socket interface, but for backwards
760 * compatibility we avoid the problem here rather than
761 * fixing the interface. Maybe 4.5BSD will remedy this?)
762 */
763
764 /*
765 * KAME note: usually we drop udpiphdr from mbuf here.
766 * we need udpiphdr for IPsec processing so we do that later.
767 */
768 /*
769 * Locate pcb(s) for datagram.
770 */
771 for (in6p = udb6.in6p_next; in6p != &udb6;
772 in6p = in6p->in6p_next) {
773 if (in6p->in6p_lport != dport)
774 continue;
775 if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_laddr)) {
776 if (!IN6_ARE_ADDR_EQUAL(&in6p->in6p_laddr, &dst6) &&
777 !in6_mcmatch(in6p, &dst6, m->m_pkthdr.rcvif))
778 continue;
779 }
780 else {
781 if (IN6_IS_ADDR_V4MAPPED(&dst6) &&
782 (in6p->in6p_flags & IN6P_IPV6_V6ONLY))
783 continue;
784 }
785 if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_faddr)) {
786 if (!IN6_ARE_ADDR_EQUAL(&in6p->in6p_faddr,
787 &src6) || in6p->in6p_fport != sport)
788 continue;
789 }
790 else {
791 if (IN6_IS_ADDR_V4MAPPED(&src6) &&
792 (in6p->in6p_flags & IN6P_IPV6_V6ONLY))
793 continue;
794 }
795
796 last = in6p;
797 udp6_sendup(m, off, (struct sockaddr *)src,
798 in6p->in6p_socket);
799 rcvcnt++;
800
801 /*
802 * Don't look for additional matches if this one does
803 * not have either the SO_REUSEPORT or SO_REUSEADDR
804 * socket options set. This heuristic avoids searching
805 * through all pcbs in the common case of a non-shared
806 * port. It assumes that an application will never
807 * clear these options after setting them.
808 */
809 if ((in6p->in6p_socket->so_options &
810 (SO_REUSEPORT|SO_REUSEADDR)) == 0)
811 break;
812 }
813 } else {
814 /*
815 * Locate pcb for datagram.
816 */
817 in6p = in6_pcblookup_connect(&udb6, &src6, sport,
818 &dst6, dport, 0);
819 if (in6p == 0) {
820 ++udpstat.udps_pcbhashmiss;
821 in6p = in6_pcblookup_bind(&udb6, &dst6, dport, 0);
822 if (in6p == 0)
823 return rcvcnt;
824 }
825
826 udp6_sendup(m, off, (struct sockaddr *)src, in6p->in6p_socket);
827 rcvcnt++;
828 }
829
830 bad:
831 return rcvcnt;
832 }
833 #endif
834
835 #ifdef INET
836 /*
837 * Notify a udp user of an asynchronous error;
838 * just wake up so that he can collect error status.
839 */
840 static void
841 udp_notify(inp, errno)
842 struct inpcb *inp;
843 int errno;
844 {
845
846 inp->inp_socket->so_error = errno;
847 sorwakeup(inp->inp_socket);
848 sowwakeup(inp->inp_socket);
849 }
850
851 void *
852 udp_ctlinput(cmd, sa, v)
853 int cmd;
854 struct sockaddr *sa;
855 void *v;
856 {
857 struct ip *ip = v;
858 struct udphdr *uh;
859 void (*notify) __P((struct inpcb *, int)) = udp_notify;
860 int errno;
861
862 if (sa->sa_family != AF_INET
863 || sa->sa_len != sizeof(struct sockaddr_in))
864 return NULL;
865 if ((unsigned)cmd >= PRC_NCMDS)
866 return NULL;
867 errno = inetctlerrmap[cmd];
868 if (PRC_IS_REDIRECT(cmd))
869 notify = in_rtchange, ip = 0;
870 else if (cmd == PRC_HOSTDEAD)
871 ip = 0;
872 else if (errno == 0)
873 return NULL;
874 if (ip) {
875 uh = (struct udphdr *)((caddr_t)ip + (ip->ip_hl << 2));
876 in_pcbnotify(&udbtable, satosin(sa)->sin_addr, uh->uh_dport,
877 ip->ip_src, uh->uh_sport, errno, notify);
878
879 /* XXX mapped address case */
880 } else
881 in_pcbnotifyall(&udbtable, satosin(sa)->sin_addr, errno,
882 notify);
883 return NULL;
884 }
885
886 int
887 #if __STDC__
888 udp_output(struct mbuf *m, ...)
889 #else
890 udp_output(m, va_alist)
891 struct mbuf *m;
892 va_dcl
893 #endif
894 {
895 struct inpcb *inp;
896 struct udpiphdr *ui;
897 int len = m->m_pkthdr.len;
898 int error = 0;
899 va_list ap;
900
901 va_start(ap, m);
902 inp = va_arg(ap, struct inpcb *);
903 va_end(ap);
904
905 /*
906 * Calculate data length and get a mbuf
907 * for UDP and IP headers.
908 */
909 M_PREPEND(m, sizeof(struct udpiphdr), M_DONTWAIT);
910 if (m == 0) {
911 error = ENOBUFS;
912 goto release;
913 }
914
915 /*
916 * Compute the packet length of the IP header, and
917 * punt if the length looks bogus.
918 */
919 if ((len + sizeof(struct udpiphdr)) > IP_MAXPACKET) {
920 error = EMSGSIZE;
921 goto release;
922 }
923
924 /*
925 * Fill in mbuf with extended UDP header
926 * and addresses and length put into network format.
927 */
928 ui = mtod(m, struct udpiphdr *);
929 ui->ui_pr = IPPROTO_UDP;
930 ui->ui_src = inp->inp_laddr;
931 ui->ui_dst = inp->inp_faddr;
932 ui->ui_sport = inp->inp_lport;
933 ui->ui_dport = inp->inp_fport;
934 ui->ui_ulen = htons((u_int16_t)len + sizeof(struct udphdr));
935
936 /*
937 * Set up checksum and output datagram.
938 */
939 if (udpcksum) {
940 /*
941 * XXX Cache pseudo-header checksum part for
942 * XXX "connected" UDP sockets.
943 */
944 ui->ui_sum = in_cksum_phdr(ui->ui_src.s_addr,
945 ui->ui_dst.s_addr, htons((u_int16_t)len +
946 sizeof(struct udphdr) + IPPROTO_UDP));
947 m->m_pkthdr.csum_flags = M_CSUM_UDPv4;
948 m->m_pkthdr.csum_data = offsetof(struct udphdr, uh_sum);
949 } else
950 ui->ui_sum = 0;
951 ((struct ip *)ui)->ip_len = sizeof (struct udpiphdr) + len;
952 ((struct ip *)ui)->ip_ttl = inp->inp_ip.ip_ttl; /* XXX */
953 ((struct ip *)ui)->ip_tos = inp->inp_ip.ip_tos; /* XXX */
954 udpstat.udps_opackets++;
955
956 #ifdef IPSEC
957 if (ipsec_setsocket(m, inp->inp_socket) != 0) {
958 error = ENOBUFS;
959 goto release;
960 }
961 #endif /*IPSEC*/
962
963 return (ip_output(m, inp->inp_options, &inp->inp_route,
964 inp->inp_socket->so_options & (SO_DONTROUTE | SO_BROADCAST),
965 inp->inp_moptions));
966
967 release:
968 m_freem(m);
969 return (error);
970 }
971
972 int udp_sendspace = 9216; /* really max datagram size */
973 int udp_recvspace = 40 * (1024 + sizeof(struct sockaddr_in));
974 /* 40 1K datagrams */
975
976 /*ARGSUSED*/
977 int
978 udp_usrreq(so, req, m, nam, control, p)
979 struct socket *so;
980 int req;
981 struct mbuf *m, *nam, *control;
982 struct proc *p;
983 {
984 struct inpcb *inp;
985 int s;
986 int error = 0;
987
988 if (req == PRU_CONTROL)
989 return (in_control(so, (long)m, (caddr_t)nam,
990 (struct ifnet *)control, p));
991
992 if (req == PRU_PURGEIF) {
993 in_pcbpurgeif0(&udbtable, (struct ifnet *)control);
994 in_purgeif((struct ifnet *)control);
995 in_pcbpurgeif(&udbtable, (struct ifnet *)control);
996 return (0);
997 }
998
999 s = splsoftnet();
1000 inp = sotoinpcb(so);
1001 #ifdef DIAGNOSTIC
1002 if (req != PRU_SEND && req != PRU_SENDOOB && control)
1003 panic("udp_usrreq: unexpected control mbuf");
1004 #endif
1005 if (inp == 0 && req != PRU_ATTACH) {
1006 error = EINVAL;
1007 goto release;
1008 }
1009
1010 /*
1011 * Note: need to block udp_input while changing
1012 * the udp pcb queue and/or pcb addresses.
1013 */
1014 switch (req) {
1015
1016 case PRU_ATTACH:
1017 if (inp != 0) {
1018 error = EISCONN;
1019 break;
1020 }
1021 if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) {
1022 error = soreserve(so, udp_sendspace, udp_recvspace);
1023 if (error)
1024 break;
1025 }
1026 error = in_pcballoc(so, &udbtable);
1027 if (error)
1028 break;
1029 inp = sotoinpcb(so);
1030 inp->inp_ip.ip_ttl = ip_defttl;
1031 break;
1032
1033 case PRU_DETACH:
1034 in_pcbdetach(inp);
1035 break;
1036
1037 case PRU_BIND:
1038 error = in_pcbbind(inp, nam, p);
1039 break;
1040
1041 case PRU_LISTEN:
1042 error = EOPNOTSUPP;
1043 break;
1044
1045 case PRU_CONNECT:
1046 error = in_pcbconnect(inp, nam);
1047 if (error)
1048 break;
1049 soisconnected(so);
1050 break;
1051
1052 case PRU_CONNECT2:
1053 error = EOPNOTSUPP;
1054 break;
1055
1056 case PRU_DISCONNECT:
1057 /*soisdisconnected(so);*/
1058 so->so_state &= ~SS_ISCONNECTED; /* XXX */
1059 in_pcbdisconnect(inp);
1060 inp->inp_laddr = zeroin_addr; /* XXX */
1061 in_pcbstate(inp, INP_BOUND); /* XXX */
1062 break;
1063
1064 case PRU_SHUTDOWN:
1065 socantsendmore(so);
1066 break;
1067
1068 case PRU_RCVD:
1069 error = EOPNOTSUPP;
1070 break;
1071
1072 case PRU_SEND:
1073 if (control && control->m_len) {
1074 m_freem(control);
1075 m_freem(m);
1076 error = EINVAL;
1077 break;
1078 }
1079 {
1080 struct in_addr laddr; /* XXX */
1081
1082 if (nam) {
1083 laddr = inp->inp_laddr; /* XXX */
1084 if ((so->so_state & SS_ISCONNECTED) != 0) {
1085 error = EISCONN;
1086 goto die;
1087 }
1088 error = in_pcbconnect(inp, nam);
1089 if (error) {
1090 die:
1091 m_freem(m);
1092 break;
1093 }
1094 } else {
1095 if ((so->so_state & SS_ISCONNECTED) == 0) {
1096 error = ENOTCONN;
1097 goto die;
1098 }
1099 }
1100 error = udp_output(m, inp);
1101 if (nam) {
1102 in_pcbdisconnect(inp);
1103 inp->inp_laddr = laddr; /* XXX */
1104 in_pcbstate(inp, INP_BOUND); /* XXX */
1105 }
1106 }
1107 break;
1108
1109 case PRU_SENSE:
1110 /*
1111 * stat: don't bother with a blocksize.
1112 */
1113 splx(s);
1114 return (0);
1115
1116 case PRU_RCVOOB:
1117 error = EOPNOTSUPP;
1118 break;
1119
1120 case PRU_SENDOOB:
1121 m_freem(control);
1122 m_freem(m);
1123 error = EOPNOTSUPP;
1124 break;
1125
1126 case PRU_SOCKADDR:
1127 in_setsockaddr(inp, nam);
1128 break;
1129
1130 case PRU_PEERADDR:
1131 in_setpeeraddr(inp, nam);
1132 break;
1133
1134 default:
1135 panic("udp_usrreq");
1136 }
1137
1138 release:
1139 splx(s);
1140 return (error);
1141 }
1142
1143 /*
1144 * Sysctl for udp variables.
1145 */
1146 int
1147 udp_sysctl(name, namelen, oldp, oldlenp, newp, newlen)
1148 int *name;
1149 u_int namelen;
1150 void *oldp;
1151 size_t *oldlenp;
1152 void *newp;
1153 size_t newlen;
1154 {
1155 /* All sysctl names at this level are terminal. */
1156 if (namelen != 1)
1157 return (ENOTDIR);
1158
1159 switch (name[0]) {
1160 case UDPCTL_CHECKSUM:
1161 return (sysctl_int(oldp, oldlenp, newp, newlen, &udpcksum));
1162 case UDPCTL_SENDSPACE:
1163 return (sysctl_int(oldp, oldlenp, newp, newlen,
1164 &udp_sendspace));
1165 case UDPCTL_RECVSPACE:
1166 return (sysctl_int(oldp, oldlenp, newp, newlen,
1167 &udp_recvspace));
1168 default:
1169 return (ENOPROTOOPT);
1170 }
1171 /* NOTREACHED */
1172 }
1173 #endif
1174