1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
|
--- src/libipsec/libpfkey.h
+++ src/libipsec/libpfkey.h
@@ -85,7 +85,7 @@ struct pfkey_send_sa_args {
u_int32_t seq;
u_int8_t l_natt_type;
u_int16_t l_natt_sport, l_natt_dport;
- struct sockaddr *l_natt_oa;
+ struct sockaddr *l_natt_oai, *l_natt_oar;
u_int16_t l_natt_frag;
u_int8_t ctxdoi, ctxalg; /* Security context DOI and algorithm */
caddr_t ctxstr; /* Security context string */
--- src/libipsec/pfkey.c
+++ src/libipsec/pfkey.c
@@ -1335,9 +1335,12 @@ pfkey_send_x1(struct pfkey_send_sa_args
len += sizeof(struct sadb_x_nat_t_type);
len += sizeof(struct sadb_x_nat_t_port);
len += sizeof(struct sadb_x_nat_t_port);
- if (sa_parms->l_natt_oa)
+ if (sa_parms->l_natt_oai)
len += sizeof(struct sadb_address) +
- PFKEY_ALIGN8(sysdep_sa_len(sa_parms->l_natt_oa));
+ PFKEY_ALIGN8(sysdep_sa_len(sa_parms->l_natt_oai));
+ if (sa_parms->l_natt_oar)
+ len += sizeof(struct sadb_address) +
+ PFKEY_ALIGN8(sysdep_sa_len(sa_parms->l_natt_oar));
#ifdef SADB_X_EXT_NAT_T_FRAG
if (sa_parms->l_natt_frag)
len += sizeof(struct sadb_x_nat_t_frag);
@@ -1452,10 +1455,21 @@ pfkey_send_x1(struct pfkey_send_sa_args
return -1;
}
- if (sa_parms->l_natt_oa) {
- p = pfkey_setsadbaddr(p, ep, SADB_X_EXT_NAT_T_OA,
- sa_parms->l_natt_oa,
- (u_int)PFKEY_ALIGN8(sysdep_sa_len(sa_parms->l_natt_oa)),
+ if (sa_parms->l_natt_oai) {
+ p = pfkey_setsadbaddr(p, ep, SADB_X_EXT_NAT_T_OAI,
+ sa_parms->l_natt_oai,
+ (u_int)PFKEY_ALIGN8(sysdep_sa_len(sa_parms->l_natt_oai)),
+ IPSEC_ULPROTO_ANY);
+ if (!p) {
+ free(newmsg);
+ return -1;
+ }
+ }
+
+ if (sa_parms->l_natt_oar) {
+ p = pfkey_setsadbaddr(p, ep, SADB_X_EXT_NAT_T_OAR,
+ sa_parms->l_natt_oar,
+ (u_int)PFKEY_ALIGN8(sysdep_sa_len(sa_parms->l_natt_oar)),
IPSEC_ULPROTO_ANY);
if (!p) {
free(newmsg);
@@ -2034,7 +2048,8 @@ pfkey_align(struct sadb_msg *msg, caddr_
case SADB_X_EXT_NAT_T_TYPE:
case SADB_X_EXT_NAT_T_SPORT:
case SADB_X_EXT_NAT_T_DPORT:
- case SADB_X_EXT_NAT_T_OA:
+ case SADB_X_EXT_NAT_T_OAI:
+ case SADB_X_EXT_NAT_T_OAR:
#endif
#ifdef SADB_X_EXT_TAG
case SADB_X_EXT_TAG:
@@ -2592,7 +2607,7 @@ pfkey_send_update_nat(int so, u_int saty
psaa.l_natt_type = l_natt_type;
psaa.l_natt_sport = l_natt_sport;
psaa.l_natt_dport = l_natt_dport;
- psaa.l_natt_oa = l_natt_oa;
+ psaa.l_natt_oar = l_natt_oa;
psaa.l_natt_frag = l_natt_frag;
return pfkey_send_update2(&psaa);
@@ -2667,7 +2682,7 @@ pfkey_send_add_nat(int so, u_int satype,
psaa.l_natt_type = l_natt_type;
psaa.l_natt_sport = l_natt_sport;
psaa.l_natt_dport = l_natt_dport;
- psaa.l_natt_oa = l_natt_oa;
+ psaa.l_natt_oai = l_natt_oa;
psaa.l_natt_frag = l_natt_frag;
return pfkey_send_add2(&psaa);
--- src/racoon/isakmp_quick.c
+++ src/racoon/isakmp_quick.c
@@ -2390,6 +2390,34 @@
spidx.src.ss_family, spidx.dst.ss_family,
_XIDT(iph2->id_p),idi2type);
}
+#ifdef ENABLE_NATT
+ if (iph2->ph1->natt_flags & NAT_DETECTED_PEER
+ && _XIDT(iph2->id) != IPSECDOI_ID_IPV4_ADDR_SUBNET
+ && _XIDT(iph2->id) != IPSECDOI_ID_IPV6_ADDR_SUBNET) {
+ u_int16_t port;
+
+ port = extract_port(&spidx.src);
+ memcpy(&spidx.src, iph2->ph1->remote,
+ sysdep_sa_len(iph2->ph1->remote));
+ set_port(&spidx.src, port);
+ switch (spidx.src.ss_family) {
+ case AF_INET:
+ spidx.prefs = sizeof(struct in_addr) << 3;
+ break;
+#ifdef INET6
+ case AF_INET6:
+ spidx.prefs = sizeof(struct in6_addr) << 3;
+ break;
+#endif
+ default:
+ spidx.prefs = 0;
+ break;
+ }
+ plog(LLV_DEBUG, LOCATION,
+ NULL, "use NAT address %s as src\n",
+ saddr2str((struct sockaddr *)&spidx.src));
+ }
+#endif
} else {
plog(LLV_DEBUG, LOCATION, NULL,
"get a source address of SP index from Phase 1"
--- src/racoon/nattraversal.c
+++ src/racoon/nattraversal.c
@@ -436,10 +436,7 @@ natt_keepalive_add_ph1 (struct ph1handle
{
int ret = 0;
- /* Should only the NATed host send keepalives?
- If yes, add '(iph1->natt_flags & NAT_DETECTED_ME)'
- to the following condition. */
- if (iph1->natt_flags & NAT_DETECTED &&
+ if (iph1->natt_flags & NAT_DETECTED_ME &&
! (iph1->natt_flags & NAT_KA_QUEUED)) {
ret = natt_keepalive_add (iph1->local, iph1->remote);
if (ret == 0)
--- src/racoon/pfkey.c
+++ src/racoon/pfkey.c
@@ -1190,7 +1190,10 @@ pk_sendupdate(iph2)
sa_args.l_natt_type = iph2->ph1->natt_options->encaps_type;
sa_args.l_natt_sport = extract_port(iph2->ph1->remote);
sa_args.l_natt_dport = extract_port(iph2->ph1->local);
- sa_args.l_natt_oa = iph2->natoa_src;
+ /* if (iph2->ph1->natt_flags & NAT_DETECTED_PEER) */
+ sa_args.l_natt_oai = iph2->natoa_dst;
+ /* if (iph2->ph1->natt_flags & NAT_DETECTED_ME) */
+ sa_args.l_natt_oar = iph2->natoa_src;
#ifdef SADB_X_EXT_NAT_T_FRAG
sa_args.l_natt_frag = iph2->ph1->rmconf->esp_frag;
#endif
@@ -1477,7 +1480,6 @@ pk_sendadd(iph2)
sa_args.l_natt_type = UDP_ENCAP_ESPINUDP;
sa_args.l_natt_sport = extract_port(iph2->ph1->local);
sa_args.l_natt_dport = extract_port(iph2->ph1->remote);
- sa_args.l_natt_oa = iph2->natoa_dst;
#ifdef SADB_X_EXT_NAT_T_FRAG
sa_args.l_natt_frag = iph2->ph1->rmconf->esp_frag;
#endif
|