Module Name:    src
Committed By:   tteras
Date:           Fri Jul  3 06:40:10 UTC 2009

Modified Files:
        src/crypto/dist/ipsec-tools/src/libipsec: libpfkey.h pfkey.c
        src/crypto/dist/ipsec-tools/src/racoon: isakmp.c isakmp_inf.c pfkey.c
            pfkey.h

Log Message:
>From Yvan Vanhullebus: Use SADB_X_EXT_NAT_T_* consistently for passing the
NAT-T port information. This might break compatibility with some kernels,
but as discussed this is the proper way to pass NAT-T ports and the broken
kernels need to be fixed.


To generate a diff of this commit:
cvs rdiff -u -r1.15 -r1.16 \
    src/crypto/dist/ipsec-tools/src/libipsec/libpfkey.h
cvs rdiff -u -r1.18 -r1.19 src/crypto/dist/ipsec-tools/src/libipsec/pfkey.c
cvs rdiff -u -r1.56 -r1.57 src/crypto/dist/ipsec-tools/src/racoon/isakmp.c
cvs rdiff -u -r1.39 -r1.40 \
    src/crypto/dist/ipsec-tools/src/racoon/isakmp_inf.c
cvs rdiff -u -r1.46 -r1.47 src/crypto/dist/ipsec-tools/src/racoon/pfkey.c
cvs rdiff -u -r1.7 -r1.8 src/crypto/dist/ipsec-tools/src/racoon/pfkey.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/crypto/dist/ipsec-tools/src/libipsec/libpfkey.h
diff -u src/crypto/dist/ipsec-tools/src/libipsec/libpfkey.h:1.15 src/crypto/dist/ipsec-tools/src/libipsec/libpfkey.h:1.16
--- src/crypto/dist/ipsec-tools/src/libipsec/libpfkey.h:1.15	Fri Dec  5 06:02:20 2008
+++ src/crypto/dist/ipsec-tools/src/libipsec/libpfkey.h	Fri Jul  3 06:40:10 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: libpfkey.h,v 1.15 2008/12/05 06:02:20 tteras Exp $	*/
+/*	$NetBSD: libpfkey.h,v 1.16 2009/07/03 06:40:10 tteras Exp $	*/
 
 /* Id: libpfkey.h,v 1.13 2005/12/04 20:26:43 manubsd Exp */
 
@@ -117,6 +117,10 @@
 u_int pfkey_get_softrate __P((u_int));
 int pfkey_send_getspi __P((int, u_int, u_int, struct sockaddr *,
 	struct sockaddr *, u_int32_t, u_int32_t, u_int32_t, u_int32_t));
+int pfkey_send_getspi_nat __P((int, u_int, u_int,
+	struct sockaddr *, struct sockaddr *, u_int8_t, u_int16_t, u_int16_t,
+	u_int32_t, u_int32_t, u_int32_t, u_int32_t));
+
 int pfkey_send_update2 __P((struct pfkey_send_sa_args *));
 int pfkey_send_add2 __P((struct pfkey_send_sa_args *)); 
 int pfkey_send_delete __P((int, u_int, u_int,
@@ -155,6 +159,14 @@
         caddr_t, int, u_int32_t));
 #endif
 
+/* XXX should be somewhere else !!!
+ */
+#ifdef SADB_X_NAT_T_NEW_MAPPING
+#define PFKEY_ADDR_X_PORT(ext) (ntohs(((struct sadb_x_nat_t_port *)ext)->sadb_x_nat_t_port_port))
+#define PFKEY_ADDR_X_NATTYPE(ext) ( ext != NULL && ((struct sadb_x_nat_t_type *)ext)->sadb_x_nat_t_type_type )
+#endif
+
+
 int pfkey_open __P((void));
 void pfkey_close __P((int));
 int pfkey_set_buffer_size __P((int, int));

Index: src/crypto/dist/ipsec-tools/src/libipsec/pfkey.c
diff -u src/crypto/dist/ipsec-tools/src/libipsec/pfkey.c:1.18 src/crypto/dist/ipsec-tools/src/libipsec/pfkey.c:1.19
--- src/crypto/dist/ipsec-tools/src/libipsec/pfkey.c:1.18	Fri Dec  5 06:02:20 2008
+++ src/crypto/dist/ipsec-tools/src/libipsec/pfkey.c	Fri Jul  3 06:40:10 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: pfkey.c,v 1.18 2008/12/05 06:02:20 tteras Exp $	*/
+/*	$NetBSD: pfkey.c,v 1.19 2009/07/03 06:40:10 tteras Exp $	*/
 
 /*	$KAME: pfkey.c,v 1.47 2003/10/02 19:52:12 itojun Exp $	*/
 
