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