Annotation of embedaddon/ipsec-tools/src/racoon/nattraversal.c, revision 1.1

1.1     ! misho       1: /*     $NetBSD: nattraversal.c,v 1.14 2011/03/14 17:18:13 tteras Exp $ */
        !             2: 
        !             3: /*
        !             4:  * Copyright (C) 2004 SuSE Linux AG, Nuernberg, Germany.
        !             5:  * Contributed by: Michal Ludvig <mludvig@suse.cz>, SUSE Labs
        !             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: #include "config.h"
        !            34: 
        !            35: #include <sys/types.h>
        !            36: #include <sys/param.h>
        !            37: 
        !            38: #ifdef __linux__
        !            39: #include <linux/udp.h>
        !            40: #endif
        !            41: #if defined(__NetBSD__) || defined (__FreeBSD__)
        !            42: #include <netinet/udp.h>
        !            43: #endif
        !            44: 
        !            45: #include <stdlib.h>
        !            46: #include <stdio.h>
        !            47: #include <string.h>
        !            48: #include <errno.h>
        !            49: #include <ctype.h>
        !            50: 
        !            51: #include "var.h"
        !            52: #include "misc.h"
        !            53: #include "vmbuf.h"
        !            54: #include "plog.h"
        !            55: #include "debug.h"
        !            56: 
        !            57: #include "localconf.h"
        !            58: #include "remoteconf.h"
        !            59: #include "sockmisc.h"
        !            60: #include "isakmp_var.h"
        !            61: #include "isakmp.h"
        !            62: #include "oakley.h"
        !            63: #include "ipsec_doi.h"
        !            64: #include "vendorid.h"
        !            65: #include "handler.h"
        !            66: #include "crypto_openssl.h"
        !            67: #include "schedule.h"
        !            68: #include "nattraversal.h"
        !            69: #include "grabmyaddr.h"
        !            70: 
        !            71: struct natt_ka_addrs {
        !            72:   struct sockaddr      *src;
        !            73:   struct sockaddr      *dst;
        !            74:   unsigned             in_use;
        !            75: 
        !            76:   TAILQ_ENTRY(natt_ka_addrs) chain;
        !            77: };
        !            78: 
        !            79: static TAILQ_HEAD(_natt_ka_addrs, natt_ka_addrs) ka_tree;
        !            80: static struct sched sc_natt = SCHED_INITIALIZER();
        !            81: 
        !            82: /*
        !            83:  * check if the given vid is NAT-T.
        !            84:  */
        !            85: int
        !            86: natt_vendorid (int vid)
        !            87: {
        !            88:   return (
        !            89: #ifdef ENABLE_NATT_00
        !            90:          vid == VENDORID_NATT_00 ||
        !            91: #endif
        !            92: #ifdef ENABLE_NATT_01
        !            93:          vid == VENDORID_NATT_01 ||
        !            94: #endif
        !            95: #ifdef ENABLE_NATT_02
        !            96:          vid == VENDORID_NATT_02 ||
        !            97:          vid == VENDORID_NATT_02_N ||
        !            98: #endif
        !            99: #ifdef ENABLE_NATT_03
        !           100:          vid == VENDORID_NATT_03 ||
        !           101: #endif
        !           102: #ifdef ENABLE_NATT_04
        !           103:          vid == VENDORID_NATT_04 ||
        !           104: #endif
        !           105: #ifdef ENABLE_NATT_05
        !           106:          vid == VENDORID_NATT_05 ||
        !           107: #endif
        !           108: #ifdef ENABLE_NATT_06
        !           109:          vid == VENDORID_NATT_06 ||
        !           110: #endif
        !           111: #ifdef ENABLE_NATT_07
        !           112:          vid == VENDORID_NATT_07 ||
        !           113: #endif
        !           114: #ifdef ENABLE_NATT_08
        !           115:          vid == VENDORID_NATT_08 ||
        !           116: #endif
        !           117:          /* Always enable NATT RFC if ENABLE_NATT
        !           118:           */
        !           119:          vid == VENDORID_NATT_RFC);
        !           120: }
        !           121: 
        !           122: vchar_t *
        !           123: natt_hash_addr (struct ph1handle *iph1, struct sockaddr *addr)
        !           124: {
        !           125:   vchar_t *natd;
        !           126:   vchar_t *buf;
        !           127:   char *ptr;
        !           128:   void *addr_ptr, *addr_port;
        !           129:   size_t buf_size, addr_size;
        !           130:   int natt_force = 0;
        !           131: 
        !           132:   if (iph1->rmconf != NULL && iph1->rmconf->nat_traversal == NATT_FORCE)
        !           133:          natt_force = 1;
        !           134: 
        !           135:   plog (LLV_INFO, LOCATION, addr, "Hashing %s with algo #%d %s\n",
        !           136:        saddr2str(addr), iph1->approval->hashtype, 
        !           137:        natt_force?"(NAT-T forced)":"");
        !           138:   
        !           139:   if (addr->sa_family == AF_INET) {
        !           140:     addr_size = sizeof (struct in_addr);       /* IPv4 address */
        !           141:     addr_ptr = &((struct sockaddr_in *)addr)->sin_addr;
        !           142:     addr_port = &((struct sockaddr_in *)addr)->sin_port;
        !           143:   }
        !           144:   else if (addr->sa_family == AF_INET6) {
        !           145:     addr_size = sizeof (struct in6_addr);      /* IPv6 address */
        !           146:     addr_ptr = &((struct sockaddr_in6 *)addr)->sin6_addr;
        !           147:     addr_port = &((struct sockaddr_in6 *)addr)->sin6_port;
        !           148:   }
        !           149:   else {
        !           150:     plog (LLV_ERROR, LOCATION, addr, "Unsupported address family #0x%x\n", addr->sa_family);
        !           151:     return NULL;
        !           152:   }
        !           153: 
        !           154:   buf_size = 2 * sizeof (cookie_t);    /* CKY-I + CKY+R */
        !           155:   buf_size += addr_size + 2;   /* Address + Port */
        !           156:   
        !           157:   if ((buf = vmalloc (buf_size)) == NULL)
        !           158:     return NULL;
        !           159: 
        !           160:   ptr = buf->v;
        !           161:   
        !           162:   /* Copy-in CKY-I */
        !           163:   memcpy (ptr, iph1->index.i_ck, sizeof (cookie_t));
        !           164:   ptr += sizeof (cookie_t);
        !           165:   
        !           166:   /* Copy-in CKY-I */
        !           167:   memcpy (ptr, iph1->index.r_ck, sizeof (cookie_t));
        !           168:   ptr += sizeof (cookie_t);
        !           169:   
        !           170:   /* Copy-in Address (or zeroes if NATT_FORCE) */
        !           171:   if (natt_force)
        !           172:     memset (ptr, 0, addr_size);
        !           173:   else
        !           174:     memcpy (ptr, addr_ptr, addr_size);
        !           175:   ptr += addr_size;
        !           176: 
        !           177:   /* Copy-in Port number */
        !           178:   memcpy (ptr, addr_port, 2);
        !           179: 
        !           180:   natd = oakley_hash (buf, iph1);
        !           181:   vfree(buf);
        !           182: 
        !           183:   return natd;
        !           184: }
        !           185: 
        !           186: int 
        !           187: natt_compare_addr_hash (struct ph1handle *iph1, vchar_t *natd_received,
        !           188:                        int natd_seq)
        !           189: {
        !           190:   vchar_t *natd_computed;
        !           191:   u_int32_t flag;
        !           192:   int verified = 0;
        !           193: 
        !           194:   if (iph1->rmconf != NULL &&
        !           195:       iph1->rmconf->nat_traversal == NATT_FORCE)
        !           196:     return verified;
        !           197: 
        !           198:   if (natd_seq == 0) {
        !           199:     natd_computed = natt_hash_addr (iph1, iph1->local);
        !           200:     flag = NAT_DETECTED_ME;
        !           201:   }
        !           202:   else {
        !           203:     natd_computed = natt_hash_addr (iph1, iph1->remote);
        !           204:     flag = NAT_DETECTED_PEER;
        !           205:   }
        !           206: 
        !           207:   if (natd_computed == NULL) {
        !           208:        plog(LLV_ERROR, LOCATION, NULL, "natd_computed allocation failed\n");
        !           209:        return verified; /* XXX should abort */
        !           210:   }
        !           211: 
        !           212:   if (natd_received->l == natd_computed->l &&
        !           213:       memcmp (natd_received->v, natd_computed->v, natd_received->l) == 0) {
        !           214:     iph1->natt_flags &= ~flag;
        !           215:     verified = 1;
        !           216:   }
        !           217: 
        !           218:   vfree (natd_computed);
        !           219: 
        !           220:   return verified;
        !           221: }
        !           222: 
        !           223: int
        !           224: natt_udp_encap (int encmode)
        !           225: {
        !           226:   return (encmode == IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_RFC || 
        !           227:          encmode == IPSECDOI_ATTR_ENC_MODE_UDPTRNS_RFC ||
        !           228:          encmode == IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_DRAFT ||
        !           229:          encmode == IPSECDOI_ATTR_ENC_MODE_UDPTRNS_DRAFT);
        !           230: }
        !           231: 
        !           232: int
        !           233: natt_fill_options (struct ph1natt_options *opts, int version)
        !           234: {
        !           235:   if (! opts)
        !           236:     return -1;
        !           237: 
        !           238:   opts->version = version;
        !           239: 
        !           240:   switch (version) {
        !           241:     case VENDORID_NATT_00:
        !           242:     case VENDORID_NATT_01:
        !           243:       opts->float_port = 0; /* No port floating for those drafts */
        !           244:       opts->payload_nat_d = ISAKMP_NPTYPE_NATD_DRAFT;
        !           245:       opts->payload_nat_oa = ISAKMP_NPTYPE_NATOA_DRAFT;
        !           246:       opts->mode_udp_tunnel = IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_DRAFT;
        !           247:       opts->mode_udp_transport = IPSECDOI_ATTR_ENC_MODE_UDPTRNS_DRAFT;
        !           248:       opts->encaps_type = UDP_ENCAP_ESPINUDP_NON_IKE;
        !           249:                break;
        !           250: 
        !           251:     case VENDORID_NATT_02:
        !           252:     case VENDORID_NATT_02_N:
        !           253:     case VENDORID_NATT_03:
        !           254:       opts->float_port = lcconf->port_isakmp_natt;
        !           255:       opts->payload_nat_d = ISAKMP_NPTYPE_NATD_DRAFT;
        !           256:       opts->payload_nat_oa = ISAKMP_NPTYPE_NATOA_DRAFT;
        !           257:       opts->mode_udp_tunnel = IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_DRAFT;
        !           258:       opts->mode_udp_transport = IPSECDOI_ATTR_ENC_MODE_UDPTRNS_DRAFT;
        !           259:       opts->encaps_type = UDP_ENCAP_ESPINUDP;
        !           260:       break;
        !           261:     case VENDORID_NATT_04:
        !           262:     case VENDORID_NATT_05:
        !           263:     case VENDORID_NATT_06:
        !           264:     case VENDORID_NATT_07:
        !           265:     case VENDORID_NATT_08:
        !           266:       opts->float_port = lcconf->port_isakmp_natt;
        !           267:       opts->payload_nat_d = ISAKMP_NPTYPE_NATD_BADDRAFT;
        !           268:       opts->payload_nat_oa = ISAKMP_NPTYPE_NATOA_BADDRAFT;
        !           269:       opts->mode_udp_tunnel = IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_RFC;
        !           270:       opts->mode_udp_transport = IPSECDOI_ATTR_ENC_MODE_UDPTRNS_RFC;
        !           271:       opts->encaps_type = UDP_ENCAP_ESPINUDP;
        !           272:       break;
        !           273:     case VENDORID_NATT_RFC:
        !           274:       opts->float_port = lcconf->port_isakmp_natt;
        !           275:       opts->payload_nat_d = ISAKMP_NPTYPE_NATD_RFC;
        !           276:       opts->payload_nat_oa = ISAKMP_NPTYPE_NATOA_RFC;
        !           277:       opts->mode_udp_tunnel = IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_RFC;
        !           278:       opts->mode_udp_transport = IPSECDOI_ATTR_ENC_MODE_UDPTRNS_RFC;
        !           279:       opts->encaps_type = UDP_ENCAP_ESPINUDP;
        !           280:          break;
        !           281:     default:
        !           282:       plog(LLV_ERROR, LOCATION, NULL, 
        !           283:           "unsupported NAT-T version: %s\n",
        !           284:           vid_string_by_id(version));
        !           285:       return -1;
        !           286:   }
        !           287:  
        !           288:   opts->mode_udp_diff = opts->mode_udp_tunnel - IPSECDOI_ATTR_ENC_MODE_TUNNEL;
        !           289: 
        !           290:   return 0;
        !           291: }
        !           292: 
        !           293: void
        !           294: natt_float_ports (struct ph1handle *iph1)
        !           295: {
        !           296:        if (! (iph1->natt_flags & NAT_DETECTED) )
        !           297:                return;
        !           298:        if (! iph1->natt_options->float_port){
        !           299:                /* Drafts 00 / 01, just schedule keepalive */
        !           300:                natt_keepalive_add_ph1 (iph1);
        !           301:                return;
        !           302:        }
        !           303:        
        !           304:        set_port (iph1->local, iph1->natt_options->float_port);
        !           305:        set_port (iph1->remote, iph1->natt_options->float_port);
        !           306:        iph1->natt_flags |= NAT_PORTS_CHANGED | NAT_ADD_NON_ESP_MARKER;
        !           307:        
        !           308:        natt_keepalive_add_ph1 (iph1);
        !           309: }
        !           310: 
        !           311: static int
        !           312: natt_is_enabled (struct remoteconf *rmconf, void *args)
        !           313: {
        !           314:   if (rmconf->nat_traversal)
        !           315:     return 1;
        !           316:   return 0;
        !           317: }
        !           318: 
        !           319: void
        !           320: natt_handle_vendorid (struct ph1handle *iph1, int vid_numeric)
        !           321: {
        !           322:   if (iph1->rmconf == NULL) {
        !           323:     /* Check if any candidate remote conf allows nat-t */
        !           324:     struct rmconfselector rmconf;
        !           325:     rmconf_selector_from_ph1(&rmconf, iph1);
        !           326:     if (enumrmconf(&rmconf, natt_is_enabled, NULL) == 0)
        !           327:       return;
        !           328:   } else {
        !           329:     if (!iph1->rmconf->nat_traversal)
        !           330:       return;
        !           331:   }
        !           332: 
        !           333:   if (! iph1->natt_options)
        !           334:     iph1->natt_options = racoon_calloc (1, sizeof (*iph1->natt_options));
        !           335: 
        !           336:   if (! iph1->natt_options) {
        !           337:     plog (LLV_ERROR, LOCATION, NULL,
        !           338:          "Allocating memory for natt_options failed!\n");
        !           339:     return;
        !           340:   }
        !           341:   
        !           342:   if (iph1->natt_options->version < vid_numeric)
        !           343:     if (natt_fill_options (iph1->natt_options, vid_numeric) == 0)
        !           344:       iph1->natt_flags |= NAT_ANNOUNCED;
        !           345: }
        !           346: 
        !           347: static void
        !           348: natt_keepalive_delete (struct natt_ka_addrs *ka)
        !           349: {
        !           350:   TAILQ_REMOVE (&ka_tree, ka, chain);
        !           351:   racoon_free (ka->src);
        !           352:   racoon_free (ka->dst);
        !           353:   racoon_free (ka);
        !           354: }
        !           355: 
        !           356: /* NAT keepalive functions */
        !           357: static void
        !           358: natt_keepalive_send (struct sched *param)
        !           359: {
        !           360:   struct natt_ka_addrs *ka, *next = NULL;
        !           361:   char keepalive_packet[] = { 0xff };
        !           362:   size_t len;
        !           363:   int s;
        !           364: 
        !           365:   for (ka = TAILQ_FIRST(&ka_tree); ka; ka = next) {
        !           366:     next = TAILQ_NEXT(ka, chain);
        !           367:     
        !           368:     s = myaddr_getfd(ka->src);
        !           369:     if (s == -1) {
        !           370:       natt_keepalive_delete(ka);
        !           371:       continue;
        !           372:     }
        !           373:     plog (LLV_DEBUG, LOCATION, NULL, "KA: %s\n", 
        !           374:          saddr2str_fromto("%s->%s", ka->src, ka->dst));
        !           375:     len = sendfromto(s, keepalive_packet, sizeof (keepalive_packet),
        !           376:                     ka->src, ka->dst, 1);
        !           377:     if (len == -1)
        !           378:       plog(LLV_ERROR, LOCATION, NULL, "KA: sendfromto failed: %s\n",
        !           379:           strerror (errno));
        !           380:   }
        !           381:   
        !           382:   sched_schedule (&sc_natt, lcconf->natt_ka_interval, natt_keepalive_send);
        !           383: }
        !           384: 
        !           385: void
        !           386: natt_keepalive_init (void)
        !           387: {
        !           388:   TAILQ_INIT(&ka_tree);
        !           389: 
        !           390:   /* To disable sending KAs set natt_ka_interval=0 */
        !           391:   if (lcconf->natt_ka_interval > 0)
        !           392:     sched_schedule (&sc_natt, lcconf->natt_ka_interval, natt_keepalive_send);
        !           393: }
        !           394: 
        !           395: int
        !           396: natt_keepalive_add (struct sockaddr *src, struct sockaddr *dst)
        !           397: {
        !           398:   struct natt_ka_addrs *ka = NULL, *new_addr;
        !           399:   
        !           400:   TAILQ_FOREACH (ka, &ka_tree, chain) {
        !           401:     if (cmpsaddr(ka->src, src) == CMPSADDR_MATCH &&
        !           402:        cmpsaddr(ka->dst, dst) == CMPSADDR_MATCH) {
        !           403:       ka->in_use++;
        !           404:       plog (LLV_INFO, LOCATION, NULL, "KA found: %s (in_use=%u)\n",
        !           405:            saddr2str_fromto("%s->%s", src, dst), ka->in_use);
        !           406:       return 0;
        !           407:     }
        !           408:   }
        !           409: 
        !           410:   plog (LLV_INFO, LOCATION, NULL, "KA list add: %s\n", saddr2str_fromto("%s->%s", src, dst));
        !           411: 
        !           412:   new_addr = (struct natt_ka_addrs *)racoon_malloc(sizeof(*new_addr));
        !           413:   if (! new_addr) {
        !           414:     plog (LLV_ERROR, LOCATION, NULL, "Can't allocate new KA list item\n");
        !           415:     return -1;
        !           416:   }
        !           417: 
        !           418:   if ((new_addr->src = dupsaddr(src)) == NULL) {
        !           419:        racoon_free(new_addr);
        !           420:        plog (LLV_ERROR, LOCATION, NULL, "Can't allocate new KA list item\n");
        !           421:        return -1;
        !           422:   }
        !           423:   if ((new_addr->dst = dupsaddr(dst)) == NULL) {
        !           424:        racoon_free(new_addr);
        !           425:        plog (LLV_ERROR, LOCATION, NULL, "Can't allocate new KA list item\n");
        !           426:        return -1;
        !           427:   }
        !           428:   new_addr->in_use = 1;
        !           429:   TAILQ_INSERT_TAIL(&ka_tree, new_addr, chain);
        !           430: 
        !           431:   return 0;
        !           432: }
        !           433: 
        !           434: int
        !           435: natt_keepalive_add_ph1 (struct ph1handle *iph1)
        !           436: {
        !           437:   int ret = 0;
        !           438:   
        !           439:   /* Should only the NATed host send keepalives?
        !           440:      If yes, add '(iph1->natt_flags & NAT_DETECTED_ME)'
        !           441:      to the following condition. */
        !           442:   if (iph1->natt_flags & NAT_DETECTED &&
        !           443:       ! (iph1->natt_flags & NAT_KA_QUEUED)) {
        !           444:     ret = natt_keepalive_add (iph1->local, iph1->remote);
        !           445:     if (ret == 0)
        !           446:       iph1->natt_flags |= NAT_KA_QUEUED;
        !           447:   }
        !           448: 
        !           449:   return ret;
        !           450: }
        !           451: 
        !           452: void
        !           453: natt_keepalive_remove (struct sockaddr *src, struct sockaddr *dst)
        !           454: {
        !           455:   struct natt_ka_addrs *ka, *next = NULL;
        !           456: 
        !           457:   plog (LLV_INFO, LOCATION, NULL, "KA remove: %s\n", saddr2str_fromto("%s->%s", src, dst));
        !           458: 
        !           459:   for (ka = TAILQ_FIRST(&ka_tree); ka; ka = next) {
        !           460:     next = TAILQ_NEXT(ka, chain);
        !           461:  
        !           462:     plog (LLV_DEBUG, LOCATION, NULL, "KA tree dump: %s (in_use=%u)\n",
        !           463:          saddr2str_fromto("%s->%s", src, dst), ka->in_use);
        !           464: 
        !           465:     if (cmpsaddr(ka->src, src) == CMPSADDR_MATCH &&
        !           466:        cmpsaddr(ka->dst, dst) == CMPSADDR_MATCH &&
        !           467:        -- ka->in_use <= 0) {
        !           468: 
        !           469:       plog (LLV_DEBUG, LOCATION, NULL, "KA removing this one...\n");
        !           470: 
        !           471:       natt_keepalive_delete (ka);
        !           472:       /* Should we break here? Every pair of addresses should 
        !           473:          be inserted only once, but who knows :-) Lets traverse 
        !           474:         the whole list... */
        !           475:     }
        !           476:   }
        !           477: }
        !           478: 
        !           479: static int
        !           480: natt_enabled_in_rmconf_stub (struct remoteconf *rmconf, void *data)
        !           481: {
        !           482:   return rmconf->nat_traversal ? 1 : 0;
        !           483: }
        !           484: 
        !           485: int
        !           486: natt_enabled_in_rmconf ()
        !           487: {
        !           488:   return enumrmconf(NULL, natt_enabled_in_rmconf_stub, NULL) != 0;
        !           489: }
        !           490: 
        !           491: 
        !           492: struct payload_list *
        !           493: isakmp_plist_append_natt_vids (struct payload_list *plist, vchar_t *vid_natt[MAX_NATT_VID_COUNT]){
        !           494:        int i, vid_natt_i = 0;
        !           495: 
        !           496:        if(vid_natt == NULL)
        !           497:                return NULL;
        !           498: 
        !           499:        for (i = 0; i < MAX_NATT_VID_COUNT; i++)
        !           500:                vid_natt[i]=NULL;
        !           501:        
        !           502:        /* Puts the olders VIDs last, as some implementations may choose the first
        !           503:         * NATT VID given
        !           504:         */
        !           505: 
        !           506:        /* Always set RFC VID
        !           507:         */
        !           508:        if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_RFC)) != NULL)
        !           509:                vid_natt_i++;
        !           510: #ifdef ENABLE_NATT_08
        !           511:        if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_08)) != NULL)
        !           512:                vid_natt_i++;
        !           513: #endif
        !           514: #ifdef ENABLE_NATT_07
        !           515:        if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_07)) != NULL)
        !           516:                vid_natt_i++;
        !           517: #endif
        !           518: #ifdef ENABLE_NATT_06
        !           519:        if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_06)) != NULL)
        !           520:                vid_natt_i++;
        !           521: #endif
        !           522: #ifdef ENABLE_NATT_05
        !           523:        if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_05)) != NULL)
        !           524:                vid_natt_i++;
        !           525: #endif
        !           526: #ifdef ENABLE_NATT_04
        !           527:        if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_04)) != NULL)
        !           528:                vid_natt_i++;
        !           529: #endif
        !           530: #ifdef ENABLE_NATT_03
        !           531:        if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_03)) != NULL)
        !           532:                vid_natt_i++;
        !           533: #endif
        !           534: #ifdef ENABLE_NATT_02
        !           535:        if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_02)) != NULL)
        !           536:                vid_natt_i++;
        !           537:        if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_02_N)) != NULL)
        !           538:                vid_natt_i++;
        !           539: #endif
        !           540: #ifdef ENABLE_NATT_01
        !           541:        if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_01)) != NULL)
        !           542:                vid_natt_i++;
        !           543: #endif
        !           544: #ifdef ENABLE_NATT_00
        !           545:        if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_00)) != NULL)
        !           546:                vid_natt_i++;
        !           547: #endif
        !           548:        /* set VID payload for NAT-T */
        !           549:        for (i = 0; i < vid_natt_i; i++)
        !           550:                plist = isakmp_plist_append(plist, vid_natt[i], ISAKMP_NPTYPE_VID);
        !           551:        
        !           552:        return plist;
        !           553: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>