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>