1 /* $NetBSD: raw_ip.c,v 1.111 2009/12/09 00:45:25 dyoung 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 #include <sys/cdefs.h> 64 __KERNEL_RCSID(0, "$NetBSD: raw_ip.c,v 1.111 2009/12/09 00:45:25 dyoung Exp $"); 65 66 #include "opt_inet.h" 67 #include "opt_compat_netbsd.h" 68 #include "opt_ipsec.h" 69 #include "opt_mrouting.h" 70 71 #include <sys/param.h> 72 #include <sys/sysctl.h> 73 #include <sys/malloc.h> 74 #include <sys/mbuf.h> 75 #include <sys/socket.h> 76 #include <sys/protosw.h> 77 #include <sys/socketvar.h> 78 #include <sys/errno.h> 79 #include <sys/systm.h> 80 #include <sys/proc.h> 81 #include <sys/kauth.h> 82 83 #include <net/if.h> 84 #include <net/route.h> 85 86 #include <netinet/in.h> 87 #include <netinet/in_systm.h> 88 #include <netinet/ip.h> 89 #include <netinet/ip_var.h> 90 #include <netinet/ip_private.h> 91 #include <netinet/ip_mroute.h> 92 #include <netinet/ip_icmp.h> 93 #include <netinet/in_pcb.h> 94 #include <netinet/in_proto.h> 95 #include <netinet/in_var.h> 96 97 #include <machine/stdarg.h> 98 99 #ifdef IPSEC 100 #include <netinet6/ipsec.h> 101 #include <netinet6/ipsec_private.h> 102 #endif /* IPSEC */ 103 104 #ifdef FAST_IPSEC 105 #include <netipsec/ipsec.h> 106 #include <netipsec/ipsec_var.h> 107 #include <netipsec/ipsec_private.h> 108 #endif /* FAST_IPSEC */ 109 110 #ifdef COMPAT_50 111 #include <compat/sys/socket.h> 112 #endif 113 114 struct inpcbtable rawcbtable; 115 116 int rip_pcbnotify(struct inpcbtable *, struct in_addr, 117 struct in_addr, int, int, void (*)(struct inpcb *, int)); 118 int rip_bind(struct inpcb *, struct mbuf *); 119 int rip_connect(struct inpcb *, struct mbuf *); 120 void rip_disconnect(struct inpcb *); 121 122 static void sysctl_net_inet_raw_setup(struct sysctllog **); 123 124 /* 125 * Nominal space allocated to a raw ip socket. 126 */ 127 #define RIPSNDQ 8192 128 #define RIPRCVQ 8192 129 130 /* 131 * Raw interface to IP protocol. 132 */ 133 134 /* 135 * Initialize raw connection block q. 136 */ 137 void 138 rip_init(void) 139 { 140 141 sysctl_net_inet_raw_setup(NULL); 142 in_pcbinit(&rawcbtable, 1, 1); 143 } 144 145 static void 146 rip_sbappendaddr(struct inpcb *last, struct ip *ip, const struct sockaddr *sa, 147 int hlen, struct mbuf *opts, struct mbuf *n) 148 { 149 if (last->inp_flags & INP_NOHEADER) 150 m_adj(n, hlen); 151 if (last->inp_flags & INP_CONTROLOPTS 152 #ifdef SO_OTIMESTAMP 153 || last->inp_socket->so_options & SO_OTIMESTAMP 154 #endif 155 || last->inp_socket->so_options & SO_TIMESTAMP) 156 ip_savecontrol(last, &opts, ip, n); 157 if (sbappendaddr(&last->inp_socket->so_rcv, sa, n, opts) == 0) { 158 /* should notify about lost packet */ 159 m_freem(n); 160 if (opts) 161 m_freem(opts); 162 } else 163 sorwakeup(last->inp_socket); 164 } 165 166 /* 167 * Setup generic address and protocol structures 168 * for raw_input routine, then pass them along with 169 * mbuf chain. 170 */ 171 void 172 rip_input(struct mbuf *m, ...) 173 { 174 int hlen, proto; 175 struct ip *ip = mtod(m, struct ip *); 176 struct inpcb_hdr *inph; 177 struct inpcb *inp; 178 struct inpcb *last = NULL; 179 struct mbuf *n, *opts = NULL; 180 struct sockaddr_in ripsrc; 181 va_list ap; 182 183 va_start(ap, m); 184 (void)va_arg(ap, int); /* ignore value, advance ap */ 185 proto = va_arg(ap, int); 186 va_end(ap); 187 188 sockaddr_in_init(&ripsrc, &ip->ip_src, 0); 189 190 /* 191 * XXX Compatibility: programs using raw IP expect ip_len 192 * XXX to have the header length subtracted, and in host order. 193 * XXX ip_off is also expected to be host order. 194 */ 195 hlen = ip->ip_hl << 2; 196 ip->ip_len = ntohs(ip->ip_len) - hlen; 197 NTOHS(ip->ip_off); 198 199 CIRCLEQ_FOREACH(inph, &rawcbtable.inpt_queue, inph_queue) { 200 inp = (struct inpcb *)inph; 201 if (inp->inp_af != AF_INET) 202 continue; 203 if (inp->inp_ip.ip_p && inp->inp_ip.ip_p != proto) 204 continue; 205 if (!in_nullhost(inp->inp_laddr) && 206 !in_hosteq(inp->inp_laddr, ip->ip_dst)) 207 continue; 208 if (!in_nullhost(inp->inp_faddr) && 209 !in_hosteq(inp->inp_faddr, ip->ip_src)) 210 continue; 211 if (last == NULL) 212 ; 213 #if defined(IPSEC) || defined(FAST_IPSEC) 214 /* check AH/ESP integrity. */ 215 else if (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) || defined(FAST_IPSEC) 228 /* check AH/ESP integrity. */ 229 if (last != NULL && 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 *inp, *ninp; 258 int nmatch; 259 260 nmatch = 0; 261 for (inp = (struct inpcb *)CIRCLEQ_FIRST(&table->inpt_queue); 262 inp != (struct inpcb *)&table->inpt_queue; 263 inp = ninp) { 264 ninp = (struct inpcb *)inp->inp_queue.cqe_next; 265 if (inp->inp_af != AF_INET) 266 continue; 267 if (inp->inp_ip.ip_p && inp->inp_ip.ip_p != proto) 268 continue; 269 if (in_hosteq(inp->inp_faddr, faddr) && 270 in_hosteq(inp->inp_laddr, laddr)) { 271 (*notify)(inp, errno); 272 nmatch++; 273 } 274 } 275 276 return nmatch; 277 } 278 279 void * 280 rip_ctlinput(int cmd, const struct sockaddr *sa, void *v) 281 { 282 struct ip *ip = v; 283 void (*notify)(struct inpcb *, int) = in_rtchange; 284 int errno; 285 286 if (sa->sa_family != AF_INET || 287 sa->sa_len != sizeof(struct sockaddr_in)) 288 return NULL; 289 if ((unsigned)cmd >= PRC_NCMDS) 290 return NULL; 291 errno = inetctlerrmap[cmd]; 292 if (PRC_IS_REDIRECT(cmd)) 293 notify = in_rtchange, ip = 0; 294 else if (cmd == PRC_HOSTDEAD) 295 ip = 0; 296 else if (errno == 0) 297 return NULL; 298 if (ip) { 299 rip_pcbnotify(&rawcbtable, satocsin(sa)->sin_addr, 300 ip->ip_src, ip->ip_p, errno, notify); 301 302 /* XXX mapped address case */ 303 } else 304 in_pcbnotifyall(&rawcbtable, satocsin(sa)->sin_addr, errno, 305 notify); 306 return NULL; 307 } 308 309 /* 310 * Generate IP header and pass packet to ip_output. 311 * Tack on options user may have setup with control call. 312 */ 313 int 314 rip_output(struct mbuf *m, ...) 315 { 316 struct inpcb *inp; 317 struct ip *ip; 318 struct mbuf *opts; 319 int flags; 320 va_list ap; 321 322 va_start(ap, m); 323 inp = va_arg(ap, struct inpcb *); 324 va_end(ap); 325 326 flags = 327 (inp->inp_socket->so_options & SO_DONTROUTE) | IP_ALLOWBROADCAST 328 | IP_RETURNMTU; 329 330 /* 331 * If the user handed us a complete IP packet, use it. 332 * Otherwise, allocate an mbuf for a header and fill it in. 333 */ 334 if ((inp->inp_flags & INP_HDRINCL) == 0) { 335 if ((m->m_pkthdr.len + sizeof(struct ip)) > IP_MAXPACKET) { 336 m_freem(m); 337 return (EMSGSIZE); 338 } 339 M_PREPEND(m, sizeof(struct ip), M_DONTWAIT); 340 if (!m) 341 return (ENOBUFS); 342 ip = mtod(m, struct ip *); 343 ip->ip_tos = 0; 344 ip->ip_off = htons(0); 345 ip->ip_p = inp->inp_ip.ip_p; 346 ip->ip_len = htons(m->m_pkthdr.len); 347 ip->ip_src = inp->inp_laddr; 348 ip->ip_dst = inp->inp_faddr; 349 ip->ip_ttl = MAXTTL; 350 opts = inp->inp_options; 351 } else { 352 if (m->m_pkthdr.len > IP_MAXPACKET) { 353 m_freem(m); 354 return (EMSGSIZE); 355 } 356 ip = mtod(m, struct ip *); 357 358 /* 359 * If the mbuf is read-only, we need to allocate 360 * a new mbuf for the header, since we need to 361 * modify the header. 362 */ 363 if (M_READONLY(m)) { 364 int hlen = ip->ip_hl << 2; 365 366 m = m_copyup(m, hlen, (max_linkhdr + 3) & ~3); 367 if (m == NULL) 368 return (ENOMEM); /* XXX */ 369 ip = mtod(m, struct ip *); 370 } 371 372 /* XXX userland passes ip_len and ip_off in host order */ 373 if (m->m_pkthdr.len != ip->ip_len) { 374 m_freem(m); 375 return (EINVAL); 376 } 377 HTONS(ip->ip_len); 378 HTONS(ip->ip_off); 379 if (ip->ip_id != 0 || m->m_pkthdr.len < IP_MINFRAGSIZE) 380 flags |= IP_NOIPNEWID; 381 opts = NULL; 382 /* XXX prevent ip_output from overwriting header fields */ 383 flags |= IP_RAWOUTPUT; 384 IP_STATINC(IP_STAT_RAWOUT); 385 } 386 return (ip_output(m, opts, &inp->inp_route, flags, inp->inp_moptions, 387 inp->inp_socket, &inp->inp_errormtu)); 388 } 389 390 /* 391 * Raw IP socket option processing. 392 */ 393 int 394 rip_ctloutput(int op, struct socket *so, struct sockopt *sopt) 395 { 396 struct inpcb *inp = sotoinpcb(so); 397 int error = 0; 398 int optval; 399 400 if (sopt->sopt_level == SOL_SOCKET && sopt->sopt_name == SO_NOHEADER) { 401 if (op == PRCO_GETOPT) { 402 optval = (inp->inp_flags & INP_NOHEADER) ? 1 : 0; 403 error = sockopt_set(sopt, &optval, sizeof(optval)); 404 } else if (op == PRCO_SETOPT) { 405 error = sockopt_getint(sopt, &optval); 406 if (error) 407 goto out; 408 if (optval) { 409 inp->inp_flags &= ~INP_HDRINCL; 410 inp->inp_flags |= INP_NOHEADER; 411 } else 412 inp->inp_flags &= ~INP_NOHEADER; 413 } 414 goto out; 415 } else if (sopt->sopt_level != IPPROTO_IP) 416 return ip_ctloutput(op, so, sopt); 417 418 switch (op) { 419 420 case PRCO_SETOPT: 421 switch (sopt->sopt_name) { 422 case IP_HDRINCL: 423 error = sockopt_getint(sopt, &optval); 424 if (error) 425 break; 426 if (optval) 427 inp->inp_flags |= INP_HDRINCL; 428 else 429 inp->inp_flags &= ~INP_HDRINCL; 430 break; 431 432 #ifdef MROUTING 433 case MRT_INIT: 434 case MRT_DONE: 435 case MRT_ADD_VIF: 436 case MRT_DEL_VIF: 437 case MRT_ADD_MFC: 438 case MRT_DEL_MFC: 439 case MRT_ASSERT: 440 case MRT_API_CONFIG: 441 case MRT_ADD_BW_UPCALL: 442 case MRT_DEL_BW_UPCALL: 443 error = ip_mrouter_set(so, sopt); 444 break; 445 #endif 446 447 default: 448 error = ip_ctloutput(op, so, sopt); 449 break; 450 } 451 break; 452 453 case PRCO_GETOPT: 454 switch (sopt->sopt_name) { 455 case IP_HDRINCL: 456 optval = inp->inp_flags & INP_HDRINCL; 457 error = sockopt_set(sopt, &optval, sizeof(optval)); 458 break; 459 460 #ifdef MROUTING 461 case MRT_VERSION: 462 case MRT_ASSERT: 463 case MRT_API_SUPPORT: 464 case MRT_API_CONFIG: 465 error = ip_mrouter_get(so, sopt); 466 break; 467 #endif 468 469 default: 470 error = ip_ctloutput(op, so, sopt); 471 break; 472 } 473 break; 474 } 475 out: 476 return error; 477 } 478 479 int 480 rip_bind(struct inpcb *inp, struct mbuf *nam) 481 { 482 struct sockaddr_in *addr = mtod(nam, struct sockaddr_in *); 483 484 if (nam->m_len != sizeof(*addr)) 485 return (EINVAL); 486 if (TAILQ_FIRST(&ifnet) == 0) 487 return (EADDRNOTAVAIL); 488 if (addr->sin_family != AF_INET && 489 addr->sin_family != AF_IMPLINK) 490 return (EAFNOSUPPORT); 491 if (!in_nullhost(addr->sin_addr) && 492 ifa_ifwithaddr(sintosa(addr)) == 0) 493 return (EADDRNOTAVAIL); 494 inp->inp_laddr = addr->sin_addr; 495 return (0); 496 } 497 498 int 499 rip_connect(struct inpcb *inp, struct mbuf *nam) 500 { 501 struct sockaddr_in *addr = mtod(nam, struct sockaddr_in *); 502 503 if (nam->m_len != sizeof(*addr)) 504 return (EINVAL); 505 if (TAILQ_FIRST(&ifnet) == 0) 506 return (EADDRNOTAVAIL); 507 if (addr->sin_family != AF_INET && 508 addr->sin_family != AF_IMPLINK) 509 return (EAFNOSUPPORT); 510 inp->inp_faddr = addr->sin_addr; 511 return (0); 512 } 513 514 void 515 rip_disconnect(struct inpcb *inp) 516 { 517 518 inp->inp_faddr = zeroin_addr; 519 } 520 521 u_long rip_sendspace = RIPSNDQ; 522 u_long rip_recvspace = RIPRCVQ; 523 524 /*ARGSUSED*/ 525 int 526 rip_usrreq(struct socket *so, int req, 527 struct mbuf *m, struct mbuf *nam, struct mbuf *control, struct lwp *l) 528 { 529 struct inpcb *inp; 530 int s; 531 int error = 0; 532 #ifdef MROUTING 533 extern struct socket *ip_mrouter; 534 #endif 535 536 if (req == PRU_CONTROL) 537 return in_control(so, (long)m, nam, (struct ifnet *)control, l); 538 539 s = splsoftnet(); 540 541 if (req == PRU_PURGEIF) { 542 mutex_enter(softnet_lock); 543 in_pcbpurgeif0(&rawcbtable, (struct ifnet *)control); 544 in_purgeif((struct ifnet *)control); 545 in_pcbpurgeif(&rawcbtable, (struct ifnet *)control); 546 mutex_exit(softnet_lock); 547 splx(s); 548 return (0); 549 } 550 551 inp = sotoinpcb(so); 552 #ifdef DIAGNOSTIC 553 if (req != PRU_SEND && req != PRU_SENDOOB && control) 554 panic("rip_usrreq: unexpected control mbuf"); 555 #endif 556 if (inp == NULL && req != PRU_ATTACH) { 557 error = EINVAL; 558 goto release; 559 } 560 561 switch (req) { 562 563 case PRU_ATTACH: 564 sosetlock(so); 565 if (inp != 0) { 566 error = EISCONN; 567 break; 568 } 569 570 if (l == NULL) { 571 error = EACCES; 572 break; 573 } 574 575 /* XXX: raw socket permissions are checked in socreate() */ 576 577 if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) { 578 error = soreserve(so, rip_sendspace, rip_recvspace); 579 if (error) 580 break; 581 } 582 error = in_pcballoc(so, &rawcbtable); 583 if (error) 584 break; 585 inp = sotoinpcb(so); 586 inp->inp_ip.ip_p = (long)nam; 587 break; 588 589 case PRU_DETACH: 590 #ifdef MROUTING 591 if (so == ip_mrouter) 592 ip_mrouter_done(); 593 #endif 594 in_pcbdetach(inp); 595 break; 596 597 case PRU_BIND: 598 error = rip_bind(inp, nam); 599 break; 600 601 case PRU_LISTEN: 602 error = EOPNOTSUPP; 603 break; 604 605 case PRU_CONNECT: 606 error = rip_connect(inp, nam); 607 if (error) 608 break; 609 soisconnected(so); 610 break; 611 612 case PRU_CONNECT2: 613 error = EOPNOTSUPP; 614 break; 615 616 case PRU_DISCONNECT: 617 soisdisconnected(so); 618 rip_disconnect(inp); 619 break; 620 621 /* 622 * Mark the connection as being incapable of further input. 623 */ 624 case PRU_SHUTDOWN: 625 socantsendmore(so); 626 break; 627 628 case PRU_RCVD: 629 error = EOPNOTSUPP; 630 break; 631 632 /* 633 * Ship a packet out. The appropriate raw output 634 * routine handles any massaging necessary. 635 */ 636 case PRU_SEND: 637 if (control && control->m_len) { 638 m_freem(control); 639 m_freem(m); 640 error = EINVAL; 641 break; 642 } 643 { 644 if (nam) { 645 if ((so->so_state & SS_ISCONNECTED) != 0) { 646 error = EISCONN; 647 goto die; 648 } 649 error = rip_connect(inp, nam); 650 if (error) { 651 die: 652 m_freem(m); 653 break; 654 } 655 } else { 656 if ((so->so_state & SS_ISCONNECTED) == 0) { 657 error = ENOTCONN; 658 goto die; 659 } 660 } 661 error = rip_output(m, inp); 662 if (nam) 663 rip_disconnect(inp); 664 } 665 break; 666 667 case PRU_SENSE: 668 /* 669 * stat: don't bother with a blocksize. 670 */ 671 splx(s); 672 return (0); 673 674 case PRU_RCVOOB: 675 error = EOPNOTSUPP; 676 break; 677 678 case PRU_SENDOOB: 679 m_freem(control); 680 m_freem(m); 681 error = EOPNOTSUPP; 682 break; 683 684 case PRU_SOCKADDR: 685 in_setsockaddr(inp, nam); 686 break; 687 688 case PRU_PEERADDR: 689 in_setpeeraddr(inp, nam); 690 break; 691 692 default: 693 panic("rip_usrreq"); 694 } 695 696 release: 697 splx(s); 698 return (error); 699 } 700 701 static void 702 sysctl_net_inet_raw_setup(struct sysctllog **clog) 703 { 704 705 sysctl_createv(clog, 0, NULL, NULL, 706 CTLFLAG_PERMANENT, 707 CTLTYPE_NODE, "net", NULL, 708 NULL, 0, NULL, 0, 709 CTL_NET, CTL_EOL); 710 sysctl_createv(clog, 0, NULL, NULL, 711 CTLFLAG_PERMANENT, 712 CTLTYPE_NODE, "inet", NULL, 713 NULL, 0, NULL, 0, 714 CTL_NET, PF_INET, CTL_EOL); 715 sysctl_createv(clog, 0, NULL, NULL, 716 CTLFLAG_PERMANENT, 717 CTLTYPE_NODE, "raw", 718 SYSCTL_DESCR("Raw IPv4 settings"), 719 NULL, 0, NULL, 0, 720 CTL_NET, PF_INET, IPPROTO_RAW, CTL_EOL); 721 722 sysctl_createv(clog, 0, NULL, NULL, 723 CTLFLAG_PERMANENT, 724 CTLTYPE_STRUCT, "pcblist", 725 SYSCTL_DESCR("Raw IPv4 control block list"), 726 sysctl_inpcblist, 0, &rawcbtable, 0, 727 CTL_NET, PF_INET, IPPROTO_RAW, 728 CTL_CREATE, CTL_EOL); 729 } 730