1 /* 2 * Copyright (c) 1982, 1986, 1988, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * @(#)raw_ip.c 8.7 (Berkeley) 5/15/95 34 * $FreeBSD: src/sys/netinet/raw_ip.c,v 1.64.2.16 2003/08/24 08:24:38 hsu Exp $ 35 * $DragonFly: src/sys/netinet/raw_ip.c,v 1.33 2008/10/28 03:07:28 sephe Exp $ 36 */ 37 38 #include "opt_inet6.h" 39 #include "opt_ipsec.h" 40 41 #include <sys/param.h> 42 #include <sys/systm.h> 43 #include <sys/kernel.h> 44 #include <sys/jail.h> 45 #include <sys/malloc.h> 46 #include <sys/mbuf.h> 47 #include <sys/proc.h> 48 #include <sys/priv.h> 49 #include <sys/protosw.h> 50 #include <sys/socket.h> 51 #include <sys/socketvar.h> 52 #include <sys/sysctl.h> 53 54 #include <sys/thread2.h> 55 #include <sys/socketvar2.h> 56 57 #include <machine/stdarg.h> 58 59 #include <net/if.h> 60 #include <net/route.h> 61 62 #define _IP_VHL 63 #include <netinet/in.h> 64 #include <netinet/in_systm.h> 65 #include <netinet/ip.h> 66 #include <netinet/in_pcb.h> 67 #include <netinet/in_var.h> 68 #include <netinet/ip_var.h> 69 70 #include <net/ip_mroute/ip_mroute.h> 71 #include <net/ipfw/ip_fw.h> 72 #include <net/dummynet/ip_dummynet.h> 73 74 #ifdef FAST_IPSEC 75 #include <netproto/ipsec/ipsec.h> 76 #endif /*FAST_IPSEC*/ 77 78 #ifdef IPSEC 79 #include <netinet6/ipsec.h> 80 #endif /*IPSEC*/ 81 82 struct inpcbinfo ripcbinfo; 83 84 /* control hooks for ipfw and dummynet */ 85 ip_fw_ctl_t *ip_fw_ctl_ptr; 86 ip_dn_ctl_t *ip_dn_ctl_ptr; 87 88 static struct lwkt_token raw_token = LWKT_TOKEN_MP_INITIALIZER(raw_token); 89 90 91 /* 92 * hooks for multicast routing. They all default to NULL, 93 * so leave them not initialized and rely on BSS being set to 0. 94 */ 95 96 /* The socket used to communicate with the multicast routing daemon. */ 97 struct socket *ip_mrouter; 98 99 /* The various mrouter and rsvp functions */ 100 int (*ip_mrouter_set)(struct socket *, struct sockopt *); 101 int (*ip_mrouter_get)(struct socket *, struct sockopt *); 102 int (*ip_mrouter_done)(void); 103 int (*ip_mforward)(struct ip *, struct ifnet *, struct mbuf *, 104 struct ip_moptions *); 105 int (*mrt_ioctl)(int, caddr_t); 106 int (*legal_vif_num)(int); 107 u_long (*ip_mcast_src)(int); 108 109 void (*rsvp_input_p)(struct mbuf *m, ...); 110 int (*ip_rsvp_vif)(struct socket *, struct sockopt *); 111 void (*ip_rsvp_force_done)(struct socket *); 112 113 /* 114 * Nominal space allocated to a raw ip socket. 115 */ 116 #define RIPSNDQ 8192 117 #define RIPRCVQ 8192 118 119 /* 120 * Raw interface to IP protocol. 121 */ 122 123 /* 124 * Initialize raw connection block queue. 125 */ 126 void 127 rip_init(void) 128 { 129 in_pcbinfo_init(&ripcbinfo); 130 /* 131 * XXX We don't use the hash list for raw IP, but it's easier 132 * to allocate a one entry hash list than it is to check all 133 * over the place for hashbase == NULL. 134 */ 135 ripcbinfo.hashbase = hashinit(1, M_PCB, &ripcbinfo.hashmask); 136 ripcbinfo.porthashbase = hashinit(1, M_PCB, &ripcbinfo.porthashmask); 137 ripcbinfo.wildcardhashbase = hashinit(1, M_PCB, 138 &ripcbinfo.wildcardhashmask); 139 ripcbinfo.ipi_size = sizeof(struct inpcb); 140 } 141 142 /* 143 * Setup generic address and protocol structures 144 * for raw_input routine, then pass them along with 145 * mbuf chain. 146 */ 147 void 148 rip_input(struct mbuf *m, ...) 149 { 150 struct sockaddr_in ripsrc = { sizeof ripsrc, AF_INET }; 151 struct ip *ip = mtod(m, struct ip *); 152 struct inpcb *inp; 153 struct inpcb *last = NULL; 154 struct mbuf *opts = NULL; 155 int off, proto; 156 __va_list ap; 157 158 __va_start(ap, m); 159 off = __va_arg(ap, int); 160 proto = __va_arg(ap, int); 161 __va_end(ap); 162 163 ripsrc.sin_addr = ip->ip_src; 164 lwkt_gettoken(&raw_token); 165 LIST_FOREACH(inp, &ripcbinfo.pcblisthead, inp_list) { 166 if (inp->inp_flags & INP_PLACEMARKER) 167 continue; 168 #ifdef INET6 169 if ((inp->inp_vflag & INP_IPV4) == 0) 170 continue; 171 #endif 172 if (inp->inp_ip_p && inp->inp_ip_p != proto) 173 continue; 174 if (inp->inp_laddr.s_addr != INADDR_ANY && 175 inp->inp_laddr.s_addr != ip->ip_dst.s_addr) 176 continue; 177 if (inp->inp_faddr.s_addr != INADDR_ANY && 178 inp->inp_faddr.s_addr != ip->ip_src.s_addr) 179 continue; 180 if (last) { 181 struct mbuf *n = m_copypacket(m, MB_DONTWAIT); 182 183 #ifdef IPSEC 184 /* check AH/ESP integrity. */ 185 if (n && ipsec4_in_reject_so(n, last->inp_socket)) { 186 m_freem(n); 187 ipsecstat.in_polvio++; 188 /* do not inject data to pcb */ 189 } else 190 #endif /*IPSEC*/ 191 #ifdef FAST_IPSEC 192 /* check AH/ESP integrity. */ 193 if (ipsec4_in_reject(n, last)) { 194 m_freem(n); 195 /* do not inject data to pcb */ 196 } else 197 #endif /*FAST_IPSEC*/ 198 if (n) { 199 lwkt_gettoken(&last->inp_socket->so_rcv.ssb_token); 200 if (last->inp_flags & INP_CONTROLOPTS || 201 last->inp_socket->so_options & SO_TIMESTAMP) 202 ip_savecontrol(last, &opts, ip, n); 203 if (ssb_appendaddr(&last->inp_socket->so_rcv, 204 (struct sockaddr *)&ripsrc, n, 205 opts) == 0) { 206 /* should notify about lost packet */ 207 m_freem(n); 208 if (opts) 209 m_freem(opts); 210 } else { 211 sorwakeup(last->inp_socket); 212 } 213 lwkt_reltoken(&last->inp_socket->so_rcv.ssb_token); 214 opts = 0; 215 } 216 } 217 last = inp; 218 } 219 #ifdef IPSEC 220 /* check AH/ESP integrity. */ 221 if (last && ipsec4_in_reject_so(m, last->inp_socket)) { 222 m_freem(m); 223 ipsecstat.in_polvio++; 224 ipstat.ips_delivered--; 225 /* do not inject data to pcb */ 226 } else 227 #endif /*IPSEC*/ 228 #ifdef FAST_IPSEC 229 /* check AH/ESP integrity. */ 230 if (last && ipsec4_in_reject(m, last)) { 231 m_freem(m); 232 ipstat.ips_delivered--; 233 /* do not inject data to pcb */ 234 } else 235 #endif /*FAST_IPSEC*/ 236 /* Check the minimum TTL for socket. */ 237 if (last && ip->ip_ttl < last->inp_ip_minttl) { 238 m_freem(opts); 239 ipstat.ips_delivered--; 240 } else if (last) { 241 if (last->inp_flags & INP_CONTROLOPTS || 242 last->inp_socket->so_options & SO_TIMESTAMP) 243 ip_savecontrol(last, &opts, ip, m); 244 lwkt_gettoken(&last->inp_socket->so_rcv.ssb_token); 245 if (ssb_appendaddr(&last->inp_socket->so_rcv, 246 (struct sockaddr *)&ripsrc, m, opts) == 0) { 247 m_freem(m); 248 if (opts) 249 m_freem(opts); 250 } else { 251 sorwakeup(last->inp_socket); 252 } 253 lwkt_reltoken(&last->inp_socket->so_rcv.ssb_token); 254 } else { 255 m_freem(m); 256 ipstat.ips_noproto++; 257 ipstat.ips_delivered--; 258 } 259 lwkt_reltoken(&raw_token); 260 } 261 262 /* 263 * Generate IP header and pass packet to ip_output. 264 * Tack on options user may have setup with control call. 265 */ 266 int 267 rip_output(struct mbuf *m, struct socket *so, ...) 268 { 269 struct ip *ip; 270 struct inpcb *inp = so->so_pcb; 271 __va_list ap; 272 int flags = (so->so_options & SO_DONTROUTE) | IP_ALLOWBROADCAST; 273 u_long dst; 274 275 __va_start(ap, so); 276 dst = __va_arg(ap, u_long); 277 __va_end(ap); 278 279 /* 280 * If the user handed us a complete IP packet, use it. 281 * Otherwise, allocate an mbuf for a header and fill it in. 282 */ 283 if ((inp->inp_flags & INP_HDRINCL) == 0) { 284 if (m->m_pkthdr.len + sizeof(struct ip) > IP_MAXPACKET) { 285 m_freem(m); 286 return(EMSGSIZE); 287 } 288 M_PREPEND(m, sizeof(struct ip), MB_WAIT); 289 if (m == NULL) 290 return(ENOBUFS); 291 ip = mtod(m, struct ip *); 292 ip->ip_tos = inp->inp_ip_tos; 293 ip->ip_off = 0; 294 ip->ip_p = inp->inp_ip_p; 295 ip->ip_len = m->m_pkthdr.len; 296 ip->ip_src = inp->inp_laddr; 297 ip->ip_dst.s_addr = dst; 298 ip->ip_ttl = inp->inp_ip_ttl; 299 } else { 300 int hlen; 301 302 if (m->m_pkthdr.len > IP_MAXPACKET) { 303 m_freem(m); 304 return(EMSGSIZE); 305 } 306 if (m->m_len < sizeof(struct ip)) { 307 m = m_pullup(m, sizeof(struct ip)); 308 if (m == NULL) 309 return ENOBUFS; 310 } 311 ip = mtod(m, struct ip *); 312 hlen = IP_VHL_HL(ip->ip_vhl) << 2; 313 314 /* Don't allow header length less than the minimum. */ 315 if (hlen < sizeof(struct ip)) { 316 m_freem(m); 317 return EINVAL; 318 } 319 320 /* 321 * Don't allow both user specified and setsockopt options. 322 * Don't allow packet length sizes that will crash. 323 */ 324 if ((hlen != sizeof(struct ip) && inp->inp_options) || 325 ip->ip_len > m->m_pkthdr.len || ip->ip_len < hlen) { 326 m_freem(m); 327 return EINVAL; 328 } 329 if (ip->ip_id == 0) 330 ip->ip_id = ip_newid(); 331 332 /* Prevent ip_output from overwriting header fields */ 333 flags |= IP_RAWOUTPUT; 334 ipstat.ips_rawout++; 335 } 336 337 return ip_output(m, inp->inp_options, &inp->inp_route, flags, 338 inp->inp_moptions, inp); 339 } 340 341 /* 342 * Raw IP socket option processing. 343 */ 344 int 345 rip_ctloutput(struct socket *so, struct sockopt *sopt) 346 { 347 struct inpcb *inp = so->so_pcb; 348 int error, optval; 349 350 if (sopt->sopt_level != IPPROTO_IP) 351 return (EINVAL); 352 353 error = 0; 354 355 switch (sopt->sopt_dir) { 356 case SOPT_GET: 357 switch (sopt->sopt_name) { 358 case IP_HDRINCL: 359 optval = inp->inp_flags & INP_HDRINCL; 360 soopt_from_kbuf(sopt, &optval, sizeof optval); 361 break; 362 363 case IP_FW_ADD: /* ADD actually returns the body... */ 364 case IP_FW_GET: 365 if (IPFW_LOADED) 366 error = ip_fw_sockopt(sopt); 367 else 368 error = ENOPROTOOPT; 369 break; 370 371 case IP_DUMMYNET_GET: 372 error = ip_dn_sockopt(sopt); 373 break ; 374 375 case MRT_INIT: 376 case MRT_DONE: 377 case MRT_ADD_VIF: 378 case MRT_DEL_VIF: 379 case MRT_ADD_MFC: 380 case MRT_DEL_MFC: 381 case MRT_VERSION: 382 case MRT_ASSERT: 383 case MRT_API_SUPPORT: 384 case MRT_API_CONFIG: 385 case MRT_ADD_BW_UPCALL: 386 case MRT_DEL_BW_UPCALL: 387 error = ip_mrouter_get ? ip_mrouter_get(so, sopt) : 388 EOPNOTSUPP; 389 break; 390 391 default: 392 error = ip_ctloutput(so, sopt); 393 break; 394 } 395 break; 396 397 case SOPT_SET: 398 switch (sopt->sopt_name) { 399 case IP_HDRINCL: 400 error = soopt_to_kbuf(sopt, &optval, sizeof optval, 401 sizeof optval); 402 if (error) 403 break; 404 if (optval) 405 inp->inp_flags |= INP_HDRINCL; 406 else 407 inp->inp_flags &= ~INP_HDRINCL; 408 break; 409 410 case IP_FW_ADD: 411 case IP_FW_DEL: 412 case IP_FW_FLUSH: 413 case IP_FW_ZERO: 414 case IP_FW_RESETLOG: 415 if (IPFW_LOADED) 416 error = ip_fw_ctl_ptr(sopt); 417 else 418 error = ENOPROTOOPT; 419 break; 420 421 case IP_DUMMYNET_CONFIGURE: 422 case IP_DUMMYNET_DEL: 423 case IP_DUMMYNET_FLUSH: 424 error = ip_dn_sockopt(sopt); 425 break ; 426 427 case IP_RSVP_ON: 428 error = ip_rsvp_init(so); 429 break; 430 431 case IP_RSVP_OFF: 432 error = ip_rsvp_done(); 433 break; 434 435 case IP_RSVP_VIF_ON: 436 case IP_RSVP_VIF_OFF: 437 error = ip_rsvp_vif ? 438 ip_rsvp_vif(so, sopt) : EINVAL; 439 break; 440 441 case MRT_INIT: 442 case MRT_DONE: 443 case MRT_ADD_VIF: 444 case MRT_DEL_VIF: 445 case MRT_ADD_MFC: 446 case MRT_DEL_MFC: 447 case MRT_VERSION: 448 case MRT_ASSERT: 449 case MRT_API_SUPPORT: 450 case MRT_API_CONFIG: 451 case MRT_ADD_BW_UPCALL: 452 case MRT_DEL_BW_UPCALL: 453 error = ip_mrouter_set ? ip_mrouter_set(so, sopt) : 454 EOPNOTSUPP; 455 break; 456 457 default: 458 error = ip_ctloutput(so, sopt); 459 break; 460 } 461 break; 462 } 463 464 return (error); 465 } 466 467 /* 468 * This function exists solely to receive the PRC_IFDOWN messages which 469 * are sent by if_down(). It looks for an ifaddr whose ifa_addr is sa, 470 * and calls in_ifadown() to remove all routes corresponding to that address. 471 * It also receives the PRC_IFUP messages from if_up() and reinstalls the 472 * interface routes. 473 */ 474 void 475 rip_ctlinput(int cmd, struct sockaddr *sa, void *vip) 476 { 477 struct in_ifaddr *ia; 478 struct in_ifaddr_container *iac; 479 struct ifnet *ifp; 480 int err; 481 int flags; 482 483 switch (cmd) { 484 case PRC_IFDOWN: 485 TAILQ_FOREACH(iac, &in_ifaddrheads[mycpuid], ia_link) { 486 ia = iac->ia; 487 488 if (ia->ia_ifa.ifa_addr == sa && 489 (ia->ia_flags & IFA_ROUTE)) { 490 /* 491 * in_ifscrub kills the interface route. 492 */ 493 in_ifscrub(ia->ia_ifp, ia); 494 /* 495 * in_ifadown gets rid of all the rest of 496 * the routes. This is not quite the right 497 * thing to do, but at least if we are running 498 * a routing process they will come back. 499 */ 500 in_ifadown(&ia->ia_ifa, 0); 501 break; 502 } 503 } 504 break; 505 506 case PRC_IFUP: 507 ia = NULL; 508 TAILQ_FOREACH(iac, &in_ifaddrheads[mycpuid], ia_link) { 509 if (iac->ia->ia_ifa.ifa_addr == sa) { 510 ia = iac->ia; 511 break; 512 } 513 } 514 if (ia == NULL || (ia->ia_flags & IFA_ROUTE)) 515 return; 516 flags = RTF_UP; 517 ifp = ia->ia_ifa.ifa_ifp; 518 519 if ((ifp->if_flags & IFF_LOOPBACK) || 520 (ifp->if_flags & IFF_POINTOPOINT)) 521 flags |= RTF_HOST; 522 523 err = rtinit(&ia->ia_ifa, RTM_ADD, flags); 524 if (err == 0) 525 ia->ia_flags |= IFA_ROUTE; 526 break; 527 } 528 } 529 530 u_long rip_sendspace = RIPSNDQ; 531 u_long rip_recvspace = RIPRCVQ; 532 533 SYSCTL_INT(_net_inet_raw, OID_AUTO, maxdgram, CTLFLAG_RW, 534 &rip_sendspace, 0, "Maximum outgoing raw IP datagram size"); 535 SYSCTL_INT(_net_inet_raw, OID_AUTO, recvspace, CTLFLAG_RW, 536 &rip_recvspace, 0, "Maximum incoming raw IP datagram size"); 537 538 static int 539 rip_attach(struct socket *so, int proto, struct pru_attach_info *ai) 540 { 541 struct inpcb *inp; 542 int error; 543 544 inp = so->so_pcb; 545 if (inp) 546 panic("rip_attach"); 547 error = priv_check_cred(ai->p_ucred, PRIV_NETINET_RAW, NULL_CRED_OKAY); 548 if (error) 549 return error; 550 551 error = soreserve(so, rip_sendspace, rip_recvspace, ai->sb_rlimit); 552 if (error) 553 return error; 554 lwkt_gettoken(&raw_token); 555 error = in_pcballoc(so, &ripcbinfo); 556 if (error == 0) { 557 inp = (struct inpcb *)so->so_pcb; 558 inp->inp_vflag |= INP_IPV4; 559 inp->inp_ip_p = proto; 560 inp->inp_ip_ttl = ip_defttl; 561 } 562 lwkt_reltoken(&raw_token); 563 return 0; 564 } 565 566 static int 567 rip_detach(struct socket *so) 568 { 569 struct inpcb *inp; 570 571 inp = so->so_pcb; 572 if (inp == 0) 573 panic("rip_detach"); 574 if (so == ip_mrouter && ip_mrouter_done) 575 ip_mrouter_done(); 576 if (ip_rsvp_force_done) 577 ip_rsvp_force_done(so); 578 if (so == ip_rsvpd) 579 ip_rsvp_done(); 580 in_pcbdetach(inp); 581 return 0; 582 } 583 584 /* 585 * NOTE: (so) is referenced from soabort*() and netmsg_pru_abort() 586 * will sofree() it when we return. 587 */ 588 static int 589 rip_abort(struct socket *so) 590 { 591 int error; 592 593 soisdisconnected(so); 594 if (so->so_state & SS_NOFDREF) /* XXX not sure why this test */ 595 error = rip_detach(so); 596 else 597 error = 0; 598 599 return error; 600 } 601 602 static int 603 rip_disconnect(struct socket *so) 604 { 605 int error; 606 607 if ((so->so_state & SS_ISCONNECTED) == 0) 608 return ENOTCONN; 609 soreference(so); 610 error = rip_abort(so); 611 sofree(so); 612 613 return error; 614 } 615 616 static int 617 rip_bind(struct socket *so, struct sockaddr *nam, struct thread *td) 618 { 619 struct inpcb *inp = so->so_pcb; 620 struct sockaddr_in *addr = (struct sockaddr_in *)nam; 621 622 if (nam->sa_len != sizeof(*addr)) 623 return EINVAL; 624 625 if (TAILQ_EMPTY(&ifnet) || ((addr->sin_family != AF_INET) && 626 (addr->sin_family != AF_IMPLINK)) || 627 (addr->sin_addr.s_addr != INADDR_ANY && 628 ifa_ifwithaddr((struct sockaddr *)addr) == 0)) 629 return EADDRNOTAVAIL; 630 inp->inp_laddr = addr->sin_addr; 631 return 0; 632 } 633 634 static int 635 rip_connect(struct socket *so, struct sockaddr *nam, struct thread *td) 636 { 637 struct inpcb *inp = so->so_pcb; 638 struct sockaddr_in *addr = (struct sockaddr_in *)nam; 639 640 if (nam->sa_len != sizeof(*addr)) 641 return EINVAL; 642 if (TAILQ_EMPTY(&ifnet)) 643 return EADDRNOTAVAIL; 644 if ((addr->sin_family != AF_INET) && 645 (addr->sin_family != AF_IMPLINK)) 646 return EAFNOSUPPORT; 647 inp->inp_faddr = addr->sin_addr; 648 soisconnected(so); 649 return 0; 650 } 651 652 static int 653 rip_shutdown(struct socket *so) 654 { 655 socantsendmore(so); 656 return 0; 657 } 658 659 static int 660 rip_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam, 661 struct mbuf *control, struct thread *td) 662 { 663 struct inpcb *inp = so->so_pcb; 664 u_long dst; 665 666 if (so->so_state & SS_ISCONNECTED) { 667 if (nam) { 668 m_freem(m); 669 return EISCONN; 670 } 671 dst = inp->inp_faddr.s_addr; 672 } else { 673 if (nam == NULL) { 674 m_freem(m); 675 return ENOTCONN; 676 } 677 dst = ((struct sockaddr_in *)nam)->sin_addr.s_addr; 678 } 679 return rip_output(m, so, dst); 680 } 681 682 SYSCTL_PROC(_net_inet_raw, OID_AUTO/*XXX*/, pcblist, CTLFLAG_RD, &ripcbinfo, 0, 683 in_pcblist_global, "S,xinpcb", "List of active raw IP sockets"); 684 685 struct pr_usrreqs rip_usrreqs = { 686 .pru_abort = rip_abort, 687 .pru_accept = pru_accept_notsupp, 688 .pru_attach = rip_attach, 689 .pru_bind = rip_bind, 690 .pru_connect = rip_connect, 691 .pru_connect2 = pru_connect2_notsupp, 692 .pru_control = in_control, 693 .pru_detach = rip_detach, 694 .pru_disconnect = rip_disconnect, 695 .pru_listen = pru_listen_notsupp, 696 .pru_peeraddr = in_setpeeraddr, 697 .pru_rcvd = pru_rcvd_notsupp, 698 .pru_rcvoob = pru_rcvoob_notsupp, 699 .pru_send = rip_send, 700 .pru_sense = pru_sense_null, 701 .pru_shutdown = rip_shutdown, 702 .pru_sockaddr = in_setsockaddr, 703 .pru_sosend = sosend, 704 .pru_soreceive = soreceive 705 }; 706