4 #include <sys/socket.h>
5 #include <netinet/in.h>
13 #include "isakmp_var.h"
18 #include "isakmp_natd.h"
22 struct ph1handle
* iph1
,
23 struct isakmp_gen
*natd_record
)
25 natd_match_t matches
= 0;
27 int dataLen
= ntohs(natd_record
->len
) - sizeof(*natd_record
);
28 char* dataPtr
= ((char*)natd_record
) + sizeof(*natd_record
);
30 /* Always recreate the natd records in case the ports change */
33 if (iph1
->local_natd
!= NULL
&& dataLen
== iph1
->local_natd
->l
&&
34 memcmp(dataPtr
, iph1
->local_natd
->v
, dataLen
) == 0)
36 plog(LLV_DEBUG
, LOCATION
, iph1
->remote
,
37 "natd payload matches local address\n");
38 matches
|= natd_match_local
;
41 if (iph1
->remote_natd
!= NULL
&& dataLen
== iph1
->remote_natd
->l
&&
42 memcmp(dataPtr
, iph1
->remote_natd
->v
, dataLen
) == 0)
44 plog(LLV_DEBUG
, LOCATION
, iph1
->remote
,
45 "natd payload matches remote address\n");
46 matches
|= natd_match_remote
;
49 matches
= natd_match_local
| natd_match_remote
;
54 plog(LLV_DEBUG
, LOCATION
, iph1
->remote
,
55 "natd payload matches no address\n");
62 * NAT detection record contains a hash of the initiator cookie,
63 * responder cookie, address, and port.
66 cookie_t initiator_cookie
;
67 cookie_t responder_cookie
;
68 struct in_addr address
;
70 } __attribute__((__packed__
)) natd_hash_contents
;
74 struct ph1handle
* iph1
)
77 natd_hash_contents hash_this
;
80 if (iph1
->remote
->sa_family
!= AF_INET
||
81 iph1
->local
->sa_family
!= AF_INET
)
84 * NAT traversal is intentionally unsupported on IPv6.
89 data_to_hash
.l
= sizeof(hash_this
);
90 data_to_hash
.v
= (char*)&hash_this
;
92 memcpy(hash_this
.initiator_cookie
, iph1
->index
.i_ck
,
93 sizeof(hash_this
.initiator_cookie
));
94 memcpy(hash_this
.responder_cookie
, iph1
->index
.r_ck
,
95 sizeof(hash_this
.responder_cookie
));
98 if (iph1
->local_natd
!= NULL
)
99 vfree(iph1
->local_natd
);
100 iph1
->local_natd
= NULL
;
101 hash_this
.address
= ((struct sockaddr_in
*)(iph1
->local
))->sin_addr
;
102 hash_this
.port
= ((struct sockaddr_in
*)(iph1
->local
))->sin_port
;
103 plog(LLV_DEBUG
, LOCATION
, iph1
->remote
,
104 "creating local %.8X%.8X:%.8X%.8X %s:%d\n",
105 *(u_long
*)&hash_this
.initiator_cookie
[0],
106 *(u_long
*)&hash_this
.initiator_cookie
[4],
107 *(u_long
*)&hash_this
.responder_cookie
[0],
108 *(u_long
*)&hash_this
.responder_cookie
[4],
109 inet_ntoa(hash_this
.address
), hash_this
.port
);
110 iph1
->local_natd
= oakley_hash(&data_to_hash
, iph1
);
111 plogdump(LLV_DEBUG
, iph1
->local_natd
->v
, iph1
->local_natd
->l
);
114 if (iph1
->remote_natd
!= NULL
)
115 vfree(iph1
->remote_natd
);
116 iph1
->remote_natd
= NULL
;
117 hash_this
.address
= ((struct sockaddr_in
*)(iph1
->remote
))->sin_addr
;
118 hash_this
.port
= ((struct sockaddr_in
*)(iph1
->remote
))->sin_port
;
119 plog(LLV_DEBUG
, LOCATION
, iph1
->remote
,
120 "creating remote %.8X%.8X:%.8X%.8X %s:%d\n",
121 *(u_long
*)&hash_this
.initiator_cookie
[0],
122 *(u_long
*)&hash_this
.initiator_cookie
[4],
123 *(u_long
*)&hash_this
.responder_cookie
[0],
124 *(u_long
*)&hash_this
.responder_cookie
[4],
125 inet_ntoa(hash_this
.address
), hash_this
.port
);
126 iph1
->remote_natd
= oakley_hash(&data_to_hash
, iph1
);
127 plogdump(LLV_DEBUG
, iph1
->remote_natd
->v
, iph1
->remote_natd
->l
);
129 return (iph1
->local_natd
!= NULL
) && (iph1
->remote_natd
!= NULL
);
135 /* returns the natt type - or 0 if no natt */
138 const struct ph1handle
* iph1
)
141 if ((iph1
->natt_flags
& natt_natd_received
) &&
142 ((iph1
->natt_flags
& (natt_no_remote_nat
| natt_no_local_nat
)) !=
143 (natt_no_remote_nat
| natt_no_local_nat
)))
144 return iph1
->natt_flags
& NATT_TYPE_MASK
;
153 natt_select_type(struct ph1handle
* iph1
)
156 int flags
= iph1
->natt_flags
;
158 if ((flags
& NATT_TYPE_MASK
) == 0) {
159 iph1
->natd_payload_type
= 0;
163 iph1
->natt_flags
&= ~NATT_TYPE_MASK
; // clear natt type flags
165 /* set the type we prefer */
166 if (flags
& natt_type_rfc
) {
167 iph1
->natt_flags
|= natt_type_rfc
;
168 iph1
->natd_payload_type
= ISAKMP_NPTYPE_NATD_RFC
;
169 plog(LLV_DEBUG
, LOCATION
, NULL
,
170 "choosing natt type RFC\n");
172 } else if (flags
& natt_type_apple
) {
173 iph1
->natt_flags
|= natt_type_apple
;
174 iph1
->natd_payload_type
= ISAKMP_NPTYPE_NATD_BADDRAFT
;
175 plog(LLV_DEBUG
, LOCATION
, NULL
,
176 "choosing natt type APPLE\n");
178 iph1
->natd_payload_type
= ISAKMP_NPTYPE_NATD_DRAFT
;
179 if (flags
& natt_type_02
) {
180 iph1
->natt_flags
|= natt_type_02
;
181 plog(LLV_DEBUG
, LOCATION
, NULL
,
182 "choosing natt type 02\n");
184 iph1
->natt_flags
|= natt_type_02N
;
185 plog(LLV_DEBUG
, LOCATION
, NULL
,
186 "choosing natt type 02N\n");