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