@@ -380,10 +380,12 @@
  *	-1	: error occured, and set errno.
  */
 int
-pfkey_send_getspi(so, satype, mode, src, dst, min, max, reqid, seq)
+pfkey_send_getspi_nat(so, satype, mode, src, dst, natt_type, sport, dport, min, max, reqid, seq)
 	int so;
 	u_int satype, mode;
 	struct sockaddr *src, *dst;
+	u_int8_t natt_type;
+	u_int16_t sport, dport;
 	u_int32_t min, max, reqid, seq;
 {
 	struct sadb_msg *newmsg;
@@ -431,6 +433,14 @@
 		len += sizeof(struct sadb_spirange);
 	}
 
+#ifdef SADB_X_EXT_NAT_T_TYPE
+	if(natt_type||sport||dport){
+		len += sizeof(struct sadb_x_nat_t_type);
+		len += sizeof(struct sadb_x_nat_t_port);
+		len += sizeof(struct sadb_x_nat_t_port);
+	}
+#endif
+
 	if ((newmsg = CALLOC((size_t)len, struct sadb_msg *)) == NULL) {
 		__ipsec_set_strerror(strerror(errno));
 		return -1;
@@ -466,6 +476,32 @@
 		return -1;
 	}
 
+#ifdef SADB_X_EXT_NAT_T_TYPE
+	/* Add nat-t messages */
+	if (natt_type) {
+		p = pfkey_set_natt_type(p, ep, SADB_X_EXT_NAT_T_TYPE, 
+					natt_type);
+		if (!p) {
+			free(newmsg);
+			return -1;
+		}
+
+		p = pfkey_set_natt_port(p, ep, SADB_X_EXT_NAT_T_SPORT,
+					sport);
+		if (!p) {
+			free(newmsg);
+			return -1;
+		}
+
+		p = pfkey_set_natt_port(p, ep, SADB_X_EXT_NAT_T_DPORT,
+					dport);
+		if (!p) {
+			free(newmsg);
+			return -1;
+		}
+	}
+#endif
+
 	/* proccessing spi range */
 	if (need_spirange) {
 		struct sadb_spirange spirange;
@@ -501,6 +537,17 @@
 	return len;
 }
 
+int
+pfkey_send_getspi(so, satype, mode, src, dst, min, max, reqid, seq)
+	int so;
+	u_int satype, mode;
+	struct sockaddr *src, *dst;
+	u_int32_t min, max, reqid, seq;
+{
+	return pfkey_send_getspi_nat(so, satype, mode, src, dst, 0, 0, 0,
+		min, max, reqid, seq);
+}
+
 /*
  * sending SADB_UPDATE message to the kernel.
  * The length of key material is a_keylen + e_keylen.

Index: src/crypto/dist/ipsec-tools/src/racoon/isakmp.c
diff -u src/crypto/dist/ipsec-tools/src/racoon/isakmp.c:1.56 src/crypto/dist/ipsec-tools/src/racoon/isakmp.c:1.57
--- src/crypto/dist/ipsec-tools/src/racoon/isakmp.c:1.56	Tue May 19 09:34:52 2009
+++ src/crypto/dist/ipsec-tools/src/racoon/isakmp.c	Fri Jul  3 06:40:10 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: isakmp.c,v 1.56 2009/05/19 09:34:52 tteras Exp $	*/
+/*	$NetBSD: isakmp.c,v 1.57 2009/07/03 06:40:10 tteras Exp $	*/
 
 /* Id: isakmp.c,v 1.74 2006/05/07 21:32:59 manubsd Exp */
 
@@ -3317,6 +3317,17 @@
 		src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
 		dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
 
