From acb4b60517572094bcd633c7df6fbd90836c4e2d Mon Sep 17 00:00:00 2001 From: Jisu Kim Date: Tue, 19 Sep 2017 14:11:30 +0200 Subject: [PATCH] ipv6 ready: icmp6_param_problem() should send an exact offset to point to the error (see patch #9455) For this, convert 'u8_t nexth' to a pointer and change 'icmp6_param_problem()' to take a pointer, not an offset number Signed-off-by: goldsimon --- src/core/ipv6/icmp6.c | 8 +++++--- src/core/ipv6/ip6.c | 22 +++++++++++----------- src/include/lwip/icmp6.h | 2 +- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/core/ipv6/icmp6.c b/src/core/ipv6/icmp6.c index 08db3817..62be025f 100644 --- a/src/core/ipv6/icmp6.c +++ b/src/core/ipv6/icmp6.c @@ -282,7 +282,8 @@ icmp6_time_exceeded_with_addrs(struct pbuf *p, enum icmp6_te_code c, * Send an icmpv6 'parameter problem' packet. * * This function must be used only in direct response to a packet that is being - * received right now. Otherwise, address zones would be lost. + * received right now. Otherwise, address zones would be lost and the calculated + * offset would be wrong (calculated against ip6_current_header()). * * @param p the input packet for which the 'param problem' should be sent, * p->payload pointing to the IP header @@ -290,9 +291,10 @@ icmp6_time_exceeded_with_addrs(struct pbuf *p, enum icmp6_te_code c, * @param pointer the pointer to the byte where the parameter is found */ void -icmp6_param_problem(struct pbuf *p, enum icmp6_pp_code c, u32_t pointer) +icmp6_param_problem(struct pbuf *p, enum icmp6_pp_code c, const void *pointer) { - icmp6_send_response(p, c, pointer, ICMP6_TYPE_PP); + u32_t pointer_u32 = (u32_t)((const u8_t *)pointer - (const u8_t *)ip6_current_header()); + icmp6_send_response(p, c, pointer_u32, ICMP6_TYPE_PP); } /** diff --git a/src/core/ipv6/ip6.c b/src/core/ipv6/ip6.c index 842503d8..9f509ea5 100644 --- a/src/core/ipv6/ip6.c +++ b/src/core/ipv6/ip6.c @@ -508,7 +508,7 @@ ip6_input(struct pbuf *p, struct netif *inp) { struct ip6_hdr *ip6hdr; struct netif *netif; - u8_t nexth; + const u8_t *nexth; u16_t hlen, hlen_tot; /* the current header length */ #if 0 /*IP_ACCEPT_LINK_LAYER_ADDRESSING*/ @todo @@ -689,7 +689,7 @@ netif_found: ip_data.current_netif = netif; /* Save next header type. */ - nexth = IP6H_NEXTH(ip6hdr); + nexth = &IP6H_NEXTH(ip6hdr); /* Init header length. */ hlen = hlen_tot = IP6_HLEN; @@ -698,9 +698,9 @@ netif_found: pbuf_remove_header(p, IP6_HLEN); /* Process known option extension headers, if present. */ - while (nexth != IP6_NEXTH_NONE) + while (*nexth != IP6_NEXTH_NONE) { - switch (nexth) { + switch (*nexth) { case IP6_NEXTH_HOPBYHOP: LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with Hop-by-Hop options header\n")); /* Get and check the header length, while staying in packet bounds. */ @@ -719,7 +719,7 @@ netif_found: hlen_tot = (u16_t)(hlen_tot + hlen); /* Get next header type. */ - nexth = *((u8_t *)p->payload); + nexth = ((u8_t *)p->payload); /* Skip over this header. */ pbuf_remove_header(p, hlen); @@ -743,7 +743,7 @@ netif_found: hlen_tot = (u16_t)(hlen_tot + hlen); /* Get next header type. */ - nexth = *((u8_t *)p->payload); + nexth = ((u8_t *)p->payload); /* Skip over this header. */ pbuf_remove_header(p, hlen); @@ -765,7 +765,7 @@ netif_found: } /* Get next header type. */ - nexth = *((u8_t *)p->payload); + nexth = ((u8_t *)p->payload); /* Skip over this header. */ hlen_tot = (u16_t)(hlen_tot + hlen); @@ -798,7 +798,7 @@ netif_found: frag_hdr = (struct ip6_frag_hdr *)p->payload; /* Get next header type. */ - nexth = frag_hdr->_nexth; + nexth = &frag_hdr->_nexth; /* Offset == 0 and more_fragments == 0? */ if ((frag_hdr->_fragment_offset & @@ -819,7 +819,7 @@ netif_found: /* Returned p point to IPv6 header. * Update all our variables and pointers and continue. */ ip6hdr = (struct ip6_hdr *)p->payload; - nexth = IP6H_NEXTH(ip6hdr); + nexth = &IP6H_NEXTH(ip6hdr); hlen = hlen_tot = IP6_HLEN; pbuf_remove_header(p, IP6_HLEN); @@ -867,7 +867,7 @@ options_done: #else /* LWIP_RAW */ { #endif /* LWIP_RAW */ - switch (nexth) { + switch (*nexth) { case IP6_NEXTH_NONE: pbuf_free(p); break; @@ -896,7 +896,7 @@ options_done: /* send ICMP parameter problem unless it was a multicast or ICMPv6 */ if ((!ip6_addr_ismulticast(ip6_current_dest_addr())) && (IP6H_NEXTH(ip6hdr) != IP6_NEXTH_ICMP6)) { - icmp6_param_problem(p, ICMP6_PP_HEADER, (u32_t)(hlen_tot - hlen)); + icmp6_param_problem(p, ICMP6_PP_HEADER, nexth); } #endif /* LWIP_ICMP */ LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip6_input: Unsupported transport protocol %"U16_F"\n", (u16_t)IP6H_NEXTH(ip6hdr))); diff --git a/src/include/lwip/icmp6.h b/src/include/lwip/icmp6.h index 374ff448..0ccb7899 100644 --- a/src/include/lwip/icmp6.h +++ b/src/include/lwip/icmp6.h @@ -59,7 +59,7 @@ void icmp6_packet_too_big(struct pbuf *p, u32_t mtu); void icmp6_time_exceeded(struct pbuf *p, enum icmp6_te_code c); void icmp6_time_exceeded_with_addrs(struct pbuf *p, enum icmp6_te_code c, const ip6_addr_t *src_addr, const ip6_addr_t *dest_addr); -void icmp6_param_problem(struct pbuf *p, enum icmp6_pp_code c, u32_t pointer); +void icmp6_param_problem(struct pbuf *p, enum icmp6_pp_code c, const void *pointer); #endif /* LWIP_ICMP6 && LWIP_IPV6 */