Add support for parsing ICMP and ICMPv6 packets in packet parser

This commit is contained in:
luwenpeng
2024-04-22 16:38:24 +08:00
parent dd32f0f231
commit 8a41a79f06
4 changed files with 332 additions and 8 deletions

View File

@@ -6,6 +6,8 @@
#include <netinet/tcp.h>
#include <netinet/udp.h>
#include <netinet/ether.h>
#include <netinet/icmp6.h>
#include <netinet/ip_icmp.h>
#include <linux/ppp_defs.h>
#include "uthash.h"
@@ -75,6 +77,8 @@ static inline const char *parse_gre(struct packet *pkt, const char *data, uint16
// 传输层
static inline const char *parse_udp(struct packet *pkt, const char *data, uint16_t len);
static inline const char *parse_tcp(struct packet *pkt, const char *data, uint16_t len);
static inline const char *parse_icmp(struct packet *pkt, const char *data, uint16_t len);
static inline const char *parse_icmp6(struct packet *pkt, const char *data, uint16_t len);
// 传输层 -- 隧道
static inline const char *parse_vxlan(struct packet *pkt, const char *data, uint16_t len);
static inline const char *parse_gtpv1_u(struct packet *pkt, const char *data, uint16_t len);
@@ -1009,6 +1013,42 @@ static inline const char *parse_tcp(struct packet *pkt, const char *data, uint16
return layer->pld_ptr;
}
static inline const char *parse_icmp(struct packet *pkt, const char *data, uint16_t len)
{
if (unlikely(len < sizeof(struct icmphdr)))
{
PACKET_LOG_DATA_INSUFFICIENCY(LAYER_TYPE_ICMP);
return data;
}
struct packet_layer *layer = get_free_layer(pkt);
if (unlikely(layer == NULL))
{
return data;
}
SET_LAYER(pkt, layer, LAYER_TYPE_ICMP, sizeof(struct icmphdr), data, len);
return layer->pld_ptr;
}
static inline const char *parse_icmp6(struct packet *pkt, const char *data, uint16_t len)
{
if (unlikely(len < sizeof(struct icmp6_hdr)))
{
PACKET_LOG_DATA_INSUFFICIENCY(LAYER_TYPE_ICMP6);
return data;
}
struct packet_layer *layer = get_free_layer(pkt);
if (unlikely(layer == NULL))
{
return data;
}
SET_LAYER(pkt, layer, LAYER_TYPE_ICMP6, sizeof(struct icmp6_hdr), data, len);
return layer->pld_ptr;
}
static inline const char *parse_vxlan(struct packet *pkt, const char *data, uint16_t len)
{
struct vxlan_hdr
@@ -1113,6 +1153,12 @@ static inline const char *parse_l4(struct packet *pkt, uint8_t next_proto, const
// TESTED
case IPPROTO_GRE:
return parse_gre(pkt, data, len);
// TESTED
case IPPROTO_ICMP:
return parse_icmp(pkt, data, len);
// TESTED
case IPPROTO_ICMPV6:
return parse_icmp6(pkt, data, len);
default:
PACKET_LOG_UNSUPPORT_IPPROTO("l4", next_proto);
return data;
@@ -1216,7 +1262,7 @@ int packet_get_innermost_tuple4(const struct packet *pkt, struct tuple4 *tuple)
layer = &pkt->layers[i];
// first get L4 layer
if (layer->type & LAYER_TYPE_L4)
if (layer->type & (LAYER_TYPE_UDP | LAYER_TYPE_TCP))
{
layer_l4 = layer;
continue;
@@ -1263,7 +1309,7 @@ int packet_get_outermost_tuple4(const struct packet *pkt, struct tuple4 *tuple)
}
// second get L4 layer
if (layer->type & LAYER_TYPE_L4)
if (layer->type & (LAYER_TYPE_UDP | LAYER_TYPE_TCP))
{
layer_l4 = layer;
break;
@@ -1297,7 +1343,7 @@ int packet_get_innermost_tuple6(const struct packet *pkt, struct tuple6 *tuple)
layer = &pkt->layers[i];
// first get L4 layer
if (layer->type & LAYER_TYPE_L4)
if (layer->type & (LAYER_TYPE_UDP | LAYER_TYPE_TCP))
{
layer_l4 = layer;
continue;
@@ -1345,7 +1391,7 @@ int packet_get_outermost_tuple6(const struct packet *pkt, struct tuple6 *tuple)
}
// second get L4 layer
if (layer->type & LAYER_TYPE_L4)
if (layer->type & (LAYER_TYPE_UDP | LAYER_TYPE_TCP))
{
layer_l4 = layer;
break;