supporting multiple comma seperated subnets in left/rightsubnet definition

e.g. leftsubnet=10.2.0.0/16,10.4.0.0/16
This commit is contained in:
Martin Willi
2008-04-25 12:41:37 +00:00
parent 1aedf08183
commit 3444390241
10 changed files with 116 additions and 57 deletions
+54 -28
View File
@@ -472,9 +472,9 @@ static peer_cfg_t *build_peer_cfg(private_stroke_config_t *this,
}
if (!vip)
{ /* if it is set to something like %poolname, request an address */
if (msg->add_conn.me.subnet)
if (msg->add_conn.me.subnets)
{ /* use the same addreass as in subnet, if any */
if (strchr(msg->add_conn.me.subnet, '.'))
if (strchr(msg->add_conn.me.subnets, '.'))
{
vip = host_create_any(AF_INET);
}
@@ -620,27 +620,67 @@ static void build_auth_info(private_stroke_config_t *this,
/**
* build a traffic selector from a stroke_end
*/
static traffic_selector_t *build_ts(private_stroke_config_t *this,
stroke_end_t *end)
static void add_ts(private_stroke_config_t *this,
stroke_end_t *end, child_cfg_t *child_cfg, bool local)
{
traffic_selector_t *ts;
if (end->tohost)
{
return traffic_selector_create_dynamic(end->protocol,
ts = traffic_selector_create_dynamic(end->protocol,
end->port ? end->port : 0, end->port ? end->port : 65535);
child_cfg->add_traffic_selector(child_cfg, local, ts);
}
else
{
host_t *net;
net = host_create_from_string(end->subnet ? end->subnet : end->address,
IKEV2_UDP_PORT);
if (!net)
if (!end->subnets)
{
DBG1(DBG_CFG, "invalid subnet: %s", end->subnet);
return NULL;
net = host_create_from_string(end->address, IKEV2_UDP_PORT);
if (net)
{
ts = traffic_selector_create_from_subnet(net, 0, end->protocol,
end->port);
child_cfg->add_traffic_selector(child_cfg, local, ts);
}
}
else
{
char *del, *start, *bits;
start = end->subnets;
do
{
int intbits = 0;
del = strchr(start, ',');
if (del)
{
*del = '\0';
}
bits = strchr(start, '/');
if (bits)
{
*bits = '\0';
intbits = atoi(bits + 1);
}
net = host_create_from_string(start, IKEV2_UDP_PORT);
if (net)
{
ts = traffic_selector_create_from_subnet(net, intbits,
end->protocol, end->port);
child_cfg->add_traffic_selector(child_cfg, local, ts);
}
else
{
DBG1(DBG_CFG, "invalid subnet: %s, skipped", start);
}
start = del + 1;
}
while (del);
}
return traffic_selector_create_from_subnet(net,
end->subnet ? end->subnet_mask : 0, end->protocol, end->port);
}
}
@@ -651,7 +691,6 @@ static child_cfg_t *build_child_cfg(private_stroke_config_t *this,
stroke_msg_t *msg)
{
child_cfg_t *child_cfg;
traffic_selector_t *ts;
action_t dpd;
switch (msg->add_conn.dpd.action)
@@ -673,21 +712,8 @@ static child_cfg_t *build_child_cfg(private_stroke_config_t *this,
msg->add_conn.me.updown, msg->add_conn.me.hostaccess,
msg->add_conn.mode, dpd, ACTION_NONE);
ts = build_ts(this, &msg->add_conn.me);
if (!ts)
{
child_cfg->destroy(child_cfg);
return NULL;
}
child_cfg->add_traffic_selector(child_cfg, TRUE, ts);
ts = build_ts(this, &msg->add_conn.other);
if (!ts)
{
child_cfg->destroy(child_cfg);
return NULL;
}
child_cfg->add_traffic_selector(child_cfg, FALSE, ts);
add_ts(this, &msg->add_conn.me, child_cfg, TRUE);
add_ts(this, &msg->add_conn.other, child_cfg, FALSE);
add_proposals(this, msg->add_conn.algorithms.esp, NULL, child_cfg);
+2 -2
View File
@@ -140,7 +140,7 @@ static void pop_string(stroke_msg_t *msg, char **string)
static void pop_end(stroke_msg_t *msg, const char* label, stroke_end_t *end)
{
pop_string(msg, &end->address);
pop_string(msg, &end->subnet);
pop_string(msg, &end->subnets);
pop_string(msg, &end->sourceip);
pop_string(msg, &end->id);
pop_string(msg, &end->cert);
@@ -149,7 +149,7 @@ static void pop_end(stroke_msg_t *msg, const char* label, stroke_end_t *end)
pop_string(msg, &end->updown);
DBG2(DBG_CFG, " %s=%s", label, end->address);
DBG2(DBG_CFG, " %ssubnet=%s", label, end->subnet);
DBG2(DBG_CFG, " %ssubnet=%s", label, end->subnets);
DBG2(DBG_CFG, " %ssourceip=%s", label, end->sourceip);
DBG2(DBG_CFG, " %sid=%s", label, end->id);
DBG2(DBG_CFG, " %scert=%s", label, end->cert);
+1 -1
View File
@@ -47,7 +47,7 @@ starter_cmp_end(starter_end_t *c1, starter_end_t *c2)
}
ADDCMP(nexthop);
STRCMP(srcip);
SUBCMP(subnet);
STRCMP(subnet);
VARCMP(has_client);
VARCMP(has_client_wildcard);
VARCMP(has_port_wildcard);
+31 -4
View File
@@ -32,7 +32,7 @@
#include "interfaces.h"
/* strings containing a colon are interpreted as an IPv6 address */
#define ip_version(string) (strchr(string, ':') != NULL)? AF_INET6 : AF_INET;
#define ip_version(string) (strchr(string, '.') ? AF_INET : AF_INET6)
static const char ike_defaults[] = "aes128-sha-modp2048";
static const char esp_defaults[] = "aes128-sha1, 3des-md5";
@@ -189,7 +189,6 @@ kw_end(starter_conn_t *conn, starter_end_t *end, kw_token_t token
conn->policy |= POLICY_GROUP | POLICY_TUNNEL;
anyaddr(conn->addr_family, &end->addr);
anyaddr(conn->tunnel_addr_family, &any);
initsubnet(&any, 0, '0', &end->subnet);
end->has_client = TRUE;
}
else
@@ -251,22 +250,44 @@ kw_end(starter_conn_t *conn, starter_end_t *end, kw_token_t token
}
else
{
ip_subnet net;
char *pos;
int len = 0;
end->has_client = TRUE;
conn->tunnel_addr_family = ip_version(value);
ugh = ttosubnet(value, 0, conn->tunnel_addr_family, &end->subnet);
pos = strchr(value, ',');
if (pos)
{
len = pos - value;
}
ugh = ttosubnet(value, len, ip_version(value), &net);
if (ugh != NULL)
{
plog("# bad subnet: %s=%s [%s]", name, value, ugh);
goto err;
}
end->subnet = clone_str(value, "subnet");
}
break;
case KW_SUBNETWITHIN:
{
ip_subnet net;
end->has_client = TRUE;
end->has_client_wildcard = TRUE;
conn->tunnel_addr_family = ip_version(value);
ugh = ttosubnet(value, 0, conn->tunnel_addr_family, &end->subnet);
ugh = ttosubnet(value, 0, ip_version(value), &net);
if (ugh != NULL)
{
plog("# bad subnet: %s=%s [%s]", name, value, ugh);
goto err;
}
end->subnet = clone_str(value, "subnetwithin");
break;
}
case KW_PROTOPORT:
ugh = ttoprotoport(value, 0, &end->protocol, &end->port, &has_port_wildcard);
end->has_port_wildcard = has_port_wildcard;
@@ -827,6 +848,12 @@ free_also(also_t *head)
static void
confread_free_conn(starter_conn_t *conn)
{
pfree(conn->left.subnet);
pfree(conn->right.subnet);
pfree(conn->left.virt);
pfree(conn->right.virt);
pfree(conn->left.srcip);
pfree(conn->right.srcip);
free_args(KW_END_FIRST, KW_END_LAST, (char *)&conn->left);
free_args(KW_END_FIRST, KW_END_LAST, (char *)&conn->right);
free_args(KW_CONN_NAME, KW_CONN_LAST, (char *)conn);
+1 -1
View File
@@ -65,7 +65,7 @@ struct starter_end {
char *iface;
ip_address addr;
ip_address nexthop;
ip_subnet subnet;
char *subnet;
bool has_client;
bool has_client_wildcard;
bool has_port_wildcard;
+3 -1
View File
@@ -646,7 +646,9 @@ private subnet behind the left participant, expressed as
if omitted, essentially assumed to be \fIleft\fB/32\fR,
signifying that the left end of the connection goes to the left participant
only. When using IKEv2, the configured subnet of the peers may differ, the
protocol narrows it to the greates common subnet.
protocol narrows it to the greatest common subnet. Further, IKEv2 supports
multiple subnets separated by commas. IKEv1 only interprets the first subnet
of such a definition.
.TP
.B leftsubnetwithin
the peer can propose any subnet or single IP address that fits within the
+1 -3
View File
@@ -161,9 +161,7 @@ static void starter_stroke_add_end(stroke_msg_t *msg, stroke_end_t *msg_end, sta
msg_end->updown = push_string(msg, conn_end->updown);
ip_address2string(&conn_end->addr, buffer, sizeof(buffer));
msg_end->address = push_string(msg, buffer);
ip_address2string(&conn_end->subnet.addr, buffer, sizeof(buffer));
msg_end->subnet = push_string(msg, buffer);
msg_end->subnet_mask = conn_end->subnet.maskbits;
msg_end->subnets = push_string(msg, conn_end->subnet);
msg_end->sendcert = conn_end->sendcert;
msg_end->hostaccess = conn_end->hostaccess;
msg_end->tohost = !conn_end->has_client;
+17 -5
View File
@@ -32,6 +32,8 @@
#include "confread.h"
#include "files.h"
#define ip_version(string) (strchr(string, '.') ? AF_INET : AF_INET6)
static int
pack_str (char **p, char **next, char **roof)
{
@@ -153,22 +155,22 @@ set_whack_end(whack_end_t *w, starter_end_t *end, sa_family_t family)
if (end->srcip && end->srcip[0] != '%')
{
int len = 0;
char *pos, *v6;
char *pos;
pos = strchr(end->srcip, '/');
v6 = strchr(end->srcip, ':');
if (pos)
{
/* use first address only for pluto */
len = pos - end->srcip;
}
w->has_srcip = !end->has_natip;
ttoaddr(end->srcip, len, v6 ? AF_INET6 : AF_INET, &w->host_srcip);
ttoaddr(end->srcip, len, ip_version(end->srcip), &w->host_srcip);
}
else
{
anyaddr(AF_INET, &w->host_srcip);
}
}
w->id = end->id;
w->cert = end->cert;
w->ca = end->ca;
@@ -183,7 +185,17 @@ set_whack_end(whack_end_t *w, starter_end_t *end, sa_family_t family)
w->host_nexthop = end->nexthop;
if (w->has_client)
w->client = end->subnet;
{
char *pos;
int len = 0;
pos = strchr(end->subnet, ',');
if (pos)
{
len = pos - end->subnet;
}
ttosubnet(end->subnet, len, ip_version(end->subnet), &w->client);
}
else
w->client.addr.u.v4.sin_family = addrtypeof(&w->host_addr);
+5 -10
View File
@@ -100,8 +100,7 @@ static int send_stroke_msg (stroke_msg_t *msg)
static int add_connection(char *name,
char *my_id, char *other_id,
char *my_addr, char *other_addr,
char *my_net, char *other_net,
u_int my_netmask, u_int other_netmask)
char *my_nets, char *other_nets)
{
stroke_msg_t msg;
@@ -118,14 +117,12 @@ static int add_connection(char *name,
msg.add_conn.me.id = push_string(&msg, my_id);
msg.add_conn.me.address = push_string(&msg, my_addr);
msg.add_conn.me.subnet = push_string(&msg, my_net);
msg.add_conn.me.subnet_mask = my_netmask;
msg.add_conn.me.subnets = push_string(&msg, my_nets);
msg.add_conn.me.sendcert = 1;
msg.add_conn.other.id = push_string(&msg, other_id);
msg.add_conn.other.address = push_string(&msg, other_addr);
msg.add_conn.other.subnet = push_string(&msg, other_net);
msg.add_conn.other.subnet_mask = other_netmask;
msg.add_conn.other.subnets = push_string(&msg, other_nets);
msg.add_conn.other.sendcert = 1;
return send_stroke_msg(&msg);
@@ -277,8 +274,7 @@ static void exit_usage(char *error)
printf(" MY_NET OTHER_NET MY_NETBITS OTHER_NETBITS\n");
printf(" where: ID is any IKEv2 ID \n");
printf(" ADDR is a IPv4 address\n");
printf(" NET is a IPv4 address of the subnet to tunnel\n");
printf(" NETBITS is the size of the subnet, as the \"24\" in 192.168.0.0/24\n");
printf(" NET is a IPv4 subnet in CIDR notation\n");
printf(" Delete a connection:\n");
printf(" stroke delete NAME\n");
printf(" where: NAME is a connection name added with \"stroke add\"\n");
@@ -334,8 +330,7 @@ int main(int argc, char *argv[])
res = add_connection(argv[2],
argv[3], argv[4],
argv[5], argv[6],
argv[7], argv[8],
atoi(argv[9]), atoi(argv[10]));
argv[7], argv[8]);
break;
case STROKE_DELETE:
case STROKE_DEL:
+1 -2
View File
@@ -127,8 +127,7 @@ struct stroke_end_t {
char *address;
char *sourceip;
int sourceip_size;
char *subnet;
int subnet_mask;
char *subnets;
int sendcert;
int hostaccess;
int tohost;