Merge branch 'icmp'
Improves handling of ICMP[v6] traffic selectors that specify message type and code. Fixes #421.
This commit is contained in:
@@ -858,6 +858,14 @@ Instead of omitting either value
|
|||||||
can be used to the same effect, e.g.
|
can be used to the same effect, e.g.
|
||||||
.BR leftsubnet=fec1::1[udp/%any],10.0.0.0/16[%any/53] .
|
.BR leftsubnet=fec1::1[udp/%any],10.0.0.0/16[%any/53] .
|
||||||
|
|
||||||
|
If the protocol is
|
||||||
|
.B icmp
|
||||||
|
or
|
||||||
|
.B ipv6-icmp
|
||||||
|
the port is interpreted as ICMP message type if it is less than 256 or as type
|
||||||
|
and code if it is greater or equal to 256, with the type in the most significant
|
||||||
|
8 bits and the code in the least significant 8 bits.
|
||||||
|
|
||||||
The port value can alternatively take the value
|
The port value can alternatively take the value
|
||||||
.B %opaque
|
.B %opaque
|
||||||
for RFC 4301 OPAQUE selectors, or a numerical range in the form
|
for RFC 4301 OPAQUE selectors, or a numerical range in the form
|
||||||
|
|||||||
+33
-6
@@ -78,7 +78,8 @@
|
|||||||
#
|
#
|
||||||
# PLUTO_MY_PORT
|
# PLUTO_MY_PORT
|
||||||
# is the UDP/TCP port to which the IPsec SA is
|
# is the UDP/TCP port to which the IPsec SA is
|
||||||
# restricted on our side.
|
# restricted on our side. For ICMP/ICMPv6 this contains the
|
||||||
|
# message type, and PLUTO_PEER_PORT the message code.
|
||||||
#
|
#
|
||||||
# PLUTO_PEER
|
# PLUTO_PEER
|
||||||
# is the IP address of our peer.
|
# is the IP address of our peer.
|
||||||
@@ -97,7 +98,8 @@
|
|||||||
#
|
#
|
||||||
# PLUTO_PEER_PORT
|
# PLUTO_PEER_PORT
|
||||||
# is the UDP/TCP port to which the IPsec SA is
|
# is the UDP/TCP port to which the IPsec SA is
|
||||||
# restricted on the peer side.
|
# restricted on the peer side. For ICMP/ICMPv6 this contains the
|
||||||
|
# message code, and PLUTO_MY_PORT the message type.
|
||||||
#
|
#
|
||||||
# PLUTO_XAUTH_ID
|
# PLUTO_XAUTH_ID
|
||||||
# is an optional user ID employed by the XAUTH protocol
|
# is an optional user ID employed by the XAUTH protocol
|
||||||
@@ -288,16 +290,41 @@ else
|
|||||||
IPSEC_POLICY_OUT="$IPSEC_POLICY --dir out"
|
IPSEC_POLICY_OUT="$IPSEC_POLICY --dir out"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# use protocol specific options to set ports
|
||||||
|
case "$PLUTO_MY_PROTOCOL" in
|
||||||
|
1) # ICMP
|
||||||
|
ICMP_TYPE_OPTION="--icmp-type"
|
||||||
|
;;
|
||||||
|
58) # ICMPv6
|
||||||
|
ICMP_TYPE_OPTION="--icmpv6-type"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
# are there port numbers?
|
# are there port numbers?
|
||||||
if [ "$PLUTO_MY_PORT" != 0 ]
|
if [ "$PLUTO_MY_PORT" != 0 ]
|
||||||
then
|
then
|
||||||
S_MY_PORT="--sport $PLUTO_MY_PORT"
|
if [ -n "$ICMP_TYPE_OPTION" ]
|
||||||
D_MY_PORT="--dport $PLUTO_MY_PORT"
|
then
|
||||||
|
S_MY_PORT="$ICMP_TYPE_OPTION $PLUTO_MY_PORT"
|
||||||
|
D_MY_PORT="$ICMP_TYPE_OPTION $PLUTO_MY_PORT"
|
||||||
|
else
|
||||||
|
S_MY_PORT="--sport $PLUTO_MY_PORT"
|
||||||
|
D_MY_PORT="--dport $PLUTO_MY_PORT"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
if [ "$PLUTO_PEER_PORT" != 0 ]
|
if [ "$PLUTO_PEER_PORT" != 0 ]
|
||||||
then
|
then
|
||||||
S_PEER_PORT="--sport $PLUTO_PEER_PORT"
|
if [ -n "$ICMP_TYPE_OPTION" ]
|
||||||
D_PEER_PORT="--dport $PLUTO_PEER_PORT"
|
then
|
||||||
|
# the syntax is --icmp[v6]-type type[/code], so add it to the existing option
|
||||||
|
S_MY_PORT="$S_MY_PORT/$PLUTO_PEER_PORT"
|
||||||
|
D_MY_PORT="$D_MY_PORT/$PLUTO_PEER_PORT"
|
||||||
|
else
|
||||||
|
S_PEER_PORT="--sport $PLUTO_PEER_PORT"
|
||||||
|
D_PEER_PORT="--dport $PLUTO_PEER_PORT"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# resolve octal escape sequences
|
# resolve octal escape sequences
|
||||||
|
|||||||
@@ -174,6 +174,27 @@ static char *make_vip_vars(private_updown_listener_t *this, ike_sa_t *ike_sa)
|
|||||||
return strdup(total);
|
return strdup(total);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine proper values for port env variable
|
||||||
|
*/
|
||||||
|
static u_int16_t get_port(traffic_selector_t *me,
|
||||||
|
traffic_selector_t *other, bool local)
|
||||||
|
{
|
||||||
|
switch (max(me->get_protocol(me), other->get_protocol(other)))
|
||||||
|
{
|
||||||
|
case IPPROTO_ICMP:
|
||||||
|
case IPPROTO_ICMPV6:
|
||||||
|
{
|
||||||
|
u_int16_t port = me->get_from_port(me);
|
||||||
|
|
||||||
|
port = max(port, other->get_from_port(other));
|
||||||
|
return local ? traffic_selector_icmp_type(port)
|
||||||
|
: traffic_selector_icmp_code(port);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return local ? me->get_from_port(me) : other->get_from_port(other);
|
||||||
|
}
|
||||||
|
|
||||||
METHOD(listener_t, child_updown, bool,
|
METHOD(listener_t, child_updown, bool,
|
||||||
private_updown_listener_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa,
|
private_updown_listener_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa,
|
||||||
bool up)
|
bool up)
|
||||||
@@ -341,11 +362,11 @@ METHOD(listener_t, child_updown, bool,
|
|||||||
ike_sa->get_unique_id(ike_sa),
|
ike_sa->get_unique_id(ike_sa),
|
||||||
me, ike_sa->get_my_id(ike_sa),
|
me, ike_sa->get_my_id(ike_sa),
|
||||||
my_client, my_client_mask,
|
my_client, my_client_mask,
|
||||||
my_ts->get_from_port(my_ts),
|
get_port(my_ts, other_ts, TRUE),
|
||||||
my_ts->get_protocol(my_ts),
|
my_ts->get_protocol(my_ts),
|
||||||
other, ike_sa->get_other_id(ike_sa),
|
other, ike_sa->get_other_id(ike_sa),
|
||||||
other_client, other_client_mask,
|
other_client, other_client_mask,
|
||||||
other_ts->get_from_port(other_ts),
|
get_port(my_ts, other_ts, FALSE),
|
||||||
other_ts->get_protocol(other_ts),
|
other_ts->get_protocol(other_ts),
|
||||||
xauth,
|
xauth,
|
||||||
virtual_ip,
|
virtual_ip,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2006-2012 Tobias Brunner
|
* Copyright (C) 2006-2013 Tobias Brunner
|
||||||
* Copyright (C) 2005-2009 Martin Willi
|
* Copyright (C) 2005-2009 Martin Willi
|
||||||
* Copyright (C) 2008 Andreas Steffen
|
* Copyright (C) 2008 Andreas Steffen
|
||||||
* Copyright (C) 2006-2007 Fabian Hartmann, Noah Heusser
|
* Copyright (C) 2006-2007 Fabian Hartmann, Noah Heusser
|
||||||
@@ -744,6 +744,17 @@ static struct xfrm_selector ts2selector(traffic_selector_t *src,
|
|||||||
ts2subnet(src, &sel.saddr, &sel.prefixlen_s);
|
ts2subnet(src, &sel.saddr, &sel.prefixlen_s);
|
||||||
ts2ports(dst, &sel.dport, &sel.dport_mask);
|
ts2ports(dst, &sel.dport, &sel.dport_mask);
|
||||||
ts2ports(src, &sel.sport, &sel.sport_mask);
|
ts2ports(src, &sel.sport, &sel.sport_mask);
|
||||||
|
if ((sel.proto == IPPROTO_ICMP || sel.proto == IPPROTO_ICMPV6) &&
|
||||||
|
(sel.dport || sel.sport))
|
||||||
|
{
|
||||||
|
/* the ICMP type is encoded in the most significant 8 bits and the ICMP
|
||||||
|
* code in the least significant 8 bits of the port. via XFRM we have
|
||||||
|
* to pass the ICMP type and code in the source and destination port
|
||||||
|
* fields, respectively. the port is in network byte order. */
|
||||||
|
u_int16_t port = max(sel.dport, sel.sport);
|
||||||
|
sel.sport = htons(port & 0xff);
|
||||||
|
sel.dport = htons(port >> 8);
|
||||||
|
}
|
||||||
sel.ifindex = 0;
|
sel.ifindex = 0;
|
||||||
sel.user = 0;
|
sel.user = 0;
|
||||||
|
|
||||||
@@ -766,7 +777,7 @@ static traffic_selector_t* selector2ts(struct xfrm_selector *sel, bool src)
|
|||||||
prefixlen = sel->prefixlen_s;
|
prefixlen = sel->prefixlen_s;
|
||||||
if (sel->sport_mask)
|
if (sel->sport_mask)
|
||||||
{
|
{
|
||||||
port = htons(sel->sport);
|
port = ntohs(sel->sport);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -775,10 +786,15 @@ static traffic_selector_t* selector2ts(struct xfrm_selector *sel, bool src)
|
|||||||
prefixlen = sel->prefixlen_d;
|
prefixlen = sel->prefixlen_d;
|
||||||
if (sel->dport_mask)
|
if (sel->dport_mask)
|
||||||
{
|
{
|
||||||
port = htons(sel->dport);
|
port = ntohs(sel->dport);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (sel->proto == IPPROTO_ICMP || sel->proto == IPPROTO_ICMPV6)
|
||||||
|
{ /* convert ICMP[v6] message type and code as supplied by the kernel in
|
||||||
|
* source and destination ports (both in network order) */
|
||||||
|
port = (sel->sport >> 8) | (sel->dport & 0xff00);
|
||||||
|
port = ntohs(port);
|
||||||
|
}
|
||||||
/* The Linux 2.6 kernel does not set the selector's family field,
|
/* The Linux 2.6 kernel does not set the selector's family field,
|
||||||
* so as a kludge we additionally test the prefix length.
|
* so as a kludge we additionally test the prefix length.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -870,6 +870,28 @@ static int lookup_algorithm(transform_type_t type, int ikev2)
|
|||||||
return alg;
|
return alg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper to set a port in a sockaddr_t, the port has to be in host order
|
||||||
|
*/
|
||||||
|
static void set_port(sockaddr_t *addr, u_int16_t port)
|
||||||
|
{
|
||||||
|
switch (addr->sa_family)
|
||||||
|
{
|
||||||
|
case AF_INET:
|
||||||
|
{
|
||||||
|
struct sockaddr_in *sin = (struct sockaddr_in*)addr;
|
||||||
|
sin->sin_port = htons(port);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case AF_INET6:
|
||||||
|
{
|
||||||
|
struct sockaddr_in6 *sin6 = (struct sockaddr_in6*)addr;
|
||||||
|
sin6->sin6_port = htons(port);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copy a host_t as sockaddr_t to the given memory location.
|
* Copy a host_t as sockaddr_t to the given memory location.
|
||||||
* @return the number of bytes copied
|
* @return the number of bytes copied
|
||||||
@@ -878,37 +900,38 @@ static size_t hostcpy(void *dest, host_t *host, bool include_port)
|
|||||||
{
|
{
|
||||||
sockaddr_t *addr = host->get_sockaddr(host), *dest_addr = dest;
|
sockaddr_t *addr = host->get_sockaddr(host), *dest_addr = dest;
|
||||||
socklen_t *len = host->get_sockaddr_len(host);
|
socklen_t *len = host->get_sockaddr_len(host);
|
||||||
u_int16_t port = htons(host->get_port(host));
|
|
||||||
|
|
||||||
memcpy(dest, addr, *len);
|
memcpy(dest, addr, *len);
|
||||||
#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
|
#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
|
||||||
dest_addr->sa_len = *len;
|
dest_addr->sa_len = *len;
|
||||||
#endif
|
#endif
|
||||||
switch (dest_addr->sa_family)
|
if (!include_port)
|
||||||
{
|
{
|
||||||
case AF_INET:
|
set_port(dest_addr, 0);
|
||||||
{
|
|
||||||
struct sockaddr_in *sin = dest;
|
|
||||||
sin->sin_port = include_port ? port : 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case AF_INET6:
|
|
||||||
{
|
|
||||||
struct sockaddr_in6 *sin6 = dest;
|
|
||||||
sin6->sin6_port = include_port ? port : 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return *len;
|
return *len;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* add a host behind an sadb_address extension
|
* Copy a host_t as sockaddr_t to the given memory location and map the port to
|
||||||
|
* ICMP/ICMPv6 message type/code as the Linux kernel expects it, that is, the
|
||||||
|
* type in the source and the code in the destination address.
|
||||||
|
* @return the number of bytes copied
|
||||||
*/
|
*/
|
||||||
static void host2ext(host_t *host, struct sadb_address *ext, bool include_port)
|
static size_t hostcpy_icmp(void *dest, host_t *host, u_int16_t type)
|
||||||
{
|
{
|
||||||
size_t len = hostcpy(ext + 1, host, include_port);
|
size_t len;
|
||||||
ext->sadb_address_len = PFKEY_LEN(sizeof(*ext) + len);
|
|
||||||
|
len = hostcpy(dest, host, TRUE);
|
||||||
|
if (type == SADB_EXT_ADDRESS_SRC)
|
||||||
|
{
|
||||||
|
set_port(dest, traffic_selector_icmp_type(host->get_port(host)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
set_port(dest, traffic_selector_icmp_code(host->get_port(host)));
|
||||||
|
}
|
||||||
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -918,10 +941,20 @@ static void add_addr_ext(struct sadb_msg *msg, host_t *host, u_int16_t type,
|
|||||||
u_int8_t proto, u_int8_t prefixlen, bool include_port)
|
u_int8_t proto, u_int8_t prefixlen, bool include_port)
|
||||||
{
|
{
|
||||||
struct sadb_address *addr = (struct sadb_address*)PFKEY_EXT_ADD_NEXT(msg);
|
struct sadb_address *addr = (struct sadb_address*)PFKEY_EXT_ADD_NEXT(msg);
|
||||||
|
size_t len;
|
||||||
|
|
||||||
addr->sadb_address_exttype = type;
|
addr->sadb_address_exttype = type;
|
||||||
addr->sadb_address_proto = proto;
|
addr->sadb_address_proto = proto;
|
||||||
addr->sadb_address_prefixlen = prefixlen;
|
addr->sadb_address_prefixlen = prefixlen;
|
||||||
host2ext(host, addr, include_port);
|
if (proto == IPPROTO_ICMP || proto == IPPROTO_ICMPV6)
|
||||||
|
{
|
||||||
|
len = hostcpy_icmp(addr + 1, host, type);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
len = hostcpy(addr + 1, host, include_port);
|
||||||
|
}
|
||||||
|
addr->sadb_address_len = PFKEY_LEN(sizeof(*addr) + len);
|
||||||
PFKEY_EXT_ADD(msg, addr);
|
PFKEY_EXT_ADD(msg, addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -70,6 +70,9 @@
|
|||||||
* @defgroup jobs jobs
|
* @defgroup jobs jobs
|
||||||
* @ingroup processing
|
* @ingroup processing
|
||||||
*
|
*
|
||||||
|
* @defgroup selectors selectors
|
||||||
|
* @ingroup libstrongswan
|
||||||
|
*
|
||||||
* @defgroup threading threading
|
* @defgroup threading threading
|
||||||
* @ingroup libstrongswan
|
* @ingroup libstrongswan
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2007-2009 Tobias Brunner
|
* Copyright (C) 2007-2013 Tobias Brunner
|
||||||
* Copyright (C) 2005-2007 Martin Willi
|
* Copyright (C) 2005-2007 Martin Willi
|
||||||
* Copyright (C) 2005 Jan Hutter
|
* Copyright (C) 2005 Jan Hutter
|
||||||
* Hochschule fuer Technik Rapperswil
|
* Hochschule fuer Technik Rapperswil
|
||||||
@@ -193,6 +193,22 @@ static bool is_any(private_traffic_selector_t *this)
|
|||||||
return this->from_port == 0 && this->to_port == 0xffff;
|
return this->from_port == 0 && this->to_port == 0xffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Print ICMP/ICMPv6 type and code
|
||||||
|
*/
|
||||||
|
static int print_icmp(printf_hook_data_t *data, u_int16_t port)
|
||||||
|
{
|
||||||
|
u_int8_t type, code;
|
||||||
|
|
||||||
|
type = traffic_selector_icmp_type(port);
|
||||||
|
code = traffic_selector_icmp_code(port);
|
||||||
|
if (code)
|
||||||
|
{
|
||||||
|
return print_in_hook(data, "%d(%d)", type, code);
|
||||||
|
}
|
||||||
|
return print_in_hook(data, "%d", type);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Described in header.
|
* Described in header.
|
||||||
*/
|
*/
|
||||||
@@ -302,20 +318,35 @@ int traffic_selector_printf_hook(printf_hook_data_t *data,
|
|||||||
{
|
{
|
||||||
struct servent *serv;
|
struct servent *serv;
|
||||||
|
|
||||||
serv = getservbyport(htons(this->from_port), serv_proto);
|
if (this->protocol == IPPROTO_ICMP ||
|
||||||
if (serv)
|
this->protocol == IPPROTO_ICMPV6)
|
||||||
{
|
{
|
||||||
written += print_in_hook(data, "%s", serv->s_name);
|
written += print_icmp(data, this->from_port);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
written += print_in_hook(data, "%d", this->from_port);
|
serv = getservbyport(htons(this->from_port), serv_proto);
|
||||||
|
if (serv)
|
||||||
|
{
|
||||||
|
written += print_in_hook(data, "%s", serv->s_name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
written += print_in_hook(data, "%d", this->from_port);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (is_opaque(this))
|
else if (is_opaque(this))
|
||||||
{
|
{
|
||||||
written += print_in_hook(data, "OPAQUE");
|
written += print_in_hook(data, "OPAQUE");
|
||||||
}
|
}
|
||||||
|
else if (this->protocol == IPPROTO_ICMP ||
|
||||||
|
this->protocol == IPPROTO_ICMPV6)
|
||||||
|
{
|
||||||
|
written += print_icmp(data, this->from_port);
|
||||||
|
written += print_in_hook(data, "-");
|
||||||
|
written += print_icmp(data, this->to_port);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
written += print_in_hook(data, "%d-%d",
|
written += print_in_hook(data, "%d-%d",
|
||||||
@@ -910,6 +941,10 @@ static private_traffic_selector_t *traffic_selector_create(u_int8_t protocol,
|
|||||||
.protocol = protocol,
|
.protocol = protocol,
|
||||||
.type = type,
|
.type = type,
|
||||||
);
|
);
|
||||||
|
if (protocol == IPPROTO_ICMP || protocol == IPPROTO_ICMPV6)
|
||||||
|
{
|
||||||
|
this->from_port = from_port < 256 ? from_port << 8 : from_port;
|
||||||
|
this->to_port = to_port < 256 ? to_port << 8 : to_port;
|
||||||
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2007 Tobias Brunner
|
* Copyright (C) 2007-2013 Tobias Brunner
|
||||||
* Copyright (C) 2005-2006 Martin Willi
|
* Copyright (C) 2005-2006 Martin Willi
|
||||||
* Copyright (C) 2005 Jan Hutter
|
* Copyright (C) 2005 Jan Hutter
|
||||||
* Hochschule fuer Technik Rapperswil
|
* Hochschule fuer Technik Rapperswil
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @defgroup traffic_selector traffic_selector
|
* @defgroup traffic_selector traffic_selector
|
||||||
* @{ @ingroup config
|
* @{ @ingroup selectors
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef TRAFFIC_SELECTOR_H_
|
#ifndef TRAFFIC_SELECTOR_H_
|
||||||
@@ -62,7 +62,12 @@ extern enum_name_t *ts_type_name;
|
|||||||
* Object representing a traffic selector entry.
|
* Object representing a traffic selector entry.
|
||||||
*
|
*
|
||||||
* A traffic selector defines an range of addresses
|
* A traffic selector defines an range of addresses
|
||||||
* and a range of ports. IPv6 is not fully supported yet.
|
* and a range of ports.
|
||||||
|
*
|
||||||
|
* If the protocol is ICMP or ICMPv6 the ICMP type and code are stored in the
|
||||||
|
* port field as follows: The message type is placed in the most significant
|
||||||
|
* 8 bits and the code in the least significant 8 bits. Utility functions are
|
||||||
|
* provided to extract the individual values.
|
||||||
*/
|
*/
|
||||||
struct traffic_selector_t {
|
struct traffic_selector_t {
|
||||||
|
|
||||||
@@ -109,7 +114,11 @@ struct traffic_selector_t {
|
|||||||
* Get starting port of this ts.
|
* Get starting port of this ts.
|
||||||
*
|
*
|
||||||
* Port is in host order, since the parser converts it.
|
* Port is in host order, since the parser converts it.
|
||||||
* Size depends on protocol.
|
*
|
||||||
|
* If the protocol is ICMP/ICMPv6 the ICMP type and code are stored in this
|
||||||
|
* field as follows: The message type is placed in the most significant
|
||||||
|
* 8 bits and the code in the least significant 8 bits. Use the utility
|
||||||
|
* functions to extract them.
|
||||||
*
|
*
|
||||||
* @return port
|
* @return port
|
||||||
*/
|
*/
|
||||||
@@ -119,7 +128,11 @@ struct traffic_selector_t {
|
|||||||
* Get ending port of this ts.
|
* Get ending port of this ts.
|
||||||
*
|
*
|
||||||
* Port is in host order, since the parser converts it.
|
* Port is in host order, since the parser converts it.
|
||||||
* Size depends on protocol.
|
*
|
||||||
|
* If the protocol is ICMP/ICMPv6 the ICMP type and code are stored in this
|
||||||
|
* field as follows: The message type is placed in the most significant
|
||||||
|
* 8 bits and the code in the least significant 8 bits. Use the utility
|
||||||
|
* functions to extract them.
|
||||||
*
|
*
|
||||||
* @return port
|
* @return port
|
||||||
*/
|
*/
|
||||||
@@ -213,9 +226,36 @@ struct traffic_selector_t {
|
|||||||
void (*destroy) (traffic_selector_t *this);
|
void (*destroy) (traffic_selector_t *this);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract the ICMP/ICMPv6 message type from a port in host order
|
||||||
|
*
|
||||||
|
* @param port port number in host order
|
||||||
|
* @return ICMP/ICMPv6 message type
|
||||||
|
*/
|
||||||
|
static inline u_int8_t traffic_selector_icmp_type(u_int16_t port)
|
||||||
|
{
|
||||||
|
return port >> 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract the ICMP/ICMPv6 message code from a port in host order
|
||||||
|
*
|
||||||
|
* @param port port number in host order
|
||||||
|
* @return ICMP/ICMPv6 message code
|
||||||
|
*/
|
||||||
|
static inline u_int8_t traffic_selector_icmp_code(u_int16_t port)
|
||||||
|
{
|
||||||
|
return port & 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new traffic selector using human readable params.
|
* Create a new traffic selector using human readable params.
|
||||||
*
|
*
|
||||||
|
* If protocol is ICMP or ICMPv6 the ports are interpreted as follows: If they
|
||||||
|
* are less than 256 the value is assumed to be a message type, if they are
|
||||||
|
* greater or equal to 256 they are assumed to be type and code as defined
|
||||||
|
* for traffic_selector_t.
|
||||||
|
*
|
||||||
* @param protocol protocol for this ts, such as TCP or UDP
|
* @param protocol protocol for this ts, such as TCP or UDP
|
||||||
* @param type type of following addresses, such as TS_IPV4_ADDR_RANGE
|
* @param type type of following addresses, such as TS_IPV4_ADDR_RANGE
|
||||||
* @param from_addr start of address range as string
|
* @param from_addr start of address range as string
|
||||||
@@ -236,6 +276,11 @@ traffic_selector_t *traffic_selector_create_from_string(
|
|||||||
/**
|
/**
|
||||||
* Create a traffic selector from a CIDR string.
|
* Create a traffic selector from a CIDR string.
|
||||||
*
|
*
|
||||||
|
* If protocol is ICMP or ICMPv6 the ports are interpreted as follows: If they
|
||||||
|
* are less than 256 the value is assumed to be a message type, if they are
|
||||||
|
* greater or equal to 256 they are assumed to be type and code as defined
|
||||||
|
* for traffic_selector_t.
|
||||||
|
*
|
||||||
* @param string CIDR string, such as 10.1.0.0/16
|
* @param string CIDR string, such as 10.1.0.0/16
|
||||||
* @param protocol protocol for this ts, such as TCP or UDP
|
* @param protocol protocol for this ts, such as TCP or UDP
|
||||||
* @param from_port start of allowed port range
|
* @param from_port start of allowed port range
|
||||||
@@ -253,6 +298,11 @@ traffic_selector_t *traffic_selector_create_from_cidr(
|
|||||||
* But the parser gives us this data in this format, so we
|
* But the parser gives us this data in this format, so we
|
||||||
* don't have to convert twice.
|
* don't have to convert twice.
|
||||||
*
|
*
|
||||||
|
* If protocol is ICMP or ICMPv6 the ports are interpreted as follows: If they
|
||||||
|
* are less than 256 the value is assumed to be a message type, if they are
|
||||||
|
* greater or equal to 256 they are assumed to be type and code as defined
|
||||||
|
* for traffic_selector_t.
|
||||||
|
*
|
||||||
* @param protocol protocol for this ts, such as TCP or UDP
|
* @param protocol protocol for this ts, such as TCP or UDP
|
||||||
* @param type type of following addresses, such as TS_IPV4_ADDR_RANGE
|
* @param type type of following addresses, such as TS_IPV4_ADDR_RANGE
|
||||||
* @param from_address start of address range, network order
|
* @param from_address start of address range, network order
|
||||||
@@ -284,8 +334,12 @@ traffic_selector_t *traffic_selector_create_from_rfc3779_format(ts_type_t type,
|
|||||||
* is sufficient. This constructor creates a traffic selector for
|
* is sufficient. This constructor creates a traffic selector for
|
||||||
* all protocols, all ports and the address range specified by the
|
* all protocols, all ports and the address range specified by the
|
||||||
* subnet.
|
* subnet.
|
||||||
* Additionally, a protocol and a port may be specified. Port ranges
|
* Additionally, a protocol and ports may be specified.
|
||||||
* are not supported via this constructor.
|
*
|
||||||
|
* If protocol is ICMP or ICMPv6 the ports are interpreted as follows: If they
|
||||||
|
* are less than 256 the value is assumed to be a message type, if they are
|
||||||
|
* greater or equal to 256 they are assumed to be type and code as defined
|
||||||
|
* for traffic_selector_t.
|
||||||
*
|
*
|
||||||
* @param net subnet to use
|
* @param net subnet to use
|
||||||
* @param netbits size of the subnet, as used in e.g. 192.168.0.0/24 notation
|
* @param netbits size of the subnet, as used in e.g. 192.168.0.0/24 notation
|
||||||
@@ -307,6 +361,10 @@ traffic_selector_t *traffic_selector_create_from_subnet(
|
|||||||
* created at runtime using the external/virtual IP. Using this constructor,
|
* created at runtime using the external/virtual IP. Using this constructor,
|
||||||
* a call to set_address() sets this traffic selector to the supplied host.
|
* a call to set_address() sets this traffic selector to the supplied host.
|
||||||
*
|
*
|
||||||
|
* If protocol is ICMP or ICMPv6 the ports are interpreted as follows: If they
|
||||||
|
* are less than 256 the value is assumed to be a message type, if they are
|
||||||
|
* greater or equal to 256 they are assumed to be type and code as defined
|
||||||
|
* for traffic_selector_t.
|
||||||
*
|
*
|
||||||
* @param protocol upper layer protocl to allow
|
* @param protocol upper layer protocl to allow
|
||||||
* @param from_port start of allowed port range
|
* @param from_port start of allowed port range
|
||||||
|
|||||||
Reference in New Issue
Block a user