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/in_pcb.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, 1991, 1993, 1995
    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  *      @(#)in_pcb.c    8.4 (Berkeley) 5/24/95
   34  * $FreeBSD: releng/5.0/sys/netinet/in_pcb.c 106681 2002-11-08 23:50:32Z sam $
   35  */
   36 
   37 #include "opt_ipsec.h"
   38 #include "opt_inet6.h"
   39 
   40 #include <sys/param.h>
   41 #include <sys/systm.h>
   42 #include <sys/malloc.h>
   43 #include <sys/mbuf.h>
   44 #include <sys/domain.h>
   45 #include <sys/protosw.h>
   46 #include <sys/socket.h>
   47 #include <sys/socketvar.h>
   48 #include <sys/proc.h>
   49 #include <sys/jail.h>
   50 #include <sys/kernel.h>
   51 #include <sys/sysctl.h>
   52 
   53 #include <machine/limits.h>
   54 
   55 #include <vm/uma.h>
   56 
   57 #include <net/if.h>
   58 #include <net/if_types.h>
   59 #include <net/route.h>
   60 
   61 #include <netinet/in.h>
   62 #include <netinet/in_pcb.h>
   63 #include <netinet/in_var.h>
   64 #include <netinet/ip_var.h>
   65 #ifdef INET6
   66 #include <netinet/ip6.h>
   67 #include <netinet6/ip6_var.h>
   68 #endif /* INET6 */
   69 
   70 #ifdef IPSEC
   71 #include <netinet6/ipsec.h>
   72 #include <netkey/key.h>
   73 #endif /* IPSEC */
   74 
   75 #ifdef FAST_IPSEC
   76 #if defined(IPSEC) || defined(IPSEC_ESP)
   77 #error "Bad idea: don't compile with both IPSEC and FAST_IPSEC!"
   78 #endif
   79 #if defined(INET6)
   80 #error "Bad idea: don't use IPv6 with FAST_IPSEC (for the moment)!"
   81 #endif
   82 
   83 #include <netipsec/ipsec.h>
   84 #include <netipsec/key.h>
   85 #define IPSEC
   86 #endif /* FAST_IPSEC */
   87 
   88 struct  in_addr zeroin_addr;
   89 
   90 /*
   91  * These configure the range of local port addresses assigned to
   92  * "unspecified" outgoing connections/packets/whatever.
   93  */
   94 int     ipport_lowfirstauto  = IPPORT_RESERVED - 1;     /* 1023 */
   95 int     ipport_lowlastauto = IPPORT_RESERVEDSTART;      /* 600 */
   96 int     ipport_firstauto = IPPORT_HIFIRSTAUTO;          /* 49152 */
   97 int     ipport_lastauto  = IPPORT_HILASTAUTO;           /* 65535 */
   98 int     ipport_hifirstauto = IPPORT_HIFIRSTAUTO;        /* 49152 */
   99 int     ipport_hilastauto  = IPPORT_HILASTAUTO;         /* 65535 */
  100 
  101 #define RANGECHK(var, min, max) \
  102         if ((var) < (min)) { (var) = (min); } \
  103         else if ((var) > (max)) { (var) = (max); }
  104 
  105 static int
  106 sysctl_net_ipport_check(SYSCTL_HANDLER_ARGS)
  107 {
  108         int error = sysctl_handle_int(oidp,
  109                 oidp->oid_arg1, oidp->oid_arg2, req);
  110         if (!error) {
  111                 RANGECHK(ipport_lowfirstauto, 1, IPPORT_RESERVED - 1);
  112                 RANGECHK(ipport_lowlastauto, 1, IPPORT_RESERVED - 1);
  113                 RANGECHK(ipport_firstauto, IPPORT_RESERVED, USHRT_MAX);
  114                 RANGECHK(ipport_lastauto, IPPORT_RESERVED, USHRT_MAX);
  115                 RANGECHK(ipport_hifirstauto, IPPORT_RESERVED, USHRT_MAX);
  116                 RANGECHK(ipport_hilastauto, IPPORT_RESERVED, USHRT_MAX);
  117         }
  118         return error;
  119 }
  120 
  121 #undef RANGECHK
  122 
  123 SYSCTL_NODE(_net_inet_ip, IPPROTO_IP, portrange, CTLFLAG_RW, 0, "IP Ports");
  124 
  125 SYSCTL_PROC(_net_inet_ip_portrange, OID_AUTO, lowfirst, CTLTYPE_INT|CTLFLAG_RW,
  126            &ipport_lowfirstauto, 0, &sysctl_net_ipport_check, "I", "");
  127 SYSCTL_PROC(_net_inet_ip_portrange, OID_AUTO, lowlast, CTLTYPE_INT|CTLFLAG_RW,
  128            &ipport_lowlastauto, 0, &sysctl_net_ipport_check, "I", "");
  129 SYSCTL_PROC(_net_inet_ip_portrange, OID_AUTO, first, CTLTYPE_INT|CTLFLAG_RW,
  130            &ipport_firstauto, 0, &sysctl_net_ipport_check, "I", "");
  131 SYSCTL_PROC(_net_inet_ip_portrange, OID_AUTO, last, CTLTYPE_INT|CTLFLAG_RW,
  132            &ipport_lastauto, 0, &sysctl_net_ipport_check, "I", "");
  133 SYSCTL_PROC(_net_inet_ip_portrange, OID_AUTO, hifirst, CTLTYPE_INT|CTLFLAG_RW,
  134            &ipport_hifirstauto, 0, &sysctl_net_ipport_check, "I", "");
  135 SYSCTL_PROC(_net_inet_ip_portrange, OID_AUTO, hilast, CTLTYPE_INT|CTLFLAG_RW,
  136            &ipport_hilastauto, 0, &sysctl_net_ipport_check, "I", "");
  137 
  138 /*
  139  * in_pcb.c: manage the Protocol Control Blocks.
  140  *
  141  * NOTE: It is assumed that most of these functions will be called at
  142  * splnet(). XXX - There are, unfortunately, a few exceptions to this
  143  * rule that should be fixed.
  144  */
  145 
  146 /*
  147  * Allocate a PCB and associate it with the socket.
  148  */
  149 int
  150 in_pcballoc(so, pcbinfo, td)
  151         struct socket *so;
  152         struct inpcbinfo *pcbinfo;
  153         struct thread *td;
  154 {
  155         register struct inpcb *inp;
  156 #ifdef IPSEC
  157         int error;
  158 #endif
  159 
  160         inp = uma_zalloc(pcbinfo->ipi_zone, M_NOWAIT);
  161         if (inp == NULL)
  162                 return (ENOBUFS);
  163         bzero((caddr_t)inp, sizeof(*inp));
  164         inp->inp_gencnt = ++pcbinfo->ipi_gencnt;
  165         inp->inp_pcbinfo = pcbinfo;
  166         inp->inp_socket = so;
  167 #ifdef IPSEC
  168         error = ipsec_init_policy(so, &inp->inp_sp);
  169         if (error != 0) {
  170                 uma_zfree(pcbinfo->ipi_zone, inp);
  171                 return error;
  172         }
  173 #endif /*IPSEC*/
  174 #if defined(INET6)
  175         if (INP_SOCKAF(so) == AF_INET6 && ip6_v6only)
  176                 inp->inp_flags |= IN6P_IPV6_V6ONLY;
  177 #endif
  178         LIST_INSERT_HEAD(pcbinfo->listhead, inp, inp_list);
  179         pcbinfo->ipi_count++;
  180         so->so_pcb = (caddr_t)inp;
  181         INP_LOCK_INIT(inp, "inp");
  182 #ifdef INET6
  183         if (ip6_auto_flowlabel)
  184                 inp->inp_flags |= IN6P_AUTOFLOWLABEL;
  185 #endif
  186         return (0);
  187 }
  188 
  189 int
  190 in_pcbbind(inp, nam, td)
  191         register struct inpcb *inp;
  192         struct sockaddr *nam;
  193         struct thread *td;
  194 {
  195         int anonport, error;
  196 
  197         if (inp->inp_lport != 0 || inp->inp_laddr.s_addr != INADDR_ANY)
  198                 return (EINVAL);
  199         anonport = inp->inp_lport == 0 && (nam == NULL ||
  200             ((struct sockaddr_in *)nam)->sin_port == 0);
  201         error = in_pcbbind_setup(inp, nam, &inp->inp_laddr.s_addr,
  202             &inp->inp_lport, td);
  203         if (error)
  204                 return (error);
  205         if (in_pcbinshash(inp) != 0) {
  206                 inp->inp_laddr.s_addr = INADDR_ANY;
  207                 inp->inp_lport = 0;
  208                 return (EAGAIN);
  209         }
  210         if (anonport)
  211                 inp->inp_flags |= INP_ANONPORT;
  212         return (0);
  213 }
  214 
  215 /*
  216  * Set up a bind operation on a PCB, performing port allocation
  217  * as required, but do not actually modify the PCB. Callers can
  218  * either complete the bind by setting inp_laddr/inp_lport and
  219  * calling in_pcbinshash(), or they can just use the resulting
  220  * port and address to authorise the sending of a once-off packet.
  221  *
  222  * On error, the values of *laddrp and *lportp are not changed.
  223  */
  224 int
  225 in_pcbbind_setup(inp, nam, laddrp, lportp, td)
  226         struct inpcb *inp;
  227         struct sockaddr *nam;
  228         in_addr_t *laddrp;
  229         u_short *lportp;
  230         struct thread *td;
  231 {
  232         struct socket *so = inp->inp_socket;
  233         unsigned short *lastport;
  234         struct sockaddr_in *sin;
  235         struct inpcbinfo *pcbinfo = inp->inp_pcbinfo;
  236         struct in_addr laddr;
  237         u_short lport = 0;
  238         int wild = 0, reuseport = (so->so_options & SO_REUSEPORT);
  239         int error, prison = 0;
  240 
  241         if (TAILQ_EMPTY(&in_ifaddrhead)) /* XXX broken! */
  242                 return (EADDRNOTAVAIL);
  243         laddr.s_addr = *laddrp;
  244         if (nam != NULL && laddr.s_addr != INADDR_ANY)
  245                 return (EINVAL);
  246         if ((so->so_options & (SO_REUSEADDR|SO_REUSEPORT)) == 0)
  247                 wild = 1;
  248         if (nam) {
  249                 sin = (struct sockaddr_in *)nam;
  250                 if (nam->sa_len != sizeof (*sin))
  251                         return (EINVAL);
  252 #ifdef notdef
  253                 /*
  254                  * We should check the family, but old programs
  255                  * incorrectly fail to initialize it.
  256                  */
  257                 if (sin->sin_family != AF_INET)
  258                         return (EAFNOSUPPORT);
  259 #endif
  260                 if (sin->sin_addr.s_addr != INADDR_ANY)
  261                         if (prison_ip(td->td_ucred, 0, &sin->sin_addr.s_addr))
  262                                 return(EINVAL);
  263                 if (sin->sin_port != *lportp) {
  264                         /* Don't allow the port to change. */
  265                         if (*lportp != 0)
  266                                 return (EINVAL);
  267                         lport = sin->sin_port;
  268                 }
  269                 /* NB: lport is left as 0 if the port isn't being changed. */
  270                 if (IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) {
  271                         /*
  272                          * Treat SO_REUSEADDR as SO_REUSEPORT for multicast;
  273                          * allow complete duplication of binding if
  274                          * SO_REUSEPORT is set, or if SO_REUSEADDR is set
  275                          * and a multicast address is bound on both
  276                          * new and duplicated sockets.
  277                          */
  278                         if (so->so_options & SO_REUSEADDR)
  279                                 reuseport = SO_REUSEADDR|SO_REUSEPORT;
  280                 } else if (sin->sin_addr.s_addr != INADDR_ANY) {
  281                         sin->sin_port = 0;              /* yech... */
  282                         bzero(&sin->sin_zero, sizeof(sin->sin_zero));
  283                         if (ifa_ifwithaddr((struct sockaddr *)sin) == 0)
  284                                 return (EADDRNOTAVAIL);
  285                 }
  286                 laddr = sin->sin_addr;
  287                 if (lport) {
  288                         struct inpcb *t;
  289                         /* GROSS */
  290                         if (ntohs(lport) < IPPORT_RESERVED && td &&
  291                             suser_cred(td->td_ucred, PRISON_ROOT))
  292                                 return (EACCES);
  293                         if (td && jailed(td->td_ucred))
  294                                 prison = 1;
  295                         if (so->so_cred->cr_uid != 0 &&
  296                             !IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) {
  297                                 t = in_pcblookup_local(inp->inp_pcbinfo,
  298                                     sin->sin_addr, lport,
  299                                     prison ? 0 :  INPLOOKUP_WILDCARD);
  300                                 if (t &&
  301                                     (ntohl(sin->sin_addr.s_addr) != INADDR_ANY ||
  302                                      ntohl(t->inp_laddr.s_addr) != INADDR_ANY ||
  303                                      (t->inp_socket->so_options &
  304                                          SO_REUSEPORT) == 0) &&
  305                                     (so->so_cred->cr_uid !=
  306                                      t->inp_socket->so_cred->cr_uid)) {
  307 #if defined(INET6)
  308                                         if (ntohl(sin->sin_addr.s_addr) !=
  309                                             INADDR_ANY ||
  310                                             ntohl(t->inp_laddr.s_addr) !=
  311                                             INADDR_ANY ||
  312                                             INP_SOCKAF(so) ==
  313                                             INP_SOCKAF(t->inp_socket))
  314 #endif /* defined(INET6) */
  315                                         return (EADDRINUSE);
  316                                 }
  317                         }
  318                         if (prison &&
  319                             prison_ip(td->td_ucred, 0, &sin->sin_addr.s_addr))
  320                                 return (EADDRNOTAVAIL);
  321                         t = in_pcblookup_local(pcbinfo, sin->sin_addr,
  322                             lport, prison ? 0 : wild);
  323                         if (t &&
  324                             (reuseport & t->inp_socket->so_options) == 0) {
  325 #if defined(INET6)
  326                                 if (ntohl(sin->sin_addr.s_addr) !=
  327                                     INADDR_ANY ||
  328                                     ntohl(t->inp_laddr.s_addr) !=
  329                                     INADDR_ANY ||
  330                                     INP_SOCKAF(so) ==
  331                                     INP_SOCKAF(t->inp_socket))
  332 #endif /* defined(INET6) */
  333                                 return (EADDRINUSE);
  334                         }
  335                 }
  336         }
  337         if (*lportp != 0)
  338                 lport = *lportp;
  339         if (lport == 0) {
  340                 ushort first, last;
  341                 int count;
  342 
  343                 if (laddr.s_addr != INADDR_ANY)
  344                         if (prison_ip(td->td_ucred, 0, &laddr.s_addr))
  345                                 return (EINVAL);
  346 
  347                 if (inp->inp_flags & INP_HIGHPORT) {
  348                         first = ipport_hifirstauto;     /* sysctl */
  349                         last  = ipport_hilastauto;
  350                         lastport = &pcbinfo->lasthi;
  351                 } else if (inp->inp_flags & INP_LOWPORT) {
  352                         if (td && (error = suser_cred(td->td_ucred,
  353                             PRISON_ROOT)) != 0)
  354                                 return error;
  355                         first = ipport_lowfirstauto;    /* 1023 */
  356                         last  = ipport_lowlastauto;     /* 600 */
  357                         lastport = &pcbinfo->lastlow;
  358                 } else {
  359                         first = ipport_firstauto;       /* sysctl */
  360                         last  = ipport_lastauto;
  361                         lastport = &pcbinfo->lastport;
  362                 }
  363                 /*
  364                  * Simple check to ensure all ports are not used up causing
  365                  * a deadlock here.
  366                  *
  367                  * We split the two cases (up and down) so that the direction
  368                  * is not being tested on each round of the loop.
  369                  */
  370                 if (first > last) {
  371                         /*
  372                          * counting down
  373                          */
  374                         count = first - last;
  375 
  376                         do {
  377                                 if (count-- < 0)        /* completely used? */
  378                                         return (EADDRNOTAVAIL);
  379                                 --*lastport;
  380                                 if (*lastport > first || *lastport < last)
  381                                         *lastport = first;
  382                                 lport = htons(*lastport);
  383                         } while (in_pcblookup_local(pcbinfo, laddr, lport,
  384                             wild));
  385                 } else {
  386                         /*
  387                          * counting up
  388                          */
  389                         count = last - first;
  390 
  391                         do {
  392                                 if (count-- < 0)        /* completely used? */
  393                                         return (EADDRNOTAVAIL);
  394                                 ++*lastport;
  395                                 if (*lastport < first || *lastport > last)
  396                                         *lastport = first;
  397                                 lport = htons(*lastport);
  398                         } while (in_pcblookup_local(pcbinfo, laddr, lport,
  399                             wild));
  400                 }
  401         }
  402         if (prison_ip(td->td_ucred, 0, &laddr.s_addr))
  403                 return (EINVAL);
  404         *laddrp = laddr.s_addr;
  405         *lportp = lport;
  406         return (0);
  407 }
  408 
  409 /*
  410  * Connect from a socket to a specified address.
  411  * Both address and port must be specified in argument sin.
  412  * If don't have a local address for this socket yet,
  413  * then pick one.
  414  */
  415 int
  416 in_pcbconnect(inp, nam, td)
  417         register struct inpcb *inp;
  418         struct sockaddr *nam;
  419         struct thread *td;
  420 {
  421         u_short lport, fport;
  422         in_addr_t laddr, faddr;
  423         int anonport, error;
  424 
  425         lport = inp->inp_lport;
  426         laddr = inp->inp_laddr.s_addr;
  427         anonport = (lport == 0);
  428         error = in_pcbconnect_setup(inp, nam, &laddr, &lport, &faddr, &fport,
  429             NULL, td);
  430         if (error)
  431                 return (error);
  432 
  433         /* Do the initial binding of the local address if required. */
  434         if (inp->inp_laddr.s_addr == INADDR_ANY && inp->inp_lport == 0) {
  435                 inp->inp_lport = lport;
  436                 inp->inp_laddr.s_addr = laddr;
  437                 if (in_pcbinshash(inp) != 0) {
  438                         inp->inp_laddr.s_addr = INADDR_ANY;
  439                         inp->inp_lport = 0;
  440                         return (EAGAIN);
  441                 }
  442         }
  443 
  444         /* Commit the remaining changes. */
  445         inp->inp_lport = lport;
  446         inp->inp_laddr.s_addr = laddr;
  447         inp->inp_faddr.s_addr = faddr;
  448         inp->inp_fport = fport;
  449         in_pcbrehash(inp);
  450         if (anonport)
  451                 inp->inp_flags |= INP_ANONPORT;
  452         return (0);
  453 }
  454 
  455 /*
  456  * Set up for a connect from a socket to the specified address.
  457  * On entry, *laddrp and *lportp should contain the current local
  458  * address and port for the PCB; these are updated to the values
  459  * that should be placed in inp_laddr and inp_lport to complete
  460  * the connect.
  461  *
  462  * On success, *faddrp and *fportp will be set to the remote address
  463  * and port. These are not updated in the error case.
  464  *
  465  * If the operation fails because the connection already exists,
  466  * *oinpp will be set to the PCB of that connection so that the
  467  * caller can decide to override it. In all other cases, *oinpp
  468  * is set to NULL.
  469  */
  470 int
  471 in_pcbconnect_setup(inp, nam, laddrp, lportp, faddrp, fportp, oinpp, td)
  472         register struct inpcb *inp;
  473         struct sockaddr *nam;
  474         in_addr_t *laddrp;
  475         u_short *lportp;
  476         in_addr_t *faddrp;
  477         u_short *fportp;
  478         struct inpcb **oinpp;
  479         struct thread *td;
  480 {
  481         struct sockaddr_in *sin = (struct sockaddr_in *)nam;
  482         struct in_ifaddr *ia;
  483         struct sockaddr_in sa;
  484         struct ucred *cred;
  485         struct inpcb *oinp;
  486         struct in_addr laddr, faddr;
  487         u_short lport, fport;
  488         int error;
  489 
  490         if (oinpp != NULL)
  491                 *oinpp = NULL;
  492         if (nam->sa_len != sizeof (*sin))
  493                 return (EINVAL);
  494         if (sin->sin_family != AF_INET)
  495                 return (EAFNOSUPPORT);
  496         if (sin->sin_port == 0)
  497                 return (EADDRNOTAVAIL);
  498         laddr.s_addr = *laddrp;
  499         lport = *lportp;
  500         faddr = sin->sin_addr;
  501         fport = sin->sin_port;
  502         cred = inp->inp_socket->so_cred;
  503         if (laddr.s_addr == INADDR_ANY && jailed(cred)) {
  504                 bzero(&sa, sizeof(sa));
  505                 sa.sin_addr.s_addr = htonl(prison_getip(cred));
  506                 sa.sin_len = sizeof(sa);
  507                 sa.sin_family = AF_INET;
  508                 error = in_pcbbind_setup(inp, (struct sockaddr *)&sa,
  509                     &laddr.s_addr, &lport, td);
  510                 if (error)
  511                         return (error);
  512         }
  513 
  514         if (!TAILQ_EMPTY(&in_ifaddrhead)) {
  515                 /*
  516                  * If the destination address is INADDR_ANY,
  517                  * use the primary local address.
  518                  * If the supplied address is INADDR_BROADCAST,
  519                  * and the primary interface supports broadcast,
  520                  * choose the broadcast address for that interface.
  521                  */
  522                 if (faddr.s_addr == INADDR_ANY)
  523                         faddr = IA_SIN(TAILQ_FIRST(&in_ifaddrhead))->sin_addr;
  524                 else if (faddr.s_addr == (u_long)INADDR_BROADCAST &&
  525                     (TAILQ_FIRST(&in_ifaddrhead)->ia_ifp->if_flags &
  526                     IFF_BROADCAST))
  527                         faddr = satosin(&TAILQ_FIRST(
  528                             &in_ifaddrhead)->ia_broadaddr)->sin_addr;
  529         }
  530         if (laddr.s_addr == INADDR_ANY) {
  531                 register struct route *ro;
  532 
  533                 ia = (struct in_ifaddr *)0;
  534                 /*
  535                  * If route is known or can be allocated now,
  536                  * our src addr is taken from the i/f, else punt.
  537                  * Note that we should check the address family of the cached
  538                  * destination, in case of sharing the cache with IPv6.
  539                  */
  540                 ro = &inp->inp_route;
  541                 if (ro->ro_rt &&
  542                     (ro->ro_dst.sa_family != AF_INET ||
  543                      satosin(&ro->ro_dst)->sin_addr.s_addr != faddr.s_addr ||
  544                      inp->inp_socket->so_options & SO_DONTROUTE)) {
  545                         RTFREE(ro->ro_rt);
  546                         ro->ro_rt = (struct rtentry *)0;
  547                 }
  548                 if ((inp->inp_socket->so_options & SO_DONTROUTE) == 0 && /*XXX*/
  549                     (ro->ro_rt == (struct rtentry *)0 ||
  550                     ro->ro_rt->rt_ifp == (struct ifnet *)0)) {
  551                         /* No route yet, so try to acquire one */
  552                         bzero(&ro->ro_dst, sizeof(struct sockaddr_in));
  553                         ro->ro_dst.sa_family = AF_INET;
  554                         ro->ro_dst.sa_len = sizeof(struct sockaddr_in);
  555                         ((struct sockaddr_in *)&ro->ro_dst)->sin_addr = faddr;
  556                         rtalloc(ro);
  557                 }
  558                 /*
  559                  * If we found a route, use the address
  560                  * corresponding to the outgoing interface
  561                  * unless it is the loopback (in case a route
  562                  * to our address on another net goes to loopback).
  563                  */
  564                 if (ro->ro_rt && !(ro->ro_rt->rt_ifp->if_flags & IFF_LOOPBACK))
  565                         ia = ifatoia(ro->ro_rt->rt_ifa);
  566                 if (ia == 0) {
  567                         bzero(&sa, sizeof(sa));
  568                         sa.sin_addr = faddr;
  569                         sa.sin_len = sizeof(sa);
  570                         sa.sin_family = AF_INET;
  571 
  572                         ia = ifatoia(ifa_ifwithdstaddr(sintosa(&sa)));
  573                         if (ia == 0)
  574                                 ia = ifatoia(ifa_ifwithnet(sintosa(&sa)));
  575                         if (ia == 0)
  576                                 ia = TAILQ_FIRST(&in_ifaddrhead);
  577                         if (ia == 0)
  578                                 return (EADDRNOTAVAIL);
  579                 }
  580                 /*
  581                  * If the destination address is multicast and an outgoing
  582                  * interface has been set as a multicast option, use the
  583                  * address of that interface as our source address.
  584                  */
  585                 if (IN_MULTICAST(ntohl(faddr.s_addr)) &&
  586                     inp->inp_moptions != NULL) {
  587                         struct ip_moptions *imo;
  588                         struct ifnet *ifp;
  589 
  590                         imo = inp->inp_moptions;
  591                         if (imo->imo_multicast_ifp != NULL) {
  592                                 ifp = imo->imo_multicast_ifp;
  593                                 TAILQ_FOREACH(ia, &in_ifaddrhead, ia_link)
  594                                         if (ia->ia_ifp == ifp)
  595                                                 break;
  596                                 if (ia == 0)
  597                                         return (EADDRNOTAVAIL);
  598                         }
  599                 }
  600                 laddr = ia->ia_addr.sin_addr;
  601         }
  602 
  603         oinp = in_pcblookup_hash(inp->inp_pcbinfo, faddr, fport, laddr, lport,
  604             0, NULL);
  605         if (oinp != NULL) {
  606                 if (oinpp != NULL)
  607                         *oinpp = oinp;
  608                 return (EADDRINUSE);
  609         }
  610         if (lport == 0) {
  611                 error = in_pcbbind_setup(inp, NULL, &laddr.s_addr, &lport, td);
  612                 if (error)
  613                         return (error);
  614         }
  615         *laddrp = laddr.s_addr;
  616         *lportp = lport;
  617         *faddrp = faddr.s_addr;
  618         *fportp = fport;
  619         return (0);
  620 }
  621 
  622 void
  623 in_pcbdisconnect(inp)
  624         struct inpcb *inp;
  625 {
  626 
  627         inp->inp_faddr.s_addr = INADDR_ANY;
  628         inp->inp_fport = 0;
  629         in_pcbrehash(inp);
  630         if (inp->inp_socket->so_state & SS_NOFDREF)
  631                 in_pcbdetach(inp);
  632 }
  633 
  634 void
  635 in_pcbdetach(inp)
  636         struct inpcb *inp;
  637 {
  638         struct socket *so = inp->inp_socket;
  639         struct inpcbinfo *ipi = inp->inp_pcbinfo;
  640 
  641 #ifdef IPSEC
  642         ipsec4_delete_pcbpolicy(inp);
  643 #endif /*IPSEC*/
  644         inp->inp_gencnt = ++ipi->ipi_gencnt;
  645         in_pcbremlists(inp);
  646         so->so_pcb = 0;
  647         sotryfree(so);
  648         if (inp->inp_options)
  649                 (void)m_free(inp->inp_options);
  650         if (inp->inp_route.ro_rt)
  651                 rtfree(inp->inp_route.ro_rt);
  652         ip_freemoptions(inp->inp_moptions);
  653         inp->inp_vflag = 0;
  654         INP_LOCK_DESTROY(inp);
  655         uma_zfree(ipi->ipi_zone, inp);
  656 }
  657 
  658 struct sockaddr *
  659 in_sockaddr(port, addr_p)
  660         in_port_t port;
  661         struct in_addr *addr_p;
  662 {
  663         struct sockaddr_in *sin;
  664 
  665         MALLOC(sin, struct sockaddr_in *, sizeof *sin, M_SONAME,
  666                 M_WAITOK | M_ZERO);
  667         sin->sin_family = AF_INET;
  668         sin->sin_len = sizeof(*sin);
  669         sin->sin_addr = *addr_p;
  670         sin->sin_port = port;
  671 
  672         return (struct sockaddr *)sin;
  673 }
  674 
  675 /*
  676  * The wrapper function will pass down the pcbinfo for this function to lock.
  677  * The socket must have a valid
  678  * (i.e., non-nil) PCB, but it should be impossible to get an invalid one
  679  * except through a kernel programming error, so it is acceptable to panic
  680  * (or in this case trap) if the PCB is invalid.  (Actually, we don't trap
  681  * because there actually /is/ a programming error somewhere... XXX)
  682  */
  683 int
  684 in_setsockaddr(so, nam, pcbinfo)
  685         struct socket *so;
  686         struct sockaddr **nam;
  687         struct inpcbinfo *pcbinfo;
  688 {
  689         int s;
  690         register struct inpcb *inp;
  691         struct in_addr addr;
  692         in_port_t port;
  693 
  694         s = splnet();
  695         INP_INFO_RLOCK(pcbinfo);
  696         inp = sotoinpcb(so);
  697         if (!inp) {
  698                 INP_INFO_RUNLOCK(pcbinfo);
  699                 splx(s);
  700                 return ECONNRESET;
  701         }
  702         INP_LOCK(inp);
  703         port = inp->inp_lport;
  704         addr = inp->inp_laddr;
  705         INP_UNLOCK(inp);
  706         INP_INFO_RUNLOCK(pcbinfo);
  707         splx(s);
  708 
  709         *nam = in_sockaddr(port, &addr);
  710         return 0;
  711 }
  712 
  713 /*
  714  * The wrapper function will pass down the pcbinfo for this function to lock.
  715  */
  716 int
  717 in_setpeeraddr(so, nam, pcbinfo)
  718         struct socket *so;
  719         struct sockaddr **nam;
  720         struct inpcbinfo *pcbinfo;
  721 {
  722         int s;
  723         register struct inpcb *inp;
  724         struct in_addr addr;
  725         in_port_t port;
  726 
  727         s = splnet();
  728         INP_INFO_RLOCK(pcbinfo);
  729         inp = sotoinpcb(so);
  730         if (!inp) {
  731                 INP_INFO_RUNLOCK(pcbinfo);
  732                 splx(s);
  733                 return ECONNRESET;
  734         }
  735         INP_LOCK(inp);
  736         port = inp->inp_fport;
  737         addr = inp->inp_faddr;
  738         INP_UNLOCK(inp);
  739         INP_INFO_RUNLOCK(pcbinfo);
  740         splx(s);
  741 
  742         *nam = in_sockaddr(port, &addr);
  743         return 0;
  744 }
  745 
  746 void
  747 in_pcbnotifyall(pcbinfo, faddr, errno, notify)
  748         struct inpcbinfo *pcbinfo;
  749         struct in_addr faddr;
  750         int errno;
  751         struct inpcb *(*notify)(struct inpcb *, int);
  752 {
  753         struct inpcb *inp, *ninp;
  754         struct inpcbhead *head;
  755         int s;
  756 
  757         s = splnet();
  758         INP_INFO_RLOCK(pcbinfo);
  759         head = pcbinfo->listhead;
  760         for (inp = LIST_FIRST(head); inp != NULL; inp = ninp) {
  761                 INP_LOCK(inp);
  762                 ninp = LIST_NEXT(inp, inp_list);
  763 #ifdef INET6
  764                 if ((inp->inp_vflag & INP_IPV4) == 0) {
  765                         INP_UNLOCK(inp);                
  766                         continue;
  767                 }
  768 #endif
  769                 if (inp->inp_faddr.s_addr != faddr.s_addr ||
  770                     inp->inp_socket == NULL) {
  771                                 INP_UNLOCK(inp);                
  772                                 continue;
  773                 }
  774                 (*notify)(inp, errno);
  775                 INP_UNLOCK(inp);                
  776         }
  777         INP_INFO_RUNLOCK(pcbinfo);
  778         splx(s);
  779 }
  780 
  781 void
  782 in_pcbpurgeif0(pcbinfo, ifp)
  783         struct inpcbinfo *pcbinfo;
  784         struct ifnet *ifp;
  785 {
  786         struct inpcb *inp;
  787         struct ip_moptions *imo;
  788         int i, gap;
  789 
  790         /* why no splnet here? XXX */
  791         INP_INFO_RLOCK(pcbinfo);
  792         LIST_FOREACH(inp, pcbinfo->listhead, inp_list) {
  793                 INP_LOCK(inp);
  794                 imo = inp->inp_moptions;
  795                 if ((inp->inp_vflag & INP_IPV4) &&
  796                     imo != NULL) {
  797                         /*
  798                          * Unselect the outgoing interface if it is being
  799                          * detached.
  800                          */
  801                         if (imo->imo_multicast_ifp == ifp)
  802                                 imo->imo_multicast_ifp = NULL;
  803 
  804                         /*
  805                          * Drop multicast group membership if we joined
  806                          * through the interface being detached.
  807                          */
  808                         for (i = 0, gap = 0; i < imo->imo_num_memberships;
  809                             i++) {
  810                                 if (imo->imo_membership[i]->inm_ifp == ifp) {
  811                                         in_delmulti(imo->imo_membership[i]);
  812                                         gap++;
  813                                 } else if (gap != 0)
  814                                         imo->imo_membership[i - gap] =
  815                                             imo->imo_membership[i];
  816                         }
  817                         imo->imo_num_memberships -= gap;
  818                 }
  819                 INP_UNLOCK(inp);
  820         }
  821         INP_INFO_RUNLOCK(pcbinfo);
  822 }
  823 
  824 /*
  825  * Check for alternatives when higher level complains
  826  * about service problems.  For now, invalidate cached
  827  * routing information.  If the route was created dynamically
  828  * (by a redirect), time to try a default gateway again.
  829  */
  830 void
  831 in_losing(inp)
  832         struct inpcb *inp;
  833 {
  834         register struct rtentry *rt;
  835         struct rt_addrinfo info;
  836 
  837         if ((rt = inp->inp_route.ro_rt)) {
  838                 bzero((caddr_t)&info, sizeof(info));
  839                 info.rti_flags = rt->rt_flags;
  840                 info.rti_info[RTAX_DST] = rt_key(rt);
  841                 info.rti_info[RTAX_GATEWAY] = rt->rt_gateway;
  842                 info.rti_info[RTAX_NETMASK] = rt_mask(rt);
  843                 rt_missmsg(RTM_LOSING, &info, rt->rt_flags, 0);
  844                 if (rt->rt_flags & RTF_DYNAMIC)
  845                         (void) rtrequest1(RTM_DELETE, &info, NULL);
  846                 inp->inp_route.ro_rt = NULL;
  847                 rtfree(rt);
  848                 /*
  849                  * A new route can be allocated
  850                  * the next time output is attempted.
  851                  */
  852         }
  853 }
  854 
  855 /*
  856  * After a routing change, flush old routing
  857  * and allocate a (hopefully) better one.
  858  */
  859 struct inpcb *
  860 in_rtchange(inp, errno)
  861         register struct inpcb *inp;
  862         int errno;
  863 {
  864         if (inp->inp_route.ro_rt) {
  865                 rtfree(inp->inp_route.ro_rt);
  866                 inp->inp_route.ro_rt = 0;
  867                 /*
  868                  * A new route can be allocated the next time
  869                  * output is attempted.
  870                  */
  871         }
  872         return inp;
  873 }
  874 
  875 /*
  876  * Lookup a PCB based on the local address and port.
  877  */
  878 struct inpcb *
  879 in_pcblookup_local(pcbinfo, laddr, lport_arg, wild_okay)
  880         struct inpcbinfo *pcbinfo;
  881         struct in_addr laddr;
  882         u_int lport_arg;
  883         int wild_okay;
  884 {
  885         register struct inpcb *inp;
  886         int matchwild = 3, wildcard;
  887         u_short lport = lport_arg;
  888 
  889         if (!wild_okay) {
  890                 struct inpcbhead *head;
  891                 /*
  892                  * Look for an unconnected (wildcard foreign addr) PCB that
  893                  * matches the local address and port we're looking for.
  894                  */
  895                 head = &pcbinfo->hashbase[INP_PCBHASH(INADDR_ANY, lport, 0, pcbinfo->hashmask)];
  896                 LIST_FOREACH(inp, head, inp_hash) {
  897 #ifdef INET6
  898                         if ((inp->inp_vflag & INP_IPV4) == 0)
  899                                 continue;
  900 #endif
  901                         if (inp->inp_faddr.s_addr == INADDR_ANY &&
  902                             inp->inp_laddr.s_addr == laddr.s_addr &&
  903                             inp->inp_lport == lport) {
  904                                 /*
  905                                  * Found.
  906                                  */
  907                                 return (inp);
  908                         }
  909                 }
  910                 /*
  911                  * Not found.
  912                  */
  913                 return (NULL);
  914         } else {
  915                 struct inpcbporthead *porthash;
  916                 struct inpcbport *phd;
  917                 struct inpcb *match = NULL;
  918                 /*
  919                  * Best fit PCB lookup.
  920                  *
  921                  * First see if this local port is in use by looking on the
  922                  * port hash list.
  923                  */
  924                 porthash = &pcbinfo->porthashbase[INP_PCBPORTHASH(lport,
  925                     pcbinfo->porthashmask)];
  926                 LIST_FOREACH(phd, porthash, phd_hash) {
  927                         if (phd->phd_port == lport)
  928                                 break;
  929                 }
  930                 if (phd != NULL) {
  931                         /*
  932                          * Port is in use by one or more PCBs. Look for best
  933                          * fit.
  934                          */
  935                         LIST_FOREACH(inp, &phd->phd_pcblist, inp_portlist) {
  936                                 wildcard = 0;
  937 #ifdef INET6
  938                                 if ((inp->inp_vflag & INP_IPV4) == 0)
  939                                         continue;
  940 #endif
  941                                 if (inp->inp_faddr.s_addr != INADDR_ANY)
  942                                         wildcard++;
  943                                 if (inp->inp_laddr.s_addr != INADDR_ANY) {
  944                                         if (laddr.s_addr == INADDR_ANY)
  945                                                 wildcard++;
  946                                         else if (inp->inp_laddr.s_addr != laddr.s_addr)
  947                                                 continue;
  948                                 } else {
  949                                         if (laddr.s_addr != INADDR_ANY)
  950                                                 wildcard++;
  951                                 }
  952                                 if (wildcard < matchwild) {
  953                                         match = inp;
  954                                         matchwild = wildcard;
  955                                         if (matchwild == 0) {
  956                                                 break;
  957                                         }
  958                                 }
  959                         }
  960                 }
  961                 return (match);
  962         }
  963 }
  964 
  965 /*
  966  * Lookup PCB in hash list.
  967  */
  968 struct inpcb *
  969 in_pcblookup_hash(pcbinfo, faddr, fport_arg, laddr, lport_arg, wildcard,
  970                   ifp)
  971         struct inpcbinfo *pcbinfo;
  972         struct in_addr faddr, laddr;
  973         u_int fport_arg, lport_arg;
  974         int wildcard;
  975         struct ifnet *ifp;
  976 {
  977         struct inpcbhead *head;
  978         register struct inpcb *inp;
  979         u_short fport = fport_arg, lport = lport_arg;
  980 
  981         /*
  982          * First look for an exact match.
  983          */
  984         head = &pcbinfo->hashbase[INP_PCBHASH(faddr.s_addr, lport, fport, pcbinfo->hashmask)];
  985         LIST_FOREACH(inp, head, inp_hash) {
  986 #ifdef INET6
  987                 if ((inp->inp_vflag & INP_IPV4) == 0)
  988                         continue;
  989 #endif
  990                 if (inp->inp_faddr.s_addr == faddr.s_addr &&
  991                     inp->inp_laddr.s_addr == laddr.s_addr &&
  992                     inp->inp_fport == fport &&
  993                     inp->inp_lport == lport) {
  994                         /*
  995                          * Found.
  996                          */
  997                         return (inp);
  998                 }
  999         }
 1000         if (wildcard) {
 1001                 struct inpcb *local_wild = NULL;
 1002 #if defined(INET6)
 1003                 struct inpcb *local_wild_mapped = NULL;
 1004 #endif /* defined(INET6) */
 1005 
 1006                 head = &pcbinfo->hashbase[INP_PCBHASH(INADDR_ANY, lport, 0, pcbinfo->hashmask)];
 1007                 LIST_FOREACH(inp, head, inp_hash) {
 1008 #ifdef INET6
 1009                         if ((inp->inp_vflag & INP_IPV4) == 0)
 1010                                 continue;
 1011 #endif
 1012                         if (inp->inp_faddr.s_addr == INADDR_ANY &&
 1013                             inp->inp_lport == lport) {
 1014                                 if (ifp && ifp->if_type == IFT_FAITH &&
 1015                                     (inp->inp_flags & INP_FAITH) == 0)
 1016                                         continue;
 1017                                 if (inp->inp_laddr.s_addr == laddr.s_addr)
 1018                                         return (inp);
 1019                                 else if (inp->inp_laddr.s_addr == INADDR_ANY) {
 1020 #if defined(INET6)
 1021                                         if (INP_CHECK_SOCKAF(inp->inp_socket,
 1022                                                              AF_INET6))
 1023                                                 local_wild_mapped = inp;
 1024                                         else
 1025 #endif /* defined(INET6) */
 1026                                         local_wild = inp;
 1027                                 }
 1028                         }
 1029                 }
 1030 #if defined(INET6)
 1031                 if (local_wild == NULL)
 1032                         return (local_wild_mapped);
 1033 #endif /* defined(INET6) */
 1034                 return (local_wild);
 1035         }
 1036 
 1037         /*
 1038          * Not found.
 1039          */
 1040         return (NULL);
 1041 }
 1042 
 1043 /*
 1044  * Insert PCB onto various hash lists.
 1045  */
 1046 int
 1047 in_pcbinshash(inp)
 1048         struct inpcb *inp;
 1049 {
 1050         struct inpcbhead *pcbhash;
 1051         struct inpcbporthead *pcbporthash;
 1052         struct inpcbinfo *pcbinfo = inp->inp_pcbinfo;
 1053         struct inpcbport *phd;
 1054         u_int32_t hashkey_faddr;
 1055 
 1056 #ifdef INET6
 1057         if (inp->inp_vflag & INP_IPV6)
 1058                 hashkey_faddr = inp->in6p_faddr.s6_addr32[3] /* XXX */;
 1059         else
 1060 #endif /* INET6 */
 1061         hashkey_faddr = inp->inp_faddr.s_addr;
 1062 
 1063         pcbhash = &pcbinfo->hashbase[INP_PCBHASH(hashkey_faddr,
 1064                  inp->inp_lport, inp->inp_fport, pcbinfo->hashmask)];
 1065 
 1066         pcbporthash = &pcbinfo->porthashbase[INP_PCBPORTHASH(inp->inp_lport,
 1067             pcbinfo->porthashmask)];
 1068 
 1069         /*
 1070          * Go through port list and look for a head for this lport.
 1071          */
 1072         LIST_FOREACH(phd, pcbporthash, phd_hash) {
 1073                 if (phd->phd_port == inp->inp_lport)
 1074                         break;
 1075         }
 1076         /*
 1077          * If none exists, malloc one and tack it on.
 1078          */
 1079         if (phd == NULL) {
 1080                 MALLOC(phd, struct inpcbport *, sizeof(struct inpcbport), M_PCB, M_NOWAIT);
 1081                 if (phd == NULL) {
 1082                         return (ENOBUFS); /* XXX */
 1083                 }
 1084                 phd->phd_port = inp->inp_lport;
 1085                 LIST_INIT(&phd->phd_pcblist);
 1086                 LIST_INSERT_HEAD(pcbporthash, phd, phd_hash);
 1087         }
 1088         inp->inp_phd = phd;
 1089         LIST_INSERT_HEAD(&phd->phd_pcblist, inp, inp_portlist);
 1090         LIST_INSERT_HEAD(pcbhash, inp, inp_hash);
 1091         return (0);
 1092 }
 1093 
 1094 /*
 1095  * Move PCB to the proper hash bucket when { faddr, fport } have  been
 1096  * changed. NOTE: This does not handle the case of the lport changing (the
 1097  * hashed port list would have to be updated as well), so the lport must
 1098  * not change after in_pcbinshash() has been called.
 1099  */
 1100 void
 1101 in_pcbrehash(inp)
 1102         struct inpcb *inp;
 1103 {
 1104         struct inpcbhead *head;
 1105         u_int32_t hashkey_faddr;
 1106 
 1107 #ifdef INET6
 1108         if (inp->inp_vflag & INP_IPV6)
 1109                 hashkey_faddr = inp->in6p_faddr.s6_addr32[3] /* XXX */;
 1110         else
 1111 #endif /* INET6 */
 1112         hashkey_faddr = inp->inp_faddr.s_addr;
 1113 
 1114         head = &inp->inp_pcbinfo->hashbase[INP_PCBHASH(hashkey_faddr,
 1115                 inp->inp_lport, inp->inp_fport, inp->inp_pcbinfo->hashmask)];
 1116 
 1117         LIST_REMOVE(inp, inp_hash);
 1118         LIST_INSERT_HEAD(head, inp, inp_hash);
 1119 }
 1120 
 1121 /*
 1122  * Remove PCB from various lists.
 1123  */
 1124 void
 1125 in_pcbremlists(inp)
 1126         struct inpcb *inp;
 1127 {
 1128         inp->inp_gencnt = ++inp->inp_pcbinfo->ipi_gencnt;
 1129         if (inp->inp_lport) {
 1130                 struct inpcbport *phd = inp->inp_phd;
 1131 
 1132                 LIST_REMOVE(inp, inp_hash);
 1133                 LIST_REMOVE(inp, inp_portlist);
 1134                 if (LIST_FIRST(&phd->phd_pcblist) == NULL) {
 1135                         LIST_REMOVE(phd, phd_hash);
 1136                         free(phd, M_PCB);
 1137                 }
 1138         }
 1139         LIST_REMOVE(inp, inp_list);
 1140         inp->inp_pcbinfo->ipi_count--;
 1141 }
 1142 
 1143 int
 1144 prison_xinpcb(struct thread *td, struct inpcb *inp)
 1145 {
 1146         if (!jailed(td->td_ucred))
 1147                 return (0);
 1148         if (ntohl(inp->inp_laddr.s_addr) == prison_getip(td->td_ucred))
 1149                 return (0);
 1150         return (1);
 1151 }

Cache object: 39070d0a284121ee49de33a0b4fc7a4c


[ 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.