traffic-selector: Add a compare function to sort traffic selectors
This commit is contained in:
parent
698ed656f7
commit
373a147fed
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue