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/ip_input.c

Version: -  FREEBSD  -  FREEBSD10  -  FREEBSD9  -  FREEBSD92  -  FREEBSD91  -  FREEBSD90  -  FREEBSD8  -  FREEBSD82  -  FREEBSD81  -  FREEBSD80  -  FREEBSD7  -  FREEBSD74  -  FREEBSD73  -  FREEBSD72  -  FREEBSD71  -  FREEBSD70  -  FREEBSD6  -  FREEBSD64  -  FREEBSD63  -  FREEBSD62  -  FREEBSD61  -  FREEBSD60  -  FREEBSD5  -  FREEBSD55  -  FREEBSD54  -  FREEBSD53  -  FREEBSD52  -  FREEBSD51  -  FREEBSD50  -  FREEBSD4  -  FREEBSD3  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  xnu-1456.1.26  -  xnu-1699.24.8  -  xnu-2050.18.24  -  OPENSOLARIS  -  minix-3-1-1 
SearchContext: -  none  -  3  -  10 

    1 /*      $OpenBSD: ip_input.c,v 1.160 2008/06/08 13:58:09 thib Exp $     */
    2 /*      $NetBSD: ip_input.c,v 1.30 1996/03/16 23:53:58 christos Exp $   */
    3 
    4 /*
    5  * Copyright (c) 1982, 1986, 1988, 1993
    6  *      The Regents of the University of California.  All rights reserved.
    7  *
    8  * Redistribution and use in source and binary forms, with or without
    9  * modification, are permitted provided that the following conditions
   10  * are met:
   11  * 1. Redistributions of source code must retain the above copyright
   12  *    notice, this list of conditions and the following disclaimer.
   13  * 2. Redistributions in binary form must reproduce the above copyright
   14  *    notice, this list of conditions and the following disclaimer in the
   15  *    documentation and/or other materials provided with the distribution.
   16  * 3. Neither the name of the University nor the names of its contributors
   17  *    may be used to endorse or promote products derived from this software
   18  *    without specific prior written permission.
   19  *
   20  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   30  * SUCH DAMAGE.
   31  *
   32  *      @(#)ip_input.c  8.2 (Berkeley) 1/4/94
   33  */
   34 
   35 #include "pf.h"
   36 #include "carp.h"
   37 
   38 #include <sys/param.h>
   39 #include <sys/systm.h>
   40 #include <sys/mbuf.h>
   41 #include <sys/domain.h>
   42 #include <sys/protosw.h>
   43 #include <sys/socket.h>
   44 #include <sys/socketvar.h>
   45 #include <sys/syslog.h>
   46 #include <sys/sysctl.h>
   47 #include <sys/pool.h>
   48 
   49 #include <net/if.h>
   50 #include <net/if_dl.h>
   51 #include <net/route.h>
   52 
   53 #include <netinet/in.h>
   54 #include <netinet/in_systm.h>
   55 #include <netinet/if_ether.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_icmp.h>
   61 
   62 #if NPF > 0
   63 #include <net/pfvar.h>
   64 #endif
   65 
   66 #ifdef MROUTING
   67 #include <netinet/ip_mroute.h>
   68 #endif
   69 
   70 #ifdef IPSEC
   71 #include <netinet/ip_ipsp.h>
   72 #endif /* IPSEC */
   73 
   74 #if NCARP > 0
   75 #include <net/if_types.h>
   76 #include <netinet/ip_carp.h>
   77 #endif
   78 
   79 #define IPMTUDISCTIMEOUT (10 * 60)      /* as per RFC 1191 */
   80 
   81 struct ipqhead ipq;
   82 
   83 int encdebug = 0;
   84 int ipsec_keep_invalid = IPSEC_DEFAULT_EMBRYONIC_SA_TIMEOUT;
   85 int ipsec_require_pfs = IPSEC_DEFAULT_PFS;
   86 int ipsec_soft_allocations = IPSEC_DEFAULT_SOFT_ALLOCATIONS;
   87 int ipsec_exp_allocations = IPSEC_DEFAULT_EXP_ALLOCATIONS;
   88 int ipsec_soft_bytes = IPSEC_DEFAULT_SOFT_BYTES;
   89 int ipsec_exp_bytes = IPSEC_DEFAULT_EXP_BYTES;
   90 int ipsec_soft_timeout = IPSEC_DEFAULT_SOFT_TIMEOUT;
   91 int ipsec_exp_timeout = IPSEC_DEFAULT_EXP_TIMEOUT;
   92 int ipsec_soft_first_use = IPSEC_DEFAULT_SOFT_FIRST_USE;
   93 int ipsec_exp_first_use = IPSEC_DEFAULT_EXP_FIRST_USE;
   94 int ipsec_expire_acquire = IPSEC_DEFAULT_EXPIRE_ACQUIRE;
   95 char ipsec_def_enc[20];
   96 char ipsec_def_auth[20];
   97 char ipsec_def_comp[20];
   98 
   99 /* values controllable via sysctl */
  100 int     ipforwarding = 0;
  101 int     ipmforwarding = 0;
  102 int     ipmultipath = 0;
  103 int     ipsendredirects = 1;
  104 int     ip_dosourceroute = 0;
  105 int     ip_defttl = IPDEFTTL;
  106 int     ip_mtudisc = 1;
  107 u_int   ip_mtudisc_timeout = IPMTUDISCTIMEOUT;
  108 int     ip_directedbcast = 0;
  109 #ifdef DIAGNOSTIC
  110 int     ipprintfs = 0;
  111 #endif
  112 
  113 struct rttimer_queue *ip_mtudisc_timeout_q = NULL;
  114 
  115 int     ipsec_auth_default_level = IPSEC_AUTH_LEVEL_DEFAULT;
  116 int     ipsec_esp_trans_default_level = IPSEC_ESP_TRANS_LEVEL_DEFAULT;
  117 int     ipsec_esp_network_default_level = IPSEC_ESP_NETWORK_LEVEL_DEFAULT;
  118 int     ipsec_ipcomp_default_level = IPSEC_IPCOMP_LEVEL_DEFAULT;
  119 
  120 /* Keep track of memory used for reassembly */
  121 int     ip_maxqueue = 300;
  122 int     ip_frags = 0;
  123 
  124 /* from in_pcb.c */
  125 extern int ipport_firstauto;
  126 extern int ipport_lastauto;
  127 extern int ipport_hifirstauto;
  128 extern int ipport_hilastauto;
  129 extern struct baddynamicports baddynamicports;
  130 
  131 int *ipctl_vars[IPCTL_MAXID] = IPCTL_VARS;
  132 
  133 extern  struct domain inetdomain;
  134 extern  struct protosw inetsw[];
  135 u_char  ip_protox[IPPROTO_MAX];
  136 int     ipqmaxlen = IFQ_MAXLEN;
  137 struct  in_ifaddrhead in_ifaddr;
  138 struct  ifqueue ipintrq;
  139 
  140 struct pool ipqent_pool;
  141 struct pool ipq_pool;
  142 
  143 struct ipstat ipstat;
  144 
  145 char *
  146 inet_ntoa(ina)
  147         struct in_addr ina;
  148 {
  149         static char buf[4*sizeof "123"];
  150         unsigned char *ucp = (unsigned char *)&ina;
  151 
  152         snprintf(buf, sizeof buf, "%d.%d.%d.%d",
  153             ucp[0] & 0xff, ucp[1] & 0xff,
  154             ucp[2] & 0xff, ucp[3] & 0xff);
  155         return (buf);
  156 }
  157 
  158 /*
  159  * We need to save the IP options in case a protocol wants to respond
  160  * to an incoming packet over the same route if the packet got here
  161  * using IP source routing.  This allows connection establishment and
  162  * maintenance when the remote end is on a network that is not known
  163  * to us.
  164  */
  165 int     ip_nhops = 0;
  166 static  struct ip_srcrt {
  167         struct  in_addr dst;                    /* final destination */
  168         char    nop;                            /* one NOP to align */
  169         char    srcopt[IPOPT_OFFSET + 1];       /* OPTVAL, OLEN and OFFSET */
  170         struct  in_addr route[MAX_IPOPTLEN/sizeof(struct in_addr)];
  171 } ip_srcrt;
  172 
  173 void save_rte(u_char *, struct in_addr);
  174 int ip_weadvertise(u_int32_t);
  175 
  176 /*
  177  * IP initialization: fill in IP protocol switch table.
  178  * All protocols not implemented in kernel go to raw IP protocol handler.
  179  */
  180 void
  181 ip_init()
  182 {
  183         struct protosw *pr;
  184         int i;
  185         const u_int16_t defbaddynamicports_tcp[] = DEFBADDYNAMICPORTS_TCP;
  186         const u_int16_t defbaddynamicports_udp[] = DEFBADDYNAMICPORTS_UDP;
  187 
  188         pool_init(&ipqent_pool, sizeof(struct ipqent), 0, 0, 0, "ipqepl",
  189             NULL);
  190         pool_init(&ipq_pool, sizeof(struct ipq), 0, 0, 0, "ipqpl",
  191             NULL);
  192 
  193         pr = pffindproto(PF_INET, IPPROTO_RAW, SOCK_RAW);
  194         if (pr == 0)
  195                 panic("ip_init");
  196         for (i = 0; i < IPPROTO_MAX; i++)
  197                 ip_protox[i] = pr - inetsw;
  198         for (pr = inetdomain.dom_protosw;
  199             pr < inetdomain.dom_protoswNPROTOSW; pr++)
  200                 if (pr->pr_domain->dom_family == PF_INET &&
  201                     pr->pr_protocol && pr->pr_protocol != IPPROTO_RAW)
  202                         ip_protox[pr->pr_protocol] = pr - inetsw;
  203         LIST_INIT(&ipq);
  204         ipintrq.ifq_maxlen = ipqmaxlen;
  205         TAILQ_INIT(&in_ifaddr);
  206         if (ip_mtudisc != 0)
  207                 ip_mtudisc_timeout_q =
  208                     rt_timer_queue_create(ip_mtudisc_timeout);
  209 
  210         /* Fill in list of ports not to allocate dynamically. */
  211         bzero((void *)&baddynamicports, sizeof(baddynamicports));
  212         for (i = 0; defbaddynamicports_tcp[i] != 0; i++)
  213                 DP_SET(baddynamicports.tcp, defbaddynamicports_tcp[i]);
  214         for (i = 0; defbaddynamicports_udp[i] != 0; i++)
  215                 DP_SET(baddynamicports.udp, defbaddynamicports_udp[i]);
  216 
  217         strlcpy(ipsec_def_enc, IPSEC_DEFAULT_DEF_ENC, sizeof(ipsec_def_enc));
  218         strlcpy(ipsec_def_auth, IPSEC_DEFAULT_DEF_AUTH, sizeof(ipsec_def_auth));
  219         strlcpy(ipsec_def_comp, IPSEC_DEFAULT_DEF_COMP, sizeof(ipsec_def_comp));
  220 }
  221 
  222 struct  sockaddr_in ipaddr = { sizeof(ipaddr), AF_INET };
  223 struct  route ipforward_rt;
  224 int     ipforward_rtableid;
  225 
  226 void
  227 ipintr()
  228 {
  229         struct mbuf *m;
  230         int s;
  231 
  232         for (;;) {
  233                 /*
  234                  * Get next datagram off input queue and get IP header
  235                  * in first mbuf.
  236                  */
  237                 s = splnet();
  238                 IF_DEQUEUE(&ipintrq, m);
  239                 splx(s);
  240                 if (m == NULL)
  241                         return;
  242 #ifdef  DIAGNOSTIC
  243                 if ((m->m_flags & M_PKTHDR) == 0)
  244                         panic("ipintr no HDR");
  245 #endif
  246                 ipv4_input(m);
  247         }
  248 }
  249 
  250 /*
  251  * Ip input routine.  Checksum and byte swap header.  If fragmented
  252  * try to reassemble.  Process options.  Pass to next level.
  253  */
  254 void
  255 ipv4_input(m)
  256         struct mbuf *m;
  257 {
  258         struct ip *ip;
  259         struct ipq *fp;
  260         struct in_ifaddr *ia;
  261         struct ipqent *ipqe;
  262         int hlen, mff, len;
  263         in_addr_t pfrdr = 0;
  264 #ifdef IPSEC
  265         int error, s;
  266         struct tdb *tdb;
  267         struct tdb_ident *tdbi;
  268         struct m_tag *mtag;
  269 #endif /* IPSEC */
  270 
  271         /*
  272          * If no IP addresses have been set yet but the interfaces
  273          * are receiving, can't do anything with incoming packets yet.
  274          */
  275         if (TAILQ_EMPTY(&in_ifaddr))
  276                 goto bad;
  277         ipstat.ips_total++;
  278         if (m->m_len < sizeof (struct ip) &&
  279             (m = m_pullup(m, sizeof (struct ip))) == NULL) {
  280                 ipstat.ips_toosmall++;
  281                 return;
  282         }
  283         ip = mtod(m, struct ip *);
  284         if (ip->ip_v != IPVERSION) {
  285                 ipstat.ips_badvers++;
  286                 goto bad;
  287         }
  288         hlen = ip->ip_hl << 2;
  289         if (hlen < sizeof(struct ip)) { /* minimum header length */
  290                 ipstat.ips_badhlen++;
  291                 goto bad;
  292         }
  293         if (hlen > m->m_len) {
  294                 if ((m = m_pullup(m, hlen)) == NULL) {
  295                         ipstat.ips_badhlen++;
  296                         return;
  297                 }
  298                 ip = mtod(m, struct ip *);
  299         }
  300 
  301         /* 127/8 must not appear on wire - RFC1122 */
  302         if ((ntohl(ip->ip_dst.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET ||
  303             (ntohl(ip->ip_src.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET) {
  304                 if ((m->m_pkthdr.rcvif->if_flags & IFF_LOOPBACK) == 0) {
  305                         ipstat.ips_badaddr++;
  306                         goto bad;
  307                 }
  308         }
  309 
  310         if ((m->m_pkthdr.csum_flags & M_IPV4_CSUM_IN_OK) == 0) {
  311                 if (m->m_pkthdr.csum_flags & M_IPV4_CSUM_IN_BAD) {
  312                         ipstat.ips_inhwcsum++;
  313                         ipstat.ips_badsum++;
  314                         goto bad;
  315                 }
  316 
  317                 if (in_cksum(m, hlen) != 0) {
  318                         ipstat.ips_badsum++;
  319                         goto bad;
  320                 }
  321         } else {
  322                 m->m_pkthdr.csum_flags &= ~M_IPV4_CSUM_IN_OK;
  323                 ipstat.ips_inhwcsum++;
  324         }
  325 
  326         /* Retrieve the packet length. */
  327         len = ntohs(ip->ip_len);
  328 
  329         /*
  330          * Convert fields to host representation.
  331          */
  332         if (len < hlen) {
  333                 ipstat.ips_badlen++;
  334                 goto bad;
  335         }
  336 
  337         /*
  338          * Check that the amount of data in the buffers
  339          * is at least as much as the IP header would have us expect.
  340          * Trim mbufs if longer than we expect.
  341          * Drop packet if shorter than we expect.
  342          */
  343         if (m->m_pkthdr.len < len) {
  344                 ipstat.ips_tooshort++;
  345                 goto bad;
  346         }
  347         if (m->m_pkthdr.len > len) {
  348                 if (m->m_len == m->m_pkthdr.len) {
  349                         m->m_len = len;
  350                         m->m_pkthdr.len = len;
  351                 } else
  352                         m_adj(m, len - m->m_pkthdr.len);
  353         }
  354 
  355 #if NCARP > 0
  356         if (m->m_pkthdr.rcvif->if_type == IFT_CARP &&
  357             ip->ip_p != IPPROTO_ICMP && carp_lsdrop(m, AF_INET,
  358             &ip->ip_src.s_addr, &ip->ip_dst.s_addr))
  359                 goto bad;
  360 #endif
  361 
  362 #if NPF > 0
  363         /*
  364          * Packet filter
  365          */
  366         pfrdr = ip->ip_dst.s_addr;
  367         if (pf_test(PF_IN, m->m_pkthdr.rcvif, &m, NULL) != PF_PASS)
  368                 goto bad;
  369         if (m == NULL)
  370                 return;
  371 
  372         ip = mtod(m, struct ip *);
  373         hlen = ip->ip_hl << 2;
  374         pfrdr = (pfrdr != ip->ip_dst.s_addr);
  375 #endif
  376 
  377         /*
  378          * Process options and, if not destined for us,
  379          * ship it on.  ip_dooptions returns 1 when an
  380          * error was detected (causing an icmp message
  381          * to be sent and the original packet to be freed).
  382          */
  383         ip_nhops = 0;           /* for source routed packets */
  384         if (hlen > sizeof (struct ip) && ip_dooptions(m)) {
  385                 return;
  386         }
  387 
  388         /*
  389          * Check our list of addresses, to see if the packet is for us.
  390          */
  391         if ((ia = in_iawithaddr(ip->ip_dst, m)) != NULL &&
  392             (ia->ia_ifp->if_flags & IFF_UP))
  393                 goto ours;
  394 
  395         if (m->m_pkthdr.pf.flags & PF_TAG_DIVERTED)
  396                 goto ours;
  397 
  398         if (IN_MULTICAST(ip->ip_dst.s_addr)) {
  399                 struct in_multi *inm;
  400 #ifdef MROUTING
  401                 extern struct socket *ip_mrouter;
  402 
  403                 if (m->m_flags & M_EXT) {
  404                         if ((m = m_pullup(m, hlen)) == NULL) {
  405                                 ipstat.ips_toosmall++;
  406                                 return;
  407                         }
  408                         ip = mtod(m, struct ip *);
  409                 }
  410                 if (ipmforwarding && ip_mrouter) {
  411                         /*
  412                          * If we are acting as a multicast router, all
  413                          * incoming multicast packets are passed to the
  414                          * kernel-level multicast forwarding function.
  415                          * The packet is returned (relatively) intact; if
  416                          * ip_mforward() returns a non-zero value, the packet
  417                          * must be discarded, else it may be accepted below.
  418                          *
  419                          * (The IP ident field is put in the same byte order
  420                          * as expected when ip_mforward() is called from
  421                          * ip_output().)
  422                          */
  423                         if (ip_mforward(m, m->m_pkthdr.rcvif) != 0) {
  424                                 ipstat.ips_cantforward++;
  425                                 m_freem(m);
  426                                 return;
  427                         }
  428 
  429                         /*
  430                          * The process-level routing daemon needs to receive
  431                          * all multicast IGMP packets, whether or not this
  432                          * host belongs to their destination groups.
  433                          */
  434                         if (ip->ip_p == IPPROTO_IGMP)
  435                                 goto ours;
  436                         ipstat.ips_forward++;
  437                 }
  438 #endif
  439                 /*
  440                  * See if we belong to the destination multicast group on the
  441                  * arrival interface.
  442                  */
  443                 IN_LOOKUP_MULTI(ip->ip_dst, m->m_pkthdr.rcvif, inm);
  444                 if (inm == NULL) {
  445                         ipstat.ips_notmember++;
  446                         if (!IN_LOCAL_GROUP(ip->ip_dst.s_addr))
  447                                 ipstat.ips_cantforward++;
  448                         m_freem(m);
  449                         return;
  450                 }
  451                 goto ours;
  452         }
  453         if (ip->ip_dst.s_addr == INADDR_BROADCAST ||
  454             ip->ip_dst.s_addr == INADDR_ANY)
  455                 goto ours;
  456 
  457 #if NCARP > 0
  458         if (m->m_pkthdr.rcvif->if_type == IFT_CARP &&
  459             ip->ip_p == IPPROTO_ICMP && carp_lsdrop(m, AF_INET,
  460             &ip->ip_src.s_addr, &ip->ip_dst.s_addr))
  461                 goto bad;
  462 #endif
  463         /*
  464          * Not for us; forward if possible and desirable.
  465          */
  466         if (ipforwarding == 0) {
  467                 ipstat.ips_cantforward++;
  468                 m_freem(m);
  469                 return;
  470         }
  471 #ifdef IPSEC
  472         if (ipsec_in_use) {
  473                 /*
  474                  * IPsec policy check for forwarded packets. Look at
  475                  * inner-most IPsec SA used.
  476                  */
  477                 mtag = m_tag_find(m, PACKET_TAG_IPSEC_IN_DONE, NULL);
  478                 s = splnet();
  479                 if (mtag != NULL) {
  480                         tdbi = (struct tdb_ident *)(mtag + 1);
  481                         tdb = gettdb(tdbi->spi, &tdbi->dst, tdbi->proto);
  482                 } else
  483                         tdb = NULL;
  484                 ipsp_spd_lookup(m, AF_INET, hlen, &error,
  485                     IPSP_DIRECTION_IN, tdb, NULL);
  486                 splx(s);
  487 
  488                 /* Error or otherwise drop-packet indication */
  489                 if (error) {
  490                         ipstat.ips_cantforward++;
  491                         m_freem(m);
  492                         return;
  493                 }
  494 
  495                 /*
  496                  * Fall through, forward packet. Outbound IPsec policy
  497                  * checking will occur in ip_output().
  498                  */
  499         }
  500 #endif /* IPSEC */
  501 
  502         ip_forward(m, pfrdr);
  503         return;
  504 
  505 ours:
  506         /*
  507          * If offset or IP_MF are set, must reassemble.
  508          * Otherwise, nothing need be done.
  509          * (We could look in the reassembly queue to see
  510          * if the packet was previously fragmented,
  511          * but it's not worth the time; just let them time out.)
  512          */
  513         if (ip->ip_off &~ htons(IP_DF | IP_RF)) {
  514                 if (m->m_flags & M_EXT) {               /* XXX */
  515                         if ((m = m_pullup(m, hlen)) == NULL) {
  516                                 ipstat.ips_toosmall++;
  517                                 return;
  518                         }
  519                         ip = mtod(m, struct ip *);
  520                 }
  521 
  522                 /*
  523                  * Look for queue of fragments
  524                  * of this datagram.
  525                  */
  526                 LIST_FOREACH(fp, &ipq, ipq_q)
  527                         if (ip->ip_id == fp->ipq_id &&
  528                             ip->ip_src.s_addr == fp->ipq_src.s_addr &&
  529                             ip->ip_dst.s_addr == fp->ipq_dst.s_addr &&
  530                             ip->ip_p == fp->ipq_p)
  531                                 goto found;
  532                 fp = 0;
  533 found:
  534 
  535                 /*
  536                  * Adjust ip_len to not reflect header,
  537                  * set ipqe_mff if more fragments are expected,
  538                  * convert offset of this to bytes.
  539                  */
  540                 ip->ip_len = htons(ntohs(ip->ip_len) - hlen);
  541                 mff = (ip->ip_off & htons(IP_MF)) != 0;
  542                 if (mff) {
  543                         /*
  544                          * Make sure that fragments have a data length
  545                          * that's a non-zero multiple of 8 bytes.
  546                          */
  547                         if (ntohs(ip->ip_len) == 0 ||
  548                             (ntohs(ip->ip_len) & 0x7) != 0) {
  549                                 ipstat.ips_badfrags++;
  550                                 goto bad;
  551                         }
  552                 }
  553                 ip->ip_off = htons(ntohs(ip->ip_off) << 3);
  554 
  555                 /*
  556                  * If datagram marked as having more fragments
  557                  * or if this is not the first fragment,
  558                  * attempt reassembly; if it succeeds, proceed.
  559                  */
  560                 if (mff || ip->ip_off) {
  561                         ipstat.ips_fragments++;
  562                         if (ip_frags + 1 > ip_maxqueue) {
  563                                 ip_flush();
  564                                 ipstat.ips_rcvmemdrop++;
  565                                 goto bad;
  566                         }
  567 
  568                         ipqe = pool_get(&ipqent_pool, PR_NOWAIT);
  569                         if (ipqe == NULL) {
  570                                 ipstat.ips_rcvmemdrop++;
  571                                 goto bad;
  572                         }
  573                         ip_frags++;
  574                         ipqe->ipqe_mff = mff;
  575                         ipqe->ipqe_m = m;
  576                         ipqe->ipqe_ip = ip;
  577                         m = ip_reass(ipqe, fp);
  578                         if (m == 0) {
  579                                 return;
  580                         }
  581                         ipstat.ips_reassembled++;
  582                         ip = mtod(m, struct ip *);
  583                         hlen = ip->ip_hl << 2;
  584                         ip->ip_len = htons(ntohs(ip->ip_len) + hlen);
  585                 } else
  586                         if (fp)
  587                                 ip_freef(fp);
  588         }
  589 
  590 #ifdef IPSEC
  591         if (!ipsec_in_use)
  592                 goto skipipsec;
  593 
  594         /*
  595          * If it's a protected packet for us, skip the policy check.
  596          * That's because we really only care about the properties of
  597          * the protected packet, and not the intermediate versions.
  598          * While this is not the most paranoid setting, it allows
  599          * some flexibility in handling nested tunnels (in setting up
  600          * the policies).
  601          */
  602         if ((ip->ip_p == IPPROTO_ESP) || (ip->ip_p == IPPROTO_AH) ||
  603             (ip->ip_p == IPPROTO_IPCOMP))
  604           goto skipipsec;
  605 
  606         /*
  607          * If the protected packet was tunneled, then we need to
  608          * verify the protected packet's information, not the
  609          * external headers. Thus, skip the policy lookup for the
  610          * external packet, and keep the IPsec information linked on
  611          * the packet header (the encapsulation routines know how
  612          * to deal with that).
  613          */
  614         if ((ip->ip_p == IPPROTO_IPIP) || (ip->ip_p == IPPROTO_IPV6))
  615           goto skipipsec;
  616 
  617         /*
  618          * If the protected packet is TCP or UDP, we'll do the
  619          * policy check in the respective input routine, so we can
  620          * check for bypass sockets.
  621          */
  622         if ((ip->ip_p == IPPROTO_TCP) || (ip->ip_p == IPPROTO_UDP))
  623           goto skipipsec;
  624 
  625         /*
  626          * IPsec policy check for local-delivery packets. Look at the
  627          * inner-most SA that protected the packet. This is in fact
  628          * a bit too restrictive (it could end up causing packets to
  629          * be dropped that semantically follow the policy, e.g., in
  630          * certain SA-bundle configurations); but the alternative is
  631          * very complicated (and requires keeping track of what
  632          * kinds of tunneling headers have been seen in-between the
  633          * IPsec headers), and I don't think we lose much functionality
  634          * that's needed in the real world (who uses bundles anyway ?).
  635          */
  636         mtag = m_tag_find(m, PACKET_TAG_IPSEC_IN_DONE, NULL);
  637         s = splnet();
  638         if (mtag) {
  639                 tdbi = (struct tdb_ident *)(mtag + 1);
  640                 tdb = gettdb(tdbi->spi, &tdbi->dst, tdbi->proto);
  641         } else
  642                 tdb = NULL;
  643         ipsp_spd_lookup(m, AF_INET, hlen, &error, IPSP_DIRECTION_IN,
  644             tdb, NULL);
  645         splx(s);
  646 
  647         /* Error or otherwise drop-packet indication. */
  648         if (error) {
  649                 ipstat.ips_cantforward++;
  650                 m_freem(m);
  651                 return;
  652         }
  653 
  654  skipipsec:
  655         /* Otherwise, just fall through and deliver the packet */
  656 #endif /* IPSEC */
  657 
  658         /*
  659          * Switch out to protocol's input routine.
  660          */
  661         ipstat.ips_delivered++;
  662         (*inetsw[ip_protox[ip->ip_p]].pr_input)(m, hlen, NULL, 0);
  663         return;
  664 bad:
  665         m_freem(m);
  666 }
  667 
  668 struct in_ifaddr *
  669 in_iawithaddr(ina, m)
  670         struct in_addr ina;
  671         struct mbuf *m;
  672 {
  673         struct in_ifaddr *ia;
  674 
  675         TAILQ_FOREACH(ia, &in_ifaddr, ia_list) {
  676                 if ((ina.s_addr == ia->ia_addr.sin_addr.s_addr) ||
  677                     ((ia->ia_ifp->if_flags & (IFF_LOOPBACK|IFF_LINK1)) ==
  678                         (IFF_LOOPBACK|IFF_LINK1) &&
  679                      ia->ia_subnet == (ina.s_addr & ia->ia_subnetmask)))
  680                         return ia;
  681                 if (((ip_directedbcast == 0) || (m && ip_directedbcast &&
  682                     ia->ia_ifp == m->m_pkthdr.rcvif)) &&
  683                     (ia->ia_ifp->if_flags & IFF_BROADCAST)) {
  684                         if (ina.s_addr == ia->ia_broadaddr.sin_addr.s_addr ||
  685                             ina.s_addr == ia->ia_netbroadcast.s_addr ||
  686                             /*
  687                              * Look for all-0's host part (old broadcast addr),
  688                              * either for subnet or net.
  689                              */
  690                             ina.s_addr == ia->ia_subnet ||
  691                             ina.s_addr == ia->ia_net) {
  692                                 /* Make sure M_BCAST is set */
  693                                 if (m)
  694                                         m->m_flags |= M_BCAST;
  695                                 return ia;
  696                             }
  697                 }
  698         }
  699 
  700         return NULL;
  701 }
  702 
  703 /*
  704  * Take incoming datagram fragment and try to
  705  * reassemble it into whole datagram.  If a chain for
  706  * reassembly of this datagram already exists, then it
  707  * is given as fp; otherwise have to make a chain.
  708  */
  709 struct mbuf *
  710 ip_reass(ipqe, fp)
  711         struct ipqent *ipqe;
  712         struct ipq *fp;
  713 {
  714         struct mbuf *m = ipqe->ipqe_m;
  715         struct ipqent *nq, *p, *q;
  716         struct ip *ip;
  717         struct mbuf *t;
  718         int hlen = ipqe->ipqe_ip->ip_hl << 2;
  719         int i, next;
  720         u_int8_t ecn, ecn0;
  721 
  722         /*
  723          * Presence of header sizes in mbufs
  724          * would confuse code below.
  725          */
  726         m->m_data += hlen;
  727         m->m_len -= hlen;
  728 
  729         /*
  730          * If first fragment to arrive, create a reassembly queue.
  731          */
  732         if (fp == NULL) {
  733                 fp = pool_get(&ipq_pool, PR_NOWAIT);
  734                 if (fp == NULL)
  735                         goto dropfrag;
  736                 LIST_INSERT_HEAD(&ipq, fp, ipq_q);
  737                 fp->ipq_ttl = IPFRAGTTL;
  738                 fp->ipq_p = ipqe->ipqe_ip->ip_p;
  739                 fp->ipq_id = ipqe->ipqe_ip->ip_id;
  740                 LIST_INIT(&fp->ipq_fragq);
  741                 fp->ipq_src = ipqe->ipqe_ip->ip_src;
  742                 fp->ipq_dst = ipqe->ipqe_ip->ip_dst;
  743                 p = NULL;
  744                 goto insert;
  745         }
  746 
  747         /*
  748          * Handle ECN by comparing this segment with the first one;
  749          * if CE is set, do not lose CE.
  750          * drop if CE and not-ECT are mixed for the same packet.
  751          */
  752         ecn = ipqe->ipqe_ip->ip_tos & IPTOS_ECN_MASK;
  753         ecn0 = LIST_FIRST(&fp->ipq_fragq)->ipqe_ip->ip_tos & IPTOS_ECN_MASK;
  754         if (ecn == IPTOS_ECN_CE) {
  755                 if (ecn0 == IPTOS_ECN_NOTECT)
  756                         goto dropfrag;
  757                 if (ecn0 != IPTOS_ECN_CE)
  758                         LIST_FIRST(&fp->ipq_fragq)->ipqe_ip->ip_tos |= IPTOS_ECN_CE;
  759         }
  760         if (ecn == IPTOS_ECN_NOTECT && ecn0 != IPTOS_ECN_NOTECT)
  761                 goto dropfrag;
  762 
  763         /*
  764          * Find a segment which begins after this one does.
  765          */
  766         for (p = NULL, q = LIST_FIRST(&fp->ipq_fragq);
  767             q != LIST_END(&fp->ipq_fragq); p = q, q = LIST_NEXT(q, ipqe_q))
  768                 if (ntohs(q->ipqe_ip->ip_off) > ntohs(ipqe->ipqe_ip->ip_off))
  769                         break;
  770 
  771         /*
  772          * If there is a preceding segment, it may provide some of
  773          * our data already.  If so, drop the data from the incoming
  774          * segment.  If it provides all of our data, drop us.
  775          */
  776         if (p != NULL) {
  777                 i = ntohs(p->ipqe_ip->ip_off) + ntohs(p->ipqe_ip->ip_len) -
  778                     ntohs(ipqe->ipqe_ip->ip_off);
  779                 if (i > 0) {
  780                         if (i >= ntohs(ipqe->ipqe_ip->ip_len))
  781                                 goto dropfrag;
  782                         m_adj(ipqe->ipqe_m, i);
  783                         ipqe->ipqe_ip->ip_off =
  784                             htons(ntohs(ipqe->ipqe_ip->ip_off) + i);
  785                         ipqe->ipqe_ip->ip_len =
  786                             htons(ntohs(ipqe->ipqe_ip->ip_len) - i);
  787                 }
  788         }
  789 
  790         /*
  791          * While we overlap succeeding segments trim them or,
  792          * if they are completely covered, dequeue them.
  793          */
  794         for (; q != NULL &&
  795             ntohs(ipqe->ipqe_ip->ip_off) + ntohs(ipqe->ipqe_ip->ip_len) >
  796             ntohs(q->ipqe_ip->ip_off); q = nq) {
  797                 i = (ntohs(ipqe->ipqe_ip->ip_off) +
  798                     ntohs(ipqe->ipqe_ip->ip_len)) - ntohs(q->ipqe_ip->ip_off);
  799                 if (i < ntohs(q->ipqe_ip->ip_len)) {
  800                         q->ipqe_ip->ip_len =
  801                             htons(ntohs(q->ipqe_ip->ip_len) - i);
  802                         q->ipqe_ip->ip_off =
  803                             htons(ntohs(q->ipqe_ip->ip_off) + i);
  804                         m_adj(q->ipqe_m, i);
  805                         break;
  806                 }
  807                 nq = LIST_NEXT(q, ipqe_q);
  808                 m_freem(q->ipqe_m);
  809                 LIST_REMOVE(q, ipqe_q);
  810                 pool_put(&ipqent_pool, q);
  811                 ip_frags--;
  812         }
  813 
  814 insert:
  815         /*
  816          * Stick new segment in its place;
  817          * check for complete reassembly.
  818          */
  819         if (p == NULL) {
  820                 LIST_INSERT_HEAD(&fp->ipq_fragq, ipqe, ipqe_q);
  821         } else {
  822                 LIST_INSERT_AFTER(p, ipqe, ipqe_q);
  823         }
  824         next = 0;
  825         for (p = NULL, q = LIST_FIRST(&fp->ipq_fragq);
  826             q != LIST_END(&fp->ipq_fragq); p = q, q = LIST_NEXT(q, ipqe_q)) {
  827                 if (ntohs(q->ipqe_ip->ip_off) != next)
  828                         return (0);
  829                 next += ntohs(q->ipqe_ip->ip_len);
  830         }
  831         if (p->ipqe_mff)
  832                 return (0);
  833 
  834         /*
  835          * Reassembly is complete.  Check for a bogus message size and
  836          * concatenate fragments.
  837          */
  838         q = LIST_FIRST(&fp->ipq_fragq);
  839         ip = q->ipqe_ip;
  840         if ((next + (ip->ip_hl << 2)) > IP_MAXPACKET) {
  841                 ipstat.ips_toolong++;
  842                 ip_freef(fp);
  843                 return (0);
  844         }
  845         m = q->ipqe_m;
  846         t = m->m_next;
  847         m->m_next = 0;
  848         m_cat(m, t);
  849         nq = LIST_NEXT(q, ipqe_q);
  850         pool_put(&ipqent_pool, q);
  851         ip_frags--;
  852         for (q = nq; q != NULL; q = nq) {
  853                 t = q->ipqe_m;
  854                 nq = LIST_NEXT(q, ipqe_q);
  855                 pool_put(&ipqent_pool, q);
  856                 ip_frags--;
  857                 m_cat(m, t);
  858         }
  859 
  860         /*
  861          * Create header for new ip packet by
  862          * modifying header of first packet;
  863          * dequeue and discard fragment reassembly header.
  864          * Make header visible.
  865          */
  866         ip->ip_len = htons(next);
  867         ip->ip_src = fp->ipq_src;
  868         ip->ip_dst = fp->ipq_dst;
  869         LIST_REMOVE(fp, ipq_q);
  870         pool_put(&ipq_pool, fp);
  871         m->m_len += (ip->ip_hl << 2);
  872         m->m_data -= (ip->ip_hl << 2);
  873         /* some debugging cruft by sklower, below, will go away soon */
  874         if (m->m_flags & M_PKTHDR) { /* XXX this should be done elsewhere */
  875                 int plen = 0;
  876                 for (t = m; t; t = t->m_next)
  877                         plen += t->m_len;
  878                 m->m_pkthdr.len = plen;
  879         }
  880         return (m);
  881 
  882 dropfrag:
  883         ipstat.ips_fragdropped++;
  884         m_freem(m);
  885         pool_put(&ipqent_pool, ipqe);
  886         ip_frags--;
  887         return (0);
  888 }
  889 
  890 /*
  891  * Free a fragment reassembly header and all
  892  * associated datagrams.
  893  */
  894 void
  895 ip_freef(fp)
  896         struct ipq *fp;
  897 {
  898         struct ipqent *q, *p;
  899 
  900         for (q = LIST_FIRST(&fp->ipq_fragq); q != LIST_END(&fp->ipq_fragq);
  901             q = p) {
  902                 p = LIST_NEXT(q, ipqe_q);
  903                 m_freem(q->ipqe_m);
  904                 LIST_REMOVE(q, ipqe_q);
  905                 pool_put(&ipqent_pool, q);
  906                 ip_frags--;
  907         }
  908         LIST_REMOVE(fp, ipq_q);
  909         pool_put(&ipq_pool, fp);
  910 }
  911 
  912 /*
  913  * IP timer processing;
  914  * if a timer expires on a reassembly queue, discard it.
  915  * clear the forwarding cache, there might be a better route.
  916  */
  917 void
  918 ip_slowtimo()
  919 {
  920         struct ipq *fp, *nfp;
  921         int s = splsoftnet();
  922 
  923         for (fp = LIST_FIRST(&ipq); fp != LIST_END(&ipq); fp = nfp) {
  924                 nfp = LIST_NEXT(fp, ipq_q);
  925                 if (--fp->ipq_ttl == 0) {
  926                         ipstat.ips_fragtimeout++;
  927                         ip_freef(fp);
  928                 }
  929         }
  930         if (ipforward_rt.ro_rt) {
  931                 RTFREE(ipforward_rt.ro_rt);
  932                 ipforward_rt.ro_rt = 0;
  933         }
  934         splx(s);
  935 }
  936 
  937 /*
  938  * Drain off all datagram fragments.
  939  */
  940 void
  941 ip_drain()
  942 {
  943 
  944         while (!LIST_EMPTY(&ipq)) {
  945                 ipstat.ips_fragdropped++;
  946                 ip_freef(LIST_FIRST(&ipq));
  947         }
  948 }
  949 
  950 /*
  951  * Flush a bunch of datagram fragments, till we are down to 75%.
  952  */
  953 void
  954 ip_flush()
  955 {
  956         int max = 50;
  957 
  958         /* ipq already locked */
  959         while (!LIST_EMPTY(&ipq) && ip_frags > ip_maxqueue * 3 / 4 && --max) {
  960                 ipstat.ips_fragdropped++;
  961                 ip_freef(LIST_FIRST(&ipq));
  962         }
  963 }
  964 
  965 /*
  966  * Do option processing on a datagram,
  967  * possibly discarding it if bad options are encountered,
  968  * or forwarding it if source-routed.
  969  * Returns 1 if packet has been forwarded/freed,
  970  * 0 if the packet should be processed further.
  971  */
  972 int
  973 ip_dooptions(m)
  974         struct mbuf *m;
  975 {
  976         struct ip *ip = mtod(m, struct ip *);
  977         u_char *cp;
  978         struct ip_timestamp ipt;
  979         struct in_ifaddr *ia;
  980         int opt, optlen, cnt, off, code, type = ICMP_PARAMPROB, forward = 0;
  981         struct in_addr sin, dst;
  982         n_time ntime;
  983 
  984         dst = ip->ip_dst;
  985         cp = (u_char *)(ip + 1);
  986         cnt = (ip->ip_hl << 2) - sizeof (struct ip);
  987 
  988         for (; cnt > 0; cnt -= optlen, cp += optlen) {
  989                 opt = cp[IPOPT_OPTVAL];
  990                 if (opt == IPOPT_EOL)
  991                         break;
  992                 if (opt == IPOPT_NOP)
  993                         optlen = 1;
  994                 else {
  995                         if (cnt < IPOPT_OLEN + sizeof(*cp)) {
  996                                 code = &cp[IPOPT_OLEN] - (u_char *)ip;
  997                                 goto bad;
  998                         }
  999                         optlen = cp[IPOPT_OLEN];
 1000                         if (optlen < IPOPT_OLEN + sizeof(*cp) || optlen > cnt) {
 1001                                 code = &cp[IPOPT_OLEN] - (u_char *)ip;
 1002                                 goto bad;
 1003                         }
 1004                 }
 1005 
 1006                 switch (opt) {
 1007 
 1008                 default:
 1009                         break;
 1010 
 1011                 /*
 1012                  * Source routing with record.
 1013                  * Find interface with current destination address.
 1014                  * If none on this machine then drop if strictly routed,
 1015                  * or do nothing if loosely routed.
 1016                  * Record interface address and bring up next address
 1017                  * component.  If strictly routed make sure next
 1018                  * address is on directly accessible net.
 1019                  */
 1020                 case IPOPT_LSRR:
 1021                 case IPOPT_SSRR:
 1022                         if (!ip_dosourceroute) {
 1023                                 type = ICMP_UNREACH;
 1024                                 code = ICMP_UNREACH_SRCFAIL;
 1025                                 goto bad;
 1026                         }
 1027                         if ((off = cp[IPOPT_OFFSET]) < IPOPT_MINOFF) {
 1028                                 code = &cp[IPOPT_OFFSET] - (u_char *)ip;
 1029                                 goto bad;
 1030                         }
 1031                         ipaddr.sin_addr = ip->ip_dst;
 1032                         ia = ifatoia(ifa_ifwithaddr(sintosa(&ipaddr)));
 1033                         if (ia == 0) {
 1034                                 if (opt == IPOPT_SSRR) {
 1035                                         type = ICMP_UNREACH;
 1036                                         code = ICMP_UNREACH_SRCFAIL;
 1037                                         goto bad;
 1038                                 }
 1039                                 /*
 1040                                  * Loose routing, and not at next destination
 1041                                  * yet; nothing to do except forward.
 1042                                  */
 1043                                 break;
 1044                         }
 1045                         off--;                  /* 0 origin */
 1046                         if ((off + sizeof(struct in_addr)) > optlen) {
 1047                                 /*
 1048                                  * End of source route.  Should be for us.
 1049                                  */
 1050                                 save_rte(cp, ip->ip_src);
 1051                                 break;
 1052                         }
 1053 
 1054                         /*
 1055                          * locate outgoing interface
 1056                          */
 1057                         bcopy((caddr_t)(cp + off), (caddr_t)&ipaddr.sin_addr,
 1058                             sizeof(ipaddr.sin_addr));
 1059                         if (opt == IPOPT_SSRR) {
 1060 #define INA     struct in_ifaddr *
 1061 #define SA      struct sockaddr *
 1062                             if ((ia = (INA)ifa_ifwithdstaddr((SA)&ipaddr)) == 0)
 1063                                 ia = (INA)ifa_ifwithnet((SA)&ipaddr);
 1064                         } else
 1065                                 ia = ip_rtaddr(ipaddr.sin_addr);
 1066                         if (ia == 0) {
 1067                                 type = ICMP_UNREACH;
 1068                                 code = ICMP_UNREACH_SRCFAIL;
 1069                                 goto bad;
 1070                         }
 1071                         ip->ip_dst = ipaddr.sin_addr;
 1072                         bcopy((caddr_t)&ia->ia_addr.sin_addr,
 1073                             (caddr_t)(cp + off), sizeof(struct in_addr));
 1074                         cp[IPOPT_OFFSET] += sizeof(struct in_addr);
 1075                         /*
 1076                          * Let ip_intr's mcast routing check handle mcast pkts
 1077                          */
 1078                         forward = !IN_MULTICAST(ip->ip_dst.s_addr);
 1079                         break;
 1080 
 1081                 case IPOPT_RR:
 1082                         if (optlen < IPOPT_OFFSET + sizeof(*cp)) {
 1083                                 code = &cp[IPOPT_OLEN] - (u_char *)ip;
 1084                                 goto bad;
 1085                         }
 1086                         if ((off = cp[IPOPT_OFFSET]) < IPOPT_MINOFF) {
 1087                                 code = &cp[IPOPT_OFFSET] - (u_char *)ip;
 1088                                 goto bad;
 1089                         }
 1090 
 1091                         /*
 1092                          * If no space remains, ignore.
 1093                          */
 1094                         off--;                  /* 0 origin */
 1095                         if ((off + sizeof(struct in_addr)) > optlen)
 1096                                 break;
 1097                         bcopy((caddr_t)(&ip->ip_dst), (caddr_t)&ipaddr.sin_addr,
 1098                             sizeof(ipaddr.sin_addr));
 1099                         /*
 1100                          * locate outgoing interface; if we're the destination,
 1101                          * use the incoming interface (should be same).
 1102                          */
 1103                         if ((ia = (INA)ifa_ifwithaddr((SA)&ipaddr)) == 0 &&
 1104                             (ia = ip_rtaddr(ipaddr.sin_addr)) == 0) {
 1105                                 type = ICMP_UNREACH;
 1106                                 code = ICMP_UNREACH_HOST;
 1107                                 goto bad;
 1108                         }
 1109                         bcopy((caddr_t)&ia->ia_addr.sin_addr,
 1110                             (caddr_t)(cp + off), sizeof(struct in_addr));
 1111                         cp[IPOPT_OFFSET] += sizeof(struct in_addr);
 1112                         break;
 1113 
 1114                 case IPOPT_TS:
 1115                         code = cp - (u_char *)ip;
 1116                         if (optlen < sizeof(struct ip_timestamp))
 1117                                 goto bad;
 1118                         bcopy(cp, &ipt, sizeof(struct ip_timestamp));
 1119                         if (ipt.ipt_ptr < 5 || ipt.ipt_len < 5)
 1120                                 goto bad;
 1121                         if (ipt.ipt_ptr - 1 + sizeof(n_time) > ipt.ipt_len) {
 1122                                 if (++ipt.ipt_oflw == 0)
 1123                                         goto bad;
 1124                                 break;
 1125                         }
 1126                         bcopy(cp + ipt.ipt_ptr - 1, &sin, sizeof sin);
 1127                         switch (ipt.ipt_flg) {
 1128 
 1129                         case IPOPT_TS_TSONLY:
 1130                                 break;
 1131 
 1132                         case IPOPT_TS_TSANDADDR:
 1133                                 if (ipt.ipt_ptr - 1 + sizeof(n_time) +
 1134                                     sizeof(struct in_addr) > ipt.ipt_len)
 1135                                         goto bad;
 1136                                 ipaddr.sin_addr = dst;
 1137                                 ia = (INA)ifaof_ifpforaddr((SA)&ipaddr,
 1138                                                             m->m_pkthdr.rcvif);
 1139                                 if (ia == 0)
 1140                                         continue;
 1141                                 bcopy((caddr_t)&ia->ia_addr.sin_addr,
 1142                                     (caddr_t)&sin, sizeof(struct in_addr));
 1143                                 ipt.ipt_ptr += sizeof(struct in_addr);
 1144                                 break;
 1145 
 1146                         case IPOPT_TS_PRESPEC:
 1147                                 if (ipt.ipt_ptr - 1 + sizeof(n_time) +
 1148                                     sizeof(struct in_addr) > ipt.ipt_len)
 1149                                         goto bad;
 1150                                 bcopy((caddr_t)&sin, (caddr_t)&ipaddr.sin_addr,
 1151                                     sizeof(struct in_addr));
 1152                                 if (ifa_ifwithaddr((SA)&ipaddr) == 0)
 1153                                         continue;
 1154                                 ipt.ipt_ptr += sizeof(struct in_addr);
 1155                                 break;
 1156 
 1157                         default:
 1158                                 /* XXX can't take &ipt->ipt_flg */
 1159                                 code = (u_char *)&ipt.ipt_ptr -
 1160                                     (u_char *)ip + 1;
 1161                                 goto bad;
 1162                         }
 1163                         ntime = iptime();
 1164                         bcopy((caddr_t)&ntime, (caddr_t)cp + ipt.ipt_ptr - 1,
 1165                             sizeof(n_time));
 1166                         ipt.ipt_ptr += sizeof(n_time);
 1167                 }
 1168         }
 1169         if (forward && ipforwarding) {
 1170                 ip_forward(m, 1);
 1171                 return (1);
 1172         }
 1173         return (0);
 1174 bad:
 1175         icmp_error(m, type, code, 0, 0);
 1176         ipstat.ips_badoptions++;
 1177         return (1);
 1178 }
 1179 
 1180 /*
 1181  * Given address of next destination (final or next hop),
 1182  * return internet address info of interface to be used to get there.
 1183  */
 1184 struct in_ifaddr *
 1185 ip_rtaddr(dst)
 1186          struct in_addr dst;
 1187 {
 1188         struct sockaddr_in *sin;
 1189 
 1190         sin = satosin(&ipforward_rt.ro_dst);
 1191 
 1192         if (ipforward_rt.ro_rt == 0 || dst.s_addr != sin->sin_addr.s_addr) {
 1193                 if (ipforward_rt.ro_rt) {
 1194                         RTFREE(ipforward_rt.ro_rt);
 1195                         ipforward_rt.ro_rt = 0;
 1196                 }
 1197                 sin->sin_family = AF_INET;
 1198                 sin->sin_len = sizeof(*sin);
 1199                 sin->sin_addr = dst;
 1200 
 1201                 rtalloc(&ipforward_rt);
 1202         }
 1203         if (ipforward_rt.ro_rt == 0)
 1204                 return ((struct in_ifaddr *)0);
 1205         return (ifatoia(ipforward_rt.ro_rt->rt_ifa));
 1206 }
 1207 
 1208 /*
 1209  * Save incoming source route for use in replies,
 1210  * to be picked up later by ip_srcroute if the receiver is interested.
 1211  */
 1212 void
 1213 save_rte(option, dst)
 1214         u_char *option;
 1215         struct in_addr dst;
 1216 {
 1217         unsigned olen;
 1218 
 1219         olen = option[IPOPT_OLEN];
 1220 #ifdef DIAGNOSTIC
 1221         if (ipprintfs)
 1222                 printf("save_rte: olen %d\n", olen);
 1223 #endif /* 0 */
 1224         if (olen > sizeof(ip_srcrt) - (1 + sizeof(dst)))
 1225                 return;
 1226         bcopy((caddr_t)option, (caddr_t)ip_srcrt.srcopt, olen);
 1227         ip_nhops = (olen - IPOPT_OFFSET - 1) / sizeof(struct in_addr);
 1228         ip_srcrt.dst = dst;
 1229 }
 1230 
 1231 /*
 1232  * Check whether we do proxy ARP for this address and we point to ourselves.
 1233  * Code shamelessly copied from arplookup().
 1234  */
 1235 int
 1236 ip_weadvertise(addr)
 1237         u_int32_t addr;
 1238 {
 1239         struct rtentry *rt;
 1240         struct ifnet *ifp;
 1241         struct ifaddr *ifa;
 1242         struct sockaddr_inarp sin;
 1243 
 1244         sin.sin_len = sizeof(sin);
 1245         sin.sin_family = AF_INET;
 1246         sin.sin_addr.s_addr = addr;
 1247         sin.sin_other = SIN_PROXY;
 1248         rt = rtalloc1(sintosa(&sin), 0, 0);     /* XXX other tables? */
 1249         if (rt == 0)
 1250                 return 0;
 1251 
 1252         if ((rt->rt_flags & RTF_GATEWAY) || (rt->rt_flags & RTF_LLINFO) == 0 ||
 1253             rt->rt_gateway->sa_family != AF_LINK) {
 1254                 RTFREE(rt);
 1255                 return 0;
 1256         }
 1257 
 1258         TAILQ_FOREACH(ifp, &ifnet, if_list)
 1259                 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
 1260                         if (ifa->ifa_addr->sa_family != rt->rt_gateway->sa_family)
 1261                                 continue;
 1262 
 1263                         if (!bcmp(LLADDR((struct sockaddr_dl *)ifa->ifa_addr),
 1264                             LLADDR((struct sockaddr_dl *)rt->rt_gateway),
 1265                             ETHER_ADDR_LEN)) {
 1266                                 RTFREE(rt);
 1267                                 return 1;
 1268                         }
 1269                 }
 1270 
 1271         RTFREE(rt);
 1272         return 0;
 1273 }
 1274 
 1275 /*
 1276  * Retrieve incoming source route for use in replies,
 1277  * in the same form used by setsockopt.
 1278  * The first hop is placed before the options, will be removed later.
 1279  */
 1280 struct mbuf *
 1281 ip_srcroute()
 1282 {
 1283         struct in_addr *p, *q;
 1284         struct mbuf *m;
 1285 
 1286         if (ip_nhops == 0)
 1287                 return ((struct mbuf *)0);
 1288         m = m_get(M_DONTWAIT, MT_SOOPTS);
 1289         if (m == 0)
 1290                 return ((struct mbuf *)0);
 1291 
 1292 #define OPTSIZ  (sizeof(ip_srcrt.nop) + sizeof(ip_srcrt.srcopt))
 1293 
 1294         /* length is (nhops+1)*sizeof(addr) + sizeof(nop + srcrt header) */
 1295         m->m_len = ip_nhops * sizeof(struct in_addr) + sizeof(struct in_addr) +
 1296             OPTSIZ;
 1297 #ifdef DIAGNOSTIC
 1298         if (ipprintfs)
 1299                 printf("ip_srcroute: nhops %d mlen %d", ip_nhops, m->m_len);
 1300 #endif
 1301 
 1302         /*
 1303          * First save first hop for return route
 1304          */
 1305         p = &ip_srcrt.route[ip_nhops - 1];
 1306         *(mtod(m, struct in_addr *)) = *p--;
 1307 #ifdef DIAGNOSTIC
 1308         if (ipprintfs)
 1309                 printf(" hops %x", ntohl(mtod(m, struct in_addr *)->s_addr));
 1310 #endif
 1311 
 1312         /*
 1313          * Copy option fields and padding (nop) to mbuf.
 1314          */
 1315         ip_srcrt.nop = IPOPT_NOP;
 1316         ip_srcrt.srcopt[IPOPT_OFFSET] = IPOPT_MINOFF;
 1317         bcopy((caddr_t)&ip_srcrt.nop,
 1318             mtod(m, caddr_t) + sizeof(struct in_addr), OPTSIZ);
 1319         q = (struct in_addr *)(mtod(m, caddr_t) +
 1320             sizeof(struct in_addr) + OPTSIZ);
 1321 #undef OPTSIZ
 1322         /*
 1323          * Record return path as an IP source route,
 1324          * reversing the path (pointers are now aligned).
 1325          */
 1326         while (p >= ip_srcrt.route) {
 1327 #ifdef DIAGNOSTIC
 1328                 if (ipprintfs)
 1329                         printf(" %x", ntohl(q->s_addr));
 1330 #endif
 1331                 *q++ = *p--;
 1332         }
 1333         /*
 1334          * Last hop goes to final destination.
 1335          */
 1336         *q = ip_srcrt.dst;
 1337 #ifdef DIAGNOSTIC
 1338         if (ipprintfs)
 1339                 printf(" %x\n", ntohl(q->s_addr));
 1340 #endif
 1341         return (m);
 1342 }
 1343 
 1344 /*
 1345  * Strip out IP options, at higher
 1346  * level protocol in the kernel.
 1347  * Second argument is buffer to which options
 1348  * will be moved, and return value is their length.
 1349  * XXX should be deleted; last arg currently ignored.
 1350  */
 1351 void
 1352 ip_stripoptions(m, mopt)
 1353         struct mbuf *m;
 1354         struct mbuf *mopt;
 1355 {
 1356         int i;
 1357         struct ip *ip = mtod(m, struct ip *);
 1358         caddr_t opts;
 1359         int olen;
 1360 
 1361         olen = (ip->ip_hl<<2) - sizeof (struct ip);
 1362         opts = (caddr_t)(ip + 1);
 1363         i = m->m_len - (sizeof (struct ip) + olen);
 1364         bcopy(opts  + olen, opts, (unsigned)i);
 1365         m->m_len -= olen;
 1366         if (m->m_flags & M_PKTHDR)
 1367                 m->m_pkthdr.len -= olen;
 1368         ip->ip_hl = sizeof(struct ip) >> 2;
 1369 }
 1370 
 1371 int inetctlerrmap[PRC_NCMDS] = {
 1372         0,              0,              0,              0,
 1373         0,              EMSGSIZE,       EHOSTDOWN,      EHOSTUNREACH,
 1374         EHOSTUNREACH,   EHOSTUNREACH,   ECONNREFUSED,   ECONNREFUSED,
 1375         EMSGSIZE,       EHOSTUNREACH,   0,              0,
 1376         0,              0,              0,              0,
 1377         ENOPROTOOPT
 1378 };
 1379 
 1380 /*
 1381  * Forward a packet.  If some error occurs return the sender
 1382  * an icmp packet.  Note we can't always generate a meaningful
 1383  * icmp message because icmp doesn't have a large enough repertoire
 1384  * of codes and types.
 1385  *
 1386  * If not forwarding, just drop the packet.  This could be confusing
 1387  * if ipforwarding was zero but some routing protocol was advancing
 1388  * us as a gateway to somewhere.  However, we must let the routing
 1389  * protocol deal with that.
 1390  *
 1391  * The srcrt parameter indicates whether the packet is being forwarded
 1392  * via a source route.
 1393  */
 1394 void
 1395 ip_forward(m, srcrt)
 1396         struct mbuf *m;
 1397         int srcrt;
 1398 {
 1399         struct ip *ip = mtod(m, struct ip *);
 1400         struct sockaddr_in *sin;
 1401         struct rtentry *rt;
 1402         int error, type = 0, code = 0, destmtu = 0, rtableid = 0;
 1403         struct mbuf *mcopy;
 1404         n_long dest;
 1405 
 1406         dest = 0;
 1407 #ifdef DIAGNOSTIC
 1408         if (ipprintfs)
 1409                 printf("forward: src %x dst %x ttl %x\n", ip->ip_src.s_addr,
 1410                     ip->ip_dst.s_addr, ip->ip_ttl);
 1411 #endif
 1412         if (m->m_flags & M_BCAST || in_canforward(ip->ip_dst) == 0) {
 1413                 ipstat.ips_cantforward++;
 1414                 m_freem(m);
 1415                 return;
 1416         }
 1417         if (ip->ip_ttl <= IPTTLDEC) {
 1418                 icmp_error(m, ICMP_TIMXCEED, ICMP_TIMXCEED_INTRANS, dest, 0);
 1419                 return;
 1420         }
 1421 
 1422 #if NPF > 0
 1423         rtableid = m->m_pkthdr.pf.rtableid;
 1424 #endif
 1425 
 1426         sin = satosin(&ipforward_rt.ro_dst);
 1427         if ((rt = ipforward_rt.ro_rt) == 0 ||
 1428             ip->ip_dst.s_addr != sin->sin_addr.s_addr ||
 1429             rtableid != ipforward_rtableid) {
 1430                 if (ipforward_rt.ro_rt) {
 1431                         RTFREE(ipforward_rt.ro_rt);
 1432                         ipforward_rt.ro_rt = 0;
 1433                 }
 1434                 sin->sin_family = AF_INET;
 1435                 sin->sin_len = sizeof(*sin);
 1436                 sin->sin_addr = ip->ip_dst;
 1437 
 1438                 rtalloc_mpath(&ipforward_rt, &ip->ip_src.s_addr, rtableid);
 1439                 if (ipforward_rt.ro_rt == 0) {
 1440                         icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, dest, 0);
 1441                         return;
 1442                 }
 1443                 ipforward_rtableid = rtableid;
 1444                 rt = ipforward_rt.ro_rt;
 1445         }
 1446 
 1447         /*
 1448          * Save at most 68 bytes of the packet in case
 1449          * we need to generate an ICMP message to the src.
 1450          * Pullup to avoid sharing mbuf cluster between m and mcopy.
 1451          */
 1452         mcopy = m_copym(m, 0, min(ntohs(ip->ip_len), 68), M_DONTWAIT);
 1453         if (mcopy)
 1454                 mcopy = m_pullup(mcopy, min(ntohs(ip->ip_len), 68));
 1455 
 1456         ip->ip_ttl -= IPTTLDEC;
 1457 
 1458         /*
 1459          * If forwarding packet using same interface that it came in on,
 1460          * perhaps should send a redirect to sender to shortcut a hop.
 1461          * Only send redirect if source is sending directly to us,
 1462          * and if packet was not source routed (or has any options).
 1463          * Also, don't send redirect if forwarding using a default route
 1464          * or a route modified by a redirect.
 1465          * Don't send redirect if we advertise destination's arp address
 1466          * as ours (proxy arp).
 1467          */
 1468         if (rt->rt_ifp == m->m_pkthdr.rcvif &&
 1469             (rt->rt_flags & (RTF_DYNAMIC|RTF_MODIFIED)) == 0 &&
 1470             satosin(rt_key(rt))->sin_addr.s_addr != 0 &&
 1471             ipsendredirects && !srcrt &&
 1472             !ip_weadvertise(satosin(rt_key(rt))->sin_addr.s_addr)) {
 1473                 if (rt->rt_ifa &&
 1474                     (ip->ip_src.s_addr & ifatoia(rt->rt_ifa)->ia_subnetmask) ==
 1475                     ifatoia(rt->rt_ifa)->ia_subnet) {
 1476                     if (rt->rt_flags & RTF_GATEWAY)
 1477                         dest = satosin(rt->rt_gateway)->sin_addr.s_addr;
 1478                     else
 1479                         dest = ip->ip_dst.s_addr;
 1480                     /* Router requirements says to only send host redirects */
 1481                     type = ICMP_REDIRECT;
 1482                     code = ICMP_REDIRECT_HOST;
 1483 #ifdef DIAGNOSTIC
 1484                     if (ipprintfs)
 1485                         printf("redirect (%d) to %x\n", code, (u_int32_t)dest);
 1486 #endif
 1487                 }
 1488         }
 1489 
 1490         error = ip_output(m, (struct mbuf *)NULL, &ipforward_rt,
 1491             (IP_FORWARDING | (ip_directedbcast ? IP_ALLOWBROADCAST : 0)),
 1492             (void *)NULL, (void *)NULL);
 1493         if (error)
 1494                 ipstat.ips_cantforward++;
 1495         else {
 1496                 ipstat.ips_forward++;
 1497                 if (type)
 1498                         ipstat.ips_redirectsent++;
 1499                 else
 1500                         goto freecopy;
 1501         }
 1502         if (mcopy == NULL)
 1503                 goto freert;
 1504 
 1505         switch (error) {
 1506 
 1507         case 0:                         /* forwarded, but need redirect */
 1508                 /* type, code set above */
 1509                 break;
 1510 
 1511         case ENETUNREACH:               /* shouldn't happen, checked above */
 1512         case EHOSTUNREACH:
 1513         case ENETDOWN:
 1514         case EHOSTDOWN:
 1515         default:
 1516                 type = ICMP_UNREACH;
 1517                 code = ICMP_UNREACH_HOST;
 1518                 break;
 1519 
 1520         case EMSGSIZE:
 1521                 type = ICMP_UNREACH;
 1522                 code = ICMP_UNREACH_NEEDFRAG;
 1523 
 1524 #ifdef IPSEC
 1525                 if (ipforward_rt.ro_rt) {
 1526                         struct rtentry *rt = ipforward_rt.ro_rt;
 1527 
 1528                         if (rt->rt_rmx.rmx_mtu)
 1529                                 destmtu = rt->rt_rmx.rmx_mtu;
 1530                         else
 1531                                 destmtu = ipforward_rt.ro_rt->rt_ifp->if_mtu;
 1532                 }
 1533 #endif /*IPSEC*/
 1534                 ipstat.ips_cantfrag++;
 1535                 break;
 1536 
 1537         case ENOBUFS:
 1538 #if 1
 1539                 /*
 1540                  * a router should not generate ICMP_SOURCEQUENCH as
 1541                  * required in RFC1812 Requirements for IP Version 4 Routers.
 1542                  * source quench could be a big problem under DoS attacks,
 1543                  * or the underlying interface is rate-limited.
 1544                  */
 1545                 goto freecopy;
 1546 #else
 1547                 type = ICMP_SOURCEQUENCH;
 1548                 code = 0;
 1549                 break;
 1550 #endif
 1551         }
 1552 
 1553         icmp_error(mcopy, type, code, dest, destmtu);
 1554         goto freert;
 1555 
 1556  freecopy:
 1557         if (mcopy)
 1558                 m_free(mcopy);
 1559  freert:
 1560 #ifndef SMALL_KERNEL
 1561         if (ipmultipath && ipforward_rt.ro_rt &&
 1562             (ipforward_rt.ro_rt->rt_flags & RTF_MPATH)) {
 1563                 RTFREE(ipforward_rt.ro_rt);
 1564                 ipforward_rt.ro_rt = 0;
 1565         }
 1566 #endif
 1567         return;
 1568 }
 1569 
 1570 int
 1571 ip_sysctl(name, namelen, oldp, oldlenp, newp, newlen)
 1572         int *name;
 1573         u_int namelen;
 1574         void *oldp;
 1575         size_t *oldlenp;
 1576         void *newp;
 1577         size_t newlen;
 1578 {
 1579         int error;
 1580 #ifdef MROUTING
 1581         extern int ip_mrtproto;
 1582         extern struct mrtstat mrtstat;
 1583 #endif
 1584 
 1585         /* Almost all sysctl names at this level are terminal. */
 1586         if (namelen != 1 && name[0] != IPCTL_IFQUEUE)
 1587                 return (ENOTDIR);
 1588 
 1589         switch (name[0]) {
 1590 #ifdef notyet
 1591         case IPCTL_DEFMTU:
 1592                 return (sysctl_int(oldp, oldlenp, newp, newlen, &ip_mtu));
 1593 #endif
 1594         case IPCTL_SOURCEROUTE:
 1595                 /*
 1596                  * Don't allow this to change in a secure environment.
 1597                  */
 1598                 if (newp && securelevel > 0)
 1599                         return (EPERM);
 1600                 return (sysctl_int(oldp, oldlenp, newp, newlen,
 1601                     &ip_dosourceroute));
 1602         case IPCTL_MTUDISC:
 1603                 error = sysctl_int(oldp, oldlenp, newp, newlen,
 1604                     &ip_mtudisc);
 1605                 if (ip_mtudisc != 0 && ip_mtudisc_timeout_q == NULL) {
 1606                         ip_mtudisc_timeout_q =
 1607                             rt_timer_queue_create(ip_mtudisc_timeout);
 1608                 } else if (ip_mtudisc == 0 && ip_mtudisc_timeout_q != NULL) {
 1609                         rt_timer_queue_destroy(ip_mtudisc_timeout_q, TRUE);
 1610                         Free(ip_mtudisc_timeout_q);
 1611                         ip_mtudisc_timeout_q = NULL;
 1612                 }
 1613                 return error;
 1614         case IPCTL_MTUDISCTIMEOUT:
 1615                 error = sysctl_int(oldp, oldlenp, newp, newlen,
 1616                    &ip_mtudisc_timeout);
 1617                 if (ip_mtudisc_timeout_q != NULL)
 1618                         rt_timer_queue_change(ip_mtudisc_timeout_q,
 1619                                               ip_mtudisc_timeout);
 1620                 return (error);
 1621         case IPCTL_IPSEC_ENC_ALGORITHM:
 1622                 return (sysctl_tstring(oldp, oldlenp, newp, newlen,
 1623                                        ipsec_def_enc, sizeof(ipsec_def_enc)));
 1624         case IPCTL_IPSEC_AUTH_ALGORITHM:
 1625                 return (sysctl_tstring(oldp, oldlenp, newp, newlen,
 1626                                        ipsec_def_auth,
 1627                                        sizeof(ipsec_def_auth)));
 1628         case IPCTL_IPSEC_IPCOMP_ALGORITHM:
 1629                 return (sysctl_tstring(oldp, oldlenp, newp, newlen,
 1630                                        ipsec_def_comp,
 1631                                        sizeof(ipsec_def_comp)));
 1632         case IPCTL_IFQUEUE:
 1633                 return (sysctl_ifq(name + 1, namelen - 1,
 1634                     oldp, oldlenp, newp, newlen, &ipintrq));
 1635         case IPCTL_STATS:
 1636                 if (newp != NULL)
 1637                         return (EPERM);
 1638                 return (sysctl_struct(oldp, oldlenp, newp, newlen,
 1639                     &ipstat, sizeof(ipstat)));
 1640         case IPCTL_MRTSTATS:
 1641 #ifdef MROUTING
 1642                 if (newp != NULL)
 1643                         return (EPERM);
 1644                 return (sysctl_struct(oldp, oldlenp, newp, newlen,
 1645                     &mrtstat, sizeof(mrtstat)));
 1646 #else
 1647                 return (EOPNOTSUPP);
 1648 #endif
 1649         case IPCTL_MRTPROTO:
 1650 #ifdef MROUTING
 1651                 return (sysctl_rdint(oldp, oldlenp, newp, ip_mrtproto));
 1652 #else
 1653                 return (EOPNOTSUPP);
 1654 #endif
 1655         default:
 1656                 if (name[0] < IPCTL_MAXID)
 1657                         return (sysctl_int_arr(ipctl_vars, name, namelen,
 1658                             oldp, oldlenp, newp, newlen));
 1659                 return (EOPNOTSUPP);
 1660         }
 1661         /* NOTREACHED */
 1662 }
 1663 
 1664 void
 1665 ip_savecontrol(struct inpcb *inp, struct mbuf **mp, struct ip *ip,
 1666     struct mbuf *m)
 1667 {
 1668 #ifdef SO_TIMESTAMP
 1669         if (inp->inp_socket->so_options & SO_TIMESTAMP) {
 1670                 struct timeval tv;
 1671 
 1672                 microtime(&tv);
 1673                 *mp = sbcreatecontrol((caddr_t) &tv, sizeof(tv),
 1674                     SCM_TIMESTAMP, SOL_SOCKET);
 1675                 if (*mp)
 1676                         mp = &(*mp)->m_next;
 1677         }
 1678 #endif
 1679         if (inp->inp_flags & INP_RECVDSTADDR) {
 1680                 *mp = sbcreatecontrol((caddr_t) &ip->ip_dst,
 1681                     sizeof(struct in_addr), IP_RECVDSTADDR, IPPROTO_IP);
 1682                 if (*mp)
 1683                         mp = &(*mp)->m_next;
 1684         }
 1685 #ifdef notyet
 1686         /* this code is broken and will probably never be fixed. */
 1687         /* options were tossed already */
 1688         if (inp->inp_flags & INP_RECVOPTS) {
 1689                 *mp = sbcreatecontrol((caddr_t) opts_deleted_above,
 1690                     sizeof(struct in_addr), IP_RECVOPTS, IPPROTO_IP);
 1691                 if (*mp)
 1692                         mp = &(*mp)->m_next;
 1693         }
 1694         /* ip_srcroute doesn't do what we want here, need to fix */
 1695         if (inp->inp_flags & INP_RECVRETOPTS) {
 1696                 *mp = sbcreatecontrol((caddr_t) ip_srcroute(),
 1697                     sizeof(struct in_addr), IP_RECVRETOPTS, IPPROTO_IP);
 1698                 if (*mp)
 1699                         mp = &(*mp)->m_next;
 1700         }
 1701 #endif
 1702         if (inp->inp_flags & INP_RECVIF) {
 1703                 struct sockaddr_dl sdl;
 1704                 struct ifnet *ifp;
 1705 
 1706                 if ((ifp = m->m_pkthdr.rcvif) == NULL ||
 1707                     ifp->if_sadl == NULL) {
 1708                         bzero(&sdl, sizeof(sdl));
 1709                         sdl.sdl_len = offsetof(struct sockaddr_dl, sdl_data[0]);
 1710                         sdl.sdl_family = AF_LINK;
 1711                         sdl.sdl_index = ifp != NULL ? ifp->if_index : 0;
 1712                         sdl.sdl_nlen = sdl.sdl_alen = sdl.sdl_slen = 0;
 1713                         *mp = sbcreatecontrol((caddr_t) &sdl, sdl.sdl_len,
 1714                             IP_RECVIF, IPPROTO_IP);
 1715                 } else {
 1716                         *mp = sbcreatecontrol((caddr_t) ifp->if_sadl,
 1717                             ifp->if_sadl->sdl_len, IP_RECVIF, IPPROTO_IP);
 1718                 }
 1719                 if (*mp)
 1720                         mp = &(*mp)->m_next;
 1721         }
 1722         if (inp->inp_flags & INP_RECVTTL) {
 1723                 *mp = sbcreatecontrol((caddr_t) &ip->ip_ttl,
 1724                     sizeof(u_char), IP_RECVTTL, IPPROTO_IP);
 1725                 if (*mp)
 1726                         mp = &(*mp)->m_next;
 1727         }
 1728 }
 1729 

Cache object: 7989223505f815cd66adc02cc5a2d764


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