Return to nattraversal.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / ipsec-tools / src / racoon |
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: }