summaryrefslogtreecommitdiff
path: root/src/charon/config
diff options
context:
space:
mode:
authorRene Mayrhofer <rene@mayrhofer.eu.org>2008-12-05 16:15:54 +0000
committerRene Mayrhofer <rene@mayrhofer.eu.org>2008-12-05 16:15:54 +0000
commitc7f1b0530b85bc7654e68992f25ed8ced5d0a80d (patch)
tree861798cd7da646014ed6919766b053099646710d /src/charon/config
parent8b80ab5a6950ce6515f477624794defd7531642a (diff)
downloadvyos-strongswan-c7f1b0530b85bc7654e68992f25ed8ced5d0a80d.tar.gz
vyos-strongswan-c7f1b0530b85bc7654e68992f25ed8ced5d0a80d.zip
[svn-upgrade] Integrating new upstream version, strongswan (4.2.9)
Diffstat (limited to 'src/charon/config')
-rw-r--r--src/charon/config/backend_manager.c19
-rw-r--r--src/charon/config/child_cfg.c99
-rw-r--r--src/charon/config/child_cfg.h41
-rw-r--r--src/charon/config/peer_cfg.c60
-rw-r--r--src/charon/config/proposal.c2
-rw-r--r--src/charon/config/traffic_selector.c109
-rw-r--r--src/charon/config/traffic_selector.h28
7 files changed, 276 insertions, 82 deletions
diff --git a/src/charon/config/backend_manager.c b/src/charon/config/backend_manager.c
index c2b408ca9..3f92ee96a 100644
--- a/src/charon/config/backend_manager.c
+++ b/src/charon/config/backend_manager.c
@@ -12,7 +12,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * $Id: backend_manager.c 4134 2008-07-01 11:10:37Z martin $
+ * $Id: backend_manager.c 4610 2008-11-11 06:19:37Z andreas $
*/
#include "backend_manager.h"
@@ -175,7 +175,7 @@ static ike_cfg_t *get_ike_cfg(private_backend_manager_t *this,
data->me = me;
data->other = other;
- DBG2(DBG_CFG, "looking for a config for %H...%H", me, other);
+ DBG2(DBG_CFG, "looking for an ike config for %H...%H", me, other);
this->mutex->lock(this->mutex);
enumerator = enumerator_create_nested(
@@ -188,8 +188,8 @@ static ike_cfg_t *get_ike_cfg(private_backend_manager_t *this,
if (match)
{
DBG2(DBG_CFG, " candidate: %s...%s, prio %d",
- current->get_my_addr(current), current->get_other_addr(current),
- match);
+ current->get_my_addr(current),
+ current->get_other_addr(current), match);
if (match > best)
{
DESTROY_IF(found);
@@ -201,6 +201,11 @@ static ike_cfg_t *get_ike_cfg(private_backend_manager_t *this,
}
enumerator->destroy(enumerator);
this->mutex->unlock(this->mutex);
+ if (found)
+ {
+ DBG2(DBG_CFG, "found matching ike config: %s...%s with prio %d",
+ found->get_my_addr(found), found->get_other_addr(found), best);
+ }
return found;
}
@@ -227,7 +232,7 @@ static peer_cfg_t *get_peer_cfg(private_backend_manager_t *this, host_t *me,
ike_cfg_match_t best_ike = MATCH_NONE;
peer_data_t *data;
- DBG2(DBG_CFG, "looking for a config for %H[%D]...%H[%D]",
+ DBG2(DBG_CFG, "looking for a peer config for %H[%D]...%H[%D]",
me, my_id, other, other_id);
data = malloc_thing(peer_data_t);
@@ -262,7 +267,7 @@ static peer_cfg_t *get_peer_cfg(private_backend_manager_t *this, host_t *me,
if (m1 && m2 && match_ike &&
auth->complies(auth, current->get_auth(current)))
{
- DBG2(DBG_CFG, " candidate '%s': %D...%D, prio %d.%d",
+ DBG2(DBG_CFG, " candidate \"%s\": %D...%D with prio %d.%d",
current->get_name(current), my_cand, other_cand,
match_peer, match_ike);
if (match_peer >= best_peer && match_ike > best_ike)
@@ -277,7 +282,7 @@ static peer_cfg_t *get_peer_cfg(private_backend_manager_t *this, host_t *me,
}
if (found)
{
- DBG1(DBG_CFG, "found matching config \"%s\": %D...%D, prio %d.%d",
+ DBG1(DBG_CFG, "found matching peer config \"%s\": %D...%D with prio %d.%d",
found->get_name(found), found->get_my_id(found),
found->get_other_id(found), best_peer, best_ike);
}
diff --git a/src/charon/config/child_cfg.c b/src/charon/config/child_cfg.c
index 24242345b..ab083b212 100644
--- a/src/charon/config/child_cfg.c
+++ b/src/charon/config/child_cfg.c
@@ -14,7 +14,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * $Id: child_cfg.c 4358 2008-09-25 13:56:23Z tobias $
+ * $Id: child_cfg.c 4611 2008-11-11 06:29:25Z andreas $
*/
#include "child_cfg.h"
@@ -118,10 +118,20 @@ struct private_child_cfg_t {
* enable IPComp
*/
bool use_ipcomp;
+
+ /**
+ * set up IPsec transport SA in MIPv6 proxy mode
+ */
+ bool proxy_mode;
+
+ /**
+ * enable installation and removal of kernel IPsec policies
+ */
+ bool install_policy;
};
/**
- * Implementation of child_cfg_t.get_name
+ * Implementation of child_cfg_t.get_name.
*/
static char *get_name(private_child_cfg_t *this)
{
@@ -129,7 +139,7 @@ static char *get_name(private_child_cfg_t *this)
}
/**
- * Implementation of child_cfg_t.add_proposal
+ * Implementation of child_cfg_t.add_proposal.
*/
static void add_proposal(private_child_cfg_t *this, proposal_t *proposal)
{
@@ -137,7 +147,7 @@ static void add_proposal(private_child_cfg_t *this, proposal_t *proposal)
}
/**
- * Implementation of child_cfg_t.get_proposals
+ * Implementation of child_cfg_t.get_proposals.
*/
static linked_list_t* get_proposals(private_child_cfg_t *this, bool strip_dh)
{
@@ -161,7 +171,7 @@ static linked_list_t* get_proposals(private_child_cfg_t *this, bool strip_dh)
}
/**
- * Implementation of child_cfg_t.get_name
+ * Implementation of child_cfg_t.select_proposal.
*/
static proposal_t* select_proposal(private_child_cfg_t*this,
linked_list_t *proposals, bool strip_dh)
@@ -210,7 +220,7 @@ static proposal_t* select_proposal(private_child_cfg_t*this,
}
/**
- * Implementation of child_cfg_t.get_name
+ * Implementation of child_cfg_t.add_traffic_selector.
*/
static void add_traffic_selector(private_child_cfg_t *this, bool local,
traffic_selector_t *ts)
@@ -226,7 +236,7 @@ static void add_traffic_selector(private_child_cfg_t *this, bool local,
}
/**
- * Implementation of child_cfg_t.get_name
+ * Implementation of child_cfg_t.get_traffic_selectors.
*/
static linked_list_t* get_traffic_selectors(private_child_cfg_t *this, bool local,
linked_list_t *supplied,
@@ -337,7 +347,36 @@ static linked_list_t* get_traffic_selectors(private_child_cfg_t *this, bool loca
}
/**
- * Implementation of child_cfg_t.get_name
+ * Implementation of child_cfg_t.equal_traffic_selectors.
+ */
+bool equal_traffic_selectors(private_child_cfg_t *this, bool local,
+ linked_list_t *ts_list, host_t *host)
+{
+ linked_list_t *this_list;
+ traffic_selector_t *this_ts, *ts;
+ bool result;
+
+ this_list = (local) ? this->my_ts : this->other_ts;
+
+ /* currently equality is established for single traffic selectors only */
+ if (this_list->get_count(this_list) != 1 || ts_list->get_count(ts_list) != 1)
+ {
+ return FALSE;
+ }
+
+ this_list->get_first(this_list, (void**)&this_ts);
+ this_ts = this_ts->clone(this_ts);
+ this_ts->set_address(this_ts, host);
+ ts_list->get_first(ts_list, (void**)&ts);
+
+ result = ts->equals(ts, this_ts);
+
+ this_ts->destroy(this_ts);
+ return result;
+}
+
+/**
+ * Implementation of child_cfg_t.get_updown.
*/
static char* get_updown(private_child_cfg_t *this)
{
@@ -345,7 +384,7 @@ static char* get_updown(private_child_cfg_t *this)
}
/**
- * Implementation of child_cfg_t.get_name
+ * Implementation of child_cfg_t.get_hostaccess.
*/
static bool get_hostaccess(private_child_cfg_t *this)
{
@@ -353,7 +392,7 @@ static bool get_hostaccess(private_child_cfg_t *this)
}
/**
- * Implementation of child_cfg_t.get_name
+ * Implementation of child_cfg_t.get_lifetime.
*/
static u_int32_t get_lifetime(private_child_cfg_t *this, bool rekey)
{
@@ -369,7 +408,7 @@ static u_int32_t get_lifetime(private_child_cfg_t *this, bool rekey)
}
/**
- * Implementation of child_cfg_t.get_mode
+ * Implementation of child_cfg_t.get_mode.
*/
static ipsec_mode_t get_mode(private_child_cfg_t *this)
{
@@ -377,7 +416,7 @@ static ipsec_mode_t get_mode(private_child_cfg_t *this)
}
/**
- * Implementation of child_cfg_t.get_dpd_action
+ * Implementation of child_cfg_t.get_dpd_action.
*/
static action_t get_dpd_action(private_child_cfg_t *this)
{
@@ -385,7 +424,7 @@ static action_t get_dpd_action(private_child_cfg_t *this)
}
/**
- * Implementation of child_cfg_t.get_close_action
+ * Implementation of child_cfg_t.get_close_action.
*/
static action_t get_close_action(private_child_cfg_t *this)
{
@@ -422,7 +461,33 @@ static bool use_ipcomp(private_child_cfg_t *this)
}
/**
- * Implementation of child_cfg_t.get_name
+ * Implementation of child_cfg_t.set_mipv6_options.
+ */
+static void set_mipv6_options(private_child_cfg_t *this, bool proxy_mode,
+ bool install_policy)
+{
+ this->proxy_mode = proxy_mode;
+ this->install_policy = install_policy;
+}
+
+/**
+ * Implementation of child_cfg_t.use_proxy_mode.
+ */
+static bool use_proxy_mode(private_child_cfg_t *this)
+{
+ return this->proxy_mode;
+}
+
+/**
+ * Implementation of child_cfg_t.install_policy.
+ */
+static bool install_policy(private_child_cfg_t *this)
+{
+ return this->install_policy;
+}
+
+/**
+ * Implementation of child_cfg_t.get_ref.
*/
static child_cfg_t* get_ref(private_child_cfg_t *this)
{
@@ -462,6 +527,7 @@ child_cfg_t *child_cfg_create(char *name, u_int32_t lifetime,
this->public.get_name = (char* (*) (child_cfg_t*))get_name;
this->public.add_traffic_selector = (void (*)(child_cfg_t*,bool,traffic_selector_t*))add_traffic_selector;
this->public.get_traffic_selectors = (linked_list_t*(*)(child_cfg_t*,bool,linked_list_t*,host_t*))get_traffic_selectors;
+ this->public.equal_traffic_selectors = (bool (*)(child_cfg_t*,bool,linked_list_t*,host_t*))equal_traffic_selectors;
this->public.add_proposal = (void (*) (child_cfg_t*,proposal_t*))add_proposal;
this->public.get_proposals = (linked_list_t* (*) (child_cfg_t*,bool))get_proposals;
this->public.select_proposal = (proposal_t* (*) (child_cfg_t*,linked_list_t*,bool))select_proposal;
@@ -472,7 +538,10 @@ child_cfg_t *child_cfg_create(char *name, u_int32_t lifetime,
this->public.get_close_action = (action_t (*) (child_cfg_t *))get_close_action;
this->public.get_lifetime = (u_int32_t (*) (child_cfg_t *,bool))get_lifetime;
this->public.get_dh_group = (diffie_hellman_group_t(*)(child_cfg_t*)) get_dh_group;
+ this->public.set_mipv6_options = (void (*) (child_cfg_t*,bool,bool))set_mipv6_options;
this->public.use_ipcomp = (bool (*) (child_cfg_t *))use_ipcomp;
+ this->public.use_proxy_mode = (bool (*) (child_cfg_t *))use_proxy_mode;
+ this->public.install_policy = (bool (*) (child_cfg_t *))install_policy;
this->public.get_ref = (child_cfg_t* (*) (child_cfg_t*))get_ref;
this->public.destroy = (void (*) (child_cfg_t*))destroy;
@@ -486,6 +555,8 @@ child_cfg_t *child_cfg_create(char *name, u_int32_t lifetime,
this->dpd_action = dpd_action;
this->close_action = close_action;
this->use_ipcomp = ipcomp;
+ this->proxy_mode = FALSE;
+ this->install_policy = TRUE;
this->refcount = 1;
this->proposals = linked_list_create();
this->my_ts = linked_list_create();
diff --git a/src/charon/config/child_cfg.h b/src/charon/config/child_cfg.h
index 83d6cafe6..787324dca 100644
--- a/src/charon/config/child_cfg.h
+++ b/src/charon/config/child_cfg.h
@@ -14,7 +14,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * $Id: child_cfg.h 4358 2008-09-25 13:56:23Z tobias $
+ * $Id: child_cfg.h 4611 2008-11-11 06:29:25Z andreas $
*/
/**
@@ -154,6 +154,17 @@ struct child_cfg_t {
host_t *host);
/**
+ * Checks [single] traffic selectors for equality
+ *
+ * @param local TRUE for TS on local side, FALSE for remote
+ * @param ts list with single traffic selector to compare with
+ * @param host address to use for narrowing "dynamic" TS', or NULL
+ * @return TRUE if TS are equal, FALSE otherwise
+ */
+ bool (*equal_traffic_selectors)(child_cfg_t *this, bool local,
+ linked_list_t *ts_list, host_t *host);
+
+ /**
* Get the updown script to run for the CHILD_SA.
*
* @return path to updown script
@@ -219,6 +230,31 @@ struct child_cfg_t {
* FALSE, otherwise
*/
bool (*use_ipcomp)(child_cfg_t *this);
+
+ /**
+ * Sets two options needed for Mobile IPv6 interoperability
+ *
+ * @proxy_mode use IPsec transport proxy mode (default FALSE)
+ * @install_policy install IPsec kernel policies (default TRUE)
+ */
+ void (*set_mipv6_options)(child_cfg_t *this, bool proxy_mod,
+ bool install_policy);
+
+ /**
+ * Check whether IPsec transport SA should be set up in proxy mode
+ *
+ * @return TRUE, if proxy mode should be used
+ * FALSE, otherwise
+ */
+ bool (*use_proxy_mode)(child_cfg_t *this);
+
+ /**
+ * Check whether IPsec policies should be installed in the kernel
+ *
+ * @return TRUE, if IPsec kernel policies should be installed
+ * FALSE, otherwise
+ */
+ bool (*install_policy)(child_cfg_t *this);
/**
* Increase the reference count.
@@ -261,7 +297,6 @@ struct child_cfg_t {
child_cfg_t *child_cfg_create(char *name, u_int32_t lifetime,
u_int32_t rekeytime, u_int32_t jitter,
char *updown, bool hostaccess, ipsec_mode_t mode,
- action_t dpd_action, action_t close_action,
- bool ipcomp);
+ action_t dpd_action, action_t close_action, bool ipcomp);
#endif /* CHILD_CFG_H_ @} */
diff --git a/src/charon/config/peer_cfg.c b/src/charon/config/peer_cfg.c
index 04f323128..9cbca040d 100644
--- a/src/charon/config/peer_cfg.c
+++ b/src/charon/config/peer_cfg.c
@@ -14,14 +14,16 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * $Id: peer_cfg.c 4276 2008-08-22 10:44:51Z martin $
+ * $Id: peer_cfg.c 4612 2008-11-11 06:37:37Z andreas $
*/
#include <string.h>
-#include <pthread.h>
#include "peer_cfg.h"
+#include <daemon.h>
+
+#include <utils/mutex.h>
#include <utils/linked_list.h>
#include <utils/identification.h>
@@ -77,7 +79,7 @@ struct private_peer_cfg_t {
/**
* mutex to lock access to list of child_cfgs
*/
- pthread_mutex_t mutex;
+ mutex_t *mutex;
/**
* id to use to identify us
@@ -197,9 +199,9 @@ static ike_cfg_t* get_ike_cfg(private_peer_cfg_t *this)
*/
static void add_child_cfg(private_peer_cfg_t *this, child_cfg_t *child_cfg)
{
- pthread_mutex_lock(&this->mutex);
+ this->mutex->lock(this->mutex);
this->child_cfgs->insert_last(this->child_cfgs, child_cfg);
- pthread_mutex_unlock(&this->mutex);
+ this->mutex->unlock(this->mutex);
}
/**
@@ -207,9 +209,9 @@ static void add_child_cfg(private_peer_cfg_t *this, child_cfg_t *child_cfg)
*/
static void remove_child_cfg(private_peer_cfg_t *this, enumerator_t *enumerator)
{
- pthread_mutex_lock(&this->mutex);
+ this->mutex->lock(this->mutex);
this->child_cfgs->remove_at(this->child_cfgs, enumerator);
- pthread_mutex_unlock(&this->mutex);
+ this->mutex->unlock(this->mutex);
}
/**
@@ -219,25 +221,29 @@ static enumerator_t* create_child_cfg_enumerator(private_peer_cfg_t *this)
{
enumerator_t *enumerator;
- pthread_mutex_lock(&this->mutex);
+ this->mutex->lock(this->mutex);
enumerator = this->child_cfgs->create_enumerator(this->child_cfgs);
return enumerator_create_cleaner(enumerator,
- (void*)pthread_mutex_unlock, &this->mutex);
+ (void*)this->mutex->unlock, this->mutex);
}
/**
* Check if child_cfg contains traffic selectors
*/
-static bool contains_ts(child_cfg_t *child, bool mine, linked_list_t *ts,
+static int contains_ts(child_cfg_t *child, bool mine, linked_list_t *ts,
host_t *host)
{
linked_list_t *selected;
- bool contains = FALSE;
+ int prio;
+ if (child->equal_traffic_selectors(child, mine, ts, host))
+ {
+ return 2;
+ }
selected = child->get_traffic_selectors(child, mine, ts, host);
- contains = selected->get_count(selected);
+ prio = selected->get_count(selected) ? 1 : 0;
selected->destroy_offset(selected, offsetof(traffic_selector_t, destroy));
- return contains;
+ return prio;
}
/**
@@ -250,18 +256,33 @@ static child_cfg_t* select_child_cfg(private_peer_cfg_t *this,
{
child_cfg_t *current, *found = NULL;
enumerator_t *enumerator;
-
+ int best = 0;
+
+ DBG2(DBG_CFG, "looking for a child config for %#R=== %#R", my_ts, other_ts);
enumerator = create_child_cfg_enumerator(this);
while (enumerator->enumerate(enumerator, &current))
{
- if (contains_ts(current, TRUE, my_ts, my_host) &&
- contains_ts(current, FALSE, other_ts, other_host))
+ int prio = contains_ts(current, TRUE, my_ts, my_host) +
+ contains_ts(current, FALSE, other_ts, other_host);
+
+ if (prio)
{
- found = current->get_ref(current);
- break;
+ DBG2(DBG_CFG, " candidate \"%s\" with prio %d",
+ current->get_name(current), prio);
+ if (prio > best)
+ {
+ best = prio;
+ DESTROY_IF(found);
+ found = current->get_ref(current);
+ }
}
}
enumerator->destroy(enumerator);
+ if (found)
+ {
+ DBG2(DBG_CFG, "found matching child config \"%s\" with prio %d",
+ found->get_name(found), best);
+ }
return found;
}
@@ -480,6 +501,7 @@ static void destroy(private_peer_cfg_t *this)
DESTROY_IF(this->mediated_by);
DESTROY_IF(this->peer_id);
#endif /* ME */
+ this->mutex->destroy(this->mutex);
free(this->name);
free(this->pool);
free(this);
@@ -536,7 +558,7 @@ peer_cfg_t *peer_cfg_create(char *name, u_int ike_version, ike_cfg_t *ike_cfg,
this->ike_version = ike_version;
this->ike_cfg = ike_cfg;
this->child_cfgs = linked_list_create();
- pthread_mutex_init(&this->mutex, NULL);
+ this->mutex = mutex_create(MUTEX_DEFAULT);
this->my_id = my_id;
this->other_id = other_id;
this->cert_policy = cert_policy;
diff --git a/src/charon/config/proposal.c b/src/charon/config/proposal.c
index b1c049fe8..202dc913a 100644
--- a/src/charon/config/proposal.c
+++ b/src/charon/config/proposal.c
@@ -13,7 +13,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * $Id: proposal.c 4390 2008-10-08 12:57:11Z martin $
+ * $Id: proposal.c 4635 2008-11-12 08:27:48Z martin $
*/
#include <string.h>
diff --git a/src/charon/config/traffic_selector.c b/src/charon/config/traffic_selector.c
index 63172f855..d4235c32a 100644
--- a/src/charon/config/traffic_selector.c
+++ b/src/charon/config/traffic_selector.c
@@ -14,7 +14,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * $Id: traffic_selector.c 4199 2008-07-21 19:08:03Z andreas $
+ * $Id: traffic_selector.c 4639 2008-11-12 15:09:24Z martin $
*/
#include <arpa/inet.h>
@@ -134,8 +134,9 @@ static u_int8_t calc_netbits(private_traffic_selector_t *this)
int byte, bit;
size_t size = (this->type == TS_IPV4_ADDR_RANGE) ? 4 : 16;
- /* go trough all bits of the addresses, begging in the front.
- * As longer as they equal, the subnet gets larger */
+ /* go trough all bits of the addresses, beginning in the front.
+ * as long as they are equal, the subnet gets larger
+ */
for (byte = 0; byte < size; byte++)
{
for (bit = 7; bit >= 0; bit--)
@@ -405,26 +406,15 @@ static bool equals(private_traffic_selector_t *this, private_traffic_selector_t
*/
static chunk_t get_from_address(private_traffic_selector_t *this)
{
- chunk_t from = chunk_empty;
-
switch (this->type)
{
case TS_IPV4_ADDR_RANGE:
- {
- from.len = sizeof(this->from4);
- from.ptr = malloc(from.len);
- memcpy(from.ptr, this->from4, from.len);
- break;
- }
+ return chunk_create(this->from, sizeof(this->from4));
case TS_IPV6_ADDR_RANGE:
- {
- from.len = sizeof(this->from6);
- from.ptr = malloc(from.len);
- memcpy(from.ptr, this->from6, from.len);
- break;
- }
+ return chunk_create(this->from, sizeof(this->from6));
+ default:
+ return chunk_empty;
}
- return from;
}
/**
@@ -432,26 +422,15 @@ static chunk_t get_from_address(private_traffic_selector_t *this)
*/
static chunk_t get_to_address(private_traffic_selector_t *this)
{
- chunk_t to = chunk_empty;
-
switch (this->type)
{
case TS_IPV4_ADDR_RANGE:
- {
- to.len = sizeof(this->to4);
- to.ptr = malloc(to.len);
- memcpy(to.ptr, this->to4, to.len);
- break;
- }
+ return chunk_create(this->to, sizeof(this->to4));
case TS_IPV6_ADDR_RANGE:
- {
- to.len = sizeof(this->to6);
- to.ptr = malloc(to.len);
- memcpy(to.ptr, this->to6, to.len);
- break;
- }
+ return chunk_create(this->to, sizeof(this->to6));
+ default:
+ return chunk_empty;
}
- return to;
}
/**
@@ -525,6 +504,14 @@ static bool is_host(private_traffic_selector_t *this, host_t *host)
}
/**
+ * Implementation of traffic_selector_t.is_dynamic
+ */
+static bool is_dynamic(private_traffic_selector_t *this)
+{
+ return this->dynamic;
+}
+
+/**
* Implements traffic_selector_t.set_address.
*/
static void set_address(private_traffic_selector_t *this, host_t *host)
@@ -583,6 +570,60 @@ static bool includes(private_traffic_selector_t *this, host_t *host)
}
/**
+ * Implements traffic_selector_t.to_subnet.
+ */
+static void to_subnet(private_traffic_selector_t *this, host_t **net, u_int8_t *mask)
+{
+ /* there is no way to do this cleanly, as the address range may
+ * be anything else but a subnet. We use from_addr as subnet
+ * and try to calculate a usable subnet mask.
+ */
+ int family, byte;
+ u_int16_t port = 0;
+ chunk_t net_chunk;
+
+ *mask = calc_netbits(this);
+
+ switch (this->type)
+ {
+ case TS_IPV4_ADDR_RANGE:
+ {
+ family = AF_INET;
+ net_chunk.len = sizeof(this->from4);
+ break;
+ }
+ case TS_IPV6_ADDR_RANGE:
+ {
+ family = AF_INET6;
+ net_chunk.len = sizeof(this->from6);
+ break;
+ }
+ default:
+ {
+ /* unreachable */
+ return;
+ }
+ }
+
+ net_chunk.ptr = malloc(net_chunk.len);
+ memcpy(net_chunk.ptr, this->from, net_chunk.len);
+
+ for (byte = net_chunk.len - 1; byte >= (*mask / 8); --byte)
+ {
+ int shift = (byte + 1) * 8 - *mask;
+ net_chunk.ptr[byte] = net_chunk.ptr[byte] & (0xFF << shift);
+ }
+
+ if (this->to_port == this->from_port)
+ {
+ port = this->to_port;
+ }
+
+ *net = host_create_from_chunk(family, net_chunk, port);
+ chunk_free(&net_chunk);
+}
+
+/**
* Implements traffic_selector_t.clone.
*/
static traffic_selector_t *clone_(private_traffic_selector_t *this)
@@ -814,9 +855,11 @@ static private_traffic_selector_t *traffic_selector_create(u_int8_t protocol,
this->public.get_type = (ts_type_t(*)(traffic_selector_t*))get_type;
this->public.get_protocol = (u_int8_t(*)(traffic_selector_t*))get_protocol;
this->public.is_host = (bool(*)(traffic_selector_t*,host_t*))is_host;
+ this->public.is_dynamic = (bool(*)(traffic_selector_t*))is_dynamic;
this->public.is_contained_in = (bool(*)(traffic_selector_t*,traffic_selector_t*))is_contained_in;
this->public.includes = (bool(*)(traffic_selector_t*,host_t*))includes;
this->public.set_address = (void(*)(traffic_selector_t*,host_t*))set_address;
+ this->public.to_subnet = (void(*)(traffic_selector_t*,host_t**,u_int8_t*))to_subnet;
this->public.clone = (traffic_selector_t*(*)(traffic_selector_t*))clone_;
this->public.destroy = (void(*)(traffic_selector_t*))destroy;
diff --git a/src/charon/config/traffic_selector.h b/src/charon/config/traffic_selector.h
index 4b079a8e0..d97ffdea0 100644
--- a/src/charon/config/traffic_selector.h
+++ b/src/charon/config/traffic_selector.h
@@ -14,7 +14,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * $Id: traffic_selector.h 3658 2008-03-26 10:06:45Z martin $
+ * $Id: traffic_selector.h 4643 2008-11-12 22:57:46Z andreas $
*/
/**
@@ -92,7 +92,7 @@ struct traffic_selector_t {
/**
* Get starting address of this ts as a chunk.
*
- * Chunk is in network order gets allocated.
+ * Chunk is in network order and points to internal data.
*
* @return chunk containing the address
*/
@@ -101,7 +101,7 @@ struct traffic_selector_t {
/**
* Get ending address of this ts as a chunk.
*
- * Chunk is in network order gets allocated.
+ * Chunk is in network order and points to internal data.
*
* @return chunk containing the address
*/
@@ -155,6 +155,13 @@ struct traffic_selector_t {
bool (*is_host) (traffic_selector_t *this, host_t* host);
/**
+ * Check if a traffic selector has been created by create_dynamic().
+ *
+ * @return TRUE if TS is dynamic
+ */
+ bool (*is_dynamic)(traffic_selector_t *this);
+
+ /**
* Update the address of a traffic selector.
*
* Update the address range of a traffic selector, if it is
@@ -168,7 +175,7 @@ struct traffic_selector_t {
* Compare two traffic selectors for equality.
*
* @param other ts to compare with this
- * @return pointer to a string.
+ * @return TRUE if equal, FALSE otherwise
*/
bool (*equals) (traffic_selector_t *this, traffic_selector_t *other);
@@ -191,6 +198,17 @@ struct traffic_selector_t {
bool (*includes) (traffic_selector_t *this, host_t *host);
/**
+ * Convert a traffic selector address range to a subnet
+ * and its net mask.
+ * If from and to ports of this traffic selector are equal,
+ * the port of the returned host_t is set to that port.
+ *
+ * @param net converted subnet (has to be freed)
+ * @param mask converted net mask
+ */
+ void (*to_subnet) (traffic_selector_t *this, host_t **net, u_int8_t *mask);
+
+ /**
* Destroys the ts object
*/
void (*destroy) (traffic_selector_t *this);
@@ -225,7 +243,7 @@ traffic_selector_t *traffic_selector_create_from_string(
* @param type type of following addresses, such as TS_IPV4_ADDR_RANGE
* @param from_address start of address range, network order
* @param from_port port number, host order
- * @param to_address end of address range as string, network
+ * @param to_address end of address range, network order
* @param to_port port number, host order
* @return traffic_selector_t object
*/