From 7b27df1b83855e61452bb7dbe3ae472024e27b1e Mon Sep 17 00:00:00 2001 From: Jisu Kim Date: Tue, 19 Sep 2017 14:08:16 +0200 Subject: [PATCH] ipv6 ready: clean up ipv6 header structs and add more header types & defines (see patch #9455) Signed-off-by: goldsimon --- src/core/ipv6/ip6.c | 35 +++++++--- src/core/ipv6/mld6.c | 4 +- src/include/lwip/prot/ip6.h | 124 ++++++++++++++++++++++++++--------- src/include/lwip/prot/mld6.h | 1 + 4 files changed, 123 insertions(+), 41 deletions(-) diff --git a/src/core/ipv6/ip6.c b/src/core/ipv6/ip6.c index 291b9717..842503d8 100644 --- a/src/core/ipv6/ip6.c +++ b/src/core/ipv6/ip6.c @@ -1201,25 +1201,42 @@ ip6_output_hinted(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest, err_t ip6_options_add_hbh_ra(struct pbuf *p, u8_t nexth, u8_t value) { + u8_t *opt_data; + u32_t offset = 0; struct ip6_hbh_hdr *hbh_hdr; + struct ip6_opt_hdr *opt_hdr; + /* fixed 4 bytes for router alert option and 2 bytes padding */ + const u8_t hlen = (sizeof(struct ip6_opt_hdr) * 2) + IP6_ROUTER_ALERT_DLEN; /* Move pointer to make room for hop-by-hop options header. */ - if (pbuf_add_header(p, sizeof(struct ip6_hbh_hdr))) { + if (pbuf_add_header(p, sizeof(struct ip6_hbh_hdr) + hlen)) { LWIP_DEBUGF(IP6_DEBUG, ("ip6_options: no space for options header\n")); IP6_STATS_INC(ip6.err); return ERR_BUF; } + /* Set fields of Hop-by-Hop header */ hbh_hdr = (struct ip6_hbh_hdr *)p->payload; - - /* Set fields. */ - hbh_hdr->_nexth = nexth; + IP6_HBH_NEXTH(hbh_hdr) = nexth; hbh_hdr->_hlen = 0; - hbh_hdr->_ra_opt_type = IP6_ROUTER_ALERT_OPTION; - hbh_hdr->_ra_opt_dlen = 2; - hbh_hdr->_ra_opt_data = value; - hbh_hdr->_padn_opt_type = IP6_PADN_ALERT_OPTION; - hbh_hdr->_padn_opt_dlen = 0; + offset = IP6_HBH_HLEN; + + /* Set router alert options to Hop-by-Hop extended option header */ + opt_hdr = (struct ip6_opt_hdr *)((u8_t *)hbh_hdr + offset); + IP6_OPT_TYPE(opt_hdr) = IP6_ROUTER_ALERT_OPTION; + IP6_OPT_DLEN(opt_hdr) = IP6_ROUTER_ALERT_DLEN; + offset += IP6_OPT_HLEN; + + /* Set router alert option data */ + opt_data = (u8_t *)hbh_hdr + offset; + opt_data[0] = value; + opt_data[1] = 0; + offset += IP6_OPT_DLEN(opt_hdr); + + /* add 2 bytes padding to make 8 bytes Hop-by-Hop header length */ + opt_hdr = (struct ip6_opt_hdr *)((u8_t *)hbh_hdr + offset); + IP6_OPT_TYPE(opt_hdr) = IP6_PADN_OPTION; + IP6_OPT_DLEN(opt_hdr) = 0; return ERR_OK; } diff --git a/src/core/ipv6/mld6.c b/src/core/ipv6/mld6.c index b5a159b5..64a204d7 100644 --- a/src/core/ipv6/mld6.c +++ b/src/core/ipv6/mld6.c @@ -554,14 +554,14 @@ mld6_send(struct netif *netif, struct mld_group *group, u8_t type) const ip6_addr_t *src_addr; /* Allocate a packet. Size is MLD header + IPv6 Hop-by-hop options header. */ - p = pbuf_alloc(PBUF_IP, sizeof(struct mld_header) + sizeof(struct ip6_hbh_hdr), PBUF_RAM); + p = pbuf_alloc(PBUF_IP, sizeof(struct mld_header) + MLD6_HBH_HLEN, PBUF_RAM); if (p == NULL) { MLD6_STATS_INC(mld6.memerr); return; } /* Move to make room for Hop-by-hop options header. */ - if (pbuf_remove_header(p, IP6_HBH_HLEN)) { + if (pbuf_remove_header(p, MLD6_HBH_HLEN)) { pbuf_free(p); MLD6_STATS_INC(mld6.lenerr); return; diff --git a/src/include/lwip/prot/ip6.h b/src/include/lwip/prot/ip6.h index 6e1e2632..996bcca3 100644 --- a/src/include/lwip/prot/ip6.h +++ b/src/include/lwip/prot/ip6.h @@ -94,13 +94,50 @@ PACK_STRUCT_END #ifdef PACK_STRUCT_USE_INCLUDES # include "arch/epstruct.h" #endif +#define IP6H_V(hdr) ((lwip_ntohl((hdr)->_v_tc_fl) >> 28) & 0x0f) +#define IP6H_TC(hdr) ((lwip_ntohl((hdr)->_v_tc_fl) >> 20) & 0xff) +#define IP6H_FL(hdr) (lwip_ntohl((hdr)->_v_tc_fl) & 0x000fffff) +#define IP6H_PLEN(hdr) (lwip_ntohs((hdr)->_plen)) +#define IP6H_NEXTH(hdr) ((hdr)->_nexth) +#define IP6H_NEXTH_P(hdr) ((u8_t *)(hdr) + 6) +#define IP6H_HOPLIM(hdr) ((hdr)->_hoplim) +#define IP6H_VTCFL_SET(hdr, v, tc, fl) (hdr)->_v_tc_fl = (lwip_htonl((((u32_t)(v)) << 28) | (((u32_t)(tc)) << 20) | (fl))) +#define IP6H_PLEN_SET(hdr, plen) (hdr)->_plen = lwip_htons(plen) +#define IP6H_NEXTH_SET(hdr, nexth) (hdr)->_nexth = (nexth) +#define IP6H_HOPLIM_SET(hdr, hl) (hdr)->_hoplim = (u8_t)(hl) + +/* ipv6 extended options header */ +#define IP6_PAD1_OPTION 0 +#define IP6_PADN_OPTION 1 +#define IP6_ROUTER_ALERT_OPTION 5 +#define IP6_JUMBO_OPTION 194 +#define IP6_HOME_ADDRESS_OPTION 201 +#define IP6_ROUTER_ALERT_DLEN 2 +#define IP6_ROUTER_ALERT_VALUE_MLD 0 + +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct ip6_opt_hdr { + /* router alert option type */ + PACK_STRUCT_FLD_8(u8_t _opt_type); + /* router alert option data len */ + PACK_STRUCT_FLD_8(u8_t _opt_dlen); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif +#define IP6_OPT_HLEN 2 +#define IP6_OPT_TYPE_ACTION(hdr) ((((hdr)->_opt_type) >> 6) & 0x3) +#define IP6_OPT_TYPE_CHANGE(hdr) ((((hdr)->_opt_type) >> 5) & 0x1) +#define IP6_OPT_TYPE(hdr) ((hdr)->_opt_type) +#define IP6_OPT_DLEN(hdr) ((hdr)->_opt_dlen) + +/* Hop-by-Hop header. */ +#define IP6_HBH_HLEN 2 -/* Hop-by-hop router alert option. */ -#define IP6_HBH_HLEN 8 -#define IP6_PAD1_OPTION 0 -#define IP6_PADN_ALERT_OPTION 1 -#define IP6_ROUTER_ALERT_OPTION 5 -#define IP6_ROUTER_ALERT_VALUE_MLD 0 #ifdef PACK_STRUCT_USE_INCLUDES # include "arch/bpstruct.h" #endif @@ -108,28 +145,65 @@ PACK_STRUCT_BEGIN struct ip6_hbh_hdr { /* next header */ PACK_STRUCT_FLD_8(u8_t _nexth); - /* header length */ + /* header length in 8-octet units */ PACK_STRUCT_FLD_8(u8_t _hlen); - /* router alert option type */ - PACK_STRUCT_FLD_8(u8_t _ra_opt_type); - /* router alert option data len */ - PACK_STRUCT_FLD_8(u8_t _ra_opt_dlen); - /* router alert option data */ - PACK_STRUCT_FIELD(u16_t _ra_opt_data); - /* PadN option type */ - PACK_STRUCT_FLD_8(u8_t _padn_opt_type); - /* PadN option data len */ - PACK_STRUCT_FLD_8(u8_t _padn_opt_dlen); } PACK_STRUCT_STRUCT; PACK_STRUCT_END #ifdef PACK_STRUCT_USE_INCLUDES # include "arch/epstruct.h" #endif +#define IP6_HBH_NEXTH(hdr) ((hdr)->_nexth) + +/* Destination header. */ +#define IP6_DEST_HLEN 2 + +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct ip6_dest_hdr { + /* next header */ + PACK_STRUCT_FLD_8(u8_t _nexth); + /* header length in 8-octet units */ + PACK_STRUCT_FLD_8(u8_t _hlen); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif +#define IP6_DEST_NEXTH(hdr) ((hdr)->_nexth) + +/* Routing header */ +#define IP6_ROUT_TYPE2 2 +#define IP6_ROUT_RPL 3 + +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct ip6_rout_hdr { + /* next header */ + PACK_STRUCT_FLD_8(u8_t _nexth); + /* reserved */ + PACK_STRUCT_FLD_8(u8_t _hlen); + /* fragment offset */ + PACK_STRUCT_FIELD(u8_t _routing_type); + /* fragmented packet identification */ + PACK_STRUCT_FIELD(u8_t _segments_left); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif +#define IP6_ROUT_NEXTH(hdr) ((hdr)->_nexth) +#define IP6_ROUT_TYPE(hdr) ((hdr)->_routing_type) +#define IP6_ROUT_SEG_LEFT(hdr) ((hdr)->_segments_left) /* Fragment header. */ #define IP6_FRAG_HLEN 8 #define IP6_FRAG_OFFSET_MASK 0xfff8 #define IP6_FRAG_MORE_FLAG 0x0001 + #ifdef PACK_STRUCT_USE_INCLUDES # include "arch/bpstruct.h" #endif @@ -148,19 +222,9 @@ PACK_STRUCT_END #ifdef PACK_STRUCT_USE_INCLUDES # include "arch/epstruct.h" #endif - -#define IP6H_V(hdr) ((lwip_ntohl((hdr)->_v_tc_fl) >> 28) & 0x0f) -#define IP6H_TC(hdr) ((lwip_ntohl((hdr)->_v_tc_fl) >> 20) & 0xff) -#define IP6H_FL(hdr) (lwip_ntohl((hdr)->_v_tc_fl) & 0x000fffff) -#define IP6H_PLEN(hdr) (lwip_ntohs((hdr)->_plen)) -#define IP6H_NEXTH(hdr) ((hdr)->_nexth) -#define IP6H_NEXTH_P(hdr) ((u8_t *)(hdr) + 6) -#define IP6H_HOPLIM(hdr) ((hdr)->_hoplim) - -#define IP6H_VTCFL_SET(hdr, v, tc, fl) (hdr)->_v_tc_fl = (lwip_htonl((((u32_t)(v)) << 28) | (((u32_t)(tc)) << 20) | (fl))) -#define IP6H_PLEN_SET(hdr, plen) (hdr)->_plen = lwip_htons(plen) -#define IP6H_NEXTH_SET(hdr, nexth) (hdr)->_nexth = (nexth) -#define IP6H_HOPLIM_SET(hdr, hl) (hdr)->_hoplim = (u8_t)(hl) +#define IP6_FRAG_NEXTH(hdr) ((hdr)->_nexth) +#define IP6_FRAG_MBIT(hdr) (lwip_ntohs((hdr)->_fragment_offset) & 0x1) +#define IP6_FRAG_ID(hdr) (lwip_ntohl((hdr)->_identification)) #ifdef __cplusplus } diff --git a/src/include/lwip/prot/mld6.h b/src/include/lwip/prot/mld6.h index be3a006a..71f1dcbd 100644 --- a/src/include/lwip/prot/mld6.h +++ b/src/include/lwip/prot/mld6.h @@ -44,6 +44,7 @@ extern "C" { #endif +#define MLD6_HBH_HLEN 8 /** Multicast listener report/query/done message header. */ #ifdef PACK_STRUCT_USE_INCLUDES # include "arch/bpstruct.h"