root/net/pfkeyv2_convert.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. import_sa
  2. export_sa
  3. import_lifetime
  4. export_lifetime
  5. import_flow
  6. export_encap
  7. export_flow
  8. import_address
  9. export_address
  10. import_auth
  11. import_credentials
  12. import_identity
  13. export_credentials
  14. export_auth
  15. export_identity
  16. import_key
  17. export_key
  18. import_udpencap
  19. export_udpencap
  20. import_tag
  21. export_tag

    1 /*      $OpenBSD: pfkeyv2_convert.c,v 1.29 2006/11/24 13:52:14 reyk 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/types.h>
   97 #include <sys/param.h>
   98 #include <sys/systm.h>
   99 #include <sys/mbuf.h>
  100 #include <sys/kernel.h>
  101 #include <sys/socket.h>
  102 #include <net/route.h>
  103 #include <net/if.h>
  104 
  105 #if NPF > 0
  106 #include <net/pfvar.h>
  107 #endif
  108 
  109 #include <netinet/ip_ipsp.h>
  110 #ifdef INET6
  111 #include <netinet6/in6_var.h>
  112 #endif
  113 #include <net/pfkeyv2.h>
  114 #include <crypto/cryptodev.h>
  115 #include <crypto/xform.h>
  116 
  117 /*
  118  * (Partly) Initialize a TDB based on an SADB_SA payload. Other parts
  119  * of the TDB will be initialized by other import routines, and tdb_init().
  120  */
  121 void
  122 import_sa(struct tdb *tdb, struct sadb_sa *sadb_sa, struct ipsecinit *ii)
  123 {
  124         if (!sadb_sa)
  125                 return;
  126 
  127         if (ii) {
  128                 ii->ii_encalg = sadb_sa->sadb_sa_encrypt;
  129                 ii->ii_authalg = sadb_sa->sadb_sa_auth;
  130                 ii->ii_compalg = sadb_sa->sadb_sa_encrypt; /* Yeurk! */
  131 
  132                 tdb->tdb_spi = sadb_sa->sadb_sa_spi;
  133                 tdb->tdb_wnd = sadb_sa->sadb_sa_replay;
  134 
  135                 if (sadb_sa->sadb_sa_flags & SADB_SAFLAGS_PFS)
  136                         tdb->tdb_flags |= TDBF_PFS;
  137 
  138                 if (sadb_sa->sadb_sa_flags & SADB_X_SAFLAGS_HALFIV)
  139                         tdb->tdb_flags |= TDBF_HALFIV;
  140 
  141                 if (sadb_sa->sadb_sa_flags & SADB_X_SAFLAGS_TUNNEL)
  142                         tdb->tdb_flags |= TDBF_TUNNELING;
  143 
  144                 if (sadb_sa->sadb_sa_flags & SADB_X_SAFLAGS_RANDOMPADDING)
  145                         tdb->tdb_flags |= TDBF_RANDOMPADDING;
  146 
  147                 if (sadb_sa->sadb_sa_flags & SADB_X_SAFLAGS_NOREPLAY)
  148                         tdb->tdb_flags |= TDBF_NOREPLAY;
  149 
  150                 if (sadb_sa->sadb_sa_flags & SADB_X_SAFLAGS_UDPENCAP)
  151                         tdb->tdb_flags |= TDBF_UDPENCAP;
  152         }
  153 
  154         if (sadb_sa->sadb_sa_state != SADB_SASTATE_MATURE)
  155                 tdb->tdb_flags |= TDBF_INVALID;
  156 }
  157 
  158 /*
  159  * Export some of the information on a TDB.
  160  */
  161 void
  162 export_sa(void **p, struct tdb *tdb)
  163 {
  164         struct sadb_sa *sadb_sa = (struct sadb_sa *) *p;
  165 
  166         sadb_sa->sadb_sa_len = sizeof(struct sadb_sa) / sizeof(uint64_t);
  167 
  168         sadb_sa->sadb_sa_spi = tdb->tdb_spi;
  169         sadb_sa->sadb_sa_replay = tdb->tdb_wnd;
  170 
  171         if (tdb->tdb_flags & TDBF_INVALID)
  172                 sadb_sa->sadb_sa_state = SADB_SASTATE_LARVAL;
  173         else
  174                 sadb_sa->sadb_sa_state = SADB_SASTATE_MATURE;
  175 
  176         if (tdb->tdb_sproto == IPPROTO_IPCOMP &&
  177             tdb->tdb_compalgxform != NULL) {
  178                 switch (tdb->tdb_compalgxform->type) {
  179                 case CRYPTO_DEFLATE_COMP:
  180                         sadb_sa->sadb_sa_encrypt = SADB_X_CALG_DEFLATE;
  181                         break;
  182                 case CRYPTO_LZS_COMP:
  183                         sadb_sa->sadb_sa_encrypt = SADB_X_CALG_LZS;
  184                         break;
  185                 }
  186         }
  187 
  188         if (tdb->tdb_authalgxform) {
  189                 switch (tdb->tdb_authalgxform->type) {
  190                 case CRYPTO_MD5_HMAC:
  191                         sadb_sa->sadb_sa_auth = SADB_AALG_MD5HMAC;
  192                         break;
  193 
  194                 case CRYPTO_SHA1_HMAC:
  195                         sadb_sa->sadb_sa_auth = SADB_AALG_SHA1HMAC;
  196                         break;
  197 
  198                 case CRYPTO_RIPEMD160_HMAC:
  199                         sadb_sa->sadb_sa_auth = SADB_X_AALG_RIPEMD160HMAC;
  200                         break;
  201 
  202                 case CRYPTO_SHA2_256_HMAC:
  203                         sadb_sa->sadb_sa_auth = SADB_X_AALG_SHA2_256;
  204                         break;
  205 
  206                 case CRYPTO_SHA2_384_HMAC:
  207                         sadb_sa->sadb_sa_auth = SADB_X_AALG_SHA2_384;
  208                         break;
  209 
  210                 case CRYPTO_SHA2_512_HMAC:
  211                         sadb_sa->sadb_sa_auth = SADB_X_AALG_SHA2_512;
  212                         break;
  213 
  214                 case CRYPTO_MD5_KPDK:
  215                         sadb_sa->sadb_sa_auth = SADB_X_AALG_MD5;
  216                         break;
  217 
  218                 case CRYPTO_SHA1_KPDK:
  219                         sadb_sa->sadb_sa_auth = SADB_X_AALG_SHA1;
  220                         break;
  221                 }
  222         }
  223 
  224         if (tdb->tdb_encalgxform) {
  225                 switch (tdb->tdb_encalgxform->type) {
  226                 case CRYPTO_NULL:
  227                         sadb_sa->sadb_sa_encrypt = SADB_EALG_NULL;
  228                         break;
  229 
  230                 case CRYPTO_DES_CBC:
  231                         sadb_sa->sadb_sa_encrypt = SADB_EALG_DESCBC;
  232                         break;
  233 
  234                 case CRYPTO_3DES_CBC:
  235                         sadb_sa->sadb_sa_encrypt = SADB_EALG_3DESCBC;
  236                         break;
  237 
  238                 case CRYPTO_AES_CBC:
  239                         sadb_sa->sadb_sa_encrypt = SADB_X_EALG_AES;
  240                         break;
  241 
  242                 case CRYPTO_AES_CTR:
  243                         sadb_sa->sadb_sa_encrypt = SADB_X_EALG_AESCTR;
  244                         break;
  245 
  246                 case CRYPTO_CAST_CBC:
  247                         sadb_sa->sadb_sa_encrypt = SADB_X_EALG_CAST;
  248                         break;
  249 
  250                 case CRYPTO_BLF_CBC:
  251                         sadb_sa->sadb_sa_encrypt = SADB_X_EALG_BLF;
  252                         break;
  253 
  254                 case CRYPTO_SKIPJACK_CBC:
  255                         sadb_sa->sadb_sa_encrypt = SADB_X_EALG_SKIPJACK;
  256                         break;
  257                 }
  258         }
  259 
  260         if (tdb->tdb_flags & TDBF_PFS)
  261                 sadb_sa->sadb_sa_flags |= SADB_SAFLAGS_PFS;
  262 
  263         /* Only relevant for the "old" IPsec transforms. */
  264         if (tdb->tdb_flags & TDBF_HALFIV)
  265                 sadb_sa->sadb_sa_flags |= SADB_X_SAFLAGS_HALFIV;
  266 
  267         if (tdb->tdb_flags & TDBF_TUNNELING)
  268                 sadb_sa->sadb_sa_flags |= SADB_X_SAFLAGS_TUNNEL;
  269 
  270         if (tdb->tdb_flags & TDBF_RANDOMPADDING)
  271                 sadb_sa->sadb_sa_flags |= SADB_X_SAFLAGS_RANDOMPADDING;
  272 
  273         if (tdb->tdb_flags & TDBF_NOREPLAY)
  274                 sadb_sa->sadb_sa_flags |= SADB_X_SAFLAGS_NOREPLAY;
  275 
  276         *p += sizeof(struct sadb_sa);
  277 }
  278 
  279 /*
  280  * Initialize expirations and counters based on lifetime payload.
  281  */
  282 void
  283 import_lifetime(struct tdb *tdb, struct sadb_lifetime *sadb_lifetime, int type)
  284 {
  285         struct timeval tv;
  286 
  287         if (!sadb_lifetime)
  288                 return;
  289 
  290         getmicrotime(&tv);
  291 
  292         switch (type) {
  293         case PFKEYV2_LIFETIME_HARD:
  294                 if ((tdb->tdb_exp_allocations =
  295                     sadb_lifetime->sadb_lifetime_allocations) != 0)
  296                         tdb->tdb_flags |= TDBF_ALLOCATIONS;
  297                 else
  298                         tdb->tdb_flags &= ~TDBF_ALLOCATIONS;
  299 
  300                 if ((tdb->tdb_exp_bytes =
  301                     sadb_lifetime->sadb_lifetime_bytes) != 0)
  302                         tdb->tdb_flags |= TDBF_BYTES;
  303                 else
  304                         tdb->tdb_flags &= ~TDBF_BYTES;
  305 
  306                 if ((tdb->tdb_exp_timeout =
  307                     sadb_lifetime->sadb_lifetime_addtime) != 0) {
  308                         tdb->tdb_flags |= TDBF_TIMER;
  309                         if (tv.tv_sec + tdb->tdb_exp_timeout < tv.tv_sec)
  310                                 tv.tv_sec = ((unsigned long) -1) / 2; /* XXX */
  311                         else
  312                                 tv.tv_sec += tdb->tdb_exp_timeout;
  313                         timeout_add(&tdb->tdb_timer_tmo, hzto(&tv));
  314                 } else
  315                         tdb->tdb_flags &= ~TDBF_TIMER;
  316 
  317                 if ((tdb->tdb_exp_first_use =
  318                     sadb_lifetime->sadb_lifetime_usetime) != 0)
  319                         tdb->tdb_flags |= TDBF_FIRSTUSE;
  320                 else
  321                         tdb->tdb_flags &= ~TDBF_FIRSTUSE;
  322                 break;
  323 
  324         case PFKEYV2_LIFETIME_SOFT:
  325                 if ((tdb->tdb_soft_allocations =
  326                     sadb_lifetime->sadb_lifetime_allocations) != 0)
  327                         tdb->tdb_flags |= TDBF_SOFT_ALLOCATIONS;
  328                 else
  329                         tdb->tdb_flags &= ~TDBF_SOFT_ALLOCATIONS;
  330 
  331                 if ((tdb->tdb_soft_bytes =
  332                     sadb_lifetime->sadb_lifetime_bytes) != 0)
  333                         tdb->tdb_flags |= TDBF_SOFT_BYTES;
  334                 else
  335                         tdb->tdb_flags &= ~TDBF_SOFT_BYTES;
  336 
  337                 if ((tdb->tdb_soft_timeout =
  338                     sadb_lifetime->sadb_lifetime_addtime) != 0) {
  339                         tdb->tdb_flags |= TDBF_SOFT_TIMER;
  340                         if (tv.tv_sec + tdb->tdb_soft_timeout < tv.tv_sec)
  341                                 tv.tv_sec = ((unsigned long) -1) / 2; /* XXX */
  342                         else
  343                                 tv.tv_sec += tdb->tdb_soft_timeout;
  344                         timeout_add(&tdb->tdb_stimer_tmo, hzto(&tv));
  345                 } else
  346                         tdb->tdb_flags &= ~TDBF_SOFT_TIMER;
  347 
  348                 if ((tdb->tdb_soft_first_use =
  349                     sadb_lifetime->sadb_lifetime_usetime) != 0)
  350                         tdb->tdb_flags |= TDBF_SOFT_FIRSTUSE;
  351                 else
  352                         tdb->tdb_flags &= ~TDBF_SOFT_FIRSTUSE;
  353                 break;
  354 
  355         case PFKEYV2_LIFETIME_CURRENT:  /* Nothing fancy here. */
  356                 tdb->tdb_cur_allocations =
  357                     sadb_lifetime->sadb_lifetime_allocations;
  358                 tdb->tdb_cur_bytes = sadb_lifetime->sadb_lifetime_bytes;
  359                 tdb->tdb_established = sadb_lifetime->sadb_lifetime_addtime;
  360                 tdb->tdb_first_use = sadb_lifetime->sadb_lifetime_usetime;
  361         }
  362 }
  363 
  364 /*
  365  * Export TDB expiration information.
  366  */
  367 void
  368 export_lifetime(void **p, struct tdb *tdb, int type)
  369 {
  370         struct sadb_lifetime *sadb_lifetime = (struct sadb_lifetime *) *p;
  371 
  372         sadb_lifetime->sadb_lifetime_len = sizeof(struct sadb_lifetime) /
  373             sizeof(uint64_t);
  374 
  375         switch (type) {
  376         case PFKEYV2_LIFETIME_HARD:
  377                 if (tdb->tdb_flags & TDBF_ALLOCATIONS)
  378                         sadb_lifetime->sadb_lifetime_allocations =
  379                             tdb->tdb_exp_allocations;
  380 
  381                 if (tdb->tdb_flags & TDBF_BYTES)
  382                         sadb_lifetime->sadb_lifetime_bytes =
  383                             tdb->tdb_exp_bytes;
  384 
  385                 if (tdb->tdb_flags & TDBF_TIMER)
  386                         sadb_lifetime->sadb_lifetime_addtime =
  387                             tdb->tdb_exp_timeout;
  388 
  389                 if (tdb->tdb_flags & TDBF_FIRSTUSE)
  390                         sadb_lifetime->sadb_lifetime_usetime =
  391                             tdb->tdb_exp_first_use;
  392                 break;
  393 
  394         case PFKEYV2_LIFETIME_SOFT:
  395                 if (tdb->tdb_flags & TDBF_SOFT_ALLOCATIONS)
  396                         sadb_lifetime->sadb_lifetime_allocations =
  397                             tdb->tdb_soft_allocations;
  398 
  399                 if (tdb->tdb_flags & TDBF_SOFT_BYTES)
  400                         sadb_lifetime->sadb_lifetime_bytes =
  401                             tdb->tdb_soft_bytes;
  402 
  403                 if (tdb->tdb_flags & TDBF_SOFT_TIMER)
  404                         sadb_lifetime->sadb_lifetime_addtime =
  405                             tdb->tdb_soft_timeout;
  406 
  407                 if (tdb->tdb_flags & TDBF_SOFT_FIRSTUSE)
  408                         sadb_lifetime->sadb_lifetime_usetime =
  409                             tdb->tdb_soft_first_use;
  410                 break;
  411 
  412         case PFKEYV2_LIFETIME_CURRENT:
  413                 sadb_lifetime->sadb_lifetime_allocations =
  414                     tdb->tdb_cur_allocations;
  415                 sadb_lifetime->sadb_lifetime_bytes = tdb->tdb_cur_bytes;
  416                 sadb_lifetime->sadb_lifetime_addtime = tdb->tdb_established;
  417                 sadb_lifetime->sadb_lifetime_usetime = tdb->tdb_first_use;
  418                 break;
  419 
  420         case PFKEYV2_LIFETIME_LASTUSE:
  421                 sadb_lifetime->sadb_lifetime_allocations = 0;
  422                 sadb_lifetime->sadb_lifetime_bytes = 0;
  423                 sadb_lifetime->sadb_lifetime_addtime = 0;
  424                 sadb_lifetime->sadb_lifetime_usetime = tdb->tdb_last_used;
  425                 break;
  426         }
  427 
  428         *p += sizeof(struct sadb_lifetime);
  429 }
  430 
  431 /*
  432  * Import flow information to two struct sockaddr_encap's. Either
  433  * all or none of the address arguments are NULL.
  434  */
  435 void
  436 import_flow(struct sockaddr_encap *flow, struct sockaddr_encap *flowmask,
  437     struct sadb_address *ssrc, struct sadb_address *ssrcmask,
  438     struct sadb_address *ddst, struct sadb_address *ddstmask,
  439     struct sadb_protocol *sab, struct sadb_protocol *ftype)
  440 {
  441         u_int8_t transproto = 0;
  442         union sockaddr_union *src = (union sockaddr_union *)(ssrc + 1);
  443         union sockaddr_union *dst = (union sockaddr_union *)(ddst + 1);
  444         union sockaddr_union *srcmask = (union sockaddr_union *)(ssrcmask + 1);
  445         union sockaddr_union *dstmask = (union sockaddr_union *)(ddstmask + 1);
  446 
  447         if (ssrc == NULL)
  448                 return; /* There wasn't any information to begin with. */
  449 
  450         bzero(flow, sizeof(*flow));
  451         bzero(flowmask, sizeof(*flowmask));
  452 
  453         if (sab != NULL)
  454                 transproto = sab->sadb_protocol_proto;
  455 
  456         /*
  457          * Check that all the address families match. We know they are
  458          * valid and supported because pfkeyv2_parsemessage() checked that.
  459          */
  460         if ((src->sa.sa_family != dst->sa.sa_family) ||
  461             (src->sa.sa_family != srcmask->sa.sa_family) ||
  462             (src->sa.sa_family != dstmask->sa.sa_family))
  463                 return;
  464 
  465         /*
  466          * We set these as an indication that tdb_filter/tdb_filtermask are
  467          * in fact initialized.
  468          */
  469         flow->sen_family = flowmask->sen_family = PF_KEY;
  470         flow->sen_len = flowmask->sen_len = SENT_LEN;
  471 
  472         switch (src->sa.sa_family)
  473         {
  474 #ifdef INET
  475         case AF_INET:
  476                 /* netmask handling */
  477                 rt_maskedcopy(&src->sa, &src->sa, &srcmask->sa);
  478                 rt_maskedcopy(&dst->sa, &dst->sa, &dstmask->sa);
  479 
  480                 flow->sen_type = SENT_IP4;
  481                 flow->sen_direction = ftype->sadb_protocol_direction;
  482                 flow->sen_ip_src = src->sin.sin_addr;
  483                 flow->sen_ip_dst = dst->sin.sin_addr;
  484                 flow->sen_proto = transproto;
  485                 flow->sen_sport = src->sin.sin_port;
  486                 flow->sen_dport = dst->sin.sin_port;
  487 
  488                 flowmask->sen_type = SENT_IP4;
  489                 flowmask->sen_direction = 0xff;
  490                 flowmask->sen_ip_src = srcmask->sin.sin_addr;
  491                 flowmask->sen_ip_dst = dstmask->sin.sin_addr;
  492                 flowmask->sen_sport = srcmask->sin.sin_port;
  493                 flowmask->sen_dport = dstmask->sin.sin_port;
  494                 if (transproto)
  495                         flowmask->sen_proto = 0xff;
  496                 break;
  497 #endif /* INET */
  498 
  499 #ifdef INET6
  500         case AF_INET6:
  501                 in6_embedscope(&src->sin6.sin6_addr, &src->sin6,
  502                     NULL, NULL);
  503                 in6_embedscope(&dst->sin6.sin6_addr, &dst->sin6,
  504                     NULL, NULL);
  505 
  506                 /* netmask handling */
  507                 rt_maskedcopy(&src->sa, &src->sa, &srcmask->sa);
  508                 rt_maskedcopy(&dst->sa, &dst->sa, &dstmask->sa);
  509 
  510                 flow->sen_type = SENT_IP6;
  511                 flow->sen_ip6_direction = ftype->sadb_protocol_direction;
  512                 flow->sen_ip6_src = src->sin6.sin6_addr;
  513                 flow->sen_ip6_dst = dst->sin6.sin6_addr;
  514                 flow->sen_ip6_proto = transproto;
  515                 flow->sen_ip6_sport = src->sin6.sin6_port;
  516                 flow->sen_ip6_dport = dst->sin6.sin6_port;
  517 
  518                 flowmask->sen_type = SENT_IP6;
  519                 flowmask->sen_ip6_direction = 0xff;
  520                 flowmask->sen_ip6_src = srcmask->sin6.sin6_addr;
  521                 flowmask->sen_ip6_dst = dstmask->sin6.sin6_addr;
  522                 flowmask->sen_ip6_sport = srcmask->sin6.sin6_port;
  523                 flowmask->sen_ip6_dport = dstmask->sin6.sin6_port;
  524                 if (transproto)
  525                         flowmask->sen_ip6_proto = 0xff;
  526                 break;
  527 #endif /* INET6 */
  528         }
  529 }
  530 
  531 /*
  532  * Helper to export addresses from an struct sockaddr_encap.
  533  */
  534 static void
  535 export_encap(void **p, struct sockaddr_encap *encap, int type)
  536 {
  537         struct sadb_address *saddr = (struct sadb_address *)*p;
  538         union sockaddr_union *sunion;
  539 
  540         *p += sizeof(struct sadb_address);
  541         sunion = (union sockaddr_union *)*p;
  542 
  543         switch (encap->sen_type) {
  544         case SENT_IP4:
  545                 saddr->sadb_address_len = (sizeof(struct sadb_address) +
  546                     PADUP(sizeof(struct sockaddr_in))) / sizeof(uint64_t);
  547                 sunion->sa.sa_len = sizeof(struct sockaddr_in);
  548                 sunion->sa.sa_family = AF_INET;
  549                 if (type == SADB_X_EXT_SRC_FLOW ||
  550                     type == SADB_X_EXT_SRC_MASK) {
  551                         sunion->sin.sin_addr = encap->sen_ip_src;
  552                         sunion->sin.sin_port = encap->sen_sport;
  553                 } else {
  554                         sunion->sin.sin_addr = encap->sen_ip_dst;
  555                         sunion->sin.sin_port = encap->sen_dport;
  556                 }
  557                 *p += PADUP(sizeof(struct sockaddr_in));
  558                 break;
  559         case SENT_IP6:
  560                 saddr->sadb_address_len = (sizeof(struct sadb_address)
  561                     + PADUP(sizeof(struct sockaddr_in6))) / sizeof(uint64_t);
  562                 sunion->sa.sa_len = sizeof(struct sockaddr_in6);
  563                 sunion->sa.sa_family = AF_INET6;
  564                 if (type == SADB_X_EXT_SRC_FLOW ||
  565                     type == SADB_X_EXT_SRC_MASK) {
  566                         sunion->sin6.sin6_addr = encap->sen_ip6_src;
  567                         sunion->sin6.sin6_port = encap->sen_ip6_sport;
  568                 } else {
  569                         sunion->sin6.sin6_addr = encap->sen_ip6_dst;
  570                         sunion->sin6.sin6_port = encap->sen_ip6_dport;
  571                 }
  572                 *p += PADUP(sizeof(struct sockaddr_in6));
  573                 break;
  574         }
  575 }
  576 
  577 /*
  578  * Export flow information from two struct sockaddr_encap's.
  579  */
  580 void
  581 export_flow(void **p, u_int8_t ftype, struct sockaddr_encap *flow,
  582     struct sockaddr_encap *flowmask, void **headers)
  583 {
  584         struct sadb_protocol *sab;
  585 
  586         headers[SADB_X_EXT_FLOW_TYPE] = *p;
  587         sab = (struct sadb_protocol *)*p;
  588         sab->sadb_protocol_len = sizeof(struct sadb_protocol) /
  589             sizeof(uint64_t);
  590 
  591         switch (ftype) {
  592         case IPSP_IPSEC_USE:
  593                 sab->sadb_protocol_proto = SADB_X_FLOW_TYPE_USE;
  594                 break;
  595         case IPSP_IPSEC_ACQUIRE:
  596                 sab->sadb_protocol_proto = SADB_X_FLOW_TYPE_ACQUIRE;
  597                 break;
  598         case IPSP_IPSEC_REQUIRE:
  599                 sab->sadb_protocol_proto = SADB_X_FLOW_TYPE_REQUIRE;
  600                 break;
  601         case IPSP_DENY:
  602                 sab->sadb_protocol_proto = SADB_X_FLOW_TYPE_DENY;
  603                 break;
  604         case IPSP_PERMIT:
  605                 sab->sadb_protocol_proto = SADB_X_FLOW_TYPE_BYPASS;
  606                 break;
  607         case IPSP_IPSEC_DONTACQ:
  608                 sab->sadb_protocol_proto = SADB_X_FLOW_TYPE_DONTACQ;
  609                 break;
  610         default:
  611                 sab->sadb_protocol_proto = 0;
  612                 break;
  613         }
  614         
  615         switch (flow->sen_type) {
  616 #ifdef INET
  617         case SENT_IP4:
  618                 sab->sadb_protocol_direction = flow->sen_direction;
  619                 break;
  620 #endif /* INET */
  621 #ifdef INET6
  622         case SENT_IP6:
  623                 sab->sadb_protocol_direction = flow->sen_ip6_direction;
  624                 break;
  625 #endif /* INET6 */
  626         }
  627         *p += sizeof(struct sadb_protocol);
  628 
  629         headers[SADB_X_EXT_PROTOCOL] = *p;
  630         sab = (struct sadb_protocol *)*p;
  631         sab->sadb_protocol_len = sizeof(struct sadb_protocol) /
  632             sizeof(uint64_t);
  633         switch (flow->sen_type) {
  634 #ifdef INET
  635         case SENT_IP4:
  636                 sab->sadb_protocol_proto = flow->sen_proto;
  637                 break;
  638 #endif /* INET */
  639 #ifdef INET6
  640         case SENT_IP6:
  641                 sab->sadb_protocol_proto = flow->sen_ip6_proto;
  642                 break;
  643 #endif /* INET6 */
  644         }
  645         *p += sizeof(struct sadb_protocol);
  646 
  647         headers[SADB_X_EXT_SRC_FLOW] = *p;
  648         export_encap(p, flow, SADB_X_EXT_SRC_FLOW);
  649 
  650         headers[SADB_X_EXT_SRC_MASK] = *p;
  651         export_encap(p, flowmask, SADB_X_EXT_SRC_MASK);
  652 
  653         headers[SADB_X_EXT_DST_FLOW] = *p;
  654         export_encap(p, flow, SADB_X_EXT_DST_FLOW);
  655 
  656         headers[SADB_X_EXT_DST_MASK] = *p;
  657         export_encap(p, flowmask, SADB_X_EXT_DST_MASK);
  658 }
  659 
  660 /*
  661  * Copy an SADB_ADDRESS payload to a struct sockaddr.
  662  */
  663 void
  664 import_address(struct sockaddr *sa, struct sadb_address *sadb_address)
  665 {
  666         int salen;
  667         struct sockaddr *ssa = (struct sockaddr *)((void *) sadb_address +
  668             sizeof(struct sadb_address));
  669 
  670         if (!sadb_address)
  671                 return;
  672 
  673         if (ssa->sa_len)
  674                 salen = ssa->sa_len;
  675         else
  676                 switch (ssa->sa_family) {
  677 #ifdef INET
  678                 case AF_INET:
  679                         salen = sizeof(struct sockaddr_in);
  680                         break;
  681 #endif /* INET */
  682 
  683 #if INET6
  684                 case AF_INET6:
  685                         salen = sizeof(struct sockaddr_in6);
  686                         break;
  687 #endif /* INET6 */
  688 
  689                 default:
  690                         return;
  691                 }
  692 
  693         bcopy(ssa, sa, salen);
  694         sa->sa_len = salen;
  695 }
  696 
  697 /*
  698  * Export a struct sockaddr as an SADB_ADDRESS payload.
  699  */
  700 void
  701 export_address(void **p, struct sockaddr *sa)
  702 {
  703         struct sadb_address *sadb_address = (struct sadb_address *) *p;
  704 
  705         sadb_address->sadb_address_len = (sizeof(struct sadb_address) +
  706             PADUP(SA_LEN(sa))) / sizeof(uint64_t);
  707 
  708         *p += sizeof(struct sadb_address);
  709         bcopy(sa, *p, SA_LEN(sa));
  710         ((struct sockaddr *) *p)->sa_family = sa->sa_family;
  711         *p += PADUP(SA_LEN(sa));
  712 }
  713 
  714 /*
  715  * Import authentication information into the TDB.
  716  */
  717 void
  718 import_auth(struct tdb *tdb, struct sadb_x_cred *sadb_auth, int dstauth)
  719 {
  720         struct ipsec_ref **ipr;
  721 
  722         if (!sadb_auth)
  723                 return;
  724 
  725         if (dstauth == PFKEYV2_AUTH_REMOTE)
  726                 ipr = &tdb->tdb_remote_auth;
  727         else
  728                 ipr = &tdb->tdb_local_auth;
  729 
  730         MALLOC(*ipr, struct ipsec_ref *, EXTLEN(sadb_auth) -
  731             sizeof(struct sadb_x_cred) + sizeof(struct ipsec_ref),
  732             M_CREDENTIALS, M_WAITOK);
  733         (*ipr)->ref_len = EXTLEN(sadb_auth) - sizeof(struct sadb_x_cred);
  734 
  735         switch (sadb_auth->sadb_x_cred_type) {
  736         case SADB_X_AUTHTYPE_PASSPHRASE:
  737                 (*ipr)->ref_type = IPSP_AUTH_PASSPHRASE;
  738                 break;
  739         case SADB_X_AUTHTYPE_RSA:
  740                 (*ipr)->ref_type = IPSP_AUTH_RSA;
  741                 break;
  742         default:
  743                 FREE(*ipr, M_CREDENTIALS);
  744                 *ipr = NULL;
  745                 return;
  746         }
  747         (*ipr)->ref_count = 1;
  748         (*ipr)->ref_malloctype = M_CREDENTIALS;
  749         bcopy((void *) sadb_auth + sizeof(struct sadb_x_cred),
  750             (*ipr) + 1, (*ipr)->ref_len);
  751 }
  752 
  753 /*
  754  * Import a set of credentials into the TDB.
  755  */
  756 void
  757 import_credentials(struct tdb *tdb, struct sadb_x_cred *sadb_cred, int dstcred)
  758 {
  759         struct ipsec_ref **ipr;
  760 
  761         if (!sadb_cred)
  762                 return;
  763 
  764         if (dstcred == PFKEYV2_CRED_REMOTE)
  765                 ipr = &tdb->tdb_remote_cred;
  766         else
  767                 ipr = &tdb->tdb_local_cred;
  768 
  769         MALLOC(*ipr, struct ipsec_ref *, EXTLEN(sadb_cred) -
  770             sizeof(struct sadb_x_cred) + sizeof(struct ipsec_ref),
  771             M_CREDENTIALS, M_WAITOK);
  772         (*ipr)->ref_len = EXTLEN(sadb_cred) - sizeof(struct sadb_x_cred);
  773 
  774         switch (sadb_cred->sadb_x_cred_type) {
  775         case SADB_X_CREDTYPE_X509:
  776                 (*ipr)->ref_type = IPSP_CRED_X509;
  777                 break;
  778         case SADB_X_CREDTYPE_KEYNOTE:
  779                 (*ipr)->ref_type = IPSP_CRED_KEYNOTE;
  780                 break;
  781         default:
  782                 FREE(*ipr, M_CREDENTIALS);
  783                 *ipr = NULL;
  784                 return;
  785         }
  786         (*ipr)->ref_count = 1;
  787         (*ipr)->ref_malloctype = M_CREDENTIALS;
  788         bcopy((void *) sadb_cred + sizeof(struct sadb_x_cred),
  789             (*ipr) + 1, (*ipr)->ref_len);
  790 }
  791 
  792 /*
  793  * Import an identity payload into the TDB.
  794  */
  795 void
  796 import_identity(struct tdb *tdb, struct sadb_ident *sadb_ident, int type)
  797 {
  798         struct ipsec_ref **ipr;
  799 
  800         if (!sadb_ident)
  801                 return;
  802 
  803         if (type == PFKEYV2_IDENTITY_SRC)
  804                 ipr = &tdb->tdb_srcid;
  805         else
  806                 ipr = &tdb->tdb_dstid;
  807 
  808         MALLOC(*ipr, struct ipsec_ref *, EXTLEN(sadb_ident) -
  809             sizeof(struct sadb_ident) + sizeof(struct ipsec_ref),
  810             M_CREDENTIALS, M_WAITOK);
  811         (*ipr)->ref_len = EXTLEN(sadb_ident) - sizeof(struct sadb_ident);
  812 
  813         switch (sadb_ident->sadb_ident_type) {
  814         case SADB_IDENTTYPE_PREFIX:
  815                 (*ipr)->ref_type = IPSP_IDENTITY_PREFIX;
  816                 break;
  817         case SADB_IDENTTYPE_FQDN:
  818                 (*ipr)->ref_type = IPSP_IDENTITY_FQDN;
  819                 break;
  820         case SADB_IDENTTYPE_USERFQDN:
  821                 (*ipr)->ref_type = IPSP_IDENTITY_USERFQDN;
  822                 break;
  823         case SADB_X_IDENTTYPE_CONNECTION:
  824                 (*ipr)->ref_type = IPSP_IDENTITY_CONNECTION;
  825                 break;
  826         default:
  827                 FREE(*ipr, M_CREDENTIALS);
  828                 *ipr = NULL;
  829                 return;
  830         }
  831         (*ipr)->ref_count = 1;
  832         (*ipr)->ref_malloctype = M_CREDENTIALS;
  833         bcopy((void *) sadb_ident + sizeof(struct sadb_ident), (*ipr) + 1,
  834             (*ipr)->ref_len);
  835 }
  836 
  837 void
  838 export_credentials(void **p, struct tdb *tdb, int dstcred)
  839 {
  840         struct ipsec_ref **ipr;
  841         struct sadb_x_cred *sadb_cred = (struct sadb_x_cred *) *p;
  842 
  843         if (dstcred == PFKEYV2_CRED_REMOTE)
  844                 ipr = &tdb->tdb_remote_cred;
  845         else
  846                 ipr = &tdb->tdb_local_cred;
  847 
  848         sadb_cred->sadb_x_cred_len = (sizeof(struct sadb_x_cred) +
  849             PADUP((*ipr)->ref_len)) / sizeof(uint64_t);
  850 
  851         switch ((*ipr)->ref_type) {
  852         case IPSP_CRED_KEYNOTE:
  853                 sadb_cred->sadb_x_cred_type = SADB_X_CREDTYPE_KEYNOTE;
  854                 break;
  855         case IPSP_CRED_X509:
  856                 sadb_cred->sadb_x_cred_type = SADB_X_CREDTYPE_X509;
  857                 break;
  858         }
  859         *p += sizeof(struct sadb_x_cred);
  860         bcopy((*ipr) + 1, *p, (*ipr)->ref_len);
  861         *p += PADUP((*ipr)->ref_len);
  862 }
  863 
  864 void
  865 export_auth(void **p, struct tdb *tdb, int dstauth)
  866 {
  867         struct ipsec_ref **ipr;
  868         struct sadb_x_cred *sadb_auth = (struct sadb_x_cred *) *p;
  869 
  870         if (dstauth == PFKEYV2_AUTH_REMOTE)
  871                 ipr = &tdb->tdb_remote_auth;
  872         else
  873                 ipr = &tdb->tdb_local_auth;
  874 
  875         sadb_auth->sadb_x_cred_len = (sizeof(struct sadb_x_cred) +
  876             PADUP((*ipr)->ref_len)) / sizeof(uint64_t);
  877 
  878         switch ((*ipr)->ref_type) {
  879         case IPSP_AUTH_PASSPHRASE:
  880                 sadb_auth->sadb_x_cred_type = SADB_X_AUTHTYPE_PASSPHRASE;
  881                 break;
  882         case IPSP_AUTH_RSA:
  883                 sadb_auth->sadb_x_cred_type = SADB_X_AUTHTYPE_RSA;
  884                 break;
  885         }
  886         *p += sizeof(struct sadb_x_cred);
  887         bcopy((*ipr) + 1, *p, (*ipr)->ref_len);
  888         *p += PADUP((*ipr)->ref_len);
  889 }
  890 
  891 void
  892 export_identity(void **p, struct tdb *tdb, int type)
  893 {
  894         struct ipsec_ref **ipr;
  895         struct sadb_ident *sadb_ident = (struct sadb_ident *) *p;
  896 
  897         if (type == PFKEYV2_IDENTITY_SRC)
  898                 ipr = &tdb->tdb_srcid;
  899         else
  900                 ipr = &tdb->tdb_dstid;
  901 
  902         sadb_ident->sadb_ident_len = (sizeof(struct sadb_ident) +
  903             PADUP((*ipr)->ref_len)) / sizeof(uint64_t);
  904 
  905         switch ((*ipr)->ref_type) {
  906         case IPSP_IDENTITY_PREFIX:
  907                 sadb_ident->sadb_ident_type = SADB_IDENTTYPE_PREFIX;
  908                 break;
  909         case IPSP_IDENTITY_FQDN:
  910                 sadb_ident->sadb_ident_type = SADB_IDENTTYPE_FQDN;
  911                 break;
  912         case IPSP_IDENTITY_USERFQDN:
  913                 sadb_ident->sadb_ident_type = SADB_IDENTTYPE_USERFQDN;
  914                 break;
  915         case IPSP_IDENTITY_CONNECTION:
  916                 sadb_ident->sadb_ident_type = SADB_X_IDENTTYPE_CONNECTION;
  917                 break;
  918         }
  919         *p += sizeof(struct sadb_ident);
  920         bcopy((*ipr) + 1, *p, (*ipr)->ref_len);
  921         *p += PADUP((*ipr)->ref_len);
  922 }
  923 
  924 /* ... */
  925 void
  926 import_key(struct ipsecinit *ii, struct sadb_key *sadb_key, int type)
  927 {
  928         if (!sadb_key)
  929                 return;
  930 
  931         if (type == PFKEYV2_ENCRYPTION_KEY) { /* Encryption key */
  932                 ii->ii_enckeylen = sadb_key->sadb_key_bits / 8;
  933                 ii->ii_enckey = (void *)sadb_key + sizeof(struct sadb_key);
  934         } else {
  935                 ii->ii_authkeylen = sadb_key->sadb_key_bits / 8;
  936                 ii->ii_authkey = (void *)sadb_key + sizeof(struct sadb_key);
  937         }
  938 }
  939 
  940 void
  941 export_key(void **p, struct tdb *tdb, int type)
  942 {
  943         struct sadb_key *sadb_key = (struct sadb_key *) *p;
  944 
  945         if (type == PFKEYV2_ENCRYPTION_KEY) {
  946                 sadb_key->sadb_key_len = (sizeof(struct sadb_key) +
  947                     PADUP(tdb->tdb_emxkeylen)) /
  948                     sizeof(uint64_t);
  949                 sadb_key->sadb_key_bits = tdb->tdb_emxkeylen * 8;
  950                 *p += sizeof(struct sadb_key);
  951                 bcopy(tdb->tdb_emxkey, *p, tdb->tdb_emxkeylen);
  952                 *p += PADUP(tdb->tdb_emxkeylen);
  953         } else {
  954                 sadb_key->sadb_key_len = (sizeof(struct sadb_key) +
  955                     PADUP(tdb->tdb_amxkeylen)) /
  956                     sizeof(uint64_t);
  957                 sadb_key->sadb_key_bits = tdb->tdb_amxkeylen * 8;
  958                 *p += sizeof(struct sadb_key);
  959                 bcopy(tdb->tdb_amxkey, *p, tdb->tdb_amxkeylen);
  960                 *p += PADUP(tdb->tdb_amxkeylen);
  961         }
  962 }
  963 
  964 /* Import/Export remote port for UDP Encapsulation */
  965 void
  966 import_udpencap(struct tdb *tdb, struct sadb_x_udpencap *sadb_udpencap)
  967 {
  968         if (sadb_udpencap)
  969                 tdb->tdb_udpencap_port = sadb_udpencap->sadb_x_udpencap_port;
  970 }
  971 
  972 void
  973 export_udpencap(void **p, struct tdb *tdb)
  974 {
  975         struct sadb_x_udpencap *sadb_udpencap = (struct sadb_x_udpencap *) *p;
  976 
  977         sadb_udpencap->sadb_x_udpencap_port = tdb->tdb_udpencap_port;
  978         sadb_udpencap->sadb_x_udpencap_reserved = 0;
  979         sadb_udpencap->sadb_x_udpencap_len =
  980             sizeof(struct sadb_x_udpencap) / sizeof(uint64_t);
  981         *p += sizeof(struct sadb_x_udpencap);
  982 }
  983 
  984 #if NPF > 0
  985 /* Import PF tag information for SA */
  986 void
  987 import_tag(struct tdb *tdb, struct sadb_x_tag *stag)
  988 {
  989         char *s;
  990 
  991         if (stag) {
  992                 s = (char *)(stag + 1);
  993                 tdb->tdb_tag = pf_tagname2tag(s);
  994         }
  995 }
  996 
  997 /* Export PF tag information for SA */
  998 void
  999 export_tag(void **p, struct tdb *tdb)
 1000 {
 1001         struct sadb_x_tag *stag = (struct sadb_x_tag *)*p;
 1002         char *s = (char *)(stag + 1);
 1003 
 1004         pf_tag2tagname(tdb->tdb_tag, s);
 1005         stag->sadb_x_tag_taglen = strlen(s) + 1;
 1006         stag->sadb_x_tag_len = (sizeof(struct sadb_x_tag) +
 1007             PADUP(stag->sadb_x_tag_taglen)) / sizeof(uint64_t);
 1008         *p += PADUP(stag->sadb_x_tag_taglen) + sizeof(struct sadb_x_tag);
 1009 }
 1010 #endif

/* [<][>][^][v][top][bottom][index][help] */