1c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh/* $NetBSD: nattraversal.c,v 1.6.6.2 2009/05/18 17:01:07 tteras Exp $ */ 20a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 30a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* 40a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * Copyright (C) 2004 SuSE Linux AG, Nuernberg, Germany. 50a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * Contributed by: Michal Ludvig <mludvig@suse.cz>, SUSE Labs 60a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * All rights reserved. 70a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * 80a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * Redistribution and use in source and binary forms, with or without 90a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * modification, are permitted provided that the following conditions 100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * are met: 110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * 1. Redistributions of source code must retain the above copyright 120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * notice, this list of conditions and the following disclaimer. 130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * 2. Redistributions in binary form must reproduce the above copyright 140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * notice, this list of conditions and the following disclaimer in the 150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * documentation and/or other materials provided with the distribution. 160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * 3. Neither the name of the project nor the names of its contributors 170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * may be used to endorse or promote products derived from this software 180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * without specific prior written permission. 190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * 200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * SUCH DAMAGE. 310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */ 320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "config.h" 340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <sys/types.h> 360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <sys/param.h> 370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef __linux__ 390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <linux/udp.h> 400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#if defined(__NetBSD__) || defined (__FreeBSD__) 420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <netinet/udp.h> 430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <stdlib.h> 460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <stdio.h> 470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <string.h> 480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <errno.h> 490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <ctype.h> 500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "var.h" 520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "misc.h" 530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "vmbuf.h" 540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "plog.h" 550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "debug.h" 560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "localconf.h" 580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "remoteconf.h" 590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "sockmisc.h" 600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "isakmp_var.h" 610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "isakmp.h" 620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "oakley.h" 630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "ipsec_doi.h" 640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "vendorid.h" 650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "handler.h" 660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "crypto_openssl.h" 670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "schedule.h" 680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "nattraversal.h" 690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "grabmyaddr.h" 700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstruct natt_ka_addrs { 720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct sockaddr *src; 730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct sockaddr *dst; 740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang unsigned in_use; 750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang TAILQ_ENTRY(natt_ka_addrs) chain; 770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}; 780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic TAILQ_HEAD(_natt_ka_addrs, natt_ka_addrs) ka_tree; 800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* 820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * check if the given vid is NAT-T. 830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */ 840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint 850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangnatt_vendorid (int vid) 860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{ 870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return ( 880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_NATT_00 890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vid == VENDORID_NATT_00 || 900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_NATT_01 920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vid == VENDORID_NATT_01 || 930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_NATT_02 950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vid == VENDORID_NATT_02 || 960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vid == VENDORID_NATT_02_N || 970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_NATT_03 990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vid == VENDORID_NATT_03 || 1000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 1010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_NATT_04 1020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vid == VENDORID_NATT_04 || 1030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 1040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_NATT_05 1050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vid == VENDORID_NATT_05 || 1060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 1070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_NATT_06 1080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vid == VENDORID_NATT_06 || 1090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 1100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_NATT_07 1110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vid == VENDORID_NATT_07 || 1120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 1130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_NATT_08 1140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vid == VENDORID_NATT_08 || 1150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 1160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* Always enable NATT RFC if ENABLE_NATT 1170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */ 1180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vid == VENDORID_NATT_RFC); 1190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang} 1200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t * 1220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangnatt_hash_addr (struct ph1handle *iph1, struct sockaddr *addr) 1230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{ 1240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vchar_t *natd; 1250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vchar_t *buf; 1260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang char *ptr; 1270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang void *addr_ptr, *addr_port; 1280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang size_t buf_size, addr_size; 1290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog (LLV_INFO, LOCATION, addr, "Hashing %s with algo #%d %s\n", 1310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang saddr2str(addr), iph1->approval->hashtype, 132c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh (iph1->rmconf->nat_traversal == NATT_FORCE)?"(NAT-T forced)":""); 1330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (addr->sa_family == AF_INET) { 1350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang addr_size = sizeof (struct in_addr); /* IPv4 address */ 1360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang addr_ptr = &((struct sockaddr_in *)addr)->sin_addr; 1370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang addr_port = &((struct sockaddr_in *)addr)->sin_port; 1380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 1390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang else if (addr->sa_family == AF_INET6) { 1400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang addr_size = sizeof (struct in6_addr); /* IPv6 address */ 1410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang addr_ptr = &((struct sockaddr_in6 *)addr)->sin6_addr; 1420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang addr_port = &((struct sockaddr_in6 *)addr)->sin6_port; 1430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 1440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang else { 1450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog (LLV_ERROR, LOCATION, addr, "Unsupported address family #0x%x\n", addr->sa_family); 1460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return NULL; 1470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 1480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang buf_size = 2 * sizeof (cookie_t); /* CKY-I + CKY+R */ 1500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang buf_size += addr_size + 2; /* Address + Port */ 1510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if ((buf = vmalloc (buf_size)) == NULL) 1530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return NULL; 1540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang ptr = buf->v; 1560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* Copy-in CKY-I */ 1580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang memcpy (ptr, iph1->index.i_ck, sizeof (cookie_t)); 1590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang ptr += sizeof (cookie_t); 1600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* Copy-in CKY-I */ 1620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang memcpy (ptr, iph1->index.r_ck, sizeof (cookie_t)); 1630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang ptr += sizeof (cookie_t); 1640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* Copy-in Address (or zeroes if NATT_FORCE) */ 166c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (iph1->rmconf->nat_traversal == NATT_FORCE) 1670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang memset (ptr, 0, addr_size); 1680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang else 1690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang memcpy (ptr, addr_ptr, addr_size); 1700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang ptr += addr_size; 1710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* Copy-in Port number */ 1730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang memcpy (ptr, addr_port, 2); 1740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang natd = oakley_hash (buf, iph1); 1760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vfree(buf); 1770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return natd; 1790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang} 1800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint 1820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangnatt_compare_addr_hash (struct ph1handle *iph1, vchar_t *natd_received, 1830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang int natd_seq) 1840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{ 1850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vchar_t *natd_computed; 1860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang u_int32_t flag; 1870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang int verified = 0; 1880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 189c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (iph1->rmconf->nat_traversal == NATT_FORCE) 1900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return verified; 1910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (natd_seq == 0) { 1930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang natd_computed = natt_hash_addr (iph1, iph1->local); 1940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang flag = NAT_DETECTED_ME; 1950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 1960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang else { 1970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang natd_computed = natt_hash_addr (iph1, iph1->remote); 1980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang flag = NAT_DETECTED_PEER; 1990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 2000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (natd_computed == NULL) { 2020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, "natd_computed allocation failed\n"); 2030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return verified; /* XXX should abort */ 2040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 2050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (natd_received->l == natd_computed->l && 2070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang memcmp (natd_received->v, natd_computed->v, natd_received->l) == 0) { 2080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang iph1->natt_flags &= ~flag; 2090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang verified = 1; 2100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 2110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vfree (natd_computed); 2130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return verified; 2150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang} 2160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint 2180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangnatt_udp_encap (int encmode) 2190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{ 2200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return (encmode == IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_RFC || 2210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang encmode == IPSECDOI_ATTR_ENC_MODE_UDPTRNS_RFC || 2220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang encmode == IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_DRAFT || 2230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang encmode == IPSECDOI_ATTR_ENC_MODE_UDPTRNS_DRAFT); 2240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang} 2250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint 2270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangnatt_fill_options (struct ph1natt_options *opts, int version) 2280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{ 2290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (! opts) 2300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return -1; 2310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang opts->version = version; 2330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang switch (version) { 2350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang case VENDORID_NATT_00: 2360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang case VENDORID_NATT_01: 2370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang opts->float_port = 0; /* No port floating for those drafts */ 2380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang opts->payload_nat_d = ISAKMP_NPTYPE_NATD_DRAFT; 2390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang opts->payload_nat_oa = ISAKMP_NPTYPE_NATOA_DRAFT; 2400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang opts->mode_udp_tunnel = IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_DRAFT; 2410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang opts->mode_udp_transport = IPSECDOI_ATTR_ENC_MODE_UDPTRNS_DRAFT; 2420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang opts->encaps_type = UDP_ENCAP_ESPINUDP_NON_IKE; 2430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang break; 2440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang case VENDORID_NATT_02: 2460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang case VENDORID_NATT_02_N: 2470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang case VENDORID_NATT_03: 2480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang opts->float_port = lcconf->port_isakmp_natt; 2490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang opts->payload_nat_d = ISAKMP_NPTYPE_NATD_DRAFT; 2500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang opts->payload_nat_oa = ISAKMP_NPTYPE_NATOA_DRAFT; 2510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang opts->mode_udp_tunnel = IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_DRAFT; 2520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang opts->mode_udp_transport = IPSECDOI_ATTR_ENC_MODE_UDPTRNS_DRAFT; 2530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang opts->encaps_type = UDP_ENCAP_ESPINUDP; 2540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang break; 2550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang case VENDORID_NATT_04: 2560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang case VENDORID_NATT_05: 2570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang case VENDORID_NATT_06: 2580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang case VENDORID_NATT_07: 2590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang case VENDORID_NATT_08: 2600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang opts->float_port = lcconf->port_isakmp_natt; 2610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang opts->payload_nat_d = ISAKMP_NPTYPE_NATD_BADDRAFT; 2620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang opts->payload_nat_oa = ISAKMP_NPTYPE_NATOA_BADDRAFT; 2630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang opts->mode_udp_tunnel = IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_RFC; 2640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang opts->mode_udp_transport = IPSECDOI_ATTR_ENC_MODE_UDPTRNS_RFC; 2650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang opts->encaps_type = UDP_ENCAP_ESPINUDP; 2660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang break; 2670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang case VENDORID_NATT_RFC: 2680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang opts->float_port = lcconf->port_isakmp_natt; 2690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang opts->payload_nat_d = ISAKMP_NPTYPE_NATD_RFC; 2700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang opts->payload_nat_oa = ISAKMP_NPTYPE_NATOA_RFC; 2710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang opts->mode_udp_tunnel = IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_RFC; 2720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang opts->mode_udp_transport = IPSECDOI_ATTR_ENC_MODE_UDPTRNS_RFC; 2730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang opts->encaps_type = UDP_ENCAP_ESPINUDP; 2740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang break; 2750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang default: 2760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, 2770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "unsupported NAT-T version: %s\n", 2780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vid_string_by_id(version)); 2790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return -1; 2800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 2810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang opts->mode_udp_diff = opts->mode_udp_tunnel - IPSECDOI_ATTR_ENC_MODE_TUNNEL; 2830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return 0; 2850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang} 2860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid 2880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangnatt_float_ports (struct ph1handle *iph1) 2890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{ 290051f86dfca525c160855397f7b6a4fb5ef8df2b5Chia-chi Yeh if (! (iph1->natt_flags & NAT_DETECTED) ) 2910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return; 2920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (! iph1->natt_options->float_port){ 2930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* Drafts 00 / 01, just schedule keepalive */ 2940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang natt_keepalive_add_ph1 (iph1); 2950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return; 2960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 2970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang set_port (iph1->local, iph1->natt_options->float_port); 2990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang set_port (iph1->remote, iph1->natt_options->float_port); 3000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang iph1->natt_flags |= NAT_PORTS_CHANGED | NAT_ADD_NON_ESP_MARKER; 3010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 3020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang natt_keepalive_add_ph1 (iph1); 3030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang} 3040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 3050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid 3060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangnatt_handle_vendorid (struct ph1handle *iph1, int vid_numeric) 3070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{ 3080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (! iph1->natt_options) 3090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang iph1->natt_options = racoon_calloc (1, sizeof (*iph1->natt_options)); 3100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 3110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (! iph1->natt_options) { 3120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog (LLV_ERROR, LOCATION, NULL, 3130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "Allocating memory for natt_options failed!\n"); 3140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return; 3150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 3160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 3170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (iph1->natt_options->version < vid_numeric) 3180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (natt_fill_options (iph1->natt_options, vid_numeric) == 0) 3190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang iph1->natt_flags |= NAT_ANNOUNCED; 3200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang} 3210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 3221c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yehstatic void 3231c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yehnatt_keepalive_delete (struct natt_ka_addrs *ka) 3241c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh{ 3251c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh TAILQ_REMOVE (&ka_tree, ka, chain); 3261c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh racoon_free (ka->src); 3271c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh racoon_free (ka->dst); 3281c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh racoon_free (ka); 3291c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh} 3301c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh 3310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* NAT keepalive functions */ 3320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic void 333c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehnatt_keepalive_send (void *param) 3340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{ 3350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct natt_ka_addrs *ka, *next = NULL; 3360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang char keepalive_packet[] = { 0xff }; 3370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang size_t len; 3380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang int s; 3390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 3400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang for (ka = TAILQ_FIRST(&ka_tree); ka; ka = next) { 3410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang next = TAILQ_NEXT(ka, chain); 3420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 343c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh s = getsockmyaddr(ka->src); 3440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (s == -1) { 3451c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh natt_keepalive_delete(ka); 3460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang continue; 3470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 3480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog (LLV_DEBUG, LOCATION, NULL, "KA: %s\n", 3490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang saddr2str_fromto("%s->%s", ka->src, ka->dst)); 3500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang len = sendfromto(s, keepalive_packet, sizeof (keepalive_packet), 3510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang ka->src, ka->dst, 1); 3520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (len == -1) 3530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, "KA: sendfromto failed: %s\n", 3540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang strerror (errno)); 3550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 3560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 357c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh sched_new (lcconf->natt_ka_interval, natt_keepalive_send, NULL); 3580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang} 3590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 3600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid 3610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangnatt_keepalive_init (void) 3620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{ 3630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang TAILQ_INIT(&ka_tree); 3640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 3650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* To disable sending KAs set natt_ka_interval=0 */ 3660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (lcconf->natt_ka_interval > 0) 367c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh sched_new (lcconf->natt_ka_interval, natt_keepalive_send, NULL); 3680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang} 3690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 3700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint 3710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangnatt_keepalive_add (struct sockaddr *src, struct sockaddr *dst) 3720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{ 3730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct natt_ka_addrs *ka = NULL, *new_addr; 3740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 3750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang TAILQ_FOREACH (ka, &ka_tree, chain) { 376c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (cmpsaddrstrict(ka->src, src) == 0 && 377c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh cmpsaddrstrict(ka->dst, dst) == 0) { 3780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang ka->in_use++; 3790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog (LLV_INFO, LOCATION, NULL, "KA found: %s (in_use=%u)\n", 3800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang saddr2str_fromto("%s->%s", src, dst), ka->in_use); 3810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return 0; 3820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 3830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 3840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 3850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog (LLV_INFO, LOCATION, NULL, "KA list add: %s\n", saddr2str_fromto("%s->%s", src, dst)); 3860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 3870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang new_addr = (struct natt_ka_addrs *)racoon_malloc(sizeof(*new_addr)); 3880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (! new_addr) { 3890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog (LLV_ERROR, LOCATION, NULL, "Can't allocate new KA list item\n"); 3900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return -1; 3910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 3920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 3930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if ((new_addr->src = dupsaddr(src)) == NULL) { 3940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang racoon_free(new_addr); 3950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog (LLV_ERROR, LOCATION, NULL, "Can't allocate new KA list item\n"); 3960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return -1; 3970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 3980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if ((new_addr->dst = dupsaddr(dst)) == NULL) { 3990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang racoon_free(new_addr); 4000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog (LLV_ERROR, LOCATION, NULL, "Can't allocate new KA list item\n"); 4010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return -1; 4020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 4030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang new_addr->in_use = 1; 4040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang TAILQ_INSERT_TAIL(&ka_tree, new_addr, chain); 4050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 4060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return 0; 4070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang} 4080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 4090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint 4100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangnatt_keepalive_add_ph1 (struct ph1handle *iph1) 4110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{ 4120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang int ret = 0; 4130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 4140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* Should only the NATed host send keepalives? 4150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang If yes, add '(iph1->natt_flags & NAT_DETECTED_ME)' 4160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang to the following condition. */ 4170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (iph1->natt_flags & NAT_DETECTED && 4180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang ! (iph1->natt_flags & NAT_KA_QUEUED)) { 4190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang ret = natt_keepalive_add (iph1->local, iph1->remote); 4200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (ret == 0) 4210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang iph1->natt_flags |= NAT_KA_QUEUED; 4220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 4230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 4240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return ret; 4250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang} 4260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 4270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid 4280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangnatt_keepalive_remove (struct sockaddr *src, struct sockaddr *dst) 4290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{ 4300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct natt_ka_addrs *ka, *next = NULL; 4310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 4320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog (LLV_INFO, LOCATION, NULL, "KA remove: %s\n", saddr2str_fromto("%s->%s", src, dst)); 4330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 4340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang for (ka = TAILQ_FIRST(&ka_tree); ka; ka = next) { 4350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang next = TAILQ_NEXT(ka, chain); 4360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 4370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog (LLV_DEBUG, LOCATION, NULL, "KA tree dump: %s (in_use=%u)\n", 4380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang saddr2str_fromto("%s->%s", src, dst), ka->in_use); 4390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 440c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh if (cmpsaddrstrict(ka->src, src) == 0 && 441c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh cmpsaddrstrict(ka->dst, dst) == 0 && 4420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang -- ka->in_use <= 0) { 4430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 4440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog (LLV_DEBUG, LOCATION, NULL, "KA removing this one...\n"); 4450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 4461c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh natt_keepalive_delete (ka); 4470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* Should we break here? Every pair of addresses should 4480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang be inserted only once, but who knows :-) Lets traverse 4490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang the whole list... */ 4500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 4510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 4520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang} 4530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 454c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehstatic struct remoteconf * 4550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangnatt_enabled_in_rmconf_stub (struct remoteconf *rmconf, void *data) 4560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{ 457c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh return (rmconf->nat_traversal ? rmconf : NULL); 4580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang} 4590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 4600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint 4610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangnatt_enabled_in_rmconf () 4620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{ 463c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh return foreachrmconf (natt_enabled_in_rmconf_stub, NULL) != NULL; 4640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang} 4650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 4660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 4670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstruct payload_list * 4680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_plist_append_natt_vids (struct payload_list *plist, vchar_t *vid_natt[MAX_NATT_VID_COUNT]){ 4690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang int i, vid_natt_i = 0; 4700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 4710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if(vid_natt == NULL) 4720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return NULL; 4730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 4740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang for (i = 0; i < MAX_NATT_VID_COUNT; i++) 4750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vid_natt[i]=NULL; 4760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 4770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* Puts the olders VIDs last, as some implementations may choose the first 4780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * NATT VID given 4790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */ 4800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 4810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* Always set RFC VID 4820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */ 4830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_RFC)) != NULL) 4840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vid_natt_i++; 4850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_NATT_08 4860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_08)) != NULL) 4870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vid_natt_i++; 4880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 4890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_NATT_07 4900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_07)) != NULL) 4910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vid_natt_i++; 4920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 4930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_NATT_06 4940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_06)) != NULL) 4950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vid_natt_i++; 4960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 4970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_NATT_05 4980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_05)) != NULL) 4990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vid_natt_i++; 5000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 5010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_NATT_04 5020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_04)) != NULL) 5030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vid_natt_i++; 5040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 5050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_NATT_03 5060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_03)) != NULL) 5070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vid_natt_i++; 5080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 5090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_NATT_02 5100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_02)) != NULL) 5110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vid_natt_i++; 5120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_02_N)) != NULL) 5130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vid_natt_i++; 5140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 5150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_NATT_01 5160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_01)) != NULL) 5170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vid_natt_i++; 5180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 5190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_NATT_00 5200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_00)) != NULL) 5210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vid_natt_i++; 5220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 5230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* set VID payload for NAT-T */ 5240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang for (i = 0; i < vid_natt_i; i++) 5250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plist = isakmp_plist_append(plist, vid_natt[i], ISAKMP_NPTYPE_VID); 5260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 5270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return plist; 5280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang} 529