cleanups in kernel interface code
added proper traffic selector to string conversion some cleanups here & there
This commit is contained in:
parent
623d3dcf78
commit
92ee45a0ee
|
@ -141,7 +141,7 @@ AC_OUTPUT(
|
||||||
src/pluto/Makefile
|
src/pluto/Makefile
|
||||||
src/whack/Makefile
|
src/whack/Makefile
|
||||||
src/charon/Makefile
|
src/charon/Makefile
|
||||||
src/charon/testing/Makefile
|
dnl src/charon/testing/Makefile
|
||||||
src/stroke/Makefile
|
src/stroke/Makefile
|
||||||
src/ipsec/Makefile
|
src/ipsec/Makefile
|
||||||
src/starter/Makefile
|
src/starter/Makefile
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
SUBDIRS = . testing
|
# SUBDIRS = . testing
|
||||||
|
|
||||||
ipsec_PROGRAMS = charon
|
ipsec_PROGRAMS = charon
|
||||||
|
|
||||||
|
|
|
@ -75,7 +75,7 @@ static connection_t *get_connection_by_hosts(private_local_connection_store_t *t
|
||||||
connection_t *found = NULL;
|
connection_t *found = NULL;
|
||||||
|
|
||||||
this->logger->log(this->logger, CONTROL|LEVEL1, "looking for connection for host pair %s...%s",
|
this->logger->log(this->logger, CONTROL|LEVEL1, "looking for connection for host pair %s...%s",
|
||||||
my_host->get_address(my_host), other_host->get_address(other_host));
|
my_host->get_string(my_host), other_host->get_string(other_host));
|
||||||
|
|
||||||
pthread_mutex_lock(&(this->mutex));
|
pthread_mutex_lock(&(this->mutex));
|
||||||
iterator = this->connections->create_iterator(this->connections, TRUE);
|
iterator = this->connections->create_iterator(this->connections, TRUE);
|
||||||
|
@ -108,8 +108,8 @@ static connection_t *get_connection_by_hosts(private_local_connection_store_t *t
|
||||||
this->logger->log(this->logger, CONTROL|LEVEL2,
|
this->logger->log(this->logger, CONTROL|LEVEL2,
|
||||||
"candidate connection \"%s\": %s...%s (prio=%d)",
|
"candidate connection \"%s\": %s...%s (prio=%d)",
|
||||||
candidate->get_name(candidate),
|
candidate->get_name(candidate),
|
||||||
candidate_my_host->get_address(candidate_my_host),
|
candidate_my_host->get_string(candidate_my_host),
|
||||||
candidate_other_host->get_address(candidate_other_host),
|
candidate_other_host->get_string(candidate_other_host),
|
||||||
prio);
|
prio);
|
||||||
|
|
||||||
if (prio > best_prio)
|
if (prio > best_prio)
|
||||||
|
@ -129,8 +129,8 @@ static connection_t *get_connection_by_hosts(private_local_connection_store_t *t
|
||||||
this->logger->log(this->logger, CONTROL,
|
this->logger->log(this->logger, CONTROL,
|
||||||
"found matching connection \"%s\": %s...%s (prio=%d)",
|
"found matching connection \"%s\": %s...%s (prio=%d)",
|
||||||
found->get_name(found),
|
found->get_name(found),
|
||||||
found_my_host->get_address(found_my_host),
|
found_my_host->get_string(found_my_host),
|
||||||
found_other_host->get_address(found_other_host),
|
found_other_host->get_string(found_other_host),
|
||||||
best_prio);
|
best_prio);
|
||||||
|
|
||||||
found = found->clone(found);
|
found = found->clone(found);
|
||||||
|
@ -243,8 +243,8 @@ void log_connections(private_local_connection_store_t *this, logger_t *logger, c
|
||||||
|
|
||||||
logger->log(logger, CONTROL, " \"%s\": %s...%s",
|
logger->log(logger, CONTROL, " \"%s\": %s...%s",
|
||||||
current->get_name(current),
|
current->get_name(current),
|
||||||
my_host->get_address(my_host),
|
my_host->get_string(my_host),
|
||||||
other_host->get_address(other_host));
|
other_host->get_string(other_host));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
iterator->destroy(iterator);
|
iterator->destroy(iterator);
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
|
|
||||||
#include <utils/linked_list.h>
|
#include <utils/linked_list.h>
|
||||||
#include <utils/identification.h>
|
#include <utils/identification.h>
|
||||||
#include <utils/logger.h>
|
#include <utils/logger_manager.h>
|
||||||
|
|
||||||
typedef struct private_policy_t private_policy_t;
|
typedef struct private_policy_t private_policy_t;
|
||||||
|
|
||||||
|
@ -105,9 +105,9 @@ struct private_policy_t {
|
||||||
u_int32_t jitter;
|
u_int32_t jitter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* select_traffic_selectors for both
|
* logger
|
||||||
*/
|
*/
|
||||||
linked_list_t *(*select_traffic_selectors) (private_policy_t *,linked_list_t*,linked_list_t*);
|
logger_t *logger;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -201,21 +201,6 @@ static linked_list_t *get_other_traffic_selectors(private_policy_t *this, traffi
|
||||||
return this->other_ts;
|
return this->other_ts;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Implementation of private_policy_t.select_my_traffic_selectors
|
|
||||||
*/
|
|
||||||
static linked_list_t *select_my_traffic_selectors(private_policy_t *this, linked_list_t *supplied)
|
|
||||||
{
|
|
||||||
return this->select_traffic_selectors(this, this->my_ts, supplied);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implementation of private_policy_t.select_other_traffic_selectors
|
|
||||||
*/
|
|
||||||
static linked_list_t *select_other_traffic_selectors(private_policy_t *this, linked_list_t *supplied)
|
|
||||||
{
|
|
||||||
return this->select_traffic_selectors(this, this->other_ts, supplied);
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* Implementation of private_policy_t.select_traffic_selectors
|
* Implementation of private_policy_t.select_traffic_selectors
|
||||||
*/
|
*/
|
||||||
|
@ -225,6 +210,9 @@ static linked_list_t *select_traffic_selectors(private_policy_t *this, linked_li
|
||||||
traffic_selector_t *supplied_ts, *stored_ts, *selected_ts;
|
traffic_selector_t *supplied_ts, *stored_ts, *selected_ts;
|
||||||
linked_list_t *selected = linked_list_create();
|
linked_list_t *selected = linked_list_create();
|
||||||
|
|
||||||
|
this->logger->log(this->logger, CONTROL|LEVEL1,
|
||||||
|
"selecting traffic selectors for %s host",
|
||||||
|
stored == this->my_ts ? "local" : "remote");
|
||||||
|
|
||||||
stored_iter = stored->create_iterator(stored, TRUE);
|
stored_iter = stored->create_iterator(stored, TRUE);
|
||||||
supplied_iter = supplied->create_iterator(supplied, TRUE);
|
supplied_iter = supplied->create_iterator(supplied, TRUE);
|
||||||
|
@ -240,11 +228,19 @@ static linked_list_t *select_traffic_selectors(private_policy_t *this, linked_li
|
||||||
{
|
{
|
||||||
supplied_iter->current(supplied_iter, (void**)&supplied_ts);
|
supplied_iter->current(supplied_iter, (void**)&supplied_ts);
|
||||||
|
|
||||||
|
this->logger->log(this->logger, CONTROL|LEVEL2,
|
||||||
|
" stored %s <=> %s received",
|
||||||
|
stored_ts->get_string(stored_ts),
|
||||||
|
supplied_ts->get_string(supplied_ts));
|
||||||
|
|
||||||
selected_ts = stored_ts->get_subset(stored_ts, supplied_ts);
|
selected_ts = stored_ts->get_subset(stored_ts, supplied_ts);
|
||||||
if (selected_ts)
|
if (selected_ts)
|
||||||
{
|
{
|
||||||
/* got a match, add to list */
|
/* got a match, add to list */
|
||||||
selected->insert_last(selected, (void*)selected_ts);
|
selected->insert_last(selected, (void*)selected_ts);
|
||||||
|
|
||||||
|
this->logger->log(this->logger, CONTROL|LEVEL1, " got a match: %s",
|
||||||
|
selected_ts->get_string(selected_ts));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -254,6 +250,22 @@ static linked_list_t *select_traffic_selectors(private_policy_t *this, linked_li
|
||||||
return selected;
|
return selected;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of private_policy_t.select_my_traffic_selectors
|
||||||
|
*/
|
||||||
|
static linked_list_t *select_my_traffic_selectors(private_policy_t *this, linked_list_t *supplied)
|
||||||
|
{
|
||||||
|
return select_traffic_selectors(this, this->my_ts, supplied);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of private_policy_t.select_other_traffic_selectors
|
||||||
|
*/
|
||||||
|
static linked_list_t *select_other_traffic_selectors(private_policy_t *this, linked_list_t *supplied)
|
||||||
|
{
|
||||||
|
return select_traffic_selectors(this, this->other_ts, supplied);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of policy_t.get_proposal_iterator
|
* Implementation of policy_t.get_proposal_iterator
|
||||||
*/
|
*/
|
||||||
|
@ -365,7 +377,7 @@ static u_int32_t get_hard_lifetime(private_policy_t *this)
|
||||||
/**
|
/**
|
||||||
* Implements policy_t.clone.
|
* Implements policy_t.clone.
|
||||||
*/
|
*/
|
||||||
static policy_t *clone(private_policy_t *this)
|
static policy_t *clone_(private_policy_t *this)
|
||||||
{
|
{
|
||||||
private_policy_t *clone = (private_policy_t*)policy_create(this->name,
|
private_policy_t *clone = (private_policy_t*)policy_create(this->name,
|
||||||
this->my_id->clone(this->my_id),
|
this->my_id->clone(this->my_id),
|
||||||
|
@ -507,7 +519,7 @@ policy_t *policy_create(char *name, identification_t *my_id, identification_t *o
|
||||||
this->public.add_updown = (void(*)(policy_t*,char*))add_updown;
|
this->public.add_updown = (void(*)(policy_t*,char*))add_updown;
|
||||||
this->public.get_soft_lifetime = (u_int32_t (*) (policy_t *))get_soft_lifetime;
|
this->public.get_soft_lifetime = (u_int32_t (*) (policy_t *))get_soft_lifetime;
|
||||||
this->public.get_hard_lifetime = (u_int32_t (*) (policy_t *))get_hard_lifetime;
|
this->public.get_hard_lifetime = (u_int32_t (*) (policy_t *))get_hard_lifetime;
|
||||||
this->public.clone = (policy_t*(*)(policy_t*))clone;
|
this->public.clone = (policy_t*(*)(policy_t*))clone_;
|
||||||
this->public.destroy = (void(*)(policy_t*))destroy;
|
this->public.destroy = (void(*)(policy_t*))destroy;
|
||||||
|
|
||||||
/* apply init values */
|
/* apply init values */
|
||||||
|
@ -521,10 +533,10 @@ policy_t *policy_create(char *name, identification_t *my_id, identification_t *o
|
||||||
/* initialize private members*/
|
/* initialize private members*/
|
||||||
this->my_ca = NULL;
|
this->my_ca = NULL;
|
||||||
this->other_ca = NULL;
|
this->other_ca = NULL;
|
||||||
this->select_traffic_selectors = select_traffic_selectors;
|
|
||||||
this->proposals = linked_list_create();
|
this->proposals = linked_list_create();
|
||||||
this->my_ts = linked_list_create();
|
this->my_ts = linked_list_create();
|
||||||
this->other_ts = linked_list_create();
|
this->other_ts = linked_list_create();
|
||||||
|
this->logger = logger_manager->get_logger(logger_manager, CONFIG);
|
||||||
|
|
||||||
return (&this->public);
|
return (&this->public);
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,13 +21,14 @@
|
||||||
* for more details.
|
* for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
|
||||||
#include "traffic_selector.h"
|
#include "traffic_selector.h"
|
||||||
|
|
||||||
#include <utils/linked_list.h>
|
#include <utils/linked_list.h>
|
||||||
#include <utils/identification.h>
|
#include <utils/identification.h>
|
||||||
#include <utils/logger_manager.h>
|
|
||||||
#include <arpa/inet.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
typedef struct private_traffic_selector_t private_traffic_selector_t;
|
typedef struct private_traffic_selector_t private_traffic_selector_t;
|
||||||
|
|
||||||
|
@ -76,9 +77,9 @@ struct private_traffic_selector_t {
|
||||||
u_int16_t to_port;
|
u_int16_t to_port;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logger reference
|
* string representation of this traffic selector
|
||||||
*/
|
*/
|
||||||
logger_t *logger;
|
char *string;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -86,6 +87,122 @@ struct private_traffic_selector_t {
|
||||||
*/
|
*/
|
||||||
static private_traffic_selector_t *traffic_selector_create(u_int8_t protocol, ts_type_t type, u_int16_t from_port, u_int16_t to_port);
|
static private_traffic_selector_t *traffic_selector_create(u_int8_t protocol, ts_type_t type, u_int16_t from_port, u_int16_t to_port);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* update the string representation of this traffic selector
|
||||||
|
*/
|
||||||
|
static void update_string(private_traffic_selector_t *this)
|
||||||
|
{
|
||||||
|
char buf[256];
|
||||||
|
struct protoent *proto;
|
||||||
|
struct servent *serv;
|
||||||
|
char *serv_proto = NULL;
|
||||||
|
char proto_str[8] = "";
|
||||||
|
char addr_str[INET6_ADDRSTRLEN];
|
||||||
|
char port_str[16] = "";
|
||||||
|
char mask_str[8] = "";
|
||||||
|
char proto_port_str[32] = "";
|
||||||
|
bool has_proto = FALSE, has_port = FALSE;
|
||||||
|
|
||||||
|
if (this->type == TS_IPV4_ADDR_RANGE)
|
||||||
|
{
|
||||||
|
u_int32_t from_no, to_no, bit;
|
||||||
|
u_int8_t mask = 32;
|
||||||
|
|
||||||
|
/* build address string */
|
||||||
|
from_no = htonl(this->from_addr_ipv4);
|
||||||
|
to_no = htonl(this->to_addr_ipv4);
|
||||||
|
inet_ntop(AF_INET, &from_no, addr_str, sizeof(addr_str));
|
||||||
|
|
||||||
|
/* build network mask string */
|
||||||
|
for (bit = 0; bit < 32; bit++)
|
||||||
|
{
|
||||||
|
if ((1<<bit & from_no) != (1<<bit & to_no))
|
||||||
|
{
|
||||||
|
mask = bit;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (mask != 32)
|
||||||
|
{
|
||||||
|
snprintf(mask_str, sizeof(mask_str), "/%d", mask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* TODO: be a little bit more verbose ;-) */
|
||||||
|
snprintf(addr_str, sizeof(addr_str), "(IPv6 address range)");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* build protocol string */
|
||||||
|
if (this->protocol)
|
||||||
|
{
|
||||||
|
proto = getprotobynumber(this->protocol);
|
||||||
|
if (proto)
|
||||||
|
{
|
||||||
|
snprintf(proto_str, sizeof(proto_str), "%s", proto->p_name);
|
||||||
|
serv_proto = proto->p_name;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
snprintf(proto_str, sizeof(proto_str), "%d", this->protocol);
|
||||||
|
}
|
||||||
|
has_proto = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* build port string */
|
||||||
|
if (this->from_port == this->to_port)
|
||||||
|
{
|
||||||
|
serv = getservbyport(htons(this->from_port), serv_proto);
|
||||||
|
if (serv)
|
||||||
|
{
|
||||||
|
snprintf(port_str, sizeof(port_str), "%s", serv->s_name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
snprintf(port_str, sizeof(port_str), "%d", this->from_port);
|
||||||
|
}
|
||||||
|
has_port = TRUE;
|
||||||
|
}
|
||||||
|
else if (!(this->from_port == 0 && this->to_port == 0xFFFF))
|
||||||
|
{
|
||||||
|
snprintf(port_str, sizeof(port_str), "%d-%d",
|
||||||
|
this->from_port, this->to_port);
|
||||||
|
has_port = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* concatenate port & proto string */
|
||||||
|
if (has_proto && has_port)
|
||||||
|
{
|
||||||
|
snprintf(proto_port_str, sizeof(proto_port_str), "[%s/%s]",
|
||||||
|
proto_str, port_str);
|
||||||
|
}
|
||||||
|
else if (has_proto)
|
||||||
|
{
|
||||||
|
snprintf(proto_port_str, sizeof(proto_port_str), "[%s]", proto_str);
|
||||||
|
}
|
||||||
|
else if (has_port)
|
||||||
|
{
|
||||||
|
snprintf(proto_port_str, sizeof(proto_port_str), "[%s]", port_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* concatenate it all */
|
||||||
|
snprintf(buf, sizeof(buf), "%s%s%s", addr_str, mask_str, proto_port_str);
|
||||||
|
|
||||||
|
if (this->string)
|
||||||
|
{
|
||||||
|
free(this->string);
|
||||||
|
}
|
||||||
|
this->string = strdup(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* implements traffic_selector_t.get_string
|
||||||
|
*/
|
||||||
|
static char *get_string(private_traffic_selector_t *this)
|
||||||
|
{
|
||||||
|
return this->string;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* implements traffic_selector_t.get_subset
|
* implements traffic_selector_t.get_subset
|
||||||
*/
|
*/
|
||||||
|
@ -99,18 +216,11 @@ static traffic_selector_t *get_subset(private_traffic_selector_t *this, private_
|
||||||
u_int8_t protocol;
|
u_int8_t protocol;
|
||||||
private_traffic_selector_t *new_ts;
|
private_traffic_selector_t *new_ts;
|
||||||
|
|
||||||
/* TODO: make output more human readable */
|
|
||||||
this->logger->log(this->logger, CONTROL|LEVEL2,
|
|
||||||
"matching traffic selector ranges %x:%d-%x:%d <=> %x:%d-%x:%d",
|
|
||||||
this->from_addr_ipv4, this->from_port, this->to_addr_ipv4, this->to_port,
|
|
||||||
other->from_addr_ipv4, other->from_port, other->to_addr_ipv4, other->to_port);
|
|
||||||
/* calculate the maximum address range allowed for both */
|
/* calculate the maximum address range allowed for both */
|
||||||
from_addr = max(this->from_addr_ipv4, other->from_addr_ipv4);
|
from_addr = max(this->from_addr_ipv4, other->from_addr_ipv4);
|
||||||
to_addr = min(this->to_addr_ipv4, other->to_addr_ipv4);
|
to_addr = min(this->to_addr_ipv4, other->to_addr_ipv4);
|
||||||
if (from_addr > to_addr)
|
if (from_addr > to_addr)
|
||||||
{
|
{
|
||||||
this->logger->log(this->logger, CONTROL|LEVEL2,
|
|
||||||
"no match in address range");
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,8 +229,6 @@ static traffic_selector_t *get_subset(private_traffic_selector_t *this, private_
|
||||||
to_port = min(this->to_port, other->to_port);
|
to_port = min(this->to_port, other->to_port);
|
||||||
if (from_port > to_port)
|
if (from_port > to_port)
|
||||||
{
|
{
|
||||||
this->logger->log(this->logger, CONTROL|LEVEL2,
|
|
||||||
"no match in port range");
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,10 +240,8 @@ static traffic_selector_t *get_subset(private_traffic_selector_t *this, private_
|
||||||
new_ts->from_addr_ipv4 = from_addr;
|
new_ts->from_addr_ipv4 = from_addr;
|
||||||
new_ts->to_addr_ipv4 = to_addr;
|
new_ts->to_addr_ipv4 = to_addr;
|
||||||
new_ts->type = TS_IPV4_ADDR_RANGE;
|
new_ts->type = TS_IPV4_ADDR_RANGE;
|
||||||
|
update_string(new_ts);
|
||||||
|
|
||||||
this->logger->log(this->logger, CONTROL|LEVEL2,
|
|
||||||
"got a match: %x:%d-%x:%d",
|
|
||||||
new_ts->from_addr_ipv4, new_ts->from_port, new_ts->to_addr_ipv4, new_ts->to_port);
|
|
||||||
return &(new_ts->public);
|
return &(new_ts->public);
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -227,35 +333,6 @@ static u_int8_t get_protocol(private_traffic_selector_t *this)
|
||||||
return this->protocol;
|
return this->protocol;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Implements traffic_selector_t.get_netmask.
|
|
||||||
*/
|
|
||||||
static u_int8_t get_netmask(private_traffic_selector_t *this)
|
|
||||||
{
|
|
||||||
switch (this->type)
|
|
||||||
{
|
|
||||||
case TS_IPV4_ADDR_RANGE:
|
|
||||||
{
|
|
||||||
u_int32_t from, to, bit;
|
|
||||||
from = htonl(this->from_addr_ipv4);
|
|
||||||
to = htonl(this->to_addr_ipv4);
|
|
||||||
for (bit = 0; bit < 32; bit++)
|
|
||||||
{
|
|
||||||
if ((1<<bit & from) != (1<<bit & to))
|
|
||||||
{
|
|
||||||
return bit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 32;
|
|
||||||
}
|
|
||||||
case TS_IPV6_ADDR_RANGE:
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements traffic_selector_t.update_address_range.
|
* Implements traffic_selector_t.update_address_range.
|
||||||
*/
|
*/
|
||||||
|
@ -266,12 +343,12 @@ static void update_address_range(private_traffic_selector_t *this, host_t *host)
|
||||||
{
|
{
|
||||||
if (this->from_addr_ipv4 == 0)
|
if (this->from_addr_ipv4 == 0)
|
||||||
{
|
{
|
||||||
chunk_t from = host->get_address_as_chunk(host);
|
chunk_t from = host->get_address(host);
|
||||||
this->from_addr_ipv4 = ntohl(*((u_int32_t*)from.ptr));
|
this->from_addr_ipv4 = ntohl(*((u_int32_t*)from.ptr));
|
||||||
this->to_addr_ipv4 = this->from_addr_ipv4;
|
this->to_addr_ipv4 = this->from_addr_ipv4;
|
||||||
chunk_free(&from);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
update_string(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -281,6 +358,7 @@ static traffic_selector_t *clone_(private_traffic_selector_t *this)
|
||||||
{
|
{
|
||||||
private_traffic_selector_t *clone = traffic_selector_create(this->protocol, this->type, this->from_port, this->to_port);
|
private_traffic_selector_t *clone = traffic_selector_create(this->protocol, this->type, this->from_port, this->to_port);
|
||||||
clone->type = this->type;
|
clone->type = this->type;
|
||||||
|
clone->string = strdup(this->string);
|
||||||
switch (clone->type)
|
switch (clone->type)
|
||||||
{
|
{
|
||||||
case TS_IPV4_ADDR_RANGE:
|
case TS_IPV4_ADDR_RANGE:
|
||||||
|
@ -303,13 +381,14 @@ static traffic_selector_t *clone_(private_traffic_selector_t *this)
|
||||||
*/
|
*/
|
||||||
static void destroy(private_traffic_selector_t *this)
|
static void destroy(private_traffic_selector_t *this)
|
||||||
{
|
{
|
||||||
|
free(this->string);
|
||||||
free(this);
|
free(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* see header
|
* see header
|
||||||
*/
|
*/
|
||||||
traffic_selector_t *traffic_selector_create_from_bytes(u_int8_t protocol, ts_type_t type, chunk_t from_addr, int16_t from_port, chunk_t to_addr, u_int16_t to_port)
|
traffic_selector_t *traffic_selector_create_from_bytes(u_int8_t protocol, ts_type_t type, chunk_t from_addr, u_int16_t from_port, chunk_t to_addr, u_int16_t to_port)
|
||||||
{
|
{
|
||||||
private_traffic_selector_t *this = traffic_selector_create(protocol, type, from_port, to_port);
|
private_traffic_selector_t *this = traffic_selector_create(protocol, type, from_port, to_port);
|
||||||
|
|
||||||
|
@ -335,6 +414,9 @@ traffic_selector_t *traffic_selector_create_from_bytes(u_int8_t protocol, ts_typ
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
update_string(this);
|
||||||
|
|
||||||
return (&this->public);
|
return (&this->public);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -352,7 +434,7 @@ traffic_selector_t *traffic_selector_create_from_subnet(host_t *net, u_int8_t ne
|
||||||
chunk_t from;
|
chunk_t from;
|
||||||
|
|
||||||
this->type = TS_IPV4_ADDR_RANGE;
|
this->type = TS_IPV4_ADDR_RANGE;
|
||||||
from = net->get_address_as_chunk(net);
|
from = net->get_address(net);
|
||||||
this->from_addr_ipv4 = ntohl(*((u_int32_t*)from.ptr));
|
this->from_addr_ipv4 = ntohl(*((u_int32_t*)from.ptr));
|
||||||
if (this->from_addr_ipv4 == 0)
|
if (this->from_addr_ipv4 == 0)
|
||||||
{
|
{
|
||||||
|
@ -363,7 +445,6 @@ traffic_selector_t *traffic_selector_create_from_subnet(host_t *net, u_int8_t ne
|
||||||
{
|
{
|
||||||
this->to_addr_ipv4 = this->from_addr_ipv4 | ((1 << (32 - netbits)) - 1);
|
this->to_addr_ipv4 = this->from_addr_ipv4 | ((1 << (32 - netbits)) - 1);
|
||||||
}
|
}
|
||||||
chunk_free(&from);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case AF_INET6:
|
case AF_INET6:
|
||||||
|
@ -379,6 +460,8 @@ traffic_selector_t *traffic_selector_create_from_subnet(host_t *net, u_int8_t ne
|
||||||
this->to_port = port;
|
this->to_port = port;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
update_string(this);
|
||||||
|
|
||||||
return (&this->public);
|
return (&this->public);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -420,6 +503,8 @@ traffic_selector_t *traffic_selector_create_from_string(u_int8_t protocol, ts_ty
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
update_string(this);
|
||||||
|
|
||||||
return (&this->public);
|
return (&this->public);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -432,13 +517,13 @@ static private_traffic_selector_t *traffic_selector_create(u_int8_t protocol, ts
|
||||||
|
|
||||||
/* public functions */
|
/* public functions */
|
||||||
this->public.get_subset = (traffic_selector_t*(*)(traffic_selector_t*,traffic_selector_t*))get_subset;
|
this->public.get_subset = (traffic_selector_t*(*)(traffic_selector_t*,traffic_selector_t*))get_subset;
|
||||||
|
this->public.get_string = (char*(*)(traffic_selector_t*))get_string;
|
||||||
this->public.get_from_address = (chunk_t(*)(traffic_selector_t*))get_from_address;
|
this->public.get_from_address = (chunk_t(*)(traffic_selector_t*))get_from_address;
|
||||||
this->public.get_to_address = (chunk_t(*)(traffic_selector_t*))get_to_address;
|
this->public.get_to_address = (chunk_t(*)(traffic_selector_t*))get_to_address;
|
||||||
this->public.get_from_port = (u_int16_t(*)(traffic_selector_t*))get_from_port;
|
this->public.get_from_port = (u_int16_t(*)(traffic_selector_t*))get_from_port;
|
||||||
this->public.get_to_port = (u_int16_t(*)(traffic_selector_t*))get_to_port;
|
this->public.get_to_port = (u_int16_t(*)(traffic_selector_t*))get_to_port;
|
||||||
this->public.get_type = (ts_type_t(*)(traffic_selector_t*))get_type;
|
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.get_protocol = (u_int8_t(*)(traffic_selector_t*))get_protocol;
|
||||||
this->public.get_netmask = (u_int8_t(*)(traffic_selector_t*))get_netmask;
|
|
||||||
this->public.update_address_range = (void(*)(traffic_selector_t*,host_t*))update_address_range;
|
this->public.update_address_range = (void(*)(traffic_selector_t*,host_t*))update_address_range;
|
||||||
this->public.clone = (traffic_selector_t*(*)(traffic_selector_t*))clone_;
|
this->public.clone = (traffic_selector_t*(*)(traffic_selector_t*))clone_;
|
||||||
this->public.destroy = (void(*)(traffic_selector_t*))destroy;
|
this->public.destroy = (void(*)(traffic_selector_t*))destroy;
|
||||||
|
@ -447,7 +532,7 @@ static private_traffic_selector_t *traffic_selector_create(u_int8_t protocol, ts
|
||||||
this->to_port = to_port;
|
this->to_port = to_port;
|
||||||
this->protocol = protocol;
|
this->protocol = protocol;
|
||||||
this->type = type;
|
this->type = type;
|
||||||
this->logger = logger_manager->get_logger(logger_manager, CONFIG);
|
this->string = NULL;
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,7 +91,8 @@ struct traffic_selector_t {
|
||||||
* - created subset of them
|
* - created subset of them
|
||||||
* - or NULL if no match between this and other
|
* - or NULL if no match between this and other
|
||||||
*/
|
*/
|
||||||
traffic_selector_t *(*get_subset) (traffic_selector_t *this, traffic_selector_t *other);
|
traffic_selector_t *(*get_subset) (traffic_selector_t *this,
|
||||||
|
traffic_selector_t *other);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Clone a traffic selector.
|
* @brief Clone a traffic selector.
|
||||||
|
@ -104,10 +105,7 @@ struct traffic_selector_t {
|
||||||
/**
|
/**
|
||||||
* @brief Get starting address of this ts as a chunk.
|
* @brief Get starting address of this ts as a chunk.
|
||||||
*
|
*
|
||||||
* Data is in network order and represents the address.
|
* Chunk is in network order gets allocated.
|
||||||
* Size depends on protocol.
|
|
||||||
*
|
|
||||||
* Resulting chunk data is allocated and must be freed!
|
|
||||||
*
|
*
|
||||||
* @param this calling object
|
* @param this calling object
|
||||||
* @return chunk containing the address
|
* @return chunk containing the address
|
||||||
|
@ -117,10 +115,7 @@ struct traffic_selector_t {
|
||||||
/**
|
/**
|
||||||
* @brief Get ending address of this ts as a chunk.
|
* @brief Get ending address of this ts as a chunk.
|
||||||
*
|
*
|
||||||
* Data is in network order and represents the address.
|
* Chunk is in network order gets allocated.
|
||||||
* Size depends on protocol.
|
|
||||||
*
|
|
||||||
* Resulting chunk data is allocated and must be freed!
|
|
||||||
*
|
*
|
||||||
* @param this calling object
|
* @param this calling object
|
||||||
* @return chunk containing the address
|
* @return chunk containing the address
|
||||||
|
@ -165,20 +160,6 @@ struct traffic_selector_t {
|
||||||
*/
|
*/
|
||||||
u_int8_t (*get_protocol) (traffic_selector_t *this);
|
u_int8_t (*get_protocol) (traffic_selector_t *this);
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get the netmask of the address range.
|
|
||||||
*
|
|
||||||
* Returns the number of bits associated to the subnet.
|
|
||||||
* (As the "24" in "192.168.0.0/24"). This is approximated
|
|
||||||
* if the address range is not a complete subnet! Since Linux
|
|
||||||
* does not support full IP address ranges (yet), we can't do this
|
|
||||||
* (much) better.
|
|
||||||
*
|
|
||||||
* @param this calling obect
|
|
||||||
* @return netmask as "bits for subnet"
|
|
||||||
*/
|
|
||||||
u_int8_t (*get_netmask) (traffic_selector_t *this);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Update the address of a traffic selector.
|
* @brief Update the address of a traffic selector.
|
||||||
*
|
*
|
||||||
|
@ -192,6 +173,16 @@ struct traffic_selector_t {
|
||||||
*/
|
*/
|
||||||
void (*update_address_range) (traffic_selector_t *this, host_t* host);
|
void (*update_address_range) (traffic_selector_t *this, host_t* host);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get a string representation of the traffic selector.
|
||||||
|
*
|
||||||
|
* String points to internal data, do not free/modify.
|
||||||
|
*
|
||||||
|
* @param this calling object
|
||||||
|
* @return pointer to a string.
|
||||||
|
*/
|
||||||
|
char* (*get_string) (traffic_selector_t *this);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Destroys the ts object
|
* @brief Destroys the ts object
|
||||||
*
|
*
|
||||||
|
@ -215,7 +206,10 @@ struct traffic_selector_t {
|
||||||
*
|
*
|
||||||
* @ingroup config
|
* @ingroup config
|
||||||
*/
|
*/
|
||||||
traffic_selector_t *traffic_selector_create_from_string(u_int8_t protocol, ts_type_t type, char *from_addr, u_int16_t from_port, char *to_addr, u_int16_t to_port);
|
traffic_selector_t *traffic_selector_create_from_string(
|
||||||
|
u_int8_t protocol, ts_type_t type,
|
||||||
|
char *from_addr, u_int16_t from_port,
|
||||||
|
char *to_addr, u_int16_t to_port);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Create a new traffic selector using data read from the net.
|
* @brief Create a new traffic selector using data read from the net.
|
||||||
|
@ -236,7 +230,10 @@ traffic_selector_t *traffic_selector_create_from_string(u_int8_t protocol, ts_ty
|
||||||
*
|
*
|
||||||
* @ingroup config
|
* @ingroup config
|
||||||
*/
|
*/
|
||||||
traffic_selector_t *traffic_selector_create_from_bytes(u_int8_t protocol, ts_type_t type, chunk_t from_address, int16_t from_port, chunk_t to_address, u_int16_t to_port);
|
traffic_selector_t *traffic_selector_create_from_bytes(
|
||||||
|
u_int8_t protocol, ts_type_t type,
|
||||||
|
chunk_t from_address, u_int16_t from_port,
|
||||||
|
chunk_t to_address, u_int16_t to_port);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Create a new traffic selector defining a whole subnet.
|
* @brief Create a new traffic selector defining a whole subnet.
|
||||||
|
@ -256,6 +253,8 @@ traffic_selector_t *traffic_selector_create_from_bytes(u_int8_t protocol, ts_typ
|
||||||
*
|
*
|
||||||
* @ingroup config
|
* @ingroup config
|
||||||
*/
|
*/
|
||||||
traffic_selector_t *traffic_selector_create_from_subnet(host_t *net, u_int8_t netbits, u_int8_t protocol, u_int16_t port);
|
traffic_selector_t *traffic_selector_create_from_subnet(
|
||||||
|
host_t *net, u_int8_t netbits,
|
||||||
|
u_int8_t protocol, u_int16_t port);
|
||||||
|
|
||||||
#endif /* TRAFFIC_SELECTOR_H_ */
|
#endif /* TRAFFIC_SELECTOR_H_ */
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
+ doxygen cleanup (charon/lib)
|
+ doxygen cleanup (charon/lib)
|
||||||
+ new build environment (autotools?)
|
+ new build environment (autotools?)
|
||||||
|
|
||||||
/ useable certificate support
|
+ useable certificate support
|
||||||
+ more id types (use atodn from pluto)
|
+ more id types (use atodn from pluto)
|
||||||
+ rewrite certificate storage the clean way
|
+ rewrite certificate storage the clean way
|
||||||
+ further subjectAltName support
|
+ further subjectAltName support
|
||||||
|
|
|
@ -82,11 +82,6 @@ struct private_traffic_selector_substructure_t {
|
||||||
* Ending address.
|
* Ending address.
|
||||||
*/
|
*/
|
||||||
chunk_t ending_address;
|
chunk_t ending_address;
|
||||||
|
|
||||||
/**
|
|
||||||
* update length
|
|
||||||
*/
|
|
||||||
void (*compute_length) (private_traffic_selector_substructure_t *this);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -137,7 +132,6 @@ encoding_rule_t traffic_selector_substructure_encodings[] = {
|
||||||
*/
|
*/
|
||||||
static status_t verify(private_traffic_selector_substructure_t *this)
|
static status_t verify(private_traffic_selector_substructure_t *this)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (this->start_port > this->end_port)
|
if (this->start_port > this->end_port)
|
||||||
{
|
{
|
||||||
return FAILED;
|
return FAILED;
|
||||||
|
@ -162,7 +156,6 @@ static status_t verify(private_traffic_selector_substructure_t *this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -196,6 +189,7 @@ static payload_type_t get_next_type(private_traffic_selector_substructure_t *thi
|
||||||
*/
|
*/
|
||||||
static void set_next_type(private_traffic_selector_substructure_t *this,payload_type_t type)
|
static void set_next_type(private_traffic_selector_substructure_t *this,payload_type_t type)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -206,82 +200,6 @@ static size_t get_length(private_traffic_selector_substructure_t *this)
|
||||||
return this->payload_length;
|
return this->payload_length;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Implementation of traffic_selector_substructure_t.get_ts_type.
|
|
||||||
*/
|
|
||||||
static ts_type_t get_ts_type (private_traffic_selector_substructure_t *this)
|
|
||||||
{
|
|
||||||
return this->ts_type;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implementation of traffic_selector_substructure_t.set_ts_type.
|
|
||||||
*/
|
|
||||||
static void set_ts_type (private_traffic_selector_substructure_t *this,ts_type_t ts_type)
|
|
||||||
{
|
|
||||||
this->ts_type = ts_type;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implementation of traffic_selector_substructure_t.get_protocol_id.
|
|
||||||
*/
|
|
||||||
static u_int8_t get_protocol_id (private_traffic_selector_substructure_t *this)
|
|
||||||
{
|
|
||||||
return this->ip_protocol_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implementation of traffic_selector_substructure_t.set_protocol_id.
|
|
||||||
*/
|
|
||||||
static void set_protocol_id (private_traffic_selector_substructure_t *this,u_int8_t protocol_id)
|
|
||||||
{
|
|
||||||
this->ip_protocol_id = protocol_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implementation of traffic_selector_substructure_t.get_start_host.
|
|
||||||
*/
|
|
||||||
static host_t * get_start_host (private_traffic_selector_substructure_t *this)
|
|
||||||
{
|
|
||||||
return (host_create_from_chunk(AF_INET,this->starting_address, this->start_port));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implementation of traffic_selector_substructure_t.set_start_host.
|
|
||||||
*/
|
|
||||||
static void set_start_host (private_traffic_selector_substructure_t *this,host_t *start_host)
|
|
||||||
{
|
|
||||||
this->start_port = start_host->get_port(start_host);
|
|
||||||
if (this->starting_address.ptr != NULL)
|
|
||||||
{
|
|
||||||
chunk_free(&(this->starting_address));
|
|
||||||
}
|
|
||||||
this->starting_address = start_host->get_address_as_chunk(start_host);
|
|
||||||
this->compute_length(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implementation of traffic_selector_substructure_t.get_end_host.
|
|
||||||
*/
|
|
||||||
static host_t *get_end_host (private_traffic_selector_substructure_t *this)
|
|
||||||
{
|
|
||||||
return (host_create_from_chunk(AF_INET,this->ending_address, this->end_port));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implementation of traffic_selector_substructure_t.set_end_host.
|
|
||||||
*/
|
|
||||||
static void set_end_host (private_traffic_selector_substructure_t *this,host_t *end_host)
|
|
||||||
{
|
|
||||||
this->end_port = end_host->get_port(end_host);
|
|
||||||
if (this->ending_address.ptr != NULL)
|
|
||||||
{
|
|
||||||
chunk_free(&(this->ending_address));
|
|
||||||
}
|
|
||||||
this->ending_address = end_host->get_address_as_chunk(end_host);
|
|
||||||
this->compute_length(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of traffic_selector_substructure_t.get_traffic_selector.
|
* Implementation of traffic_selector_substructure_t.get_traffic_selector.
|
||||||
*/
|
*/
|
||||||
|
@ -295,11 +213,12 @@ static traffic_selector_t *get_traffic_selector(private_traffic_selector_substru
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of private_ts_payload_t.compute_length
|
* recompute length field of the payload
|
||||||
*/
|
*/
|
||||||
void compute_length(private_traffic_selector_substructure_t *this)
|
void compute_length(private_traffic_selector_substructure_t *this)
|
||||||
{
|
{
|
||||||
this->payload_length = TRAFFIC_SELECTOR_HEADER_LENGTH + this->ending_address.len + this->starting_address.len;
|
this->payload_length = TRAFFIC_SELECTOR_HEADER_LENGTH +
|
||||||
|
this->ending_address.len + this->starting_address.len;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -329,19 +248,8 @@ traffic_selector_substructure_t *traffic_selector_substructure_create()
|
||||||
this->public.payload_interface.destroy = (void (*) (payload_t *))destroy;
|
this->public.payload_interface.destroy = (void (*) (payload_t *))destroy;
|
||||||
|
|
||||||
/* public functions */
|
/* public functions */
|
||||||
this->public.destroy = (void (*) (traffic_selector_substructure_t *)) destroy;
|
|
||||||
this->public.get_ts_type = (ts_type_t (*) (traffic_selector_substructure_t *)) get_ts_type;
|
|
||||||
this->public.set_ts_type = (void (*) (traffic_selector_substructure_t *,ts_type_t)) set_ts_type;
|
|
||||||
this->public.get_protocol_id = (u_int8_t (*) (traffic_selector_substructure_t *)) get_protocol_id;
|
|
||||||
this->public.set_protocol_id = (void (*) (traffic_selector_substructure_t *,u_int8_t)) set_protocol_id;
|
|
||||||
this->public.get_start_host = (host_t * (*) (traffic_selector_substructure_t *))get_start_host;
|
|
||||||
this->public.set_start_host = (void (*) (traffic_selector_substructure_t *, host_t *))set_start_host;
|
|
||||||
this->public.get_end_host = (host_t * (*) (traffic_selector_substructure_t *))get_end_host;
|
|
||||||
this->public.set_end_host = (void (*) (traffic_selector_substructure_t *, host_t *))set_end_host;
|
|
||||||
this->public.get_traffic_selector = (traffic_selector_t* (*)(traffic_selector_substructure_t*))get_traffic_selector;
|
this->public.get_traffic_selector = (traffic_selector_t* (*)(traffic_selector_substructure_t*))get_traffic_selector;
|
||||||
|
this->public.destroy = (void (*) (traffic_selector_substructure_t *)) destroy;
|
||||||
/* private functions */
|
|
||||||
this->compute_length = compute_length;
|
|
||||||
|
|
||||||
/* private variables */
|
/* private variables */
|
||||||
this->payload_length = TRAFFIC_SELECTOR_HEADER_LENGTH;
|
this->payload_length = TRAFFIC_SELECTOR_HEADER_LENGTH;
|
||||||
|
@ -369,7 +277,7 @@ traffic_selector_substructure_t *traffic_selector_substructure_create_from_traff
|
||||||
this->starting_address = traffic_selector->get_from_address(traffic_selector);
|
this->starting_address = traffic_selector->get_from_address(traffic_selector);
|
||||||
this->ending_address = traffic_selector->get_to_address(traffic_selector);
|
this->ending_address = traffic_selector->get_to_address(traffic_selector);
|
||||||
|
|
||||||
this->compute_length(this);
|
compute_length(this);
|
||||||
|
|
||||||
return &(this->public);
|
return &(this->public);
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,7 +74,7 @@ static bool is_local_address(private_interfaces_t *this, host_t *host)
|
||||||
while (iterator->iterate(iterator, (void**)&lhost))
|
while (iterator->iterate(iterator, (void**)&lhost))
|
||||||
{
|
{
|
||||||
if (host->get_family(host) == lhost->get_family(lhost) &&
|
if (host->get_family(host) == lhost->get_family(lhost) &&
|
||||||
streq(host->get_address(host), lhost->get_address(lhost)))
|
streq(host->get_string(host), lhost->get_string(lhost)))
|
||||||
{
|
{
|
||||||
iterator->destroy(iterator);
|
iterator->destroy(iterator);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
|
@ -162,8 +162,8 @@ static status_t receiver(private_socket_t *this, packet_t **packet)
|
||||||
pkt->set_destination(pkt, dest);
|
pkt->set_destination(pkt, dest);
|
||||||
|
|
||||||
this->logger->log(this->logger, CONTROL|LEVEL1, "received packet: from %s:%d to %s:%d",
|
this->logger->log(this->logger, CONTROL|LEVEL1, "received packet: from %s:%d to %s:%d",
|
||||||
source->get_address(source), source->get_port(source),
|
source->get_string(source), source->get_port(source),
|
||||||
dest->get_address(dest), dest->get_port(dest));
|
dest->get_string(dest), dest->get_port(dest));
|
||||||
|
|
||||||
data_offset = IP_LEN + UDP_LEN;
|
data_offset = IP_LEN + UDP_LEN;
|
||||||
|
|
||||||
|
@ -200,8 +200,8 @@ status_t sender(private_socket_t *this, packet_t *packet)
|
||||||
data = packet->get_data(packet);
|
data = packet->get_data(packet);
|
||||||
|
|
||||||
this->logger->log(this->logger, CONTROL|LEVEL1, "sending packet: from %s:%d to %s:%d",
|
this->logger->log(this->logger, CONTROL|LEVEL1, "sending packet: from %s:%d to %s:%d",
|
||||||
src->get_address(src), src->get_port(src),
|
src->get_string(src), src->get_port(src),
|
||||||
dst->get_address(dst), dst->get_port(dst));
|
dst->get_string(dst), dst->get_port(dst));
|
||||||
|
|
||||||
/* send data */
|
/* send data */
|
||||||
sport = src->get_port(src);
|
sport = src->get_port(src);
|
||||||
|
@ -404,7 +404,7 @@ static status_t initialize(private_socket_t *this)
|
||||||
if (setsockopt(this->natt_fd, SOL_UDP, UDP_ENCAP, &type, sizeof(type)) < 0)
|
if (setsockopt(this->natt_fd, SOL_UDP, UDP_ENCAP, &type, sizeof(type)) < 0)
|
||||||
{
|
{
|
||||||
this->logger->log(this->logger, ERROR,
|
this->logger->log(this->logger, ERROR,
|
||||||
"unable to set UDP_ENCAP on raw socket! NAT-T may fail! error: %s",
|
"unable to set UDP_ENCAP on NAT-T socket: %s; NAT-T may fail",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -113,8 +113,8 @@ static status_t execute(private_incoming_packet_job_t *this)
|
||||||
src = message->get_source(message);
|
src = message->get_source(message);
|
||||||
dst = message->get_destination(message);
|
dst = message->get_destination(message);
|
||||||
this->logger->log(this->logger, CONTROL, "received packet: from %s:%d to %s:%d",
|
this->logger->log(this->logger, CONTROL, "received packet: from %s:%d to %s:%d",
|
||||||
src->get_address(src), src->get_port(src),
|
src->get_string(src), src->get_port(src),
|
||||||
dst->get_address(dst), dst->get_port(dst));
|
dst->get_string(dst), dst->get_port(dst));
|
||||||
|
|
||||||
status = message->parse_header(message);
|
status = message->parse_header(message);
|
||||||
if (status != SUCCESS)
|
if (status != SUCCESS)
|
||||||
|
|
|
@ -112,8 +112,8 @@ static void add(private_send_queue_t *this, packet_t *packet)
|
||||||
src = packet->get_source(packet);
|
src = packet->get_source(packet);
|
||||||
dst = packet->get_destination(packet);
|
dst = packet->get_destination(packet);
|
||||||
this->logger->log(this->logger, CONTROL, "sending packet: from %s:%d to %s:%d",
|
this->logger->log(this->logger, CONTROL, "sending packet: from %s:%d to %s:%d",
|
||||||
src->get_address(src), src->get_port(src),
|
src->get_string(src), src->get_port(src),
|
||||||
dst->get_address(dst), dst->get_port(dst));
|
dst->get_string(dst), dst->get_port(dst));
|
||||||
|
|
||||||
pthread_mutex_lock(&this->mutex);
|
pthread_mutex_lock(&this->mutex);
|
||||||
this->list->insert_last(this->list, packet);
|
this->list->insert_last(this->list, packet);
|
||||||
|
|
|
@ -22,8 +22,6 @@
|
||||||
* for more details.
|
* for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <netdb.h>
|
|
||||||
|
|
||||||
#include "child_sa.h"
|
#include "child_sa.h"
|
||||||
|
|
||||||
#include <daemon.h>
|
#include <daemon.h>
|
||||||
|
@ -48,18 +46,15 @@ typedef struct sa_policy_t sa_policy_t;
|
||||||
* for deleting a policy...
|
* for deleting a policy...
|
||||||
*/
|
*/
|
||||||
struct sa_policy_t {
|
struct sa_policy_t {
|
||||||
|
/**
|
||||||
struct {
|
* Traffic selector for us
|
||||||
/** subnet address behind peer peer */
|
*/
|
||||||
host_t *net;
|
traffic_selector_t *my_ts;
|
||||||
/** netmask used for net */
|
|
||||||
u_int8_t net_mask;
|
|
||||||
} me, other;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Protocol for this policy, such as TCP/UDP/ICMP...
|
* Traffic selector for other
|
||||||
*/
|
*/
|
||||||
int upper_proto;
|
traffic_selector_t *other_ts;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct private_child_sa_t private_child_sa_t;
|
typedef struct private_child_sa_t private_child_sa_t;
|
||||||
|
@ -343,7 +338,7 @@ static status_t install(private_child_sa_t *this, proposal_t *proposal, prf_plus
|
||||||
/* send SA down to the kernel */
|
/* send SA down to the kernel */
|
||||||
this->logger->log(this->logger, CONTROL|LEVEL2,
|
this->logger->log(this->logger, CONTROL|LEVEL2,
|
||||||
" SPI 0x%.8x, src %s dst %s",
|
" SPI 0x%.8x, src %s dst %s",
|
||||||
ntohl(spi), src->get_address(src), dst->get_address(dst));
|
ntohl(spi), src->get_string(src), dst->get_string(dst));
|
||||||
status = charon->kernel_interface->add_sa(charon->kernel_interface,
|
status = charon->kernel_interface->add_sa(charon->kernel_interface,
|
||||||
src, dst,
|
src, dst,
|
||||||
spi, this->protocol,
|
spi, this->protocol,
|
||||||
|
@ -432,79 +427,52 @@ static status_t add_policies(private_child_sa_t *this, linked_list_t *my_ts_list
|
||||||
while (other_iter->has_next(other_iter))
|
while (other_iter->has_next(other_iter))
|
||||||
{
|
{
|
||||||
/* set up policies for every entry in my_ts_list to every entry in other_ts_list */
|
/* set up policies for every entry in my_ts_list to every entry in other_ts_list */
|
||||||
int family;
|
|
||||||
chunk_t from_addr;
|
|
||||||
u_int16_t from_port, to_port;
|
|
||||||
sa_policy_t *policy;
|
|
||||||
status_t status;
|
status_t status;
|
||||||
|
sa_policy_t *policy;
|
||||||
|
|
||||||
other_iter->current(other_iter, (void**)&other_ts);
|
other_iter->current(other_iter, (void**)&other_ts);
|
||||||
|
|
||||||
|
if (my_ts->get_type(my_ts) != other_ts->get_type(other_ts))
|
||||||
|
{
|
||||||
|
this->logger->log(this->logger, CONTROL|LEVEL1,
|
||||||
|
"CHILD_SA policy uses two different IP families, ignored");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/* only set up policies if protocol matches, or if one is zero (any) */
|
/* only set up policies if protocol matches, or if one is zero (any) */
|
||||||
if (my_ts->get_protocol(my_ts) != other_ts->get_protocol(other_ts) &&
|
if (my_ts->get_protocol(my_ts) != other_ts->get_protocol(other_ts) &&
|
||||||
my_ts->get_protocol(my_ts) && other_ts->get_protocol(other_ts))
|
my_ts->get_protocol(my_ts) && other_ts->get_protocol(other_ts))
|
||||||
{
|
{
|
||||||
this->logger->log(this->logger, ERROR,
|
this->logger->log(this->logger, CONTROL|LEVEL1,
|
||||||
"CHILD_SA policy uses two different protocols, ignored");
|
"CHILD_SA policy uses two different protocols, ignored");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
policy = malloc_thing(sa_policy_t);
|
|
||||||
policy->upper_proto = max(my_ts->get_protocol(my_ts), other_ts->get_protocol(other_ts));
|
|
||||||
|
|
||||||
/* calculate net and ports for local side */
|
|
||||||
family = my_ts->get_type(my_ts) == TS_IPV4_ADDR_RANGE ? AF_INET : AF_INET6;
|
|
||||||
from_addr = my_ts->get_from_address(my_ts);
|
|
||||||
from_port = my_ts->get_from_port(my_ts);
|
|
||||||
to_port = my_ts->get_to_port(my_ts);
|
|
||||||
from_port = (from_port != to_port) ? 0 : from_port;
|
|
||||||
policy->me.net = host_create_from_chunk(family, from_addr, from_port);
|
|
||||||
policy->me.net_mask = my_ts->get_netmask(my_ts);
|
|
||||||
chunk_free(&from_addr);
|
|
||||||
|
|
||||||
/* calculate net and ports for remote side */
|
|
||||||
family = other_ts->get_type(other_ts) == TS_IPV4_ADDR_RANGE ? AF_INET : AF_INET6;
|
|
||||||
from_addr = other_ts->get_from_address(other_ts);
|
|
||||||
from_port = other_ts->get_from_port(other_ts);
|
|
||||||
to_port = other_ts->get_to_port(other_ts);
|
|
||||||
from_port = (from_port != to_port) ? 0 : from_port;
|
|
||||||
policy->other.net = host_create_from_chunk(family, from_addr, from_port);
|
|
||||||
policy->other.net_mask = other_ts->get_netmask(other_ts);
|
|
||||||
chunk_free(&from_addr);
|
|
||||||
|
|
||||||
/* install 3 policies: out, in and forward */
|
/* install 3 policies: out, in and forward */
|
||||||
status = charon->kernel_interface->add_policy(charon->kernel_interface,
|
status = charon->kernel_interface->add_policy(charon->kernel_interface,
|
||||||
this->me.addr, this->other.addr,
|
this->me.addr, this->other.addr, my_ts, other_ts,
|
||||||
policy->me.net, policy->other.net,
|
POLICY_OUT, this->protocol, this->reqid, FALSE);
|
||||||
policy->me.net_mask, policy->other.net_mask,
|
|
||||||
XFRM_POLICY_OUT, policy->upper_proto,
|
|
||||||
this->protocol, this->reqid, FALSE);
|
|
||||||
|
|
||||||
status |= charon->kernel_interface->add_policy(charon->kernel_interface,
|
status |= charon->kernel_interface->add_policy(charon->kernel_interface,
|
||||||
this->other.addr, this->me.addr,
|
this->other.addr, this->me.addr, other_ts, my_ts,
|
||||||
policy->other.net, policy->me.net,
|
POLICY_IN, this->protocol, this->reqid, FALSE);
|
||||||
policy->other.net_mask, policy->me.net_mask,
|
|
||||||
XFRM_POLICY_IN, policy->upper_proto,
|
|
||||||
this->protocol, this->reqid, FALSE);
|
|
||||||
|
|
||||||
status |= charon->kernel_interface->add_policy(charon->kernel_interface,
|
status |= charon->kernel_interface->add_policy(charon->kernel_interface,
|
||||||
this->other.addr, this->me.addr,
|
this->other.addr, this->me.addr, other_ts, my_ts,
|
||||||
policy->other.net, policy->me.net,
|
POLICY_FWD, this->protocol, this->reqid, FALSE);
|
||||||
policy->other.net_mask, policy->me.net_mask,
|
|
||||||
XFRM_POLICY_FWD, policy->upper_proto,
|
|
||||||
this->protocol, this->reqid, FALSE);
|
|
||||||
|
|
||||||
if (status != SUCCESS)
|
if (status != SUCCESS)
|
||||||
{
|
{
|
||||||
my_iter->destroy(my_iter);
|
my_iter->destroy(my_iter);
|
||||||
other_iter->destroy(other_iter);
|
other_iter->destroy(other_iter);
|
||||||
policy->me.net->destroy(policy->me.net);
|
|
||||||
policy->other.net->destroy(policy->other.net);
|
|
||||||
free(policy);
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add it to the policy list, since we want to know which policies we own */
|
/* store policy to delete/update them later */
|
||||||
this->policies->insert_last(this->policies, policy);
|
policy = malloc_thing(sa_policy_t);
|
||||||
|
policy->my_ts = my_ts->clone(my_ts);
|
||||||
|
policy->other_ts = other_ts->clone(other_ts);
|
||||||
|
this->policies->insert_last(this->policies, (void*)policy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
my_iter->destroy(my_iter);
|
my_iter->destroy(my_iter);
|
||||||
|
@ -533,22 +501,38 @@ static void* get_rekeying_transaction(private_child_sa_t *this)
|
||||||
*/
|
*/
|
||||||
static status_t get_use_time(private_child_sa_t *this, bool inbound, time_t *use_time)
|
static status_t get_use_time(private_child_sa_t *this, bool inbound, time_t *use_time)
|
||||||
{
|
{
|
||||||
|
iterator_t *iterator;
|
||||||
|
sa_policy_t *policy;
|
||||||
status_t status;
|
status_t status;
|
||||||
|
|
||||||
*use_time = UNDEFINED_TIME;
|
*use_time = UNDEFINED_TIME;
|
||||||
|
|
||||||
|
iterator = this->policies->create_iterator(this->policies, TRUE);
|
||||||
|
while (iterator->iterate(iterator, (void**)&policy))
|
||||||
|
{
|
||||||
if (inbound)
|
if (inbound)
|
||||||
{
|
{
|
||||||
status = charon->kernel_interface->query_sa(charon->kernel_interface,
|
time_t in = UNDEFINED_TIME, fwd = UNDEFINED_TIME;
|
||||||
this->me.addr, this->me.spi,
|
|
||||||
this->protocol, use_time);
|
status = charon->kernel_interface->query_policy(
|
||||||
|
charon->kernel_interface,
|
||||||
|
policy->other_ts, policy->my_ts,
|
||||||
|
POLICY_IN, (u_int32_t*)&in);
|
||||||
|
status |= charon->kernel_interface->query_policy(
|
||||||
|
charon->kernel_interface,
|
||||||
|
policy->other_ts, policy->my_ts,
|
||||||
|
POLICY_FWD, (u_int32_t*)&fwd);
|
||||||
|
*use_time = max(in, fwd);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
status = charon->kernel_interface->query_sa(charon->kernel_interface,
|
status = charon->kernel_interface->query_policy(
|
||||||
this->other.addr, this->other.spi,
|
charon->kernel_interface,
|
||||||
this->protocol, use_time);
|
policy->my_ts, policy->other_ts,
|
||||||
|
POLICY_OUT, (u_int32_t*)use_time);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
iterator->destroy(iterator);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -561,23 +545,30 @@ static void log_status(private_child_sa_t *this, logger_t *logger, char* name)
|
||||||
char use_in_str[12] = "unused";
|
char use_in_str[12] = "unused";
|
||||||
char use_out_str[12] = "unused";
|
char use_out_str[12] = "unused";
|
||||||
char rekey_str[12] = "disabled";
|
char rekey_str[12] = "disabled";
|
||||||
time_t use_in, use_out, now, rekeying;
|
u_int32_t use_in, use_out, use_fwd, now, rekeying;
|
||||||
|
status_t status;
|
||||||
|
|
||||||
if (logger == NULL)
|
if (logger == NULL)
|
||||||
{
|
{
|
||||||
logger = this->logger;
|
logger = this->logger;
|
||||||
}
|
}
|
||||||
now = time(NULL);
|
now = (u_int32_t)time(NULL);
|
||||||
get_use_time(this, TRUE, &use_in);
|
|
||||||
if (use_in)
|
/* query SA times */
|
||||||
|
status = charon->kernel_interface->query_sa(charon->kernel_interface,
|
||||||
|
this->me.addr, this->me.spi, this->protocol, &use_in);
|
||||||
|
if (status == SUCCESS && use_in)
|
||||||
{
|
{
|
||||||
snprintf(use_in_str, sizeof(use_in_str), "%ds", (int)(now - use_in));
|
snprintf(use_in_str, sizeof(use_in_str), "%ds", now - use_in);
|
||||||
}
|
}
|
||||||
get_use_time(this, FALSE, &use_out);
|
status = charon->kernel_interface->query_sa(charon->kernel_interface,
|
||||||
if (use_out)
|
this->other.addr, this->other.spi, this->protocol, &use_out);
|
||||||
|
if (status == SUCCESS && use_out)
|
||||||
{
|
{
|
||||||
snprintf(use_out_str, sizeof(use_out_str), "%ds", (int)(now - use_out));
|
snprintf(use_out_str, sizeof(use_out_str), "%ds", now - use_out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* calculate rekey times */
|
||||||
if (this->soft_lifetime)
|
if (this->soft_lifetime)
|
||||||
{
|
{
|
||||||
rekeying = this->soft_lifetime - (now - this->install_time);
|
rekeying = this->soft_lifetime - (now - this->install_time);
|
||||||
|
@ -590,9 +581,8 @@ static void log_status(private_child_sa_t *this, logger_t *logger, char* name)
|
||||||
this->protocol == PROTO_ESP ? "ESP" : "AH",
|
this->protocol == PROTO_ESP ? "ESP" : "AH",
|
||||||
htonl(this->me.spi), htonl(this->other.spi),
|
htonl(this->me.spi), htonl(this->other.spi),
|
||||||
this->reqid);
|
this->reqid);
|
||||||
|
|
||||||
logger->log(logger, CONTROL|LEVEL1,
|
logger->log(logger, CONTROL|LEVEL1,
|
||||||
" \"%s\": state: %s, rekeying: %s, last traffic (in/out): %s/%s",
|
" \"%s\": state: %s, rekeying: %s, key age (in/out): %s/%s",
|
||||||
name, mapping_find(child_sa_state_m, this->state),
|
name, mapping_find(child_sa_state_m, this->state),
|
||||||
rekey_str, use_in_str, use_out_str);
|
rekey_str, use_in_str, use_out_str);
|
||||||
|
|
||||||
|
@ -600,55 +590,40 @@ static void log_status(private_child_sa_t *this, logger_t *logger, char* name)
|
||||||
while (iterator->has_next(iterator))
|
while (iterator->has_next(iterator))
|
||||||
{
|
{
|
||||||
sa_policy_t *policy;
|
sa_policy_t *policy;
|
||||||
struct protoent *proto;
|
char *my_str;
|
||||||
char proto_str[8] = "";
|
char *other_str;
|
||||||
char *proto_name = proto_str;
|
char pol_in_str[12] = "unused";
|
||||||
char my_net_str[8] = "";
|
char pol_out_str[12] = "unused";
|
||||||
char other_net_str[8] = "";
|
char pol_fwd_str[12] = "unused";
|
||||||
char my_port_str[8] = "";
|
|
||||||
char other_port_str[8] = "";
|
|
||||||
u_int16_t my_port, other_port;
|
|
||||||
|
|
||||||
|
/* get ts strings */
|
||||||
iterator->current(iterator, (void**)&policy);
|
iterator->current(iterator, (void**)&policy);
|
||||||
|
my_str = policy->my_ts->get_string(policy->my_ts);
|
||||||
|
other_str = policy->other_ts->get_string(policy->other_ts);
|
||||||
|
|
||||||
if (policy->upper_proto)
|
/* query policy times */
|
||||||
|
status = charon->kernel_interface->query_policy(charon->kernel_interface,
|
||||||
|
policy->other_ts, policy->my_ts, POLICY_IN, &use_in);
|
||||||
|
if (status == SUCCESS && use_in)
|
||||||
{
|
{
|
||||||
proto = getprotobynumber(policy->upper_proto);
|
snprintf(pol_in_str, sizeof(pol_in_str), "%ds", now - use_in);
|
||||||
if (proto)
|
|
||||||
{
|
|
||||||
proto_name = proto->p_name;
|
|
||||||
}
|
}
|
||||||
else
|
status = charon->kernel_interface->query_policy(charon->kernel_interface,
|
||||||
|
policy->my_ts, policy->other_ts, POLICY_OUT, &use_out);
|
||||||
|
if (status == SUCCESS && use_out)
|
||||||
{
|
{
|
||||||
snprintf(proto_str, sizeof(proto_str), "%d", policy->upper_proto);
|
snprintf(pol_out_str, sizeof(pol_out_str), "%ds", now - use_out);
|
||||||
}
|
}
|
||||||
}
|
status = charon->kernel_interface->query_policy(charon->kernel_interface,
|
||||||
if (policy->me.net_mask != 32)
|
policy->other_ts, policy->my_ts, POLICY_FWD, &use_fwd);
|
||||||
|
if (status == SUCCESS && use_fwd)
|
||||||
{
|
{
|
||||||
snprintf(my_net_str, sizeof(my_net_str), "/%d", policy->me.net_mask);
|
snprintf(pol_fwd_str, sizeof(pol_fwd_str), "%ds", now - use_fwd);
|
||||||
}
|
|
||||||
if (policy->other.net_mask != 32)
|
|
||||||
{
|
|
||||||
snprintf(other_net_str, sizeof(other_net_str), "/%d", policy->other.net_mask);
|
|
||||||
}
|
|
||||||
my_port = policy->me.net->get_port(policy->me.net);
|
|
||||||
other_port = policy->other.net->get_port(policy->other.net);
|
|
||||||
if (my_port)
|
|
||||||
{
|
|
||||||
snprintf(my_port_str, sizeof(my_port_str), ":%d", my_port);
|
|
||||||
}
|
|
||||||
if (other_port)
|
|
||||||
{
|
|
||||||
snprintf(other_port_str, sizeof(other_port_str), ":%d", other_port);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
logger->log(logger, CONTROL, " \"%s\": %s%s%s==%s==%s%s%s",
|
logger->log(logger, CONTROL,
|
||||||
name,
|
" \"%s\": %s====%s, last use (in/out/fwd): %s/%s/%s",
|
||||||
policy->me.net->get_address(policy->me.net),
|
name, my_str, other_str, pol_in_str, pol_out_str, pol_fwd_str);
|
||||||
my_port_str, my_net_str,
|
|
||||||
proto_name,
|
|
||||||
policy->other.net->get_address(policy->other.net),
|
|
||||||
other_port_str, other_net_str);
|
|
||||||
}
|
}
|
||||||
iterator->destroy(iterator);
|
iterator->destroy(iterator);
|
||||||
}
|
}
|
||||||
|
@ -688,16 +663,15 @@ static status_t update_sa_hosts(private_child_sa_t *this, host_t *new_me, host_t
|
||||||
this->logger->log(this->logger, CONTROL|LEVEL1,
|
this->logger->log(this->logger, CONTROL|LEVEL1,
|
||||||
"updating %s SA 0x%x, from %s:%d..%s:%d to %s:%d..%s:%d",
|
"updating %s SA 0x%x, from %s:%d..%s:%d to %s:%d..%s:%d",
|
||||||
mapping_find(protocol_id_m, this->protocol), ntohl(spi),
|
mapping_find(protocol_id_m, this->protocol), ntohl(spi),
|
||||||
src->get_address(src), src->get_port(src),
|
src->get_string(src), src->get_port(src),
|
||||||
dst->get_address(dst), dst->get_port(dst),
|
dst->get_string(dst), dst->get_port(dst),
|
||||||
new_src->get_address(new_src), new_src->get_port(new_src),
|
new_src->get_string(new_src), new_src->get_port(new_src),
|
||||||
new_dst->get_address(new_dst), new_dst->get_port(new_dst));
|
new_dst->get_string(new_dst), new_dst->get_port(new_dst));
|
||||||
|
|
||||||
status = charon->kernel_interface->update_sa_hosts(
|
status = charon->kernel_interface->update_sa(charon->kernel_interface,
|
||||||
charon->kernel_interface,
|
dst, spi, this->protocol,
|
||||||
src, dst, new_src, new_dst,
|
new_src, new_dst,
|
||||||
src_changes, dst_changes,
|
src_changes, dst_changes);
|
||||||
spi, this->protocol);
|
|
||||||
|
|
||||||
if (status != SUCCESS)
|
if (status != SUCCESS)
|
||||||
{
|
{
|
||||||
|
@ -721,26 +695,20 @@ static status_t update_policy_hosts(private_child_sa_t *this, host_t *new_me, ho
|
||||||
status = charon->kernel_interface->add_policy(
|
status = charon->kernel_interface->add_policy(
|
||||||
charon->kernel_interface,
|
charon->kernel_interface,
|
||||||
new_me, new_other,
|
new_me, new_other,
|
||||||
policy->me.net, policy->other.net,
|
policy->my_ts, policy->other_ts,
|
||||||
policy->me.net_mask, policy->other.net_mask,
|
POLICY_OUT, this->protocol, this->reqid, TRUE);
|
||||||
XFRM_POLICY_OUT, policy->upper_proto,
|
|
||||||
this->protocol, this->reqid, TRUE);
|
|
||||||
|
|
||||||
status |= charon->kernel_interface->add_policy(
|
status |= charon->kernel_interface->add_policy(
|
||||||
charon->kernel_interface,
|
charon->kernel_interface,
|
||||||
new_other, new_me,
|
new_other, new_me,
|
||||||
policy->other.net, policy->me.net,
|
policy->other_ts, policy->my_ts,
|
||||||
policy->other.net_mask, policy->me.net_mask,
|
POLICY_IN, this->protocol, this->reqid, TRUE);
|
||||||
XFRM_POLICY_IN, policy->upper_proto,
|
|
||||||
this->protocol, this->reqid, TRUE);
|
|
||||||
|
|
||||||
status |= charon->kernel_interface->add_policy(
|
status |= charon->kernel_interface->add_policy(
|
||||||
charon->kernel_interface,
|
charon->kernel_interface,
|
||||||
new_other, new_me,
|
new_other, new_me,
|
||||||
policy->other.net, policy->me.net,
|
policy->other_ts, policy->my_ts,
|
||||||
policy->other.net_mask, policy->me.net_mask,
|
POLICY_FWD, this->protocol, this->reqid, TRUE);
|
||||||
XFRM_POLICY_FWD, policy->upper_proto,
|
|
||||||
this->protocol, this->reqid, TRUE);
|
|
||||||
|
|
||||||
if (status != SUCCESS)
|
if (status != SUCCESS)
|
||||||
{
|
{
|
||||||
|
@ -757,7 +725,7 @@ static status_t update_policy_hosts(private_child_sa_t *this, host_t *new_me, ho
|
||||||
* Implementation of child_sa_t.update_hosts.
|
* Implementation of child_sa_t.update_hosts.
|
||||||
*/
|
*/
|
||||||
static status_t update_hosts(private_child_sa_t *this, host_t *new_me, host_t *new_other,
|
static status_t update_hosts(private_child_sa_t *this, host_t *new_me, host_t *new_other,
|
||||||
int my_changes, int other_changes)
|
host_diff_t my_changes, host_diff_t other_changes)
|
||||||
{
|
{
|
||||||
if (!my_changes && !other_changes)
|
if (!my_changes && !other_changes)
|
||||||
{
|
{
|
||||||
|
@ -835,21 +803,18 @@ static void destroy(private_child_sa_t *this)
|
||||||
{
|
{
|
||||||
/* let rekeyed policies, as they are used by another child_sa */
|
/* let rekeyed policies, as they are used by another child_sa */
|
||||||
charon->kernel_interface->del_policy(charon->kernel_interface,
|
charon->kernel_interface->del_policy(charon->kernel_interface,
|
||||||
policy->me.net, policy->other.net,
|
policy->my_ts, policy->other_ts,
|
||||||
policy->me.net_mask, policy->other.net_mask,
|
POLICY_OUT);
|
||||||
XFRM_POLICY_OUT, policy->upper_proto);
|
|
||||||
|
|
||||||
charon->kernel_interface->del_policy(charon->kernel_interface,
|
charon->kernel_interface->del_policy(charon->kernel_interface,
|
||||||
policy->other.net, policy->me.net,
|
policy->other_ts, policy->my_ts,
|
||||||
policy->other.net_mask, policy->me.net_mask,
|
POLICY_IN);
|
||||||
XFRM_POLICY_IN, policy->upper_proto);
|
|
||||||
|
|
||||||
charon->kernel_interface->del_policy(charon->kernel_interface,
|
charon->kernel_interface->del_policy(charon->kernel_interface,
|
||||||
policy->other.net, policy->me.net,
|
policy->other_ts, policy->my_ts,
|
||||||
policy->other.net_mask, policy->me.net_mask,
|
POLICY_FWD);
|
||||||
XFRM_POLICY_FWD, policy->upper_proto);
|
policy->my_ts->destroy(policy->my_ts);
|
||||||
policy->me.net->destroy(policy->me.net);
|
policy->other_ts->destroy(policy->other_ts);
|
||||||
policy->other.net->destroy(policy->other.net);
|
|
||||||
free(policy);
|
free(policy);
|
||||||
}
|
}
|
||||||
this->policies->destroy(this->policies);
|
this->policies->destroy(this->policies);
|
||||||
|
@ -876,7 +841,7 @@ child_sa_t * child_sa_create(u_int32_t rekey, host_t *me, host_t* other,
|
||||||
this->public.alloc = (status_t(*)(child_sa_t*,linked_list_t*))alloc;
|
this->public.alloc = (status_t(*)(child_sa_t*,linked_list_t*))alloc;
|
||||||
this->public.add = (status_t(*)(child_sa_t*,proposal_t*,prf_plus_t*))add;
|
this->public.add = (status_t(*)(child_sa_t*,proposal_t*,prf_plus_t*))add;
|
||||||
this->public.update = (status_t(*)(child_sa_t*,proposal_t*,prf_plus_t*))update;
|
this->public.update = (status_t(*)(child_sa_t*,proposal_t*,prf_plus_t*))update;
|
||||||
this->public.update_hosts = (status_t (*)(child_sa_t*,host_t*,host_t*,int,int))update_hosts;
|
this->public.update_hosts = (status_t (*)(child_sa_t*,host_t*,host_t*,host_diff_t,host_diff_t))update_hosts;
|
||||||
this->public.add_policies = (status_t (*)(child_sa_t*, linked_list_t*,linked_list_t*))add_policies;
|
this->public.add_policies = (status_t (*)(child_sa_t*, linked_list_t*,linked_list_t*))add_policies;
|
||||||
this->public.get_use_time = (status_t (*)(child_sa_t*,bool,time_t*))get_use_time;
|
this->public.get_use_time = (status_t (*)(child_sa_t*,bool,time_t*))get_use_time;
|
||||||
this->public.set_rekeying_transaction = (void (*)(child_sa_t*,void*))set_rekeying_transaction;
|
this->public.set_rekeying_transaction = (void (*)(child_sa_t*,void*))set_rekeying_transaction;
|
||||||
|
|
|
@ -172,10 +172,12 @@ struct child_sa_t {
|
||||||
* @param this calling object
|
* @param this calling object
|
||||||
* @param new_me the new local host
|
* @param new_me the new local host
|
||||||
* @param new_other the new remote host
|
* @param new_other the new remote host
|
||||||
|
* @param my_diff differences to apply for me
|
||||||
|
* @param other_diff differences to apply for other
|
||||||
* @return SUCCESS or FAILED
|
* @return SUCCESS or FAILED
|
||||||
*/
|
*/
|
||||||
status_t (*update_hosts) (child_sa_t *this, host_t *new_me, host_t *new_other,
|
status_t (*update_hosts) (child_sa_t *this, host_t *new_me, host_t *new_other,
|
||||||
int my_changes, int other_changes);
|
host_diff_t my_diff, host_diff_t other_diff);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Install the policies using some traffic selectors.
|
* @brief Install the policies using some traffic selectors.
|
||||||
|
|
|
@ -366,6 +366,8 @@ static status_t transmit_request(private_ike_sa_t *this)
|
||||||
status = request->generate(request, this->crypter_out, this->signer_out, &packet);
|
status = request->generate(request, this->crypter_out, this->signer_out, &packet);
|
||||||
if (status != SUCCESS)
|
if (status != SUCCESS)
|
||||||
{
|
{
|
||||||
|
this->logger->log(this->logger, ERROR,
|
||||||
|
"request generation failed. transaction discarded");
|
||||||
return FAILED;
|
return FAILED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -848,9 +850,9 @@ static void set_state(private_ike_sa_t *this, ike_sa_state_t state)
|
||||||
my_id = this->policy->get_my_id(this->policy);
|
my_id = this->policy->get_my_id(this->policy);
|
||||||
other_id = this->policy->get_other_id(this->policy);
|
other_id = this->policy->get_other_id(this->policy);
|
||||||
this->logger->log(this->logger, AUDIT, "IKE_SA established: %s[%s]...%s[%s]",
|
this->logger->log(this->logger, AUDIT, "IKE_SA established: %s[%s]...%s[%s]",
|
||||||
my_host->get_address(my_host),
|
my_host->get_string(my_host),
|
||||||
my_id->get_string(my_id),
|
my_id->get_string(my_id),
|
||||||
other_host->get_address(other_host),
|
other_host->get_string(other_host),
|
||||||
other_id->get_string(other_id));
|
other_id->get_string(other_id));
|
||||||
|
|
||||||
send_dpd(this);
|
send_dpd(this);
|
||||||
|
@ -1236,9 +1238,9 @@ static void log_status(private_ike_sa_t *this, logger_t *logger, char *name)
|
||||||
this->ike_sa_id->get_responder_spi(this->ike_sa_id));
|
this->ike_sa_id->get_responder_spi(this->ike_sa_id));
|
||||||
logger->log(logger, CONTROL, " \"%s\": %s[%s]...%s[%s]",
|
logger->log(logger, CONTROL, " \"%s\": %s[%s]...%s[%s]",
|
||||||
name,
|
name,
|
||||||
my_host->get_address(my_host),
|
my_host->get_string(my_host),
|
||||||
my_id ? my_id->get_string(my_id) : "(unknown)",
|
my_id ? my_id->get_string(my_id) : "(unknown)",
|
||||||
other_host->get_address(other_host),
|
other_host->get_string(other_host),
|
||||||
other_id ? other_id->get_string(other_id) : "(unknown)");
|
other_id ? other_id->get_string(other_id) : "(unknown)");
|
||||||
|
|
||||||
iterator = this->child_sas->create_iterator(this->child_sas, TRUE);
|
iterator = this->child_sas->create_iterator(this->child_sas, TRUE);
|
||||||
|
@ -1391,9 +1393,9 @@ static void destroy(private_ike_sa_t *this)
|
||||||
}
|
}
|
||||||
|
|
||||||
this->logger->log(this->logger, AUDIT, "IKE_SA deleted between %s[%s]...%s[%s]",
|
this->logger->log(this->logger, AUDIT, "IKE_SA deleted between %s[%s]...%s[%s]",
|
||||||
my_host->get_address(my_host),
|
my_host->get_string(my_host),
|
||||||
my_id ? my_id->get_string(my_id) : "(unknown)",
|
my_id ? my_id->get_string(my_id) : "(unknown)",
|
||||||
other_host->get_address(other_host),
|
other_host->get_string(other_host),
|
||||||
other_id ? other_id->get_string(other_id) : "(unknown)");
|
other_id ? other_id->get_string(other_id) : "(unknown)");
|
||||||
this->connection->destroy(this->connection);
|
this->connection->destroy(this->connection);
|
||||||
}
|
}
|
||||||
|
|
|
@ -391,7 +391,7 @@ static void import_certificate(private_ike_auth_t *this, cert_payload_t *cert_pa
|
||||||
encoding = cert_payload->get_cert_encoding(cert_payload);
|
encoding = cert_payload->get_cert_encoding(cert_payload);
|
||||||
if (encoding != CERT_X509_SIGNATURE)
|
if (encoding != CERT_X509_SIGNATURE)
|
||||||
{
|
{
|
||||||
this->logger->log(this->logger, CONTROL,
|
this->logger->log(this->logger, ERROR,
|
||||||
"certificate payload %s not supported, ignored",
|
"certificate payload %s not supported, ignored",
|
||||||
enum_name(&cert_encoding_names, encoding));
|
enum_name(&cert_encoding_names, encoding));
|
||||||
return;
|
return;
|
||||||
|
@ -401,7 +401,7 @@ static void import_certificate(private_ike_auth_t *this, cert_payload_t *cert_pa
|
||||||
if (charon->credentials->verify(charon->credentials, cert, &found))
|
if (charon->credentials->verify(charon->credentials, cert, &found))
|
||||||
{
|
{
|
||||||
this->logger->log(this->logger, CONTROL|LEVEL1,
|
this->logger->log(this->logger, CONTROL|LEVEL1,
|
||||||
"end entity certificate is trusted");
|
"received end entity certificate is trusted, added to store");
|
||||||
if (found)
|
if (found)
|
||||||
{
|
{
|
||||||
cert->destroy(cert);
|
cert->destroy(cert);
|
||||||
|
@ -413,8 +413,8 @@ static void import_certificate(private_ike_auth_t *this, cert_payload_t *cert_pa
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
this->logger->log(this->logger, ERROR,
|
this->logger->log(this->logger, CONTROL,
|
||||||
"end entity certificate is not trusted");
|
"received end entity certificate is not trusted, discarded");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -219,7 +219,7 @@ static chunk_t generate_natd_hash(private_ike_sa_init_t *this,
|
||||||
this->nat_hasher->allocate_hash(this->nat_hasher, natd_string, &natd_hash);
|
this->nat_hasher->allocate_hash(this->nat_hasher, natd_string, &natd_hash);
|
||||||
|
|
||||||
sprintf(buf, "natd_hash(%016llx %016llx %s:%d) == SHA1(", spi_i, spi_r,
|
sprintf(buf, "natd_hash(%016llx %016llx %s:%d) == SHA1(", spi_i, spi_r,
|
||||||
host->get_address(host), host->get_port(host));
|
host->get_string(host), host->get_port(host));
|
||||||
chunk_to_hex(buf + strlen(buf), sizeof(buf) - strlen(buf), natd_string);
|
chunk_to_hex(buf + strlen(buf), sizeof(buf) - strlen(buf), natd_string);
|
||||||
strcat(buf, ") == ");
|
strcat(buf, ") == ");
|
||||||
chunk_to_hex(buf + strlen(buf), sizeof(buf) - strlen(buf), natd_hash);
|
chunk_to_hex(buf + strlen(buf), sizeof(buf) - strlen(buf), natd_hash);
|
||||||
|
@ -520,7 +520,7 @@ static status_t get_response(private_ike_sa_init_t *this,
|
||||||
|
|
||||||
this->logger->log(this->logger, AUDIT,
|
this->logger->log(this->logger, AUDIT,
|
||||||
"no connection for hosts %s...%s found, deleting IKE_SA",
|
"no connection for hosts %s...%s found, deleting IKE_SA",
|
||||||
me->get_address(me), other->get_address(other));
|
me->get_string(me), other->get_string(other));
|
||||||
return DESTROY_ME;
|
return DESTROY_ME;
|
||||||
}
|
}
|
||||||
this->ike_sa->set_connection(this->ike_sa, this->connection);
|
this->ike_sa->set_connection(this->ike_sa, this->connection);
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <linux/netlink.h>
|
#include <linux/netlink.h>
|
||||||
#include <linux/rtnetlink.h>
|
#include <linux/rtnetlink.h>
|
||||||
|
#include <linux/xfrm.h>
|
||||||
#include <linux/udp.h>
|
#include <linux/udp.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
@ -408,11 +409,20 @@ static void receive_messages(private_kernel_interface_t *this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* convert a host_t to a struct xfrm_address
|
||||||
|
*/
|
||||||
|
static void host2xfrm(host_t *host, xfrm_address_t *xfrm)
|
||||||
|
{
|
||||||
|
chunk_t chunk = host->get_address(host);
|
||||||
|
memcpy(xfrm, chunk.ptr, max(chunk.len, sizeof(xfrm_address_t)));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of kernel_interface_t.get_spi.
|
* Implementation of kernel_interface_t.get_spi.
|
||||||
*/
|
*/
|
||||||
static status_t get_spi(private_kernel_interface_t *this,
|
static status_t get_spi(private_kernel_interface_t *this,
|
||||||
host_t *src, host_t *dest,
|
host_t *src, host_t *dst,
|
||||||
protocol_id_t protocol, u_int32_t reqid,
|
protocol_id_t protocol, u_int32_t reqid,
|
||||||
u_int32_t *spi)
|
u_int32_t *spi)
|
||||||
{
|
{
|
||||||
|
@ -432,8 +442,8 @@ static status_t get_spi(private_kernel_interface_t *this,
|
||||||
hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_userspi_info));
|
hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_userspi_info));
|
||||||
|
|
||||||
userspi = (struct xfrm_userspi_info*)NLMSG_DATA(hdr);
|
userspi = (struct xfrm_userspi_info*)NLMSG_DATA(hdr);
|
||||||
userspi->info.saddr = src->get_xfrm_addr(src);
|
host2xfrm(src, &userspi->info.saddr);
|
||||||
userspi->info.id.daddr = dest->get_xfrm_addr(dest);
|
host2xfrm(dst, &userspi->info.id.daddr);
|
||||||
userspi->info.id.proto = (protocol == PROTO_ESP) ? KERNEL_ESP : KERNEL_AH;
|
userspi->info.id.proto = (protocol == PROTO_ESP) ? KERNEL_ESP : KERNEL_AH;
|
||||||
userspi->info.mode = TRUE; /* tunnel mode */
|
userspi->info.mode = TRUE; /* tunnel mode */
|
||||||
userspi->info.reqid = reqid;
|
userspi->info.reqid = reqid;
|
||||||
|
@ -476,9 +486,8 @@ static status_t get_spi(private_kernel_interface_t *this,
|
||||||
* Implementation of kernel_interface_t.add_sa.
|
* Implementation of kernel_interface_t.add_sa.
|
||||||
*/
|
*/
|
||||||
static status_t add_sa(private_kernel_interface_t *this,
|
static status_t add_sa(private_kernel_interface_t *this,
|
||||||
host_t *me, host_t *other,
|
host_t *src, host_t *dst, u_int32_t spi,
|
||||||
u_int32_t spi, protocol_id_t protocol,
|
protocol_id_t protocol, u_int32_t reqid,
|
||||||
u_int32_t reqid,
|
|
||||||
u_int64_t expire_soft, u_int64_t expire_hard,
|
u_int64_t expire_soft, u_int64_t expire_hard,
|
||||||
algorithm_t *enc_alg, algorithm_t *int_alg,
|
algorithm_t *enc_alg, algorithm_t *int_alg,
|
||||||
prf_plus_t *prf_plus, natt_conf_t *natt,
|
prf_plus_t *prf_plus, natt_conf_t *natt,
|
||||||
|
@ -502,12 +511,11 @@ static status_t add_sa(private_kernel_interface_t *this,
|
||||||
hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_usersa_info));
|
hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_usersa_info));
|
||||||
|
|
||||||
sa = (struct xfrm_usersa_info*)NLMSG_DATA(hdr);
|
sa = (struct xfrm_usersa_info*)NLMSG_DATA(hdr);
|
||||||
sa->saddr = me->get_xfrm_addr(me);
|
host2xfrm(src, &sa->saddr);
|
||||||
sa->id.daddr = other->get_xfrm_addr(other);
|
host2xfrm(dst, &sa->id.daddr);
|
||||||
|
|
||||||
sa->id.spi = spi;
|
sa->id.spi = spi;
|
||||||
sa->id.proto = (protocol == PROTO_ESP) ? KERNEL_ESP : KERNEL_AH;
|
sa->id.proto = (protocol == PROTO_ESP) ? KERNEL_ESP : KERNEL_AH;
|
||||||
sa->family = me->get_family(me);
|
sa->family = src->get_family(src);
|
||||||
sa->mode = TRUE; /* tunnel mode */
|
sa->mode = TRUE; /* tunnel mode */
|
||||||
sa->replay_window = 32;
|
sa->replay_window = 32;
|
||||||
sa->reqid = reqid;
|
sa->reqid = reqid;
|
||||||
|
@ -595,8 +603,8 @@ static status_t add_sa(private_kernel_interface_t *this,
|
||||||
|
|
||||||
struct xfrm_encap_tmpl* encap = (struct xfrm_encap_tmpl*)RTA_DATA(rthdr);
|
struct xfrm_encap_tmpl* encap = (struct xfrm_encap_tmpl*)RTA_DATA(rthdr);
|
||||||
encap->encap_type = UDP_ENCAP_ESPINUDP;
|
encap->encap_type = UDP_ENCAP_ESPINUDP;
|
||||||
encap->encap_sport = ntohs(natt->sport);
|
encap->encap_sport = htons(natt->sport);
|
||||||
encap->encap_dport = ntohs(natt->dport);
|
encap->encap_dport = htons(natt->dport);
|
||||||
memset(&encap->encap_oa, 0, sizeof (xfrm_address_t));
|
memset(&encap->encap_oa, 0, sizeof (xfrm_address_t));
|
||||||
/* encap_oa could probably be derived from the
|
/* encap_oa could probably be derived from the
|
||||||
* traffic selectors [rfc4306, p39]. In the netlink kernel implementation
|
* traffic selectors [rfc4306, p39]. In the netlink kernel implementation
|
||||||
|
@ -633,13 +641,13 @@ static status_t add_sa(private_kernel_interface_t *this,
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of kernel_interface_t.update_sa_hosts.
|
* Implementation of kernel_interface_t.update_sa.
|
||||||
*/
|
*/
|
||||||
static status_t update_sa_hosts(
|
static status_t update_sa(
|
||||||
private_kernel_interface_t *this,
|
private_kernel_interface_t *this,
|
||||||
host_t *src, host_t *dst,
|
host_t *src, host_t *dst,
|
||||||
host_t *new_src, host_t *new_dst,
|
host_t *new_src, host_t *new_dst,
|
||||||
int src_changes, int dst_changes,
|
host_diff_t src_changes, host_diff_t dst_changes,
|
||||||
u_int32_t spi, protocol_id_t protocol)
|
u_int32_t spi, protocol_id_t protocol)
|
||||||
{
|
{
|
||||||
unsigned char request[BUFFER_SIZE];
|
unsigned char request[BUFFER_SIZE];
|
||||||
|
@ -658,11 +666,11 @@ static status_t update_sa_hosts(
|
||||||
hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_usersa_id));
|
hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_usersa_id));
|
||||||
|
|
||||||
sa_id = (struct xfrm_usersa_id*)NLMSG_DATA(hdr);
|
sa_id = (struct xfrm_usersa_id*)NLMSG_DATA(hdr);
|
||||||
sa_id->daddr = dst->get_xfrm_addr(dst);
|
host2xfrm(dst, &sa_id->daddr);
|
||||||
sa_id->spi = spi;
|
sa_id->spi = spi;
|
||||||
sa_id->proto = (protocol == PROTO_ESP) ? KERNEL_ESP : KERNEL_AH;
|
sa_id->proto = (protocol == PROTO_ESP) ? KERNEL_ESP : KERNEL_AH;
|
||||||
sa_id->family = dst->get_family(dst);
|
sa_id->family = dst->get_family(dst);
|
||||||
|
POS;
|
||||||
if (send_message(this, hdr, &update) != SUCCESS)
|
if (send_message(this, hdr, &update) != SUCCESS)
|
||||||
{
|
{
|
||||||
this->logger->log(this->logger, ERROR, "netlink communication failed");
|
this->logger->log(this->logger, ERROR, "netlink communication failed");
|
||||||
|
@ -687,6 +695,7 @@ static status_t update_sa_hosts(
|
||||||
free(update);
|
free(update);
|
||||||
return FAILED;
|
return FAILED;
|
||||||
}
|
}
|
||||||
|
POS;
|
||||||
|
|
||||||
this->logger->log(this->logger, CONTROL|LEVEL2, "updating SA");
|
this->logger->log(this->logger, CONTROL|LEVEL2, "updating SA");
|
||||||
update->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
|
update->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
|
||||||
|
@ -695,7 +704,7 @@ static status_t update_sa_hosts(
|
||||||
struct xfrm_usersa_info *sa = (struct xfrm_usersa_info*)NLMSG_DATA(update);
|
struct xfrm_usersa_info *sa = (struct xfrm_usersa_info*)NLMSG_DATA(update);
|
||||||
if (src_changes & HOST_DIFF_ADDR)
|
if (src_changes & HOST_DIFF_ADDR)
|
||||||
{
|
{
|
||||||
sa->saddr = new_src->get_xfrm_addr(new_src);
|
host2xfrm(new_src, &sa->saddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dst_changes & HOST_DIFF_ADDR)
|
if (dst_changes & HOST_DIFF_ADDR)
|
||||||
|
@ -703,7 +712,7 @@ static status_t update_sa_hosts(
|
||||||
this->logger->log(this->logger, CONTROL|LEVEL2, "destination address changed! replacing SA");
|
this->logger->log(this->logger, CONTROL|LEVEL2, "destination address changed! replacing SA");
|
||||||
|
|
||||||
update->nlmsg_type = XFRM_MSG_NEWSA;
|
update->nlmsg_type = XFRM_MSG_NEWSA;
|
||||||
sa->id.daddr = new_dst->get_xfrm_addr(new_dst);
|
host2xfrm(new_dst, &sa->id.daddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (src_changes & HOST_DIFF_PORT || dst_changes & HOST_DIFF_PORT)
|
if (src_changes & HOST_DIFF_PORT || dst_changes & HOST_DIFF_PORT)
|
||||||
|
@ -722,7 +731,7 @@ static status_t update_sa_hosts(
|
||||||
rthdr = RTA_NEXT(rthdr, rtsize);
|
rthdr = RTA_NEXT(rthdr, rtsize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
POS;
|
||||||
if (send_message(this, update, &response) != SUCCESS)
|
if (send_message(this, update, &response) != SUCCESS)
|
||||||
{
|
{
|
||||||
this->logger->log(this->logger, ERROR, "netlink communication failed");
|
this->logger->log(this->logger, ERROR, "netlink communication failed");
|
||||||
|
@ -745,6 +754,7 @@ static status_t update_sa_hosts(
|
||||||
this->logger->log(this->logger, CONTROL|LEVEL2, "deleting old SA");
|
this->logger->log(this->logger, CONTROL|LEVEL2, "deleting old SA");
|
||||||
status = this->public.del_sa(&this->public, dst, spi, protocol);
|
status = this->public.del_sa(&this->public, dst, spi, protocol);
|
||||||
}
|
}
|
||||||
|
POS;
|
||||||
|
|
||||||
free(update);
|
free(update);
|
||||||
free(response);
|
free(response);
|
||||||
|
@ -755,7 +765,7 @@ static status_t update_sa_hosts(
|
||||||
* Implementation of kernel_interface_t.query_sa.
|
* Implementation of kernel_interface_t.query_sa.
|
||||||
*/
|
*/
|
||||||
static status_t query_sa(private_kernel_interface_t *this, host_t *dst,
|
static status_t query_sa(private_kernel_interface_t *this, host_t *dst,
|
||||||
u_int32_t spi, protocol_id_t protocol, time_t *use_time)
|
u_int32_t spi, protocol_id_t protocol, u_int32_t *use_time)
|
||||||
{
|
{
|
||||||
unsigned char request[BUFFER_SIZE];
|
unsigned char request[BUFFER_SIZE];
|
||||||
struct nlmsghdr *response;
|
struct nlmsghdr *response;
|
||||||
|
@ -772,7 +782,7 @@ static status_t query_sa(private_kernel_interface_t *this, host_t *dst,
|
||||||
hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_usersa_info));
|
hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_usersa_info));
|
||||||
|
|
||||||
sa_id = (struct xfrm_usersa_id*)NLMSG_DATA(hdr);
|
sa_id = (struct xfrm_usersa_id*)NLMSG_DATA(hdr);
|
||||||
sa_id->daddr = dst->get_xfrm_addr(dst);
|
host2xfrm(dst, &sa_id->daddr);
|
||||||
sa_id->spi = spi;
|
sa_id->spi = spi;
|
||||||
sa_id->proto = (protocol == PROTO_ESP) ? KERNEL_ESP : KERNEL_AH;
|
sa_id->proto = (protocol == PROTO_ESP) ? KERNEL_ESP : KERNEL_AH;
|
||||||
sa_id->family = dst->get_family(dst);
|
sa_id->family = dst->get_family(dst);
|
||||||
|
@ -796,7 +806,7 @@ static status_t query_sa(private_kernel_interface_t *this, host_t *dst,
|
||||||
}
|
}
|
||||||
|
|
||||||
sa_info = (struct xfrm_usersa_info*)NLMSG_DATA(response);
|
sa_info = (struct xfrm_usersa_info*)NLMSG_DATA(response);
|
||||||
*use_time = (time_t)sa_info->curlft.use_time;
|
*use_time = sa_info->curlft.use_time;
|
||||||
|
|
||||||
free(response);
|
free(response);
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
|
@ -824,7 +834,7 @@ static status_t del_sa(private_kernel_interface_t *this, host_t *dst,
|
||||||
hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_usersa_id));
|
hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_usersa_id));
|
||||||
|
|
||||||
sa_id = (struct xfrm_usersa_id*)NLMSG_DATA(hdr);
|
sa_id = (struct xfrm_usersa_id*)NLMSG_DATA(hdr);
|
||||||
sa_id->daddr = dst->get_xfrm_addr(dst);
|
host2xfrm(dst, &sa_id->daddr);
|
||||||
sa_id->spi = spi;
|
sa_id->spi = spi;
|
||||||
sa_id->proto = (protocol == PROTO_ESP) ? KERNEL_ESP : KERNEL_AH;
|
sa_id->proto = (protocol == PROTO_ESP) ? KERNEL_ESP : KERNEL_AH;
|
||||||
sa_id->family = dst->get_family(dst);
|
sa_id->family = dst->get_family(dst);
|
||||||
|
@ -850,15 +860,110 @@ static status_t del_sa(private_kernel_interface_t *this, host_t *dst,
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* convert a traffic selector address range to subnet and its mask.
|
||||||
|
*/
|
||||||
|
static void ts2subnet(traffic_selector_t* ts,
|
||||||
|
xfrm_address_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.
|
||||||
|
*/
|
||||||
|
chunk_t chunk;
|
||||||
|
|
||||||
|
chunk = ts->get_from_address(ts);
|
||||||
|
memcpy(net, chunk.ptr, chunk.len);
|
||||||
|
|
||||||
|
switch (ts->get_type(ts))
|
||||||
|
{
|
||||||
|
case TS_IPV4_ADDR_RANGE:
|
||||||
|
{
|
||||||
|
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) != (1<<bit & to))
|
||||||
|
{
|
||||||
|
*mask = bit;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*mask = 32;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case TS_IPV6_ADDR_RANGE:
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
/* TODO: IPV6 support */
|
||||||
|
*mask = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* convert a traffic selector port range to port/portmask
|
||||||
|
*/
|
||||||
|
static void ts2ports(traffic_selector_t* ts,
|
||||||
|
u_int16_t *port, u_int16_t *mask)
|
||||||
|
{
|
||||||
|
/* linux does not seem to accept complex portmasks. Only
|
||||||
|
* any or a specific port is allowed. We set to any, if we have
|
||||||
|
* a port range, or to a specific, if we have one port only.
|
||||||
|
*/
|
||||||
|
u_int16_t from, to;
|
||||||
|
|
||||||
|
from = ts->get_from_port(ts);
|
||||||
|
to = ts->get_to_port(ts);
|
||||||
|
|
||||||
|
if (from == to)
|
||||||
|
{
|
||||||
|
*port = htons(from);
|
||||||
|
*mask = ~0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*port = 0;
|
||||||
|
*mask = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* convert a pair of traffic_selectors to a xfrm_selector
|
||||||
|
*/
|
||||||
|
static struct xfrm_selector ts2selector(traffic_selector_t *src,
|
||||||
|
traffic_selector_t *dst)
|
||||||
|
{
|
||||||
|
struct xfrm_selector sel;
|
||||||
|
|
||||||
|
memset(&sel, 0, sizeof(sel));
|
||||||
|
sel.family = src->get_type(src) == TS_IPV4_ADDR_RANGE ? AF_INET : AF_INET6;
|
||||||
|
/* src or dest proto may be "any" (0), use more restrictive one */
|
||||||
|
sel.proto = max(src->get_protocol(src), dst->get_protocol(dst));
|
||||||
|
ts2subnet(dst, &sel.daddr, &sel.prefixlen_d);
|
||||||
|
ts2subnet(src, &sel.saddr, &sel.prefixlen_s);
|
||||||
|
ts2ports(dst, &sel.dport, &sel.dport_mask);
|
||||||
|
ts2ports(src, &sel.sport, &sel.sport_mask);
|
||||||
|
sel.ifindex = 0;
|
||||||
|
sel.user = 0;
|
||||||
|
|
||||||
|
return sel;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of kernel_interface_t.add_policy.
|
* Implementation of kernel_interface_t.add_policy.
|
||||||
*/
|
*/
|
||||||
static status_t add_policy(private_kernel_interface_t *this,
|
static status_t add_policy(private_kernel_interface_t *this,
|
||||||
host_t *me, host_t *other,
|
|
||||||
host_t *src, host_t *dst,
|
host_t *src, host_t *dst,
|
||||||
u_int8_t src_hostbits, u_int8_t dst_hostbits,
|
traffic_selector_t *src_ts,
|
||||||
u_int8_t direction, u_int8_t upper_proto,
|
traffic_selector_t *dst_ts,
|
||||||
protocol_id_t protocol,
|
policy_dir_t direction, protocol_id_t protocol,
|
||||||
u_int32_t reqid, bool update)
|
u_int32_t reqid, bool update)
|
||||||
{
|
{
|
||||||
iterator_t *iterator;
|
iterator_t *iterator;
|
||||||
|
@ -873,16 +978,7 @@ static status_t add_policy(private_kernel_interface_t *this,
|
||||||
/* create a policy */
|
/* create a policy */
|
||||||
policy = malloc_thing(kernel_policy_t);
|
policy = malloc_thing(kernel_policy_t);
|
||||||
memset(policy, 0, sizeof(kernel_policy_t));
|
memset(policy, 0, sizeof(kernel_policy_t));
|
||||||
policy->sel.saddr = src->get_xfrm_addr(src);
|
policy->sel = ts2selector(src_ts, dst_ts);
|
||||||
policy->sel.prefixlen_s = src_hostbits;
|
|
||||||
policy->sel.sport = htons(src->get_port(src));
|
|
||||||
policy->sel.sport_mask = (policy->sel.sport) ? ~0 : 0;
|
|
||||||
policy->sel.daddr = dst->get_xfrm_addr(dst);
|
|
||||||
policy->sel.prefixlen_d = dst_hostbits;
|
|
||||||
policy->sel.dport = htons(dst->get_port(dst));
|
|
||||||
policy->sel.dport_mask = (policy->sel.dport) ? ~0 : 0;
|
|
||||||
policy->sel.proto = upper_proto;
|
|
||||||
policy->sel.family = src->get_family(src);
|
|
||||||
policy->direction = direction;
|
policy->direction = direction;
|
||||||
|
|
||||||
/* find the policy, which matches EXACTLY */
|
/* find the policy, which matches EXACTLY */
|
||||||
|
@ -893,12 +989,17 @@ static status_t add_policy(private_kernel_interface_t *this,
|
||||||
if (memcmp(current, policy, sizeof(struct xfrm_selector)) == 0 &&
|
if (memcmp(current, policy, sizeof(struct xfrm_selector)) == 0 &&
|
||||||
policy->direction == current->direction)
|
policy->direction == current->direction)
|
||||||
{
|
{
|
||||||
|
free(policy);
|
||||||
/* use existing policy */
|
/* use existing policy */
|
||||||
if (!update)
|
if (!update)
|
||||||
{
|
{
|
||||||
current->refcount++;
|
current->refcount++;
|
||||||
|
iterator->destroy(iterator);
|
||||||
|
pthread_mutex_unlock(&this->pol_mutex);
|
||||||
|
this->logger->log(this->logger, CONTROL|LEVEL1,
|
||||||
|
"policy already exists, increasing refcount");
|
||||||
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
free(policy);
|
|
||||||
policy = current;
|
policy = current;
|
||||||
found = TRUE;
|
found = TRUE;
|
||||||
break;
|
break;
|
||||||
|
@ -921,7 +1022,7 @@ static status_t add_policy(private_kernel_interface_t *this,
|
||||||
|
|
||||||
policy_info = (struct xfrm_userpolicy_info*)NLMSG_DATA(hdr);
|
policy_info = (struct xfrm_userpolicy_info*)NLMSG_DATA(hdr);
|
||||||
policy_info->sel = policy->sel;
|
policy_info->sel = policy->sel;
|
||||||
policy_info->dir = direction;
|
policy_info->dir = policy->direction;
|
||||||
policy_info->priority = SPD_PRIORITY;
|
policy_info->priority = SPD_PRIORITY;
|
||||||
policy_info->action = XFRM_POLICY_ALLOW;
|
policy_info->action = XFRM_POLICY_ALLOW;
|
||||||
policy_info->share = XFRM_SHARE_ANY;
|
policy_info->share = XFRM_SHARE_ANY;
|
||||||
|
@ -955,8 +1056,8 @@ static status_t add_policy(private_kernel_interface_t *this,
|
||||||
tmpl->aalgos = tmpl->ealgos = tmpl->calgos = ~0;
|
tmpl->aalgos = tmpl->ealgos = tmpl->calgos = ~0;
|
||||||
tmpl->mode = TRUE;
|
tmpl->mode = TRUE;
|
||||||
|
|
||||||
tmpl->saddr = me->get_xfrm_addr(me);
|
host2xfrm(src, &tmpl->saddr);
|
||||||
tmpl->id.daddr = other->get_xfrm_addr(other);
|
host2xfrm(dst, &tmpl->id.daddr);
|
||||||
|
|
||||||
if (send_message(this, hdr, &response) != SUCCESS)
|
if (send_message(this, hdr, &response) != SUCCESS)
|
||||||
{
|
{
|
||||||
|
@ -981,13 +1082,74 @@ static status_t add_policy(private_kernel_interface_t *this,
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of kernel_interface_t.query_policy.
|
||||||
|
*/
|
||||||
|
static status_t query_policy(private_kernel_interface_t *this,
|
||||||
|
traffic_selector_t *src_ts,
|
||||||
|
traffic_selector_t *dst_ts,
|
||||||
|
policy_dir_t direction, u_int32_t *use_time)
|
||||||
|
{
|
||||||
|
unsigned char request[BUFFER_SIZE];
|
||||||
|
struct nlmsghdr *response;
|
||||||
|
struct nlmsghdr *hdr;
|
||||||
|
struct xfrm_userpolicy_id *policy_id;
|
||||||
|
struct xfrm_userpolicy_info *policy;
|
||||||
|
|
||||||
|
memset(&request, 0, sizeof(request));
|
||||||
|
status_t status = SUCCESS;
|
||||||
|
|
||||||
|
this->logger->log(this->logger, CONTROL|LEVEL2, "querying policy");
|
||||||
|
|
||||||
|
hdr = (struct nlmsghdr*)request;
|
||||||
|
hdr->nlmsg_flags = NLM_F_REQUEST;
|
||||||
|
hdr->nlmsg_type = XFRM_MSG_GETPOLICY;
|
||||||
|
hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_userpolicy_id));
|
||||||
|
|
||||||
|
policy_id = (struct xfrm_userpolicy_id*)NLMSG_DATA(hdr);
|
||||||
|
policy_id->sel = ts2selector(src_ts, dst_ts);
|
||||||
|
policy_id->dir = direction;
|
||||||
|
|
||||||
|
if (send_message(this, hdr, &response) != SUCCESS)
|
||||||
|
{
|
||||||
|
this->logger->log(this->logger, ERROR, "netlink communication failed");
|
||||||
|
return FAILED;
|
||||||
|
}
|
||||||
|
else if (response->nlmsg_type == NLMSG_ERROR)
|
||||||
|
{
|
||||||
|
this->logger->log(this->logger, ERROR, "netlink request XFRM_MSG_GETPOLICY got an error: %s",
|
||||||
|
strerror(-((struct nlmsgerr*)NLMSG_DATA(response))->error));
|
||||||
|
free(response);
|
||||||
|
return FAILED;
|
||||||
|
}
|
||||||
|
else if (response->nlmsg_type != XFRM_MSG_NEWPOLICY)
|
||||||
|
{
|
||||||
|
this->logger->log(this->logger, ERROR, "netlink request XFRM_MSG_GETPOLICY got an unknown reply");
|
||||||
|
free(response);
|
||||||
|
return FAILED;
|
||||||
|
}
|
||||||
|
else if (response->nlmsg_len < NLMSG_LENGTH(sizeof(struct xfrm_userpolicy_info)))
|
||||||
|
{
|
||||||
|
this->logger->log(this->logger, ERROR, "netlink request XFRM_MSG_GETPOLICY got an invalid reply");
|
||||||
|
free(response);
|
||||||
|
return FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
policy = (struct xfrm_userpolicy_info*)NLMSG_DATA(response);
|
||||||
|
|
||||||
|
*use_time = (time_t)policy->curlft.use_time;
|
||||||
|
|
||||||
|
free(response);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of kernel_interface_t.del_policy.
|
* Implementation of kernel_interface_t.del_policy.
|
||||||
*/
|
*/
|
||||||
static status_t del_policy(private_kernel_interface_t *this,
|
static status_t del_policy(private_kernel_interface_t *this,
|
||||||
host_t *src, host_t *dst,
|
traffic_selector_t *src_ts,
|
||||||
u_int8_t src_hostbits, u_int8_t dst_hostbits,
|
traffic_selector_t *dst_ts,
|
||||||
u_int8_t direction, u_int8_t upper_proto)
|
policy_dir_t direction)
|
||||||
{
|
{
|
||||||
kernel_policy_t *current, policy, *to_delete = NULL;
|
kernel_policy_t *current, policy, *to_delete = NULL;
|
||||||
unsigned char request[BUFFER_SIZE];
|
unsigned char request[BUFFER_SIZE];
|
||||||
|
@ -1001,16 +1163,7 @@ static status_t del_policy(private_kernel_interface_t *this,
|
||||||
|
|
||||||
/* create a policy */
|
/* create a policy */
|
||||||
memset(&policy, 0, sizeof(kernel_policy_t));
|
memset(&policy, 0, sizeof(kernel_policy_t));
|
||||||
policy.sel.saddr = src->get_xfrm_addr(src);
|
policy.sel = ts2selector(src_ts, dst_ts);
|
||||||
policy.sel.prefixlen_s = src_hostbits;
|
|
||||||
policy.sel.sport = htons(src->get_port(src));
|
|
||||||
policy.sel.sport_mask = (policy.sel.sport) ? ~0 : 0;
|
|
||||||
policy.sel.daddr = dst->get_xfrm_addr(dst);
|
|
||||||
policy.sel.prefixlen_d = dst_hostbits;
|
|
||||||
policy.sel.dport = htons(dst->get_port(dst));
|
|
||||||
policy.sel.dport_mask = (policy.sel.dport) ? ~0 : 0;
|
|
||||||
policy.sel.proto = upper_proto;
|
|
||||||
policy.sel.family = src->get_family(src);
|
|
||||||
policy.direction = direction;
|
policy.direction = direction;
|
||||||
|
|
||||||
/* find the policy */
|
/* find the policy */
|
||||||
|
@ -1025,7 +1178,7 @@ static status_t del_policy(private_kernel_interface_t *this,
|
||||||
if (--to_delete->refcount > 0)
|
if (--to_delete->refcount > 0)
|
||||||
{
|
{
|
||||||
/* is used by more SAs, keep in kernel */
|
/* is used by more SAs, keep in kernel */
|
||||||
this->logger->log(this->logger, CONTROL|LEVEL2,
|
this->logger->log(this->logger, CONTROL|LEVEL1,
|
||||||
"is used by other SAs, not removed");
|
"is used by other SAs, not removed");
|
||||||
iterator->destroy(iterator);
|
iterator->destroy(iterator);
|
||||||
pthread_mutex_unlock(&this->pol_mutex);
|
pthread_mutex_unlock(&this->pol_mutex);
|
||||||
|
@ -1103,11 +1256,12 @@ kernel_interface_t *kernel_interface_create()
|
||||||
/* public functions */
|
/* public functions */
|
||||||
this->public.get_spi = (status_t(*)(kernel_interface_t*,host_t*,host_t*,protocol_id_t,u_int32_t,u_int32_t*))get_spi;
|
this->public.get_spi = (status_t(*)(kernel_interface_t*,host_t*,host_t*,protocol_id_t,u_int32_t,u_int32_t*))get_spi;
|
||||||
this->public.add_sa = (status_t(*)(kernel_interface_t *,host_t*,host_t*,u_int32_t,protocol_id_t,u_int32_t,u_int64_t,u_int64_t,algorithm_t*,algorithm_t*,prf_plus_t*,natt_conf_t*,bool))add_sa;
|
this->public.add_sa = (status_t(*)(kernel_interface_t *,host_t*,host_t*,u_int32_t,protocol_id_t,u_int32_t,u_int64_t,u_int64_t,algorithm_t*,algorithm_t*,prf_plus_t*,natt_conf_t*,bool))add_sa;
|
||||||
this->public.update_sa_hosts = (status_t(*)(kernel_interface_t*,host_t*,host_t*,host_t*,host_t*,int,int,u_int32_t,protocol_id_t))update_sa_hosts;
|
this->public.update_sa = (status_t(*)(kernel_interface_t*,host_t*,u_int32_t,protocol_id_t,host_t*,host_t*,host_diff_t,host_diff_t))update_sa;
|
||||||
this->public.query_sa = (status_t(*)(kernel_interface_t*,host_t*,u_int32_t,protocol_id_t,time_t*))query_sa;
|
this->public.query_sa = (status_t(*)(kernel_interface_t*,host_t*,u_int32_t,protocol_id_t,u_int32_t*))query_sa;
|
||||||
this->public.del_sa = (status_t(*)(kernel_interface_t*,host_t*,u_int32_t,protocol_id_t))del_sa;
|
this->public.del_sa = (status_t(*)(kernel_interface_t*,host_t*,u_int32_t,protocol_id_t))del_sa;
|
||||||
this->public.add_policy = (status_t(*)(kernel_interface_t*,host_t*,host_t*,host_t*,host_t*,u_int8_t,u_int8_t,u_int8_t,u_int8_t,protocol_id_t,u_int32_t,bool))add_policy;
|
this->public.add_policy = (status_t(*)(kernel_interface_t*,host_t*,host_t*,traffic_selector_t*,traffic_selector_t*,policy_dir_t,protocol_id_t,u_int32_t,bool))add_policy;
|
||||||
this->public.del_policy = (status_t(*)(kernel_interface_t*,host_t*,host_t*,u_int8_t,u_int8_t,u_int8_t,u_int8_t))del_policy;
|
this->public.query_policy = (status_t(*)(kernel_interface_t*,traffic_selector_t*,traffic_selector_t*,policy_dir_t,u_int32_t*))query_policy;
|
||||||
|
this->public.del_policy = (status_t(*)(kernel_interface_t*,traffic_selector_t*,traffic_selector_t*,policy_dir_t))del_policy;
|
||||||
this->public.destroy = (void(*)(kernel_interface_t*)) destroy;
|
this->public.destroy = (void(*)(kernel_interface_t*)) destroy;
|
||||||
|
|
||||||
/* private members */
|
/* private members */
|
||||||
|
|
|
@ -25,8 +25,6 @@
|
||||||
#ifndef KERNEL_INTERFACE_H_
|
#ifndef KERNEL_INTERFACE_H_
|
||||||
#define KERNEL_INTERFACE_H_
|
#define KERNEL_INTERFACE_H_
|
||||||
|
|
||||||
#include <linux/xfrm.h>
|
|
||||||
|
|
||||||
#include <utils/host.h>
|
#include <utils/host.h>
|
||||||
#include <crypto/prf_plus.h>
|
#include <crypto/prf_plus.h>
|
||||||
#include <encoding/payloads/proposal_substructure.h>
|
#include <encoding/payloads/proposal_substructure.h>
|
||||||
|
@ -34,10 +32,29 @@
|
||||||
typedef struct natt_conf_t natt_conf_t;
|
typedef struct natt_conf_t natt_conf_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Configuration for NAT-T
|
* Configuration for NAT-T
|
||||||
*/
|
*/
|
||||||
struct natt_conf_t {
|
struct natt_conf_t {
|
||||||
u_int16_t sport, dport;
|
/** source port to use for UDP-encapsulated packets */
|
||||||
|
u_int16_t sport;
|
||||||
|
/** dest port to use for UDP-encapsulated packets */
|
||||||
|
u_int16_t dport;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef enum policy_dir_t policy_dir_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Direction of a policy. These are equal to those
|
||||||
|
* defined in xfrm.h, but we want to stay implementation
|
||||||
|
* neutral here.
|
||||||
|
*/
|
||||||
|
enum policy_dir_t {
|
||||||
|
/** Policy for inbound traffic */
|
||||||
|
POLICY_IN = 0,
|
||||||
|
/** Policy for outbound traffic */
|
||||||
|
POLICY_OUT = 1,
|
||||||
|
/** Policy for forwarded traffic */
|
||||||
|
POLICY_FWD = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct kernel_interface_t kernel_interface_t;
|
typedef struct kernel_interface_t kernel_interface_t;
|
||||||
|
@ -101,8 +118,8 @@ struct kernel_interface_t {
|
||||||
* @param expire_hard lieftime in seconds before delete
|
* @param expire_hard lieftime in seconds before delete
|
||||||
* @param enc_alg Algorithm to use for encryption (ESP only)
|
* @param enc_alg Algorithm to use for encryption (ESP only)
|
||||||
* @param int_alg Algorithm to use for integrity protection
|
* @param int_alg Algorithm to use for integrity protection
|
||||||
* @param prf_plus PRF to derive keys
|
* @param prf_plus PRF to derive keys from
|
||||||
* @param natt NAT-T Configuration
|
* @param natt NAT-T Configuration, or NULL of no NAT-T used
|
||||||
* @param replace Should an already installed SA be updated?
|
* @param replace Should an already installed SA be updated?
|
||||||
* @return
|
* @return
|
||||||
* - SUCCESS
|
* - SUCCESS
|
||||||
|
@ -113,36 +130,39 @@ struct kernel_interface_t {
|
||||||
protocol_id_t protocol, u_int32_t reqid,
|
protocol_id_t protocol, u_int32_t reqid,
|
||||||
u_int64_t expire_soft, u_int64_t expire_hard,
|
u_int64_t expire_soft, u_int64_t expire_hard,
|
||||||
algorithm_t *enc_alg, algorithm_t *int_alg,
|
algorithm_t *enc_alg, algorithm_t *int_alg,
|
||||||
prf_plus_t *prf_plus, natt_conf_t *natt, bool replace);
|
prf_plus_t *prf_plus, natt_conf_t *natt, bool update);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Update the hosts on an installed SA. Encapsulation ports are also updated.
|
* @brief Update the hosts on an installed SA.
|
||||||
*
|
*
|
||||||
* @note We cannot directly update the destination address as the kernel requires the spi,
|
* We cannot directly update the destination address as the kernel
|
||||||
* the protocol AND the destination address (and family) to identify SAs. Therefore if the
|
* requires the spi, the protocol AND the destination address (and family)
|
||||||
* destination address changed we create a new SA and delete the old one.
|
* to identify SAs. Therefore if the destination address changed we
|
||||||
|
* create a new SA and delete the old one.
|
||||||
*
|
*
|
||||||
* @param this calling object
|
* @param this calling object
|
||||||
* @param src source address for this SA
|
|
||||||
* @param dst destination address for this SA
|
* @param dst destination address for this SA
|
||||||
|
* @param spi SPI of the SA
|
||||||
|
* @param protocol protocol for this SA (ESP/AH)
|
||||||
* @param new_src new source address for this SA
|
* @param new_src new source address for this SA
|
||||||
* @param new_dst new destination address for this SA
|
* @param new_dst new destination address for this SA
|
||||||
* @param src_changes changes in src
|
* @param src_changes changes in src
|
||||||
* @param dst_changes changes in dst
|
* @param dst_changes changes in dst
|
||||||
* @param spi SPI allocated by us or remote peer
|
|
||||||
* @param protocol protocol for this SA (ESP/AH)
|
|
||||||
* @return
|
* @return
|
||||||
* - SUCCESS
|
* - SUCCESS
|
||||||
* - FAILED if kernel comm failed
|
* - FAILED if kernel comm failed
|
||||||
*/
|
*/
|
||||||
status_t (*update_sa_hosts)(kernel_interface_t *this,
|
status_t (*update_sa)(kernel_interface_t *this, host_t *dst, u_int32_t spi,
|
||||||
host_t *src, host_t *dst,
|
protocol_id_t protocol,
|
||||||
host_t *new_src, host_t *new_dst,
|
host_t *new_src, host_t *new_dst,
|
||||||
int src_changes, int dst_changes,
|
host_diff_t src_changes, host_diff_t dst_changes);
|
||||||
u_int32_t spi, protocol_id_t protocol);
|
|
||||||
/**
|
/**
|
||||||
* @brief Query the use time of an SA.
|
* @brief Query the use time of an SA.
|
||||||
*
|
*
|
||||||
|
* The use time of an SA is not the time of the last usage, but
|
||||||
|
* the time of the first usage of the SA.
|
||||||
|
*
|
||||||
* @param this calling object
|
* @param this calling object
|
||||||
* @param dst destination address for this SA
|
* @param dst destination address for this SA
|
||||||
* @param spi SPI allocated by us or remote peer
|
* @param spi SPI allocated by us or remote peer
|
||||||
|
@ -153,7 +173,7 @@ struct kernel_interface_t {
|
||||||
* - FAILED if kernel comm failed
|
* - FAILED if kernel comm failed
|
||||||
*/
|
*/
|
||||||
status_t (*query_sa) (kernel_interface_t *this, host_t *dst, u_int32_t spi,
|
status_t (*query_sa) (kernel_interface_t *this, host_t *dst, u_int32_t spi,
|
||||||
protocol_id_t protocol, time_t *use_time);
|
protocol_id_t protocol, u_int32_t *use_time);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Delete a previusly installed SA from the SAD.
|
* @brief Delete a previusly installed SA from the SAD.
|
||||||
|
@ -172,20 +192,19 @@ struct kernel_interface_t {
|
||||||
/**
|
/**
|
||||||
* @brief Add a policy to the SPD.
|
* @brief Add a policy to the SPD.
|
||||||
*
|
*
|
||||||
* A policy is always associated to an SA, so
|
* A policy is always associated to an SA. Traffic which matches a
|
||||||
* traffic applied to a policy. Traffic which
|
* policy is handled by the SA with the same reqid.
|
||||||
* matches a policy is handled by the SA with the same
|
* If the update flag is set, the policy is updated with the new
|
||||||
* reqid.
|
* src/dst addresses.
|
||||||
|
* If the update flag is not set, but a such policy is already in the
|
||||||
|
* kernel, the reference count to this policy is increased.
|
||||||
*
|
*
|
||||||
* @param this calling object
|
* @param this calling object
|
||||||
* @param me address of local peer
|
* @param src source address of SA
|
||||||
* @param other address of remote peer
|
* @param dst dest address of SA
|
||||||
* @param src src address of traffic this policy applies
|
* @param src_ts traffic selector to match traffic source
|
||||||
* @param dst dest address of traffic this policy applies
|
* @param dst_ts traffic selector to match traffic dest
|
||||||
* @param src_hostbits subnetmask to use for src address
|
* @param direction direction of traffic, POLICY_IN, POLICY_OUT, POLICY_FWD
|
||||||
* @param dst_hostbits subnetmask to use for dst address
|
|
||||||
* @param direction direction of traffic, XFRM_POLICY_OUT, XFRM_POLICY_IN, XFRM_POLICY_FWD
|
|
||||||
* @param upper_proto upper layer protocol of traffic for this policy (TCP, UDP, ICMP, ...)
|
|
||||||
* @param protocol protocol to use to protect traffic (AH/ESP)
|
* @param protocol protocol to use to protect traffic (AH/ESP)
|
||||||
* @param reqid uniqe ID of an SA to use to enforce policy
|
* @param reqid uniqe ID of an SA to use to enforce policy
|
||||||
* @param update update an existing policy, if TRUE
|
* @param update update an existing policy, if TRUE
|
||||||
|
@ -194,31 +213,52 @@ struct kernel_interface_t {
|
||||||
* - FAILED if kernel comm failed
|
* - FAILED if kernel comm failed
|
||||||
*/
|
*/
|
||||||
status_t (*add_policy) (kernel_interface_t *this,
|
status_t (*add_policy) (kernel_interface_t *this,
|
||||||
host_t *me, host_t *other,
|
|
||||||
host_t *src, host_t *dst,
|
host_t *src, host_t *dst,
|
||||||
u_int8_t src_hostbits, u_int8_t dst_hostbits,
|
traffic_selector_t *src_ts,
|
||||||
u_int8_t direction, u_int8_t upper_proto,
|
traffic_selector_t *dst_ts,
|
||||||
protocol_id_t protocol,
|
policy_dir_t direction, protocol_id_t protocol,
|
||||||
u_int32_t reqid, bool update);
|
u_int32_t reqid, bool update);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Query the use time of a policy.
|
||||||
|
*
|
||||||
|
* The use time of a policy is the time the policy was used
|
||||||
|
* for the last time.
|
||||||
|
*
|
||||||
|
* @param this calling object
|
||||||
|
* @param src_ts traffic selector to match traffic source
|
||||||
|
* @param dst_ts traffic selector to match traffic dest
|
||||||
|
* @param direction direction of traffic, POLICY_IN, POLICY_OUT, POLICY_FWD
|
||||||
|
* @param[out] use_time the time of this SA's last use
|
||||||
|
* @return
|
||||||
|
* - SUCCESS
|
||||||
|
* - FAILED if kernel comm failed
|
||||||
|
*/
|
||||||
|
status_t (*query_policy) (kernel_interface_t *this,
|
||||||
|
traffic_selector_t *src_ts,
|
||||||
|
traffic_selector_t *dst_ts,
|
||||||
|
policy_dir_t direction, u_int32_t *use_time);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Remove a policy from the SPD.
|
* @brief Remove a policy from the SPD.
|
||||||
*
|
*
|
||||||
|
* The kernel interface implements reference counting for policies.
|
||||||
|
* If the same policy is installed multiple times (in the case of rekeying),
|
||||||
|
* the reference counter is increased. del_policy() decreases the ref counter
|
||||||
|
* and removes the policy only when no more references are available.
|
||||||
|
*
|
||||||
* @param this calling object
|
* @param this calling object
|
||||||
* @param src src address of traffic this policy applies
|
* @param src_ts traffic selector to match traffic source
|
||||||
* @param dst dest address of traffic this policy applies
|
* @param dst_ts traffic selector to match traffic dest
|
||||||
* @param src_hostbits subnetmask to use for src address
|
* @param direction direction of traffic, POLICY_IN, POLICY_OUT, POLICY_FWD
|
||||||
* @param dst_hostbits subnetmask to use for dst address
|
|
||||||
* @param direction direction of traffic, XFRM_POLICY_OUT, XFRM_POLICY_IN, XFRM_POLICY_FWD
|
|
||||||
* @param upper_proto upper layer protocol of traffic for this policy (TCP, UDP, ICMP, ...)
|
|
||||||
* @return
|
* @return
|
||||||
* - SUCCESS
|
* - SUCCESS
|
||||||
* - FAILED if kernel comm failed
|
* - FAILED if kernel comm failed
|
||||||
*/
|
*/
|
||||||
status_t (*del_policy) (kernel_interface_t *this,
|
status_t (*del_policy) (kernel_interface_t *this,
|
||||||
host_t *src, host_t *dst,
|
traffic_selector_t *src_ts,
|
||||||
u_int8_t src_hostbits, u_int8_t dst_hostbits,
|
traffic_selector_t *dst_ts,
|
||||||
u_int8_t direction, u_int8_t upper_proto);
|
policy_dir_t direction);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Destroys a kernel_interface object.
|
* @brief Destroys a kernel_interface object.
|
||||||
|
|
|
@ -428,9 +428,9 @@ static void stroke_add_conn(private_stroke_t *this, stroke_msg_t *msg)
|
||||||
charon->connections->add_connection(charon->connections, connection);
|
charon->connections->add_connection(charon->connections, connection);
|
||||||
this->logger->log(this->logger, CONTROL, "added connection \"%s\": %s[%s]...%s[%s]",
|
this->logger->log(this->logger, CONTROL, "added connection \"%s\": %s[%s]...%s[%s]",
|
||||||
msg->add_conn.name,
|
msg->add_conn.name,
|
||||||
my_host->get_address(my_host),
|
my_host->get_string(my_host),
|
||||||
my_id->get_string(my_id),
|
my_id->get_string(my_id),
|
||||||
other_host->get_address(other_host),
|
other_host->get_string(other_host),
|
||||||
other_id->get_string(other_id));
|
other_id->get_string(other_id));
|
||||||
/* add to global policy list */
|
/* add to global policy list */
|
||||||
charon->policies->add_policy(charon->policies, policy);
|
charon->policies->add_policy(charon->policies, policy);
|
||||||
|
|
|
@ -100,9 +100,9 @@ static bool is_anyaddr(private_host_t *this)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* implements host_t.get_address
|
* implements host_t.get_string
|
||||||
*/
|
*/
|
||||||
static char *get_address(private_host_t *this)
|
static char *get_string(private_host_t *this)
|
||||||
{
|
{
|
||||||
switch (this->family)
|
switch (this->family)
|
||||||
{
|
{
|
||||||
|
@ -128,9 +128,9 @@ static char *get_address(private_host_t *this)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of host_t.get_address_as_chunk.
|
* Implementation of host_t.get_address.
|
||||||
*/
|
*/
|
||||||
static chunk_t get_address_as_chunk(private_host_t *this)
|
static chunk_t get_address(private_host_t *this)
|
||||||
{
|
{
|
||||||
chunk_t address = CHUNK_INITIALIZER;
|
chunk_t address = CHUNK_INITIALIZER;
|
||||||
|
|
||||||
|
@ -139,9 +139,8 @@ static chunk_t get_address_as_chunk(private_host_t *this)
|
||||||
case AF_INET:
|
case AF_INET:
|
||||||
{
|
{
|
||||||
/* allocate 4 bytes for IPv4 address*/
|
/* allocate 4 bytes for IPv4 address*/
|
||||||
address.ptr = malloc(4);
|
address.ptr = (char*)&(this->address4.sin_addr.s_addr);
|
||||||
address.len = 4;
|
address.len = 4;
|
||||||
memcpy(address.ptr,&(this->address4.sin_addr.s_addr),4);
|
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
|
@ -151,22 +150,9 @@ static chunk_t get_address_as_chunk(private_host_t *this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static xfrm_address_t get_xfrm_addr(private_host_t *this)
|
/**
|
||||||
{
|
* implements host_t.get_family
|
||||||
switch (this->family)
|
*/
|
||||||
{
|
|
||||||
case AF_INET:
|
|
||||||
{
|
|
||||||
return (xfrm_address_t)(this->address4.sin_addr.s_addr);
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
/* todo */
|
|
||||||
return (xfrm_address_t)(this->address4.sin_addr.s_addr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int get_family(private_host_t *this)
|
static int get_family(private_host_t *this)
|
||||||
{
|
{
|
||||||
return this->family;
|
return this->family;
|
||||||
|
@ -203,12 +189,11 @@ static void set_port(private_host_t *this, u_int16_t port)
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
/**/
|
/*TODO*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements host_t.clone.
|
* Implements host_t.clone.
|
||||||
*/
|
*/
|
||||||
|
@ -249,9 +234,9 @@ static bool ip_equals(private_host_t *this, private_host_t *other)
|
||||||
/**
|
/**
|
||||||
* Implements host_t.get_differences
|
* Implements host_t.get_differences
|
||||||
*/
|
*/
|
||||||
static int get_differences(private_host_t *this, private_host_t *other)
|
static host_diff_t get_differences(private_host_t *this, private_host_t *other)
|
||||||
{
|
{
|
||||||
int ret = HOST_DIFF_NONE;
|
host_diff_t ret = HOST_DIFF_NONE;
|
||||||
|
|
||||||
if (!this->public.ip_equals(&this->public, &other->public))
|
if (!this->public.ip_equals(&this->public, &other->public))
|
||||||
{
|
{
|
||||||
|
@ -307,12 +292,11 @@ static private_host_t *host_create_empty(void)
|
||||||
this->public.get_sockaddr_len = (socklen_t*(*) (host_t*))get_sockaddr_len;
|
this->public.get_sockaddr_len = (socklen_t*(*) (host_t*))get_sockaddr_len;
|
||||||
this->public.clone = (host_t* (*) (host_t*))clone;
|
this->public.clone = (host_t* (*) (host_t*))clone;
|
||||||
this->public.get_family = (int (*) (host_t*))get_family;
|
this->public.get_family = (int (*) (host_t*))get_family;
|
||||||
this->public.get_xfrm_addr = (xfrm_address_t (*) (host_t *))get_xfrm_addr;
|
this->public.get_string = (char* (*) (host_t *))get_string;
|
||||||
this->public.get_address = (char* (*) (host_t *))get_address;
|
this->public.get_address = (chunk_t (*) (host_t *)) get_address;
|
||||||
this->public.get_address_as_chunk = (chunk_t (*) (host_t *)) get_address_as_chunk;
|
|
||||||
this->public.get_port = (u_int16_t (*) (host_t *))get_port;
|
this->public.get_port = (u_int16_t (*) (host_t *))get_port;
|
||||||
this->public.set_port = (void (*) (host_t *,u_int16_t))set_port;
|
this->public.set_port = (void (*) (host_t *,u_int16_t))set_port;
|
||||||
this->public.get_differences = (int (*) (host_t *,host_t *)) get_differences;
|
this->public.get_differences = (host_diff_t (*) (host_t *,host_t *)) get_differences;
|
||||||
this->public.ip_equals = (bool (*) (host_t *,host_t *)) ip_equals;
|
this->public.ip_equals = (bool (*) (host_t *,host_t *)) ip_equals;
|
||||||
this->public.equals = (bool (*) (host_t *,host_t *)) equals;
|
this->public.equals = (bool (*) (host_t *,host_t *)) equals;
|
||||||
this->public.is_anyaddr = (bool (*) (host_t *)) is_anyaddr;
|
this->public.is_anyaddr = (bool (*) (host_t *)) is_anyaddr;
|
||||||
|
|
|
@ -35,10 +35,17 @@
|
||||||
|
|
||||||
#include <types.h>
|
#include <types.h>
|
||||||
|
|
||||||
|
typedef enum host_diff_t host_diff_t;
|
||||||
|
|
||||||
#define HOST_DIFF_NONE 0
|
/**
|
||||||
#define HOST_DIFF_ADDR 1
|
* Differences between two hosts. They differ in
|
||||||
#define HOST_DIFF_PORT 2
|
* address, port, or both.
|
||||||
|
*/
|
||||||
|
enum host_diff_t {
|
||||||
|
HOST_DIFF_NONE = 0,
|
||||||
|
HOST_DIFF_ADDR = 1,
|
||||||
|
HOST_DIFF_PORT = 2,
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct host_t host_t;
|
typedef struct host_t host_t;
|
||||||
|
|
||||||
|
@ -80,7 +87,7 @@ struct host_t {
|
||||||
/**
|
/**
|
||||||
* @brief Get the length of the sockaddr struct.
|
* @brief Get the length of the sockaddr struct.
|
||||||
*
|
*
|
||||||
* Sepending on the family, the length of the sockaddr struct
|
* Depending on the family, the length of the sockaddr struct
|
||||||
* is different. Use this function to get the length of the sockaddr
|
* is different. Use this function to get the length of the sockaddr
|
||||||
* struct returned by get_sock_addr.
|
* struct returned by get_sock_addr.
|
||||||
*
|
*
|
||||||
|
@ -91,20 +98,6 @@ struct host_t {
|
||||||
*/
|
*/
|
||||||
socklen_t *(*get_sockaddr_len) (host_t *this);
|
socklen_t *(*get_sockaddr_len) (host_t *this);
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Gets the address as xfrm_address_t.
|
|
||||||
*
|
|
||||||
* This function allows the conversion to an
|
|
||||||
* xfrm_address_t, used for netlink communication
|
|
||||||
* with the kernel.
|
|
||||||
*
|
|
||||||
* @see kernel_interface_t.
|
|
||||||
*
|
|
||||||
* @param this calling object
|
|
||||||
* @return address in xfrm_address_t format
|
|
||||||
*/
|
|
||||||
xfrm_address_t (*get_xfrm_addr) (host_t *this);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Gets the family of the address
|
* @brief Gets the family of the address
|
||||||
*
|
*
|
||||||
|
@ -114,15 +107,15 @@ struct host_t {
|
||||||
int (*get_family) (host_t *this);
|
int (*get_family) (host_t *this);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief get the address of this host
|
* @brief Get the address of this host as a string
|
||||||
*
|
*
|
||||||
* Mostly used for debugging purposes.
|
* Mostly used for debugging purposes. String
|
||||||
* @warning string must NOT be freed
|
* points to internal data.
|
||||||
*
|
*
|
||||||
* @param this object
|
* @param this object
|
||||||
* @return address string,
|
* @return address string,
|
||||||
*/
|
*/
|
||||||
char* (*get_address) (host_t *this);
|
char* (*get_string) (host_t *this);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Checks if the ip address of host is set to default route.
|
* @brief Checks if the ip address of host is set to default route.
|
||||||
|
@ -137,12 +130,12 @@ struct host_t {
|
||||||
/**
|
/**
|
||||||
* @brief get the address of this host as chunk_t
|
* @brief get the address of this host as chunk_t
|
||||||
*
|
*
|
||||||
* @warning returned chunk has to get destroyed by caller.
|
* Returned chunk points to internal data.
|
||||||
*
|
*
|
||||||
* @param this object
|
* @param this object
|
||||||
* @return address string,
|
* @return address string,
|
||||||
*/
|
*/
|
||||||
chunk_t (*get_address_as_chunk) (host_t *this);
|
chunk_t (*get_address) (host_t *this);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief get the port of this host
|
* @brief get the port of this host
|
||||||
|
@ -183,10 +176,9 @@ struct host_t {
|
||||||
*
|
*
|
||||||
* @param this object to compare
|
* @param this object to compare
|
||||||
* @param other the other to compare
|
* @param other the other to compare
|
||||||
* @return a combination of HOST_DIFF_NONE,
|
* @return differences in a combination of host_diff_t's
|
||||||
* HOST_DIFF_ADDR and HOST_DIFF_PORT
|
|
||||||
*/
|
*/
|
||||||
int (*get_differences) (host_t *this, host_t *other);
|
host_diff_t (*get_differences) (host_t *this, host_t *other);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Destroy this host object
|
* @brief Destroy this host object
|
||||||
|
|
|
@ -174,6 +174,7 @@ whitelist_t whitelist[] = {
|
||||||
{inet_ntoa, 0xFF},
|
{inet_ntoa, 0xFF},
|
||||||
{strerror, 0xFF},
|
{strerror, 0xFF},
|
||||||
{getprotobynumber, 0xFF},
|
{getprotobynumber, 0xFF},
|
||||||
|
{getservbyport, 0xFF},
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue