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/netinet6/esp_output.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 /*      $NetBSD: esp_output.c,v 1.18 2003/09/07 15:59:36 itojun Exp $   */
    2 /*      $KAME: esp_output.c,v 1.44 2001/07/26 06:53:15 jinmei Exp $     */
    3 
    4 /*
    5  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
    6  * 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 project 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 PROJECT 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 PROJECT 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 
   33 /*
   34  * RFC1827/2406 Encapsulated Security Payload.
   35  */
   36 
   37 #include <sys/cdefs.h>
   38 __KERNEL_RCSID(0, "$NetBSD: esp_output.c,v 1.18 2003/09/07 15:59:36 itojun Exp $");
   39 
   40 #include "opt_inet.h"
   41 
   42 #include <sys/param.h>
   43 #include <sys/systm.h>
   44 #include <sys/malloc.h>
   45 #include <sys/mbuf.h>
   46 #include <sys/domain.h>
   47 #include <sys/protosw.h>
   48 #include <sys/socket.h>
   49 #include <sys/socketvar.h>
   50 #include <sys/errno.h>
   51 #include <sys/time.h>
   52 #include <sys/kernel.h>
   53 #include <sys/syslog.h>
   54 
   55 #include <net/if.h>
   56 #include <net/route.h>
   57 
   58 #include <netinet/in.h>
   59 #include <netinet/in_systm.h>
   60 #include <netinet/ip.h>
   61 #include <netinet/in_var.h>
   62 
   63 #ifdef INET6
   64 #include <netinet/ip6.h>
   65 #include <netinet6/ip6_var.h>
   66 #include <netinet/icmp6.h>
   67 #endif
   68 
   69 #include <netinet6/ipsec.h>
   70 #include <netinet6/ah.h>
   71 #include <netinet6/esp.h>
   72 #include <netkey/key.h>
   73 #include <netkey/keydb.h>
   74 
   75 #include <net/net_osdep.h>
   76 
   77 static int esp_output __P((struct mbuf *, u_char *, struct mbuf *,
   78         struct ipsecrequest *, int));
   79 
   80 /*
   81  * compute ESP header size.
   82  */
   83 size_t
   84 esp_hdrsiz(isr)
   85         struct ipsecrequest *isr;
   86 {
   87         struct secasvar *sav;
   88         const struct esp_algorithm *algo;
   89         const struct ah_algorithm *aalgo;
   90         size_t ivlen;
   91         size_t authlen;
   92         size_t hdrsiz;
   93 
   94         /* sanity check */
   95         if (isr == NULL)
   96                 panic("esp_hdrsiz: NULL was passed.");
   97 
   98         sav = isr->sav;
   99 
  100         if (isr->saidx.proto != IPPROTO_ESP)
  101                 panic("unsupported mode passed to esp_hdrsiz");
  102 
  103         if (sav == NULL)
  104                 goto estimate;
  105         if (sav->state != SADB_SASTATE_MATURE
  106          && sav->state != SADB_SASTATE_DYING)
  107                 goto estimate;
  108 
  109         /* we need transport mode ESP. */
  110         algo = esp_algorithm_lookup(sav->alg_enc);
  111         if (!algo)
  112                 goto estimate;
  113         ivlen = sav->ivlen;
  114         if (ivlen < 0)
  115                 goto estimate;
  116 
  117         /*
  118          * XXX
  119          * right now we don't calcurate the padding size.  simply
  120          * treat the padding size as constant, for simplicity.
  121          *
  122          * XXX variable size padding support
  123          */
  124         if (sav->flags & SADB_X_EXT_OLD) {
  125                 /* RFC 1827 */
  126                 hdrsiz = sizeof(struct esp) + ivlen +
  127                     esp_max_padbound() - 1 + 2;
  128         } else {
  129                 /* RFC 2406 */
  130                 aalgo = ah_algorithm_lookup(sav->alg_auth);
  131                 if (aalgo && sav->replay && sav->key_auth)
  132                         authlen = (aalgo->sumsiz)(sav);
  133                 else
  134                         authlen = 0;
  135                 hdrsiz = sizeof(struct newesp) + ivlen +
  136                     esp_max_padbound() - 1 + 2 + authlen;
  137         }
  138 
  139         return hdrsiz;
  140 
  141    estimate:
  142         /*
  143          * ASSUMING:
  144          *      sizeof(struct newesp) > sizeof(struct esp).
  145          *      esp_max_ivlen() = max ivlen for CBC mode
  146          *      esp_max_padbound - 1 =
  147          *         maximum padding length without random padding length
  148          *      2 = (Pad Length field) + (Next Header field).
  149          *      AH_MAXSUMSIZE = maximum ICV we support.
  150          */
  151         return sizeof(struct newesp) + esp_max_ivlen() +
  152             esp_max_padbound() - 1 + 2 + AH_MAXSUMSIZE;
  153 }
  154 
  155 /*
  156  * Modify the packet so that the payload is encrypted.
  157  * The mbuf (m) must start with IPv4 or IPv6 header.
  158  * On failure, free the given mbuf and return NULL.
  159  *
  160  * on invocation:
  161  *      m   nexthdrp md
  162  *      v   v        v
  163  *      IP ......... payload
  164  * during the encryption:
  165  *      m   nexthdrp mprev md
  166  *      v   v        v     v
  167  *      IP ............... esp iv payload pad padlen nxthdr
  168  *                         <--><-><------><--------------->
  169  *                         esplen plen    extendsiz
  170  *                             ivlen
  171  *                         <-----> esphlen
  172  *      <-> hlen
  173  *      <-----------------> espoff
  174  */
  175 static int
  176 esp_output(m, nexthdrp, md, isr, af)
  177         struct mbuf *m;
  178         u_char *nexthdrp;
  179         struct mbuf *md;
  180         struct ipsecrequest *isr;
  181         int af;
  182 {
  183         struct mbuf *n;
  184         struct mbuf *mprev;
  185         struct esp *esp;
  186         struct esptail *esptail;
  187         struct secasvar *sav = isr->sav;
  188         const struct esp_algorithm *algo;
  189         u_int32_t spi;
  190         u_int8_t nxt = 0;
  191         size_t plen;    /* payload length to be encrypted */
  192         size_t espoff;
  193         int ivlen;
  194         int afnumber;
  195         size_t extendsiz;
  196         int error = 0;
  197         struct ipsecstat *stat;
  198 
  199         switch (af) {
  200 #ifdef INET
  201         case AF_INET:
  202                 afnumber = 4;
  203                 stat = &ipsecstat;
  204                 break;
  205 #endif
  206 #ifdef INET6
  207         case AF_INET6:
  208                 afnumber = 6;
  209                 stat = &ipsec6stat;
  210                 break;
  211 #endif
  212         default:
  213                 ipseclog((LOG_ERR, "esp_output: unsupported af %d\n", af));
  214                 return 0;       /* no change at all */
  215         }
  216 
  217         /* some sanity check */
  218         if ((sav->flags & SADB_X_EXT_OLD) == 0 && !sav->replay) {
  219                 switch (af) {
  220 #ifdef INET
  221                 case AF_INET:
  222                     {
  223                         struct ip *ip;
  224 
  225                         ip = mtod(m, struct ip *);
  226                         ipseclog((LOG_DEBUG, "esp4_output: internal error: "
  227                                 "sav->replay is null: %x->%x, SPI=%u\n",
  228                                 (u_int32_t)ntohl(ip->ip_src.s_addr),
  229                                 (u_int32_t)ntohl(ip->ip_dst.s_addr),
  230                                 (u_int32_t)ntohl(sav->spi)));
  231                         ipsecstat.out_inval++;
  232                         break;
  233                     }
  234 #endif /* INET */
  235 #ifdef INET6
  236                 case AF_INET6:
  237                         ipseclog((LOG_DEBUG, "esp6_output: internal error: "
  238                                 "sav->replay is null: SPI=%u\n",
  239                                 (u_int32_t)ntohl(sav->spi)));
  240                         ipsec6stat.out_inval++;
  241                         break;
  242 #endif /* INET6 */
  243                 default:
  244                         panic("esp_output: should not reach here");
  245                 }
  246                 m_freem(m);
  247                 return EINVAL;
  248         }
  249 
  250         algo = esp_algorithm_lookup(sav->alg_enc);
  251         if (!algo) {
  252                 ipseclog((LOG_ERR, "esp_output: unsupported algorithm: "
  253                     "SPI=%u\n", (u_int32_t)ntohl(sav->spi)));
  254                 m_freem(m);
  255                 return EINVAL;
  256         }
  257         spi = sav->spi;
  258         ivlen = sav->ivlen;
  259         /* should be okey */
  260         if (ivlen < 0) {
  261                 panic("invalid ivlen");
  262         }
  263 
  264     {
  265         /*
  266          * insert ESP header.
  267          * XXX inserts ESP header right after IPv4 header.  should
  268          * chase the header chain.
  269          * XXX sequential number
  270          */
  271 #ifdef INET
  272         struct ip *ip = NULL;
  273 #endif
  274 #ifdef INET6
  275         struct ip6_hdr *ip6 = NULL;
  276 #endif
  277         size_t esplen;  /* sizeof(struct esp/newesp) */
  278         size_t esphlen; /* sizeof(struct esp/newesp) + ivlen */
  279         size_t hlen = 0;        /* ip header len */
  280 
  281         if (sav->flags & SADB_X_EXT_OLD) {
  282                 /* RFC 1827 */
  283                 esplen = sizeof(struct esp);
  284         } else {
  285                 /* RFC 2406 */
  286                 if (sav->flags & SADB_X_EXT_DERIV)
  287                         esplen = sizeof(struct esp);
  288                 else
  289                         esplen = sizeof(struct newesp);
  290         }
  291         esphlen = esplen + ivlen;
  292 
  293         for (mprev = m; mprev && mprev->m_next != md; mprev = mprev->m_next)
  294                 ;
  295         if (mprev == NULL || mprev->m_next != md) {
  296                 ipseclog((LOG_DEBUG, "esp%d_output: md is not in chain\n",
  297                     afnumber));
  298                 m_freem(m);
  299                 return EINVAL;
  300         }
  301 
  302         plen = 0;
  303         for (n = md; n; n = n->m_next)
  304                 plen += n->m_len;
  305 
  306         switch (af) {
  307 #ifdef INET
  308         case AF_INET:
  309                 ip = mtod(m, struct ip *);
  310                 hlen = ip->ip_hl << 2;
  311                 break;
  312 #endif
  313 #ifdef INET6
  314         case AF_INET6:
  315                 ip6 = mtod(m, struct ip6_hdr *);
  316                 hlen = sizeof(*ip6);
  317                 break;
  318 #endif
  319         }
  320 
  321         /* make the packet over-writable */
  322         mprev->m_next = NULL;
  323         if ((md = ipsec_copypkt(md)) == NULL) {
  324                 m_freem(m);
  325                 error = ENOBUFS;
  326                 goto fail;
  327         }
  328         mprev->m_next = md;
  329 
  330         espoff = m->m_pkthdr.len - plen;
  331 
  332         /*
  333          * grow the mbuf to accomodate ESP header.
  334          * before: IP ... payload
  335          * after:  IP ... ESP IV payload
  336          */
  337         if (M_LEADINGSPACE(md) < esphlen || (md->m_flags & M_EXT) != 0) {
  338                 MGET(n, M_DONTWAIT, MT_DATA);
  339                 if (!n) {
  340                         m_freem(m);
  341                         error = ENOBUFS;
  342                         goto fail;
  343                 }
  344                 n->m_len = esphlen;
  345                 mprev->m_next = n;
  346                 n->m_next = md;
  347                 m->m_pkthdr.len += esphlen;
  348                 esp = mtod(n, struct esp *);
  349         } else {
  350                 md->m_len += esphlen;
  351                 md->m_data -= esphlen;
  352                 m->m_pkthdr.len += esphlen;
  353                 esp = mtod(md, struct esp *);
  354         }
  355 
  356         nxt = *nexthdrp;
  357         *nexthdrp = IPPROTO_ESP;
  358         switch (af) {
  359 #ifdef INET
  360         case AF_INET:
  361                 if (esphlen < (IP_MAXPACKET - ntohs(ip->ip_len)))
  362                         ip->ip_len = htons(ntohs(ip->ip_len) + esphlen);
  363                 else {
  364                         ipseclog((LOG_ERR,
  365                             "IPv4 ESP output: size exceeds limit\n"));
  366                         ipsecstat.out_inval++;
  367                         m_freem(m);
  368                         error = EMSGSIZE;
  369                         goto fail;
  370                 }
  371                 break;
  372 #endif
  373 #ifdef INET6
  374         case AF_INET6:
  375                 /* total packet length will be computed in ip6_output() */
  376                 break;
  377 #endif
  378         }
  379     }
  380 
  381         /* initialize esp header. */
  382         esp->esp_spi = spi;
  383         if ((sav->flags & SADB_X_EXT_OLD) == 0) {
  384                 struct newesp *nesp;
  385                 nesp = (struct newesp *)esp;
  386                 if (sav->replay->count == ~0) {
  387                         if ((sav->flags & SADB_X_EXT_CYCSEQ) == 0) {
  388                                 /* XXX Is it noisy ? */
  389                                 ipseclog((LOG_WARNING,
  390                                     "replay counter overflowed. %s\n",
  391                                     ipsec_logsastr(sav)));
  392                                 stat->out_inval++;
  393                                 m_freem(m);
  394                                 return EINVAL;
  395                         }
  396                 }
  397                 sav->replay->count++;
  398                 /*
  399                  * XXX sequence number must not be cycled, if the SA is
  400                  * installed by IKE daemon.
  401                  */
  402                 nesp->esp_seq = htonl(sav->replay->count & 0xffffffff);
  403         }
  404 
  405     {
  406         /*
  407          * find the last mbuf. make some room for ESP trailer.
  408          */
  409 #ifdef INET
  410         struct ip *ip = NULL;
  411 #endif
  412         size_t padbound;
  413         u_char *extend;
  414         int i;
  415 
  416         if (algo->padbound)
  417                 padbound = algo->padbound;
  418         else
  419                 padbound = 4;
  420         /* ESP packet, including nxthdr field, must be length of 4n */
  421         if (padbound < 4)
  422                 padbound = 4;
  423 
  424         extendsiz = padbound - (plen % padbound);
  425         if (extendsiz == 1)
  426                 extendsiz = padbound + 1;
  427 
  428         n = m;
  429         while (n->m_next)
  430                 n = n->m_next;
  431 
  432         /*
  433          * if M_EXT, the external mbuf data may be shared among
  434          * two consequtive TCP packets, and it may be unsafe to use the
  435          * trailing space.
  436          */
  437         if (!(n->m_flags & M_EXT) && extendsiz < M_TRAILINGSPACE(n)) {
  438                 extend = mtod(n, u_char *) + n->m_len;
  439                 n->m_len += extendsiz;
  440                 m->m_pkthdr.len += extendsiz;
  441         } else {
  442                 struct mbuf *nn;
  443 
  444                 MGET(nn, M_DONTWAIT, MT_DATA);
  445                 if (!nn) {
  446                         ipseclog((LOG_DEBUG, "esp%d_output: can't alloc mbuf",
  447                             afnumber));
  448                         m_freem(m);
  449                         error = ENOBUFS;
  450                         goto fail;
  451                 }
  452                 extend = mtod(nn, u_char *);
  453                 nn->m_len = extendsiz;
  454                 nn->m_next = NULL;
  455                 n->m_next = nn;
  456                 n = nn;
  457                 m->m_pkthdr.len += extendsiz;
  458         }
  459         switch (sav->flags & SADB_X_EXT_PMASK) {
  460         case SADB_X_EXT_PRAND:
  461                 key_randomfill(extend, extendsiz);
  462                 break;
  463         case SADB_X_EXT_PZERO:
  464                 bzero(extend, extendsiz);
  465                 break;
  466         case SADB_X_EXT_PSEQ:
  467                 for (i = 0; i < extendsiz; i++)
  468                         extend[i] = (i + 1) & 0xff;
  469                 break;
  470         }
  471 
  472         /* initialize esp trailer. */
  473         esptail = (struct esptail *)
  474                 (mtod(n, u_int8_t *) + n->m_len - sizeof(struct esptail));
  475         esptail->esp_nxt = nxt;
  476         esptail->esp_padlen = extendsiz - 2;
  477 
  478         /* modify IP header (for ESP header part only) */
  479         switch (af) {
  480 #ifdef INET
  481         case AF_INET:
  482                 ip = mtod(m, struct ip *);
  483                 if (extendsiz < (IP_MAXPACKET - ntohs(ip->ip_len)))
  484                         ip->ip_len = htons(ntohs(ip->ip_len) + extendsiz);
  485                 else {
  486                         ipseclog((LOG_ERR,
  487                             "IPv4 ESP output: size exceeds limit\n"));
  488                         ipsecstat.out_inval++;
  489                         m_freem(m);
  490                         error = EMSGSIZE;
  491                         goto fail;
  492                 }
  493                 break;
  494 #endif
  495 #ifdef INET6
  496         case AF_INET6:
  497                 /* total packet length will be computed in ip6_output() */
  498                 break;
  499 #endif
  500         }
  501     }
  502 
  503         /*
  504          * pre-compute and cache intermediate key
  505          */
  506         error = esp_schedule(algo, sav);
  507         if (error) {
  508                 m_freem(m);
  509                 stat->out_inval++;
  510                 goto fail;
  511         }
  512 
  513         /*
  514          * encrypt the packet, based on security association
  515          * and the algorithm specified.
  516          */
  517         if (!algo->encrypt)
  518                 panic("internal error: no encrypt function");
  519         if ((*algo->encrypt)(m, espoff, plen + extendsiz, sav, algo, ivlen)) {
  520                 /* m is already freed */
  521                 ipseclog((LOG_ERR, "packet encryption failure\n"));
  522                 stat->out_inval++;
  523                 error = EINVAL;
  524                 goto fail;
  525         }
  526 
  527         /*
  528          * calculate ICV if required.
  529          */
  530         if (!sav->replay)
  531                 goto noantireplay;
  532         if (!sav->key_auth)
  533                 goto noantireplay;
  534         if (sav->key_auth == SADB_AALG_NONE)
  535                 goto noantireplay;
  536 
  537     {
  538         const struct ah_algorithm *aalgo;
  539         u_char authbuf[AH_MAXSUMSIZE];
  540         struct mbuf *n;
  541         u_char *p;
  542         size_t siz;
  543 #ifdef INET
  544         struct ip *ip;
  545 #endif
  546 
  547         aalgo = ah_algorithm_lookup(sav->alg_auth);
  548         if (!aalgo)
  549                 goto noantireplay;
  550         siz = ((aalgo->sumsiz)(sav) + 3) & ~(4 - 1);
  551         if (AH_MAXSUMSIZE < siz)
  552                 panic("assertion failed for AH_MAXSUMSIZE");
  553 
  554         if (esp_auth(m, espoff, m->m_pkthdr.len - espoff, sav, authbuf)) {
  555                 ipseclog((LOG_ERR, "ESP checksum generation failure\n"));
  556                 m_freem(m);
  557                 error = EINVAL;
  558                 stat->out_inval++;
  559                 goto fail;
  560         }
  561 
  562         n = m;
  563         while (n->m_next)
  564                 n = n->m_next;
  565 
  566         if (!(n->m_flags & M_EXT) && siz < M_TRAILINGSPACE(n)) { /* XXX */
  567                 n->m_len += siz;
  568                 m->m_pkthdr.len += siz;
  569                 p = mtod(n, u_char *) + n->m_len - siz;
  570         } else {
  571                 struct mbuf *nn;
  572 
  573                 MGET(nn, M_DONTWAIT, MT_DATA);
  574                 if (!nn) {
  575                         ipseclog((LOG_DEBUG, "can't alloc mbuf in esp%d_output",
  576                             afnumber));
  577                         m_freem(m);
  578                         error = ENOBUFS;
  579                         goto fail;
  580                 }
  581                 nn->m_len = siz;
  582                 nn->m_next = NULL;
  583                 n->m_next = nn;
  584                 n = nn;
  585                 m->m_pkthdr.len += siz;
  586                 p = mtod(nn, u_char *);
  587         }
  588         bcopy(authbuf, p, siz);
  589 
  590         /* modify IP header (for ESP header part only) */
  591         switch (af) {
  592 #ifdef INET
  593         case AF_INET:
  594                 ip = mtod(m, struct ip *);
  595                 if (siz < (IP_MAXPACKET - ntohs(ip->ip_len)))
  596                         ip->ip_len = htons(ntohs(ip->ip_len) + siz);
  597                 else {
  598                         ipseclog((LOG_ERR,
  599                             "IPv4 ESP output: size exceeds limit\n"));
  600                         ipsecstat.out_inval++;
  601                         m_freem(m);
  602                         error = EMSGSIZE;
  603                         goto fail;
  604                 }
  605                 break;
  606 #endif
  607 #ifdef INET6
  608         case AF_INET6:
  609                 /* total packet length will be computed in ip6_output() */
  610                 break;
  611 #endif
  612         }
  613     }
  614 
  615 noantireplay:
  616         if (!m) {
  617                 ipseclog((LOG_ERR,
  618                     "NULL mbuf after encryption in esp%d_output", afnumber));
  619         } else
  620                 stat->out_success++;
  621         stat->out_esphist[sav->alg_enc]++;
  622         key_sa_recordxfer(sav, m);
  623         return 0;
  624 
  625 fail:
  626 #if 1
  627         return error;
  628 #else
  629         panic("something bad in esp_output");
  630 #endif
  631 }
  632 
  633 #ifdef INET
  634 int
  635 esp4_output(m, isr)
  636         struct mbuf *m;
  637         struct ipsecrequest *isr;
  638 {
  639         struct ip *ip;
  640         if (m->m_len < sizeof(struct ip)) {
  641                 ipseclog((LOG_DEBUG, "esp4_output: first mbuf too short\n"));
  642                 m_freem(m);
  643                 return 0;
  644         }
  645         ip = mtod(m, struct ip *);
  646         /* XXX assumes that m->m_next points to payload */
  647         return esp_output(m, &ip->ip_p, m->m_next, isr, AF_INET);
  648 }
  649 #endif /* INET */
  650 
  651 #ifdef INET6
  652 int
  653 esp6_output(m, nexthdrp, md, isr)
  654         struct mbuf *m;
  655         u_char *nexthdrp;
  656         struct mbuf *md;
  657         struct ipsecrequest *isr;
  658 {
  659         if (m->m_len < sizeof(struct ip6_hdr)) {
  660                 ipseclog((LOG_DEBUG, "esp6_output: first mbuf too short\n"));
  661                 m_freem(m);
  662                 return 0;
  663         }
  664         return esp_output(m, nexthdrp, md, isr, AF_INET6);
  665 }
  666 #endif /* INET6 */

Cache object: fe36e427d4de5d883b088f06bb53633d


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