aboutsummaryrefslogtreecommitdiffstats
path: root/src/libhydra/plugins/kernel_netlink
diff options
context:
space:
mode:
authorTobias Brunner <tobias@strongswan.org>2015-08-26 17:46:10 +0200
committerTobias Brunner <tobias@strongswan.org>2015-08-31 15:30:57 +0200
commit7b20ab0a9403c9cbeb7009a5cf77d7f3f6d3f5dd (patch)
tree216958702123c81dcffdb5462c6ebf7698cab4db /src/libhydra/plugins/kernel_netlink
parentd34a82dd57f11025f0b39537d414e2eb5fc6ad8b (diff)
downloadstrongswan-7b20ab0a9403c9cbeb7009a5cf77d7f3f6d3f5dd.tar.bz2
strongswan-7b20ab0a9403c9cbeb7009a5cf77d7f3f6d3f5dd.tar.xz
kernel-netlink: Properly set port mask for ICMP type/code if only set on one side
If only one traffic selector had a port (type/code) the other side had the port mask set to 0, which canceled out the applied type/code. It also fixes the installation of ICMP type/code on big-endian hosts. Fixes #1091. References #595.
Diffstat (limited to 'src/libhydra/plugins/kernel_netlink')
-rw-r--r--src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c15
1 files changed, 8 insertions, 7 deletions
diff --git a/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c b/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c
index 8ea2914e0..605476ef1 100644
--- a/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c
+++ b/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c
@@ -735,6 +735,7 @@ static struct xfrm_selector ts2selector(traffic_selector_t *src,
traffic_selector_t *dst)
{
struct xfrm_selector sel;
+ u_int16_t port;
memset(&sel, 0, sizeof(sel));
sel.family = (src->get_type(src) == TS_IPV4_ADDR_RANGE) ? AF_INET : AF_INET6;
@@ -747,13 +748,13 @@ static struct xfrm_selector ts2selector(traffic_selector_t *src,
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);
+ /* the kernel expects the ICMP type and code in the source and
+ * destination port fields, respectively. */
+ port = ntohs(max(sel.dport, sel.sport));
+ sel.sport = htons(traffic_selector_icmp_type(port));
+ sel.sport_mask = sel.sport ? ~0 : 0;
+ sel.dport = htons(traffic_selector_icmp_code(port));
+ sel.dport_mask = sel.dport ? ~0 : 0;
}
sel.ifindex = 0;
sel.user = 0;