1 /* $NetBSD: raw_ip.c,v 1.147 2015/04/03 20:01:07 rtr Exp $ */ 2 3 /* 4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of the project nor the names of its contributors 16 * may be used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32 /* 33 * Copyright (c) 1982, 1986, 1988, 1993 34 * The Regents of the University of California. All rights reserved. 35 * 36 * Redistribution and use in source and binary forms, with or without 37 * modification, are permitted provided that the following conditions 38 * are met: 39 * 1. Redistributions of source code must retain the above copyright 40 * notice, this list of conditions and the following disclaimer. 41 * 2. Redistributions in binary form must reproduce the above copyright 42 * notice, this list of conditions and the following disclaimer in the 43 * documentation and/or other materials provided with the distribution. 44 * 3. Neither the name of the University nor the names of its contributors 45 * may be used to endorse or promote products derived from this software 46 * without specific prior written permission. 47 * 48 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 51 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 58 * SUCH DAMAGE. 59 * 60 * @(#)raw_ip.c 8.7 (Berkeley) 5/15/95 61 */ 62 63 /* 64 * Raw interface to IP protocol. 65 */ 66 67 #include <sys/cdefs.h> 68 __KERNEL_RCSID(0, "$NetBSD: raw_ip.c,v 1.147 2015/04/03 20:01:07 rtr Exp $"); 69 70 #include "opt_inet.h" 71 #include "opt_compat_netbsd.h" 72 #include "opt_ipsec.h" 73 #include "opt_mrouting.h" 74 75 #include <sys/param.h> 76 #include <sys/sysctl.h> 77 #include <sys/mbuf.h> 78 #include <sys/socket.h> 79 #include <sys/protosw.h> 80 #include <sys/socketvar.h> 81 #include <sys/errno.h> 82 #include <sys/systm.h> 83 #include <sys/proc.h> 84 #include <sys/kauth.h> 85 86 #include <net/if.h> 87 #include <net/route.h> 88 89 #include <netinet/in.h> 90 #include <netinet/in_systm.h> 91 #include <netinet/ip.h> 92 #include <netinet/ip_var.h> 93 #include <netinet/ip_private.h> 94 #include <netinet/ip_mroute.h> 95 #include <netinet/ip_icmp.h> 96 #include <netinet/in_pcb.h> 97 #include <netinet/in_proto.h> 98 #include <netinet/in_var.h> 99 100 #ifdef IPSEC 101 #include <netipsec/ipsec.h> 102 #include <netipsec/ipsec_var.h> 103 #include <netipsec/ipsec_private.h> 104 #endif /* IPSEC */ 105 106 #ifdef COMPAT_50 107 #include <compat/sys/socket.h> 108 #endif 109 110 struct inpcbtable rawcbtable; 111 112 int rip_pcbnotify(struct inpcbtable *, struct in_addr, 113 struct in_addr, int, int, void (*)(struct inpcb *, int)); 114 int rip_connect_pcb(struct inpcb *, struct mbuf *); 115 static void rip_disconnect1(struct inpcb *); 116 117 static void sysctl_net_inet_raw_setup(struct sysctllog **); 118 119 /* 120 * Nominal space allocated to a raw ip socket. 121 */ 122 #define RIPSNDQ 8192 123 #define RIPRCVQ 8192 124 125 static u_long rip_sendspace = RIPSNDQ; 126 static u_long rip_recvspace = RIPRCVQ; 127 128 /* 129 * Raw interface to IP protocol. 130 */ 131 132 /* 133 * Initialize raw connection block q. 134 */ 135 void 136 rip_init(void) 137 { 138 139 sysctl_net_inet_raw_setup(NULL); 140 in_pcbinit(&rawcbtable, 1, 1); 141 } 142 143 static void 144 rip_sbappendaddr(struct inpcb *last, struct ip *ip, const struct sockaddr *sa, 145 int hlen, struct mbuf *opts, struct mbuf *n) 146 { 147 if (last->inp_flags & INP_NOHEADER) 148 m_adj(n, hlen); 149 if (last->inp_flags & INP_CONTROLOPTS 150 #ifdef SO_OTIMESTAMP 151 || last->inp_socket->so_options & SO_OTIMESTAMP 152 #endif 153 || last->inp_socket->so_options & SO_TIMESTAMP) 154 ip_savecontrol(last, &opts, ip, n); 155 if (sbappendaddr(&last->inp_socket->so_rcv, sa, n, opts) == 0) { 156 /* should notify about lost packet */ 157 m_freem(n); 158 if (opts) 159 m_freem(opts); 160 } else 161 sorwakeup(last->inp_socket); 162 } 163 164 /* 165 * Setup generic address and protocol structures 166 * for raw_input routine, then pass them along with 167 * mbuf chain. 168 */ 169 void 170 rip_input(struct mbuf *m, ...) 171 { 172 int hlen, proto; 173 struct ip *ip = mtod(m, struct ip *); 174 struct inpcb_hdr *inph; 175 struct inpcb *inp; 176 struct inpcb *last = NULL; 177 struct mbuf *n, *opts = NULL; 178 struct sockaddr_in ripsrc; 179 va_list ap; 180 181 va_start(ap, m); 182 (void)va_arg(ap, int); /* ignore value, advance ap */ 183 proto = va_arg(ap, int); 184 va_end(ap); 185 186 sockaddr_in_init(&ripsrc, &ip->ip_src, 0); 187 188 /* 189 * XXX Compatibility: programs using raw IP expect ip_len 190 * XXX to have the header length subtracted, and in host order. 191 * XXX ip_off is also expected to be host order. 192 */ 193 hlen = ip->ip_hl << 2; 194 ip->ip_len = ntohs(ip->ip_len) - hlen; 195 NTOHS(ip->ip_off); 196 197 TAILQ_FOREACH(inph, &rawcbtable.inpt_queue, inph_queue) { 198 inp = (struct inpcb *)inph; 199 if (inp->inp_af != AF_INET) 200 continue; 201 if (inp->inp_ip.ip_p && inp->inp_ip.ip_p != proto) 202 continue; 203 if (!in_nullhost(inp->inp_laddr) && 204 !in_hosteq(inp->inp_laddr, ip->ip_dst)) 205 continue; 206 if (!in_nullhost(inp->inp_faddr) && 207 !in_hosteq(inp->inp_faddr, ip->ip_src)) 208 continue; 209 if (last == NULL) 210 ; 211 #if defined(IPSEC) 212 /* check AH/ESP integrity. */ 213 else if (ipsec_used && 214 ipsec4_in_reject_so(m, last->inp_socket)) { 215 IPSEC_STATINC(IPSEC_STAT_IN_POLVIO); 216 /* do not inject data to pcb */ 217 } 218 #endif /*IPSEC*/ 219 else if ((n = m_copypacket(m, M_DONTWAIT)) != NULL) { 220 rip_sbappendaddr(last, ip, sintosa(&ripsrc), hlen, opts, 221 n); 222 opts = NULL; 223 } 224 last = inp; 225 } 226 #if defined(IPSEC) 227 /* check AH/ESP integrity. */ 228 if (ipsec_used && last != NULL 229 && ipsec4_in_reject_so(m, last->inp_socket)) { 230 m_freem(m); 231 IPSEC_STATINC(IPSEC_STAT_IN_POLVIO); 232 IP_STATDEC(IP_STAT_DELIVERED); 233 /* do not inject data to pcb */ 234 } else 235 #endif /*IPSEC*/ 236 if (last != NULL) 237 rip_sbappendaddr(last, ip, sintosa(&ripsrc), hlen, opts, m); 238 else if (inetsw[ip_protox[ip->ip_p]].pr_input == rip_input) { 239 uint64_t *ips; 240 241 icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_PROTOCOL, 242 0, 0); 243 ips = IP_STAT_GETREF(); 244 ips[IP_STAT_NOPROTO]++; 245 ips[IP_STAT_DELIVERED]--; 246 IP_STAT_PUTREF(); 247 } else 248 m_freem(m); 249 return; 250 } 251 252 int 253 rip_pcbnotify(struct inpcbtable *table, 254 struct in_addr faddr, struct in_addr laddr, int proto, int errno, 255 void (*notify)(struct inpcb *, int)) 256 { 257 struct inpcb_hdr *inph, *ninph; 258 int nmatch; 259 260 nmatch = 0; 261 TAILQ_FOREACH_SAFE(inph, &table->inpt_queue, inph_queue, ninph) { 262 struct inpcb *inp = (struct inpcb *)inph; 263 if (inp->inp_af != AF_INET) 264 continue; 265 if (inp->inp_ip.ip_p && inp->inp_ip.ip_p != proto) 266 continue; 267 if (in_hosteq(inp->inp_faddr, faddr) && 268 in_hosteq(inp->inp_laddr, laddr)) { 269 (*notify)(inp, errno); 270 nmatch++; 271 } 272 } 273 274 return nmatch; 275 } 276 277 void * 278 rip_ctlinput(int cmd, const struct sockaddr *sa, void *v) 279 { 280 struct ip *ip = v; 281 void (*notify)(struct inpcb *, int) = in_rtchange; 282 int errno; 283 284 if (sa->sa_family != AF_INET || 285 sa->sa_len != sizeof(struct sockaddr_in)) 286 return NULL; 287 if ((unsigned)cmd >= PRC_NCMDS) 288 return NULL; 289 errno = inetctlerrmap[cmd]; 290 if (PRC_IS_REDIRECT(cmd)) 291 notify = in_rtchange, ip = 0; 292 else if (cmd == PRC_HOSTDEAD) 293 ip = 0; 294 else if (errno == 0) 295 return NULL; 296 if (ip) { 297 rip_pcbnotify(&rawcbtable, satocsin(sa)->sin_addr, 298 ip->ip_src, ip->ip_p, errno, notify); 299 300 /* XXX mapped address case */ 301 } else 302 in_pcbnotifyall(&rawcbtable, satocsin(sa)->sin_addr, errno, 303 notify); 304 return NULL; 305 } 306 307 /* 308 * Generate IP header and pass packet to ip_output. 309 * Tack on options user may have setup with control call. 310 */ 311 int 312 rip_output(struct mbuf *m, ...) 313 { 314 struct inpcb *inp; 315 struct ip *ip; 316 struct mbuf *opts; 317 int flags; 318 va_list ap; 319 320 va_start(ap, m); 321 inp = va_arg(ap, struct inpcb *); 322 va_end(ap); 323 324 flags = 325 (inp->inp_socket->so_options & SO_DONTROUTE) | IP_ALLOWBROADCAST 326 | IP_RETURNMTU; 327 328 /* 329 * If the user handed us a complete IP packet, use it. 330 * Otherwise, allocate an mbuf for a header and fill it in. 331 */ 332 if ((inp->inp_flags & INP_HDRINCL) == 0) { 333 if ((m->m_pkthdr.len + sizeof(struct ip)) > IP_MAXPACKET) { 334 m_freem(m); 335 return (EMSGSIZE); 336 } 337 M_PREPEND(m, sizeof(struct ip), M_DONTWAIT); 338 if (!m) 339 return (ENOBUFS); 340 ip = mtod(m, struct ip *); 341 ip->ip_tos = 0; 342 ip->ip_off = htons(0); 343 ip->ip_p = inp->inp_ip.ip_p; 344 ip->ip_len = htons(m->m_pkthdr.len); 345 ip->ip_src = inp->inp_laddr; 346 ip->ip_dst = inp->inp_faddr; 347 ip->ip_ttl = MAXTTL; 348 opts = inp->inp_options; 349 } else { 350 if (m->m_pkthdr.len > IP_MAXPACKET) { 351 m_freem(m); 352 return (EMSGSIZE); 353 } 354 ip = mtod(m, struct ip *); 355 356 /* 357 * If the mbuf is read-only, we need to allocate 358 * a new mbuf for the header, since we need to 359 * modify the header. 360 */ 361 if (M_READONLY(m)) { 362 int hlen = ip->ip_hl << 2; 363 364 m = m_copyup(m, hlen, (max_linkhdr + 3) & ~3); 365 if (m == NULL) 366 return (ENOMEM); /* XXX */ 367 ip = mtod(m, struct ip *); 368 } 369 370 /* XXX userland passes ip_len and ip_off in host order */ 371 if (m->m_pkthdr.len != ip->ip_len) { 372 m_freem(m); 373 return (EINVAL); 374 } 375 HTONS(ip->ip_len); 376 HTONS(ip->ip_off); 377 if (ip->ip_id != 0 || m->m_pkthdr.len < IP_MINFRAGSIZE) 378 flags |= IP_NOIPNEWID; 379 opts = NULL; 380 /* XXX prevent ip_output from overwriting header fields */ 381 flags |= IP_RAWOUTPUT; 382 IP_STATINC(IP_STAT_RAWOUT); 383 } 384 385 /* 386 * IP output. Note: if IP_RETURNMTU flag is set, the MTU size 387 * will be stored in inp_errormtu. 388 */ 389 return ip_output(m, opts, &inp->inp_route, flags, inp->inp_moptions, 390 inp->inp_socket); 391 } 392 393 /* 394 * Raw IP socket option processing. 395 */ 396 int 397 rip_ctloutput(int op, struct socket *so, struct sockopt *sopt) 398 { 399 struct inpcb *inp = sotoinpcb(so); 400 int error = 0; 401 int optval; 402 403 if (sopt->sopt_level == SOL_SOCKET && sopt->sopt_name == SO_NOHEADER) { 404 if (op == PRCO_GETOPT) { 405 optval = (inp->inp_flags & INP_NOHEADER) ? 1 : 0; 406 error = sockopt_set(sopt, &optval, sizeof(optval)); 407 } else if (op == PRCO_SETOPT) { 408 error = sockopt_getint(sopt, &optval); 409 if (error) 410 goto out; 411 if (optval) { 412 inp->inp_flags &= ~INP_HDRINCL; 413 inp->inp_flags |= INP_NOHEADER; 414 } else 415 inp->inp_flags &= ~INP_NOHEADER; 416 } 417 goto out; 418 } else if (sopt->sopt_level != IPPROTO_IP) 419 return ip_ctloutput(op, so, sopt); 420 421 switch (op) { 422 423 case PRCO_SETOPT: 424 switch (sopt->sopt_name) { 425 case IP_HDRINCL: 426 error = sockopt_getint(sopt, &optval); 427 if (error) 428 break; 429 if (optval) 430 inp->inp_flags |= INP_HDRINCL; 431 else 432 inp->inp_flags &= ~INP_HDRINCL; 433 break; 434 435 #ifdef MROUTING 436 case MRT_INIT: 437 case MRT_DONE: 438 case MRT_ADD_VIF: 439 case MRT_DEL_VIF: 440 case MRT_ADD_MFC: 441 case MRT_DEL_MFC: 442 case MRT_ASSERT: 443 case MRT_API_CONFIG: 444 case MRT_ADD_BW_UPCALL: 445 case MRT_DEL_BW_UPCALL: 446 error = ip_mrouter_set(so, sopt); 447 break; 448 #endif 449 450 default: 451 error = ip_ctloutput(op, so, sopt); 452 break; 453 } 454 break; 455 456 case PRCO_GETOPT: 457 switch (sopt->sopt_name) { 458 case IP_HDRINCL: 459 optval = inp->inp_flags & INP_HDRINCL; 460 error = sockopt_set(sopt, &optval, sizeof(optval)); 461 break; 462 463 #ifdef MROUTING 464 case MRT_VERSION: 465 case MRT_ASSERT: 466 case MRT_API_SUPPORT: 467 case MRT_API_CONFIG: 468 error = ip_mrouter_get(so, sopt); 469 break; 470 #endif 471 472 default: 473 error = ip_ctloutput(op, so, sopt); 474 break; 475 } 476 break; 477 } 478 out: 479 return error; 480 } 481 482 int 483 rip_connect_pcb(struct inpcb *inp, struct mbuf *nam) 484 { 485 struct sockaddr_in *addr = mtod(nam, struct sockaddr_in *); 486 487 if (nam->m_len != sizeof(*addr)) 488 return (EINVAL); 489 if (IFNET_EMPTY()) 490 return (EADDRNOTAVAIL); 491 if (addr->sin_family != AF_INET) 492 return (EAFNOSUPPORT); 493 inp->inp_faddr = addr->sin_addr; 494 return (0); 495 } 496 497 static void 498 rip_disconnect1(struct inpcb *inp) 499 { 500 501 inp->inp_faddr = zeroin_addr; 502 } 503 504 static int 505 rip_attach(struct socket *so, int proto) 506 { 507 struct inpcb *inp; 508 int error; 509 510 KASSERT(sotoinpcb(so) == NULL); 511 sosetlock(so); 512 513 if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) { 514 error = soreserve(so, rip_sendspace, rip_recvspace); 515 if (error) { 516 return error; 517 } 518 } 519 520 error = in_pcballoc(so, &rawcbtable); 521 if (error) { 522 return error; 523 } 524 inp = sotoinpcb(so); 525 inp->inp_ip.ip_p = proto; 526 KASSERT(solocked(so)); 527 528 return 0; 529 } 530 531 static void 532 rip_detach(struct socket *so) 533 { 534 struct inpcb *inp; 535 536 KASSERT(solocked(so)); 537 inp = sotoinpcb(so); 538 KASSERT(inp != NULL); 539 540 #ifdef MROUTING 541 extern struct socket *ip_mrouter; 542 if (so == ip_mrouter) { 543 ip_mrouter_done(); 544 } 545 #endif 546 in_pcbdetach(inp); 547 } 548 549 static int 550 rip_accept(struct socket *so, struct mbuf *nam) 551 { 552 KASSERT(solocked(so)); 553 554 panic("rip_accept"); 555 556 return EOPNOTSUPP; 557 } 558 559 static int 560 rip_bind(struct socket *so, struct sockaddr *nam, struct lwp *l) 561 { 562 struct inpcb *inp = sotoinpcb(so); 563 struct sockaddr_in *addr = (struct sockaddr_in *)nam; 564 int error = 0; 565 int s; 566 567 KASSERT(solocked(so)); 568 KASSERT(inp != NULL); 569 KASSERT(nam != NULL); 570 571 if (addr->sin_len != sizeof(*addr)) 572 return EINVAL; 573 574 s = splsoftnet(); 575 if (IFNET_EMPTY()) { 576 error = EADDRNOTAVAIL; 577 goto release; 578 } 579 if (addr->sin_family != AF_INET) { 580 error = EAFNOSUPPORT; 581 goto release; 582 } 583 if (!in_nullhost(addr->sin_addr) && 584 ifa_ifwithaddr(sintosa(addr)) == 0) { 585 error = EADDRNOTAVAIL; 586 goto release; 587 } 588 inp->inp_laddr = addr->sin_addr; 589 590 release: 591 splx(s); 592 return error; 593 } 594 595 static int 596 rip_listen(struct socket *so, struct lwp *l) 597 { 598 KASSERT(solocked(so)); 599 600 return EOPNOTSUPP; 601 } 602 603 static int 604 rip_connect(struct socket *so, struct mbuf *nam, struct lwp *l) 605 { 606 struct inpcb *inp = sotoinpcb(so); 607 int error = 0; 608 int s; 609 610 KASSERT(solocked(so)); 611 KASSERT(inp != NULL); 612 KASSERT(nam != NULL); 613 614 s = splsoftnet(); 615 error = rip_connect_pcb(inp, nam); 616 if (! error) 617 soisconnected(so); 618 splx(s); 619 620 return error; 621 } 622 623 static int 624 rip_connect2(struct socket *so, struct socket *so2) 625 { 626 KASSERT(solocked(so)); 627 628 return EOPNOTSUPP; 629 } 630 631 static int 632 rip_disconnect(struct socket *so) 633 { 634 struct inpcb *inp = sotoinpcb(so); 635 int s; 636 637 KASSERT(solocked(so)); 638 KASSERT(inp != NULL); 639 640 s = splsoftnet(); 641 soisdisconnected(so); 642 rip_disconnect1(inp); 643 splx(s); 644 645 return 0; 646 } 647 648 static int 649 rip_shutdown(struct socket *so) 650 { 651 int s; 652 653 KASSERT(solocked(so)); 654 655 /* 656 * Mark the connection as being incapable of further input. 657 */ 658 s = splsoftnet(); 659 socantsendmore(so); 660 splx(s); 661 662 return 0; 663 } 664 665 static int 666 rip_abort(struct socket *so) 667 { 668 KASSERT(solocked(so)); 669 670 panic("rip_abort"); 671 672 return EOPNOTSUPP; 673 } 674 675 static int 676 rip_ioctl(struct socket *so, u_long cmd, void *nam, struct ifnet *ifp) 677 { 678 return in_control(so, cmd, nam, ifp); 679 } 680 681 static int 682 rip_stat(struct socket *so, struct stat *ub) 683 { 684 KASSERT(solocked(so)); 685 686 /* stat: don't bother with a blocksize. */ 687 return 0; 688 } 689 690 static int 691 rip_peeraddr(struct socket *so, struct mbuf *nam) 692 { 693 int s; 694 695 KASSERT(solocked(so)); 696 KASSERT(sotoinpcb(so) != NULL); 697 KASSERT(nam != NULL); 698 699 s = splsoftnet(); 700 in_setpeeraddr(sotoinpcb(so), nam); 701 splx(s); 702 703 return 0; 704 } 705 706 static int 707 rip_sockaddr(struct socket *so, struct mbuf *nam) 708 { 709 int s; 710 711 KASSERT(solocked(so)); 712 KASSERT(sotoinpcb(so) != NULL); 713 KASSERT(nam != NULL); 714 715 s = splsoftnet(); 716 in_setsockaddr(sotoinpcb(so), nam); 717 splx(s); 718 719 return 0; 720 } 721 722 static int 723 rip_rcvd(struct socket *so, int flags, struct lwp *l) 724 { 725 KASSERT(solocked(so)); 726 727 return EOPNOTSUPP; 728 } 729 730 static int 731 rip_recvoob(struct socket *so, struct mbuf *m, int flags) 732 { 733 KASSERT(solocked(so)); 734 735 return EOPNOTSUPP; 736 } 737 738 static int 739 rip_send(struct socket *so, struct mbuf *m, struct mbuf *nam, 740 struct mbuf *control, struct lwp *l) 741 { 742 struct inpcb *inp = sotoinpcb(so); 743 int error = 0; 744 int s; 745 746 KASSERT(solocked(so)); 747 KASSERT(inp != NULL); 748 KASSERT(m != NULL); 749 750 /* 751 * Ship a packet out. The appropriate raw output 752 * routine handles any massaging necessary. 753 */ 754 if (control && control->m_len) { 755 m_freem(control); 756 m_freem(m); 757 return EINVAL; 758 } 759 760 s = splsoftnet(); 761 if (nam) { 762 if ((so->so_state & SS_ISCONNECTED) != 0) { 763 error = EISCONN; 764 goto die; 765 } 766 error = rip_connect_pcb(inp, nam); 767 if (error) { 768 die: 769 m_freem(m); 770 splx(s); 771 return error; 772 } 773 } else { 774 if ((so->so_state & SS_ISCONNECTED) == 0) { 775 error = ENOTCONN; 776 goto die; 777 } 778 } 779 error = rip_output(m, inp); 780 if (nam) 781 rip_disconnect1(inp); 782 783 splx(s); 784 return error; 785 } 786 787 static int 788 rip_sendoob(struct socket *so, struct mbuf *m, struct mbuf *control) 789 { 790 KASSERT(solocked(so)); 791 792 m_freem(m); 793 m_freem(control); 794 795 return EOPNOTSUPP; 796 } 797 798 static int 799 rip_purgeif(struct socket *so, struct ifnet *ifp) 800 { 801 int s; 802 803 s = splsoftnet(); 804 mutex_enter(softnet_lock); 805 in_pcbpurgeif0(&rawcbtable, ifp); 806 in_purgeif(ifp); 807 in_pcbpurgeif(&rawcbtable, ifp); 808 mutex_exit(softnet_lock); 809 splx(s); 810 811 return 0; 812 } 813 814 int 815 rip_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam, 816 struct mbuf *control, struct lwp *l) 817 { 818 KASSERT(req != PRU_ATTACH); 819 KASSERT(req != PRU_DETACH); 820 KASSERT(req != PRU_ACCEPT); 821 KASSERT(req != PRU_BIND); 822 KASSERT(req != PRU_LISTEN); 823 KASSERT(req != PRU_CONNECT); 824 KASSERT(req != PRU_CONNECT2); 825 KASSERT(req != PRU_DISCONNECT); 826 KASSERT(req != PRU_SHUTDOWN); 827 KASSERT(req != PRU_ABORT); 828 KASSERT(req != PRU_CONTROL); 829 KASSERT(req != PRU_SENSE); 830 KASSERT(req != PRU_PEERADDR); 831 KASSERT(req != PRU_SOCKADDR); 832 KASSERT(req != PRU_RCVD); 833 KASSERT(req != PRU_RCVOOB); 834 KASSERT(req != PRU_SEND); 835 KASSERT(req != PRU_SENDOOB); 836 KASSERT(req != PRU_PURGEIF); 837 838 KASSERT(solocked(so)); 839 840 if (sotoinpcb(so) == NULL) 841 return EINVAL; 842 843 panic("rip_usrreq"); 844 845 return 0; 846 } 847 848 PR_WRAP_USRREQS(rip) 849 #define rip_attach rip_attach_wrapper 850 #define rip_detach rip_detach_wrapper 851 #define rip_accept rip_accept_wrapper 852 #define rip_bind rip_bind_wrapper 853 #define rip_listen rip_listen_wrapper 854 #define rip_connect rip_connect_wrapper 855 #define rip_connect2 rip_connect2_wrapper 856 #define rip_disconnect rip_disconnect_wrapper 857 #define rip_shutdown rip_shutdown_wrapper 858 #define rip_abort rip_abort_wrapper 859 #define rip_ioctl rip_ioctl_wrapper 860 #define rip_stat rip_stat_wrapper 861 #define rip_peeraddr rip_peeraddr_wrapper 862 #define rip_sockaddr rip_sockaddr_wrapper 863 #define rip_rcvd rip_rcvd_wrapper 864 #define rip_recvoob rip_recvoob_wrapper 865 #define rip_send rip_send_wrapper 866 #define rip_sendoob rip_sendoob_wrapper 867 #define rip_purgeif rip_purgeif_wrapper 868 #define rip_usrreq rip_usrreq_wrapper 869 870 const struct pr_usrreqs rip_usrreqs = { 871 .pr_attach = rip_attach, 872 .pr_detach = rip_detach, 873 .pr_accept = rip_accept, 874 .pr_bind = rip_bind, 875 .pr_listen = rip_listen, 876 .pr_connect = rip_connect, 877 .pr_connect2 = rip_connect2, 878 .pr_disconnect = rip_disconnect, 879 .pr_shutdown = rip_shutdown, 880 .pr_abort = rip_abort, 881 .pr_ioctl = rip_ioctl, 882 .pr_stat = rip_stat, 883 .pr_peeraddr = rip_peeraddr, 884 .pr_sockaddr = rip_sockaddr, 885 .pr_rcvd = rip_rcvd, 886 .pr_recvoob = rip_recvoob, 887 .pr_send = rip_send, 888 .pr_sendoob = rip_sendoob, 889 .pr_purgeif = rip_purgeif, 890 .pr_generic = rip_usrreq, 891 }; 892 893 static void 894 sysctl_net_inet_raw_setup(struct sysctllog **clog) 895 { 896 897 sysctl_createv(clog, 0, NULL, NULL, 898 CTLFLAG_PERMANENT, 899 CTLTYPE_NODE, "inet", NULL, 900 NULL, 0, NULL, 0, 901 CTL_NET, PF_INET, CTL_EOL); 902 sysctl_createv(clog, 0, NULL, NULL, 903 CTLFLAG_PERMANENT, 904 CTLTYPE_NODE, "raw", 905 SYSCTL_DESCR("Raw IPv4 settings"), 906 NULL, 0, NULL, 0, 907 CTL_NET, PF_INET, IPPROTO_RAW, CTL_EOL); 908 909 sysctl_createv(clog, 0, NULL, NULL, 910 CTLFLAG_PERMANENT, 911 CTLTYPE_STRUCT, "pcblist", 912 SYSCTL_DESCR("Raw IPv4 control block list"), 913 sysctl_inpcblist, 0, &rawcbtable, 0, 914 CTL_NET, PF_INET, IPPROTO_RAW, 915 CTL_CREATE, CTL_EOL); 916 } 917