feature: add GTP utils, support overwrite message length of GTP header

This commit is contained in:
luwenpeng
2024-07-09 11:17:03 +08:00
parent b435ec2ea1
commit c87ad330e0
28 changed files with 1676 additions and 648 deletions

View File

@@ -4,13 +4,13 @@
#include <assert.h>
#include "log.h"
#include "checksum.h"
#include "ip4_utils.h"
#include "ip6_utils.h"
#include "crc32_hash.h"
#include "packet_def.h"
#include "packet_utils.h"
#include "packet_parse.h"
#include "crc32_hash.h"
#include "checksum.h"
#include "ipv4_utils.h"
#include "ipv6_utils.h"
#include "ip_reassembly.h"
#define IP_REASSEMBLE_DEBUG(format, ...) LOG_DEBUG("ip_reassembly", format, ##__VA_ARGS__)
@@ -310,12 +310,12 @@ static inline void ip_frag_hdr_init(struct ip_frag_hdr *hdr, const struct packet
if (layer->proto == LAYER_PROTO_IPV6)
{
struct ip6_frag *frag_ext = ipv6_hdr_get_frag_ext((const struct ip6_hdr *)layer->hdr_ptr);
struct ip6_frag *frag_ext = ip6_hdr_get_frag_ext((const struct ip6_hdr *)layer->hdr_ptr);
hdr->next_proto = frag_ext->ip6f_nxt;
}
else
{
hdr->next_proto = ipv4_hdr_get_proto((const struct ip *)layer->hdr_ptr);
hdr->next_proto = ip4_hdr_get_proto((const struct ip *)layer->hdr_ptr);
}
hdr->l3_offset = layer->hdr_offset;
@@ -719,18 +719,18 @@ static struct packet *ip_frag_reassemble(struct ip_reassembly *assy, struct ip_f
{
// update ip total length & ip checksum
ip4_hdr = (struct ip *)(ptr + flow->hdr.l3_offset);
ipv4_hdr_set_total_len(ip4_hdr, packet_len - flow->hdr.l3_offset); // update total length
ipv4_hdr_set_mf_flag(ip4_hdr, false); // update more fragment flag
ipv4_hdr_set_frag_offset(ip4_hdr, 0); // update fragment offset
ip4_hdr->ip_sum = 0; // update checksum
ip4_hdr_set_total_len(ip4_hdr, packet_len - flow->hdr.l3_offset); // update total length
ip4_hdr_set_mf_flag(ip4_hdr, false); // update more fragment flag
ip4_hdr_set_frag_offset(ip4_hdr, 0); // update fragment offset
ip4_hdr->ip_sum = 0; // update checksum
ip4_hdr->ip_sum = checksum((const char *)ip4_hdr, flow->hdr.l3_len);
}
else
{
// update ipv6 payload length & next header
ip6_hdr = (struct ip6_hdr *)(ptr + flow->hdr.l3_offset);
ipv6_hdr_set_payload_len(ip6_hdr, flow->expected_total_size); // update payload length
ipv6_hdr_set_next_header(ip6_hdr, flow->hdr.next_proto); // update next header
ip6_hdr_set_payload_len(ip6_hdr, flow->expected_total_size); // update payload length
ip6_hdr_set_next_header(ip6_hdr, flow->hdr.next_proto); // update next header
}
// create a new packet
@@ -904,10 +904,10 @@ struct packet *ipv4_reassembly_packet(struct ip_reassembly *assy, const struct p
{
const struct raw_layer *layer = pkt->frag_layer;
const struct ip *hdr = (const struct ip *)layer->hdr_ptr;
uint16_t frag_len = ipv4_hdr_get_total_len(hdr) - ipv4_hdr_get_hdr_len(hdr);
uint16_t frag_len = ip4_hdr_get_total_len(hdr) - ip4_hdr_get_hdr_len(hdr);
if (frag_len > layer->pld_len)
{
IP_REASSEMBLE_ERROR("unexpected header length, ip id: %lu", ipv4_hdr_get_ipid(hdr));
IP_REASSEMBLE_ERROR("unexpected header length, ip id: %lu", ip4_hdr_get_ipid(hdr));
return NULL;
}
@@ -916,8 +916,8 @@ struct packet *ipv4_reassembly_packet(struct ip_reassembly *assy, const struct p
uint64_t dst_addr = hdr->ip_dst.s_addr;
key.src_dst_addr[0] = src_addr << 32 | dst_addr;
key.src_dst_len = IPV4_KEYLEN;
key.ip_id = ipv4_hdr_get_ipid(hdr);
key.proto = ipv4_hdr_get_proto(hdr);
key.ip_id = ip4_hdr_get_ipid(hdr);
key.proto = ip4_hdr_get_proto(hdr);
struct ip_flow *flow = ip_reassembly_update_flow(assy, &key, now);
if (flow == NULL)
@@ -926,8 +926,8 @@ struct packet *ipv4_reassembly_packet(struct ip_reassembly *assy, const struct p
}
char *frag_data = (char *)layer->pld_ptr;
bool more_frags = ipv4_hdr_get_mf_flag(hdr);
uint16_t frag_offset = ipv4_hdr_get_frag_offset(hdr);
bool more_frags = ip4_hdr_get_mf_flag(hdr);
uint16_t frag_offset = ip4_hdr_get_frag_offset(hdr);
if (ip_flow_update(assy, flow, pkt, frag_data, frag_len, frag_offset, more_frags) != 0)
{
ip_reassembly_del_flow(assy, flow);
@@ -990,14 +990,14 @@ struct packet *ipv6_reassembly_packet(struct ip_reassembly *assy, const struct p
{
const struct raw_layer *layer = pkt->frag_layer;
const struct ip6_hdr *hdr = (const struct ip6_hdr *)layer->hdr_ptr;
const struct ip6_frag *frag_hdr = ipv6_hdr_get_frag_ext(hdr);
const struct ip6_frag *frag_hdr = ip6_hdr_get_frag_ext(hdr);
if (frag_hdr == NULL)
{
return NULL;
}
char *frag_data = (char *)frag_hdr + sizeof(struct ip6_frag);
uint16_t frag_len = ipv6_hdr_get_payload_len(hdr) - sizeof(struct ip6_frag);
uint16_t frag_len = ip6_hdr_get_payload_len(hdr) - sizeof(struct ip6_frag);
if (frag_data + frag_len > pkt->data_ptr + pkt->data_len)
{
IP_REASSEMBLE_ERROR("unexpected header length, frag id: %lu", ipv6_frag_get_ident(frag_hdr));