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