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