diff options
Diffstat (limited to 'src/vnet/ip/ip6_to_ip4.h')
-rw-r--r-- | src/vnet/ip/ip6_to_ip4.h | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/src/vnet/ip/ip6_to_ip4.h b/src/vnet/ip/ip6_to_ip4.h index 29d5718d4da..ebabcd0b797 100644 --- a/src/vnet/ip/ip6_to_ip4.h +++ b/src/vnet/ip/ip6_to_ip4.h @@ -96,10 +96,10 @@ ip6_parse (vlib_main_t *vm, vlib_buffer_t *b, ip6_header_t *ip6, u32 buff_len, * @returns 1 on success, 0 otherwise. */ always_inline u16 -ip6_get_port (vlib_main_t * vm, vlib_buffer_t * b, ip6_header_t * ip6, - u16 buffer_len, u8 * ip_protocol, u16 * src_port, - u16 * dst_port, u8 * icmp_type_or_tcp_flags, - u32 * tcp_ack_number, u32 * tcp_seq_number) +ip6_get_port (vlib_main_t *vm, vlib_buffer_t *b, ip6_header_t *ip6, + u16 buffer_len, u8 *ip_protocol, u16 *src_port, u16 *dst_port, + u8 *icmp_type_or_tcp_flags, u32 *tcp_ack_number, + u32 *tcp_seq_number, void **l4_hdr) { u8 l4_protocol; u16 l4_offset; @@ -120,8 +120,19 @@ ip6_get_port (vlib_main_t * vm, vlib_buffer_t * b, ip6_header_t * ip6, *ip_protocol = l4_protocol; } l4 = u8_ptr_add (ip6, l4_offset); + if (l4_hdr) + *l4_hdr = l4; if (l4_protocol == IP_PROTOCOL_TCP || l4_protocol == IP_PROTOCOL_UDP) { + if ((IP_PROTOCOL_UDP == l4_protocol && + u8_ptr_add (l4, sizeof (udp_header_t)) > + u8_ptr_add (vlib_buffer_get_current (b), b->current_length)) || + (IP_PROTOCOL_TCP == l4_protocol && + u8_ptr_add (l4, sizeof (tcp_header_t)) > + u8_ptr_add (vlib_buffer_get_current (b), b->current_length))) + { + return 0; + } if (src_port) *src_port = ((udp_header_t *) (l4))->src_port; if (dst_port) @@ -135,6 +146,11 @@ ip6_get_port (vlib_main_t * vm, vlib_buffer_t * b, ip6_header_t * ip6, } else if (l4_protocol == IP_PROTOCOL_ICMP6) { + if (u8_ptr_add (l4, sizeof (icmp46_header_t)) > + u8_ptr_add (vlib_buffer_get_current (b), b->current_length)) + { + return 0; + } icmp46_header_t *icmp = (icmp46_header_t *) (l4); if (icmp_type_or_tcp_flags) *icmp_type_or_tcp_flags = ((icmp46_header_t *) (l4))->type; |