--- isakmpd-20041012.orig/dpd.c
+++ isakmpd-20041012/dpd.c
@@ -26,6 +26,7 @@
 
 #include <sys/types.h>
 #include <stdlib.h>
+#include <memory.h>
 
 #include "sysdep.h"
 
@@ -174,6 +175,7 @@
 		}
 		break;
 	default:
+	;
 	}
 
 	/* Mark handled.  */
@@ -223,6 +225,7 @@
 		    dpd_check_event, sa, &tv);
 		break;
 	default:
+	;
 	}
 	if (!sa->dpd_event) 
 		log_print("dpd_timer_reset: timer_add_event failed");
--- isakmpd-20041012.orig/ipsec.c
+++ isakmpd-20041012/ipsec.c
@@ -1020,6 +1020,52 @@
 	}
 }
 
+/*
+ * deal with a NOTIFY of INVALID_SPI
+ */
+static void
+ipsec_invalid_spi (struct message *msg, struct payload *p)
+{
+  struct sockaddr *dst;
+  int invspisz, off;
+  u_int32_t spi;
+  u_int16_t totsiz;
+  u_int8_t spisz;
+
+  /* Any notification that make us do something should be protected */
+  if(!TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_HASH]))
+    {
+      LOG_DBG ((LOG_SA, 40,
+      	       "ipsec_invalid_spi: missing HASH payload in INVALID_SPI"
+      	       " notification"));
+      return;
+    }
+
+  /*
+   * get the invalid spi out of the variable sized notification data
+   * field, which is after the variable sized SPI field [which specifies
+   * the receiving entity's phase-1 SPI, not the invalid spi]
+   */
+  totsiz = GET_ISAKMP_GEN_LENGTH (p->p);
+  spisz = GET_ISAKMP_NOTIFY_SPI_SZ (p->p);
+  off = ISAKMP_NOTIFY_SPI_OFF + spisz;
+  invspisz = totsiz - off;
+
+  if (invspisz != sizeof spi)
+    {
+      LOG_DBG ((LOG_SA, 40,
+	       "ipsec_invalid_spi: SPI size %d in INVALID_SPI "
+	       "payload unsupported", spisz));
+       return;
+    }
+  memcpy (&spi, p->p + off, sizeof spi);
+
+  msg->transport->vtbl->get_dst (msg->transport, &dst);
+
+  /* delete matching SPI's from this peer */
+  ipsec_delete_spi_list (dst, 0, (u_int8_t *)&spi, 1, "INVALID_SPI");
+}
+
 static int
 ipsec_responder(struct message *msg)
 {
@@ -1205,7 +1251,9 @@
 			return dv != IPSEC_ENCAP_TUNNEL
 			    && dv != IPSEC_ENCAP_TRANSPORT
 			    && dv != IPSEC_ENCAP_UDP_ENCAP_TUNNEL
-			    && dv != IPSEC_ENCAP_UDP_ENCAP_TRANSPORT;
+			    && dv != IPSEC_ENCAP_UDP_ENCAP_TRANSPORT
+			    && dv != IPSEC_ENCAP_UDP_ENCAP_TUNNEL_DRAFT
+			    && dv != IPSEC_ENCAP_UDP_ENCAP_TRANSPORT_DRAFT;
 #else
 			return dv < IPSEC_ENCAP_TUNNEL
 			    || dv > IPSEC_ENCAP_TRANSPORT;
@@ -1837,7 +1885,7 @@
 ipsec_get_id(char *section, int *id, struct sockaddr **addr,
     struct sockaddr **mask, u_int8_t *tproto, u_int16_t *port)
 {
-	char	*type, *address, *netmask;
+    char	*type, *address, *netmask;
 
 	type = conf_get_str(section, "ID-type");
 	if (!type) {
--- isakmpd-20041012.orig/GNUmakefile
+++ isakmpd-20041012/GNUmakefile
@@ -40,12 +40,12 @@
 # integrated, freebsd/netbsd means FreeBSD/NetBSD with KAME IPsec.
 # darwin means MacOS X 10.2 and later with KAME IPsec. linux means Linux-2.5
 # and later with native IPSec support.
-OS=		openbsd
+#OS=		openbsd
 #OS=		netbsd
 #OS=		freebsd
 #OS=		freeswan
 #OS=		darwin
-#OS=		linux
+OS=		linux
 
 .CURDIR:=	$(shell pwd)
 VPATH=		${.CURDIR}/sysdep/${OS}
@@ -55,9 +55,10 @@
 ifndef BINDIR
 BINDIR=		/sbin
 endif
-ifndef LDSTATIC
-LDSTATIC=	-static
-endif
+
+#ifndef LDSTATIC
+#LDSTATIC=	-static
+#endif
 
 SRCS=		app.c attribute.c cert.c connection.c \
 		constants.c conf.c cookie.c crypto.c dh.c doi.c exchange.c \
@@ -131,11 +132,14 @@
 ifneq ($(findstring install,$(MAKECMDGOALS)),install)
 # Skip 'regress' until the regress/ structure has gmake makefiles for it.
 #SUBDIR:=	regress
-SUBDIR:=
+#SUBDIR:=	apps/certpatch
 mksubdirs:
 	$(foreach DIR, ${SUBDIR}, \
-		cd ${DIR}; ${MAKE} ${MAKEFLAGS} CFLAGS="${CFLAGS}" \
-			MKDEP="${MKDEP}" ${MAKECMDGOALS})
+		cd ${.CURDIR}/${DIR}; ${MAKE} ${MAKECMDGOALS};)
+		
+#	$(foreach DIR, ${SUBDIR}, \
+#		cd ${DIR}; ${MAKE} CFLAGS="${CFLAGS}" \
+#			MKDEP="${MKDEP}" ${MAKECMDGOALS})
 else
 mksubdirs:
 endif
@@ -173,7 +177,7 @@
 endif
 
 SRCS+=		${IPSEC_SRCS} ${X509} ${POLICY} ${EC} ${AGGRESSIVE} ${DNSSEC} \
-		$(ISAKMP_CFG)
+			$(ISAKMP_CFG) ${DPD} ${NAT_TRAVERSAL}
 CFLAGS+=	${IPSEC_CFLAGS}
 LDADD+=		${DESLIB}
 DPADD+=		${DESLIBDEP}
--- isakmpd-20041012.orig/exchange.h
+++ isakmpd-20041012/exchange.h
@@ -221,6 +221,8 @@
 #define EXCHANGE_FLAG_NAT_T_ENABLE	0x10	/* We are doing NAT-T.  */
 #define EXCHANGE_FLAG_NAT_T_KEEPALIVE	0x20	/* We are the NAT:ed peer.  */
 #define EXCHANGE_FLAG_DPD_CAP_PEER	0x40	/* Peer is DPD capable.  */
+#define EXCHANGE_FLAG_NAT_T_RFC		0x0080	/* Peer does RFC NAT-T. */
+#define EXCHANGE_FLAG_NAT_T_DRAFT	0x0100	/* Peer does draft NAT-T.*/
 
 extern int      exchange_add_certs(struct message *);
 extern void     exchange_finalize(struct message *);
--- isakmpd-20041012.orig/log.c
+++ isakmpd-20041012/log.c
@@ -79,7 +79,6 @@
 
 struct packhdr {
 	struct pcap_pkthdr pcap;/* pcap file packet header */
-	u_int32_t sa_family;	/* address family */
 	union {
 		struct ip       ip4;	/* IPv4 header (w/o options) */
 		struct ip6_hdr  ip6;	/* IPv6 header */
@@ -97,7 +96,7 @@
 static u_int8_t *packet_buf = NULL;
 
 static int      udp_cksum(struct packhdr *, const struct udphdr *,
-    u_int16_t *);
+    u_int16_t *, int);
 static u_int16_t in_cksum(const u_int16_t *, int);
 #endif				/* USE_DEBUG */
 
@@ -539,11 +538,9 @@
 	udp.uh_ulen = htons(datalen);
 
 	/* ip */
-	hdr.sa_family = htonl(src->sa_family);
 	switch (src->sa_family) {
 	default:
 		/* Assume IPv4. XXX Can 'default' ever happen here?  */
-		hdr.sa_family = htonl(AF_INET);
 		hdr.ip.ip4.ip_src.s_addr = 0x02020202;
 		hdr.ip.ip4.ip_dst.s_addr = 0x01010101;
 		/* The rest of the setup is common to AF_INET.  */
@@ -584,9 +581,7 @@
 	}
 
 	/* Calculate UDP checksum.  */
-	udp.uh_sum = udp_cksum(&hdr, &udp, (u_int16_t *) packet_buf);
-	hdrlen += sizeof hdr.sa_family;
-
+	udp.uh_sum = udp_cksum(&hdr, &udp, (u_int16_t *) packet_buf, src->sa_family);
 	/* pcap file packet header */
 	gettimeofday(&tv, 0);
 	hdr.pcap.ts.tv_sec = tv.tv_sec;
@@ -610,7 +605,7 @@
 
 /* Copied from tcpdump/print-udp.c, mostly rewritten.  */
 static int
-udp_cksum(struct packhdr *hdr, const struct udphdr *u, u_int16_t *d)
+udp_cksum(struct packhdr *hdr, const struct udphdr *u, u_int16_t *d, int af)
 {
 	struct ip	*ip4;
 	struct ip6_hdr	*ip6;
@@ -639,7 +634,7 @@
 
 	/* Setup pseudoheader.  */
 	memset(phu.pa, 0, sizeof phu);
-	switch (ntohl(hdr->sa_family)) {
+	switch (af) {
 	case AF_INET:
 		ip4 = &hdr->ip.ip4;
 		memcpy(&phu.ip4p.src, &ip4->ip_src, sizeof(struct in_addr));
@@ -664,7 +659,7 @@
 
 	/* IPv6 wants a 0xFFFF checksum "on error", not 0x0.  */
 	if (tlen < 0)
-		return (ntohl(hdr->sa_family) == AF_INET ? 0 : 0xFFFF);
+		return (af == AF_INET ? 0 : 0xFFFF);
 
 	sum = 0;
 	for (i = 0; i < hdrlen; i += 2)
--- isakmpd-20041012.orig/nat_traversal.c
+++ isakmpd-20041012/nat_traversal.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: nat_traversal.c,v 1.7 2004/08/08 19:11:06 deraadt Exp $	*/
+/*	$OpenBSD: nat_traversal.c,v 1.17 2006/06/14 14:03:33 hshoexer Exp $	*/
 
 /*
  * Copyright (c) 2004 H�kan Olsson.  All rights reserved.
@@ -48,40 +48,40 @@
 #include "util.h"
 #include "virtual.h"
 
+int	disable_nat_t = 0;
+
 /*
- * XXX According to draft-ietf-ipsec-nat-t-ike-07.txt, the NAT-T
- * capability of the other peer is determined by a particular vendor ID
- * sent as the first message. This vendor ID string is supposed to be a
- * MD5 hash of "RFC XXXX", where XXXX is the future RFC number.
+ * NAT-T capability of the other peer is determined by a particular vendor
+ * ID sent in the first message. This vendor ID string is supposed to be a
+ * MD5 hash of "RFC 3947".
  *
  * These seem to be the "well" known variants of this string in use by
  * products today.
  */
-static const char *isakmp_nat_t_cap_text[] = {
-	"draft-ietf-ipsec-nat-t-ike-00",	/* V1 (XXX: may be obsolete) */
-	"draft-ietf-ipsec-nat-t-ike-02\n",	/* V2 */
-	"draft-ietf-ipsec-nat-t-ike-03",	/* V3 */
-#ifdef notyet
-	"RFC XXXX",
-#endif
+
+static struct nat_t_cap isakmp_nat_t_cap[] = {
+	{ VID_DRAFT_V2_N, EXCHANGE_FLAG_NAT_T_DRAFT,
+	  "draft-ietf-ipsec-nat-t-ike-02\n", NULL, 0 },
+	{ VID_DRAFT_V3, EXCHANGE_FLAG_NAT_T_DRAFT,
+	  "draft-ietf-ipsec-nat-t-ike-03", NULL, 0 },
+	{ VID_RFC3947, EXCHANGE_FLAG_NAT_T_RFC,
+	  "RFC 3947", NULL, 0 },
 };
 
+#define NUMNATTCAP	(sizeof isakmp_nat_t_cap / sizeof isakmp_nat_t_cap[0])
+
 /* In seconds. Recommended in draft-ietf-ipsec-udp-encaps-09.  */
 #define NAT_T_KEEPALIVE_INTERVAL	20
 
-/* The MD5 hashes of the above strings is put in this array.  */
-static char	**nat_t_hashes;
-static size_t	  nat_t_hashsize;
-
 static int	nat_t_setup_hashes(void);
-static int	nat_t_add_vendor_payload(struct message *, char *);
+static int	nat_t_add_vendor_payload(struct message *, struct nat_t_cap *);
 static int	nat_t_add_nat_d(struct message *, struct sockaddr *);
 static int	nat_t_match_nat_d_payload(struct message *, struct sockaddr *);
 
 void
 nat_t_init(void)
 {
-	nat_t_hashes = (char **)NULL;
+	nat_t_setup_hashes();
 }
 
 /* Generate the NAT-T capability marker hashes. Executed only once.  */
@@ -89,7 +89,7 @@
 nat_t_setup_hashes(void)
 {
 	struct hash *hash;
-	int n = sizeof isakmp_nat_t_cap_text / sizeof isakmp_nat_t_cap_text[0];
+	int n = NUMNATTCAP;
 	int i;
 
 	/* The draft says to use MD5.  */
@@ -100,56 +100,49 @@
 		    "could not find MD5 hash structure!");
 		return -1;
 	}
-	nat_t_hashsize = hash->hashsize;
 
-	/* Allocate one more than is necessary, i.e NULL terminated.  */
-	nat_t_hashes = (char **)calloc((size_t)(n + 1), sizeof(char *));
-	if (!nat_t_hashes) {
-		log_error("nat_t_setup_hashes: calloc (%lu,%lu) failed",
-		    (unsigned long)n, (unsigned long)sizeof(char *));
-		return -1;
-	}
-
-	/* Populate with hashes.  */
+	/* Populate isakmp_nat_t_cap with hashes.  */
 	for (i = 0; i < n; i++) {
-		nat_t_hashes[i] = (char *)malloc(nat_t_hashsize);
-		if (!nat_t_hashes[i]) {
+		isakmp_nat_t_cap[i].hashsize = hash->hashsize;
+		isakmp_nat_t_cap[i].hash = (char *)malloc(hash->hashsize);
+		if (!isakmp_nat_t_cap[i].hash) {
 			log_error("nat_t_setup_hashes: malloc (%lu) failed",
-			    (unsigned long)nat_t_hashsize);
+			    (unsigned long)hash->hashsize);
 			goto errout;
 		}
 
 		hash->Init(hash->ctx);
 		hash->Update(hash->ctx,
-		    (unsigned char *)isakmp_nat_t_cap_text[i],
-		    strlen(isakmp_nat_t_cap_text[i]));
-		hash->Final(nat_t_hashes[i], hash->ctx);
+		    (unsigned char *)isakmp_nat_t_cap[i].text,
+		    strlen(isakmp_nat_t_cap[i].text));
+		hash->Final(isakmp_nat_t_cap[i].hash, hash->ctx);
 
 		LOG_DBG((LOG_EXCHANGE, 50, "nat_t_setup_hashes: "
-		    "MD5(\"%s\") (%lu bytes)", isakmp_nat_t_cap_text[i],
-		    (unsigned long)nat_t_hashsize));
+		    "MD5(\"%s\") (%lu bytes)", isakmp_nat_t_cap[i].text,
+		    (unsigned long)hash->hashsize));
 		LOG_DBG_BUF((LOG_EXCHANGE, 50, "nat_t_setup_hashes",
-		    nat_t_hashes[i], nat_t_hashsize));
+		    isakmp_nat_t_cap[i].hash, hash->hashsize));
 	}
 
 	return 0;
 
-  errout:
+errout:
 	for (i = 0; i < n; i++)
-		if (nat_t_hashes[i])
-			free(nat_t_hashes[i]);
-	free(nat_t_hashes);
-	nat_t_hashes = NULL;
+		if (isakmp_nat_t_cap[i].hash)
+			free(isakmp_nat_t_cap[i].hash);
 	return -1;
 }
 
 /* Add one NAT-T VENDOR payload.  */
 static int
-nat_t_add_vendor_payload(struct message *msg, char *hash)
+nat_t_add_vendor_payload(struct message *msg, struct nat_t_cap *cap)
 {
-	size_t	 buflen = nat_t_hashsize + ISAKMP_GEN_SZ;
+	size_t	  buflen = cap->hashsize + ISAKMP_GEN_SZ;
 	u_int8_t *buf;
 
+	if (disable_nat_t)
+		return 0;
+
 	buf = malloc(buflen);
 	if (!buf) {
 		log_error("nat_t_add_vendor_payload: malloc (%lu) failed",
@@ -158,12 +151,11 @@
 	}
 
 	SET_ISAKMP_GEN_LENGTH(buf, buflen);
-	memcpy(buf + ISAKMP_VENDOR_ID_OFF, hash, nat_t_hashsize);
+	memcpy(buf + ISAKMP_VENDOR_ID_OFF, cap->hash, cap->hashsize);
 	if (message_add_payload(msg, ISAKMP_PAYLOAD_VENDOR, buf, buflen, 1)) {
 		free(buf);
 		return -1;
 	}
-
 	return 0;
 }
 
@@ -171,16 +163,14 @@
 int
 nat_t_add_vendor_payloads(struct message *msg)
 {
-	int i = 0;
+	int i;
 
-	if (!nat_t_hashes)
-		if (nat_t_setup_hashes())
-			return 0;  /* XXX should this be an error?  */
+	if (disable_nat_t)
+		return 0;
 
-	while (nat_t_hashes[i])
-		if (nat_t_add_vendor_payload(msg, nat_t_hashes[i++]))
+	for (i = 0; i < NUMNATTCAP; i++)
+		if (nat_t_add_vendor_payload(msg, &isakmp_nat_t_cap[i]))
 			return -1;
-
 	return 0;
 }
 
@@ -192,36 +182,31 @@
 {
 	u_int8_t *pbuf = p->p;
 	size_t	  vlen;
-	int	  i = 0;
+	int	  i;
 
-	/* Already checked? */
-	if (p->flags & PL_MARK ||
-	    msg->exchange->flags & EXCHANGE_FLAG_NAT_T_CAP_PEER)
+	if (disable_nat_t)
 		return;
 
-	if (!nat_t_hashes)
-		if (nat_t_setup_hashes())
-			return;
-
 	vlen = GET_ISAKMP_GEN_LENGTH(pbuf) - ISAKMP_GEN_SZ;
-	if (vlen != nat_t_hashsize) {
-		LOG_DBG((LOG_EXCHANGE, 50, "nat_t_check_vendor_payload: "
-		    "bad size %lu != %lu", (unsigned long)vlen,
-		    (unsigned long)nat_t_hashsize));
-		return;
-	}
 
-	while (nat_t_hashes[i])
-		if (memcmp(nat_t_hashes[i++], pbuf + ISAKMP_GEN_SZ,
+	for (i = 0; i < NUMNATTCAP; i++) {
+		if (vlen != isakmp_nat_t_cap[i].hashsize) {
+			LOG_DBG((LOG_EXCHANGE, 50, "nat_t_check_vendor_payload: "
+			    "bad size %lu != %lu", (unsigned long)vlen,
+			    (unsigned long)isakmp_nat_t_cap[i].hashsize));
+			continue;
+		}
+		if (memcmp(isakmp_nat_t_cap[i].hash, pbuf + ISAKMP_GEN_SZ,
 		    vlen) == 0) {
 			/* This peer is NAT-T capable.  */
 			msg->exchange->flags |= EXCHANGE_FLAG_NAT_T_CAP_PEER;
+			msg->exchange->flags |= isakmp_nat_t_cap[i].flags;
 			LOG_DBG((LOG_EXCHANGE, 10,
 			    "nat_t_check_vendor_payload: "
 			    "NAT-T capable peer detected"));
 			p->flags |= PL_MARK;
-			return;
 		}
+	}
 
 	return;
 }
@@ -233,10 +218,8 @@
 {
 	struct ipsec_exch *ie = (struct ipsec_exch *)msg->exchange->data;
 	struct hash	 *hash;
-	struct prf	 *prf;
 	u_int8_t	 *res;
 	in_port_t	  port;
-	int		  prf_type = PRF_HMAC; /* XXX */
 
 	hash = hash_get(ie->hash->type);
 	if (hash == NULL) {
@@ -244,31 +227,25 @@
 		return NULL;
 	}
 
-	prf = prf_alloc(prf_type, hash->type, msg->exchange->cookies,
-	    ISAKMP_HDR_COOKIES_LEN);
-	if(!prf) {
-		log_print("nat_t_generate_nat_d_hash: prf_alloc failed");
-		return NULL;
-	}
+	*hashlen = hash->hashsize;
 
-	*hashlen = prf->blocksize;
 	res = (u_int8_t *)malloc((unsigned long)*hashlen);
 	if (!res) {
 		log_print("nat_t_generate_nat_d_hash: malloc (%lu) failed",
 		    (unsigned long)*hashlen);
-		prf_free(prf);
 		*hashlen = 0;
 		return NULL;
 	}
 
 	port = sockaddr_port(sa);
-	memset(res, 0, *hashlen);
-
-	prf->Update(prf->prfctx, sockaddr_addrdata(sa), sockaddr_addrlen(sa));
-	prf->Update(prf->prfctx, (unsigned char *)&port, sizeof port);
-	prf->Final(res, prf->prfctx);
-	prf_free (prf);
+	bzero(res, *hashlen);
 
+	hash->Init(hash->ctx);
+	hash->Update(hash->ctx, msg->exchange->cookies,
+	    sizeof msg->exchange->cookies);
+	hash->Update(hash->ctx, sockaddr_addrdata(sa), sockaddr_addrlen(sa));
+	hash->Update(hash->ctx, (unsigned char *)&port, sizeof port);
+	hash->Final(res, hash->ctx);
 	return res;
 }
 
@@ -276,6 +253,7 @@
 static int
 nat_t_add_nat_d(struct message *msg, struct sockaddr *sa)
 {
+	int	  ret;
 	u_int8_t *hbuf, *buf;
 	size_t	  hbuflen, buflen;
 
@@ -298,11 +276,19 @@
 	memcpy(buf + ISAKMP_NAT_D_DATA_OFF, hbuf, hbuflen);
 	free(hbuf);
 
-	if (message_add_payload(msg, ISAKMP_PAYLOAD_NAT_D, buf, buflen, 1)) {
+	if (msg->exchange->flags & EXCHANGE_FLAG_NAT_T_RFC)
+		ret = message_add_payload(msg, ISAKMP_PAYLOAD_NAT_D, buf,
+		    buflen, 1);
+	else if (msg->exchange->flags & EXCHANGE_FLAG_NAT_T_DRAFT)
+		ret = message_add_payload(msg, ISAKMP_PAYLOAD_NAT_D_DRAFT,
+		    buf, buflen, 1);
+	else
+		ret = -1;
+		
+	if (ret) {
 		free(buf);
 		return -1;
 	}
-
 	return 0;
 }
 
@@ -312,14 +298,14 @@
 {
 	struct sockaddr *sa;
 
-	msg->transport->vtbl->get_src(msg->transport, &sa);
+	/* Remote address first. */
+	msg->transport->vtbl->get_dst(msg->transport, &sa);
 	if (nat_t_add_nat_d(msg, sa))
 		return -1;
 
-	msg->transport->vtbl->get_dst(msg->transport, &sa);
+	msg->transport->vtbl->get_src(msg->transport, &sa);
 	if (nat_t_add_nat_d(msg, sa))
 		return -1;
-
 	return 0;
 }
 
@@ -336,8 +322,8 @@
 	 * If there are no NAT-D payloads in the message, return "found"
 	 * as this will avoid NAT-T (see nat_t_exchange_check_nat_d()).
 	 */
-	p = payload_first(msg, ISAKMP_PAYLOAD_NAT_D);
-	if (!p)
+	if ((p = payload_first(msg, ISAKMP_PAYLOAD_NAT_D_DRAFT)) == NULL &&
+	    (p = payload_first(msg, ISAKMP_PAYLOAD_NAT_D)) == NULL)
 		return 1;
 
 	hbuf = nat_t_generate_nat_d_hash(msg, sa, &hbuflen);
--- isakmpd-20041012.orig/udp_encap.c
+++ isakmpd-20041012/udp_encap.c
@@ -61,6 +61,11 @@
 
 #define UDP_SIZE 65536
 
+#if defined(USE_NAT_TRAVERSAL) && defined (LINUX_IPSEC)
+#include <linux/socket.h>
+#include <linux/udp.h>
+#endif
+
 /* If a system doesn't have SO_REUSEPORT, SO_REUSEADDR will have to do.  */
 #ifndef SO_REUSEPORT
 #define SO_REUSEPORT SO_REUSEADDR
@@ -134,6 +139,18 @@
 	if (sysdep_cleartext(s, laddr->sa_family) == -1)
 		goto err;
 
+#if defined(USE_NAT_TRAVERSAL) && defined (LINUX_IPSEC)
+    {
+#ifndef SOL_UDP
+#define SOL_UDP 17
+#endif
+        int option = UDP_ENCAP_ESPINUDP;
+        if(setsockopt(s, SOL_UDP, UDP_ENCAP, &option,
+                      sizeof (option)) < 0)
+            goto err;
+    }
+#endif
+
 	/* Wildcard address ?  */
 	switch (laddr->sa_family) {
 	case AF_INET:
--- isakmpd-20041012.orig/apps/Makefile
+++ isakmpd-20041012/apps/Makefile
@@ -31,4 +31,4 @@
 
 SUBDIR= certpatch
 
-.include <bsd.subdir.mk>
+#.include <bsd.subdir.mk>
--- isakmpd-20041012.orig/apps/certpatch/GNUmakefile
+++ isakmpd-20041012/apps/certpatch/GNUmakefile
@@ -0,0 +1,55 @@
+#	$OpenBSD: Makefile,v 1.7 2003/06/03 14:35:00 ho Exp $
+#	$EOM: Makefile,v 1.6 2000/03/28 21:22:06 ho Exp $
+
+#
+# Copyright (c) 1999 Niels Provos.  All rights reserved.
+# Copyright (c) 2001 Niklas Hallqvist.  All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+#
+# This code was written under funding by Ericsson Radio Systems.
+#
+
+PROG=		certpatch
+SRCS=		certpatch.c
+BINDIR?=	/usr/sbin
+TOPSRC=		${.CURDIR}../..
+TOPOBJ!=	cd ${TOPSRC}; printf "all:\n\t@pwd\n" |${MAKE} -f-
+OS=			linux
+FEATURES!=	awk '/^FEATURES=/ { print $$0 }' ${.CURDIR}/../../Makefile | sed 's/FEATURES=.//'
+.PATH:		${TOPSRC} ${TOPSRC}/sysdep/${OS} ${TOPOBJ}
+CFLAGS+=	-I${TOPSRC} -I${TOPSRC}/sysdep/${OS} -I${TOPOBJ} -Wall
+LDFLAGS+=	-lcrypto -lssl -lgmp
+MAN=		certpatch.8
+
+CFLAGS+=	-DMP_FLAVOUR=MP_FLAVOUR_GMP
+LDADD+=		-lgmp
+DPADD+=		${LIBGMP}
+
+# Override LIBSYSDEPDIR definition from Makefile.sysdep
+LIBSYSDEPDIR=	${TOPSRC}/sysdep/common/libsysdep
+
+all:	${PROG}
+
+clean:	
+	rm -f ${PROG}
--- isakmpd-20041012.orig/pf_key_v2.c
+++ isakmpd-20041012/pf_key_v2.c
@@ -1055,6 +1055,10 @@
 #endif
 #if defined (USE_NAT_TRAVERSAL) && defined (SADB_X_EXT_UDPENCAP)
 	struct sadb_x_udpencap udpencap;
+#elif defined (USE_NAT_TRAVERSAL) && defined (SADB_X_EXT_NAT_T_TYPE)
+	struct sadb_x_nat_t_type nat_t_type;
+	struct sadb_x_nat_t_port nat_t_sport;
+	struct sadb_x_nat_t_port nat_t_dport;
 #endif
 #ifdef USE_DEBUG
 	char           *addr_str;
@@ -1273,10 +1277,15 @@
 		log_print("pf_key_v2_set_spi: invalid proto %d", proto->proto);
 		goto cleanup;
 	}
-	if (incoming)
+	if (incoming) {
 		sa->transport->vtbl->get_src(sa->transport, &dst);
-	else
+		sa->transport->vtbl->get_dst(sa->transport, &src);
+	}
+	else {
 		sa->transport->vtbl->get_dst(sa->transport, &dst);
+		sa->transport->vtbl->get_src(sa->transport, &src);
+	}
+
 #ifdef KAME
 	msg.sadb_msg_seq = (incoming ?
 	    pf_key_v2_seq_by_sa(proto->spi[incoming], sizeof ssa.sadb_sa_spi,
@@ -1319,12 +1328,13 @@
 	ssa.sadb_sa_flags = 0;
 #ifdef SADB_X_SAFLAGS_TUNNEL
 	if (iproto->encap_mode == IPSEC_ENCAP_TUNNEL ||
-	    iproto->encap_mode == IPSEC_ENCAP_UDP_ENCAP_TUNNEL)
+	    iproto->encap_mode == IPSEC_ENCAP_UDP_ENCAP_TUNNEL ||
+	    iproto->encap_mode == IPSEC_ENCAP_UDP_ENCAP_TUNNEL_DRAFT)
 		ssa.sadb_sa_flags = SADB_X_SAFLAGS_TUNNEL;
 #endif
 
-#if defined (USE_NAT_TRAVERSAL) && defined (SADB_X_EXT_UDPENCAP)
 	if (isakmp_sa->flags & SA_FLAG_NAT_T_ENABLE) {
+#if defined (USE_NAT_TRAVERSAL) && defined (SADB_X_EXT_UDPENCAP)
 		memset(&udpencap, 0, sizeof udpencap);
 		ssa.sadb_sa_flags |= SADB_X_SAFLAGS_UDPENCAP;
 		udpencap.sadb_x_udpencap_exttype = SADB_X_EXT_UDPENCAP;
@@ -1334,8 +1344,40 @@
 		if (pf_key_v2_msg_add(update, (struct sadb_ext *)&udpencap, 0)
 		    == -1)
 			goto cleanup;
-	}
+#elif defined (USE_NAT_TRAVERSAL) && defined (SADB_X_EXT_NAT_T_TYPE)
+#ifndef UDP_ENCAP_ESPINUDP
+#define UDP_ENCAP_ESPINUDP	2
+#endif
+		memset(&nat_t_type, 0, sizeof nat_t_type);
+		memset(&nat_t_sport, 0, sizeof nat_t_sport);
+		memset(&nat_t_dport, 0, sizeof nat_t_dport);
+
+		/* type = draft-udp-encap-06 */
+		nat_t_type.sadb_x_nat_t_type_len = sizeof nat_t_type / PF_KEY_V2_CHUNK;
+		nat_t_type.sadb_x_nat_t_type_exttype = SADB_X_EXT_NAT_T_TYPE;
+		nat_t_type.sadb_x_nat_t_type_type = UDP_ENCAP_ESPINUDP;
+		if(pf_key_v2_msg_add(update, (struct sadb_ext *)&nat_t_type, 0) == -1)
+			goto cleanup;
+
+		/* source port */
+		nat_t_sport.sadb_x_nat_t_port_len = sizeof nat_t_sport / 
+		                                           PF_KEY_V2_CHUNK;
+		nat_t_sport.sadb_x_nat_t_port_exttype = SADB_X_EXT_NAT_T_SPORT;
+		nat_t_sport.sadb_x_nat_t_port_port = sockaddr_port(src);
+		if(pf_key_v2_msg_add(update, (struct sadb_ext *)&nat_t_sport, 0) == -1)
+			goto cleanup;
+
+		/* destination port */
+		nat_t_dport.sadb_x_nat_t_port_len = sizeof nat_t_dport / 
+		                                           PF_KEY_V2_CHUNK;
+		nat_t_dport.sadb_x_nat_t_port_exttype = SADB_X_EXT_NAT_T_DPORT;
+		nat_t_dport.sadb_x_nat_t_port_port = sockaddr_port(dst);
+		if(pf_key_v2_msg_add(update, (struct sadb_ext *)&nat_t_dport, 0) == -1)
+			goto cleanup;
+
+		/* original address (transport mode checksum missing info) goes here */
 #endif
+    }
 
 	if (pf_key_v2_msg_add(update, (struct sadb_ext *)&ssa, 0) == -1)
 		goto cleanup;
@@ -1395,10 +1437,6 @@
 	/*
 	 * Setup the ADDRESS extensions.
          */
-	if (incoming)
-		sa->transport->vtbl->get_dst(sa->transport, &src);
-	else
-		sa->transport->vtbl->get_src(sa->transport, &src);
 	len = sizeof *addr + PF_KEY_V2_ROUND(sysdep_sa_len(src));
 	addr = calloc(1, len);
 	if (!addr)
@@ -2167,7 +2205,7 @@
 		pf_key_v2_msg_free(ret);
 	return -1;
 
-#elif defined (SADB_X_SPDADD) && defined (SADB_X_SPDDELETE)
+#elif defined (SADB_X_SPDUPDATE) && defined (SADB_X_SPDDELETE)
 	struct sadb_msg msg;
 	struct sadb_x_policy *policy = 0;
 	struct sadb_x_ipsecrequest *ipsecrequest;
@@ -2181,7 +2219,7 @@
 	struct sockaddr_in *ip4_sa;
 	struct sockaddr_in6 *ip6_sa;
 
-	msg.sadb_msg_type = delete ? SADB_X_SPDDELETE : SADB_X_SPDADD;
+	msg.sadb_msg_type = delete ? SADB_X_SPDDELETE : SADB_X_SPDUPDATE;
 	msg.sadb_msg_satype = SADB_SATYPE_UNSPEC;
 	msg.sadb_msg_seq = 0;
 	flow = pf_key_v2_msg_new(&msg, 0);
--- isakmpd-20041012.orig/isakmp_num.cst
+++ isakmpd-20041012/isakmp_num.cst
@@ -57,15 +57,18 @@
   KD				17	# RFC 3547, Key Download
   SEQ				18	# RFC 3547, Sequence Number
   POP				19	# RFC 3547, Proof of possession
-  RESERVED_MIN			20
+  NAT_D				20	# RFC 3947, NAT Discovery payload
+  NAT_OA			21	# RFC 3947, NAT Original Address payload
+  RESERVED_MIN			22
   RESERVED_MAX			127
   PRIVATE_MIN			128
 # XXX values from draft-ietf-ipsec-nat-t-ike-01,02,03. Later drafts specify
 # XXX NAT_D as payload 15 and NAT_OA as 16, but these are allocated by RFC
 # XXX 3547 as seen above.
-  NAT_D				130	# NAT Discovery payload
-  NAT_OA			131	# NAT Original Address payload
+  NAT_D_DRAFT			130	# NAT Discovery payload
+  NAT_OA_DRAFT			131	# NAT Original Address payload
   PRIVATE_MAX			255
+  MAX				255
 .
 
 # ISAKMP exchange types.
--- isakmpd-20041012.orig/ipsec_num.cst
+++ isakmpd-20041012/ipsec_num.cst
@@ -62,10 +62,10 @@
 IPSEC_ENCAP
   TUNNEL				1
   TRANSPORT				2
-  FUTURE_UDP_ENCAP_TUNNEL		3	# XXX Not yet assigned
-  FUTURE_UDP_ENCAP_TRANSPORT		4	# XXX Not yet assigned
-  UDP_ENCAP_TUNNEL			61443	# draft-ietf-ipsec-nat-t-ike
-  UDP_ENCAP_TRANSPORT			61443	# draft-ietf-ipsec-nat-t-ike
+  UDP_ENCAP_TUNNEL			3
+  UDP_ENCAP_TRANSPORT			4
+  UDP_ENCAP_TUNNEL_DRAFT		61443	# draft-ietf-ipsec-nat-t-ike
+  UDP_ENCAP_TRANSPORT_DRAFT		61443	# draft-ietf-ipsec-nat-t-ike
 .
 
 # IPSEC authentication algorithm.
--- isakmpd-20041012.orig/nat_traversal.h
+++ isakmpd-20041012/nat_traversal.h
@@ -1,4 +1,4 @@
-/*	$OpenBSD: nat_traversal.h,v 1.2 2004/06/21 23:27:10 ho Exp $	*/
+/*	$OpenBSD: nat_traversal.h,v 1.4 2005/07/25 15:03:47 hshoexer Exp $	*/
 
 /*
  * Copyright (c) 2004 H�kan Olsson.  All rights reserved.
@@ -27,6 +27,24 @@
 #ifndef _NAT_TRAVERSAL_H_
 #define _NAT_TRAVERSAL_H_
 
+#define VID_DRAFT_V2	0
+#define VID_DRAFT_V2_N	1
+#define VID_DRAFT_V3	2
+#define VID_RFC3947	3
+
+struct nat_t_cap {
+	int		 id;
+	u_int32_t	 flags;
+	const char	*text;
+	char		*hash;
+	size_t		 hashsize;
+};
+
+/*
+ * Set if -T is given on the command line to disable NAT-T support.
+ */
+extern int	disable_nat_t;
+
 void	nat_t_init(void);
 int	nat_t_add_vendor_payloads(struct message *);
 void	nat_t_check_vendor_payload(struct message *, struct payload *);
--- isakmpd-20041012.orig/message.c
+++ isakmpd-20041012/message.c
@@ -112,6 +112,7 @@
 	message_validate_hash, message_validate_sig, message_validate_nonce,
 	message_validate_notify, message_validate_delete,
 	message_validate_vendor, message_validate_attribute,
+	message_validate_nat_d, message_validate_nat_oa,
 	message_validate_nat_d, message_validate_nat_oa
 };
 
@@ -120,7 +121,7 @@
 	isakmp_id_fld, isakmp_cert_fld, isakmp_certreq_fld, isakmp_hash_fld,
 	isakmp_sig_fld, isakmp_nonce_fld, isakmp_notify_fld, isakmp_delete_fld,
 	isakmp_vendor_fld, isakmp_attribute_fld, isakmp_nat_d_fld,
-	isakmp_nat_oa_fld
+	isakmp_nat_oa_fld, isakmp_nat_d_fld, isakmp_nat_oa_fld
 };
 
 /*
@@ -138,7 +139,8 @@
 	ISAKMP_PAYLOAD_SAK, ISAKMP_PAYLOAD_SAT, ISAKMP_PAYLOAD_KD,
 	ISAKMP_PAYLOAD_SEQ, ISAKMP_PAYLOAD_POP
 #endif
-	ISAKMP_PAYLOAD_NAT_D, ISAKMP_PAYLOAD_NAT_OA
+	ISAKMP_PAYLOAD_NAT_D, ISAKMP_PAYLOAD_NAT_OA, 
+	ISAKMP_PAYLOAD_NAT_D_DRAFT, ISAKMP_PAYLOAD_NAT_OA_DRAFT
 };
 
 static u_int8_t payload_map[256];
@@ -347,8 +349,8 @@
 		}
 		/* Ignore most private payloads.  */
 		if (next >= ISAKMP_PAYLOAD_PRIVATE_MIN &&
-		    next != ISAKMP_PAYLOAD_NAT_D &&
-		    next != ISAKMP_PAYLOAD_NAT_OA) {
+		    next != ISAKMP_PAYLOAD_NAT_D_DRAFT &&
+		    next != ISAKMP_PAYLOAD_NAT_OA_DRAFT) {
 			LOG_DBG((LOG_MESSAGE, 30, "message_parse_payloads: "
 			    "private next payload type %s in payload of "
 			    "type %d ignored",
@@ -460,8 +462,10 @@
 		return ISAKMP_ATTRIBUTE_SZ;
 #if defined (USE_NAT_TRAVERSAL)
 	case ISAKMP_PAYLOAD_NAT_D:
+	case ISAKMP_PAYLOAD_NAT_D_DRAFT:
 		return ISAKMP_NAT_D_SZ;
 	case ISAKMP_PAYLOAD_NAT_OA:
+	case ISAKMP_PAYLOAD_NAT_OA_DRAFT:
 		return ISAKMP_NAT_OA_SZ;
 #endif
 	/* Not yet supported and any other unknown payloads. */
--- isakmpd-20041012.orig/policy.c
+++ isakmpd-20041012/policy.c
@@ -511,7 +511,10 @@
 							break;
 						}
 #if defined (USE_NAT_TRAVERSAL)
-					else if (decode_16(value) == IPSEC_ENCAP_UDP_ENCAP_TUNNEL)
+					else if (decode_16(value) ==
+					    IPSEC_ENCAP_UDP_ENCAP_TUNNEL ||
+					    decode_16(value) ==
+					    IPSEC_ENCAP_UDP_ENCAP_TUNNEL_DRAFT)
 						switch (proto->proto) {
 						case IPSEC_PROTO_IPSEC_AH:
 							ah_encapsulation = "udp-encap-tunnel";
@@ -1932,7 +1935,7 @@
 void
 policy_init(void)
 {
-	char           *ptr, *policy_file;
+	char           *ptr, *policy_file, *use_keynote;
 	char          **asserts;
 	size_t          sz, len;
 	int             fd, i;
@@ -1940,10 +1943,11 @@
 	LOG_DBG((LOG_POLICY, 30, "policy_init: initializing"));
 
 	/* Do we want to use the policy modules?  */
-	if (ignore_policy ||
-	    strncmp("yes", conf_get_str("General", "Use-Keynote"), 3))
-		return;
-
+	use_keynote = conf_get_str("General", "Use-Keynote");
+	if (ignore_policy || 
+		(use_keynote && strncmp("yes", use_keynote, 3)))
+	         return;
+ 
 	/* Get policy file from configuration.  */
 	policy_file = conf_get_str("General", "Policy-file");
 	if (!policy_file)
--- isakmpd-20041012.orig/ike_phase_1.c
+++ isakmpd-20041012/ike_phase_1.c
@@ -1040,9 +1040,9 @@
 
 		/* Compare expected/desired and received remote ID */
 		if (bcmp(rid, payload->p + ISAKMP_ID_DATA_OFF, sz)) {
-			free(rid);
 			log_print("ike_phase_1_recv_ID: "
-			    "received remote ID other than expected %s", p);
+			    "received remote ID other than expected %s - %s", p, payload->p);
+			free(rid);
 			return -1;
 		}
 		free(rid);
--- isakmpd-20041012.orig/x509.c
+++ isakmpd-20041012/x509.c
@@ -910,7 +910,11 @@
 	X509_STORE_CTX_init(&csc, x509_cas, cert, NULL);
 #if OPENSSL_VERSION_NUMBER >= 0x00907000L
 	/* XXX See comment in x509_read_crls_from_dir.  */
+#if OPENSSL_VERSION_NUMBER >= 0x00908000L
+	if (x509_cas->param->flags & X509_V_FLAG_CRL_CHECK) {
+#else
 	if (x509_cas->flags & X509_V_FLAG_CRL_CHECK) {
+#endif
 		X509_STORE_CTX_set_flags(&csc, X509_V_FLAG_CRL_CHECK);
 		X509_STORE_CTX_set_flags(&csc, X509_V_FLAG_CRL_CHECK_ALL);
 	}
--- isakmpd-20041012.orig/sysdep/linux/sysdep.c
+++ isakmpd-20041012/sysdep/linux/sysdep.c
@@ -169,22 +169,22 @@
     return 0;
 
   if (!(af == AF_INET || af == AF_INET6))
-    {
+    { 
       log_print ("sysdep_cleartext: unsupported protocol family %d", af);
       return -1;
     }
 
   if (setsockopt (fd, af == AF_INET ? IPPROTO_IP : IPPROTO_IPV6,
-		  af == AF_INET ? IP_IPSEC_POLICY : IPV6_IPSEC_POLICY,
-		  &pol_in, sizeof pol_in) < 0 ||
+          af == AF_INET ? IP_IPSEC_POLICY : IPV6_IPSEC_POLICY,
+          &pol_in, sizeof pol_in) < 0 ||
       setsockopt (fd, af == AF_INET ? IPPROTO_IP : IPPROTO_IPV6,
-		  af == AF_INET ? IP_IPSEC_POLICY : IPV6_IPSEC_POLICY,
-		  &pol_out, sizeof pol_out) < 0)
-    {
+          af == AF_INET ? IP_IPSEC_POLICY : IPV6_IPSEC_POLICY,
+          &pol_out, sizeof pol_out) < 0)
+    { 
       log_error ("sysdep_cleartext: "
-		 "setsockopt (%d, IPPROTO_IP%s, IP%s_IPSEC_POLICY, ...) "
-		 "failed", fd, af == AF_INET ? "" : "V6",
-		 af == AF_INET ? "" : "V6");
+         "setsockopt (%d, IPPROTO_IP%s, IP%s_IPSEC_POLICY, ...) "
+         "failed", fd, af == AF_INET ? "" : "V6",
+         af == AF_INET ? "" : "V6");
       return -1;
     }
   return 0;
--- isakmpd-20041012.orig/sysdep/linux/GNUmakefile.sysdep
+++ isakmpd-20041012/sysdep/linux/GNUmakefile.sysdep
@@ -33,13 +33,13 @@
 LDADD+=		-lgmp ${LIBSYSDEP} ${LIBCRYPTO}
 DPADD+=		${LIBGMP} ${LIBSYSDEP}
 
-CFLAGS+=	-DUSE_OLD_SOCKADDR -DHAVE_PCAP \
-		-DNEED_SYSDEP_APP -DMP_FLAVOUR=MP_FLAVOUR_GMP \
-		-I/usr/src/linux/include -I${.CURDIR}/sysdep/common \
+CFLAGS+=	-DHAVE_GETNAMEINFO -DUSE_OLD_SOCKADDR -DHAVE_PCAP \
+		-DNEED_SYSDEP_APP -DMP_FLAVOUR=MP_FLAVOUR_GMP -DUSE_AES \
+		-I${.CURDIR}/sysdep/linux/include -I${.CURDIR}/sysdep/common \
 		-I/usr/include/openssl
 
 FEATURES=	debug tripledes blowfish cast ec aggressive x509 policy
-FEATURES+=	des aes
+FEATURES+=	dpd nat_traversal isakmp_cfg des aes
 
 IPSEC_SRCS=	pf_key_v2.c
 IPSEC_CFLAGS=	-DUSE_PF_KEY_V2
@@ -51,7 +51,7 @@
 # hack libsysdep.a dependenc
 ${LIBSYSDEPDIR}/.depend ${LIBSYSDEP}:
 	cd ${LIBSYSDEPDIR} && \
-		${MAKE} --no-print-directory ${MAKEFLAGS} \
+		${MAKE} --no-print-directory \
 			CFLAGS="${CFLAGS}" MKDEP="${MKDEP}" ${MAKECMDGOALS}
 
 ifeq ($(findstring clean,$(MAKECMDGOALS)),clean)
--- isakmpd-20041012.orig/sysdep/linux/include/bitstring.h
+++ isakmpd-20041012/sysdep/linux/include/bitstring.h
@@ -0,0 +1,132 @@
+/*	$OpenBSD: bitstring.h,v 1.4 2002/06/19 02:50:10 millert Exp $	*/
+/*	$NetBSD: bitstring.h,v 1.5 1997/05/14 15:49:55 pk Exp $	*/
+
+/*
+ * Copyright (c) 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Paul Vixie.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)bitstring.h	8.1 (Berkeley) 7/19/93
+ */
+
+#ifndef _BITSTRING_H_
+#define	_BITSTRING_H_
+
+/* modified for SV/AT and bitstring bugfix by M.R.Murphy, 11oct91
+ * bitstr_size changed gratuitously, but shorter
+ * bit_alloc   spelling error fixed
+ * the following were efficient, but didn't work, they've been made to
+ * work, but are no longer as efficient :-)
+ * bit_nclear, bit_nset, bit_ffc, bit_ffs
+ */
+typedef	unsigned char bitstr_t;
+
+/* internal macros */
+				/* byte of the bitstring bit is in */
+#define	_bit_byte(bit) \
+	((bit) >> 3)
+
+				/* mask for the bit within its byte */
+#define	_bit_mask(bit) \
+	(1 << ((bit)&0x7))
+
+/* external macros */
+				/* bytes in a bitstring of nbits bits */
+#define	bitstr_size(nbits) \
+	(((nbits) + 7) >> 3)
+
+				/* allocate a bitstring */
+#define	bit_alloc(nbits) \
+	(bitstr_t *)calloc((size_t)bitstr_size(nbits), sizeof(bitstr_t))
+
+				/* allocate a bitstring on the stack */
+#define	bit_decl(name, nbits) \
+	((name)[bitstr_size(nbits)])
+
+				/* is bit N of bitstring name set? */
+#define	bit_test(name, bit) \
+	((name)[_bit_byte(bit)] & _bit_mask(bit))
+
+				/* set bit N of bitstring name */
+#define	bit_set(name, bit) \
+	((name)[_bit_byte(bit)] |= _bit_mask(bit))
+
+				/* clear bit N of bitstring name */
+#define	bit_clear(name, bit) \
+	((name)[_bit_byte(bit)] &= ~_bit_mask(bit))
+
+				/* clear bits start ... stop in bitstring */
+#define	bit_nclear(name, start, stop) do { \
+	register bitstr_t *_name = name; \
+	register int _start = start, _stop = stop; \
+	while (_start <= _stop) { \
+		bit_clear(_name, _start); \
+		_start++; \
+		} \
+} while(0)
+
+				/* set bits start ... stop in bitstring */
+#define	bit_nset(name, start, stop) do { \
+	register bitstr_t *_name = name; \
+	register int _start = start, _stop = stop; \
+	while (_start <= _stop) { \
+		bit_set(_name, _start); \
+		_start++; \
+		} \
+} while(0)
+
+				/* find first bit clear in name */
+#define	bit_ffc(name, nbits, value) do { \
+	register bitstr_t *_name = name; \
+	register int _bit, _nbits = nbits, _value = -1; \
+	for (_bit = 0; _bit < _nbits; ++_bit) \
+		if (!bit_test(_name, _bit)) { \
+			_value = _bit; \
+			break; \
+		} \
+	*(value) = _value; \
+} while(0)
+
+				/* find first bit set in name */
+#define	bit_ffs(name, nbits, value) do { \
+	register bitstr_t *_name = name; \
+	register int _bit, _nbits = nbits, _value = -1; \
+	for (_bit = 0; _bit < _nbits; ++_bit) \
+		if (bit_test(_name, _bit)) { \
+			_value = _bit; \
+			break; \
+		} \
+	*(value) = _value; \
+} while(0)
+
+#endif /* !_BITSTRING_H_ */
--- isakmpd-20041012.orig/sysdep/linux/include/sys/queue.h
+++ isakmpd-20041012/sysdep/linux/include/sys/queue.h
@@ -0,0 +1,453 @@
+/*
+ * Copyright (c) 1991, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)queue.h	8.5 (Berkeley) 8/20/94
+ * $FreeBSD: src/sys/sys/queue.h,v 1.45 2001/12/11 11:49:58 sheldonh Exp $
+ */
+
+#ifndef _SYS_QUEUE_H_
+#define	_SYS_QUEUE_H_
+
+//#include <machine/ansi.h>	/* for __offsetof */
+
+/*
+ * This file defines four types of data structures: singly-linked lists,
+ * singly-linked tail queues, lists and tail queues.
+ *
+ * A singly-linked list is headed by a single forward pointer. The elements
+ * are singly linked for minimum space and pointer manipulation overhead at
+ * the expense of O(n) removal for arbitrary elements. New elements can be
+ * added to the list after an existing element or at the head of the list.
+ * Elements being removed from the head of the list should use the explicit
+ * macro for this purpose for optimum efficiency. A singly-linked list may
+ * only be traversed in the forward direction.  Singly-linked lists are ideal
+ * for applications with large datasets and few or no removals or for
+ * implementing a LIFO queue.
+ *
+ * A singly-linked tail queue is headed by a pair of pointers, one to the
+ * head of the list and the other to the tail of the list. The elements are
+ * singly linked for minimum space and pointer manipulation overhead at the
+ * expense of O(n) removal for arbitrary elements. New elements can be added
+ * to the list after an existing element, at the head of the list, or at the
+ * end of the list. Elements being removed from the head of the tail queue
+ * should use the explicit macro for this purpose for optimum efficiency.
+ * A singly-linked tail queue may only be traversed in the forward direction.
+ * Singly-linked tail queues are ideal for applications with large datasets
+ * and few or no removals or for implementing a FIFO queue.
+ *
+ * A list is headed by a single forward pointer (or an array of forward
+ * pointers for a hash table header). The elements are doubly linked
+ * so that an arbitrary element can be removed without a need to
+ * traverse the list. New elements can be added to the list before
+ * or after an existing element or at the head of the list. A list
+ * may only be traversed in the forward direction.
+ *
+ * A tail queue is headed by a pair of pointers, one to the head of the
+ * list and the other to the tail of the list. The elements are doubly
+ * linked so that an arbitrary element can be removed without a need to
+ * traverse the list. New elements can be added to the list before or
+ * after an existing element, at the head of the list, or at the end of
+ * the list. A tail queue may be traversed in either direction.
+ *
+ * For details on the use of these macros, see the queue(3) manual page.
+ *
+ *
+ *			SLIST	LIST	STAILQ	TAILQ
+ * _HEAD		+	+	+	+
+ * _HEAD_INITIALIZER	+	+	+	+
+ * _ENTRY		+	+	+	+
+ * _INIT		+	+	+	+
+ * _EMPTY		+	+	+	+
+ * _FIRST		+	+	+	+
+ * _NEXT		+	+	+	+
+ * _PREV		-	-	-	+
+ * _LAST		-	-	+	+
+ * _FOREACH		+	+	+	+
+ * _FOREACH_REVERSE	-	-	-	+
+ * _INSERT_HEAD		+	+	+	+
+ * _INSERT_BEFORE	-	+	-	+
+ * _INSERT_AFTER	+	+	+	+
+ * _INSERT_TAIL		-	-	+	+
+ * _REMOVE_HEAD		+	-	+	-
+ * _REMOVE		+	+	+	+
+ *
+ */
+
+/*
+ * Singly-linked List declarations.
+ */
+#define	SLIST_HEAD(name, type)						\
+struct name {								\
+	struct type *slh_first;	/* first element */			\
+}
+
+#define	SLIST_HEAD_INITIALIZER(head)					\
+	{ NULL }
+ 
+#define	SLIST_ENTRY(type)						\
+struct {								\
+	struct type *sle_next;	/* next element */			\
+}
+ 
+/*
+ * Singly-linked List functions.
+ */
+#define	SLIST_EMPTY(head)	((head)->slh_first == NULL)
+
+#define	SLIST_FIRST(head)	((head)->slh_first)
+
+#define	SLIST_FOREACH(var, head, field)					\
+	for ((var) = SLIST_FIRST((head));				\
+	    (var);							\
+	    (var) = SLIST_NEXT((var), field))
+
+#define	SLIST_INIT(head) do {						\
+	SLIST_FIRST((head)) = NULL;					\
+} while (0)
+
+#define	SLIST_INSERT_AFTER(slistelm, elm, field) do {			\
+	SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field);	\
+	SLIST_NEXT((slistelm), field) = (elm);				\
+} while (0)
+
+#define	SLIST_INSERT_HEAD(head, elm, field) do {			\
+	SLIST_NEXT((elm), field) = SLIST_FIRST((head));			\
+	SLIST_FIRST((head)) = (elm);					\
+} while (0)
+
+#define	SLIST_NEXT(elm, field)	((elm)->field.sle_next)
+
+#define	SLIST_REMOVE(head, elm, type, field) do {			\
+	if (SLIST_FIRST((head)) == (elm)) {				\
+		SLIST_REMOVE_HEAD((head), field);			\
+	}								\
+	else {								\
+		struct type *curelm = SLIST_FIRST((head));		\
+		while (SLIST_NEXT(curelm, field) != (elm))		\
+			curelm = SLIST_NEXT(curelm, field);		\
+		SLIST_NEXT(curelm, field) =				\
+		    SLIST_NEXT(SLIST_NEXT(curelm, field), field);	\
+	}								\
+} while (0)
+
+#define	SLIST_REMOVE_HEAD(head, field) do {				\
+	SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field);	\
+} while (0)
+
+/*
+ * Singly-linked Tail queue declarations.
+ */
+#define	STAILQ_HEAD(name, type)						\
+struct name {								\
+	struct type *stqh_first;/* first element */			\
+	struct type **stqh_last;/* addr of last next element */		\
+}
+
+#define	STAILQ_HEAD_INITIALIZER(head)					\
+	{ NULL, &(head).stqh_first }
+
+#define	STAILQ_ENTRY(type)						\
+struct {								\
+	struct type *stqe_next;	/* next element */			\
+}
+
+/*
+ * Singly-linked Tail queue functions.
+ */
+#define	STAILQ_EMPTY(head)	((head)->stqh_first == NULL)
+
+#define	STAILQ_FIRST(head)	((head)->stqh_first)
+
+#define	STAILQ_FOREACH(var, head, field)				\
+	for((var) = STAILQ_FIRST((head));				\
+	   (var);							\
+	   (var) = STAILQ_NEXT((var), field))
+
+#define	STAILQ_INIT(head) do {						\
+	STAILQ_FIRST((head)) = NULL;					\
+	(head)->stqh_last = &STAILQ_FIRST((head));			\
+} while (0)
+
+#define	STAILQ_INSERT_AFTER(head, tqelm, elm, field) do {		\
+	if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)\
+		(head)->stqh_last = &STAILQ_NEXT((elm), field);		\
+	STAILQ_NEXT((tqelm), field) = (elm);				\
+} while (0)
+
+#define	STAILQ_INSERT_HEAD(head, elm, field) do {			\
+	if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL)	\
+		(head)->stqh_last = &STAILQ_NEXT((elm), field);		\
+	STAILQ_FIRST((head)) = (elm);					\
+} while (0)
+
+#define	STAILQ_INSERT_TAIL(head, elm, field) do {			\
+	STAILQ_NEXT((elm), field) = NULL;				\
+	*(head)->stqh_last = (elm);					\
+	(head)->stqh_last = &STAILQ_NEXT((elm), field);			\
+} while (0)
+
+#define	STAILQ_LAST(head, type, field)					\
+	(STAILQ_EMPTY(head) ?						\
+		NULL :							\
+	        ((struct type *)					\
+		((char *)((head)->stqh_last) - __offsetof(struct type, field))))
+
+#define	STAILQ_NEXT(elm, field)	((elm)->field.stqe_next)
+
+#define	STAILQ_REMOVE(head, elm, type, field) do {			\
+	if (STAILQ_FIRST((head)) == (elm)) {				\
+		STAILQ_REMOVE_HEAD(head, field);			\
+	}								\
+	else {								\
+		struct type *curelm = STAILQ_FIRST((head));		\
+		while (STAILQ_NEXT(curelm, field) != (elm))		\
+			curelm = STAILQ_NEXT(curelm, field);		\
+		if ((STAILQ_NEXT(curelm, field) =			\
+		     STAILQ_NEXT(STAILQ_NEXT(curelm, field), field)) == NULL)\
+			(head)->stqh_last = &STAILQ_NEXT((curelm), field);\
+	}								\
+} while (0)
+
+#define	STAILQ_REMOVE_HEAD(head, field) do {				\
+	if ((STAILQ_FIRST((head)) =					\
+	     STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL)		\
+		(head)->stqh_last = &STAILQ_FIRST((head));		\
+} while (0)
+
+#define	STAILQ_REMOVE_HEAD_UNTIL(head, elm, field) do {			\
+	if ((STAILQ_FIRST((head)) = STAILQ_NEXT((elm), field)) == NULL)	\
+		(head)->stqh_last = &STAILQ_FIRST((head));		\
+} while (0)
+
+/*
+ * List declarations.
+ */
+#define	LIST_HEAD(name, type)						\
+struct name {								\
+	struct type *lh_first;	/* first element */			\
+}
+
+#define	LIST_HEAD_INITIALIZER(head)					\
+	{ NULL }
+
+#define	LIST_ENTRY(type)						\
+struct {								\
+	struct type *le_next;	/* next element */			\
+	struct type **le_prev;	/* address of previous next element */	\
+}
+
+/*
+ * List functions.
+ */
+
+#define	LIST_EMPTY(head)	((head)->lh_first == NULL)
+
+#define	LIST_FIRST(head)	((head)->lh_first)
+
+#define	LIST_FOREACH(var, head, field)					\
+	for ((var) = LIST_FIRST((head));				\
+	    (var);							\
+	    (var) = LIST_NEXT((var), field))
+
+#define	LIST_INIT(head) do {						\
+	LIST_FIRST((head)) = NULL;					\
+} while (0)
+
+#define	LIST_INSERT_AFTER(listelm, elm, field) do {			\
+	if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL)\
+		LIST_NEXT((listelm), field)->field.le_prev =		\
+		    &LIST_NEXT((elm), field);				\
+	LIST_NEXT((listelm), field) = (elm);				\
+	(elm)->field.le_prev = &LIST_NEXT((listelm), field);		\
+} while (0)
+
+#define	LIST_INSERT_BEFORE(listelm, elm, field) do {			\
+	(elm)->field.le_prev = (listelm)->field.le_prev;		\
+	LIST_NEXT((elm), field) = (listelm);				\
+	*(listelm)->field.le_prev = (elm);				\
+	(listelm)->field.le_prev = &LIST_NEXT((elm), field);		\
+} while (0)
+
+#define	LIST_INSERT_HEAD(head, elm, field) do {				\
+	if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL)	\
+		LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\
+	LIST_FIRST((head)) = (elm);					\
+	(elm)->field.le_prev = &LIST_FIRST((head));			\
+} while (0)
+
+#define	LIST_NEXT(elm, field)	((elm)->field.le_next)
+
+#define	LIST_REMOVE(elm, field) do {					\
+	if (LIST_NEXT((elm), field) != NULL)				\
+		LIST_NEXT((elm), field)->field.le_prev = 		\
+		    (elm)->field.le_prev;				\
+	*(elm)->field.le_prev = LIST_NEXT((elm), field);		\
+} while (0)
+
+/*
+ * Tail queue declarations.
+ */
+#define	TAILQ_HEAD(name, type)						\
+struct name {								\
+	struct type *tqh_first;	/* first element */			\
+	struct type **tqh_last;	/* addr of last next element */		\
+}
+
+#define	TAILQ_HEAD_INITIALIZER(head)					\
+	{ NULL, &(head).tqh_first }
+
+#define	TAILQ_ENTRY(type)						\
+struct {								\
+	struct type *tqe_next;	/* next element */			\
+	struct type **tqe_prev;	/* address of previous next element */	\
+}
+
+/*
+ * Tail queue functions.
+ */
+#define	TAILQ_EMPTY(head)	((head)->tqh_first == NULL)
+
+#define	TAILQ_FIRST(head)	((head)->tqh_first)
+
+#define	TAILQ_FOREACH(var, head, field)					\
+	for ((var) = TAILQ_FIRST((head));				\
+	    (var);							\
+	    (var) = TAILQ_NEXT((var), field))
+
+#define	TAILQ_FOREACH_REVERSE(var, head, headname, field)		\
+	for ((var) = TAILQ_LAST((head), headname);			\
+	    (var);							\
+	    (var) = TAILQ_PREV((var), headname, field))
+
+#define	TAILQ_INIT(head) do {						\
+	TAILQ_FIRST((head)) = NULL;					\
+	(head)->tqh_last = &TAILQ_FIRST((head));			\
+} while (0)
+
+#define	TAILQ_INSERT_AFTER(head, listelm, elm, field) do {		\
+	if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL)\
+		TAILQ_NEXT((elm), field)->field.tqe_prev = 		\
+		    &TAILQ_NEXT((elm), field);				\
+	else								\
+		(head)->tqh_last = &TAILQ_NEXT((elm), field);		\
+	TAILQ_NEXT((listelm), field) = (elm);				\
+	(elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field);		\
+} while (0)
+
+#define	TAILQ_INSERT_BEFORE(listelm, elm, field) do {			\
+	(elm)->field.tqe_prev = (listelm)->field.tqe_prev;		\
+	TAILQ_NEXT((elm), field) = (listelm);				\
+	*(listelm)->field.tqe_prev = (elm);				\
+	(listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field);		\
+} while (0)
+
+#define	TAILQ_INSERT_HEAD(head, elm, field) do {			\
+	if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL)	\
+		TAILQ_FIRST((head))->field.tqe_prev =			\
+		    &TAILQ_NEXT((elm), field);				\
+	else								\
+		(head)->tqh_last = &TAILQ_NEXT((elm), field);		\
+	TAILQ_FIRST((head)) = (elm);					\
+	(elm)->field.tqe_prev = &TAILQ_FIRST((head));			\
+} while (0)
+
+#define	TAILQ_INSERT_TAIL(head, elm, field) do {			\
+	TAILQ_NEXT((elm), field) = NULL;				\
+	(elm)->field.tqe_prev = (head)->tqh_last;			\
+	*(head)->tqh_last = (elm);					\
+	(head)->tqh_last = &TAILQ_NEXT((elm), field);			\
+} while (0)
+
+#define	TAILQ_LAST(head, headname)					\
+	(*(((struct headname *)((head)->tqh_last))->tqh_last))
+
+#define	TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
+
+#define	TAILQ_PREV(elm, headname, field)				\
+	(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
+
+#define	TAILQ_REMOVE(head, elm, field) do {				\
+	if ((TAILQ_NEXT((elm), field)) != NULL)				\
+		TAILQ_NEXT((elm), field)->field.tqe_prev = 		\
+		    (elm)->field.tqe_prev;				\
+	else								\
+		(head)->tqh_last = (elm)->field.tqe_prev;		\
+	*(elm)->field.tqe_prev = TAILQ_NEXT((elm), field);		\
+} while (0)
+
+
+#ifdef _KERNEL
+
+/*
+ * XXX insque() and remque() are an old way of handling certain queues.
+ * They bogusly assumes that all queue heads look alike.
+ */
+
+struct quehead {
+	struct quehead *qh_link;
+	struct quehead *qh_rlink;
+};
+
+#ifdef	__GNUC__
+
+static __inline void
+insque(void *a, void *b)
+{
+	struct quehead *element = (struct quehead *)a,
+		 *head = (struct quehead *)b;
+
+	element->qh_link = head->qh_link;
+	element->qh_rlink = head;
+	head->qh_link = element;
+	element->qh_link->qh_rlink = element;
+}
+
+static __inline void
+remque(void *a)
+{
+	struct quehead *element = (struct quehead *)a;
+
+	element->qh_link->qh_rlink = element->qh_rlink;
+	element->qh_rlink->qh_link = element->qh_link;
+	element->qh_rlink = 0;
+}
+
+#else /* !__GNUC__ */
+
+void	insque __P((void *a, void *b));
+void	remque __P((void *a));
+
+#endif /* __GNUC__ */
+
+#endif /* _KERNEL */
+
+#endif /* !_SYS_QUEUE_H_ */
--- isakmpd-20041012.orig/sysdep/common/pcap.h
+++ isakmpd-20041012/sysdep/common/pcap.h
@@ -55,8 +55,13 @@
 	u_int32_t linktype;	/* data link type (DLT_*) */
 };
 
