diff options
author | Alexander Chernavin <achernavin@netgate.com> | 2020-03-06 06:11:07 -0500 |
---|---|---|
committer | Matthew Smith <mgsmith@netgate.com> | 2020-03-24 14:28:34 +0000 |
commit | 46d0ff3945404f7c95e0e504f98f466e155ab753 (patch) | |
tree | a517e9ed68c3afe0d57db62e717ed6e5f32188c0 /src/vnet | |
parent | 1839fe165c7ffb834775b8582fe0ee2321ff2ab6 (diff) |
map: fix translation of icmp6 error messages
Translation of ICMPv6 error messages to ICMP error messages fails
because the sender port is not set that leads to securtiy check
failure.
With this commit, during ICMPv6 error messages translation, get the
sender port value from the inner packet.
Type: fix
Change-Id: I1ee295a3685fab4837172edfb629a699f49afbee
Signed-off-by: Alexander Chernavin <achernavin@netgate.com>
Diffstat (limited to 'src/vnet')
-rw-r--r-- | src/vnet/ip/ip6_to_ip4.h | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/src/vnet/ip/ip6_to_ip4.h b/src/vnet/ip/ip6_to_ip4.h index 17a11e6df0a..6a533e3b54e 100644 --- a/src/vnet/ip/ip6_to_ip4.h +++ b/src/vnet/ip/ip6_to_ip4.h @@ -170,6 +170,57 @@ ip6_get_port (vlib_main_t * vm, vlib_buffer_t * b, ip6_header_t * ip6, if (dst_port) *dst_port = ((u16 *) (icmp))[2]; } + else if (clib_net_to_host_u16 (ip6->payload_length) >= 64) + { + u16 ip6_pay_len; + ip6_header_t *inner_ip6; + u8 inner_l4_protocol; + u16 inner_l4_offset; + u16 inner_frag_offset; + u8 *inner_l4; + + ip6_pay_len = clib_net_to_host_u16 (ip6->payload_length); + inner_ip6 = (ip6_header_t *) u8_ptr_add (icmp, 8); + + if (ip6_parse (vm, b, inner_ip6, ip6_pay_len - 8, + &inner_l4_protocol, &inner_l4_offset, + &inner_frag_offset)) + return 0; + + if (inner_frag_offset && + ip6_frag_hdr_offset (((ip6_frag_hdr_t *) + u8_ptr_add (inner_ip6, + inner_frag_offset)))) + return 0; + + inner_l4 = u8_ptr_add (inner_ip6, inner_l4_offset); + if (inner_l4_protocol == IP_PROTOCOL_TCP || + inner_l4_protocol == IP_PROTOCOL_UDP) + { + if (src_port) + *src_port = ((udp_header_t *) (inner_l4))->dst_port; + if (dst_port) + *dst_port = ((udp_header_t *) (inner_l4))->src_port; + } + else if (inner_l4_protocol == IP_PROTOCOL_ICMP6) + { + icmp46_header_t *inner_icmp = (icmp46_header_t *) (inner_l4); + if (inner_icmp->type == ICMP6_echo_request) + { + if (src_port) + *src_port = ((u16 *) (inner_icmp))[2]; + if (dst_port) + *dst_port = ((u16 *) (inner_icmp))[2]; + } + else if (inner_icmp->type == ICMP6_echo_reply) + { + if (src_port) + *src_port = ((u16 *) (inner_icmp))[2]; + if (dst_port) + *dst_port = ((u16 *) (inner_icmp))[2]; + } + } + } } return 1; } |