packet parser suppoort skip IPv6 extension headers
This commit is contained in:
@@ -1033,6 +1033,25 @@ static inline const char *parse_ipv4(struct packet *pkt, const char *data, uint1
|
||||
|
||||
static inline const char *parse_ipv6(struct packet *pkt, const char *data, uint16_t len)
|
||||
{
|
||||
/*
|
||||
* IP6 Extension Headers
|
||||
*
|
||||
* Internet Protocol, Version 6 (IPv6) : https://datatracker.ietf.org/doc/html/rfc2460
|
||||
* IP Encapsulating Security Payload (ESP) : https://datatracker.ietf.org/doc/html/rfc2406
|
||||
* IP Authentication Header : https://datatracker.ietf.org/doc/html/rfc4302
|
||||
*
|
||||
* skip next header
|
||||
* #define IPPROTO_HOPOPTS 0 // IP6 hop-by-hop options
|
||||
* #define IPPROTO_ROUTING 43 // IP6 routing header
|
||||
* #define IPPROTO_AH 51 // IP6 Auth Header
|
||||
* #define IPPROTO_DSTOPTS 60 // IP6 destination option
|
||||
*
|
||||
* not skip next header
|
||||
* #define IPPROTO_FRAGMENT 44 // IP6 fragmentation header
|
||||
* #define IPPROTO_ESP 50 // IP6 Encap Sec. Payload
|
||||
* #define IPPROTO_NONE 59 // IP6 no next header
|
||||
*/
|
||||
|
||||
if (unlikely(len < sizeof(struct ip6_hdr)))
|
||||
{
|
||||
PACKET_LOG_DATA_INSUFFICIENCY(LAYER_TYPE_IPV6);
|
||||
@@ -1050,9 +1069,30 @@ static inline const char *parse_ipv6(struct packet *pkt, const char *data, uint1
|
||||
PACKET_LOG_DATA_INSUFFICIENCY(LAYER_TYPE_IPV6);
|
||||
return data;
|
||||
}
|
||||
uint16_t trim_len = len - pld_len - sizeof(struct ip6_hdr);
|
||||
uint8_t next_proto = ipv6_hdr_get_next_header((const struct ip6_hdr *)data);
|
||||
SET_LAYER(pkt, layer, LAYER_TYPE_IPV6, sizeof(struct ip6_hdr), data, len, trim_len);
|
||||
uint16_t hdr_len = sizeof(struct ip6_hdr);
|
||||
uint16_t trim_len = len - pld_len - sizeof(struct ip6_hdr);
|
||||
const char *next_hdr_ptr = data + hdr_len;
|
||||
while (next_proto == IPPROTO_HOPOPTS || next_proto == IPPROTO_ROUTING || next_proto == IPPROTO_AH || next_proto == IPPROTO_DSTOPTS)
|
||||
{
|
||||
if (unlikely(pld_len < 2))
|
||||
{
|
||||
PACKET_LOG_DATA_INSUFFICIENCY(LAYER_TYPE_IPV6);
|
||||
return data;
|
||||
}
|
||||
struct ip6_ext *ext = (struct ip6_ext *)next_hdr_ptr;
|
||||
uint16_t skip_len = ext->ip6e_len * 8 + 8;
|
||||
if (unlikely(skip_len > pld_len))
|
||||
{
|
||||
PACKET_LOG_DATA_INSUFFICIENCY(LAYER_TYPE_IPV6);
|
||||
return data;
|
||||
}
|
||||
hdr_len += skip_len;
|
||||
pld_len -= skip_len;
|
||||
next_hdr_ptr += skip_len;
|
||||
next_proto = ext->ip6e_nxt;
|
||||
}
|
||||
SET_LAYER(pkt, layer, LAYER_TYPE_IPV6, hdr_len, data, len, trim_len);
|
||||
|
||||
// ipv6 fragment
|
||||
if (next_proto == IPPROTO_FRAGMENT)
|
||||
@@ -1062,8 +1102,6 @@ static inline const char *parse_ipv6(struct packet *pkt, const char *data, uint1
|
||||
// try continue parse
|
||||
}
|
||||
|
||||
// TODO parse ipv6 extension headers
|
||||
|
||||
// TESTED
|
||||
return parse_l4(pkt, next_proto, layer->pld_ptr, layer->pld_len);
|
||||
}
|
||||
@@ -1364,8 +1402,8 @@ void packet_print_str(const struct packet *pkt)
|
||||
}
|
||||
|
||||
char buffer[2048] = {0};
|
||||
printf("packet: %p, data_ptr: %p, data_len: %u, layers_used: %u, layers_size: %u\n",
|
||||
pkt, pkt->data_ptr, pkt->data_len,
|
||||
printf("packet: %p, data_ptr: %p, data_len: %u, trim_len: %u, layers_used: %u, layers_size: %u\n",
|
||||
pkt, pkt->data_ptr, pkt->data_len, pkt->trim_len,
|
||||
pkt->layers_used, pkt->layers_size);
|
||||
for (uint8_t i = 0; i < pkt->layers_used; i++)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user