+struct pcap_timeval {
+	int32_t tv_sec;		/* seconds */
+	int32_t tv_usec;	/* microseconds */
+};
+
 struct pcap_pkthdr {
-	struct timeval ts;	/* time stamp */
+	struct pcap_timeval ts;	/* time stamp */
 	u_int32_t caplen;	/* length of portion present */
 	u_int32_t len;		/* length this packet (off wire) */
 };
--- isakmpd-20041012.orig/sysdep/common/libsysdep/arc4random.c
+++ isakmpd-20041012/sysdep/common/libsysdep/arc4random.c
@@ -78,7 +78,7 @@
 static void
 arc4_stir(struct arc4_stream *as)
 {
-	int     fd;
+	int     fd, i;
 	struct {
 		struct timeval tv;
 		u_int8_t rnd[128 - sizeof(struct timeval)];
--- isakmpd-20041012.orig/x509v3.cnf
+++ isakmpd-20041012/x509v3.cnf
@@ -0,0 +1,26 @@
+# default settings
+CERTPATHLEN             = 1
+CERTUSAGE               = digitalSignature,keyCertSign
+CERTIP                  = 0.0.0.0
+CERTFQDN                = nohost.nodomain
+
+# This section should be referenced when building an x509v3 CA
+# Certificate.
+# The default path length and the key usage can be overriden
+# modified by setting the CERTPATHLEN and CERTUSAGE environment 
+# variables.
+[x509v3_CA]
+basicConstraints=critical,CA:true,pathlen:$ENV::CERTPATHLEN
+keyUsage=$ENV::CERTUSAGE
+
+# This section should be referenced to add an IP Address
+# as an alternate subject name, needed by isakmpd
+# The address must be provided in the CERTIP environment variable
+[x509v3_IPAddr]
+subjectAltName=IP:$ENV::CERTIP
+
+# This section should be referenced to add a FQDN hostname
+# as an alternate subject name, needed by isakmpd
+# The address must be provided in the CERTFQDN environment variable
+[x509v3_FQDN]
+subjectAltName=DNS:$ENV::CERTFQDN