1 /* $NetBSD: nattraversal.c,v 1.12 2009/07/03 06:41:46 tteras Exp $ */
4 * Copyright (C) 2004 SuSE Linux AG, Nuernberg, Germany.
5 * Contributed by: Michal Ludvig <mludvig@suse.cz>, SUSE Labs
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the project nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 #include <sys/types.h>
36 #include <sys/param.h>
39 #include <linux/udp.h>
41 #if defined(__NetBSD__) || defined (__FreeBSD__)
42 #include <netinet/udp.h>
57 #include "localconf.h"
58 #include "remoteconf.h"
60 #include "isakmp_var.h"
63 #include "ipsec_doi.h"
66 #include "crypto_openssl.h"
68 #include "nattraversal.h"
69 #include "grabmyaddr.h"
71 struct natt_ka_addrs
{
76 TAILQ_ENTRY(natt_ka_addrs
) chain
;
79 static TAILQ_HEAD(_natt_ka_addrs
, natt_ka_addrs
) ka_tree
;
80 static struct sched sc_natt
= SCHED_INITIALIZER();
83 * check if the given vid is NAT-T.
86 natt_vendorid (int vid
)
90 vid
== VENDORID_NATT_00
||
93 vid
== VENDORID_NATT_01
||
96 vid
== VENDORID_NATT_02
||
97 vid
== VENDORID_NATT_02_N
||
100 vid
== VENDORID_NATT_03
||
102 #ifdef ENABLE_NATT_04
103 vid
== VENDORID_NATT_04
||
105 #ifdef ENABLE_NATT_05
106 vid
== VENDORID_NATT_05
||
108 #ifdef ENABLE_NATT_06
109 vid
== VENDORID_NATT_06
||
111 #ifdef ENABLE_NATT_07
112 vid
== VENDORID_NATT_07
||
114 #ifdef ENABLE_NATT_08
115 vid
== VENDORID_NATT_08
||
117 /* Always enable NATT RFC if ENABLE_NATT
119 vid
== VENDORID_NATT_RFC
);
123 natt_hash_addr (struct ph1handle
*iph1
, struct sockaddr
*addr
)
128 void *addr_ptr
, *addr_port
;
129 size_t buf_size
, addr_size
;
132 if (iph1
->rmconf
!= NULL
&& iph1
->rmconf
->nat_traversal
== NATT_FORCE
)
135 plog (LLV_INFO
, LOCATION
, addr
, "Hashing %s with algo #%d %s\n",
136 saddr2str(addr
), iph1
->approval
->hashtype
,
137 natt_force
?"(NAT-T forced)":"");
139 if (addr
->sa_family
== AF_INET
) {
140 addr_size
= sizeof (struct in_addr
); /* IPv4 address */
141 addr_ptr
= &((struct sockaddr_in
*)addr
)->sin_addr
;
142 addr_port
= &((struct sockaddr_in
*)addr
)->sin_port
;
144 else if (addr
->sa_family
== AF_INET6
) {
145 addr_size
= sizeof (struct in6_addr
); /* IPv6 address */
146 addr_ptr
= &((struct sockaddr_in6
*)addr
)->sin6_addr
;
147 addr_port
= &((struct sockaddr_in6
*)addr
)->sin6_port
;
150 plog (LLV_ERROR
, LOCATION
, addr
, "Unsupported address family #0x%x\n", addr
->sa_family
);
154 buf_size
= 2 * sizeof (cookie_t
); /* CKY-I + CKY+R */
155 buf_size
+= addr_size
+ 2; /* Address + Port */
157 if ((buf
= vmalloc (buf_size
)) == NULL
)
163 memcpy (ptr
, iph1
->index
.i_ck
, sizeof (cookie_t
));
164 ptr
+= sizeof (cookie_t
);
167 memcpy (ptr
, iph1
->index
.r_ck
, sizeof (cookie_t
));
168 ptr
+= sizeof (cookie_t
);
170 /* Copy-in Address (or zeroes if NATT_FORCE) */
172 memset (ptr
, 0, addr_size
);
174 memcpy (ptr
, addr_ptr
, addr_size
);
177 /* Copy-in Port number */
178 memcpy (ptr
, addr_port
, 2);
180 natd
= oakley_hash (buf
, iph1
);
187 natt_compare_addr_hash (struct ph1handle
*iph1
, vchar_t
*natd_received
,
190 vchar_t
*natd_computed
;
194 if (iph1
->rmconf
!= NULL
&&
195 iph1
->rmconf
->nat_traversal
== NATT_FORCE
)
199 natd_computed
= natt_hash_addr (iph1
, iph1
->local
);
200 flag
= NAT_DETECTED_ME
;
203 natd_computed
= natt_hash_addr (iph1
, iph1
->remote
);
204 flag
= NAT_DETECTED_PEER
;
207 if (natd_computed
== NULL
) {
208 plog(LLV_ERROR
, LOCATION
, NULL
, "natd_computed allocation failed\n");
209 return verified
; /* XXX should abort */
212 if (natd_received
->l
== natd_computed
->l
&&
213 memcmp (natd_received
->v
, natd_computed
->v
, natd_received
->l
) == 0) {
214 iph1
->natt_flags
&= ~flag
;
218 vfree (natd_computed
);
224 natt_udp_encap (int encmode
)
226 return (encmode
== IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_RFC
||
227 encmode
== IPSECDOI_ATTR_ENC_MODE_UDPTRNS_RFC
||
228 encmode
== IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_DRAFT
||
229 encmode
== IPSECDOI_ATTR_ENC_MODE_UDPTRNS_DRAFT
);
233 natt_fill_options (struct ph1natt_options
*opts
, int version
)
238 opts
->version
= version
;
241 case VENDORID_NATT_00
:
242 case VENDORID_NATT_01
:
243 opts
->float_port
= 0; /* No port floating for those drafts */
244 opts
->payload_nat_d
= ISAKMP_NPTYPE_NATD_DRAFT
;
245 opts
->payload_nat_oa
= ISAKMP_NPTYPE_NATOA_DRAFT
;
246 opts
->mode_udp_tunnel
= IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_DRAFT
;
247 opts
->mode_udp_transport
= IPSECDOI_ATTR_ENC_MODE_UDPTRNS_DRAFT
;
248 opts
->encaps_type
= UDP_ENCAP_ESPINUDP_NON_IKE
;
251 case VENDORID_NATT_02
:
252 case VENDORID_NATT_02_N
:
253 case VENDORID_NATT_03
:
254 opts
->float_port
= lcconf
->port_isakmp_natt
;
255 opts
->payload_nat_d
= ISAKMP_NPTYPE_NATD_DRAFT
;
256 opts
->payload_nat_oa
= ISAKMP_NPTYPE_NATOA_DRAFT
;
257 opts
->mode_udp_tunnel
= IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_DRAFT
;
258 opts
->mode_udp_transport
= IPSECDOI_ATTR_ENC_MODE_UDPTRNS_DRAFT
;
259 opts
->encaps_type
= UDP_ENCAP_ESPINUDP
;
261 case VENDORID_NATT_04
:
262 case VENDORID_NATT_05
:
263 case VENDORID_NATT_06
:
264 case VENDORID_NATT_07
:
265 case VENDORID_NATT_08
:
266 opts
->float_port
= lcconf
->port_isakmp_natt
;
267 opts
->payload_nat_d
= ISAKMP_NPTYPE_NATD_BADDRAFT
;
268 opts
->payload_nat_oa
= ISAKMP_NPTYPE_NATOA_BADDRAFT
;
269 opts
->mode_udp_tunnel
= IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_RFC
;
270 opts
->mode_udp_transport
= IPSECDOI_ATTR_ENC_MODE_UDPTRNS_RFC
;
271 opts
->encaps_type
= UDP_ENCAP_ESPINUDP
;
273 case VENDORID_NATT_RFC
:
274 opts
->float_port
= lcconf
->port_isakmp_natt
;
275 opts
->payload_nat_d
= ISAKMP_NPTYPE_NATD_RFC
;
276 opts
->payload_nat_oa
= ISAKMP_NPTYPE_NATOA_RFC
;
277 opts
->mode_udp_tunnel
= IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_RFC
;
278 opts
->mode_udp_transport
= IPSECDOI_ATTR_ENC_MODE_UDPTRNS_RFC
;
279 opts
->encaps_type
= UDP_ENCAP_ESPINUDP
;
282 plog(LLV_ERROR
, LOCATION
, NULL
,
283 "unsupported NAT-T version: %s\n",
284 vid_string_by_id(version
));
288 opts
->mode_udp_diff
= opts
->mode_udp_tunnel
- IPSECDOI_ATTR_ENC_MODE_TUNNEL
;
294 natt_float_ports (struct ph1handle
*iph1
)
296 if (! (iph1
->natt_flags
& NAT_DETECTED
) )
298 if (! iph1
->natt_options
->float_port
){
299 /* Drafts 00 / 01, just schedule keepalive */
300 natt_keepalive_add_ph1 (iph1
);
304 set_port (iph1
->local
, iph1
->natt_options
->float_port
);
305 set_port (iph1
->remote
, iph1
->natt_options
->float_port
);
306 iph1
->natt_flags
|= NAT_PORTS_CHANGED
| NAT_ADD_NON_ESP_MARKER
;
308 natt_keepalive_add_ph1 (iph1
);
312 natt_is_enabled (struct remoteconf
*rmconf
, void *args
)
314 if (rmconf
->nat_traversal
)
320 natt_handle_vendorid (struct ph1handle
*iph1
, int vid_numeric
)
322 if (iph1
->rmconf
== NULL
) {
323 /* Check if any candidate remote conf allows nat-t */
324 struct rmconfselector rmconf
;
325 rmconf_selector_from_ph1(&rmconf
, iph1
);
326 if (enumrmconf(&rmconf
, natt_is_enabled
, NULL
) == 0)
329 if (!iph1
->rmconf
->nat_traversal
)
333 if (! iph1
->natt_options
)
334 iph1
->natt_options
= racoon_calloc (1, sizeof (*iph1
->natt_options
));
336 if (! iph1
->natt_options
) {
337 plog (LLV_ERROR
, LOCATION
, NULL
,
338 "Allocating memory for natt_options failed!\n");
342 if (iph1
->natt_options
->version
< vid_numeric
)
343 if (natt_fill_options (iph1
->natt_options
, vid_numeric
) == 0)
344 iph1
->natt_flags
|= NAT_ANNOUNCED
;
348 natt_keepalive_delete (struct natt_ka_addrs
*ka
)
350 TAILQ_REMOVE (&ka_tree
, ka
, chain
);
351 racoon_free (ka
->src
);
352 racoon_free (ka
->dst
);
356 /* NAT keepalive functions */
358 natt_keepalive_send (struct sched
*param
)
360 struct natt_ka_addrs
*ka
, *next
= NULL
;
361 char keepalive_packet
[] = { 0xff };
365 for (ka
= TAILQ_FIRST(&ka_tree
); ka
; ka
= next
) {
366 next
= TAILQ_NEXT(ka
, chain
);
368 s
= myaddr_getfd(ka
->src
);
370 natt_keepalive_delete(ka
);
373 plog (LLV_DEBUG
, LOCATION
, NULL
, "KA: %s\n",
374 saddr2str_fromto("%s->%s", ka
->src
, ka
->dst
));
375 len
= sendfromto(s
, keepalive_packet
, sizeof (keepalive_packet
),
376 ka
->src
, ka
->dst
, 1);
378 plog(LLV_ERROR
, LOCATION
, NULL
, "KA: sendfromto failed: %s\n",
382 sched_schedule (&sc_natt
, lcconf
->natt_ka_interval
, natt_keepalive_send
);
386 natt_keepalive_init (void)
388 TAILQ_INIT(&ka_tree
);
390 /* To disable sending KAs set natt_ka_interval=0 */
391 if (lcconf
->natt_ka_interval
> 0)
392 sched_schedule (&sc_natt
, lcconf
->natt_ka_interval
, natt_keepalive_send
);
396 natt_keepalive_add (struct sockaddr
*src
, struct sockaddr
*dst
)
398 struct natt_ka_addrs
*ka
= NULL
, *new_addr
;
400 TAILQ_FOREACH (ka
, &ka_tree
, chain
) {
401 if (cmpsaddr(ka
->src
, src
) == 0 &&
402 cmpsaddr(ka
->dst
, dst
) == 0) {
404 plog (LLV_INFO
, LOCATION
, NULL
, "KA found: %s (in_use=%u)\n",
405 saddr2str_fromto("%s->%s", src
, dst
), ka
->in_use
);
410 plog (LLV_INFO
, LOCATION
, NULL
, "KA list add: %s\n", saddr2str_fromto("%s->%s", src
, dst
));
412 new_addr
= (struct natt_ka_addrs
*)racoon_malloc(sizeof(*new_addr
));
414 plog (LLV_ERROR
, LOCATION
, NULL
, "Can't allocate new KA list item\n");
418 if ((new_addr
->src
= dupsaddr(src
)) == NULL
) {
419 racoon_free(new_addr
);
420 plog (LLV_ERROR
, LOCATION
, NULL
, "Can't allocate new KA list item\n");
423 if ((new_addr
->dst
= dupsaddr(dst
)) == NULL
) {
424 racoon_free(new_addr
);
425 plog (LLV_ERROR
, LOCATION
, NULL
, "Can't allocate new KA list item\n");
428 new_addr
->in_use
= 1;
429 TAILQ_INSERT_TAIL(&ka_tree
, new_addr
, chain
);
435 natt_keepalive_add_ph1 (struct ph1handle
*iph1
)
439 /* Should only the NATed host send keepalives?
440 If yes, add '(iph1->natt_flags & NAT_DETECTED_ME)'
441 to the following condition. */
442 if (iph1
->natt_flags
& NAT_DETECTED
&&
443 ! (iph1
->natt_flags
& NAT_KA_QUEUED
)) {
444 ret
= natt_keepalive_add (iph1
->local
, iph1
->remote
);
446 iph1
->natt_flags
|= NAT_KA_QUEUED
;
453 natt_keepalive_remove (struct sockaddr
*src
, struct sockaddr
*dst
)
455 struct natt_ka_addrs
*ka
, *next
= NULL
;
457 plog (LLV_INFO
, LOCATION
, NULL
, "KA remove: %s\n", saddr2str_fromto("%s->%s", src
, dst
));
459 for (ka
= TAILQ_FIRST(&ka_tree
); ka
; ka
= next
) {
460 next
= TAILQ_NEXT(ka
, chain
);
462 plog (LLV_DEBUG
, LOCATION
, NULL
, "KA tree dump: %s (in_use=%u)\n",
463 saddr2str_fromto("%s->%s", src
, dst
), ka
->in_use
);
465 if (cmpsaddr(ka
->src
, src
) == 0 &&
466 cmpsaddr(ka
->dst
, dst
) == 0 &&
467 -- ka
->in_use
<= 0) {
469 plog (LLV_DEBUG
, LOCATION
, NULL
, "KA removing this one...\n");
471 natt_keepalive_delete (ka
);
472 /* Should we break here? Every pair of addresses should
473 be inserted only once, but who knows :-) Lets traverse
480 natt_enabled_in_rmconf_stub (struct remoteconf
*rmconf
, void *data
)
482 return rmconf
->nat_traversal
? 1 : 0;
486 natt_enabled_in_rmconf ()
488 return enumrmconf(NULL
, natt_enabled_in_rmconf_stub
, NULL
) != 0;
492 struct payload_list
*
493 isakmp_plist_append_natt_vids (struct payload_list
*plist
, vchar_t
*vid_natt
[MAX_NATT_VID_COUNT
]){
494 int i
, vid_natt_i
= 0;
499 for (i
= 0; i
< MAX_NATT_VID_COUNT
; i
++)
502 /* Puts the olders VIDs last, as some implementations may choose the first
506 /* Always set RFC VID
508 if ((vid_natt
[vid_natt_i
] = set_vendorid(VENDORID_NATT_RFC
)) != NULL
)
510 #ifdef ENABLE_NATT_08
511 if ((vid_natt
[vid_natt_i
] = set_vendorid(VENDORID_NATT_08
)) != NULL
)
514 #ifdef ENABLE_NATT_07
515 if ((vid_natt
[vid_natt_i
] = set_vendorid(VENDORID_NATT_07
)) != NULL
)
518 #ifdef ENABLE_NATT_06
519 if ((vid_natt
[vid_natt_i
] = set_vendorid(VENDORID_NATT_06
)) != NULL
)
522 #ifdef ENABLE_NATT_05
523 if ((vid_natt
[vid_natt_i
] = set_vendorid(VENDORID_NATT_05
)) != NULL
)
526 #ifdef ENABLE_NATT_04
527 if ((vid_natt
[vid_natt_i
] = set_vendorid(VENDORID_NATT_04
)) != NULL
)
530 #ifdef ENABLE_NATT_03
531 if ((vid_natt
[vid_natt_i
] = set_vendorid(VENDORID_NATT_03
)) != NULL
)
534 #ifdef ENABLE_NATT_02
535 if ((vid_natt
[vid_natt_i
] = set_vendorid(VENDORID_NATT_02
)) != NULL
)
537 if ((vid_natt
[vid_natt_i
] = set_vendorid(VENDORID_NATT_02_N
)) != NULL
)
540 #ifdef ENABLE_NATT_01
541 if ((vid_natt
[vid_natt_i
] = set_vendorid(VENDORID_NATT_01
)) != NULL
)
544 #ifdef ENABLE_NATT_00
545 if ((vid_natt
[vid_natt_i
] = set_vendorid(VENDORID_NATT_00
)) != NULL
)
548 /* set VID payload for NAT-T */
549 for (i
= 0; i
< vid_natt_i
; i
++)
550 plist
= isakmp_plist_append(plist
, vid_natt
[i
], ISAKMP_NPTYPE_VID
);