1 /* $NetBSD: raw_ip6.c,v 1.149 2016/08/01 03:15:31 ozaki-r Exp $ */ 2 /* $KAME: raw_ip6.c,v 1.82 2001/07/23 18:57:56 jinmei Exp $ */ 3 4 /* 5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. Neither the name of the project nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 */ 32 33 /* 34 * Copyright (c) 1982, 1986, 1988, 1993 35 * The Regents of the University of California. All rights reserved. 36 * 37 * Redistribution and use in source and binary forms, with or without 38 * modification, are permitted provided that the following conditions 39 * are met: 40 * 1. Redistributions of source code must retain the above copyright 41 * notice, this list of conditions and the following disclaimer. 42 * 2. Redistributions in binary form must reproduce the above copyright 43 * notice, this list of conditions and the following disclaimer in the 44 * documentation and/or other materials provided with the distribution. 45 * 3. Neither the name of the University nor the names of its contributors 46 * may be used to endorse or promote products derived from this software 47 * without specific prior written permission. 48 * 49 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 50 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 51 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 52 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 53 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 54 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 55 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 56 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 57 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 58 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 59 * SUCH DAMAGE. 60 * 61 * @(#)raw_ip.c 8.2 (Berkeley) 1/4/94 62 */ 63 64 #include <sys/cdefs.h> 65 __KERNEL_RCSID(0, "$NetBSD: raw_ip6.c,v 1.149 2016/08/01 03:15:31 ozaki-r Exp $"); 66 67 #ifdef _KERNEL_OPT 68 #include "opt_ipsec.h" 69 #endif 70 71 #include <sys/param.h> 72 #include <sys/sysctl.h> 73 #include <sys/mbuf.h> 74 #include <sys/socket.h> 75 #include <sys/protosw.h> 76 #include <sys/socketvar.h> 77 #include <sys/systm.h> 78 #include <sys/proc.h> 79 #include <sys/kauth.h> 80 #include <sys/kmem.h> 81 82 #include <net/if.h> 83 #include <net/if_types.h> 84 #include <net/net_stats.h> 85 86 #include <netinet/in.h> 87 #include <netinet/in_var.h> 88 #include <netinet/ip6.h> 89 #include <netinet6/ip6_var.h> 90 #include <netinet6/ip6_private.h> 91 #include <netinet6/ip6_mroute.h> 92 #include <netinet/icmp6.h> 93 #include <netinet6/icmp6_private.h> 94 #include <netinet6/in6_pcb.h> 95 #include <netinet6/nd6.h> 96 #include <netinet6/ip6protosw.h> 97 #include <netinet6/scope6_var.h> 98 #include <netinet6/raw_ip6.h> 99 100 #ifdef IPSEC 101 #include <netipsec/ipsec.h> 102 #include <netipsec/ipsec_var.h> 103 #include <netipsec/ipsec_private.h> 104 #include <netipsec/ipsec6.h> 105 #endif 106 107 #include "faith.h" 108 #if defined(NFAITH) && 0 < NFAITH 109 #include <net/if_faith.h> 110 #endif 111 112 extern struct inpcbtable rawcbtable; 113 struct inpcbtable raw6cbtable; 114 #define ifatoia6(ifa) ((struct in6_ifaddr *)(ifa)) 115 116 /* 117 * Raw interface to IP6 protocol. 118 */ 119 120 static percpu_t *rip6stat_percpu; 121 122 #define RIP6_STATINC(x) _NET_STATINC(rip6stat_percpu, x) 123 124 static void sysctl_net_inet6_raw6_setup(struct sysctllog **); 125 126 /* 127 * Initialize raw connection block queue. 128 */ 129 void 130 rip6_init(void) 131 { 132 133 sysctl_net_inet6_raw6_setup(NULL); 134 in6_pcbinit(&raw6cbtable, 1, 1); 135 136 rip6stat_percpu = percpu_alloc(sizeof(uint64_t) * RIP6_NSTATS); 137 } 138 139 /* 140 * Setup generic address and protocol structures 141 * for raw_input routine, then pass them along with 142 * mbuf chain. 143 */ 144 int 145 rip6_input(struct mbuf **mp, int *offp, int proto) 146 { 147 struct mbuf *m = *mp; 148 struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *); 149 struct inpcb_hdr *inph; 150 struct in6pcb *in6p; 151 struct in6pcb *last = NULL; 152 struct sockaddr_in6 rip6src; 153 struct mbuf *opts = NULL; 154 155 RIP6_STATINC(RIP6_STAT_IPACKETS); 156 157 #if defined(NFAITH) && 0 < NFAITH 158 if (faithprefix(&ip6->ip6_dst)) { 159 /* send icmp6 host unreach? */ 160 m_freem(m); 161 return IPPROTO_DONE; 162 } 163 #endif 164 165 /* Be proactive about malicious use of IPv4 mapped address */ 166 if (IN6_IS_ADDR_V4MAPPED(&ip6->ip6_src) || 167 IN6_IS_ADDR_V4MAPPED(&ip6->ip6_dst)) { 168 /* XXX stat */ 169 m_freem(m); 170 return IPPROTO_DONE; 171 } 172 173 sockaddr_in6_init(&rip6src, &ip6->ip6_src, 0, 0, 0); 174 if (sa6_recoverscope(&rip6src) != 0) { 175 /* XXX: should be impossible. */ 176 m_freem(m); 177 return IPPROTO_DONE; 178 } 179 180 TAILQ_FOREACH(inph, &raw6cbtable.inpt_queue, inph_queue) { 181 in6p = (struct in6pcb *)inph; 182 if (in6p->in6p_af != AF_INET6) 183 continue; 184 if (in6p->in6p_ip6.ip6_nxt && 185 in6p->in6p_ip6.ip6_nxt != proto) 186 continue; 187 if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_laddr) && 188 !IN6_ARE_ADDR_EQUAL(&in6p->in6p_laddr, &ip6->ip6_dst)) 189 continue; 190 if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_faddr) && 191 !IN6_ARE_ADDR_EQUAL(&in6p->in6p_faddr, &ip6->ip6_src)) 192 continue; 193 if (in6p->in6p_cksum != -1) { 194 RIP6_STATINC(RIP6_STAT_ISUM); 195 if (in6_cksum(m, proto, *offp, 196 m->m_pkthdr.len - *offp)) { 197 RIP6_STATINC(RIP6_STAT_BADSUM); 198 continue; 199 } 200 } 201 if (last) { 202 struct mbuf *n; 203 204 #ifdef IPSEC 205 /* 206 * Check AH/ESP integrity 207 */ 208 if (ipsec_used && !ipsec6_in_reject(m, last)) 209 #endif /* IPSEC */ 210 if ((n = m_copy(m, 0, (int)M_COPYALL)) != NULL) { 211 if (last->in6p_flags & IN6P_CONTROLOPTS) 212 ip6_savecontrol(last, &opts, ip6, n); 213 /* strip intermediate headers */ 214 m_adj(n, *offp); 215 if (sbappendaddr(&last->in6p_socket->so_rcv, 216 sin6tosa(&rip6src), n, opts) == 0) { 217 /* should notify about lost packet */ 218 m_freem(n); 219 if (opts) 220 m_freem(opts); 221 RIP6_STATINC(RIP6_STAT_FULLSOCK); 222 } else 223 sorwakeup(last->in6p_socket); 224 opts = NULL; 225 } 226 } 227 last = in6p; 228 } 229 #ifdef IPSEC 230 if (ipsec_used && last && ipsec6_in_reject(m, last)) { 231 m_freem(m); 232 /* 233 * XXX ipsec6_in_reject update stat if there is an error 234 * so we just need to update stats by hand in the case of last is 235 * NULL 236 */ 237 if (!last) 238 IPSEC6_STATINC(IPSEC_STAT_IN_POLVIO); 239 IP6_STATDEC(IP6_STAT_DELIVERED); 240 /* do not inject data into pcb */ 241 } else 242 #endif /* IPSEC */ 243 if (last) { 244 if (last->in6p_flags & IN6P_CONTROLOPTS) 245 ip6_savecontrol(last, &opts, ip6, m); 246 /* strip intermediate headers */ 247 m_adj(m, *offp); 248 if (sbappendaddr(&last->in6p_socket->so_rcv, 249 sin6tosa(&rip6src), m, opts) == 0) { 250 m_freem(m); 251 if (opts) 252 m_freem(opts); 253 RIP6_STATINC(RIP6_STAT_FULLSOCK); 254 } else 255 sorwakeup(last->in6p_socket); 256 } else { 257 RIP6_STATINC(RIP6_STAT_NOSOCK); 258 if (m->m_flags & M_MCAST) 259 RIP6_STATINC(RIP6_STAT_NOSOCKMCAST); 260 if (proto == IPPROTO_NONE) 261 m_freem(m); 262 else { 263 int s; 264 struct ifnet *rcvif = m_get_rcvif(m, &s); 265 u_int8_t *prvnxtp = ip6_get_prevhdr(m, *offp); /* XXX */ 266 in6_ifstat_inc(rcvif, ifs6_in_protounknown); 267 m_put_rcvif(rcvif, &s); 268 icmp6_error(m, ICMP6_PARAM_PROB, 269 ICMP6_PARAMPROB_NEXTHEADER, 270 prvnxtp - mtod(m, u_int8_t *)); 271 } 272 IP6_STATDEC(IP6_STAT_DELIVERED); 273 } 274 return IPPROTO_DONE; 275 } 276 277 void * 278 rip6_ctlinput(int cmd, const struct sockaddr *sa, void *d) 279 { 280 struct ip6_hdr *ip6; 281 struct ip6ctlparam *ip6cp = NULL; 282 const struct sockaddr_in6 *sa6_src = NULL; 283 void *cmdarg; 284 void (*notify)(struct in6pcb *, int) = in6_rtchange; 285 int nxt; 286 287 if (sa->sa_family != AF_INET6 || 288 sa->sa_len != sizeof(struct sockaddr_in6)) 289 return NULL; 290 291 if ((unsigned)cmd >= PRC_NCMDS) 292 return NULL; 293 if (PRC_IS_REDIRECT(cmd)) 294 notify = in6_rtchange, d = NULL; 295 else if (cmd == PRC_HOSTDEAD) 296 d = NULL; 297 else if (cmd == PRC_MSGSIZE) 298 ; /* special code is present, see below */ 299 else if (inet6ctlerrmap[cmd] == 0) 300 return NULL; 301 302 /* if the parameter is from icmp6, decode it. */ 303 if (d != NULL) { 304 ip6cp = (struct ip6ctlparam *)d; 305 ip6 = ip6cp->ip6c_ip6; 306 cmdarg = ip6cp->ip6c_cmdarg; 307 sa6_src = ip6cp->ip6c_src; 308 nxt = ip6cp->ip6c_nxt; 309 } else { 310 ip6 = NULL; 311 cmdarg = NULL; 312 sa6_src = &sa6_any; 313 nxt = -1; 314 } 315 316 if (ip6 && cmd == PRC_MSGSIZE) { 317 const struct sockaddr_in6 *sa6 = (const struct sockaddr_in6 *)sa; 318 int valid = 0; 319 struct in6pcb *in6p; 320 321 /* 322 * Check to see if we have a valid raw IPv6 socket 323 * corresponding to the address in the ICMPv6 message 324 * payload, and the protocol (ip6_nxt) meets the socket. 325 * XXX chase extension headers, or pass final nxt value 326 * from icmp6_notify_error() 327 */ 328 in6p = NULL; 329 in6p = in6_pcblookup_connect(&raw6cbtable, &sa6->sin6_addr, 0, 330 (const struct in6_addr *)&sa6_src->sin6_addr, 0, 0, 0); 331 #if 0 332 if (!in6p) { 333 /* 334 * As the use of sendto(2) is fairly popular, 335 * we may want to allow non-connected pcb too. 336 * But it could be too weak against attacks... 337 * We should at least check if the local 338 * address (= s) is really ours. 339 */ 340 in6p = in6_pcblookup_bind(&raw6cbtable, 341 &sa6->sin6_addr, 0, 0); 342 } 343 #endif 344 345 if (in6p && in6p->in6p_ip6.ip6_nxt && 346 in6p->in6p_ip6.ip6_nxt == nxt) 347 valid++; 348 349 /* 350 * Depending on the value of "valid" and routing table 351 * size (mtudisc_{hi,lo}wat), we will: 352 * - recalculate the new MTU and create the 353 * corresponding routing entry, or 354 * - ignore the MTU change notification. 355 */ 356 icmp6_mtudisc_update((struct ip6ctlparam *)d, valid); 357 358 /* 359 * regardless of if we called icmp6_mtudisc_update(), 360 * we need to call in6_pcbnotify(), to notify path MTU 361 * change to the userland (RFC3542), because some 362 * unconnected sockets may share the same destination 363 * and want to know the path MTU. 364 */ 365 } 366 367 (void) in6_pcbnotify(&raw6cbtable, sa, 0, 368 sin6tocsa(sa6_src), 0, cmd, cmdarg, notify); 369 return NULL; 370 } 371 372 /* 373 * Generate IPv6 header and pass packet to ip6_output. 374 * Tack on options user may have setup with control call. 375 */ 376 int 377 rip6_output(struct mbuf *m, struct socket * const so, 378 struct sockaddr_in6 * const dstsock, struct mbuf * const control) 379 { 380 struct in6_addr *dst; 381 struct ip6_hdr *ip6; 382 struct in6pcb *in6p; 383 u_int plen = m->m_pkthdr.len; 384 int error = 0; 385 struct ip6_pktopts opt, *optp = NULL; 386 struct ifnet *oifp = NULL; 387 int type, code; /* for ICMPv6 output statistics only */ 388 int scope_ambiguous = 0; 389 struct in6_addr *in6a; 390 int bound = curlwp_bind(); 391 struct psref psref; 392 393 in6p = sotoin6pcb(so); 394 395 dst = &dstsock->sin6_addr; 396 if (control) { 397 if ((error = ip6_setpktopts(control, &opt, 398 in6p->in6p_outputopts, 399 kauth_cred_get(), so->so_proto->pr_protocol)) != 0) { 400 goto bad; 401 } 402 optp = &opt; 403 } else 404 optp = in6p->in6p_outputopts; 405 406 /* 407 * Check and convert scope zone ID into internal form. 408 * XXX: we may still need to determine the zone later. 409 */ 410 if (!(so->so_state & SS_ISCONNECTED)) { 411 if (dstsock->sin6_scope_id == 0 && !ip6_use_defzone) 412 scope_ambiguous = 1; 413 if ((error = sa6_embedscope(dstsock, ip6_use_defzone)) != 0) 414 goto bad; 415 } 416 417 /* 418 * For an ICMPv6 packet, we should know its type and code 419 * to update statistics. 420 */ 421 if (so->so_proto->pr_protocol == IPPROTO_ICMPV6) { 422 struct icmp6_hdr *icmp6; 423 if (m->m_len < sizeof(struct icmp6_hdr) && 424 (m = m_pullup(m, sizeof(struct icmp6_hdr))) == NULL) { 425 error = ENOBUFS; 426 goto bad; 427 } 428 icmp6 = mtod(m, struct icmp6_hdr *); 429 type = icmp6->icmp6_type; 430 code = icmp6->icmp6_code; 431 } else { 432 type = 0; 433 code = 0; 434 } 435 436 M_PREPEND(m, sizeof(*ip6), M_DONTWAIT); 437 if (!m) { 438 error = ENOBUFS; 439 goto bad; 440 } 441 ip6 = mtod(m, struct ip6_hdr *); 442 443 /* 444 * Next header might not be ICMP6 but use its pseudo header anyway. 445 */ 446 ip6->ip6_dst = *dst; 447 448 /* 449 * Source address selection. 450 */ 451 if ((in6a = in6_selectsrc(dstsock, optp, in6p->in6p_moptions, 452 &in6p->in6p_route, &in6p->in6p_laddr, &oifp, &psref, &error)) == 0) { 453 if (error == 0) 454 error = EADDRNOTAVAIL; 455 goto bad; 456 } 457 ip6->ip6_src = *in6a; 458 459 if (oifp && scope_ambiguous) { 460 /* 461 * Application should provide a proper zone ID or the use of 462 * default zone IDs should be enabled. Unfortunately, some 463 * applications do not behave as it should, so we need a 464 * workaround. Even if an appropriate ID is not determined 465 * (when it's required), if we can determine the outgoing 466 * interface. determine the zone ID based on the interface. 467 */ 468 error = in6_setscope(&dstsock->sin6_addr, oifp, NULL); 469 if (error != 0) 470 goto bad; 471 } 472 ip6->ip6_dst = dstsock->sin6_addr; 473 474 /* fill in the rest of the IPv6 header fields */ 475 ip6->ip6_flow = in6p->in6p_flowinfo & IPV6_FLOWINFO_MASK; 476 ip6->ip6_vfc &= ~IPV6_VERSION_MASK; 477 ip6->ip6_vfc |= IPV6_VERSION; 478 /* ip6_plen will be filled in ip6_output, so not fill it here. */ 479 ip6->ip6_nxt = in6p->in6p_ip6.ip6_nxt; 480 ip6->ip6_hlim = in6_selecthlim(in6p, oifp); 481 482 if_put(oifp, &psref); 483 oifp = NULL; 484 485 if (so->so_proto->pr_protocol == IPPROTO_ICMPV6 || 486 in6p->in6p_cksum != -1) { 487 int off; 488 u_int16_t sum; 489 490 /* compute checksum */ 491 if (so->so_proto->pr_protocol == IPPROTO_ICMPV6) 492 off = offsetof(struct icmp6_hdr, icmp6_cksum); 493 else 494 off = in6p->in6p_cksum; 495 if (plen < off + 1) { 496 error = EINVAL; 497 goto bad; 498 } 499 off += sizeof(struct ip6_hdr); 500 501 sum = 0; 502 m = m_copyback_cow(m, off, sizeof(sum), (void *)&sum, 503 M_DONTWAIT); 504 if (m == NULL) { 505 error = ENOBUFS; 506 goto bad; 507 } 508 sum = in6_cksum(m, ip6->ip6_nxt, sizeof(*ip6), plen); 509 m = m_copyback_cow(m, off, sizeof(sum), (void *)&sum, 510 M_DONTWAIT); 511 if (m == NULL) { 512 error = ENOBUFS; 513 goto bad; 514 } 515 } 516 517 { 518 struct ifnet *ret_oifp = NULL; 519 520 error = ip6_output(m, optp, &in6p->in6p_route, 0, 521 in6p->in6p_moptions, so, &ret_oifp); 522 if (so->so_proto->pr_protocol == IPPROTO_ICMPV6) { 523 if (ret_oifp) 524 icmp6_ifoutstat_inc(ret_oifp, type, code); 525 ICMP6_STATINC(ICMP6_STAT_OUTHIST + type); 526 } else 527 RIP6_STATINC(RIP6_STAT_OPACKETS); 528 } 529 530 goto freectl; 531 532 bad: 533 if (m) 534 m_freem(m); 535 536 freectl: 537 if (control) { 538 ip6_clearpktopts(&opt, -1); 539 m_freem(control); 540 } 541 if_put(oifp, &psref); 542 curlwp_bindx(bound); 543 return error; 544 } 545 546 /* 547 * Raw IPv6 socket option processing. 548 */ 549 int 550 rip6_ctloutput(int op, struct socket *so, struct sockopt *sopt) 551 { 552 int error = 0; 553 554 if (sopt->sopt_level == SOL_SOCKET && sopt->sopt_name == SO_NOHEADER) { 555 int optval; 556 557 /* need to fiddle w/ opt(IPPROTO_IPV6, IPV6_CHECKSUM)? */ 558 if (op == PRCO_GETOPT) { 559 optval = 1; 560 error = sockopt_set(sopt, &optval, sizeof(optval)); 561 } else if (op == PRCO_SETOPT) { 562 error = sockopt_getint(sopt, &optval); 563 if (error) 564 goto out; 565 if (optval == 0) 566 error = EINVAL; 567 } 568 569 goto out; 570 } else if (sopt->sopt_level != IPPROTO_IPV6) 571 return ip6_ctloutput(op, so, sopt); 572 573 switch (sopt->sopt_name) { 574 case MRT6_INIT: 575 case MRT6_DONE: 576 case MRT6_ADD_MIF: 577 case MRT6_DEL_MIF: 578 case MRT6_ADD_MFC: 579 case MRT6_DEL_MFC: 580 case MRT6_PIM: 581 if (op == PRCO_SETOPT) 582 error = ip6_mrouter_set(so, sopt); 583 else if (op == PRCO_GETOPT) 584 error = ip6_mrouter_get(so, sopt); 585 else 586 error = EINVAL; 587 break; 588 case IPV6_CHECKSUM: 589 return ip6_raw_ctloutput(op, so, sopt); 590 default: 591 return ip6_ctloutput(op, so, sopt); 592 } 593 out: 594 return error; 595 } 596 597 extern u_long rip6_sendspace; 598 extern u_long rip6_recvspace; 599 600 int 601 rip6_attach(struct socket *so, int proto) 602 { 603 struct in6pcb *in6p; 604 int s, error; 605 606 KASSERT(sotoin6pcb(so) == NULL); 607 sosetlock(so); 608 609 error = kauth_authorize_network(curlwp->l_cred, 610 KAUTH_NETWORK_SOCKET, KAUTH_REQ_NETWORK_SOCKET_RAWSOCK, 611 KAUTH_ARG(AF_INET6), 612 KAUTH_ARG(SOCK_RAW), 613 KAUTH_ARG(so->so_proto->pr_protocol)); 614 if (error) { 615 return error; 616 } 617 s = splsoftnet(); 618 error = soreserve(so, rip6_sendspace, rip6_recvspace); 619 if (error) { 620 splx(s); 621 return error; 622 } 623 if ((error = in6_pcballoc(so, &raw6cbtable)) != 0) { 624 splx(s); 625 return error; 626 } 627 splx(s); 628 in6p = sotoin6pcb(so); 629 in6p->in6p_ip6.ip6_nxt = proto; 630 in6p->in6p_cksum = -1; 631 632 in6p->in6p_icmp6filt = kmem_alloc(sizeof(struct icmp6_filter), KM_SLEEP); 633 if (in6p->in6p_icmp6filt == NULL) { 634 in6_pcbdetach(in6p); 635 return ENOMEM; 636 } 637 ICMP6_FILTER_SETPASSALL(in6p->in6p_icmp6filt); 638 KASSERT(solocked(so)); 639 return error; 640 } 641 642 static void 643 rip6_detach(struct socket *so) 644 { 645 struct in6pcb *in6p = sotoin6pcb(so); 646 647 KASSERT(solocked(so)); 648 KASSERT(in6p != NULL); 649 650 if (so == ip6_mrouter) { 651 ip6_mrouter_done(); 652 } 653 /* xxx: RSVP */ 654 if (in6p->in6p_icmp6filt != NULL) { 655 kmem_free(in6p->in6p_icmp6filt, sizeof(struct icmp6_filter)); 656 in6p->in6p_icmp6filt = NULL; 657 } 658 in6_pcbdetach(in6p); 659 } 660 661 static int 662 rip6_accept(struct socket *so, struct sockaddr *nam) 663 { 664 KASSERT(solocked(so)); 665 666 return EOPNOTSUPP; 667 } 668 669 static int 670 rip6_bind(struct socket *so, struct sockaddr *nam, struct lwp *l) 671 { 672 struct in6pcb *in6p = sotoin6pcb(so); 673 struct sockaddr_in6 *addr = (struct sockaddr_in6 *)nam; 674 struct ifaddr *ifa = NULL; 675 int error = 0; 676 int s; 677 678 KASSERT(solocked(so)); 679 KASSERT(in6p != NULL); 680 KASSERT(nam != NULL); 681 682 if (addr->sin6_len != sizeof(*addr)) 683 return EINVAL; 684 if (IFNET_READER_EMPTY() || addr->sin6_family != AF_INET6) 685 return EADDRNOTAVAIL; 686 687 if ((error = sa6_embedscope(addr, ip6_use_defzone)) != 0) 688 return error; 689 690 /* 691 * we don't support mapped address here, it would confuse 692 * users so reject it 693 */ 694 if (IN6_IS_ADDR_V4MAPPED(&addr->sin6_addr)) 695 return EADDRNOTAVAIL; 696 s = pserialize_read_enter(); 697 if (!IN6_IS_ADDR_UNSPECIFIED(&addr->sin6_addr) && 698 (ifa = ifa_ifwithaddr(sin6tosa(addr))) == NULL) { 699 error = EADDRNOTAVAIL; 700 goto out; 701 } 702 if (ifa && (ifatoia6(ifa))->ia6_flags & 703 (IN6_IFF_ANYCAST|IN6_IFF_NOTREADY| 704 IN6_IFF_DETACHED|IN6_IFF_DEPRECATED)) { 705 error = EADDRNOTAVAIL; 706 goto out; 707 } 708 709 in6p->in6p_laddr = addr->sin6_addr; 710 error = 0; 711 out: 712 pserialize_read_exit(s); 713 return error; 714 } 715 716 static int 717 rip6_listen(struct socket *so, struct lwp *l) 718 { 719 KASSERT(solocked(so)); 720 721 return EOPNOTSUPP; 722 } 723 724 static int 725 rip6_connect(struct socket *so, struct sockaddr *nam, struct lwp *l) 726 { 727 struct in6pcb *in6p = sotoin6pcb(so); 728 struct sockaddr_in6 *addr = (struct sockaddr_in6 *)nam; 729 struct in6_addr *in6a = NULL; 730 struct ifnet *ifp = NULL; 731 int scope_ambiguous = 0; 732 int error = 0; 733 struct psref psref; 734 int bound; 735 736 KASSERT(solocked(so)); 737 KASSERT(in6p != NULL); 738 KASSERT(nam != NULL); 739 740 if (IFNET_READER_EMPTY()) 741 return EADDRNOTAVAIL; 742 if (addr->sin6_family != AF_INET6) 743 return EAFNOSUPPORT; 744 745 /* 746 * Application should provide a proper zone ID or the use of 747 * default zone IDs should be enabled. Unfortunately, some 748 * applications do not behave as it should, so we need a 749 * workaround. Even if an appropriate ID is not determined, 750 * we'll see if we can determine the outgoing interface. If we 751 * can, determine the zone ID based on the interface below. 752 */ 753 if (addr->sin6_scope_id == 0 && !ip6_use_defzone) 754 scope_ambiguous = 1; 755 if ((error = sa6_embedscope(addr, ip6_use_defzone)) != 0) 756 return error; 757 758 bound = curlwp_bind(); 759 /* Source address selection. XXX: need pcblookup? */ 760 in6a = in6_selectsrc(addr, in6p->in6p_outputopts, 761 in6p->in6p_moptions, &in6p->in6p_route, 762 &in6p->in6p_laddr, &ifp, &psref, &error); 763 if (in6a == NULL) { 764 if (error == 0) 765 error = EADDRNOTAVAIL; 766 goto out; 767 } 768 /* XXX: see above */ 769 if (ifp && scope_ambiguous && 770 (error = in6_setscope(&addr->sin6_addr, ifp, NULL)) != 0) { 771 goto out; 772 } 773 in6p->in6p_laddr = *in6a; 774 in6p->in6p_faddr = addr->sin6_addr; 775 soisconnected(so); 776 out: 777 if_put(ifp, &psref); 778 curlwp_bindx(bound); 779 return error; 780 } 781 782 static int 783 rip6_connect2(struct socket *so, struct socket *so2) 784 { 785 KASSERT(solocked(so)); 786 787 return EOPNOTSUPP; 788 } 789 790 static int 791 rip6_disconnect(struct socket *so) 792 { 793 struct in6pcb *in6p = sotoin6pcb(so); 794 795 KASSERT(solocked(so)); 796 KASSERT(in6p != NULL); 797 798 if ((so->so_state & SS_ISCONNECTED) == 0) 799 return ENOTCONN; 800 801 in6p->in6p_faddr = in6addr_any; 802 so->so_state &= ~SS_ISCONNECTED; /* XXX */ 803 return 0; 804 } 805 806 static int 807 rip6_shutdown(struct socket *so) 808 { 809 KASSERT(solocked(so)); 810 811 /* 812 * Mark the connection as being incapable of futther input. 813 */ 814 socantsendmore(so); 815 return 0; 816 } 817 818 static int 819 rip6_abort(struct socket *so) 820 { 821 KASSERT(solocked(so)); 822 823 soisdisconnected(so); 824 rip6_detach(so); 825 return 0; 826 } 827 828 static int 829 rip6_ioctl(struct socket *so, u_long cmd, void *nam, struct ifnet *ifp) 830 { 831 return in6_control(so, cmd, nam, ifp); 832 } 833 834 static int 835 rip6_stat(struct socket *so, struct stat *ub) 836 { 837 KASSERT(solocked(so)); 838 839 /* stat: don't bother with a blocksize */ 840 return 0; 841 } 842 843 static int 844 rip6_peeraddr(struct socket *so, struct sockaddr *nam) 845 { 846 KASSERT(solocked(so)); 847 KASSERT(sotoin6pcb(so) != NULL); 848 KASSERT(nam != NULL); 849 850 in6_setpeeraddr(sotoin6pcb(so), (struct sockaddr_in6 *)nam); 851 return 0; 852 } 853 854 static int 855 rip6_sockaddr(struct socket *so, struct sockaddr *nam) 856 { 857 KASSERT(solocked(so)); 858 KASSERT(sotoin6pcb(so) != NULL); 859 KASSERT(nam != NULL); 860 861 in6_setsockaddr(sotoin6pcb(so), (struct sockaddr_in6 *)nam); 862 return 0; 863 } 864 865 static int 866 rip6_rcvd(struct socket *so, int flags, struct lwp *l) 867 { 868 KASSERT(solocked(so)); 869 870 return EOPNOTSUPP; 871 } 872 873 static int 874 rip6_recvoob(struct socket *so, struct mbuf *m, int flags) 875 { 876 KASSERT(solocked(so)); 877 878 return EOPNOTSUPP; 879 } 880 881 static int 882 rip6_send(struct socket *so, struct mbuf *m, struct sockaddr *nam, 883 struct mbuf *control, struct lwp *l) 884 { 885 struct in6pcb *in6p = sotoin6pcb(so); 886 struct sockaddr_in6 tmp; 887 struct sockaddr_in6 *dst; 888 int error = 0; 889 890 KASSERT(solocked(so)); 891 KASSERT(in6p != NULL); 892 KASSERT(m != NULL); 893 894 /* 895 * Ship a packet out. The appropriate raw output 896 * routine handles any messaging necessary. 897 */ 898 899 /* always copy sockaddr to avoid overwrites */ 900 if (so->so_state & SS_ISCONNECTED) { 901 if (nam) { 902 error = EISCONN; 903 goto release; 904 } 905 /* XXX */ 906 sockaddr_in6_init(&tmp, &in6p->in6p_faddr, 0, 0, 0); 907 dst = &tmp; 908 } else { 909 if (nam == NULL) { 910 error = ENOTCONN; 911 goto release; 912 } 913 tmp = *(struct sockaddr_in6 *)nam; 914 dst = &tmp; 915 916 if (dst->sin6_family != AF_INET6) { 917 error = EAFNOSUPPORT; 918 goto release; 919 } 920 } 921 error = rip6_output(m, so, dst, control); 922 m = NULL; 923 924 release: 925 if (m) 926 m_freem(m); 927 928 return error; 929 } 930 931 static int 932 rip6_sendoob(struct socket *so, struct mbuf *m, struct mbuf *control) 933 { 934 KASSERT(solocked(so)); 935 936 if (m) 937 m_freem(m); 938 939 return EOPNOTSUPP; 940 } 941 942 static int 943 rip6_purgeif(struct socket *so, struct ifnet *ifp) 944 { 945 946 mutex_enter(softnet_lock); 947 in6_pcbpurgeif0(&raw6cbtable, ifp); 948 in6_purgeif(ifp); 949 in6_pcbpurgeif(&raw6cbtable, ifp); 950 mutex_exit(softnet_lock); 951 952 return 0; 953 } 954 955 static int 956 sysctl_net_inet6_raw6_stats(SYSCTLFN_ARGS) 957 { 958 959 return (NETSTAT_SYSCTL(rip6stat_percpu, RIP6_NSTATS)); 960 } 961 962 static void 963 sysctl_net_inet6_raw6_setup(struct sysctllog **clog) 964 { 965 966 sysctl_createv(clog, 0, NULL, NULL, 967 CTLFLAG_PERMANENT, 968 CTLTYPE_NODE, "inet6", NULL, 969 NULL, 0, NULL, 0, 970 CTL_NET, PF_INET6, CTL_EOL); 971 sysctl_createv(clog, 0, NULL, NULL, 972 CTLFLAG_PERMANENT, 973 CTLTYPE_NODE, "raw6", 974 SYSCTL_DESCR("Raw IPv6 settings"), 975 NULL, 0, NULL, 0, 976 CTL_NET, PF_INET6, IPPROTO_RAW, CTL_EOL); 977 978 sysctl_createv(clog, 0, NULL, NULL, 979 CTLFLAG_PERMANENT, 980 CTLTYPE_STRUCT, "pcblist", 981 SYSCTL_DESCR("Raw IPv6 control block list"), 982 sysctl_inpcblist, 0, &raw6cbtable, 0, 983 CTL_NET, PF_INET6, IPPROTO_RAW, 984 CTL_CREATE, CTL_EOL); 985 sysctl_createv(clog, 0, NULL, NULL, 986 CTLFLAG_PERMANENT, 987 CTLTYPE_STRUCT, "stats", 988 SYSCTL_DESCR("Raw IPv6 statistics"), 989 sysctl_net_inet6_raw6_stats, 0, NULL, 0, 990 CTL_NET, PF_INET6, IPPROTO_RAW, RAW6CTL_STATS, 991 CTL_EOL); 992 } 993 994 PR_WRAP_USRREQS(rip6) 995 #define rip6_attach rip6_attach_wrapper 996 #define rip6_detach rip6_detach_wrapper 997 #define rip6_accept rip6_accept_wrapper 998 #define rip6_bind rip6_bind_wrapper 999 #define rip6_listen rip6_listen_wrapper 1000 #define rip6_connect rip6_connect_wrapper 1001 #define rip6_connect2 rip6_connect2_wrapper 1002 #define rip6_disconnect rip6_disconnect_wrapper 1003 #define rip6_shutdown rip6_shutdown_wrapper 1004 #define rip6_abort rip6_abort_wrapper 1005 #define rip6_ioctl rip6_ioctl_wrapper 1006 #define rip6_stat rip6_stat_wrapper 1007 #define rip6_peeraddr rip6_peeraddr_wrapper 1008 #define rip6_sockaddr rip6_sockaddr_wrapper 1009 #define rip6_rcvd rip6_rcvd_wrapper 1010 #define rip6_recvoob rip6_recvoob_wrapper 1011 #define rip6_send rip6_send_wrapper 1012 #define rip6_sendoob rip6_sendoob_wrapper 1013 #define rip6_purgeif rip6_purgeif_wrapper 1014 1015 const struct pr_usrreqs rip6_usrreqs = { 1016 .pr_attach = rip6_attach, 1017 .pr_detach = rip6_detach, 1018 .pr_accept = rip6_accept, 1019 .pr_bind = rip6_bind, 1020 .pr_listen = rip6_listen, 1021 .pr_connect = rip6_connect, 1022 .pr_connect2 = rip6_connect2, 1023 .pr_disconnect = rip6_disconnect, 1024 .pr_shutdown = rip6_shutdown, 1025 .pr_abort = rip6_abort, 1026 .pr_ioctl = rip6_ioctl, 1027 .pr_stat = rip6_stat, 1028 .pr_peeraddr = rip6_peeraddr, 1029 .pr_sockaddr = rip6_sockaddr, 1030 .pr_rcvd = rip6_rcvd, 1031 .pr_recvoob = rip6_recvoob, 1032 .pr_send = rip6_send, 1033 .pr_sendoob = rip6_sendoob, 1034 .pr_purgeif = rip6_purgeif, 1035 }; 1036