fixed compiler warning
[strongswan.git] / src / pluto / nat_traversal.c
1 /* FreeS/WAN NAT-Traversal
2 * Copyright (C) 2002-2005 Mathieu Lafon - Arkoon Network Security
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * for more details.
13 */
14
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <ctype.h>
18 #include <stdarg.h>
19 #include <syslog.h>
20 #include <errno.h>
21 #include <string.h>
22 #include <unistd.h>
23 #include <signal.h> /* used only if MSG_NOSIGNAL not defined */
24 #include <sys/queue.h>
25
26 #include <freeswan.h>
27 #include <ipsec_policy.h>
28 #include <pfkeyv2.h>
29 #include <pfkey.h>
30
31 #include <library.h>
32 #include <crypto/hashers/hasher.h>
33
34 #include "constants.h"
35 #include "defs.h"
36 #include "log.h"
37 #include "server.h"
38 #include "state.h"
39 #include "connections.h"
40 #include "packet.h"
41 #include "demux.h"
42 #include "kernel.h"
43 #include "whack.h"
44 #include "timer.h"
45 #include "cookie.h"
46 #include "crypto.h"
47 #include "vendor.h"
48 #include "ike_alg.h"
49 #include "nat_traversal.h"
50
51 /* #define FORCE_NAT_TRAVERSAL */
52 #define NAT_D_DEBUG
53 #define NAT_T_SUPPORT_LAST_DRAFTS
54
55 #ifndef SOL_UDP
56 #define SOL_UDP 17
57 #endif
58
59 #ifndef UDP_ESPINUDP
60 #define UDP_ESPINUDP 100
61 #endif
62
63 #define DEFAULT_KEEP_ALIVE_PERIOD 20
64
65 #ifdef _IKE_ALG_H
66 /* Alg patch: hash_digest_len -> hash_digest_size */
67 #define hash_digest_len hash_digest_size
68 #endif
69
70 bool nat_traversal_enabled = FALSE;
71 bool nat_traversal_support_non_ike = FALSE;
72 bool nat_traversal_support_port_floating = FALSE;
73
74 static unsigned int _kap = 0;
75 static unsigned int _ka_evt = 0;
76 static bool _force_ka = 0;
77
78 static const char *natt_version = "0.6c";
79
80 void init_nat_traversal (bool activate, unsigned int keep_alive_period,
81 bool fka, bool spf)
82 {
83 nat_traversal_enabled = activate;
84 nat_traversal_support_non_ike = activate;
85 #ifdef NAT_T_SUPPORT_LAST_DRAFTS
86 nat_traversal_support_port_floating = activate ? spf : FALSE;
87 #endif
88 _force_ka = fka;
89 _kap = keep_alive_period ? keep_alive_period : DEFAULT_KEEP_ALIVE_PERIOD;
90 plog(" including NAT-Traversal patch (Version %s)%s%s%s"
91 , natt_version, activate ? "" : " [disabled]"
92 , activate & fka ? " [Force KeepAlive]" : ""
93 , activate & !spf ? " [Port Floating disabled]" : "");
94 }
95
96 static void disable_nat_traversal (int type)
97 {
98 if (type == ESPINUDP_WITH_NON_IKE)
99 nat_traversal_support_non_ike = FALSE;
100 else
101 nat_traversal_support_port_floating = FALSE;
102
103 if (!nat_traversal_support_non_ike &&
104 !nat_traversal_support_port_floating)
105 nat_traversal_enabled = FALSE;
106 }
107
108 static void _natd_hash(const struct hash_desc *oakley_hasher, char *hash,
109 u_int8_t *icookie, u_int8_t *rcookie,
110 const ip_address *ip, u_int16_t port)
111 {
112 if (is_zero_cookie(icookie))
113 {
114 DBG_log("_natd_hash: Warning, icookie is zero !!");
115 }
116 if (is_zero_cookie(rcookie))
117 {
118 DBG_log("_natd_hash: Warning, rcookie is zero !!");
119 }
120
121 /**
122 * draft-ietf-ipsec-nat-t-ike-01.txt
123 *
124 * HASH = HASH(CKY-I | CKY-R | IP | Port)
125 *
126 * All values in network order
127 */
128 {
129 chunk_t icookie_chunk = { icookie, COOKIE_SIZE };
130 chunk_t rcookie_chunk = { rcookie, COOKIE_SIZE };
131 chunk_t port_chunk = chunk_from_thing(port);
132 chunk_t addr_chunk;
133 hash_algorithm_t hash_alg;
134 hasher_t *hasher;
135 size_t hash_size;
136
137 hash_alg = oakley_to_hash_algorithm(oakley_hasher->algo_id);
138 hasher = lib->crypto->create_hasher(lib->crypto, hash_alg);
139 hasher->get_hash(hasher, icookie_chunk, NULL);
140 hasher->get_hash(hasher, rcookie_chunk, NULL);
141 switch (addrtypeof(ip))
142 {
143 case AF_INET:
144 addr_chunk = chunk_from_thing(ip->u.v4.sin_addr.s_addr);
145 break;
146 case AF_INET6:
147 addr_chunk = chunk_from_thing(ip->u.v6.sin6_addr.s6_addr);
148 break;
149 default:
150 addr_chunk = chunk_empty; /* should never occur */
151 }
152 hasher->get_hash(hasher, addr_chunk, NULL);
153 hasher->get_hash(hasher, port_chunk, hash);
154 hash_size = hasher->get_hash_size(hasher);
155 hasher->destroy(hasher);
156 #ifdef NAT_D_DEBUG
157 DBG(DBG_NATT,
158 DBG_dump_chunk("_natd_hash: icookie=", icookie_chunk);
159 DBG_dump_chunk("_natd_hash: rcookie=", rcookie_chunk);
160 DBG_dump_chunk("_natd_hash: ip=", addr_chunk);
161 DBG_log("_natd_hash: port=%d", port);
162 DBG_dump("_natd_hash: hash=", hash, hash_size);
163 )
164 #endif
165 }
166 }
167
168 /* Add NAT-Traversal VIDs (supported ones)
169 * used when we are Initiator
170 */
171 bool nat_traversal_add_vid(u_int8_t np, pb_stream *outs)
172 {
173 bool r = TRUE;
174
175 if (nat_traversal_support_port_floating)
176 {
177 u_int8_t last_np = nat_traversal_support_non_ike ?
178 ISAKMP_NEXT_VID : np;
179
180 if (r)
181 r = out_vendorid(ISAKMP_NEXT_VID, outs, VID_NATT_RFC);
182 if (r)
183 r = out_vendorid(ISAKMP_NEXT_VID, outs, VID_NATT_IETF_03);
184 if (r)
185 r = out_vendorid(ISAKMP_NEXT_VID, outs, VID_NATT_IETF_02);
186 if (r)
187 r = out_vendorid(last_np, outs, VID_NATT_IETF_02_N);
188 }
189 if (nat_traversal_support_non_ike)
190 {
191 if (r)
192 r = out_vendorid(np, outs, VID_NATT_IETF_00);
193 }
194 return r;
195 }
196
197 u_int32_t nat_traversal_vid_to_method(unsigned short nat_t_vid)
198 {
199 switch (nat_t_vid)
200 {
201 case VID_NATT_IETF_00:
202 return LELEM(NAT_TRAVERSAL_IETF_00_01);
203 case VID_NATT_IETF_02:
204 case VID_NATT_IETF_02_N:
205 case VID_NATT_IETF_03:
206 return LELEM(NAT_TRAVERSAL_IETF_02_03);
207 case VID_NATT_RFC:
208 return LELEM(NAT_TRAVERSAL_RFC);
209 }
210 return 0;
211 }
212
213 void nat_traversal_natd_lookup(struct msg_digest *md)
214 {
215 char hash[MAX_DIGEST_LEN];
216 struct payload_digest *p;
217 struct state *st = md->st;
218 int i;
219
220 if (!st || !md->iface || !st->st_oakley.hasher)
221 {
222 loglog(RC_LOG_SERIOUS, "NAT-Traversal: assert failed %s:%d"
223 , __FILE__, __LINE__);
224 return;
225 }
226
227 /** Count NAT-D **/
228 for (p = md->chain[ISAKMP_NEXT_NATD_RFC], i=0; p != NULL; p = p->next, i++);
229
230 /*
231 * We need at least 2 NAT-D (1 for us, many for peer)
232 */
233 if (i < 2)
234 {
235 loglog(RC_LOG_SERIOUS,
236 "NAT-Traversal: Only %d NAT-D - Aborting NAT-Traversal negociation", i);
237 st->nat_traversal = 0;
238 return;
239 }
240
241 /*
242 * First one with my IP & port
243 */
244 p = md->chain[ISAKMP_NEXT_NATD_RFC];
245 _natd_hash(st->st_oakley.hasher, hash, st->st_icookie, st->st_rcookie,
246 &(md->iface->addr), ntohs(st->st_connection->spd.this.host_port));
247
248 if (!(pbs_left(&p->pbs) == st->st_oakley.hasher->hash_digest_len &&
249 memeq(p->pbs.cur, hash, st->st_oakley.hasher->hash_digest_len)))
250 {
251 #ifdef NAT_D_DEBUG
252 DBG(DBG_NATT,
253 DBG_log("NAT_TRAVERSAL_NAT_BHND_ME");
254 DBG_dump("expected NAT-D:", hash
255 , st->st_oakley.hasher->hash_digest_len);
256 DBG_dump("received NAT-D:", p->pbs.cur, pbs_left(&p->pbs));
257 )
258 #endif
259 st->nat_traversal |= LELEM(NAT_TRAVERSAL_NAT_BHND_ME);
260 }
261
262 /*
263 * The others with sender IP & port
264 */
265 _natd_hash(st->st_oakley.hasher, hash, st->st_icookie, st->st_rcookie,
266 &(md->sender), ntohs(md->sender_port));
267 for (p = p->next, i=0 ; p != NULL; p = p->next)
268 {
269 if (pbs_left(&p->pbs) == st->st_oakley.hasher->hash_digest_len &&
270 memeq(p->pbs.cur, hash, st->st_oakley.hasher->hash_digest_len))
271 {
272 i++;
273 }
274 }
275 if (!i)
276 {
277 #ifdef NAT_D_DEBUG
278 DBG(DBG_NATT,
279 DBG_log("NAT_TRAVERSAL_NAT_BHND_PEER");
280 DBG_dump("expected NAT-D:", hash
281 , st->st_oakley.hasher->hash_digest_len);
282 p = md->chain[ISAKMP_NEXT_NATD_RFC];
283 for (p = p->next, i=0 ; p != NULL; p = p->next)
284 {
285 DBG_dump("received NAT-D:", p->pbs.cur, pbs_left(&p->pbs));
286 }
287 )
288 #endif
289 st->nat_traversal |= LELEM(NAT_TRAVERSAL_NAT_BHND_PEER);
290 }
291 #ifdef FORCE_NAT_TRAVERSAL
292 st->nat_traversal |= LELEM(NAT_TRAVERSAL_NAT_BHND_PEER);
293 st->nat_traversal |= LELEM(NAT_TRAVERSAL_NAT_BHND_ME);
294 #endif
295 }
296
297 bool nat_traversal_add_natd(u_int8_t np, pb_stream *outs,
298 struct msg_digest *md)
299 {
300 char hash[MAX_DIGEST_LEN];
301 struct state *st = md->st;
302
303 if (!st || !st->st_oakley.hasher)
304 {
305 loglog(RC_LOG_SERIOUS, "NAT-Traversal: assert failed %s:%d"
306 , __FILE__, __LINE__);
307 return FALSE;
308 }
309
310 DBG(DBG_EMITTING,
311 DBG_log("sending NATD payloads")
312 )
313
314 /*
315 * First one with sender IP & port
316 */
317 _natd_hash(st->st_oakley.hasher, hash, st->st_icookie,
318 is_zero_cookie(st->st_rcookie) ? md->hdr.isa_rcookie : st->st_rcookie,
319 &(md->sender),
320 #ifdef FORCE_NAT_TRAVERSAL
321 0
322 #else
323 ntohs(md->sender_port)
324 #endif
325 );
326 if (!out_generic_raw((st->nat_traversal & NAT_T_WITH_RFC_VALUES
327 ? ISAKMP_NEXT_NATD_RFC : ISAKMP_NEXT_NATD_DRAFTS), &isakmp_nat_d, outs,
328 hash, st->st_oakley.hasher->hash_digest_len, "NAT-D"))
329 {
330 return FALSE;
331 }
332
333 /*
334 * Second one with my IP & port
335 */
336 _natd_hash(st->st_oakley.hasher, hash, st->st_icookie,
337 is_zero_cookie(st->st_rcookie) ? md->hdr.isa_rcookie : st->st_rcookie,
338 &(md->iface->addr),
339 #ifdef FORCE_NAT_TRAVERSAL
340 0
341 #else
342 ntohs(st->st_connection->spd.this.host_port)
343 #endif
344 );
345 return (out_generic_raw(np, &isakmp_nat_d, outs,
346 hash, st->st_oakley.hasher->hash_digest_len, "NAT-D"));
347 }
348
349 /*
350 * nat_traversal_natoa_lookup()
351 *
352 * Look for NAT-OA in message
353 */
354 void nat_traversal_natoa_lookup(struct msg_digest *md)
355 {
356 struct payload_digest *p;
357 struct state *st = md->st;
358 int i;
359 ip_address ip;
360
361 if (!st || !md->iface)
362 {
363 loglog(RC_LOG_SERIOUS, "NAT-Traversal: assert failed %s:%d"
364 , __FILE__, __LINE__);
365 return;
366 }
367
368 /* Initialize NAT-OA */
369 anyaddr(AF_INET, &st->nat_oa);
370
371 /* Count NAT-OA **/
372 for (p = md->chain[ISAKMP_NEXT_NATOA_RFC], i=0; p != NULL; p = p->next, i++);
373
374 DBG(DBG_NATT,
375 DBG_log("NAT-Traversal: received %d NAT-OA.", i)
376 )
377
378 if (i == 0)
379 return;
380
381 if (!(st->nat_traversal & LELEM(NAT_TRAVERSAL_NAT_BHND_PEER)))
382 {
383 loglog(RC_LOG_SERIOUS, "NAT-Traversal: received %d NAT-OA. "
384 "ignored because peer is not NATed", i);
385 return;
386 }
387
388 if (i > 1)
389 {
390 loglog(RC_LOG_SERIOUS, "NAT-Traversal: received %d NAT-OA. "
391 "using first, ignoring others", i);
392 }
393
394 /* Take first */
395 p = md->chain[ISAKMP_NEXT_NATOA_RFC];
396
397 DBG(DBG_PARSING,
398 DBG_dump("NAT-OA:", p->pbs.start, pbs_room(&p->pbs));
399 );
400
401 switch (p->payload.nat_oa.isanoa_idtype)
402 {
403 case ID_IPV4_ADDR:
404 if (pbs_left(&p->pbs) == sizeof(struct in_addr))
405 {
406 initaddr(p->pbs.cur, pbs_left(&p->pbs), AF_INET, &ip);
407 }
408 else
409 {
410 loglog(RC_LOG_SERIOUS, "NAT-Traversal: received IPv4 NAT-OA "
411 "with invalid IP size (%d)", (int)pbs_left(&p->pbs));
412 return;
413 }
414 break;
415 case ID_IPV6_ADDR:
416 if (pbs_left(&p->pbs) == sizeof(struct in6_addr))
417 {
418 initaddr(p->pbs.cur, pbs_left(&p->pbs), AF_INET6, &ip);
419 }
420 else
421 {
422 loglog(RC_LOG_SERIOUS, "NAT-Traversal: received IPv6 NAT-OA "
423 "with invalid IP size (%d)", (int)pbs_left(&p->pbs));
424 return;
425 }
426 break;
427 default:
428 loglog(RC_LOG_SERIOUS, "NAT-Traversal: "
429 "invalid ID Type (%d) in NAT-OA - ignored",
430 p->payload.nat_oa.isanoa_idtype);
431 return;
432 }
433
434 DBG(DBG_NATT,
435 {
436 char ip_t[ADDRTOT_BUF];
437 addrtot(&ip, 0, ip_t, sizeof(ip_t));
438
439 DBG_log("received NAT-OA: %s", ip_t);
440 }
441 )
442
443 if (isanyaddr(&ip))
444 loglog(RC_LOG_SERIOUS, "NAT-Traversal: received %%any NAT-OA...");
445 else
446 st->nat_oa = ip;
447 }
448
449 bool nat_traversal_add_natoa(u_int8_t np, pb_stream *outs,
450 struct state *st)
451 {
452 struct isakmp_nat_oa natoa;
453 pb_stream pbs;
454 unsigned char ip_val[sizeof(struct in6_addr)];
455 size_t ip_len = 0;
456 ip_address *ip;
457
458 if ((!st) || (!st->st_connection))
459 {
460 loglog(RC_LOG_SERIOUS, "NAT-Traversal: assert failed %s:%d"
461 , __FILE__, __LINE__);
462 return FALSE;
463 }
464 ip = &(st->st_connection->spd.this.host_addr);
465
466 memset(&natoa, 0, sizeof(natoa));
467 natoa.isanoa_np = np;
468
469 switch (addrtypeof(ip))
470 {
471 case AF_INET:
472 ip_len = sizeof(ip->u.v4.sin_addr.s_addr);
473 memcpy(ip_val, &ip->u.v4.sin_addr.s_addr, ip_len);
474 natoa.isanoa_idtype = ID_IPV4_ADDR;
475 break;
476 case AF_INET6:
477 ip_len = sizeof(ip->u.v6.sin6_addr.s6_addr);
478 memcpy(ip_val, &ip->u.v6.sin6_addr.s6_addr, ip_len);
479 natoa.isanoa_idtype = ID_IPV6_ADDR;
480 break;
481 default:
482 loglog(RC_LOG_SERIOUS, "NAT-Traversal: "
483 "invalid addrtypeof()=%d", addrtypeof(ip));
484 return FALSE;
485 }
486
487 if (!out_struct(&natoa, &isakmp_nat_oa, outs, &pbs))
488 return FALSE;
489
490 if (!out_raw(ip_val, ip_len, &pbs, "NAT-OA"))
491 return FALSE;
492
493 DBG(DBG_NATT,
494 DBG_dump("NAT-OA (S):", ip_val, ip_len)
495 )
496
497 close_output_pbs(&pbs);
498 return TRUE;
499 }
500
501 void nat_traversal_show_result (u_int32_t nt, u_int16_t sport)
502 {
503 const char *mth = NULL, *rslt = NULL;
504
505 switch (nt & NAT_TRAVERSAL_METHOD)
506 {
507 case LELEM(NAT_TRAVERSAL_IETF_00_01):
508 mth = natt_type_bitnames[0];
509 break;
510 case LELEM(NAT_TRAVERSAL_IETF_02_03):
511 mth = natt_type_bitnames[1];
512 break;
513 case LELEM(NAT_TRAVERSAL_RFC):
514 mth = natt_type_bitnames[2];
515 break;
516 }
517
518 switch (nt & NAT_T_DETECTED)
519 {
520 case 0:
521 rslt = "no NAT detected";
522 break;
523 case LELEM(NAT_TRAVERSAL_NAT_BHND_ME):
524 rslt = "i am NATed";
525 break;
526 case LELEM(NAT_TRAVERSAL_NAT_BHND_PEER):
527 rslt = "peer is NATed";
528 break;
529 case LELEM(NAT_TRAVERSAL_NAT_BHND_ME) | LELEM(NAT_TRAVERSAL_NAT_BHND_PEER):
530 rslt = "both are NATed";
531 break;
532 }
533
534 loglog(RC_LOG_SERIOUS,
535 "NAT-Traversal: Result using %s: %s",
536 mth ? mth : "unknown method",
537 rslt ? rslt : "unknown result"
538 );
539
540 if ((nt & LELEM(NAT_TRAVERSAL_NAT_BHND_PEER))
541 && (sport == IKE_UDP_PORT)
542 && ((nt & NAT_T_WITH_PORT_FLOATING)==0))
543 {
544 loglog(RC_LOG_SERIOUS,
545 "Warning: peer is NATed but source port is still udp/%d. "
546 "Ipsec-passthrough NAT device suspected -- NAT-T may not work.",
547 IKE_UDP_PORT
548 );
549 }
550 }
551
552 int nat_traversal_espinudp_socket (int sk, u_int32_t type)
553 {
554 int r = setsockopt(sk, SOL_UDP, UDP_ESPINUDP, &type, sizeof(type));
555
556 if (r < 0 && errno == ENOPROTOOPT)
557 {
558 loglog(RC_LOG_SERIOUS,
559 "NAT-Traversal: ESPINUDP(%d) not supported by kernel -- "
560 "NAT-T disabled", type);
561 disable_nat_traversal(type);
562 }
563 return r;
564 }
565
566 void nat_traversal_new_ka_event (void)
567 {
568 if (_ka_evt)
569 return; /* event already scheduled */
570
571 event_schedule(EVENT_NAT_T_KEEPALIVE, _kap, NULL);
572 _ka_evt = 1;
573 }
574
575 static void nat_traversal_send_ka (struct state *st)
576 {
577 static unsigned char ka_payload = 0xff;
578 chunk_t sav;
579
580 DBG(DBG_NATT,
581 DBG_log("ka_event: send NAT-KA to %s:%d",
582 ip_str(&st->st_connection->spd.that.host_addr),
583 st->st_connection->spd.that.host_port);
584 )
585
586 /* save state chunk */
587 sav = st->st_tpacket;
588
589 /* send keep alive */
590 st->st_tpacket = chunk_create(&ka_payload, 1);
591 send_packet(st, "NAT-T Keep Alive");
592
593 /* restore state chunk */
594 st->st_tpacket = sav;
595 }
596
597 /**
598 * Find ISAKMP States with NAT-T and send keep-alive
599 */
600 static void nat_traversal_ka_event_state (struct state *st, void *data)
601 {
602 unsigned int *_kap_st = (unsigned int *)data;
603 const struct connection *c = st->st_connection;
604
605 if (!c)
606 return;
607
608 if ((st->st_state == STATE_MAIN_R3 || st->st_state == STATE_MAIN_I4)
609 && (st->nat_traversal & NAT_T_DETECTED)
610 && ((st->nat_traversal & LELEM(NAT_TRAVERSAL_NAT_BHND_ME)) || _force_ka))
611 {
612 /*
613 * - ISAKMP established
614 * - NAT-Traversal detected
615 * - NAT-KeepAlive needed (we are NATed)
616 */
617 if (c->newest_isakmp_sa != st->st_serialno)
618 {
619 /*
620 * if newest is also valid, ignore this one, we will only use
621 * newest.
622 */
623 struct state *st_newest;
624
625 st_newest = state_with_serialno(c->newest_isakmp_sa);
626 if (st_newest
627 && (st_newest->st_state == STATE_MAIN_R3 || st_newest->st_state == STATE_MAIN_I4)
628 && (st_newest->nat_traversal & NAT_T_DETECTED)
629 && ((st_newest->nat_traversal & LELEM(NAT_TRAVERSAL_NAT_BHND_ME)) || _force_ka))
630 {
631 return;
632 }
633 }
634 set_cur_state(st);
635 nat_traversal_send_ka(st);
636 reset_cur_state();
637 (*_kap_st)++;
638 }
639 }
640
641 void nat_traversal_ka_event (void)
642 {
643 unsigned int _kap_st = 0;
644
645 _ka_evt = 0; /* ready to be reschedule */
646
647 for_each_state((void *)nat_traversal_ka_event_state, &_kap_st);
648
649 /* if there are still states who needs Keep-Alive, schedule new event */
650 if (_kap_st)
651 nat_traversal_new_ka_event();
652 }
653
654 struct _new_mapp_nfo {
655 ip_address addr;
656 u_int16_t sport, dport;
657 };
658
659 static void nat_traversal_find_new_mapp_state (struct state *st, void *data)
660 {
661 struct connection *c = st->st_connection;
662 struct _new_mapp_nfo *nfo = (struct _new_mapp_nfo *)data;
663
664 if (c != NULL
665 && sameaddr(&c->spd.that.host_addr, &(nfo->addr))
666 && c->spd.that.host_port == nfo->sport)
667 {
668
669 /* change host port */
670 c->spd.that.host_port = nfo->dport;
671
672 if (IS_IPSEC_SA_ESTABLISHED(st->st_state)
673 || IS_ONLY_INBOUND_IPSEC_SA_ESTABLISHED(st->st_state))
674 {
675 if (!update_ipsec_sa(st))
676 {
677 /*
678 * If ipsec update failed, restore old port or we'll
679 * not be able to update anymore.
680 */
681 c->spd.that.host_port = nfo->sport;
682 }
683 }
684 }
685 }
686
687 static int nat_traversal_new_mapping(const ip_address *src, u_int16_t sport,
688 const ip_address *dst, u_int16_t dport)
689 {
690 char srca[ADDRTOT_BUF], dsta[ADDRTOT_BUF];
691 struct _new_mapp_nfo nfo;
692
693 addrtot(src, 0, srca, ADDRTOT_BUF);
694 addrtot(dst, 0, dsta, ADDRTOT_BUF);
695
696 if (!sameaddr(src, dst))
697 {
698 loglog(RC_LOG_SERIOUS, "nat_traversal_new_mapping: "
699 "address change currently not supported [%s:%d,%s:%d]",
700 srca, sport, dsta, dport);
701 return -1;
702 }
703
704 if (sport == dport)
705 {
706 /* no change */
707 return 0;
708 }
709
710 DBG_log("NAT-T: new mapping %s:%d/%d)", srca, sport, dport);
711
712 nfo.addr = *src;
713 nfo.sport = sport;
714 nfo.dport = dport;
715
716 for_each_state((void *)nat_traversal_find_new_mapp_state, &nfo);
717
718 return 0;
719 }
720
721 void nat_traversal_change_port_lookup(struct msg_digest *md, struct state *st)
722 {
723 struct connection *c = st ? st->st_connection : NULL;
724 struct iface *i = NULL;
725
726 if ((st == NULL) || (c == NULL))
727 return;
728
729 if (md)
730 {
731 /*
732 * If source port has changed, update (including other states and
733 * established kernel SA)
734 */
735 if (c->spd.that.host_port != md->sender_port)
736 {
737 nat_traversal_new_mapping(&c->spd.that.host_addr, c->spd.that.host_port,
738 &c->spd.that.host_addr, md->sender_port);
739 }
740
741 /*
742 * If interface type has changed, update local port (500/4500)
743 */
744 if ((c->spd.this.host_port == NAT_T_IKE_FLOAT_PORT && !md->iface->ike_float)
745 || (c->spd.this.host_port != NAT_T_IKE_FLOAT_PORT && md->iface->ike_float))
746 {
747 c->spd.this.host_port = (md->iface->ike_float)
748 ? NAT_T_IKE_FLOAT_PORT : pluto_port;
749
750 DBG(DBG_NATT,
751 DBG_log("NAT-T: updating local port to %d", c->spd.this.host_port);
752 );
753 }
754 }
755
756 /*
757 * If we're initiator and NAT-T (with port floating) is detected, we
758 * need to change port (MAIN_I3 or QUICK_I1)
759 */
760 if ((st->st_state == STATE_MAIN_I3 || st->st_state == STATE_QUICK_I1)
761 && (st->nat_traversal & NAT_T_WITH_PORT_FLOATING)
762 && (st->nat_traversal & NAT_T_DETECTED)
763 && (c->spd.this.host_port != NAT_T_IKE_FLOAT_PORT))
764 {
765 DBG(DBG_NATT,
766 DBG_log("NAT-T: floating to port %d", NAT_T_IKE_FLOAT_PORT);
767 )
768 c->spd.this.host_port = NAT_T_IKE_FLOAT_PORT;
769 c->spd.that.host_port = NAT_T_IKE_FLOAT_PORT;
770 /*
771 * Also update pending connections or they will be deleted if uniqueids
772 * option is set.
773 */
774 update_pending(st, st);
775 }
776
777 /*
778 * Find valid interface according to local port (500/4500)
779 */
780 if ((c->spd.this.host_port == NAT_T_IKE_FLOAT_PORT && !c->interface->ike_float)
781 || (c->spd.this.host_port != NAT_T_IKE_FLOAT_PORT && c->interface->ike_float))
782 {
783 for (i = interfaces; i != NULL; i = i->next)
784 {
785 if (sameaddr(&c->interface->addr, &i->addr)
786 && i->ike_float != c->interface->ike_float)
787 {
788 DBG(DBG_NATT,
789 DBG_log("NAT-T: using interface %s:%d", i->rname,
790 i->ike_float ? NAT_T_IKE_FLOAT_PORT : pluto_port);
791 )
792 c->interface = i;
793 break;
794 }
795 }
796 }
797 }
798
799 struct _new_klips_mapp_nfo {
800 struct sadb_sa *sa;
801 ip_address src, dst;
802 u_int16_t sport, dport;
803 };
804
805 static void nat_t_new_klips_mapp (struct state *st, void *data)
806 {
807 struct connection *c = st->st_connection;
808 struct _new_klips_mapp_nfo *nfo = (struct _new_klips_mapp_nfo *)data;
809
810 if (c != NULL && st->st_esp.present
811 && sameaddr(&c->spd.that.host_addr, &(nfo->src))
812 && st->st_esp.our_spi == nfo->sa->sadb_sa_spi)
813 {
814 nat_traversal_new_mapping(&c->spd.that.host_addr, c->spd.that.host_port,
815 &(nfo->dst), nfo->dport);
816 }
817 }
818
819 void process_pfkey_nat_t_new_mapping(
820 struct sadb_msg *msg __attribute__ ((unused)),
821 struct sadb_ext *extensions[SADB_EXT_MAX + 1])
822 {
823 struct _new_klips_mapp_nfo nfo;
824 struct sadb_address *srcx = (void *) extensions[SADB_EXT_ADDRESS_SRC];
825 struct sadb_address *dstx = (void *) extensions[SADB_EXT_ADDRESS_DST];
826 struct sockaddr *srca, *dsta;
827 err_t ugh = NULL;
828
829 nfo.sa = (void *) extensions[SADB_EXT_SA];
830
831 if (!nfo.sa || !srcx || !dstx)
832 {
833 plog("SADB_X_NAT_T_NEW_MAPPING message from KLIPS malformed: "
834 "got NULL params");
835 return;
836 }
837
838 srca = ((struct sockaddr *)(void *)&srcx[1]);
839 dsta = ((struct sockaddr *)(void *)&dstx[1]);
840
841 if (srca->sa_family != AF_INET || dsta->sa_family != AF_INET)
842 {
843 ugh = "only AF_INET supported";
844 }
845 else
846 {
847 char text_said[SATOT_BUF];
848 char _srca[ADDRTOT_BUF], _dsta[ADDRTOT_BUF];
849 ip_said said;
850
851 initaddr((const void *) &((const struct sockaddr_in *)srca)->sin_addr,
852 sizeof(((const struct sockaddr_in *)srca)->sin_addr),
853 srca->sa_family, &(nfo.src));
854 nfo.sport = ntohs(((const struct sockaddr_in *)srca)->sin_port);
855 initaddr((const void *) &((const struct sockaddr_in *)dsta)->sin_addr,
856 sizeof(((const struct sockaddr_in *)dsta)->sin_addr),
857 dsta->sa_family, &(nfo.dst));
858 nfo.dport = ntohs(((const struct sockaddr_in *)dsta)->sin_port);
859
860 DBG(DBG_NATT,
861 initsaid(&nfo.src, nfo.sa->sadb_sa_spi, SA_ESP, &said);
862 satot(&said, 0, text_said, SATOT_BUF);
863 addrtot(&nfo.src, 0, _srca, ADDRTOT_BUF);
864 addrtot(&nfo.dst, 0, _dsta, ADDRTOT_BUF);
865 DBG_log("new klips mapping %s %s:%d %s:%d",
866 text_said, _srca, nfo.sport, _dsta, nfo.dport);
867 )
868
869 for_each_state((void *)nat_t_new_klips_mapp, &nfo);
870 }
871
872 if (ugh != NULL)
873 plog("SADB_X_NAT_T_NEW_MAPPING message from KLIPS malformed: %s", ugh);
874 }
875