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