1 /*-
2 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
3 * Copyright (c) 2010-2011 Juniper Networks, Inc.
4 * Copyright (c) 2014 Kevin Lo
5 * All rights reserved.
6 *
7 * Portions of this software were developed by Robert N. M. Watson under
8 * contract to Juniper Networks, Inc.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the project nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 *
34 * $KAME: udp6_usrreq.c,v 1.27 2001/05/21 05:45:10 jinmei Exp $
35 * $KAME: udp6_output.c,v 1.31 2001/05/21 16:39:15 jinmei Exp $
36 */
37
38 /*-
39 * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995
40 * The Regents of the University of California.
41 * All rights reserved.
42 *
43 * Redistribution and use in source and binary forms, with or without
44 * modification, are permitted provided that the following conditions
45 * are met:
46 * 1. Redistributions of source code must retain the above copyright
47 * notice, this list of conditions and the following disclaimer.
48 * 2. Redistributions in binary form must reproduce the above copyright
49 * notice, this list of conditions and the following disclaimer in the
50 * documentation and/or other materials provided with the distribution.
51 * 4. Neither the name of the University nor the names of its contributors
52 * may be used to endorse or promote products derived from this software
53 * without specific prior written permission.
54 *
55 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
56 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
57 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
58 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
59 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
60 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
61 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
62 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
63 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
64 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
65 * SUCH DAMAGE.
66 *
67 * @(#)udp_usrreq.c 8.6 (Berkeley) 5/23/95
68 */
69
70 #include <sys/cdefs.h>
71 __FBSDID("$FreeBSD: releng/10.1/sys/netinet6/udp6_usrreq.c 272991 2014-10-12 17:07:15Z tuexen $");
72
73 #include "opt_inet.h"
74 #include "opt_inet6.h"
75 #include "opt_ipfw.h"
76 #include "opt_ipsec.h"
77 #include "opt_kdtrace.h"
78
79 #include <sys/param.h>
80 #include <sys/jail.h>
81 #include <sys/kernel.h>
82 #include <sys/lock.h>
83 #include <sys/mbuf.h>
84 #include <sys/priv.h>
85 #include <sys/proc.h>
86 #include <sys/protosw.h>
87 #include <sys/sdt.h>
88 #include <sys/signalvar.h>
89 #include <sys/socket.h>
90 #include <sys/socketvar.h>
91 #include <sys/sx.h>
92 #include <sys/sysctl.h>
93 #include <sys/syslog.h>
94 #include <sys/systm.h>
95
96 #include <net/if.h>
97 #include <net/if_types.h>
98 #include <net/route.h>
99
100 #include <netinet/in.h>
101 #include <netinet/in_kdtrace.h>
102 #include <netinet/in_pcb.h>
103 #include <netinet/in_systm.h>
104 #include <netinet/in_var.h>
105 #include <netinet/ip.h>
106 #include <netinet/ip_icmp.h>
107 #include <netinet/ip6.h>
108 #include <netinet/icmp_var.h>
109 #include <netinet/icmp6.h>
110 #include <netinet/ip_var.h>
111 #include <netinet/udp.h>
112 #include <netinet/udp_var.h>
113 #include <netinet/udplite.h>
114
115 #include <netinet6/ip6protosw.h>
116 #include <netinet6/ip6_var.h>
117 #include <netinet6/in6_pcb.h>
118 #include <netinet6/udp6_var.h>
119 #include <netinet6/scope6_var.h>
120
121 #ifdef IPSEC
122 #include <netipsec/ipsec.h>
123 #include <netipsec/ipsec6.h>
124 #endif /* IPSEC */
125
126 #include <security/mac/mac_framework.h>
127
128 /*
129 * UDP protocol implementation.
130 * Per RFC 768, August, 1980.
131 */
132
133 extern struct protosw inetsw[];
134 static void udp6_detach(struct socket *so);
135
136 static void
137 udp6_append(struct inpcb *inp, struct mbuf *n, int off,
138 struct sockaddr_in6 *fromsa)
139 {
140 struct socket *so;
141 struct mbuf *opts;
142
143 INP_LOCK_ASSERT(inp);
144
145 #ifdef IPSEC
146 /* Check AH/ESP integrity. */
147 if (ipsec6_in_reject(n, inp)) {
148 m_freem(n);
149 IPSEC6STAT_INC(ips_in_polvio);
150 return;
151 }
152 #endif /* IPSEC */
153 #ifdef MAC
154 if (mac_inpcb_check_deliver(inp, n) != 0) {
155 m_freem(n);
156 return;
157 }
158 #endif
159 opts = NULL;
160 if (inp->inp_flags & INP_CONTROLOPTS ||
161 inp->inp_socket->so_options & SO_TIMESTAMP)
162 ip6_savecontrol(inp, n, &opts);
163 m_adj(n, off + sizeof(struct udphdr));
164
165 so = inp->inp_socket;
166 SOCKBUF_LOCK(&so->so_rcv);
167 if (sbappendaddr_locked(&so->so_rcv, (struct sockaddr *)fromsa, n,
168 opts) == 0) {
169 SOCKBUF_UNLOCK(&so->so_rcv);
170 m_freem(n);
171 if (opts)
172 m_freem(opts);
173 UDPSTAT_INC(udps_fullsock);
174 } else
175 sorwakeup_locked(so);
176 }
177
178 int
179 udp6_input(struct mbuf **mp, int *offp, int proto)
180 {
181 struct mbuf *m = *mp;
182 struct ifnet *ifp;
183 struct ip6_hdr *ip6;
184 struct udphdr *uh;
185 struct inpcb *inp;
186 struct inpcbinfo *pcbinfo;
187 struct udpcb *up;
188 int off = *offp;
189 int cscov_partial;
190 int plen, ulen;
191 struct sockaddr_in6 fromsa;
192 struct m_tag *fwd_tag;
193 uint16_t uh_sum;
194 uint8_t nxt;
195
196 ifp = m->m_pkthdr.rcvif;
197 ip6 = mtod(m, struct ip6_hdr *);
198
199 if (faithprefix_p != NULL && (*faithprefix_p)(&ip6->ip6_dst)) {
200 /* XXX send icmp6 host/port unreach? */
201 m_freem(m);
202 return (IPPROTO_DONE);
203 }
204
205 #ifndef PULLDOWN_TEST
206 IP6_EXTHDR_CHECK(m, off, sizeof(struct udphdr), IPPROTO_DONE);
207 ip6 = mtod(m, struct ip6_hdr *);
208 uh = (struct udphdr *)((caddr_t)ip6 + off);
209 #else
210 IP6_EXTHDR_GET(uh, struct udphdr *, m, off, sizeof(*uh));
211 if (!uh)
212 return (IPPROTO_DONE);
213 #endif
214
215 UDPSTAT_INC(udps_ipackets);
216
217 /*
218 * Destination port of 0 is illegal, based on RFC768.
219 */
220 if (uh->uh_dport == 0)
221 goto badunlocked;
222
223 plen = ntohs(ip6->ip6_plen) - off + sizeof(*ip6);
224 ulen = ntohs((u_short)uh->uh_ulen);
225
226 nxt = ip6->ip6_nxt;
227 cscov_partial = (nxt == IPPROTO_UDPLITE) ? 1 : 0;
228 if (nxt == IPPROTO_UDPLITE) {
229 /* Zero means checksum over the complete packet. */
230 if (ulen == 0)
231 ulen = plen;
232 if (ulen == plen)
233 cscov_partial = 0;
234 if ((ulen < sizeof(struct udphdr)) || (ulen > plen)) {
235 /* XXX: What is the right UDPLite MIB counter? */
236 goto badunlocked;
237 }
238 if (uh->uh_sum == 0) {
239 /* XXX: What is the right UDPLite MIB counter? */
240 goto badunlocked;
241 }
242 } else {
243 if ((ulen < sizeof(struct udphdr)) || (plen != ulen)) {
244 UDPSTAT_INC(udps_badlen);
245 goto badunlocked;
246 }
247 if (uh->uh_sum == 0) {
248 UDPSTAT_INC(udps_nosum);
249 goto badunlocked;
250 }
251 }
252
253 if ((m->m_pkthdr.csum_flags & CSUM_DATA_VALID_IPV6) &&
254 !cscov_partial) {
255 if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR)
256 uh_sum = m->m_pkthdr.csum_data;
257 else
258 uh_sum = in6_cksum_pseudo(ip6, ulen, nxt,
259 m->m_pkthdr.csum_data);
260 uh_sum ^= 0xffff;
261 } else
262 uh_sum = in6_cksum_partial(m, nxt, off, plen, ulen);
263
264 if (uh_sum != 0) {
265 UDPSTAT_INC(udps_badsum);
266 goto badunlocked;
267 }
268
269 /*
270 * Construct sockaddr format source address.
271 */
272 init_sin6(&fromsa, m);
273 fromsa.sin6_port = uh->uh_sport;
274
275 pcbinfo = get_inpcbinfo(nxt);
276 if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) {
277 struct inpcb *last;
278 struct inpcbhead *pcblist;
279 struct ip6_moptions *imo;
280
281 INP_INFO_RLOCK(pcbinfo);
282 /*
283 * In the event that laddr should be set to the link-local
284 * address (this happens in RIPng), the multicast address
285 * specified in the received packet will not match laddr. To
286 * handle this situation, matching is relaxed if the
287 * receiving interface is the same as one specified in the
288 * socket and if the destination multicast address matches
289 * one of the multicast groups specified in the socket.
290 */
291
292 /*
293 * KAME note: traditionally we dropped udpiphdr from mbuf
294 * here. We need udphdr for IPsec processing so we do that
295 * later.
296 */
297 pcblist = get_pcblist(nxt);
298 last = NULL;
299 LIST_FOREACH(inp, pcblist, inp_list) {
300 if ((inp->inp_vflag & INP_IPV6) == 0)
301 continue;
302 if (inp->inp_lport != uh->uh_dport)
303 continue;
304 if (inp->inp_fport != 0 &&
305 inp->inp_fport != uh->uh_sport)
306 continue;
307 if (!IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr)) {
308 if (!IN6_ARE_ADDR_EQUAL(&inp->in6p_laddr,
309 &ip6->ip6_dst))
310 continue;
311 }
312 if (!IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr)) {
313 if (!IN6_ARE_ADDR_EQUAL(&inp->in6p_faddr,
314 &ip6->ip6_src) ||
315 inp->inp_fport != uh->uh_sport)
316 continue;
317 }
318
319 /*
320 * XXXRW: Because we weren't holding either the inpcb
321 * or the hash lock when we checked for a match
322 * before, we should probably recheck now that the
323 * inpcb lock is (supposed to be) held.
324 */
325
326 /*
327 * Handle socket delivery policy for any-source
328 * and source-specific multicast. [RFC3678]
329 */
330 imo = inp->in6p_moptions;
331 if (imo && IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) {
332 struct sockaddr_in6 mcaddr;
333 int blocked;
334
335 INP_RLOCK(inp);
336
337 bzero(&mcaddr, sizeof(struct sockaddr_in6));
338 mcaddr.sin6_len = sizeof(struct sockaddr_in6);
339 mcaddr.sin6_family = AF_INET6;
340 mcaddr.sin6_addr = ip6->ip6_dst;
341
342 blocked = im6o_mc_filter(imo, ifp,
343 (struct sockaddr *)&mcaddr,
344 (struct sockaddr *)&fromsa);
345 if (blocked != MCAST_PASS) {
346 if (blocked == MCAST_NOTGMEMBER)
347 IP6STAT_INC(ip6s_notmember);
348 if (blocked == MCAST_NOTSMEMBER ||
349 blocked == MCAST_MUTED)
350 UDPSTAT_INC(udps_filtermcast);
351 INP_RUNLOCK(inp); /* XXX */
352 continue;
353 }
354
355 INP_RUNLOCK(inp);
356 }
357 if (last != NULL) {
358 struct mbuf *n;
359
360 if ((n = m_copy(m, 0, M_COPYALL)) != NULL) {
361 INP_RLOCK(last);
362 up = intoudpcb(last);
363 if (up->u_tun_func == NULL) {
364 udp6_append(last, n, off, &fromsa);
365 } else {
366 /*
367 * Engage the tunneling
368 * protocol we will have to
369 * leave the info_lock up,
370 * since we are hunting
371 * through multiple UDP's.
372 *
373 */
374 (*up->u_tun_func)(n, off, last);
375 }
376 INP_RUNLOCK(last);
377 }
378 }
379 last = inp;
380 /*
381 * Don't look for additional matches if this one does
382 * not have either the SO_REUSEPORT or SO_REUSEADDR
383 * socket options set. This heuristic avoids
384 * searching through all pcbs in the common case of a
385 * non-shared port. It assumes that an application
386 * will never clear these options after setting them.
387 */
388 if ((last->inp_socket->so_options &
389 (SO_REUSEPORT|SO_REUSEADDR)) == 0)
390 break;
391 }
392
393 if (last == NULL) {
394 /*
395 * No matching pcb found; discard datagram. (No need
396 * to send an ICMP Port Unreachable for a broadcast
397 * or multicast datgram.)
398 */
399 UDPSTAT_INC(udps_noport);
400 UDPSTAT_INC(udps_noportmcast);
401 goto badheadlocked;
402 }
403 INP_RLOCK(last);
404 INP_INFO_RUNLOCK(pcbinfo);
405 up = intoudpcb(last);
406 UDP_PROBE(receive, NULL, last, ip6, last, uh);
407 if (up->u_tun_func == NULL) {
408 udp6_append(last, m, off, &fromsa);
409 } else {
410 /*
411 * Engage the tunneling protocol.
412 */
413 (*up->u_tun_func)(m, off, last);
414 }
415 INP_RUNLOCK(last);
416 return (IPPROTO_DONE);
417 }
418 /*
419 * Locate pcb for datagram.
420 */
421
422 /*
423 * Grab info from PACKET_TAG_IPFORWARD tag prepended to the chain.
424 */
425 if ((m->m_flags & M_IP6_NEXTHOP) &&
426 (fwd_tag = m_tag_find(m, PACKET_TAG_IPFORWARD, NULL)) != NULL) {
427 struct sockaddr_in6 *next_hop6;
428
429 next_hop6 = (struct sockaddr_in6 *)(fwd_tag + 1);
430
431 /*
432 * Transparently forwarded. Pretend to be the destination.
433 * Already got one like this?
434 */
435 inp = in6_pcblookup_mbuf(pcbinfo, &ip6->ip6_src,
436 uh->uh_sport, &ip6->ip6_dst, uh->uh_dport,
437 INPLOOKUP_RLOCKPCB, m->m_pkthdr.rcvif, m);
438 if (!inp) {
439 /*
440 * It's new. Try to find the ambushing socket.
441 * Because we've rewritten the destination address,
442 * any hardware-generated hash is ignored.
443 */
444 inp = in6_pcblookup(pcbinfo, &ip6->ip6_src,
445 uh->uh_sport, &next_hop6->sin6_addr,
446 next_hop6->sin6_port ? htons(next_hop6->sin6_port) :
447 uh->uh_dport, INPLOOKUP_WILDCARD |
448 INPLOOKUP_RLOCKPCB, m->m_pkthdr.rcvif);
449 }
450 /* Remove the tag from the packet. We don't need it anymore. */
451 m_tag_delete(m, fwd_tag);
452 m->m_flags &= ~M_IP6_NEXTHOP;
453 } else
454 inp = in6_pcblookup_mbuf(pcbinfo, &ip6->ip6_src,
455 uh->uh_sport, &ip6->ip6_dst, uh->uh_dport,
456 INPLOOKUP_WILDCARD | INPLOOKUP_RLOCKPCB,
457 m->m_pkthdr.rcvif, m);
458 if (inp == NULL) {
459 if (udp_log_in_vain) {
460 char ip6bufs[INET6_ADDRSTRLEN];
461 char ip6bufd[INET6_ADDRSTRLEN];
462
463 log(LOG_INFO,
464 "Connection attempt to UDP [%s]:%d from [%s]:%d\n",
465 ip6_sprintf(ip6bufd, &ip6->ip6_dst),
466 ntohs(uh->uh_dport),
467 ip6_sprintf(ip6bufs, &ip6->ip6_src),
468 ntohs(uh->uh_sport));
469 }
470 UDPSTAT_INC(udps_noport);
471 if (m->m_flags & M_MCAST) {
472 printf("UDP6: M_MCAST is set in a unicast packet.\n");
473 UDPSTAT_INC(udps_noportmcast);
474 goto badunlocked;
475 }
476 if (V_udp_blackhole)
477 goto badunlocked;
478 if (badport_bandlim(BANDLIM_ICMP6_UNREACH) < 0)
479 goto badunlocked;
480 icmp6_error(m, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOPORT, 0);
481 return (IPPROTO_DONE);
482 }
483 INP_RLOCK_ASSERT(inp);
484 up = intoudpcb(inp);
485 if (cscov_partial) {
486 if (up->u_rxcslen == 0 || up->u_rxcslen > ulen) {
487 INP_RUNLOCK(inp);
488 m_freem(m);
489 return (IPPROTO_DONE);
490 }
491 }
492 UDP_PROBE(receive, NULL, inp, ip6, inp, uh);
493 if (up->u_tun_func == NULL) {
494 udp6_append(inp, m, off, &fromsa);
495 } else {
496 /*
497 * Engage the tunneling protocol.
498 */
499
500 (*up->u_tun_func)(m, off, inp);
501 }
502 INP_RUNLOCK(inp);
503 return (IPPROTO_DONE);
504
505 badheadlocked:
506 INP_INFO_RUNLOCK(pcbinfo);
507 badunlocked:
508 if (m)
509 m_freem(m);
510 return (IPPROTO_DONE);
511 }
512
513 static void
514 udp6_common_ctlinput(int cmd, struct sockaddr *sa, void *d,
515 struct inpcbinfo *pcbinfo)
516 {
517 struct udphdr uh;
518 struct ip6_hdr *ip6;
519 struct mbuf *m;
520 int off = 0;
521 struct ip6ctlparam *ip6cp = NULL;
522 const struct sockaddr_in6 *sa6_src = NULL;
523 void *cmdarg;
524 struct inpcb *(*notify)(struct inpcb *, int) = udp_notify;
525 struct udp_portonly {
526 u_int16_t uh_sport;
527 u_int16_t uh_dport;
528 } *uhp;
529
530 if (sa->sa_family != AF_INET6 ||
531 sa->sa_len != sizeof(struct sockaddr_in6))
532 return;
533
534 if ((unsigned)cmd >= PRC_NCMDS)
535 return;
536 if (PRC_IS_REDIRECT(cmd))
537 notify = in6_rtchange, d = NULL;
538 else if (cmd == PRC_HOSTDEAD)
539 d = NULL;
540 else if (inet6ctlerrmap[cmd] == 0)
541 return;
542
543 /* if the parameter is from icmp6, decode it. */
544 if (d != NULL) {
545 ip6cp = (struct ip6ctlparam *)d;
546 m = ip6cp->ip6c_m;
547 ip6 = ip6cp->ip6c_ip6;
548 off = ip6cp->ip6c_off;
549 cmdarg = ip6cp->ip6c_cmdarg;
550 sa6_src = ip6cp->ip6c_src;
551 } else {
552 m = NULL;
553 ip6 = NULL;
554 cmdarg = NULL;
555 sa6_src = &sa6_any;
556 }
557
558 if (ip6) {
559 /*
560 * XXX: We assume that when IPV6 is non NULL,
561 * M and OFF are valid.
562 */
563
564 /* Check if we can safely examine src and dst ports. */
565 if (m->m_pkthdr.len < off + sizeof(*uhp))
566 return;
567
568 bzero(&uh, sizeof(uh));
569 m_copydata(m, off, sizeof(*uhp), (caddr_t)&uh);
570
571 (void)in6_pcbnotify(pcbinfo, sa, uh.uh_dport,
572 (struct sockaddr *)ip6cp->ip6c_src, uh.uh_sport, cmd,
573 cmdarg, notify);
574 } else
575 (void)in6_pcbnotify(pcbinfo, sa, 0,
576 (const struct sockaddr *)sa6_src, 0, cmd, cmdarg, notify);
577 }
578
579 void
580 udp6_ctlinput(int cmd, struct sockaddr *sa, void *d)
581 {
582
583 return (udp6_common_ctlinput(cmd, sa, d, &V_udbinfo));
584 }
585
586 void
587 udplite6_ctlinput(int cmd, struct sockaddr *sa, void *d)
588 {
589
590 return (udp6_common_ctlinput(cmd, sa, d, &V_ulitecbinfo));
591 }
592
593 static int
594 udp6_getcred(SYSCTL_HANDLER_ARGS)
595 {
596 struct xucred xuc;
597 struct sockaddr_in6 addrs[2];
598 struct inpcb *inp;
599 int error;
600
601 error = priv_check(req->td, PRIV_NETINET_GETCRED);
602 if (error)
603 return (error);
604
605 if (req->newlen != sizeof(addrs))
606 return (EINVAL);
607 if (req->oldlen != sizeof(struct xucred))
608 return (EINVAL);
609 error = SYSCTL_IN(req, addrs, sizeof(addrs));
610 if (error)
611 return (error);
612 if ((error = sa6_embedscope(&addrs[0], V_ip6_use_defzone)) != 0 ||
613 (error = sa6_embedscope(&addrs[1], V_ip6_use_defzone)) != 0) {
614 return (error);
615 }
616 inp = in6_pcblookup(&V_udbinfo, &addrs[1].sin6_addr,
617 addrs[1].sin6_port, &addrs[0].sin6_addr, addrs[0].sin6_port,
618 INPLOOKUP_WILDCARD | INPLOOKUP_RLOCKPCB, NULL);
619 if (inp != NULL) {
620 INP_RLOCK_ASSERT(inp);
621 if (inp->inp_socket == NULL)
622 error = ENOENT;
623 if (error == 0)
624 error = cr_canseesocket(req->td->td_ucred,
625 inp->inp_socket);
626 if (error == 0)
627 cru2x(inp->inp_cred, &xuc);
628 INP_RUNLOCK(inp);
629 } else
630 error = ENOENT;
631 if (error == 0)
632 error = SYSCTL_OUT(req, &xuc, sizeof(struct xucred));
633 return (error);
634 }
635
636 SYSCTL_PROC(_net_inet6_udp6, OID_AUTO, getcred, CTLTYPE_OPAQUE|CTLFLAG_RW, 0,
637 0, udp6_getcred, "S,xucred", "Get the xucred of a UDP6 connection");
638
639 static int
640 udp6_output(struct inpcb *inp, struct mbuf *m, struct sockaddr *addr6,
641 struct mbuf *control, struct thread *td)
642 {
643 u_int32_t ulen = m->m_pkthdr.len;
644 u_int32_t plen = sizeof(struct udphdr) + ulen;
645 struct ip6_hdr *ip6;
646 struct udphdr *udp6;
647 struct in6_addr *laddr, *faddr, in6a;
648 struct sockaddr_in6 *sin6 = NULL;
649 struct ifnet *oifp = NULL;
650 int cscov_partial = 0;
651 int scope_ambiguous = 0;
652 u_short fport;
653 int error = 0;
654 uint8_t nxt;
655 uint16_t cscov = 0;
656 struct ip6_pktopts *optp, opt;
657 int af = AF_INET6, hlen = sizeof(struct ip6_hdr);
658 int flags;
659 struct sockaddr_in6 tmp;
660
661 INP_WLOCK_ASSERT(inp);
662 INP_HASH_WLOCK_ASSERT(inp->inp_pcbinfo);
663
664 if (addr6) {
665 /* addr6 has been validated in udp6_send(). */
666 sin6 = (struct sockaddr_in6 *)addr6;
667
668 /* protect *sin6 from overwrites */
669 tmp = *sin6;
670 sin6 = &tmp;
671
672 /*
673 * Application should provide a proper zone ID or the use of
674 * default zone IDs should be enabled. Unfortunately, some
675 * applications do not behave as it should, so we need a
676 * workaround. Even if an appropriate ID is not determined,
677 * we'll see if we can determine the outgoing interface. If we
678 * can, determine the zone ID based on the interface below.
679 */
680 if (sin6->sin6_scope_id == 0 && !V_ip6_use_defzone)
681 scope_ambiguous = 1;
682 if ((error = sa6_embedscope(sin6, V_ip6_use_defzone)) != 0)
683 return (error);
684 }
685
686 if (control) {
687 if ((error = ip6_setpktopts(control, &opt,
688 inp->in6p_outputopts, td->td_ucred, IPPROTO_UDP)) != 0)
689 goto release;
690 optp = &opt;
691 } else
692 optp = inp->in6p_outputopts;
693
694 if (sin6) {
695 faddr = &sin6->sin6_addr;
696
697 /*
698 * Since we saw no essential reason for calling in_pcbconnect,
699 * we get rid of such kind of logic, and call in6_selectsrc
700 * and in6_pcbsetport in order to fill in the local address
701 * and the local port.
702 */
703 if (sin6->sin6_port == 0) {
704 error = EADDRNOTAVAIL;
705 goto release;
706 }
707
708 if (!IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr)) {
709 /* how about ::ffff:0.0.0.0 case? */
710 error = EISCONN;
711 goto release;
712 }
713
714 fport = sin6->sin6_port; /* allow 0 port */
715
716 if (IN6_IS_ADDR_V4MAPPED(faddr)) {
717 if ((inp->inp_flags & IN6P_IPV6_V6ONLY)) {
718 /*
719 * I believe we should explicitly discard the
720 * packet when mapped addresses are disabled,
721 * rather than send the packet as an IPv6 one.
722 * If we chose the latter approach, the packet
723 * might be sent out on the wire based on the
724 * default route, the situation which we'd
725 * probably want to avoid.
726 * (20010421 jinmei@kame.net)
727 */
728 error = EINVAL;
729 goto release;
730 }
731 if (!IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr) &&
732 !IN6_IS_ADDR_V4MAPPED(&inp->in6p_laddr)) {
733 /*
734 * when remote addr is an IPv4-mapped address,
735 * local addr should not be an IPv6 address,
736 * since you cannot determine how to map IPv6
737 * source address to IPv4.
738 */
739 error = EINVAL;
740 goto release;
741 }
742
743 af = AF_INET;
744 }
745
746 if (!IN6_IS_ADDR_V4MAPPED(faddr)) {
747 error = in6_selectsrc(sin6, optp, inp, NULL,
748 td->td_ucred, &oifp, &in6a);
749 if (error)
750 goto release;
751 if (oifp && scope_ambiguous &&
752 (error = in6_setscope(&sin6->sin6_addr,
753 oifp, NULL))) {
754 goto release;
755 }
756 laddr = &in6a;
757 } else
758 laddr = &inp->in6p_laddr; /* XXX */
759 if (laddr == NULL) {
760 if (error == 0)
761 error = EADDRNOTAVAIL;
762 goto release;
763 }
764 if (inp->inp_lport == 0 &&
765 (error = in6_pcbsetport(laddr, inp, td->td_ucred)) != 0) {
766 /* Undo an address bind that may have occurred. */
767 inp->in6p_laddr = in6addr_any;
768 goto release;
769 }
770 } else {
771 if (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr)) {
772 error = ENOTCONN;
773 goto release;
774 }
775 if (IN6_IS_ADDR_V4MAPPED(&inp->in6p_faddr)) {
776 if ((inp->inp_flags & IN6P_IPV6_V6ONLY)) {
777 /*
778 * XXX: this case would happen when the
779 * application sets the V6ONLY flag after
780 * connecting the foreign address.
781 * Such applications should be fixed,
782 * so we bark here.
783 */
784 log(LOG_INFO, "udp6_output: IPV6_V6ONLY "
785 "option was set for a connected socket\n");
786 error = EINVAL;
787 goto release;
788 } else
789 af = AF_INET;
790 }
791 laddr = &inp->in6p_laddr;
792 faddr = &inp->in6p_faddr;
793 fport = inp->inp_fport;
794 }
795
796 if (af == AF_INET)
797 hlen = sizeof(struct ip);
798
799 /*
800 * Calculate data length and get a mbuf
801 * for UDP and IP6 headers.
802 */
803 M_PREPEND(m, hlen + sizeof(struct udphdr), M_NOWAIT);
804 if (m == 0) {
805 error = ENOBUFS;
806 goto release;
807 }
808
809 /*
810 * Stuff checksum and output datagram.
811 */
812 nxt = (inp->inp_socket->so_proto->pr_protocol == IPPROTO_UDP) ?
813 IPPROTO_UDP : IPPROTO_UDPLITE;
814 udp6 = (struct udphdr *)(mtod(m, caddr_t) + hlen);
815 udp6->uh_sport = inp->inp_lport; /* lport is always set in the PCB */
816 udp6->uh_dport = fport;
817 if (nxt == IPPROTO_UDPLITE) {
818 struct udpcb *up;
819
820 up = intoudpcb(inp);
821 cscov = up->u_txcslen;
822 if (cscov >= plen)
823 cscov = 0;
824 udp6->uh_ulen = htons(cscov);
825 /*
826 * For UDP-Lite, checksum coverage length of zero means
827 * the entire UDPLite packet is covered by the checksum.
828 */
829 cscov_partial = (cscov == 0) ? 0 : 1;
830 } else if (plen <= 0xffff)
831 udp6->uh_ulen = htons((u_short)plen);
832 else
833 udp6->uh_ulen = 0;
834 udp6->uh_sum = 0;
835
836 switch (af) {
837 case AF_INET6:
838 ip6 = mtod(m, struct ip6_hdr *);
839 ip6->ip6_flow = inp->inp_flow & IPV6_FLOWINFO_MASK;
840 ip6->ip6_vfc &= ~IPV6_VERSION_MASK;
841 ip6->ip6_vfc |= IPV6_VERSION;
842 ip6->ip6_plen = htons((u_short)plen);
843 ip6->ip6_nxt = nxt;
844 ip6->ip6_hlim = in6_selecthlim(inp, NULL);
845 ip6->ip6_src = *laddr;
846 ip6->ip6_dst = *faddr;
847
848 if (cscov_partial) {
849 if ((udp6->uh_sum = in6_cksum_partial(m, nxt,
850 sizeof(struct ip6_hdr), plen, cscov)) == 0)
851 udp6->uh_sum = 0xffff;
852 } else {
853 udp6->uh_sum = in6_cksum_pseudo(ip6, plen, nxt, 0);
854 m->m_pkthdr.csum_flags = CSUM_UDP_IPV6;
855 m->m_pkthdr.csum_data = offsetof(struct udphdr, uh_sum);
856 }
857
858 flags = 0;
859
860 UDP_PROBE(send, NULL, inp, ip6, inp, udp6);
861 UDPSTAT_INC(udps_opackets);
862 error = ip6_output(m, optp, NULL, flags, inp->in6p_moptions,
863 NULL, inp);
864 break;
865 case AF_INET:
866 error = EAFNOSUPPORT;
867 goto release;
868 }
869 goto releaseopt;
870
871 release:
872 m_freem(m);
873
874 releaseopt:
875 if (control) {
876 ip6_clearpktopts(&opt, -1);
877 m_freem(control);
878 }
879 return (error);
880 }
881
882 static void
883 udp6_abort(struct socket *so)
884 {
885 struct inpcb *inp;
886 struct inpcbinfo *pcbinfo;
887
888 pcbinfo = get_inpcbinfo(so->so_proto->pr_protocol);
889 inp = sotoinpcb(so);
890 KASSERT(inp != NULL, ("udp6_abort: inp == NULL"));
891
892 #ifdef INET
893 if (inp->inp_vflag & INP_IPV4) {
894 struct pr_usrreqs *pru;
895
896 pru = inetsw[ip_protox[IPPROTO_UDP]].pr_usrreqs;
897 (*pru->pru_abort)(so);
898 return;
899 }
900 #endif
901
902 INP_WLOCK(inp);
903 if (!IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr)) {
904 INP_HASH_WLOCK(pcbinfo);
905 in6_pcbdisconnect(inp);
906 inp->in6p_laddr = in6addr_any;
907 INP_HASH_WUNLOCK(pcbinfo);
908 soisdisconnected(so);
909 }
910 INP_WUNLOCK(inp);
911 }
912
913 static int
914 udp6_attach(struct socket *so, int proto, struct thread *td)
915 {
916 struct inpcb *inp;
917 struct inpcbinfo *pcbinfo;
918 int error;
919
920 pcbinfo = get_inpcbinfo(so->so_proto->pr_protocol);
921 inp = sotoinpcb(so);
922 KASSERT(inp == NULL, ("udp6_attach: inp != NULL"));
923
924 if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) {
925 error = soreserve(so, udp_sendspace, udp_recvspace);
926 if (error)
927 return (error);
928 }
929 INP_INFO_WLOCK(pcbinfo);
930 error = in_pcballoc(so, pcbinfo);
931 if (error) {
932 INP_INFO_WUNLOCK(pcbinfo);
933 return (error);
934 }
935 inp = (struct inpcb *)so->so_pcb;
936 inp->inp_vflag |= INP_IPV6;
937 if ((inp->inp_flags & IN6P_IPV6_V6ONLY) == 0)
938 inp->inp_vflag |= INP_IPV4;
939 inp->in6p_hops = -1; /* use kernel default */
940 inp->in6p_cksum = -1; /* just to be sure */
941 /*
942 * XXX: ugly!!
943 * IPv4 TTL initialization is necessary for an IPv6 socket as well,
944 * because the socket may be bound to an IPv6 wildcard address,
945 * which may match an IPv4-mapped IPv6 address.
946 */
947 inp->inp_ip_ttl = V_ip_defttl;
948
949 error = udp_newudpcb(inp);
950 if (error) {
951 in_pcbdetach(inp);
952 in_pcbfree(inp);
953 INP_INFO_WUNLOCK(pcbinfo);
954 return (error);
955 }
956 INP_WUNLOCK(inp);
957 INP_INFO_WUNLOCK(pcbinfo);
958 return (0);
959 }
960
961 static int
962 udp6_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
963 {
964 struct inpcb *inp;
965 struct inpcbinfo *pcbinfo;
966 int error;
967
968 pcbinfo = get_inpcbinfo(so->so_proto->pr_protocol);
969 inp = sotoinpcb(so);
970 KASSERT(inp != NULL, ("udp6_bind: inp == NULL"));
971
972 INP_WLOCK(inp);
973 INP_HASH_WLOCK(pcbinfo);
974 inp->inp_vflag &= ~INP_IPV4;
975 inp->inp_vflag |= INP_IPV6;
976 if ((inp->inp_flags & IN6P_IPV6_V6ONLY) == 0) {
977 struct sockaddr_in6 *sin6_p;
978
979 sin6_p = (struct sockaddr_in6 *)nam;
980
981 if (IN6_IS_ADDR_UNSPECIFIED(&sin6_p->sin6_addr))
982 inp->inp_vflag |= INP_IPV4;
983 #ifdef INET
984 else if (IN6_IS_ADDR_V4MAPPED(&sin6_p->sin6_addr)) {
985 struct sockaddr_in sin;
986
987 in6_sin6_2_sin(&sin, sin6_p);
988 inp->inp_vflag |= INP_IPV4;
989 inp->inp_vflag &= ~INP_IPV6;
990 error = in_pcbbind(inp, (struct sockaddr *)&sin,
991 td->td_ucred);
992 goto out;
993 }
994 #endif
995 }
996
997 error = in6_pcbbind(inp, nam, td->td_ucred);
998 #ifdef INET
999 out:
1000 #endif
1001 INP_HASH_WUNLOCK(pcbinfo);
1002 INP_WUNLOCK(inp);
1003 return (error);
1004 }
1005
1006 static void
1007 udp6_close(struct socket *so)
1008 {
1009 struct inpcb *inp;
1010 struct inpcbinfo *pcbinfo;
1011
1012 pcbinfo = get_inpcbinfo(so->so_proto->pr_protocol);
1013 inp = sotoinpcb(so);
1014 KASSERT(inp != NULL, ("udp6_close: inp == NULL"));
1015
1016 #ifdef INET
1017 if (inp->inp_vflag & INP_IPV4) {
1018 struct pr_usrreqs *pru;
1019
1020 pru = inetsw[ip_protox[IPPROTO_UDP]].pr_usrreqs;
1021 (*pru->pru_disconnect)(so);
1022 return;
1023 }
1024 #endif
1025 INP_WLOCK(inp);
1026 if (!IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr)) {
1027 INP_HASH_WLOCK(pcbinfo);
1028 in6_pcbdisconnect(inp);
1029 inp->in6p_laddr = in6addr_any;
1030 INP_HASH_WUNLOCK(pcbinfo);
1031 soisdisconnected(so);
1032 }
1033 INP_WUNLOCK(inp);
1034 }
1035
1036 static int
1037 udp6_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
1038 {
1039 struct inpcb *inp;
1040 struct inpcbinfo *pcbinfo;
1041 struct sockaddr_in6 *sin6;
1042 int error;
1043
1044 pcbinfo = get_inpcbinfo(so->so_proto->pr_protocol);
1045 inp = sotoinpcb(so);
1046 sin6 = (struct sockaddr_in6 *)nam;
1047 KASSERT(inp != NULL, ("udp6_connect: inp == NULL"));
1048
1049 /*
1050 * XXXRW: Need to clarify locking of v4/v6 flags.
1051 */
1052 INP_WLOCK(inp);
1053 #ifdef INET
1054 if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
1055 struct sockaddr_in sin;
1056
1057 if ((inp->inp_flags & IN6P_IPV6_V6ONLY) != 0) {
1058 error = EINVAL;
1059 goto out;
1060 }
1061 if (inp->inp_faddr.s_addr != INADDR_ANY) {
1062 error = EISCONN;
1063 goto out;
1064 }
1065 in6_sin6_2_sin(&sin, sin6);
1066 inp->inp_vflag |= INP_IPV4;
1067 inp->inp_vflag &= ~INP_IPV6;
1068 error = prison_remote_ip4(td->td_ucred, &sin.sin_addr);
1069 if (error != 0)
1070 goto out;
1071 INP_HASH_WLOCK(pcbinfo);
1072 error = in_pcbconnect(inp, (struct sockaddr *)&sin,
1073 td->td_ucred);
1074 INP_HASH_WUNLOCK(pcbinfo);
1075 if (error == 0)
1076 soisconnected(so);
1077 goto out;
1078 }
1079 #endif
1080 if (!IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr)) {
1081 error = EISCONN;
1082 goto out;
1083 }
1084 inp->inp_vflag &= ~INP_IPV4;
1085 inp->inp_vflag |= INP_IPV6;
1086 error = prison_remote_ip6(td->td_ucred, &sin6->sin6_addr);
1087 if (error != 0)
1088 goto out;
1089 INP_HASH_WLOCK(pcbinfo);
1090 error = in6_pcbconnect(inp, nam, td->td_ucred);
1091 INP_HASH_WUNLOCK(pcbinfo);
1092 if (error == 0)
1093 soisconnected(so);
1094 out:
1095 INP_WUNLOCK(inp);
1096 return (error);
1097 }
1098
1099 static void
1100 udp6_detach(struct socket *so)
1101 {
1102 struct inpcb *inp;
1103 struct inpcbinfo *pcbinfo;
1104 struct udpcb *up;
1105
1106 pcbinfo = get_inpcbinfo(so->so_proto->pr_protocol);
1107 inp = sotoinpcb(so);
1108 KASSERT(inp != NULL, ("udp6_detach: inp == NULL"));
1109
1110 INP_INFO_WLOCK(pcbinfo);
1111 INP_WLOCK(inp);
1112 up = intoudpcb(inp);
1113 KASSERT(up != NULL, ("%s: up == NULL", __func__));
1114 in_pcbdetach(inp);
1115 in_pcbfree(inp);
1116 INP_INFO_WUNLOCK(pcbinfo);
1117 udp_discardcb(up);
1118 }
1119
1120 static int
1121 udp6_disconnect(struct socket *so)
1122 {
1123 struct inpcb *inp;
1124 struct inpcbinfo *pcbinfo;
1125 int error;
1126
1127 pcbinfo = get_inpcbinfo(so->so_proto->pr_protocol);
1128 inp = sotoinpcb(so);
1129 KASSERT(inp != NULL, ("udp6_disconnect: inp == NULL"));
1130
1131 #ifdef INET
1132 if (inp->inp_vflag & INP_IPV4) {
1133 struct pr_usrreqs *pru;
1134
1135 pru = inetsw[ip_protox[IPPROTO_UDP]].pr_usrreqs;
1136 (void)(*pru->pru_disconnect)(so);
1137 return (0);
1138 }
1139 #endif
1140
1141 INP_WLOCK(inp);
1142
1143 if (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr)) {
1144 error = ENOTCONN;
1145 goto out;
1146 }
1147
1148 INP_HASH_WLOCK(pcbinfo);
1149 in6_pcbdisconnect(inp);
1150 inp->in6p_laddr = in6addr_any;
1151 INP_HASH_WUNLOCK(pcbinfo);
1152 SOCK_LOCK(so);
1153 so->so_state &= ~SS_ISCONNECTED; /* XXX */
1154 SOCK_UNLOCK(so);
1155 out:
1156 INP_WUNLOCK(inp);
1157 return (0);
1158 }
1159
1160 static int
1161 udp6_send(struct socket *so, int flags, struct mbuf *m,
1162 struct sockaddr *addr, struct mbuf *control, struct thread *td)
1163 {
1164 struct inpcb *inp;
1165 struct inpcbinfo *pcbinfo;
1166 int error = 0;
1167
1168 pcbinfo = get_inpcbinfo(so->so_proto->pr_protocol);
1169 inp = sotoinpcb(so);
1170 KASSERT(inp != NULL, ("udp6_send: inp == NULL"));
1171
1172 INP_WLOCK(inp);
1173 if (addr) {
1174 if (addr->sa_len != sizeof(struct sockaddr_in6)) {
1175 error = EINVAL;
1176 goto bad;
1177 }
1178 if (addr->sa_family != AF_INET6) {
1179 error = EAFNOSUPPORT;
1180 goto bad;
1181 }
1182 }
1183
1184 #ifdef INET
1185 if ((inp->inp_flags & IN6P_IPV6_V6ONLY) == 0) {
1186 int hasv4addr;
1187 struct sockaddr_in6 *sin6 = 0;
1188
1189 if (addr == 0)
1190 hasv4addr = (inp->inp_vflag & INP_IPV4);
1191 else {
1192 sin6 = (struct sockaddr_in6 *)addr;
1193 hasv4addr = IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)
1194 ? 1 : 0;
1195 }
1196 if (hasv4addr) {
1197 struct pr_usrreqs *pru;
1198
1199 /*
1200 * XXXRW: We release UDP-layer locks before calling
1201 * udp_send() in order to avoid recursion. However,
1202 * this does mean there is a short window where inp's
1203 * fields are unstable. Could this lead to a
1204 * potential race in which the factors causing us to
1205 * select the UDPv4 output routine are invalidated?
1206 */
1207 INP_WUNLOCK(inp);
1208 if (sin6)
1209 in6_sin6_2_sin_in_sock(addr);
1210 pru = inetsw[ip_protox[IPPROTO_UDP]].pr_usrreqs;
1211 /* addr will just be freed in sendit(). */
1212 return ((*pru->pru_send)(so, flags, m, addr, control,
1213 td));
1214 }
1215 }
1216 #endif
1217 #ifdef MAC
1218 mac_inpcb_create_mbuf(inp, m);
1219 #endif
1220 INP_HASH_WLOCK(pcbinfo);
1221 error = udp6_output(inp, m, addr, control, td);
1222 INP_HASH_WUNLOCK(pcbinfo);
1223 #ifdef INET
1224 #endif
1225 INP_WUNLOCK(inp);
1226 return (error);
1227
1228 bad:
1229 INP_WUNLOCK(inp);
1230 m_freem(m);
1231 return (error);
1232 }
1233
1234 struct pr_usrreqs udp6_usrreqs = {
1235 .pru_abort = udp6_abort,
1236 .pru_attach = udp6_attach,
1237 .pru_bind = udp6_bind,
1238 .pru_connect = udp6_connect,
1239 .pru_control = in6_control,
1240 .pru_detach = udp6_detach,
1241 .pru_disconnect = udp6_disconnect,
1242 .pru_peeraddr = in6_mapped_peeraddr,
1243 .pru_send = udp6_send,
1244 .pru_shutdown = udp_shutdown,
1245 .pru_sockaddr = in6_mapped_sockaddr,
1246 .pru_soreceive = soreceive_dgram,
1247 .pru_sosend = sosend_dgram,
1248 .pru_sosetlabel = in_pcbsosetlabel,
1249 .pru_close = udp6_close
1250 };
Cache object: 353f3fc6b81699961ddeca189fc0a7e9
|