+#ifdef SADB_X_NAT_T_NEW_MAPPING
+		if (PFKEY_ADDR_X_NATTYPE(mhp[SADB_X_EXT_NAT_T_TYPE])) {
+			/* NAT-T is enabled for this SADB entry; copy
+			 * the ports from NAT-T extensions */
+			if(mhp[SADB_X_EXT_NAT_T_SPORT] != NULL)
+				set_port(src, PFKEY_ADDR_X_PORT(mhp[SADB_X_EXT_NAT_T_SPORT]));
+			if(mhp[SADB_X_EXT_NAT_T_DPORT] != NULL)
+				set_port(dst, PFKEY_ADDR_X_PORT(mhp[SADB_X_EXT_NAT_T_DPORT]));
+		}
+#endif
+
 		if (sa->sadb_sa_state != SADB_SASTATE_LARVAL &&
 		    sa->sadb_sa_state != SADB_SASTATE_MATURE &&
 		    sa->sadb_sa_state != SADB_SASTATE_DYING) {

Index: src/crypto/dist/ipsec-tools/src/racoon/isakmp_inf.c
diff -u src/crypto/dist/ipsec-tools/src/racoon/isakmp_inf.c:1.39 src/crypto/dist/ipsec-tools/src/racoon/isakmp_inf.c:1.40
--- src/crypto/dist/ipsec-tools/src/racoon/isakmp_inf.c:1.39	Mon May 18 17:07:15 2009
+++ src/crypto/dist/ipsec-tools/src/racoon/isakmp_inf.c	Fri Jul  3 06:40:10 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: isakmp_inf.c,v 1.39 2009/05/18 17:07:15 tteras Exp $	*/
+/*	$NetBSD: isakmp_inf.c,v 1.40 2009/07/03 06:40:10 tteras Exp $	*/
 
 /* Id: isakmp_inf.c,v 1.44 2006/05/06 20:45:52 manubsd Exp */
 
@@ -1124,8 +1124,7 @@
 	size_t i;
 	caddr_t mhp[SADB_EXT_MAX + 1];
 #ifdef ENABLE_NATT
-	struct sadb_x_nat_t_type *natt_type;
-	struct sadb_x_nat_t_port *natt_port;
+	int natt_port_forced;
 #endif
 
 	plog(LLV_DEBUG2, LOCATION, NULL,
@@ -1180,22 +1179,25 @@
 			continue;
 		}
 #ifdef ENABLE_NATT
-		natt_type = (void *)mhp[SADB_X_EXT_NAT_T_TYPE];
-		if (natt_type && natt_type->sadb_x_nat_t_type_type) {
+		if (PFKEY_ADDR_X_NATTYPE(mhp[SADB_X_EXT_NAT_T_TYPE])) {
 			/* NAT-T is enabled for this SADB entry; copy
 			 * the ports from NAT-T extensions */
-			natt_port = (void *)mhp[SADB_X_EXT_NAT_T_SPORT];
-			if (extract_port(src) == 0 && natt_port != NULL)
-				set_port(src, ntohs(natt_port->sadb_x_nat_t_port_port));
-
-			natt_port = (void *)mhp[SADB_X_EXT_NAT_T_DPORT];
-			if (extract_port(dst) == 0 && natt_port != NULL)
-				set_port(dst, ntohs(natt_port->sadb_x_nat_t_port_port));
-		}else{
-			/* Force default UDP ports, so CMPSADDR will match SAs with NO encapsulation
-			 */
+			if (extract_port(src) == 0 &&
+			    mhp[SADB_X_EXT_NAT_T_SPORT] != NULL) {
+				set_port(src, PFKEY_ADDR_X_PORT(mhp[SADB_X_EXT_NAT_T_SPORT]));
+			}
+
+			if (extract_port(dst) == 0 &&
+			    mhp[SADB_X_EXT_NAT_T_DPORT] != NULL) {
+				set_port(dst, PFKEY_ADDR_X_PORT(mhp[SADB_X_EXT_NAT_T_DPORT]));
+			}
+			natt_port_forced = 0;
+		} else {
+			/* Force default UDP ports, so
+			 * CMPSADDR will match SAs with NO encapsulation */
 			set_port(src, PORT_ISAKMP);
 			set_port(dst, PORT_ISAKMP);
+			natt_port_forced = 1;
 		}
 #endif
 		plog(LLV_DEBUG2, LOCATION, NULL, "src: %s\n", saddr2str(src));
@@ -1211,10 +1213,9 @@
 		}
 
 #ifdef ENABLE_NATT
-		if (natt_type == NULL ||
-			! natt_type->sadb_x_nat_t_type_type) {
-			/* Set back port to 0 if it was forced to default UDP port
-			 */
+		if (natt_port_forced) {
+			/* Set back port to 0 if it was forced
+			 * to default UDP port */
 			set_port(src, 0);
 			set_port(dst, 0);
 		}

Index: src/crypto/dist/ipsec-tools/src/racoon/pfkey.c
diff -u src/crypto/dist/ipsec-tools/src/racoon/pfkey.c:1.46 src/crypto/dist/ipsec-tools/src/racoon/pfkey.c:1.47
--- src/crypto/dist/ipsec-tools/src/racoon/pfkey.c:1.46	Fri Mar 13 04:49:16 2009
+++ src/crypto/dist/ipsec-tools/src/racoon/pfkey.c	Fri Jul  3 06:40:10 2009
@@ -1,6 +1,6 @@
-/*	$NetBSD: pfkey.c,v 1.46 2009/03/13 04:49:16 tteras Exp $	*/
+/*	$NetBSD: pfkey.c,v 1.47 2009/07/03 06:40:10 tteras Exp $	*/
 
-/* $Id: pfkey.c,v 1.46 2009/03/13 04:49:16 tteras Exp $ */
+/* $Id: pfkey.c,v 1.47 2009/07/03 06:40:10 tteras Exp $ */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -769,6 +769,28 @@
 	return res;
 }
 
+void
+pk_fixup_sa_addresses(mhp)
+	caddr_t *mhp;
+{
+	struct sockaddr *src, *dst;
+	src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
+	dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
+#ifdef ENABLE_NATT
+	if (PFKEY_ADDR_X_NATTYPE(mhp[SADB_X_EXT_NAT_T_TYPE])) {
+		/* NAT-T is enabled for this SADB entry; copy
+		 * the ports from NAT-T extensions */
+		if(mhp[SADB_X_EXT_NAT_T_SPORT] != NULL)
+			set_port(src, PFKEY_ADDR_X_PORT(mhp[SADB_X_EXT_NAT_T_SPORT]));
+		if(mhp[SADB_X_EXT_NAT_T_DPORT] != NULL)
+			set_port(dst, PFKEY_ADDR_X_PORT(mhp[SADB_X_EXT_NAT_T_DPORT]));
+	}
+#else
+	set_port(src, 0);
+	set_port(dst, 0);
+#endif
+}
+
 int
 pfkey_convertfromipsecdoi(proto_id, t_id, hashtype,
 		e_type, e_keylen, a_type, a_keylen, flags)
@@ -866,6 +888,8 @@
 	struct saprop *pp;
 	struct saproto *pr;
 	u_int32_t minspi, maxspi;
+	u_int8_t natt_type = 0;
+	u_int16_t sport = 0, dport = 0;
 
 	if (iph2->side == INITIATOR)
 		pp = iph2->proposal;
@@ -919,19 +943,27 @@
 		}
 
 #ifdef ENABLE_NATT
