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