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/net/pfkeyv2_convert.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 /*      $OpenBSD: pfkeyv2_convert.c,v 1.79 2022/01/20 17:13:12 bluhm Exp $      */
    2 /*
    3  * The author of this code is Angelos D. Keromytis (angelos@keromytis.org)
    4  *
    5  * Part of this code is based on code written by Craig Metz (cmetz@inner.net)
    6  * for NRL. Those licenses follow this one.
    7  *
    8  * Copyright (c) 2001 Angelos D. Keromytis.
    9  *
   10  * Permission to use, copy, and modify this software with or without fee
   11  * is hereby granted, provided that this entire notice is included in
   12  * all copies of any software which is or includes a copy or
   13  * modification of this software.
   14  * You may use this code under the GNU public license if you so wish. Please
   15  * contribute changes back to the authors under this freer than GPL license
   16  * so that we may further the use of strong encryption without limitations to
   17  * all.
   18  *
   19  * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
   20  * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
   21  * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
   22  * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
   23  * PURPOSE.
   24  */
   25 
   26 /*
   27  *      @(#)COPYRIGHT   1.1 (NRL) 17 January 1995
   28  *
   29  * NRL grants permission for redistribution and use in source and binary
   30  * forms, with or without modification, of the software and documentation
   31  * created at NRL provided that the following conditions are met:
   32  *
   33  * 1. Redistributions of source code must retain the above copyright
   34  *    notice, this list of conditions and the following disclaimer.
   35  * 2. Redistributions in binary form must reproduce the above copyright
   36  *    notice, this list of conditions and the following disclaimer in the
   37  *    documentation and/or other materials provided with the distribution.
   38  * 3. All advertising materials mentioning features or use of this software
   39  *    must display the following acknowledgements:
   40  *      This product includes software developed by the University of
   41  *      California, Berkeley and its contributors.
   42  *      This product includes software developed at the Information
   43  *      Technology Division, US Naval Research Laboratory.
   44  * 4. Neither the name of the NRL nor the names of its contributors
   45  *    may be used to endorse or promote products derived from this software
   46  *    without specific prior written permission.
   47  *
   48  * THE SOFTWARE PROVIDED BY NRL IS PROVIDED BY NRL AND CONTRIBUTORS ``AS
   49  * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   50  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
   51  * PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL NRL OR
   52  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   53  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   54  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   55  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   56  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   57  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   58  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   59  *
   60  * The views and conclusions contained in the software and documentation
   61  * are those of the authors and should not be interpreted as representing
   62  * official policies, either expressed or implied, of the US Naval
   63  * Research Laboratory (NRL).
   64  */
   65 
   66 /*
   67  * Copyright (c) 1995, 1996, 1997, 1998, 1999 Craig Metz. All rights reserved.
   68  *
   69  * Redistribution and use in source and binary forms, with or without
   70  * modification, are permitted provided that the following conditions
   71  * are met:
   72  * 1. Redistributions of source code must retain the above copyright
   73  *    notice, this list of conditions and the following disclaimer.
   74  * 2. Redistributions in binary form must reproduce the above copyright
   75  *    notice, this list of conditions and the following disclaimer in the
   76  *    documentation and/or other materials provided with the distribution.
   77  * 3. Neither the name of the author nor the names of any contributors
   78  *    may be used to endorse or promote products derived from this software
   79  *    without specific prior written permission.
   80  *
   81  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   82  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   83  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   84  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   85  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   86  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   87  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   88  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   89  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   90  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   91  * SUCH DAMAGE.
   92  */
   93 
   94 #include "pf.h"
   95 
   96 #include <sys/param.h>
   97 #include <sys/systm.h>
   98 #include <sys/mbuf.h>
   99 #include <sys/kernel.h>
  100 #include <sys/socket.h>
  101 #include <sys/timeout.h>
  102 #include <net/route.h>
  103 #include <net/if.h>
  104 
  105 #include <netinet/in.h>
  106 #include <netinet/ip_ipsp.h>
  107 #include <net/pfkeyv2.h>
  108 #include <crypto/cryptodev.h>
  109 #include <crypto/xform.h>
  110 
  111 #if NPF > 0
  112 #include <net/pfvar.h>
  113 #endif
  114 
  115 /*
  116  * (Partly) Initialize a TDB based on an SADB_SA payload. Other parts
  117  * of the TDB will be initialized by other import routines, and tdb_init().
  118  */
  119 void
  120 import_sa(struct tdb *tdb, struct sadb_sa *sadb_sa, struct ipsecinit *ii)
  121 {
  122         if (!sadb_sa)
  123                 return;
  124 
  125         mtx_enter(&tdb->tdb_mtx);
  126         if (ii) {
  127                 ii->ii_encalg = sadb_sa->sadb_sa_encrypt;
  128                 ii->ii_authalg = sadb_sa->sadb_sa_auth;
  129                 ii->ii_compalg = sadb_sa->sadb_sa_encrypt; /* Yeurk! */
  130 
  131                 tdb->tdb_spi = sadb_sa->sadb_sa_spi;
  132                 tdb->tdb_wnd = sadb_sa->sadb_sa_replay;
  133 
  134                 if (sadb_sa->sadb_sa_flags & SADB_SAFLAGS_PFS)
  135                         tdb->tdb_flags |= TDBF_PFS;
  136 
  137                 if (sadb_sa->sadb_sa_flags & SADB_X_SAFLAGS_TUNNEL)
  138                         tdb->tdb_flags |= TDBF_TUNNELING;
  139 
  140                 if (sadb_sa->sadb_sa_flags & SADB_X_SAFLAGS_UDPENCAP)
  141                         tdb->tdb_flags |= TDBF_UDPENCAP;
  142 
  143                 if (sadb_sa->sadb_sa_flags & SADB_X_SAFLAGS_ESN)
  144                         tdb->tdb_flags |= TDBF_ESN;
  145         }
  146 
  147         if (sadb_sa->sadb_sa_state != SADB_SASTATE_MATURE)
  148                 tdb->tdb_flags |= TDBF_INVALID;
  149         mtx_leave(&tdb->tdb_mtx);
  150 }
  151 
  152 /*
  153  * Export some of the information on a TDB.
  154  */
  155 void
  156 export_sa(void **p, struct tdb *tdb)
  157 {
  158         struct sadb_sa *sadb_sa = (struct sadb_sa *) *p;
  159 
  160         sadb_sa->sadb_sa_len = sizeof(struct sadb_sa) / sizeof(uint64_t);
  161 
  162         sadb_sa->sadb_sa_spi = tdb->tdb_spi;
  163         sadb_sa->sadb_sa_replay = tdb->tdb_wnd;
  164 
  165         if (tdb->tdb_flags & TDBF_INVALID)
  166                 sadb_sa->sadb_sa_state = SADB_SASTATE_LARVAL;
  167         else
  168                 sadb_sa->sadb_sa_state = SADB_SASTATE_MATURE;
  169 
  170         if (tdb->tdb_sproto == IPPROTO_IPCOMP &&
  171             tdb->tdb_compalgxform != NULL) {
  172                 switch (tdb->tdb_compalgxform->type) {
  173                 case CRYPTO_DEFLATE_COMP:
  174                         sadb_sa->sadb_sa_encrypt = SADB_X_CALG_DEFLATE;
  175                         break;
  176                 }
  177         }
  178 
  179         if (tdb->tdb_authalgxform) {
  180                 switch (tdb->tdb_authalgxform->type) {
  181                 case CRYPTO_MD5_HMAC:
  182                         sadb_sa->sadb_sa_auth = SADB_AALG_MD5HMAC;
  183                         break;
  184 
  185                 case CRYPTO_SHA1_HMAC:
  186                         sadb_sa->sadb_sa_auth = SADB_AALG_SHA1HMAC;
  187                         break;
  188 
  189                 case CRYPTO_RIPEMD160_HMAC:
  190                         sadb_sa->sadb_sa_auth = SADB_X_AALG_RIPEMD160HMAC;
  191                         break;
  192 
  193                 case CRYPTO_SHA2_256_HMAC:
  194                         sadb_sa->sadb_sa_auth = SADB_X_AALG_SHA2_256;
  195                         break;
  196 
  197                 case CRYPTO_SHA2_384_HMAC:
  198                         sadb_sa->sadb_sa_auth = SADB_X_AALG_SHA2_384;
  199                         break;
  200 
  201                 case CRYPTO_SHA2_512_HMAC:
  202                         sadb_sa->sadb_sa_auth = SADB_X_AALG_SHA2_512;
  203                         break;
  204 
  205                 case CRYPTO_AES_128_GMAC:
  206                         sadb_sa->sadb_sa_auth = SADB_X_AALG_AES128GMAC;
  207                         break;
  208 
  209                 case CRYPTO_AES_192_GMAC:
  210                         sadb_sa->sadb_sa_auth = SADB_X_AALG_AES192GMAC;
  211                         break;
  212 
  213                 case CRYPTO_AES_256_GMAC:
  214                         sadb_sa->sadb_sa_auth = SADB_X_AALG_AES256GMAC;
  215                         break;
  216 
  217                 case CRYPTO_CHACHA20_POLY1305_MAC:
  218                         sadb_sa->sadb_sa_auth = SADB_X_AALG_CHACHA20POLY1305;
  219                         break;
  220                 }
  221         }
  222 
  223         if (tdb->tdb_encalgxform) {
  224                 switch (tdb->tdb_encalgxform->type) {
  225                 case CRYPTO_NULL:
  226                         sadb_sa->sadb_sa_encrypt = SADB_EALG_NULL;
  227                         break;
  228 
  229                 case CRYPTO_3DES_CBC:
  230                         sadb_sa->sadb_sa_encrypt = SADB_EALG_3DESCBC;
  231                         break;
  232 
  233                 case CRYPTO_AES_CBC:
  234                         sadb_sa->sadb_sa_encrypt = SADB_X_EALG_AES;
  235                         break;
  236 
  237                 case CRYPTO_AES_CTR:
  238                         sadb_sa->sadb_sa_encrypt = SADB_X_EALG_AESCTR;
  239                         break;
  240 
  241                 case CRYPTO_AES_GCM_16:
  242                         sadb_sa->sadb_sa_encrypt = SADB_X_EALG_AESGCM16;
  243                         break;
  244 
  245                 case CRYPTO_AES_GMAC:
  246                         sadb_sa->sadb_sa_encrypt = SADB_X_EALG_AESGMAC;
  247                         break;
  248 
  249                 case CRYPTO_CAST_CBC:
  250                         sadb_sa->sadb_sa_encrypt = SADB_X_EALG_CAST;
  251                         break;
  252 
  253                 case CRYPTO_BLF_CBC:
  254                         sadb_sa->sadb_sa_encrypt = SADB_X_EALG_BLF;
  255                         break;
  256 
  257                 case CRYPTO_CHACHA20_POLY1305:
  258                         sadb_sa->sadb_sa_encrypt = SADB_X_EALG_CHACHA20POLY1305;
  259                         break;
  260                 }
  261         }
  262 
  263         if (tdb->tdb_flags & TDBF_PFS)
  264                 sadb_sa->sadb_sa_flags |= SADB_SAFLAGS_PFS;
  265 
  266         if (tdb->tdb_flags & TDBF_TUNNELING)
  267                 sadb_sa->sadb_sa_flags |= SADB_X_SAFLAGS_TUNNEL;
  268 
  269         if (tdb->tdb_flags & TDBF_UDPENCAP)
  270                 sadb_sa->sadb_sa_flags |= SADB_X_SAFLAGS_UDPENCAP;
  271 
  272         if (tdb->tdb_flags & TDBF_ESN)
  273                 sadb_sa->sadb_sa_flags |= SADB_X_SAFLAGS_ESN;
  274 
  275         *p += sizeof(struct sadb_sa);
  276 }
  277 
  278 /*
  279  * Initialize expirations and counters based on lifetime payload.
  280  */
  281 void
  282 import_lifetime(struct tdb *tdb, struct sadb_lifetime *sadb_lifetime, int type)
  283 {
  284         if (!sadb_lifetime)
  285                 return;
  286 
  287         mtx_enter(&tdb->tdb_mtx);
  288         switch (type) {
  289         case PFKEYV2_LIFETIME_HARD:
  290                 if ((tdb->tdb_exp_allocations =
  291                     sadb_lifetime->sadb_lifetime_allocations) != 0)
  292                         tdb->tdb_flags |= TDBF_ALLOCATIONS;
  293                 else
  294                         tdb->tdb_flags &= ~TDBF_ALLOCATIONS;
  295 
  296                 if ((tdb->tdb_exp_bytes =
  297                     sadb_lifetime->sadb_lifetime_bytes) != 0)
  298                         tdb->tdb_flags |= TDBF_BYTES;
  299                 else
  300                         tdb->tdb_flags &= ~TDBF_BYTES;
  301 
  302                 if ((tdb->tdb_exp_timeout =
  303                     sadb_lifetime->sadb_lifetime_addtime) != 0) {
  304                         tdb->tdb_flags |= TDBF_TIMER;
  305                         if (timeout_add_sec(&tdb->tdb_timer_tmo,
  306                             tdb->tdb_exp_timeout))
  307                                 tdb_ref(tdb);
  308                 } else
  309                         tdb->tdb_flags &= ~TDBF_TIMER;
  310 
  311                 if ((tdb->tdb_exp_first_use =
  312                     sadb_lifetime->sadb_lifetime_usetime) != 0)
  313                         tdb->tdb_flags |= TDBF_FIRSTUSE;
  314                 else
  315                         tdb->tdb_flags &= ~TDBF_FIRSTUSE;
  316                 break;
  317 
  318         case PFKEYV2_LIFETIME_SOFT:
  319                 if ((tdb->tdb_soft_allocations =
  320                     sadb_lifetime->sadb_lifetime_allocations) != 0)
  321                         tdb->tdb_flags |= TDBF_SOFT_ALLOCATIONS;
  322                 else
  323                         tdb->tdb_flags &= ~TDBF_SOFT_ALLOCATIONS;
  324 
  325                 if ((tdb->tdb_soft_bytes =
  326                     sadb_lifetime->sadb_lifetime_bytes) != 0)
  327                         tdb->tdb_flags |= TDBF_SOFT_BYTES;
  328                 else
  329                         tdb->tdb_flags &= ~TDBF_SOFT_BYTES;
  330 
  331                 if ((tdb->tdb_soft_timeout =
  332                     sadb_lifetime->sadb_lifetime_addtime) != 0) {
  333                         tdb->tdb_flags |= TDBF_SOFT_TIMER;
  334                         if (timeout_add_sec(&tdb->tdb_stimer_tmo,
  335                             tdb->tdb_soft_timeout))
  336                                 tdb_ref(tdb);
  337                 } else
  338                         tdb->tdb_flags &= ~TDBF_SOFT_TIMER;
  339 
  340                 if ((tdb->tdb_soft_first_use =
  341                     sadb_lifetime->sadb_lifetime_usetime) != 0)
  342                         tdb->tdb_flags |= TDBF_SOFT_FIRSTUSE;
  343                 else
  344                         tdb->tdb_flags &= ~TDBF_SOFT_FIRSTUSE;
  345                 break;
  346 
  347         case PFKEYV2_LIFETIME_CURRENT:  /* Nothing fancy here. */
  348                 tdb->tdb_cur_allocations =
  349                     sadb_lifetime->sadb_lifetime_allocations;
  350                 tdb->tdb_cur_bytes = sadb_lifetime->sadb_lifetime_bytes;
  351                 tdb->tdb_established = sadb_lifetime->sadb_lifetime_addtime;
  352                 tdb->tdb_first_use = sadb_lifetime->sadb_lifetime_usetime;
  353         }
  354         mtx_leave(&tdb->tdb_mtx);
  355 }
  356 
  357 /*
  358  * Export TDB expiration information.
  359  */
  360 void
  361 export_lifetime(void **p, struct tdb *tdb, int type)
  362 {
  363         struct sadb_lifetime *sadb_lifetime = (struct sadb_lifetime *) *p;
  364 
  365         sadb_lifetime->sadb_lifetime_len = sizeof(struct sadb_lifetime) /
  366             sizeof(uint64_t);
  367 
  368         switch (type) {
  369         case PFKEYV2_LIFETIME_HARD:
  370                 if (tdb->tdb_flags & TDBF_ALLOCATIONS)
  371                         sadb_lifetime->sadb_lifetime_allocations =
  372                             tdb->tdb_exp_allocations;
  373 
  374                 if (tdb->tdb_flags & TDBF_BYTES)
  375                         sadb_lifetime->sadb_lifetime_bytes =
  376                             tdb->tdb_exp_bytes;
  377 
  378                 if (tdb->tdb_flags & TDBF_TIMER)
  379                         sadb_lifetime->sadb_lifetime_addtime =
  380                             tdb->tdb_exp_timeout;
  381 
  382                 if (tdb->tdb_flags & TDBF_FIRSTUSE)
  383                         sadb_lifetime->sadb_lifetime_usetime =
  384                             tdb->tdb_exp_first_use;
  385                 break;
  386 
  387         case PFKEYV2_LIFETIME_SOFT:
  388                 if (tdb->tdb_flags & TDBF_SOFT_ALLOCATIONS)
  389                         sadb_lifetime->sadb_lifetime_allocations =
  390                             tdb->tdb_soft_allocations;
  391 
  392                 if (tdb->tdb_flags & TDBF_SOFT_BYTES)
  393                         sadb_lifetime->sadb_lifetime_bytes =
  394                             tdb->tdb_soft_bytes;
  395 
  396                 if (tdb->tdb_flags & TDBF_SOFT_TIMER)
  397                         sadb_lifetime->sadb_lifetime_addtime =
  398                             tdb->tdb_soft_timeout;
  399 
  400                 if (tdb->tdb_flags & TDBF_SOFT_FIRSTUSE)
  401                         sadb_lifetime->sadb_lifetime_usetime =
  402                             tdb->tdb_soft_first_use;
  403                 break;
  404 
  405         case PFKEYV2_LIFETIME_CURRENT:
  406                 sadb_lifetime->sadb_lifetime_allocations =
  407                     tdb->tdb_cur_allocations;
  408                 sadb_lifetime->sadb_lifetime_bytes = tdb->tdb_cur_bytes;
  409                 sadb_lifetime->sadb_lifetime_addtime = tdb->tdb_established;
  410                 sadb_lifetime->sadb_lifetime_usetime = tdb->tdb_first_use;
  411                 break;
  412 
  413         case PFKEYV2_LIFETIME_LASTUSE:
  414                 sadb_lifetime->sadb_lifetime_allocations = 0;
  415                 sadb_lifetime->sadb_lifetime_bytes = 0;
  416                 sadb_lifetime->sadb_lifetime_addtime = 0;
  417                 sadb_lifetime->sadb_lifetime_usetime = tdb->tdb_last_used;
  418                 break;
  419         }
  420 
  421         *p += sizeof(struct sadb_lifetime);
  422 }
  423 
  424 /*
  425  * Import flow information to two struct sockaddr_encap's. Either
  426  * all or none of the address arguments are NULL.
  427  */
  428 int
  429 import_flow(struct sockaddr_encap *flow, struct sockaddr_encap *flowmask,
  430     struct sadb_address *ssrc, struct sadb_address *ssrcmask,
  431     struct sadb_address *ddst, struct sadb_address *ddstmask,
  432     struct sadb_protocol *sab, struct sadb_protocol *ftype)
  433 {
  434         u_int8_t transproto = 0;
  435         union sockaddr_union *src, *dst, *srcmask, *dstmask;
  436 
  437         if (ssrc == NULL)
  438                 return 0; /* There wasn't any information to begin with. */
  439 
  440         src = (union sockaddr_union *)(ssrc + 1);
  441         dst = (union sockaddr_union *)(ddst + 1);
  442         srcmask = (union sockaddr_union *)(ssrcmask + 1);
  443         dstmask = (union sockaddr_union *)(ddstmask + 1);
  444 
  445         bzero(flow, sizeof(*flow));
  446         bzero(flowmask, sizeof(*flowmask));
  447 
  448         if (sab != NULL)
  449                 transproto = sab->sadb_protocol_proto;
  450 
  451         /*
  452          * Check that all the address families match. We know they are
  453          * valid and supported because pfkeyv2_parsemessage() checked that.
  454          */
  455         if ((src->sa.sa_family != dst->sa.sa_family) ||
  456             (src->sa.sa_family != srcmask->sa.sa_family) ||
  457             (src->sa.sa_family != dstmask->sa.sa_family))
  458                 return EINVAL;
  459 
  460         /*
  461          * We set these as an indication that tdb_filter/tdb_filtermask are
  462          * in fact initialized.
  463          */
  464         flow->sen_family = flowmask->sen_family = PF_KEY;
  465         flow->sen_len = flowmask->sen_len = SENT_LEN;
  466 
  467         switch (src->sa.sa_family) {
  468         case AF_INET:
  469                 /* netmask handling */
  470                 rt_maskedcopy(&src->sa, &src->sa, &srcmask->sa);
  471                 rt_maskedcopy(&dst->sa, &dst->sa, &dstmask->sa);
  472 
  473                 flow->sen_type = SENT_IP4;
  474                 flow->sen_direction = ftype->sadb_protocol_direction;
  475                 flow->sen_ip_src = src->sin.sin_addr;
  476                 flow->sen_ip_dst = dst->sin.sin_addr;
  477                 flow->sen_proto = transproto;
  478                 flow->sen_sport = src->sin.sin_port;
  479                 flow->sen_dport = dst->sin.sin_port;
  480 
  481                 flowmask->sen_type = SENT_IP4;
  482                 flowmask->sen_direction = 0xff;
  483                 flowmask->sen_ip_src = srcmask->sin.sin_addr;
  484                 flowmask->sen_ip_dst = dstmask->sin.sin_addr;
  485                 flowmask->sen_sport = srcmask->sin.sin_port;
  486                 flowmask->sen_dport = dstmask->sin.sin_port;
  487                 if (transproto)
  488                         flowmask->sen_proto = 0xff;
  489                 break;
  490 
  491 #ifdef INET6
  492         case AF_INET6:
  493                 in6_embedscope(&src->sin6.sin6_addr, &src->sin6,
  494                     NULL);
  495                 in6_embedscope(&dst->sin6.sin6_addr, &dst->sin6,
  496                     NULL);
  497 
  498                 /* netmask handling */
  499                 rt_maskedcopy(&src->sa, &src->sa, &srcmask->sa);
  500                 rt_maskedcopy(&dst->sa, &dst->sa, &dstmask->sa);
  501 
  502                 flow->sen_type = SENT_IP6;
  503                 flow->sen_ip6_direction = ftype->sadb_protocol_direction;
  504                 flow->sen_ip6_src = src->sin6.sin6_addr;
  505                 flow->sen_ip6_dst = dst->sin6.sin6_addr;
  506                 flow->sen_ip6_proto = transproto;
  507                 flow->sen_ip6_sport = src->sin6.sin6_port;
  508                 flow->sen_ip6_dport = dst->sin6.sin6_port;
  509 
  510                 flowmask->sen_type = SENT_IP6;
  511                 flowmask->sen_ip6_direction = 0xff;
  512                 flowmask->sen_ip6_src = srcmask->sin6.sin6_addr;
  513                 flowmask->sen_ip6_dst = dstmask->sin6.sin6_addr;
  514                 flowmask->sen_ip6_sport = srcmask->sin6.sin6_port;
  515                 flowmask->sen_ip6_dport = dstmask->sin6.sin6_port;
  516                 if (transproto)
  517                         flowmask->sen_ip6_proto = 0xff;
  518                 break;
  519 #endif /* INET6 */
  520         }
  521 
  522         return 0;
  523 }
  524 
  525 /*
  526  * Helper to export addresses from an struct sockaddr_encap.
  527  */
  528 static void
  529 export_encap(void **p, struct sockaddr_encap *encap, int type)
  530 {
  531         struct sadb_address *saddr = (struct sadb_address *)*p;
  532         union sockaddr_union *sunion;
  533 
  534         *p += sizeof(struct sadb_address);
  535         sunion = (union sockaddr_union *)*p;
  536 
  537         switch (encap->sen_type) {
  538         case SENT_IP4:
  539                 saddr->sadb_address_len = (sizeof(struct sadb_address) +
  540                     PADUP(sizeof(struct sockaddr_in))) / sizeof(uint64_t);
  541                 sunion->sa.sa_len = sizeof(struct sockaddr_in);
  542                 sunion->sa.sa_family = AF_INET;
  543                 if (type == SADB_X_EXT_SRC_FLOW ||
  544                     type == SADB_X_EXT_SRC_MASK) {
  545                         sunion->sin.sin_addr = encap->sen_ip_src;
  546                         sunion->sin.sin_port = encap->sen_sport;
  547                 } else {
  548                         sunion->sin.sin_addr = encap->sen_ip_dst;
  549                         sunion->sin.sin_port = encap->sen_dport;
  550                 }
  551                 *p += PADUP(sizeof(struct sockaddr_in));
  552                 break;
  553         case SENT_IP6:
  554                 saddr->sadb_address_len = (sizeof(struct sadb_address)
  555                     + PADUP(sizeof(struct sockaddr_in6))) / sizeof(uint64_t);
  556                 sunion->sa.sa_len = sizeof(struct sockaddr_in6);
  557                 sunion->sa.sa_family = AF_INET6;
  558                 if (type == SADB_X_EXT_SRC_FLOW ||
  559                     type == SADB_X_EXT_SRC_MASK) {
  560                         sunion->sin6.sin6_addr = encap->sen_ip6_src;
  561                         sunion->sin6.sin6_port = encap->sen_ip6_sport;
  562                 } else {
  563                         sunion->sin6.sin6_addr = encap->sen_ip6_dst;
  564                         sunion->sin6.sin6_port = encap->sen_ip6_dport;
  565                 }
  566                 *p += PADUP(sizeof(struct sockaddr_in6));
  567                 break;
  568         }
  569 }
  570 
  571 /*
  572  * Export flow information from two struct sockaddr_encap's.
  573  */
  574 void
  575 export_flow(void **p, u_int8_t ftype, struct sockaddr_encap *flow,
  576     struct sockaddr_encap *flowmask, void **headers)
  577 {
  578         struct sadb_protocol *sab;
  579 
  580         headers[SADB_X_EXT_FLOW_TYPE] = *p;
  581         sab = (struct sadb_protocol *)*p;
  582         sab->sadb_protocol_len = sizeof(struct sadb_protocol) /
  583             sizeof(uint64_t);
  584 
  585         switch (ftype) {
  586         case IPSP_IPSEC_USE:
  587                 sab->sadb_protocol_proto = SADB_X_FLOW_TYPE_USE;
  588                 break;
  589         case IPSP_IPSEC_ACQUIRE:
  590                 sab->sadb_protocol_proto = SADB_X_FLOW_TYPE_ACQUIRE;
  591                 break;
  592         case IPSP_IPSEC_REQUIRE:
  593                 sab->sadb_protocol_proto = SADB_X_FLOW_TYPE_REQUIRE;
  594                 break;
  595         case IPSP_DENY:
  596                 sab->sadb_protocol_proto = SADB_X_FLOW_TYPE_DENY;
  597                 break;
  598         case IPSP_PERMIT:
  599                 sab->sadb_protocol_proto = SADB_X_FLOW_TYPE_BYPASS;
  600                 break;
  601         case IPSP_IPSEC_DONTACQ:
  602                 sab->sadb_protocol_proto = SADB_X_FLOW_TYPE_DONTACQ;
  603                 break;
  604         default:
  605                 sab->sadb_protocol_proto = 0;
  606                 break;
  607         }
  608 
  609         switch (flow->sen_type) {
  610         case SENT_IP4:
  611                 sab->sadb_protocol_direction = flow->sen_direction;
  612                 break;
  613 #ifdef INET6
  614         case SENT_IP6:
  615                 sab->sadb_protocol_direction = flow->sen_ip6_direction;
  616                 break;
  617 #endif /* INET6 */
  618         }
  619         *p += sizeof(struct sadb_protocol);
  620 
  621         headers[SADB_X_EXT_PROTOCOL] = *p;
  622         sab = (struct sadb_protocol *)*p;
  623         sab->sadb_protocol_len = sizeof(struct sadb_protocol) /
  624             sizeof(uint64_t);
  625         switch (flow->sen_type) {
  626         case SENT_IP4:
  627                 sab->sadb_protocol_proto = flow->sen_proto;
  628                 break;
  629 #ifdef INET6
  630         case SENT_IP6:
  631                 sab->sadb_protocol_proto = flow->sen_ip6_proto;
  632                 break;
  633 #endif /* INET6 */
  634         }
  635         *p += sizeof(struct sadb_protocol);
  636 
  637         headers[SADB_X_EXT_SRC_FLOW] = *p;
  638         export_encap(p, flow, SADB_X_EXT_SRC_FLOW);
  639 
  640         headers[SADB_X_EXT_SRC_MASK] = *p;
  641         export_encap(p, flowmask, SADB_X_EXT_SRC_MASK);
  642 
  643         headers[SADB_X_EXT_DST_FLOW] = *p;
  644         export_encap(p, flow, SADB_X_EXT_DST_FLOW);
  645 
  646         headers[SADB_X_EXT_DST_MASK] = *p;
  647         export_encap(p, flowmask, SADB_X_EXT_DST_MASK);
  648 }
  649 
  650 /*
  651  * Copy an SADB_ADDRESS payload to a struct sockaddr.
  652  */
  653 void
  654 import_address(struct sockaddr *sa, struct sadb_address *sadb_address)
  655 {
  656         int salen;
  657         struct sockaddr *ssa = (struct sockaddr *)((void *) sadb_address +
  658             sizeof(struct sadb_address));
  659 
  660         if (!sadb_address)
  661                 return;
  662 
  663         if (ssa->sa_len)
  664                 salen = ssa->sa_len;
  665         else
  666                 switch (ssa->sa_family) {
  667                 case AF_INET:
  668                         salen = sizeof(struct sockaddr_in);
  669                         break;
  670 
  671 #ifdef INET6
  672                 case AF_INET6:
  673                         salen = sizeof(struct sockaddr_in6);
  674                         break;
  675 #endif /* INET6 */
  676 
  677                 default:
  678                         return;
  679                 }
  680 
  681         bcopy(ssa, sa, salen);
  682         sa->sa_len = salen;
  683 }
  684 
  685 /*
  686  * Export a struct sockaddr as an SADB_ADDRESS payload.
  687  */
  688 void
  689 export_address(void **p, struct sockaddr *sa)
  690 {
  691         struct sadb_address *sadb_address = (struct sadb_address *) *p;
  692 
  693         sadb_address->sadb_address_len = (sizeof(struct sadb_address) +
  694             PADUP(sa->sa_len)) / sizeof(uint64_t);
  695 
  696         *p += sizeof(struct sadb_address);
  697         bcopy(sa, *p, sa->sa_len);
  698         ((struct sockaddr *) *p)->sa_family = sa->sa_family;
  699         *p += PADUP(sa->sa_len);
  700 }
  701 
  702 /*
  703  * Import an identity payload into the TDB.
  704  */
  705 static void
  706 import_identity(struct ipsec_id **id, struct sadb_ident *sadb_ident,
  707     size_t *id_sz)
  708 {
  709         size_t id_len;
  710 
  711         if (!sadb_ident) {
  712                 *id = NULL;
  713                 return;
  714         }
  715 
  716         id_len = EXTLEN(sadb_ident) - sizeof(struct sadb_ident);
  717         *id_sz = sizeof(struct ipsec_id) + id_len;
  718         *id = malloc(*id_sz, M_CREDENTIALS, M_WAITOK);
  719         (*id)->len = id_len;
  720 
  721         switch (sadb_ident->sadb_ident_type) {
  722         case SADB_IDENTTYPE_PREFIX:
  723                 (*id)->type = IPSP_IDENTITY_PREFIX;
  724                 break;
  725         case SADB_IDENTTYPE_FQDN:
  726                 (*id)->type = IPSP_IDENTITY_FQDN;
  727                 break;
  728         case SADB_IDENTTYPE_USERFQDN:
  729                 (*id)->type = IPSP_IDENTITY_USERFQDN;
  730                 break;
  731         case SADB_IDENTTYPE_ASN1_DN:
  732                 (*id)->type = IPSP_IDENTITY_ASN1_DN;
  733                 break;
  734         default:
  735                 free(*id, M_CREDENTIALS, *id_sz);
  736                 *id = NULL;
  737                 return;
  738         }
  739         bcopy((void *) sadb_ident + sizeof(struct sadb_ident), (*id) + 1,
  740             (*id)->len);
  741 }
  742 
  743 void
  744 import_identities(struct ipsec_ids **ids, int swapped,
  745     struct sadb_ident *srcid, struct sadb_ident *dstid)
  746 {
  747         struct ipsec_ids *tmp;
  748         size_t id_local_sz, id_remote_sz;
  749 
  750         *ids = NULL;
  751         tmp = malloc(sizeof(struct ipsec_ids), M_CREDENTIALS, M_WAITOK);
  752         import_identity(&tmp->id_local, swapped ? dstid: srcid, &id_local_sz);
  753         import_identity(&tmp->id_remote, swapped ? srcid: dstid, &id_remote_sz);
  754         if (tmp->id_local != NULL && tmp->id_remote != NULL) {
  755                 *ids = ipsp_ids_insert(tmp);
  756                 if (*ids == tmp)
  757                         return;
  758         }
  759         free(tmp->id_local, M_CREDENTIALS, id_local_sz);
  760         free(tmp->id_remote, M_CREDENTIALS, id_remote_sz);
  761         free(tmp, M_CREDENTIALS, sizeof(*tmp));
  762 }
  763 
  764 static void
  765 export_identity(void **p, struct ipsec_id *id)
  766 {
  767         struct sadb_ident *sadb_ident = (struct sadb_ident *) *p;
  768 
  769         sadb_ident->sadb_ident_len = (sizeof(struct sadb_ident) +
  770             PADUP(id->len)) / sizeof(uint64_t);
  771 
  772         switch (id->type) {
  773         case IPSP_IDENTITY_PREFIX:
  774                 sadb_ident->sadb_ident_type = SADB_IDENTTYPE_PREFIX;
  775                 break;
  776         case IPSP_IDENTITY_FQDN:
  777                 sadb_ident->sadb_ident_type = SADB_IDENTTYPE_FQDN;
  778                 break;
  779         case IPSP_IDENTITY_USERFQDN:
  780                 sadb_ident->sadb_ident_type = SADB_IDENTTYPE_USERFQDN;
  781                 break;
  782         case IPSP_IDENTITY_ASN1_DN:
  783                 sadb_ident->sadb_ident_type = SADB_IDENTTYPE_ASN1_DN;
  784                 break;
  785         }
  786         *p += sizeof(struct sadb_ident);
  787         bcopy(id + 1, *p, id->len);
  788         *p += PADUP(id->len);
  789 }
  790 
  791 void
  792 export_identities(void **p, struct ipsec_ids *ids, int swapped,
  793     void **headers)
  794 {
  795         headers[SADB_EXT_IDENTITY_SRC] = *p;
  796         export_identity(p, swapped ? ids->id_remote : ids->id_local);
  797         headers[SADB_EXT_IDENTITY_DST] = *p;
  798         export_identity(p, swapped ? ids->id_local : ids->id_remote);
  799 }
  800 
  801 /* ... */
  802 void
  803 import_key(struct ipsecinit *ii, struct sadb_key *sadb_key, int type)
  804 {
  805         if (!sadb_key)
  806                 return;
  807 
  808         if (type == PFKEYV2_ENCRYPTION_KEY) { /* Encryption key */
  809                 ii->ii_enckeylen = sadb_key->sadb_key_bits / 8;
  810                 ii->ii_enckey = (void *)sadb_key + sizeof(struct sadb_key);
  811         } else {
  812                 ii->ii_authkeylen = sadb_key->sadb_key_bits / 8;
  813                 ii->ii_authkey = (void *)sadb_key + sizeof(struct sadb_key);
  814         }
  815 }
  816 
  817 void
  818 export_key(void **p, struct tdb *tdb, int type)
  819 {
  820         struct sadb_key *sadb_key = (struct sadb_key *) *p;
  821 
  822         if (type == PFKEYV2_ENCRYPTION_KEY) {
  823                 sadb_key->sadb_key_len = (sizeof(struct sadb_key) +
  824                     PADUP(tdb->tdb_emxkeylen)) /
  825                     sizeof(uint64_t);
  826                 sadb_key->sadb_key_bits = tdb->tdb_emxkeylen * 8;
  827                 *p += sizeof(struct sadb_key);
  828                 bcopy(tdb->tdb_emxkey, *p, tdb->tdb_emxkeylen);
  829                 *p += PADUP(tdb->tdb_emxkeylen);
  830         } else {
  831                 sadb_key->sadb_key_len = (sizeof(struct sadb_key) +
  832                     PADUP(tdb->tdb_amxkeylen)) /
  833                     sizeof(uint64_t);
  834                 sadb_key->sadb_key_bits = tdb->tdb_amxkeylen * 8;
  835                 *p += sizeof(struct sadb_key);
  836                 bcopy(tdb->tdb_amxkey, *p, tdb->tdb_amxkeylen);
  837                 *p += PADUP(tdb->tdb_amxkeylen);
  838         }
  839 }
  840 
  841 /* Import/Export remote port for UDP Encapsulation */
  842 void
  843 import_udpencap(struct tdb *tdb, struct sadb_x_udpencap *sadb_udpencap)
  844 {
  845         if (sadb_udpencap)
  846                 tdb->tdb_udpencap_port = sadb_udpencap->sadb_x_udpencap_port;
  847 }
  848 
  849 void
  850 export_udpencap(void **p, struct tdb *tdb)
  851 {
  852         struct sadb_x_udpencap *sadb_udpencap = (struct sadb_x_udpencap *) *p;
  853 
  854         sadb_udpencap->sadb_x_udpencap_port = tdb->tdb_udpencap_port;
  855         sadb_udpencap->sadb_x_udpencap_reserved = 0;
  856         sadb_udpencap->sadb_x_udpencap_len =
  857             sizeof(struct sadb_x_udpencap) / sizeof(uint64_t);
  858         *p += sizeof(struct sadb_x_udpencap);
  859 }
  860 
  861 /* Export PF replay for SA */
  862 void
  863 export_replay(void **p, struct tdb *tdb)
  864 {
  865         struct sadb_x_replay *sreplay = (struct sadb_x_replay *)*p;
  866 
  867         sreplay->sadb_x_replay_count = tdb->tdb_rpl;
  868         sreplay->sadb_x_replay_len =
  869             sizeof(struct sadb_x_replay) / sizeof(uint64_t);
  870         *p += sizeof(struct sadb_x_replay);
  871 }
  872 
  873 /* Export mtu for SA */
  874 void
  875 export_mtu(void **p, struct tdb *tdb)
  876 {
  877         struct sadb_x_mtu *smtu = (struct sadb_x_mtu *)*p;
  878 
  879         smtu->sadb_x_mtu_mtu = tdb->tdb_mtu;
  880         smtu->sadb_x_mtu_len =
  881             sizeof(struct sadb_x_mtu) / sizeof(uint64_t);
  882         *p += sizeof(struct sadb_x_mtu);
  883 }
  884 
  885 /* Import rdomain switch for SA */
  886 void
  887 import_rdomain(struct tdb *tdb, struct sadb_x_rdomain *srdomain)
  888 {
  889         if (srdomain)
  890                 tdb->tdb_rdomain_post = srdomain->sadb_x_rdomain_dom2;
  891 }
  892 
  893 /* Export rdomain switch for SA */
  894 void
  895 export_rdomain(void **p, struct tdb *tdb)
  896 {
  897         struct sadb_x_rdomain *srdomain = (struct sadb_x_rdomain *)*p;
  898 
  899         srdomain->sadb_x_rdomain_dom1 = tdb->tdb_rdomain;
  900         srdomain->sadb_x_rdomain_dom2 = tdb->tdb_rdomain_post;
  901         srdomain->sadb_x_rdomain_len =
  902             sizeof(struct sadb_x_rdomain) / sizeof(uint64_t);
  903         *p += sizeof(struct sadb_x_rdomain);
  904 }
  905 
  906 #if NPF > 0
  907 /* Import PF tag information for SA */
  908 void
  909 import_tag(struct tdb *tdb, struct sadb_x_tag *stag)
  910 {
  911         char *s;
  912 
  913         if (stag) {
  914                 s = (char *)(stag + 1);
  915                 tdb->tdb_tag = pf_tagname2tag(s, 1);
  916         }
  917 }
  918 
  919 /* Export PF tag information for SA */
  920 void
  921 export_tag(void **p, struct tdb *tdb)
  922 {
  923         struct sadb_x_tag *stag = (struct sadb_x_tag *)*p;
  924         char *s = (char *)(stag + 1);
  925 
  926         pf_tag2tagname(tdb->tdb_tag, s);
  927 
  928         stag->sadb_x_tag_taglen = strlen(s) + 1;
  929         stag->sadb_x_tag_len = (sizeof(struct sadb_x_tag) +
  930             PADUP(stag->sadb_x_tag_taglen)) / sizeof(uint64_t);
  931         *p += sizeof(struct sadb_x_tag) + PADUP(stag->sadb_x_tag_taglen);
  932 }
  933 
  934 /* Import enc(4) tap device information for SA */
  935 void
  936 import_tap(struct tdb *tdb, struct sadb_x_tap *stap)
  937 {
  938         if (stap)
  939                 tdb->tdb_tap = stap->sadb_x_tap_unit;
  940 }
  941 
  942 /* Export enc(4) tap device information for SA */
  943 void
  944 export_tap(void **p, struct tdb *tdb)
  945 {
  946         struct sadb_x_tap *stag = (struct sadb_x_tap *)*p;
  947 
  948         stag->sadb_x_tap_unit = tdb->tdb_tap;
  949         stag->sadb_x_tap_len = sizeof(struct sadb_x_tap) / sizeof(uint64_t);
  950         *p += sizeof(struct sadb_x_tap);
  951 }
  952 #endif
  953 
  954 void
  955 export_satype(void **p, struct tdb *tdb)
  956 {
  957         struct sadb_protocol *sab = *p;
  958 
  959         sab->sadb_protocol_len = sizeof(struct sadb_protocol) /
  960             sizeof(uint64_t);
  961         sab->sadb_protocol_proto = tdb->tdb_satype;
  962         *p += sizeof(struct sadb_protocol);
  963 }
  964 
  965 void
  966 export_counter(void **p, struct tdb *tdb)
  967 {
  968         uint64_t counters[tdb_ncounters];
  969         struct sadb_x_counter *scnt = (struct sadb_x_counter *)*p;
  970 
  971         counters_read(tdb->tdb_counters, counters, tdb_ncounters);
  972 
  973         scnt->sadb_x_counter_len = sizeof(struct sadb_x_counter) /
  974             sizeof(uint64_t);
  975         scnt->sadb_x_counter_pad = 0;
  976         scnt->sadb_x_counter_ipackets = counters[tdb_ipackets];
  977         scnt->sadb_x_counter_opackets = counters[tdb_opackets];
  978         scnt->sadb_x_counter_ibytes = counters[tdb_ibytes];
  979         scnt->sadb_x_counter_obytes = counters[tdb_obytes];
  980         scnt->sadb_x_counter_idrops = counters[tdb_idrops];
  981         scnt->sadb_x_counter_odrops = counters[tdb_odrops];
  982         scnt->sadb_x_counter_idecompbytes = counters[tdb_idecompbytes];
  983         scnt->sadb_x_counter_ouncompbytes = counters[tdb_ouncompbytes];
  984         *p += sizeof(struct sadb_x_counter);
  985 }

Cache object: f7794f87d8b0811dc58fb235f60959d1


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