The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/netinet/raw_ip.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    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$
   35  */
   36 
   37 #include <sys/param.h>
   38 #include <sys/systm.h>
   39 #include <sys/kernel.h>
   40 #include <sys/malloc.h>
   41 #include <sys/mbuf.h>
   42 #include <sys/proc.h>
   43 #include <sys/protosw.h>
   44 #include <sys/socket.h>
   45 #include <sys/socketvar.h>
   46 #include <sys/sysctl.h>
   47 
   48 #include <vm/vm_zone.h>
   49 
   50 #include <net/if.h>
   51 #include <net/route.h>
   52 
   53 #define _IP_VHL
   54 #include <netinet/in.h>
   55 #include <netinet/in_systm.h>
   56 #include <netinet/ip.h>
   57 #include <netinet/in_pcb.h>
   58 #include <netinet/in_var.h>
   59 #include <netinet/ip_var.h>
   60 #include <netinet/ip_mroute.h>
   61 
   62 #include <netinet/ip_fw.h>
   63 
   64 #include "opt_ipdn.h"
   65 #ifdef DUMMYNET
   66 #include <netinet/ip_dummynet.h>
   67 #endif
   68 #if !defined(COMPAT_IPFW) || COMPAT_IPFW == 1
   69 #undef COMPAT_IPFW
   70 #define COMPAT_IPFW 1
   71 #else
   72 #undef COMPAT_IPFW
   73 #endif
   74 
   75 static struct inpcbhead ripcb;
   76 static struct inpcbinfo ripcbinfo;
   77 
   78 /*
   79  * Nominal space allocated to a raw ip socket.
   80  */
   81 #define RIPSNDQ         8192
   82 #define RIPRCVQ         8192
   83 
   84 /*
   85  * Raw interface to IP protocol.
   86  */
   87 
   88 /*
   89  * Initialize raw connection block q.
   90  */
   91 void
   92 rip_init()
   93 {
   94         LIST_INIT(&ripcb);
   95         ripcbinfo.listhead = &ripcb;
   96         /*
   97          * XXX We don't use the hash list for raw IP, but it's easier
   98          * to allocate a one entry hash list than it is to check all
   99          * over the place for hashbase == NULL.
  100          */
  101         ripcbinfo.hashbase = hashinit(1, M_PCB, &ripcbinfo.hashmask);
  102         ripcbinfo.porthashbase = hashinit(1, M_PCB, &ripcbinfo.porthashmask);
  103         ripcbinfo.ipi_zone = zinit("ripcb", sizeof(struct inpcb),
  104                                    maxsockets, ZONE_INTERRUPT, 0);
  105 }
  106 
  107 static struct   sockaddr_in ripsrc = { sizeof(ripsrc), AF_INET };
  108 /*
  109  * Setup generic address and protocol structures
  110  * for raw_input routine, then pass them along with
  111  * mbuf chain.
  112  */
  113 void
  114 rip_input(m, iphlen)
  115         struct mbuf *m;
  116         int iphlen;
  117 {
  118         register struct ip *ip = mtod(m, struct ip *);
  119         register struct inpcb *inp;
  120         struct inpcb *last = 0;
  121         struct mbuf *opts = 0;
  122 
  123         ripsrc.sin_addr = ip->ip_src;
  124         for (inp = ripcb.lh_first; inp != NULL; inp = inp->inp_list.le_next) {
  125                 if (inp->inp_ip_p && inp->inp_ip_p != ip->ip_p)
  126                         continue;
  127                 if (inp->inp_laddr.s_addr &&
  128                   inp->inp_laddr.s_addr != ip->ip_dst.s_addr)
  129                         continue;
  130                 if (inp->inp_faddr.s_addr &&
  131                   inp->inp_faddr.s_addr != ip->ip_src.s_addr)
  132                         continue;
  133                 if (last) {
  134                         struct mbuf *n = m_copy(m, 0, (int)M_COPYALL);
  135                         if (n) {
  136                                 if (last->inp_flags & INP_CONTROLOPTS ||
  137                                     last->inp_socket->so_options & SO_TIMESTAMP)
  138                                     ip_savecontrol(last, &opts, ip, n);
  139                                 if (sbappendaddr(&last->inp_socket->so_rcv,
  140                                     (struct sockaddr *)&ripsrc, n,
  141                                     opts) == 0) {
  142                                         /* should notify about lost packet */
  143                                         m_freem(n);
  144                                         if (opts)
  145                                             m_freem(opts);
  146                                 } else
  147                                         sorwakeup(last->inp_socket);
  148                                 opts = 0;
  149                         }
  150                 }
  151                 last = inp;
  152         }
  153         if (last) {
  154                 if (last->inp_flags & INP_CONTROLOPTS ||
  155                     last->inp_socket->so_options & SO_TIMESTAMP)
  156                         ip_savecontrol(last, &opts, ip, m);
  157                 if (sbappendaddr(&last->inp_socket->so_rcv,
  158                     (struct sockaddr *)&ripsrc, m, opts) == 0) {
  159                         m_freem(m);
  160                         if (opts)
  161                             m_freem(opts);
  162                 } else
  163                         sorwakeup(last->inp_socket);
  164         } else {
  165                 m_freem(m);
  166               ipstat.ips_noproto++;
  167               ipstat.ips_delivered--;
  168       }
  169 }
  170 
  171 /*
  172  * Generate IP header and pass packet to ip_output.
  173  * Tack on options user may have setup with control call.
  174  */
  175 int
  176 rip_output(m, so, dst)
  177         register struct mbuf *m;
  178         struct socket *so;
  179         u_long dst;
  180 {
  181         register struct ip *ip;
  182         register struct inpcb *inp = sotoinpcb(so);
  183         int flags = (so->so_options & SO_DONTROUTE) | IP_ALLOWBROADCAST;
  184 
  185         /*
  186          * If the user handed us a complete IP packet, use it.
  187          * Otherwise, allocate an mbuf for a header and fill it in.
  188          */
  189         if ((inp->inp_flags & INP_HDRINCL) == 0) {
  190                 if (m->m_pkthdr.len + sizeof(struct ip) > IP_MAXPACKET) {
  191                         m_freem(m);
  192                         return(EMSGSIZE);
  193                 }
  194                 M_PREPEND(m, sizeof(struct ip), M_WAIT);
  195                 ip = mtod(m, struct ip *);
  196                 ip->ip_tos = 0;
  197                 ip->ip_off = 0;
  198                 ip->ip_p = inp->inp_ip_p;
  199                 ip->ip_len = m->m_pkthdr.len;
  200                 ip->ip_src = inp->inp_laddr;
  201                 ip->ip_dst.s_addr = dst;
  202                 ip->ip_ttl = MAXTTL;
  203         } else {
  204                 if (m->m_pkthdr.len > IP_MAXPACKET) {
  205                         m_freem(m);
  206                         return(EMSGSIZE);
  207                 }
  208                 ip = mtod(m, struct ip *);
  209                 /* don't allow both user specified and setsockopt options,
  210                    and don't allow packet length sizes that will crash */
  211                 if (((IP_VHL_HL(ip->ip_vhl) != (sizeof (*ip) >> 2)) 
  212                      && inp->inp_options)
  213                     || (ip->ip_len > m->m_pkthdr.len)
  214                     || (ip->ip_len < (IP_VHL_HL(ip->ip_vhl) << 2))) {
  215                         m_freem(m);
  216                         return EINVAL;
  217                 }
  218                 if (ip->ip_id == 0)
  219                         ip->ip_id = htons(ip_id++);
  220                 /* XXX prevent ip_output from overwriting header fields */
  221                 flags |= IP_RAWOUTPUT;
  222                 ipstat.ips_rawout++;
  223         }
  224         return (ip_output(m, inp->inp_options, &inp->inp_route, flags,
  225                           inp->inp_moptions));
  226 }
  227 
  228 /*
  229  * Raw IP socket option processing.
  230  */
  231 int
  232 rip_ctloutput(so, sopt)
  233         struct socket *so;
  234         struct sockopt *sopt;
  235 {
  236         struct  inpcb *inp = sotoinpcb(so);
  237         int     error, optval;
  238 
  239         if (sopt->sopt_level != IPPROTO_IP)
  240                 return (EINVAL);
  241 
  242         error = 0;
  243 
  244         switch (sopt->sopt_dir) {
  245         case SOPT_GET:
  246                 switch (sopt->sopt_name) {
  247                 case IP_HDRINCL:
  248                         optval = inp->inp_flags & INP_HDRINCL;
  249                         error = sooptcopyout(sopt, &optval, sizeof optval);
  250                         break;
  251 
  252 #ifdef COMPAT_IPFW
  253                 case IP_FW_GET:
  254                         if (ip_fw_ctl_ptr == 0)
  255                                 error = ENOPROTOOPT;
  256                         else
  257                                 error = ip_fw_ctl_ptr(sopt);
  258                         break;
  259 
  260 #ifdef DUMMYNET
  261                 case IP_DUMMYNET_GET:
  262                         if (ip_dn_ctl_ptr == NULL)
  263                                 error = ENOPROTOOPT ;
  264                         else
  265                                 error = ip_dn_ctl_ptr(sopt);
  266                         break ;
  267 #endif /* DUMMYNET */
  268 #endif /* COMPAT_IPFW */
  269 
  270                 case MRT_INIT:
  271                 case MRT_DONE:
  272                 case MRT_ADD_VIF:
  273                 case MRT_DEL_VIF:
  274                 case MRT_ADD_MFC:
  275                 case MRT_DEL_MFC:
  276                 case MRT_VERSION:
  277                 case MRT_ASSERT:
  278                         error = ip_mrouter_get(so, sopt);
  279                         break;
  280 
  281                 default:
  282                         error = ip_ctloutput(so, sopt);
  283                         break;
  284                 }
  285                 break;
  286 
  287         case SOPT_SET:
  288                 switch (sopt->sopt_name) {
  289                 case IP_HDRINCL:
  290                         error = sooptcopyin(sopt, &optval, sizeof optval,
  291                                             sizeof optval);
  292                         if (error)
  293                                 break;
  294                         if (optval)
  295                                 inp->inp_flags |= INP_HDRINCL;
  296                         else
  297                                 inp->inp_flags &= ~INP_HDRINCL;
  298                         break;
  299 
  300 #ifdef COMPAT_IPFW
  301                 case IP_FW_ADD:
  302                 case IP_FW_DEL:
  303                 case IP_FW_FLUSH:
  304                 case IP_FW_ZERO:
  305                 case IP_FW_RESETLOG:
  306                         if (ip_fw_ctl_ptr == 0)
  307                                 error = ENOPROTOOPT;
  308                         else
  309                                 error = ip_fw_ctl_ptr(sopt);
  310                         break;
  311 
  312 #ifdef DUMMYNET
  313                 case IP_DUMMYNET_CONFIGURE:
  314                 case IP_DUMMYNET_DEL:
  315                 case IP_DUMMYNET_FLUSH:
  316                         if (ip_dn_ctl_ptr == NULL)
  317                                 error = ENOPROTOOPT ;
  318                         else
  319                                 error = ip_dn_ctl_ptr(sopt);
  320                         break ;
  321 #endif
  322 #endif /* COMPAT_IPFW */
  323 
  324                 case IP_RSVP_ON:
  325                         error = ip_rsvp_init(so);
  326                         break;
  327 
  328                 case IP_RSVP_OFF:
  329                         error = ip_rsvp_done();
  330                         break;
  331 
  332                         /* XXX - should be combined */
  333                 case IP_RSVP_VIF_ON:
  334                         error = ip_rsvp_vif_init(so, sopt);
  335                         break;
  336                         
  337                 case IP_RSVP_VIF_OFF:
  338                         error = ip_rsvp_vif_done(so, sopt);
  339                         break;
  340 
  341                 case MRT_INIT:
  342                 case MRT_DONE:
  343                 case MRT_ADD_VIF:
  344                 case MRT_DEL_VIF:
  345                 case MRT_ADD_MFC:
  346                 case MRT_DEL_MFC:
  347                 case MRT_VERSION:
  348                 case MRT_ASSERT:
  349                         error = ip_mrouter_set(so, sopt);
  350                         break;
  351 
  352                 default:
  353                         error = ip_ctloutput(so, sopt);
  354                         break;
  355                 }
  356                 break;
  357         }
  358 
  359         return (error);
  360 }
  361 
  362 /*
  363  * This function exists solely to receive the PRC_IFDOWN messages which
  364  * are sent by if_down().  It looks for an ifaddr whose ifa_addr is sa,
  365  * and calls in_ifadown() to remove all routes corresponding to that address.
  366  * It also receives the PRC_IFUP messages from if_up() and reinstalls the
  367  * interface routes.
  368  */
  369 void
  370 rip_ctlinput(cmd, sa, vip)
  371         int cmd;
  372         struct sockaddr *sa;
  373         void *vip;
  374 {
  375         struct in_ifaddr *ia;
  376         struct ifnet *ifp;
  377         int err;
  378         int flags;
  379 
  380         switch (cmd) {
  381         case PRC_IFDOWN:
  382                 for (ia = in_ifaddrhead.tqh_first; ia;
  383                      ia = ia->ia_link.tqe_next) {
  384                         if (ia->ia_ifa.ifa_addr == sa
  385                             && (ia->ia_flags & IFA_ROUTE)) {
  386                                 /*
  387                                  * in_ifscrub kills the interface route.
  388                                  */
  389                                 in_ifscrub(ia->ia_ifp, ia);
  390                                 /*
  391                                  * in_ifadown gets rid of all the rest of
  392                                  * the routes.  This is not quite the right
  393                                  * thing to do, but at least if we are running
  394                                  * a routing process they will come back.
  395                                  */
  396                                 in_ifadown(&ia->ia_ifa);
  397                                 break;
  398                         }
  399                 }
  400                 break;
  401 
  402         case PRC_IFUP:
  403                 for (ia = in_ifaddrhead.tqh_first; ia;
  404                      ia = ia->ia_link.tqe_next) {
  405                         if (ia->ia_ifa.ifa_addr == sa)
  406                                 break;
  407                 }
  408                 if (ia == 0 || (ia->ia_flags & IFA_ROUTE))
  409                         return;
  410                 flags = RTF_UP;
  411                 ifp = ia->ia_ifa.ifa_ifp;
  412 
  413                 if ((ifp->if_flags & IFF_LOOPBACK)
  414                     || (ifp->if_flags & IFF_POINTOPOINT))
  415                         flags |= RTF_HOST;
  416 
  417                 err = rtinit(&ia->ia_ifa, RTM_ADD, flags);
  418                 if (err == 0)
  419                         ia->ia_flags |= IFA_ROUTE;
  420                 break;
  421         }
  422 }
  423 
  424 static u_long   rip_sendspace = RIPSNDQ;
  425 static u_long   rip_recvspace = RIPRCVQ;
  426 
  427 SYSCTL_INT(_net_inet_raw, OID_AUTO, maxdgram, CTLFLAG_RW, &rip_sendspace,
  428            0, "");
  429 SYSCTL_INT(_net_inet_raw, OID_AUTO, recvspace, CTLFLAG_RW, &rip_recvspace,
  430            0, "");
  431 
  432 static int
  433 rip_attach(struct socket *so, int proto, struct proc *p)
  434 {
  435         struct inpcb *inp;
  436         int error, s;
  437 
  438         inp = sotoinpcb(so);
  439         if (inp)
  440                 panic("rip_attach");
  441         if (p && (error = suser(p->p_ucred, &p->p_acflag)) != 0)
  442                 return error;
  443 
  444         s = splnet();
  445         error = in_pcballoc(so, &ripcbinfo, p);
  446         splx(s);
  447         if (error)
  448                 return error;
  449         error = soreserve(so, rip_sendspace, rip_recvspace);
  450         if (error)
  451                 return error;
  452         inp = (struct inpcb *)so->so_pcb;
  453         inp->inp_ip_p = proto;
  454         return 0;
  455 }
  456 
  457 static int
  458 rip_detach(struct socket *so)
  459 {
  460         struct inpcb *inp;
  461 
  462         inp = sotoinpcb(so);
  463         if (inp == 0)
  464                 panic("rip_detach");
  465         if (so == ip_mrouter)
  466                 ip_mrouter_done();
  467         ip_rsvp_force_done(so);
  468         if (so == ip_rsvpd)
  469                 ip_rsvp_done();
  470         in_pcbdetach(inp);
  471         return 0;
  472 }
  473 
  474 static int
  475 rip_abort(struct socket *so)
  476 {
  477         soisdisconnected(so);
  478         return rip_detach(so);
  479 }
  480 
  481 static int
  482 rip_disconnect(struct socket *so)
  483 {
  484         if ((so->so_state & SS_ISCONNECTED) == 0)
  485                 return ENOTCONN;
  486         return rip_abort(so);
  487 }
  488 
  489 static int
  490 rip_bind(struct socket *so, struct sockaddr *nam, struct proc *p)
  491 {
  492         struct inpcb *inp = sotoinpcb(so);
  493         struct sockaddr_in *addr = (struct sockaddr_in *)nam;
  494 
  495         if (nam->sa_len != sizeof(*addr))
  496                 return EINVAL;
  497 
  498         if (TAILQ_EMPTY(&ifnet) || ((addr->sin_family != AF_INET) &&
  499                                     (addr->sin_family != AF_IMPLINK)) ||
  500             (addr->sin_addr.s_addr &&
  501              ifa_ifwithaddr((struct sockaddr *)addr) == 0))
  502                 return EADDRNOTAVAIL;
  503         inp->inp_laddr = addr->sin_addr;
  504         return 0;
  505 }
  506 
  507 static int
  508 rip_connect(struct socket *so, struct sockaddr *nam, struct proc *p)
  509 {
  510         struct inpcb *inp = sotoinpcb(so);
  511         struct sockaddr_in *addr = (struct sockaddr_in *)nam;
  512 
  513         if (nam->sa_len != sizeof(*addr))
  514                 return EINVAL;
  515         if (TAILQ_EMPTY(&ifnet))
  516                 return EADDRNOTAVAIL;
  517         if ((addr->sin_family != AF_INET) &&
  518             (addr->sin_family != AF_IMPLINK))
  519                 return EAFNOSUPPORT;
  520         inp->inp_faddr = addr->sin_addr;
  521         soisconnected(so);
  522         return 0;
  523 }
  524 
  525 static int
  526 rip_shutdown(struct socket *so)
  527 {
  528         socantsendmore(so);
  529         return 0;
  530 }
  531 
  532 static int
  533 rip_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam,
  534          struct mbuf *control, struct proc *p)
  535 {
  536         struct inpcb *inp = sotoinpcb(so);
  537         register u_long dst;
  538 
  539         if (so->so_state & SS_ISCONNECTED) {
  540                 if (nam) {
  541                         m_freem(m);
  542                         return EISCONN;
  543                 }
  544                 dst = inp->inp_faddr.s_addr;
  545         } else {
  546                 if (nam == NULL) {
  547                         m_freem(m);
  548                         return ENOTCONN;
  549                 }
  550                 dst = ((struct sockaddr_in *)nam)->sin_addr.s_addr;
  551         }
  552         return rip_output(m, so, dst);
  553 }
  554 
  555 static int
  556 rip_pcblist SYSCTL_HANDLER_ARGS
  557 {
  558         int error, i, n, s;
  559         struct inpcb *inp, **inp_list;
  560         inp_gen_t gencnt;
  561         struct xinpgen xig;
  562 
  563         /*
  564          * The process of preparing the TCB list is too time-consuming and
  565          * resource-intensive to repeat twice on every request.
  566          */
  567         if (req->oldptr == 0) {
  568                 n = ripcbinfo.ipi_count;
  569                 req->oldidx = 2 * (sizeof xig)
  570                         + (n + n/8) * sizeof(struct xinpcb);
  571                 return 0;
  572         }
  573 
  574         if (req->newptr != 0)
  575                 return EPERM;
  576 
  577         /*
  578          * OK, now we're committed to doing something.
  579          */
  580         s = splnet();
  581         gencnt = ripcbinfo.ipi_gencnt;
  582         n = ripcbinfo.ipi_count;
  583         splx(s);
  584 
  585         xig.xig_len = sizeof xig;
  586         xig.xig_count = n;
  587         xig.xig_gen = gencnt;
  588         xig.xig_sogen = so_gencnt;
  589         error = SYSCTL_OUT(req, &xig, sizeof xig);
  590         if (error)
  591                 return error;
  592 
  593         inp_list = malloc(n * sizeof *inp_list, M_TEMP, M_WAITOK);
  594         if (inp_list == 0)
  595                 return ENOMEM;
  596         
  597         s = splnet();
  598         for (inp = ripcbinfo.listhead->lh_first, i = 0; inp && i < n;
  599              inp = inp->inp_list.le_next) {
  600                 if (inp->inp_gencnt <= gencnt)
  601                         inp_list[i++] = inp;
  602         }
  603         splx(s);
  604         n = i;
  605 
  606         error = 0;
  607         for (i = 0; i < n; i++) {
  608                 inp = inp_list[i];
  609                 if (inp->inp_gencnt <= gencnt) {
  610                         struct xinpcb xi;
  611                         xi.xi_len = sizeof xi;
  612                         /* XXX should avoid extra copy */
  613                         bcopy(inp, &xi.xi_inp, sizeof *inp);
  614                         if (inp->inp_socket)
  615                                 sotoxsocket(inp->inp_socket, &xi.xi_socket);
  616                         error = SYSCTL_OUT(req, &xi, sizeof xi);
  617                 }
  618         }
  619         if (!error) {
  620                 /*
  621                  * Give the user an updated idea of our state.
  622                  * If the generation differs from what we told
  623                  * her before, she knows that something happened
  624                  * while we were processing this request, and it
  625                  * might be necessary to retry.
  626                  */
  627                 s = splnet();
  628                 xig.xig_gen = ripcbinfo.ipi_gencnt;
  629                 xig.xig_sogen = so_gencnt;
  630                 xig.xig_count = ripcbinfo.ipi_count;
  631                 splx(s);
  632                 error = SYSCTL_OUT(req, &xig, sizeof xig);
  633         }
  634         free(inp_list, M_TEMP);
  635         return error;
  636 }
  637 
  638 SYSCTL_PROC(_net_inet_raw, OID_AUTO/*XXX*/, pcblist, CTLFLAG_RD, 0, 0,
  639             rip_pcblist, "S,xinpcb", "List of active raw IP sockets");
  640 
  641 struct pr_usrreqs rip_usrreqs = {
  642         rip_abort, pru_accept_notsupp, rip_attach, rip_bind, rip_connect,
  643         pru_connect2_notsupp, in_control, rip_detach, rip_disconnect,
  644         pru_listen_notsupp, in_setpeeraddr, pru_rcvd_notsupp,
  645         pru_rcvoob_notsupp, rip_send, pru_sense_null, rip_shutdown, 
  646         in_setsockaddr, sosend, soreceive, sopoll
  647 };

Cache object: 0c81b49c7208b964c82653bd168ffbe5


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.