traffic-selector: Add a compare function to sort traffic selectors

This commit is contained in:
Martin Willi 2015-02-19 18:01:38 +01:00
parent 698ed656f7
commit 373a147fed
2 changed files with 86 additions and 34 deletions

View File

@ -449,41 +449,9 @@ METHOD(traffic_selector_t, get_subset, traffic_selector_t*,
}
METHOD(traffic_selector_t, equals, bool,
private_traffic_selector_t *this, traffic_selector_t *other_public)
private_traffic_selector_t *this, traffic_selector_t *other)
{
private_traffic_selector_t *other;
other = (private_traffic_selector_t*)other_public;
if (this->type != other->type)
{
return FALSE;
}
if (!(this->from_port == other->from_port &&
this->to_port == other->to_port &&
this->protocol == other->protocol))
{
return FALSE;
}
switch (this->type)
{
case TS_IPV4_ADDR_RANGE:
if (memeq(this->from4, other->from4, sizeof(this->from4)) &&
memeq(this->to4, other->to4, sizeof(this->to4)))
{
return TRUE;
}
break;
case TS_IPV6_ADDR_RANGE:
if (memeq(this->from6, other->from6, sizeof(this->from6)) &&
memeq(this->to6, other->to6, sizeof(this->to6)))
{
return TRUE;
}
break;
default:
break;
}
return FALSE;
return traffic_selector_cmp(&this->public, other, NULL) == 0;
}
METHOD(traffic_selector_t, get_from_address, chunk_t,
@ -723,6 +691,79 @@ METHOD(traffic_selector_t, destroy, void,
free(this);
}
/**
* Compare two integers
*/
static int compare_int(int a, int b)
{
return a - b;
}
/*
* See header
*/
int traffic_selector_cmp(traffic_selector_t *a_pub, traffic_selector_t *b_pub,
void *opts)
{
private_traffic_selector_t *a, *b;
int res;
a = (private_traffic_selector_t*)a_pub;
b = (private_traffic_selector_t*)b_pub;
/* IPv4 before IPv6 */
res = compare_int(a->type, b->type);
if (res)
{
return res;
}
switch (a->type)
{
case TS_IPV4_ADDR_RANGE:
/* lower starting subnets first */
res = memcmp(a->from4, b->from4, sizeof(a->from4));
if (res)
{
return res;
}
/* larger subnets first */
res = memcmp(b->to4, a->to4, sizeof(a->to4));
if (res)
{
return res;
}
break;
case TS_IPV6_ADDR_RANGE:
res = memcmp(a->from6, b->from6, sizeof(a->from6));
if (res)
{
return res;
}
res = memcmp(b->to6, a->to6, sizeof(a->to6));
if (res)
{
return res;
}
break;
default:
return 1;
}
/* lower protocols first */
res = compare_int(a->protocol, b->protocol);
if (res)
{
return res;
}
/* lower starting ports first */
res = compare_int(a->from_port, b->from_port);
if (res)
{
return res;
}
/* larger port ranges first */
return compare_int(b->to_port, a->to_port);
}
/*
* see header
*/

View File

@ -248,6 +248,17 @@ static inline u_int8_t traffic_selector_icmp_code(u_int16_t port)
return port & 0xff;
}
/**
* Compare two traffic selectors, usable as sort function
*
* @param a first selector to compare
* @param b second selector to compare
* @param opts optional sort options, currently unused
* @return > 0 if a > b, 0 if a == b, < 0 if a < b
*/
int traffic_selector_cmp(traffic_selector_t *a, traffic_selector_t *b,
void *opts);
/**
* Create a new traffic selector using human readable params.
*