Project

General

Profile

Feature #2252

Updated by Tobias Brunner almost 4 years ago

Hello,

I'm not sure if this is intentional, but the 'includes()' method in
traffic_selector.c compares the address family and address range for matching
on the selector, but does *not* compare protocol and port:

<pre><code class="c">
> METHOD(traffic_selector_t, includes, bool,

>
private_traffic_selector_t *this, host_t *host)
> {

>
chunk_t addr;

>
int family = host->get_family(host);


>
>
if ((family == AF_INET && this->type == TS_IPV4_ADDR_RANGE) ||

>
(family == AF_INET6 && this->type == TS_IPV6_ADDR_RANGE))

>
{

>
addr = host->get_address(host);


>
>
return memcmp(this->from, addr.ptr, addr.len) <= 0 &&

>
memcmp(this->to, addr.ptr, addr.len) >= 0;

>
}


>
>
return FALSE;
> }
</code></pre>


Libipsec (ipsec_policy.c) attempts to match an outbound packet to a policy
that compares protocol and source/destination address range, but *not*
source/destination port range:

<pre><code class="c">
> METHOD(ipsec_policy_t, match_packet, bool,
> private_ipsec_policy_t *this, ip_packet_t *packet)
> {

>
uint8_t proto = packet->get_next_header(packet);

>
host_t *src = packet->get_source(packet),

>
*dst = packet->get_destination(packet);


>
>
return (!this->protocol || this->protocol == proto) &&

>
this->src_ts->includes(this->src_ts, src) &&

>
this->dst_ts->includes(this->dst_ts, dst);
> }
</code></pre>


As a result, if you have multiple SP/SAs that have the same /32
source/destination address but differ only in destination port, the above
results in all packets being matched by only *one* of those SP/SAs.

Seems to me that 'includes()' is actually 'includes_address()' and that
match_packet() should have additional tests for port range matching.

Thanks in advance.

Phil

Back