-		if (! pr->udp_encap) {
-			/* Remove port information, that SA doesn't use it */
-			set_port(iph2->src, 0);
-			set_port(iph2->dst, 0);
+		if (pr->udp_encap) {
+			natt_type = iph2->ph1->natt_options->encaps_type;
+			sport=extract_port(src);
+			dport=extract_port(dst);
 		}
 #endif
+		/* Always remove port information, it will be sent in
+		 * SADB_X_EXT_NAT_T_[S|D]PORT if needed */
+		set_port(src, 0);
+		set_port(dst, 0);
+
 		plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_getspi\n");
-		if (pfkey_send_getspi(
+		if (pfkey_send_getspi_nat(
 				lcconf->sock_pfkey,
 				satype,
 				mode,
 				dst,			/* src of SA */
 				src,			/* dst of SA */
+				natt_type,
+				dport,
+				sport,
 				minspi, maxspi,
 				pr->reqid_in, iph2->seq) < 0) {
 			plog(LLV_ERROR, LOCATION, NULL,
@@ -1157,13 +1189,13 @@
 #ifdef SADB_X_EXT_NAT_T_FRAG
 			sa_args.l_natt_frag = iph2->ph1->rmconf->esp_frag;
 #endif
-		} else {
-			/* Remove port information, that SA doesn't use it */
-			set_port(sa_args.src, 0);
-			set_port(sa_args.dst, 0);
 		}
-
 #endif
+		/* Always remove port information, it will be sent in
+		 * SADB_X_EXT_NAT_T_[S|D]PORT if needed */
+		set_port(sa_args.src, 0);
+		set_port(sa_args.dst, 0);
+
 		/* more info to fill in */
 		sa_args.spi = pr->spi;
 		sa_args.reqid = pr->reqid_in;
@@ -1236,6 +1268,7 @@
 		return -1;
 	}
 	msg = (struct sadb_msg *)mhp[0];
+	pk_fixup_sa_addresses(mhp);
 	src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
 	dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
 	sa = (struct sadb_sa *)mhp[SADB_EXT_SA];
@@ -1328,7 +1361,6 @@
 	/* Force the update of ph2's ports, as there is at least one
 	 * situation where they'll mismatch with ph1's values
 	 */
-
 #ifdef ENABLE_NATT
 	set_port(iph2->src, extract_port(iph2->ph1->local));
 	set_port(iph2->dst, extract_port(iph2->ph1->remote));
@@ -1456,17 +1488,12 @@
 #ifdef SADB_X_EXT_NAT_T_FRAG
 			sa_args.l_natt_frag = iph2->ph1->rmconf->esp_frag;
 #endif
-		} else {
-			/* Remove port information, that SA doesn't use it */
-			set_port(sa_args.src, 0);
-			set_port(sa_args.dst, 0);
 		}
-
-#else
-		/* Remove port information, it is not used without NAT-T */
+#endif
+		/* Always remove port information, it will be sent in
+		 * SADB_X_EXT_NAT_T_[S|D]PORT if needed */
 		set_port(sa_args.src, 0);
 		set_port(sa_args.dst, 0);
-#endif
 
 		/* more info to fill in */
 		sa_args.spi = pr->spi_p;
@@ -1596,6 +1623,7 @@
 	}
 	msg = (struct sadb_msg *)mhp[0];
 	sa = (struct sadb_sa *)mhp[SADB_EXT_SA];
+	pk_fixup_sa_addresses(mhp);
 	src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
 	dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
 
@@ -1721,6 +1749,7 @@
 	}
 	msg = (struct sadb_msg *)mhp[0];
 	xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
+	pk_fixup_sa_addresses(mhp);
 	sp_src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
 	sp_dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
 
@@ -1971,6 +2000,7 @@
 	}
 	msg = (struct sadb_msg *)mhp[0];
 	sa = (struct sadb_sa *)mhp[SADB_EXT_SA];
+	pk_fixup_sa_addresses(mhp);
 	src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
 	dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
 
@@ -2709,7 +2739,6 @@
 		return -1;
 	}
 	msg = (struct sadb_msg *)mhp[0];
-
 	saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC];
 	daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
 	xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];

Index: src/crypto/dist/ipsec-tools/src/racoon/pfkey.h
diff -u src/crypto/dist/ipsec-tools/src/racoon/pfkey.h:1.7 src/crypto/dist/ipsec-tools/src/racoon/pfkey.h:1.8
--- src/crypto/dist/ipsec-tools/src/racoon/pfkey.h:1.7	Tue Dec 23 14:03:12 2008
+++ src/crypto/dist/ipsec-tools/src/racoon/pfkey.h	Fri Jul  3 06:40:10 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: pfkey.h,v 1.7 2008/12/23 14:03:12 tteras Exp $	*/
+/*	$NetBSD: pfkey.h,v 1.8 2009/07/03 06:40:10 tteras Exp $	*/
 
 /* Id: pfkey.h,v 1.3 2004/06/11 16:00:17 ludvigm Exp */
 
@@ -52,6 +52,7 @@
 extern int pk_checkalg __P((int, int, int));
 
 struct ph2handle;
+extern void pk_fixup_sa_addresses __P((caddr_t *mhp));
 extern int pk_sendgetspi __P((struct ph2handle *));
 extern int pk_sendupdate __P((struct ph2handle *));
 extern int pk_sendadd __P((struct ph2handle *));

Reply via email to