Feature #2252
Updated by Tobias Brunner over 8 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
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