feature: add GTP utils, support overwrite message length of GTP header
This commit is contained in:
@@ -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));
|
||||
|
||||
Reference in New Issue
Block a user