2 * Copyright (C) 2008-2009 Tobias Brunner
3 * Hochschule fuer Technik Rapperswil
4 * Copyright (C) 2010 Martin Willi
5 * Copyright (C) 2010 revosec AG
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 #include "kernel_interface.h"
22 typedef struct private_kernel_interface_t private_kernel_interface_t
;
25 * Private data of a kernel_interface_t object.
27 struct private_kernel_interface_t
{
30 * Public part of kernel_interface_t object.
32 kernel_interface_t
public;
37 kernel_ipsec_t
*ipsec
;
45 METHOD(kernel_interface_t
, get_spi
, status_t
,
46 private_kernel_interface_t
*this, host_t
*src
, host_t
*dst
,
47 protocol_id_t protocol
, u_int32_t reqid
, u_int32_t
*spi
)
53 return this->ipsec
->get_spi(this->ipsec
, src
, dst
, protocol
, reqid
, spi
);
56 METHOD(kernel_interface_t
, get_cpi
, status_t
,
57 private_kernel_interface_t
*this, host_t
*src
, host_t
*dst
,
58 u_int32_t reqid
, u_int16_t
*cpi
)
64 return this->ipsec
->get_cpi(this->ipsec
, src
, dst
, reqid
, cpi
);
67 METHOD(kernel_interface_t
, add_sa
, status_t
,
68 private_kernel_interface_t
*this, host_t
*src
, host_t
*dst
,
69 u_int32_t spi
, protocol_id_t protocol
, u_int32_t reqid
,
70 mark_t mark
, lifetime_cfg_t
*lifetime
, u_int16_t enc_alg
, chunk_t enc_key
,
71 u_int16_t int_alg
, chunk_t int_key
, ipsec_mode_t mode
, u_int16_t ipcomp
,
72 u_int16_t cpi
, bool encap
, bool inbound
, traffic_selector_t
*src_ts
,
73 traffic_selector_t
*dst_ts
)
79 return this->ipsec
->add_sa(this->ipsec
, src
, dst
, spi
, protocol
, reqid
,
80 mark
, lifetime
, enc_alg
, enc_key
, int_alg
, int_key
, mode
, ipcomp
,
81 cpi
, encap
, inbound
, src_ts
, dst_ts
);
84 METHOD(kernel_interface_t
, update_sa
, status_t
,
85 private_kernel_interface_t
*this, u_int32_t spi
, protocol_id_t protocol
,
86 u_int16_t cpi
, host_t
*src
, host_t
*dst
, host_t
*new_src
, host_t
*new_dst
,
87 bool encap
, bool new_encap
, mark_t mark
)
93 return this->ipsec
->update_sa(this->ipsec
, spi
, protocol
, cpi
, src
, dst
,
94 new_src
, new_dst
, encap
, new_encap
, mark
);
97 METHOD(kernel_interface_t
, query_sa
, status_t
,
98 private_kernel_interface_t
*this, host_t
*src
, host_t
*dst
,
99 u_int32_t spi
, protocol_id_t protocol
, mark_t mark
, u_int64_t
*bytes
)
103 return NOT_SUPPORTED
;
105 return this->ipsec
->query_sa(this->ipsec
, src
, dst
, spi
, protocol
, mark
, bytes
);
108 METHOD(kernel_interface_t
, del_sa
, status_t
,
109 private_kernel_interface_t
*this, host_t
*src
, host_t
*dst
, u_int32_t spi
,
110 protocol_id_t protocol
, u_int16_t cpi
, mark_t mark
)
114 return NOT_SUPPORTED
;
116 return this->ipsec
->del_sa(this->ipsec
, src
, dst
, spi
, protocol
, cpi
, mark
);
119 METHOD(kernel_interface_t
, add_policy
, status_t
,
120 private_kernel_interface_t
*this, host_t
*src
, host_t
*dst
,
121 traffic_selector_t
*src_ts
, traffic_selector_t
*dst_ts
,
122 policy_dir_t direction
, u_int32_t spi
, protocol_id_t protocol
,
123 u_int32_t reqid
, mark_t mark
, ipsec_mode_t mode
, u_int16_t ipcomp
,
124 u_int16_t cpi
, bool routed
)
128 return NOT_SUPPORTED
;
130 return this->ipsec
->add_policy(this->ipsec
, src
, dst
, src_ts
, dst_ts
,
131 direction
, spi
, protocol
, reqid
, mark
, mode
, ipcomp
, cpi
, routed
);
134 METHOD(kernel_interface_t
, query_policy
, status_t
,
135 private_kernel_interface_t
*this, traffic_selector_t
*src_ts
,
136 traffic_selector_t
*dst_ts
, policy_dir_t direction
, mark_t mark
,
141 return NOT_SUPPORTED
;
143 return this->ipsec
->query_policy(this->ipsec
, src_ts
, dst_ts
,
144 direction
, mark
, use_time
);
147 METHOD(kernel_interface_t
, del_policy
, status_t
,
148 private_kernel_interface_t
*this, traffic_selector_t
*src_ts
,
149 traffic_selector_t
*dst_ts
, policy_dir_t direction
, mark_t mark
,
154 return NOT_SUPPORTED
;
156 return this->ipsec
->del_policy(this->ipsec
, src_ts
, dst_ts
,
157 direction
, mark
, unrouted
);
160 METHOD(kernel_interface_t
, get_source_addr
, host_t
*,
161 private_kernel_interface_t
*this, host_t
*dest
, host_t
*src
)
167 return this->net
->get_source_addr(this->net
, dest
, src
);
170 METHOD(kernel_interface_t
, get_nexthop
, host_t
*,
171 private_kernel_interface_t
*this, host_t
*dest
)
177 return this->net
->get_nexthop(this->net
, dest
);
180 METHOD(kernel_interface_t
, get_interface
, char*,
181 private_kernel_interface_t
*this, host_t
*host
)
187 return this->net
->get_interface(this->net
, host
);
190 METHOD(kernel_interface_t
, create_address_enumerator
, enumerator_t
*,
191 private_kernel_interface_t
*this, bool include_down_ifaces
,
192 bool include_virtual_ips
)
196 return enumerator_create_empty();
198 return this->net
->create_address_enumerator(this->net
, include_down_ifaces
,
199 include_virtual_ips
);
202 METHOD(kernel_interface_t
, add_ip
, status_t
,
203 private_kernel_interface_t
*this, host_t
*virtual_ip
, host_t
*iface_ip
)
207 return NOT_SUPPORTED
;
209 return this->net
->add_ip(this->net
, virtual_ip
, iface_ip
);
212 METHOD(kernel_interface_t
, del_ip
, status_t
,
213 private_kernel_interface_t
*this, host_t
*virtual_ip
)
217 return NOT_SUPPORTED
;
219 return this->net
->del_ip(this->net
, virtual_ip
);
222 METHOD(kernel_interface_t
, add_route
, status_t
,
223 private_kernel_interface_t
*this, chunk_t dst_net
,
224 u_int8_t prefixlen
, host_t
*gateway
, host_t
*src_ip
, char *if_name
)
228 return NOT_SUPPORTED
;
230 return this->net
->add_route(this->net
, dst_net
, prefixlen
, gateway
,
234 METHOD(kernel_interface_t
, del_route
, status_t
,
235 private_kernel_interface_t
*this, chunk_t dst_net
,
236 u_int8_t prefixlen
, host_t
*gateway
, host_t
*src_ip
, char *if_name
)
240 return NOT_SUPPORTED
;
242 return this->net
->del_route(this->net
, dst_net
, prefixlen
, gateway
,
246 METHOD(kernel_interface_t
, bypass_socket
, bool,
247 private_kernel_interface_t
*this, int fd
, int family
)
253 return this->ipsec
->bypass_socket(this->ipsec
, fd
, family
);
256 METHOD(kernel_interface_t
, get_address_by_ts
, status_t
,
257 private_kernel_interface_t
*this, traffic_selector_t
*ts
, host_t
**ip
)
264 DBG2(DBG_KNL
, "getting a local address in traffic selector %R", ts
);
266 /* if we have a family which includes localhost, we do not
267 * search for an IP, we use the default */
268 family
= ts
->get_type(ts
) == TS_IPV4_ADDR_RANGE ? AF_INET
: AF_INET6
;
270 if (family
== AF_INET
)
272 host
= host_create_from_string("127.0.0.1", 0);
276 host
= host_create_from_string("::1", 0);
279 if (ts
->includes(ts
, host
))
281 *ip
= host_create_any(family
);
283 DBG2(DBG_KNL
, "using host %H", *ip
);
288 addrs
= create_address_enumerator(this, TRUE
, TRUE
);
289 while (addrs
->enumerate(addrs
, (void**)&host
))
291 if (ts
->includes(ts
, host
))
294 *ip
= host
->clone(host
);
298 addrs
->destroy(addrs
);
302 DBG1(DBG_KNL
, "no local address found in traffic selector %R", ts
);
306 DBG2(DBG_KNL
, "using host %H", *ip
);
311 METHOD(kernel_interface_t
, add_ipsec_interface
, void,
312 private_kernel_interface_t
*this, kernel_ipsec_constructor_t constructor
)
316 this->ipsec
= constructor();
320 METHOD(kernel_interface_t
, remove_ipsec_interface
, void,
321 private_kernel_interface_t
*this, kernel_ipsec_constructor_t constructor
)
323 /* TODO: replace if interface currently in use */
326 METHOD(kernel_interface_t
, add_net_interface
, void,
327 private_kernel_interface_t
*this, kernel_net_constructor_t constructor
)
331 this->net
= constructor();
335 METHOD(kernel_interface_t
, remove_net_interface
, void,
336 private_kernel_interface_t
*this, kernel_net_constructor_t constructor
)
338 /* TODO: replace if interface currently in use */
341 METHOD(kernel_interface_t
, destroy
, void,
342 private_kernel_interface_t
*this)
344 DESTROY_IF(this->ipsec
);
345 DESTROY_IF(this->net
);
350 * Described in header-file
352 kernel_interface_t
*kernel_interface_create()
354 private_kernel_interface_t
*this;
361 .update_sa
= _update_sa
,
362 .query_sa
= _query_sa
,
364 .add_policy
= _add_policy
,
365 .query_policy
= _query_policy
,
366 .del_policy
= _del_policy
,
367 .get_source_addr
= _get_source_addr
,
368 .get_nexthop
= _get_nexthop
,
369 .get_interface
= _get_interface
,
370 .create_address_enumerator
= _create_address_enumerator
,
373 .add_route
= _add_route
,
374 .del_route
= _del_route
,
375 .bypass_socket
= _bypass_socket
,
377 .get_address_by_ts
= _get_address_by_ts
,
378 .add_ipsec_interface
= _add_ipsec_interface
,
379 .remove_ipsec_interface
= _remove_ipsec_interface
,
380 .add_net_interface
= _add_net_interface
,
381 .remove_net_interface
= _remove_net_interface
,
386 return &this->public;