aboutsummaryrefslogtreecommitdiffstats
path: root/src/charon/threads/kernel_interface.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/charon/threads/kernel_interface.c')
-rw-r--r--src/charon/threads/kernel_interface.c48
1 files changed, 22 insertions, 26 deletions
diff --git a/src/charon/threads/kernel_interface.c b/src/charon/threads/kernel_interface.c
index 9ca821fa2..b09070390 100644
--- a/src/charon/threads/kernel_interface.c
+++ b/src/charon/threads/kernel_interface.c
@@ -889,42 +889,37 @@ static void ts2subnet(traffic_selector_t* ts,
/* 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.
- */
- chunk_t chunk;
+ */
+ int byte, bit;
+ bool found = FALSE;
+ chunk_t from, to;
+ size_t size = (ts->get_type(ts) == TS_IPV4_ADDR_RANGE) ? 4 : 16;
- chunk = ts->get_from_address(ts);
- memcpy(net, chunk.ptr, chunk.len);
+ from = ts->get_from_address(ts);
+ to = ts->get_to_address(ts);
- switch (ts->get_type(ts))
+ *mask = (size * 8);
+ /* go trough all bits of the addresses, beginning in the front.
+ * As longer as they equal, the subnet gets larger */
+ for (byte = 0; byte < size; byte++)
{
- case TS_IPV4_ADDR_RANGE:
+ for (bit = 7; bit >= 0; bit--)
{
- u_int32_t from, to, bit;
-
- from = *(u_int32_t*)chunk.ptr;
- chunk_free(&chunk);
- chunk = ts->get_to_address(ts);
- to = *(u_int32_t*)chunk.ptr;
- chunk_free(&chunk);
- for (bit = 0; bit < 32; bit++)
+ if ((1<<bit & from.ptr[byte]) != (1<<bit & to.ptr[byte]))
{
- if ((1<<bit & from) != (1<<bit & to))
- {
- *mask = bit;
- return;
- }
+ *mask = ((7 - bit) + (byte * 8));
+ found = TRUE;
+ break;
}
- *mask = 32;
- return;
}
- case TS_IPV6_ADDR_RANGE:
- default:
+ if (found)
{
- /* TODO: IPV6 support */
- *mask = 0;
- return;
+ break;
}
}
+ memcpy(net, from.ptr, from.len);
+ chunk_free(&from);
+ chunk_free(&to);
}
/**
@@ -1075,6 +1070,7 @@ static status_t add_policy(private_kernel_interface_t *this,
tmpl->id.proto = (protocol == PROTO_AH) ? KERNEL_AH : KERNEL_ESP;
tmpl->aalgos = tmpl->ealgos = tmpl->calgos = ~0;
tmpl->mode = TRUE;
+ tmpl->family = src->get_family(src);
host2xfrm(src, &tmpl->saddr);
host2xfrm(dst, &tmpl->id.daddr);