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

@@ -46,7 +46,8 @@ enum layer_proto
// L4 -- tunnel
LAYER_PROTO_VXLAN = 61,
LAYER_PROTO_GTP = 62,
LAYER_PROTO_GTP_U = 62,
LAYER_PROTO_GTP_C = 63,
};
struct layer

View File

@@ -3,7 +3,7 @@
#include "dablooms.h"
#include "tcp_utils.h"
#include "udp_utils.h"
#include "ipv4_utils.h"
#include "ip4_utils.h"
#include "packet_def.h"
#include "packet_layer.h"
#include "duplicated_packet_filter.h"
@@ -47,9 +47,9 @@ static inline int duplicated_packet_key_get(const struct packet *packet, struct
memset(key, 0, sizeof(struct duplicated_packet_key));
const struct ip *iphdr = (const struct ip *)ip_layer->hdr_ptr;
key->ip_id = ipv4_hdr_get_ipid(iphdr);
key->src_addr = ipv4_hdr_get_src_addr(iphdr);
key->dst_addr = ipv4_hdr_get_dst_addr(iphdr);
key->ip_id = ip4_hdr_get_ipid(iphdr);
key->src_addr = ip4_hdr_get_src_addr(iphdr);
key->dst_addr = ip4_hdr_get_dst_addr(iphdr);
if (tcp_layer)
{

View File

@@ -3,8 +3,8 @@
#include "tuple.h"
#include "dablooms.h"
#include "udp_utils.h"
#include "ipv4_utils.h"
#include "ipv6_utils.h"
#include "ip4_utils.h"
#include "ip6_utils.h"
#include "evicted_session_filter.h"
struct evicted_session_filter

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));

View File

@@ -248,20 +248,20 @@ TEST(IPV4_REASSEMBLE, PADDING_ORDER)
layer = packet_get_innermost_raw_layer(new_pkt, LAYER_PROTO_IPV4);
EXPECT_TRUE(layer);
struct ip *hdr = (struct ip *)layer->hdr_ptr;
EXPECT_TRUE(ipv4_hdr_get_version(hdr) == 4);
EXPECT_TRUE(ipv4_hdr_get_hdr_len(hdr) == 20 /* IPv4 */);
EXPECT_TRUE(ipv4_hdr_get_tos(hdr) == 0);
EXPECT_TRUE(ipv4_hdr_get_total_len(hdr) == 20 /* IPv4 */ + 20 /* TCP */ + 28 /* DATA */);
EXPECT_TRUE(ipv4_hdr_get_ipid(hdr) == 0xffff);
EXPECT_TRUE(ipv4_hdr_get_flags(hdr) == 0x0);
EXPECT_TRUE(ipv4_hdr_get_frag_offset(hdr) == 0);
EXPECT_TRUE(ipv4_hdr_get_ttl(hdr) == 127);
EXPECT_TRUE(ipv4_hdr_get_proto(hdr) == 6);
EXPECT_TRUE(ipv4_hdr_get_checksum(hdr) == 0x6d73); // NOTE this is correct checksum
EXPECT_TRUE(ipv4_hdr_get_src_addr(hdr) == 0xc0a82467);
EXPECT_TRUE(ipv4_hdr_get_dst_addr(hdr) == 0xc0a82889);
EXPECT_TRUE(ipv4_hdr_get_opt_len(hdr) == 0);
EXPECT_TRUE(ipv4_hdr_get_opt_data(hdr) == NULL);
EXPECT_TRUE(ip4_hdr_get_version(hdr) == 4);
EXPECT_TRUE(ip4_hdr_get_hdr_len(hdr) == 20 /* IPv4 */);
EXPECT_TRUE(ip4_hdr_get_tos(hdr) == 0);
EXPECT_TRUE(ip4_hdr_get_total_len(hdr) == 20 /* IPv4 */ + 20 /* TCP */ + 28 /* DATA */);
EXPECT_TRUE(ip4_hdr_get_ipid(hdr) == 0xffff);
EXPECT_TRUE(ip4_hdr_get_flags(hdr) == 0x0);
EXPECT_TRUE(ip4_hdr_get_frag_offset(hdr) == 0);
EXPECT_TRUE(ip4_hdr_get_ttl(hdr) == 127);
EXPECT_TRUE(ip4_hdr_get_proto(hdr) == 6);
EXPECT_TRUE(ip4_hdr_get_checksum(hdr) == 0x6d73); // NOTE this is correct checksum
EXPECT_TRUE(ip4_hdr_get_src_addr(hdr) == 0xc0a82467);
EXPECT_TRUE(ip4_hdr_get_dst_addr(hdr) == 0xc0a82889);
EXPECT_TRUE(ip4_hdr_get_opt_len(hdr) == 0);
EXPECT_TRUE(ip4_hdr_get_opt_data(hdr) == NULL);
// check TCP
layer = packet_get_innermost_raw_layer(new_pkt, LAYER_PROTO_TCP);
@@ -343,20 +343,20 @@ TEST(IPV4_REASSEMBLE, PADDING_UNORDER)
layer = packet_get_innermost_raw_layer(new_pkt, LAYER_PROTO_IPV4);
EXPECT_TRUE(layer);
struct ip *hdr = (struct ip *)layer->hdr_ptr;
EXPECT_TRUE(ipv4_hdr_get_version(hdr) == 4);
EXPECT_TRUE(ipv4_hdr_get_hdr_len(hdr) == 20 /* IPv4 */);
EXPECT_TRUE(ipv4_hdr_get_tos(hdr) == 0);
EXPECT_TRUE(ipv4_hdr_get_total_len(hdr) == 20 /* IPv4 */ + 20 /* TCP */ + 28 /* DATA */);
EXPECT_TRUE(ipv4_hdr_get_ipid(hdr) == 0xffff);
EXPECT_TRUE(ipv4_hdr_get_flags(hdr) == 0x0);
EXPECT_TRUE(ipv4_hdr_get_frag_offset(hdr) == 0);
EXPECT_TRUE(ipv4_hdr_get_ttl(hdr) == 127);
EXPECT_TRUE(ipv4_hdr_get_proto(hdr) == 6);
EXPECT_TRUE(ipv4_hdr_get_checksum(hdr) == 0x6d73); // NOTE this is correct checksum
EXPECT_TRUE(ipv4_hdr_get_src_addr(hdr) == 0xc0a82467);
EXPECT_TRUE(ipv4_hdr_get_dst_addr(hdr) == 0xc0a82889);
EXPECT_TRUE(ipv4_hdr_get_opt_len(hdr) == 0);
EXPECT_TRUE(ipv4_hdr_get_opt_data(hdr) == NULL);
EXPECT_TRUE(ip4_hdr_get_version(hdr) == 4);
EXPECT_TRUE(ip4_hdr_get_hdr_len(hdr) == 20 /* IPv4 */);
EXPECT_TRUE(ip4_hdr_get_tos(hdr) == 0);
EXPECT_TRUE(ip4_hdr_get_total_len(hdr) == 20 /* IPv4 */ + 20 /* TCP */ + 28 /* DATA */);
EXPECT_TRUE(ip4_hdr_get_ipid(hdr) == 0xffff);
EXPECT_TRUE(ip4_hdr_get_flags(hdr) == 0x0);
EXPECT_TRUE(ip4_hdr_get_frag_offset(hdr) == 0);
EXPECT_TRUE(ip4_hdr_get_ttl(hdr) == 127);
EXPECT_TRUE(ip4_hdr_get_proto(hdr) == 6);
EXPECT_TRUE(ip4_hdr_get_checksum(hdr) == 0x6d73); // NOTE this is correct checksum
EXPECT_TRUE(ip4_hdr_get_src_addr(hdr) == 0xc0a82467);
EXPECT_TRUE(ip4_hdr_get_dst_addr(hdr) == 0xc0a82889);
EXPECT_TRUE(ip4_hdr_get_opt_len(hdr) == 0);
EXPECT_TRUE(ip4_hdr_get_opt_data(hdr) == NULL);
// check TCP
layer = packet_get_innermost_raw_layer(new_pkt, LAYER_PROTO_TCP);
@@ -503,20 +503,20 @@ TEST(IPV4_REASSEMBLE, DUP_FIRST_FRAG)
layer = packet_get_innermost_raw_layer(new_pkt, LAYER_PROTO_IPV4);
EXPECT_TRUE(layer);
struct ip *hdr = (struct ip *)layer->hdr_ptr;
EXPECT_TRUE(ipv4_hdr_get_version(hdr) == 4);
EXPECT_TRUE(ipv4_hdr_get_hdr_len(hdr) == 20 /* IPv4 */);
EXPECT_TRUE(ipv4_hdr_get_tos(hdr) == 0);
EXPECT_TRUE(ipv4_hdr_get_total_len(hdr) == 20 /* IPv4 */ + 20 /* TCP */ + 28 /* DATA */);
EXPECT_TRUE(ipv4_hdr_get_ipid(hdr) == 0xffff);
EXPECT_TRUE(ipv4_hdr_get_flags(hdr) == 0x0);
EXPECT_TRUE(ipv4_hdr_get_frag_offset(hdr) == 0);
EXPECT_TRUE(ipv4_hdr_get_ttl(hdr) == 127);
EXPECT_TRUE(ipv4_hdr_get_proto(hdr) == 6);
EXPECT_TRUE(ipv4_hdr_get_checksum(hdr) == 0x6d73); // NOTE this is correct checksum
EXPECT_TRUE(ipv4_hdr_get_src_addr(hdr) == 0xc0a82467);
EXPECT_TRUE(ipv4_hdr_get_dst_addr(hdr) == 0xc0a82889);
EXPECT_TRUE(ipv4_hdr_get_opt_len(hdr) == 0);
EXPECT_TRUE(ipv4_hdr_get_opt_data(hdr) == NULL);
EXPECT_TRUE(ip4_hdr_get_version(hdr) == 4);
EXPECT_TRUE(ip4_hdr_get_hdr_len(hdr) == 20 /* IPv4 */);
EXPECT_TRUE(ip4_hdr_get_tos(hdr) == 0);
EXPECT_TRUE(ip4_hdr_get_total_len(hdr) == 20 /* IPv4 */ + 20 /* TCP */ + 28 /* DATA */);
EXPECT_TRUE(ip4_hdr_get_ipid(hdr) == 0xffff);
EXPECT_TRUE(ip4_hdr_get_flags(hdr) == 0x0);
EXPECT_TRUE(ip4_hdr_get_frag_offset(hdr) == 0);
EXPECT_TRUE(ip4_hdr_get_ttl(hdr) == 127);
EXPECT_TRUE(ip4_hdr_get_proto(hdr) == 6);
EXPECT_TRUE(ip4_hdr_get_checksum(hdr) == 0x6d73); // NOTE this is correct checksum
EXPECT_TRUE(ip4_hdr_get_src_addr(hdr) == 0xc0a82467);
EXPECT_TRUE(ip4_hdr_get_dst_addr(hdr) == 0xc0a82889);
EXPECT_TRUE(ip4_hdr_get_opt_len(hdr) == 0);
EXPECT_TRUE(ip4_hdr_get_opt_data(hdr) == NULL);
// check TCP
layer = packet_get_innermost_raw_layer(new_pkt, LAYER_PROTO_TCP);
@@ -610,20 +610,20 @@ TEST(IPV4_REASSEMBLE, DUP_LAST_FRAG)
layer = packet_get_innermost_raw_layer(new_pkt, LAYER_PROTO_IPV4);
EXPECT_TRUE(layer);
struct ip *hdr = (struct ip *)layer->hdr_ptr;
EXPECT_TRUE(ipv4_hdr_get_version(hdr) == 4);
EXPECT_TRUE(ipv4_hdr_get_hdr_len(hdr) == 20 /* IPv4 */);
EXPECT_TRUE(ipv4_hdr_get_tos(hdr) == 0);
EXPECT_TRUE(ipv4_hdr_get_total_len(hdr) == 20 /* IPv4 */ + 20 /* TCP */ + 28 /* DATA */);
EXPECT_TRUE(ipv4_hdr_get_ipid(hdr) == 0xffff);
EXPECT_TRUE(ipv4_hdr_get_flags(hdr) == 0x0);
EXPECT_TRUE(ipv4_hdr_get_frag_offset(hdr) == 0);
EXPECT_TRUE(ipv4_hdr_get_ttl(hdr) == 127);
EXPECT_TRUE(ipv4_hdr_get_proto(hdr) == 6);
EXPECT_TRUE(ipv4_hdr_get_checksum(hdr) == 0x6d73); // NOTE this is correct checksum
EXPECT_TRUE(ipv4_hdr_get_src_addr(hdr) == 0xc0a82467);
EXPECT_TRUE(ipv4_hdr_get_dst_addr(hdr) == 0xc0a82889);
EXPECT_TRUE(ipv4_hdr_get_opt_len(hdr) == 0);
EXPECT_TRUE(ipv4_hdr_get_opt_data(hdr) == NULL);
EXPECT_TRUE(ip4_hdr_get_version(hdr) == 4);
EXPECT_TRUE(ip4_hdr_get_hdr_len(hdr) == 20 /* IPv4 */);
EXPECT_TRUE(ip4_hdr_get_tos(hdr) == 0);
EXPECT_TRUE(ip4_hdr_get_total_len(hdr) == 20 /* IPv4 */ + 20 /* TCP */ + 28 /* DATA */);
EXPECT_TRUE(ip4_hdr_get_ipid(hdr) == 0xffff);
EXPECT_TRUE(ip4_hdr_get_flags(hdr) == 0x0);
EXPECT_TRUE(ip4_hdr_get_frag_offset(hdr) == 0);
EXPECT_TRUE(ip4_hdr_get_ttl(hdr) == 127);
EXPECT_TRUE(ip4_hdr_get_proto(hdr) == 6);
EXPECT_TRUE(ip4_hdr_get_checksum(hdr) == 0x6d73); // NOTE this is correct checksum
EXPECT_TRUE(ip4_hdr_get_src_addr(hdr) == 0xc0a82467);
EXPECT_TRUE(ip4_hdr_get_dst_addr(hdr) == 0xc0a82889);
EXPECT_TRUE(ip4_hdr_get_opt_len(hdr) == 0);
EXPECT_TRUE(ip4_hdr_get_opt_data(hdr) == NULL);
// check TCP
layer = packet_get_innermost_raw_layer(new_pkt, LAYER_PROTO_TCP);

View File

@@ -683,21 +683,21 @@ TEST(IPV6_REASSEMBLE, NORMAL)
layer = packet_get_innermost_raw_layer(new_pkt, LAYER_PROTO_IPV6);
EXPECT_TRUE(layer);
struct ip6_hdr *hdr = (struct ip6_hdr *)layer->hdr_ptr;
EXPECT_TRUE(ipv6_hdr_get_version(hdr) == 6);
EXPECT_TRUE(ipv6_hdr_get_traffic_class(hdr) == 0);
EXPECT_TRUE(ipv6_hdr_get_flow_label(hdr) == 0x21289);
EXPECT_TRUE(ipv6_hdr_get_payload_len(hdr) == 5387);
EXPECT_TRUE(ipv6_hdr_get_next_header(hdr) == 17); // UDP
EXPECT_TRUE(ipv6_hdr_get_hop_limit(hdr) == 64);
EXPECT_TRUE(ip6_hdr_get_version(hdr) == 6);
EXPECT_TRUE(ip6_hdr_get_traffic_class(hdr) == 0);
EXPECT_TRUE(ip6_hdr_get_flow_label(hdr) == 0x21289);
EXPECT_TRUE(ip6_hdr_get_payload_len(hdr) == 5387);
EXPECT_TRUE(ip6_hdr_get_next_header(hdr) == 17); // UDP
EXPECT_TRUE(ip6_hdr_get_hop_limit(hdr) == 64);
char src_str[INET6_ADDRSTRLEN];
char dst_str[INET6_ADDRSTRLEN];
struct in6_addr src_addr = ipv6_hdr_get_src_in6_addr(hdr);
struct in6_addr dst_addr = ipv6_hdr_get_dst_in6_addr(hdr);
struct in6_addr src_addr = ip6_hdr_get_src_in6_addr(hdr);
struct in6_addr dst_addr = ip6_hdr_get_dst_in6_addr(hdr);
inet_ntop(AF_INET6, &src_addr, src_str, INET6_ADDRSTRLEN);
inet_ntop(AF_INET6, &dst_addr, dst_str, INET6_ADDRSTRLEN);
EXPECT_TRUE(strcmp(src_str, "2607:f010:3f9::1001") == 0);
EXPECT_TRUE(strcmp(dst_str, "2607:f010:3f9::11:0") == 0);
EXPECT_TRUE(ipv6_hdr_get_frag_ext(hdr) == NULL);
EXPECT_TRUE(ip6_hdr_get_frag_ext(hdr) == NULL);
// check UDP
layer = packet_get_innermost_raw_layer(new_pkt, LAYER_PROTO_UDP);
@@ -861,21 +861,21 @@ TEST(IPV6_REASSEMBLE, DUP_FIRST_FRAG)
layer = packet_get_innermost_raw_layer(new_pkt, LAYER_PROTO_IPV6);
EXPECT_TRUE(layer);
struct ip6_hdr *hdr = (struct ip6_hdr *)layer->hdr_ptr;
EXPECT_TRUE(ipv6_hdr_get_version(hdr) == 6);
EXPECT_TRUE(ipv6_hdr_get_traffic_class(hdr) == 0);
EXPECT_TRUE(ipv6_hdr_get_flow_label(hdr) == 0x21289);
EXPECT_TRUE(ipv6_hdr_get_payload_len(hdr) == 5387);
EXPECT_TRUE(ipv6_hdr_get_next_header(hdr) == 17); // UDP
EXPECT_TRUE(ipv6_hdr_get_hop_limit(hdr) == 64);
EXPECT_TRUE(ip6_hdr_get_version(hdr) == 6);
EXPECT_TRUE(ip6_hdr_get_traffic_class(hdr) == 0);
EXPECT_TRUE(ip6_hdr_get_flow_label(hdr) == 0x21289);
EXPECT_TRUE(ip6_hdr_get_payload_len(hdr) == 5387);
EXPECT_TRUE(ip6_hdr_get_next_header(hdr) == 17); // UDP
EXPECT_TRUE(ip6_hdr_get_hop_limit(hdr) == 64);
char src_str[INET6_ADDRSTRLEN];
char dst_str[INET6_ADDRSTRLEN];
struct in6_addr src_addr = ipv6_hdr_get_src_in6_addr(hdr);
struct in6_addr dst_addr = ipv6_hdr_get_dst_in6_addr(hdr);
struct in6_addr src_addr = ip6_hdr_get_src_in6_addr(hdr);
struct in6_addr dst_addr = ip6_hdr_get_dst_in6_addr(hdr);
inet_ntop(AF_INET6, &src_addr, src_str, INET6_ADDRSTRLEN);
inet_ntop(AF_INET6, &dst_addr, dst_str, INET6_ADDRSTRLEN);
EXPECT_TRUE(strcmp(src_str, "2607:f010:3f9::1001") == 0);
EXPECT_TRUE(strcmp(dst_str, "2607:f010:3f9::11:0") == 0);
EXPECT_TRUE(ipv6_hdr_get_frag_ext(hdr) == NULL);
EXPECT_TRUE(ip6_hdr_get_frag_ext(hdr) == NULL);
// check UDP
layer = packet_get_innermost_raw_layer(new_pkt, LAYER_PROTO_UDP);
@@ -986,21 +986,21 @@ TEST(IPV6_REASSEMBLE, DUP_LAST_FRAG)
layer = packet_get_innermost_raw_layer(new_pkt, LAYER_PROTO_IPV6);
EXPECT_TRUE(layer);
struct ip6_hdr *hdr = (struct ip6_hdr *)layer->hdr_ptr;
EXPECT_TRUE(ipv6_hdr_get_version(hdr) == 6);
EXPECT_TRUE(ipv6_hdr_get_traffic_class(hdr) == 0);
EXPECT_TRUE(ipv6_hdr_get_flow_label(hdr) == 0x21289);
EXPECT_TRUE(ipv6_hdr_get_payload_len(hdr) == 5387);
EXPECT_TRUE(ipv6_hdr_get_next_header(hdr) == 17); // UDP
EXPECT_TRUE(ipv6_hdr_get_hop_limit(hdr) == 64);
EXPECT_TRUE(ip6_hdr_get_version(hdr) == 6);
EXPECT_TRUE(ip6_hdr_get_traffic_class(hdr) == 0);
EXPECT_TRUE(ip6_hdr_get_flow_label(hdr) == 0x21289);
EXPECT_TRUE(ip6_hdr_get_payload_len(hdr) == 5387);
EXPECT_TRUE(ip6_hdr_get_next_header(hdr) == 17); // UDP
EXPECT_TRUE(ip6_hdr_get_hop_limit(hdr) == 64);
char src_str[INET6_ADDRSTRLEN];
char dst_str[INET6_ADDRSTRLEN];
struct in6_addr src_addr = ipv6_hdr_get_src_in6_addr(hdr);
struct in6_addr dst_addr = ipv6_hdr_get_dst_in6_addr(hdr);
struct in6_addr src_addr = ip6_hdr_get_src_in6_addr(hdr);
struct in6_addr dst_addr = ip6_hdr_get_dst_in6_addr(hdr);
inet_ntop(AF_INET6, &src_addr, src_str, INET6_ADDRSTRLEN);
inet_ntop(AF_INET6, &dst_addr, dst_str, INET6_ADDRSTRLEN);
EXPECT_TRUE(strcmp(src_str, "2607:f010:3f9::1001") == 0);
EXPECT_TRUE(strcmp(dst_str, "2607:f010:3f9::11:0") == 0);
EXPECT_TRUE(ipv6_hdr_get_frag_ext(hdr) == NULL);
EXPECT_TRUE(ip6_hdr_get_frag_ext(hdr) == NULL);
// check UDP
layer = packet_get_innermost_raw_layer(new_pkt, LAYER_PROTO_UDP);

View File

@@ -9,8 +9,8 @@ extern "C"
#include "udp_utils.h"
#include "tcp_utils.h"
#include "ipv4_utils.h"
#include "ipv6_utils.h"
#include "ip4_utils.h"
#include "ip6_utils.h"
#include "ip_reassembly.h"
#include "packet_def.h"
#include "packet_utils.h"
@@ -22,7 +22,7 @@ static inline void packet_set_ipv4_src_addr(struct packet *pkt, uint32_t saddr)
const struct raw_layer *ipv4_layer = packet_get_innermost_raw_layer(pkt, LAYER_PROTO_IPV4);
EXPECT_TRUE(ipv4_layer);
struct ip *hdr = (struct ip *)ipv4_layer->hdr_ptr;
ipv4_hdr_set_src_addr(hdr, saddr);
ip4_hdr_set_src_addr(hdr, saddr);
}
static inline void packet_set_ipv6_src_addr(struct packet *pkt, struct in6_addr saddr)
@@ -30,7 +30,7 @@ static inline void packet_set_ipv6_src_addr(struct packet *pkt, struct in6_addr
const struct raw_layer *ipv6_layer = packet_get_innermost_raw_layer(pkt, LAYER_PROTO_IPV6);
EXPECT_TRUE(ipv6_layer);
struct ip6_hdr *hdr = (struct ip6_hdr *)ipv6_layer->hdr_ptr;
ipv6_hdr_set_src_in6_addr(hdr, saddr);
ip6_hdr_set_src_in6_addr(hdr, saddr);
}
static inline void packet_set_ipv6_frag_offset(struct packet *pkt, uint16_t offset)
@@ -38,7 +38,7 @@ static inline void packet_set_ipv6_frag_offset(struct packet *pkt, uint16_t offs
const struct raw_layer *ipv6_layer = packet_get_innermost_raw_layer(pkt, LAYER_PROTO_IPV6);
EXPECT_TRUE(ipv6_layer);
struct ip6_hdr *hdr = (struct ip6_hdr *)ipv6_layer->hdr_ptr;
struct ip6_frag *frag_hdr = ipv6_hdr_get_frag_ext(hdr);
struct ip6_frag *frag_hdr = ip6_hdr_get_frag_ext(hdr);
EXPECT_TRUE(frag_hdr);
ipv6_frag_set_offset(frag_hdr, offset);
}

354
src/packet/gtp1_utils.h Normal file
View File

@@ -0,0 +1,354 @@
#pragma once
#ifdef __cplusplus
extern "C"
{
#endif
#include <stdio.h>
#include <string.h>
#include <arpa/inet.h>
/*
* https://en.wikipedia.org/wiki/GPRS_Tunnelling_Protocol
*
* GTP-C: Gateway GPRS Support Nodes (GGSN) <----> Serving GPRS support Nodes (SGSN)
* GTP-U: Radio Access Network <----> Core Network
*
* GTPv1:
* -> GTPv1-C
* -> GTPv1-U
*/
/*
* GTP version 1
*
* 0 1 2 3
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Ver |T|R|E|S|N| Message Type | Message Length |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | TEID |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Sequence Number(O) |N-PDU Number(O)|Next Ext Hdr(O)| (optional headers)
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*
* Message Length:
* a 16-bit field that indicates the length of the payload in bytes
* (rest of the packet following the mandatory 8-byte GTP header).
* Includes the optional fields.
*/
/*
* Next Extension Headers
*
* 0 1 2 3
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Length | Contents |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | ... |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Contents | Next Ext Hdr |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*
* Extension length
* an 8-bit field. This field states the length of this extension header,
* including the length, the contents, and the next extension header field,
* in 4-octet units, so the length of the extension must always be a multiple of 4.
*/
struct gtp1_hdr
{
uint8_t flags;
uint8_t msg_type;
uint16_t msg_len;
uint32_t teid;
} __attribute__((packed));
struct gtp1_hdr_long
{
uint8_t flags;
uint8_t msg_type;
uint16_t msg_len;
uint32_t teid;
uint16_t seq;
uint8_t npdu;
uint8_t next_ext_hdr;
} __attribute__((packed));
#define GTP1_FLAG_N_PDU (0x01)
#define GTP1_FLAG_SEQ_NUM (0x02)
#define GTP1_FLAG_EXT_HDR (0x04)
#define GTP1_FLAG_RESERVED (0x08)
#define GTP1_FLAG_PROTOCOL (0x10)
#define GTP1_FLAG_VERSION (0xE0)
/******************************************************************************
* get
******************************************************************************/
static inline uint8_t gtp1_hdr_get_flags(const struct gtp1_hdr *gtp)
{
return gtp->flags;
}
static inline uint8_t gtp1_hdr_get_version(const struct gtp1_hdr *gtp)
{
return (gtp->flags & GTP1_FLAG_VERSION) >> 5;
}
static inline uint8_t gtp1_hdr_get_protocol(const struct gtp1_hdr *gtp)
{
return (gtp->flags & GTP1_FLAG_PROTOCOL) >> 4;
}
static inline uint8_t gtp1_hdr_get_reserved(const struct gtp1_hdr *gtp)
{
return (gtp->flags & GTP1_FLAG_RESERVED) >> 3;
}
static inline uint8_t gtp1_hdr_get_ext_flag(const struct gtp1_hdr *gtp)
{
return (gtp->flags & GTP1_FLAG_EXT_HDR) >> 2;
}
static inline uint8_t gtp1_hdr_get_seq_flag(const struct gtp1_hdr *gtp)
{
return (gtp->flags & GTP1_FLAG_SEQ_NUM) >> 1;
}
static inline uint8_t gtp1_hdr_get_npdu_flag(const struct gtp1_hdr *gtp)
{
return (gtp->flags & GTP1_FLAG_N_PDU) >> 0;
}
static inline uint8_t gtp1_hdr_get_msg_type(const struct gtp1_hdr *gtp)
{
return gtp->msg_type;
}
static inline uint16_t gtp1_hdr_get_msg_len(const struct gtp1_hdr *gtp)
{
return ntohs(gtp->msg_len);
}
static inline uint32_t gtp1_hdr_get_teid(const struct gtp1_hdr *gtp)
{
return ntohl(gtp->teid);
}
static inline uint16_t gtp1_hdr_get_seq(const struct gtp1_hdr *gtp)
{
if (gtp1_hdr_get_seq_flag(gtp))
{
const struct gtp1_hdr_long *gtp_long = (const struct gtp1_hdr_long *)gtp;
return ntohs(gtp_long->seq);
}
else
{
return 0;
}
}
static inline uint8_t gtp1_hdr_get_npdu(const struct gtp1_hdr *gtp)
{
if (gtp1_hdr_get_npdu_flag(gtp))
{
const struct gtp1_hdr_long *gtp_long = (const struct gtp1_hdr_long *)gtp;
return gtp_long->npdu;
}
else
{
return 0;
}
}
static inline uint8_t gtp1_hdr_get_next_ext_type(const struct gtp1_hdr *gtp)
{
if (gtp1_hdr_get_ext_flag(gtp))
{
const struct gtp1_hdr_long *gtp_long = (const struct gtp1_hdr_long *)gtp;
return gtp_long->next_ext_hdr;
}
else
{
return 0;
}
}
static inline uint8_t peek_gtp_version(const char *data, uint16_t len)
{
if (data == NULL || len == 0)
{
return 0;
}
return ((*(uint8_t *)data) >> 5) & 0x07;
}
// include gtp fixed header and optional headers and extension headers
static inline uint16_t calc_gtp1_hdr_len(const char *data, uint16_t len)
{
if (data == NULL || len < sizeof(struct gtp1_hdr))
{
return 0;
}
const struct gtp1_hdr *gtp = (const struct gtp1_hdr *)data;
if (gtp1_hdr_get_version(gtp) != 1)
{
return 0;
}
if (gtp1_hdr_get_flags(gtp) & (GTP1_FLAG_SEQ_NUM | GTP1_FLAG_N_PDU | GTP1_FLAG_EXT_HDR))
{
if (sizeof(struct gtp1_hdr_long) > len)
{
return 0;
}
const struct gtp1_hdr_long *gtp_long = (const struct gtp1_hdr_long *)data;
uint8_t next_ext_hdr = gtp_long->next_ext_hdr;
uint16_t offset = sizeof(struct gtp1_hdr_long);
while (next_ext_hdr)
{
if (offset + 1 > len)
{
return 0;
}
uint8_t ext_hdr_len = *((char *)data + offset) * 4;
if (offset + ext_hdr_len > len)
{
return 0;
}
offset += ext_hdr_len; // skip extension header
next_ext_hdr = *((char *)data + offset - 1);
}
return offset;
}
else
{
return sizeof(struct gtp1_hdr);
}
}
/******************************************************************************
* set
******************************************************************************/
static inline void gtp1_hdr_set_flags(struct gtp1_hdr *gtp, uint8_t flags)
{
gtp->flags = flags;
}
static inline void gtp1_hdr_set_version(struct gtp1_hdr *gtp, uint8_t version)
{
gtp->flags = (gtp->flags & ~GTP1_FLAG_VERSION) | (version << 5);
}
static inline void gtp1_hdr_set_protocol(struct gtp1_hdr *gtp, uint8_t protocol_type)
{
gtp->flags = (gtp->flags & ~GTP1_FLAG_PROTOCOL) | (protocol_type << 4);
}
static inline void gtp1_hdr_set_reserved(struct gtp1_hdr *gtp, uint8_t reserved)
{
gtp->flags = (gtp->flags & ~GTP1_FLAG_RESERVED) | (reserved << 3);
}
static inline void gtp1_hdr_set_ext_flag(struct gtp1_hdr *gtp, uint8_t ext_flag)
{
gtp->flags = (gtp->flags & ~GTP1_FLAG_EXT_HDR) | (ext_flag << 2);
}
static inline void gtp1_hdr_set_seq_flag(struct gtp1_hdr *gtp, uint8_t seq_flag)
{
gtp->flags = (gtp->flags & ~GTP1_FLAG_SEQ_NUM) | (seq_flag << 1);
}
static inline void gtp1_hdr_set_npdu_flag(struct gtp1_hdr *gtp, uint8_t npdu_flag)
{
gtp->flags = (gtp->flags & ~GTP1_FLAG_N_PDU) | (npdu_flag << 0);
}
static inline void gtp1_hdr_set_msg_type(struct gtp1_hdr *gtp, uint8_t msg_type)
{
gtp->msg_type = msg_type;
}
static inline void gtp1_hdr_set_msg_len(struct gtp1_hdr *gtp, uint16_t msg_len)
{
gtp->msg_len = htons(msg_len);
}
static inline void gtp1_hdr_set_teid(struct gtp1_hdr *gtp, uint32_t teid)
{
gtp->teid = htonl(teid);
}
static inline void gtp1_hdr_set_seq(struct gtp1_hdr *gtp, uint16_t seq)
{
if (gtp1_hdr_get_seq_flag(gtp))
{
struct gtp1_hdr_long *gtp_long = (struct gtp1_hdr_long *)gtp;
gtp_long->seq = htons(seq);
}
}
static inline void gtp1_hdr_set_npdu(struct gtp1_hdr *gtp, uint8_t npdu)
{
if (gtp1_hdr_get_npdu_flag(gtp))
{
struct gtp1_hdr_long *gtp_long = (struct gtp1_hdr_long *)gtp;
gtp_long->npdu = npdu;
}
}
static inline void gtp1_hdr_set_next_ext_type(struct gtp1_hdr *gtp, uint8_t next_ext_hdr)
{
if (gtp1_hdr_get_ext_flag(gtp))
{
struct gtp1_hdr_long *gtp_long = (struct gtp1_hdr_long *)gtp;
gtp_long->next_ext_hdr = next_ext_hdr;
}
}
/******************************************************************************
* print
******************************************************************************/
static inline int gtp1_hdr_to_str(const struct gtp1_hdr *gtp, char *buf, size_t len)
{
int used = 0;
used += snprintf(buf + used, len - used, "GTP: flags=0x%02x (version=%u, protocol=%u, reserved=%u, ext_flag=%u, seq_flag=%u, npdu_flag=%u), msg_type=0x%02x, msg_len=%u, teid=%u",
gtp1_hdr_get_flags(gtp),
gtp1_hdr_get_version(gtp),
gtp1_hdr_get_protocol(gtp),
gtp1_hdr_get_reserved(gtp),
gtp1_hdr_get_ext_flag(gtp),
gtp1_hdr_get_seq_flag(gtp),
gtp1_hdr_get_npdu_flag(gtp),
gtp1_hdr_get_msg_type(gtp),
gtp1_hdr_get_msg_len(gtp),
gtp1_hdr_get_teid(gtp));
if (gtp1_hdr_get_seq_flag(gtp))
{
used += snprintf(buf + used, len - used, ", seq=%u", gtp1_hdr_get_seq(gtp));
}
if (gtp1_hdr_get_npdu_flag(gtp))
{
used += snprintf(buf + used, len - used, ", npdu=%u", gtp1_hdr_get_npdu(gtp));
}
if (gtp1_hdr_get_ext_flag(gtp))
{
used += snprintf(buf + used, len - used, ", next_ext_hdr=%u", gtp1_hdr_get_next_ext_type(gtp));
}
return used;
}
#ifdef __cplusplus
}
#endif

268
src/packet/gtp2_utils.h Normal file
View File

@@ -0,0 +1,268 @@
#pragma once
#ifdef __cplusplus
extern "C"
{
#endif
#include <stdio.h>
#include <string.h>
#include <arpa/inet.h>
/*
* https://en.wikipedia.org/wiki/GPRS_Tunnelling_Protocol
* https://www.etsi.org/deliver/etsi_ts/129200_129299/129274/08.04.00_60/ts_129274v080400p.pdf
*
* GTP-C: Gateway GPRS Support Nodes (GGSN) <----> Serving GPRS support Nodes (SGSN)
* GTP-U: Radio Access Network <----> Core Network
*
* GTPv2:
* -> GTPv2-C
* -> (no GTPv2-U)
*/
/*
* GTP version 2
*
* 0 1 2 3
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Ver |P|T|spare| Message Type | Message Length |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | TEID (only if T=1) |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Sequence Number | Spare |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*
* Message length:
* This field shall indicate the length of the message in octets excluding the mandatory of the GTP-C header (the first 4 octets).
* The TEID (if present) and the Sequence Number shall be included in the length count.
*/
struct gtp2_hdr
{
uint8_t flags;
uint8_t msg_type;
uint16_t msg_len;
uint32_t seq_and_spare;
} __attribute__((packed));
struct gtp2_hdr_long
{
uint8_t flags;
uint8_t msg_type;
uint16_t msg_len;
uint32_t teid;
uint32_t seq_and_spare;
} __attribute__((packed));
#define GPT2_FLAG_SPARE (0x07)
#define GTP2_FLAG_TEID (0x08)
#define GTP2_FLAG_PIGGYBACK (0x10)
#define GTP2_FLAG_VERSION (0xE0)
/******************************************************************************
* get
******************************************************************************/
static inline uint8_t gtp2_hdr_get_flags(const struct gtp2_hdr *gtp)
{
return gtp->flags;
}
static inline uint8_t gtp2_hdr_get_version(const struct gtp2_hdr *gtp)
{
return (gtp->flags & GTP2_FLAG_VERSION) >> 5;
}
static inline uint8_t gtp2_hdr_get_piggyback_flag(const struct gtp2_hdr *gtp)
{
return (gtp->flags & GTP2_FLAG_PIGGYBACK) >> 4;
}
static inline uint8_t gtp2_hdr_get_teid_flag(const struct gtp2_hdr *gtp)
{
return (gtp->flags & GTP2_FLAG_TEID) >> 3;
}
static inline uint8_t gtp2_hdr_get_spare_flag(const struct gtp2_hdr *gtp)
{
return (gtp->flags & GPT2_FLAG_SPARE) >> 0;
}
static inline uint8_t gtp2_hdr_get_msg_type(const struct gtp2_hdr *gtp)
{
return gtp->msg_type;
}
static inline uint16_t gtp2_hdr_get_msg_len(const struct gtp2_hdr *gtp)
{
return ntohs(gtp->msg_len);
}
static inline uint32_t gtp2_hdr_get_teid(const struct gtp2_hdr *gtp)
{
if (gtp2_hdr_get_teid_flag(gtp))
{
const struct gtp2_hdr_long *gtp_long = (const struct gtp2_hdr_long *)gtp;
return ntohl(gtp_long->teid);
}
else
{
return 0;
}
}
static inline uint32_t gtp2_hdr_get_seq(const struct gtp2_hdr *gtp)
{
if (gtp2_hdr_get_teid_flag(gtp))
{
const struct gtp2_hdr_long *gtp_long = (const struct gtp2_hdr_long *)gtp;
return ntohl(gtp_long->seq_and_spare) >> 8;
}
else
{
return ntohl(gtp->seq_and_spare) >> 8;
}
}
static inline uint8_t gtp2_hdr_get_spare(const struct gtp2_hdr *gtp)
{
if (gtp2_hdr_get_teid_flag(gtp))
{
const struct gtp2_hdr_long *gtp_long = (const struct gtp2_hdr_long *)gtp;
return ntohl(gtp_long->seq_and_spare) & 0xFF;
}
else
{
return ntohl(gtp->seq_and_spare) & 0xFF;
}
}
static inline uint16_t calc_gtp2_hdr_len(const char *data, uint16_t len)
{
if (len < sizeof(struct gtp2_hdr))
{
return 0;
}
const struct gtp2_hdr *gtp = (const struct gtp2_hdr *)data;
if (gtp2_hdr_get_version(gtp) == 2)
{
if (gtp2_hdr_get_teid_flag(gtp))
{
return sizeof(struct gtp2_hdr_long);
}
else
{
return sizeof(struct gtp2_hdr);
}
}
return 0;
}
/******************************************************************************
* set
******************************************************************************/
static inline void gtp2_hdr_set_flags(struct gtp2_hdr *gtp, uint8_t flags)
{
gtp->flags = flags;
}
static inline void gtp2_hdr_set_version(struct gtp2_hdr *gtp, uint8_t version)
{
gtp->flags = (gtp->flags & ~GTP2_FLAG_VERSION) | (version << 5);
}
static inline void gtp2_hdr_set_piggyback_flag(struct gtp2_hdr *gtp, uint8_t piggyback)
{
gtp->flags = (gtp->flags & ~GTP2_FLAG_PIGGYBACK) | (piggyback << 4);
}
static inline void gtp2_hdr_set_teid_flag(struct gtp2_hdr *gtp, uint8_t teid_flag)
{
gtp->flags = (gtp->flags & ~GTP2_FLAG_TEID) | (teid_flag << 3);
}
static inline void gtp2_hdr_set_spare_flag(struct gtp2_hdr *gtp, uint8_t spare_flag)
{
gtp->flags = (gtp->flags & ~GPT2_FLAG_SPARE) | (spare_flag << 0);
}
static inline void gtp2_hdr_set_msg_type(struct gtp2_hdr *gtp, uint8_t msg_type)
{
gtp->msg_type = msg_type;
}
static inline void gtp2_hdr_set_msg_len(struct gtp2_hdr *gtp, uint16_t msg_len)
{
gtp->msg_len = htons(msg_len);
}
static inline void gtp2_hdr_set_teid(struct gtp2_hdr *gtp, uint32_t teid)
{
if (gtp2_hdr_get_teid_flag(gtp))
{
struct gtp2_hdr_long *gtp_long = (struct gtp2_hdr_long *)gtp;
gtp_long->teid = htonl(teid);
}
}
static inline void gtp2_hdr_set_seq(struct gtp2_hdr *gtp, uint32_t seq)
{
if (gtp2_hdr_get_teid_flag(gtp))
{
struct gtp2_hdr_long *gtp_long = (struct gtp2_hdr_long *)gtp;
gtp_long->seq_and_spare = htonl((seq << 8) | gtp2_hdr_get_spare(gtp));
}
else
{
gtp->seq_and_spare = htonl((seq << 8) | gtp2_hdr_get_spare(gtp));
}
}
static inline void gtp2_hdr_set_spare(struct gtp2_hdr *gtp, uint8_t spare)
{
if (gtp2_hdr_get_teid_flag(gtp))
{
struct gtp2_hdr_long *gtp_long = (struct gtp2_hdr_long *)gtp;
gtp_long->seq_and_spare = htonl((gtp2_hdr_get_seq(gtp) << 8) | spare);
}
else
{
gtp->seq_and_spare = htonl((gtp2_hdr_get_seq(gtp) << 8) | spare);
}
}
/******************************************************************************
* print
******************************************************************************/
static inline int gtp2_hdr_to_str(const struct gtp2_hdr *gtp, char *buf, size_t len)
{
int used = 0;
used += snprintf(buf + used, len - used, "GTP: flags=0x%02x (version=%u, piggyback=%u, teid_flag=%u, spare_flag=%u), msg_type=0x%02x, msg_len=%u",
gtp2_hdr_get_flags(gtp),
gtp2_hdr_get_version(gtp),
gtp2_hdr_get_piggyback_flag(gtp),
gtp2_hdr_get_teid_flag(gtp),
gtp2_hdr_get_spare_flag(gtp),
gtp2_hdr_get_msg_type(gtp),
gtp2_hdr_get_msg_len(gtp));
if (gtp2_hdr_get_teid_flag(gtp))
{
used += snprintf(buf + used, len - used, ", teid=%u", gtp2_hdr_get_teid(gtp));
}
else
{
used += snprintf(buf + used, len - used, ", seq=%u, spare=%u", gtp2_hdr_get_seq(gtp), gtp2_hdr_get_spare(gtp));
}
return used;
}
#ifdef __cplusplus
}
#endif

View File

@@ -34,100 +34,100 @@ extern "C"
* get
******************************************************************************/
static inline uint8_t ipv4_hdr_get_version(const struct ip *hdr)
static inline uint8_t ip4_hdr_get_version(const struct ip *hdr)
{
return hdr->ip_v;
}
// IP Options are included in the hdr_len field
static inline uint8_t ipv4_hdr_get_hdr_len(const struct ip *hdr)
static inline uint8_t ip4_hdr_get_hdr_len(const struct ip *hdr)
{
return hdr->ip_hl << 2;
}
static inline uint8_t ipv4_hdr_get_tos(const struct ip *hdr)
static inline uint8_t ip4_hdr_get_tos(const struct ip *hdr)
{
return hdr->ip_tos;
}
static inline uint16_t ipv4_hdr_get_total_len(const struct ip *hdr)
static inline uint16_t ip4_hdr_get_total_len(const struct ip *hdr)
{
return ntohs(hdr->ip_len);
}
static inline uint16_t ipv4_hdr_get_ipid(const struct ip *hdr)
static inline uint16_t ip4_hdr_get_ipid(const struct ip *hdr)
{
return ntohs(hdr->ip_id);
}
static inline uint8_t ipv4_hdr_get_flags(const struct ip *hdr)
static inline uint8_t ip4_hdr_get_flags(const struct ip *hdr)
{
return (ntohs(hdr->ip_off) & (~IP_OFFMASK)) >> 13;
}
static inline bool ipv4_hdr_get_rf_flag(const struct ip *hdr)
static inline bool ip4_hdr_get_rf_flag(const struct ip *hdr)
{
return (ntohs(hdr->ip_off) & IP_RF) != 0;
}
static inline bool ipv4_hdr_get_df_flag(const struct ip *hdr)
static inline bool ip4_hdr_get_df_flag(const struct ip *hdr)
{
return (ntohs(hdr->ip_off) & IP_DF) != 0;
}
static inline bool ipv4_hdr_get_mf_flag(const struct ip *hdr)
static inline bool ip4_hdr_get_mf_flag(const struct ip *hdr)
{
return (ntohs(hdr->ip_off) & IP_MF) != 0;
}
static inline uint16_t ipv4_hdr_get_frag_offset(const struct ip *hdr)
static inline uint16_t ip4_hdr_get_frag_offset(const struct ip *hdr)
{
return (ntohs(hdr->ip_off) & IP_OFFMASK) << 3;
}
static inline uint8_t ipv4_hdr_get_ttl(const struct ip *hdr)
static inline uint8_t ip4_hdr_get_ttl(const struct ip *hdr)
{
return hdr->ip_ttl;
}
static inline uint8_t ipv4_hdr_get_proto(const struct ip *hdr)
static inline uint8_t ip4_hdr_get_proto(const struct ip *hdr)
{
return hdr->ip_p;
}
static inline uint16_t ipv4_hdr_get_checksum(const struct ip *hdr)
static inline uint16_t ip4_hdr_get_checksum(const struct ip *hdr)
{
return ntohs(hdr->ip_sum);
}
static inline uint32_t ipv4_hdr_get_src_addr(const struct ip *hdr)
static inline uint32_t ip4_hdr_get_src_addr(const struct ip *hdr)
{
return ntohl(hdr->ip_src.s_addr);
}
static inline uint32_t ipv4_hdr_get_dst_addr(const struct ip *hdr)
static inline uint32_t ip4_hdr_get_dst_addr(const struct ip *hdr)
{
return ntohl(hdr->ip_dst.s_addr);
}
static inline struct in_addr ipv4_hdr_get_src_in_addr(const struct ip *hdr)
static inline struct in_addr ip4_hdr_get_src_in_addr(const struct ip *hdr)
{
return hdr->ip_src;
}
static inline struct in_addr ipv4_hdr_get_dst_in_addr(const struct ip *hdr)
static inline struct in_addr ip4_hdr_get_dst_in_addr(const struct ip *hdr)
{
return hdr->ip_dst;
}
static inline uint8_t ipv4_hdr_get_opt_len(const struct ip *hdr)
static inline uint8_t ip4_hdr_get_opt_len(const struct ip *hdr)
{
return ipv4_hdr_get_hdr_len(hdr) - sizeof(struct ip);
return ip4_hdr_get_hdr_len(hdr) - sizeof(struct ip);
}
static inline const char *ipv4_hdr_get_opt_data(const struct ip *hdr)
static inline const char *ip4_hdr_get_opt_data(const struct ip *hdr)
{
if (ipv4_hdr_get_opt_len(hdr) == 0)
if (ip4_hdr_get_opt_len(hdr) == 0)
{
return NULL;
}
@@ -139,37 +139,37 @@ static inline const char *ipv4_hdr_get_opt_data(const struct ip *hdr)
* set
******************************************************************************/
static inline void ipv4_hdr_set_version(struct ip *hdr, uint8_t version)
static inline void ip4_hdr_set_version(struct ip *hdr, uint8_t version)
{
hdr->ip_v = version;
}
static inline void ipv4_hdr_set_hdr_len(struct ip *hdr, uint8_t hdr_len)
static inline void ip4_hdr_set_hdr_len(struct ip *hdr, uint8_t hdr_len)
{
hdr->ip_hl = hdr_len >> 2;
}
static inline void ipv4_hdr_set_tos(struct ip *hdr, uint8_t tos)
static inline void ip4_hdr_set_tos(struct ip *hdr, uint8_t tos)
{
hdr->ip_tos = tos;
}
static inline void ipv4_hdr_set_total_len(struct ip *hdr, uint16_t total_len)
static inline void ip4_hdr_set_total_len(struct ip *hdr, uint16_t total_len)
{
hdr->ip_len = htons(total_len);
}
static inline void ipv4_hdr_set_ipid(struct ip *hdr, uint16_t ipid)
static inline void ip4_hdr_set_ipid(struct ip *hdr, uint16_t ipid)
{
hdr->ip_id = htons(ipid);
}
static inline void ipv4_hdr_set_flags(struct ip *hdr, uint8_t flags)
static inline void ip4_hdr_set_flags(struct ip *hdr, uint8_t flags)
{
hdr->ip_off = htons((flags << 13) | (ntohs(hdr->ip_off) & IP_OFFMASK));
}
static inline void ipv4_hdr_set_rf_flag(struct ip *hdr, bool flag)
static inline void ip4_hdr_set_rf_flag(struct ip *hdr, bool flag)
{
if (flag)
{
@@ -181,7 +181,7 @@ static inline void ipv4_hdr_set_rf_flag(struct ip *hdr, bool flag)
}
}
static inline void ipv4_hdr_set_df_flag(struct ip *hdr, bool flag)
static inline void ip4_hdr_set_df_flag(struct ip *hdr, bool flag)
{
if (flag)
{
@@ -193,7 +193,7 @@ static inline void ipv4_hdr_set_df_flag(struct ip *hdr, bool flag)
}
}
static inline void ipv4_hdr_set_mf_flag(struct ip *hdr, bool flag)
static inline void ip4_hdr_set_mf_flag(struct ip *hdr, bool flag)
{
if (flag)
{
@@ -205,55 +205,55 @@ static inline void ipv4_hdr_set_mf_flag(struct ip *hdr, bool flag)
}
}
static inline void ipv4_hdr_set_frag_offset(struct ip *hdr, uint16_t frag_offset)
static inline void ip4_hdr_set_frag_offset(struct ip *hdr, uint16_t frag_offset)
{
hdr->ip_off = htons((frag_offset >> 3) | (ntohs(hdr->ip_off) & ~IP_OFFMASK));
}
static inline void ipv4_hdr_set_ttl(struct ip *hdr, uint8_t ttl)
static inline void ip4_hdr_set_ttl(struct ip *hdr, uint8_t ttl)
{
hdr->ip_ttl = ttl;
}
static inline void ipv4_hdr_set_protocol(struct ip *hdr, uint8_t protocol)
static inline void ip4_hdr_set_protocol(struct ip *hdr, uint8_t protocol)
{
hdr->ip_p = protocol;
}
static inline void ipv4_hdr_set_checksum(struct ip *hdr, uint16_t checksum)
static inline void ip4_hdr_set_checksum(struct ip *hdr, uint16_t checksum)
{
hdr->ip_sum = htons(checksum);
}
static inline void ipv4_hdr_set_src_addr(struct ip *hdr, uint32_t saddr)
static inline void ip4_hdr_set_src_addr(struct ip *hdr, uint32_t saddr)
{
hdr->ip_src.s_addr = htonl(saddr);
}
static inline void ipv4_hdr_set_dst_addr(struct ip *hdr, uint32_t daddr)
static inline void ip4_hdr_set_dst_addr(struct ip *hdr, uint32_t daddr)
{
hdr->ip_dst.s_addr = htonl(daddr);
}
static inline void ipv4_hdr_set_src_in_addr(struct ip *hdr, struct in_addr saddr)
static inline void ip4_hdr_set_src_in_addr(struct ip *hdr, struct in_addr saddr)
{
hdr->ip_src = saddr;
}
static inline void ipv4_hdr_set_dst_in_addr(struct ip *hdr, struct in_addr daddr)
static inline void ip4_hdr_set_dst_in_addr(struct ip *hdr, struct in_addr daddr)
{
hdr->ip_dst = daddr;
}
static inline void ipv4_hdr_set_opt_len(struct ip *hdr, uint8_t opt_len)
static inline void ip4_hdr_set_opt_len(struct ip *hdr, uint8_t opt_len)
{
ipv4_hdr_set_hdr_len(hdr, opt_len + sizeof(struct ip));
ip4_hdr_set_hdr_len(hdr, opt_len + sizeof(struct ip));
}
// must be called after ipv4_hdr_set_opt_len
static inline void ipv4_hdr_set_opt_data(struct ip *hdr, const char *opt_data)
// must be called after ip4_hdr_set_opt_len
static inline void ip4_hdr_set_opt_data(struct ip *hdr, const char *opt_data)
{
memcpy((char *)hdr + sizeof(struct ip), opt_data, ipv4_hdr_get_opt_len(hdr));
memcpy((char *)hdr + sizeof(struct ip), opt_data, ip4_hdr_get_opt_len(hdr));
}
/******************************************************************************
@@ -365,24 +365,24 @@ static inline const char *ip_proto_to_str(uint16_t proto)
}
}
static inline int ipv4_hdr_to_str(const struct ip *hdr, char *buf, size_t size)
static inline int ip4_hdr_to_str(const struct ip *hdr, char *buf, size_t size)
{
memset(buf, 0, size);
char src_addr_str[INET6_ADDRSTRLEN] = {0};
char dst_addr_str[INET6_ADDRSTRLEN] = {0};
uint16_t proto = ipv4_hdr_get_proto(hdr);
struct in_addr src_addr = ipv4_hdr_get_src_in_addr(hdr);
struct in_addr dst_addr = ipv4_hdr_get_dst_in_addr(hdr);
uint16_t proto = ip4_hdr_get_proto(hdr);
struct in_addr src_addr = ip4_hdr_get_src_in_addr(hdr);
struct in_addr dst_addr = ip4_hdr_get_dst_in_addr(hdr);
inet_ntop(AF_INET, &src_addr, src_addr_str, sizeof(src_addr_str));
inet_ntop(AF_INET, &dst_addr, dst_addr_str, sizeof(dst_addr_str));
return snprintf(buf, size, "IPv4: version=%u hdr_len=%u tos=%u total_len=%u ipid=%u flags=%u(rf=%u df=%u mf=%u) frag_offset=%u ttl=%u proto=%s checksum=0x%x src_addr=%s dst_addr=%s opt_len=%u",
ipv4_hdr_get_version(hdr), ipv4_hdr_get_hdr_len(hdr), ipv4_hdr_get_tos(hdr),
ipv4_hdr_get_total_len(hdr), ipv4_hdr_get_ipid(hdr), ipv4_hdr_get_flags(hdr),
ipv4_hdr_get_rf_flag(hdr), ipv4_hdr_get_df_flag(hdr), ipv4_hdr_get_mf_flag(hdr),
ipv4_hdr_get_frag_offset(hdr), ipv4_hdr_get_ttl(hdr), ip_proto_to_str(proto),
ipv4_hdr_get_checksum(hdr), src_addr_str, dst_addr_str, ipv4_hdr_get_opt_len(hdr));
ip4_hdr_get_version(hdr), ip4_hdr_get_hdr_len(hdr), ip4_hdr_get_tos(hdr),
ip4_hdr_get_total_len(hdr), ip4_hdr_get_ipid(hdr), ip4_hdr_get_flags(hdr),
ip4_hdr_get_rf_flag(hdr), ip4_hdr_get_df_flag(hdr), ip4_hdr_get_mf_flag(hdr),
ip4_hdr_get_frag_offset(hdr), ip4_hdr_get_ttl(hdr), ip_proto_to_str(proto),
ip4_hdr_get_checksum(hdr), src_addr_str, dst_addr_str, ip4_hdr_get_opt_len(hdr));
}
#ifdef __cplusplus

View File

@@ -52,47 +52,47 @@ extern "C"
* get
******************************************************************************/
static inline uint8_t ipv6_hdr_get_version(const struct ip6_hdr *hdr)
static inline uint8_t ip6_hdr_get_version(const struct ip6_hdr *hdr)
{
return (ntohl(hdr->ip6_flow) & 0xf0000000) >> 28;
}
static inline uint8_t ipv6_hdr_get_traffic_class(const struct ip6_hdr *hdr)
static inline uint8_t ip6_hdr_get_traffic_class(const struct ip6_hdr *hdr)
{
return (ntohl(hdr->ip6_flow) & 0x0ff00000) >> 20;
}
static inline uint32_t ipv6_hdr_get_flow_label(const struct ip6_hdr *hdr)
static inline uint32_t ip6_hdr_get_flow_label(const struct ip6_hdr *hdr)
{
return ntohl(hdr->ip6_flow) & 0x000fffff;
}
static inline uint16_t ipv6_hdr_get_payload_len(const struct ip6_hdr *hdr)
static inline uint16_t ip6_hdr_get_payload_len(const struct ip6_hdr *hdr)
{
return ntohs(hdr->ip6_plen);
}
static inline uint8_t ipv6_hdr_get_next_header(const struct ip6_hdr *hdr)
static inline uint8_t ip6_hdr_get_next_header(const struct ip6_hdr *hdr)
{
return hdr->ip6_nxt;
}
static inline uint8_t ipv6_hdr_get_hop_limit(const struct ip6_hdr *hdr)
static inline uint8_t ip6_hdr_get_hop_limit(const struct ip6_hdr *hdr)
{
return hdr->ip6_hlim;
}
static inline struct in6_addr ipv6_hdr_get_src_in6_addr(const struct ip6_hdr *hdr)
static inline struct in6_addr ip6_hdr_get_src_in6_addr(const struct ip6_hdr *hdr)
{
return hdr->ip6_src;
}
static inline struct in6_addr ipv6_hdr_get_dst_in6_addr(const struct ip6_hdr *hdr)
static inline struct in6_addr ip6_hdr_get_dst_in6_addr(const struct ip6_hdr *hdr)
{
return hdr->ip6_dst;
}
static inline struct ip6_frag *ipv6_hdr_get_frag_ext(const struct ip6_hdr *hdr)
static inline struct ip6_frag *ip6_hdr_get_frag_ext(const struct ip6_hdr *hdr)
{
if (hdr->ip6_nxt != IPPROTO_FRAGMENT)
{
@@ -105,42 +105,42 @@ static inline struct ip6_frag *ipv6_hdr_get_frag_ext(const struct ip6_hdr *hdr)
* set
******************************************************************************/
static inline void ipv6_hdr_set_version(struct ip6_hdr *hdr, uint8_t version)
static inline void ip6_hdr_set_version(struct ip6_hdr *hdr, uint8_t version)
{
hdr->ip6_flow = htonl((ntohl(hdr->ip6_flow) & 0x0fffffff) | (version << 28));
}
static inline void ipv6_hdr_set_traffic_class(struct ip6_hdr *hdr, uint8_t traffic_class)
static inline void ip6_hdr_set_traffic_class(struct ip6_hdr *hdr, uint8_t traffic_class)
{
hdr->ip6_flow = htonl((ntohl(hdr->ip6_flow) & 0xf00fffff) | (traffic_class << 20));
}
static inline void ipv6_hdr_set_flow_label(struct ip6_hdr *hdr, uint32_t flow_label)
static inline void ip6_hdr_set_flow_label(struct ip6_hdr *hdr, uint32_t flow_label)
{
hdr->ip6_flow = htonl((ntohl(hdr->ip6_flow) & 0xfff00000) | flow_label);
}
static inline void ipv6_hdr_set_payload_len(struct ip6_hdr *hdr, uint16_t payload_len)
static inline void ip6_hdr_set_payload_len(struct ip6_hdr *hdr, uint16_t payload_len)
{
hdr->ip6_plen = htons(payload_len);
}
static inline void ipv6_hdr_set_next_header(struct ip6_hdr *hdr, uint8_t next_header)
static inline void ip6_hdr_set_next_header(struct ip6_hdr *hdr, uint8_t next_header)
{
hdr->ip6_nxt = next_header;
}
static inline void ipv6_hdr_set_hop_limit(struct ip6_hdr *hdr, uint8_t hop_limit)
static inline void ip6_hdr_set_hop_limit(struct ip6_hdr *hdr, uint8_t hop_limit)
{
hdr->ip6_hlim = hop_limit;
}
static inline void ipv6_hdr_set_src_in6_addr(struct ip6_hdr *hdr, struct in6_addr src_addr)
static inline void ip6_hdr_set_src_in6_addr(struct ip6_hdr *hdr, struct in6_addr src_addr)
{
hdr->ip6_src = src_addr;
}
static inline void ipv6_hdr_set_dst_in6_addr(struct ip6_hdr *hdr, struct in6_addr dst_addr)
static inline void ip6_hdr_set_dst_in6_addr(struct ip6_hdr *hdr, struct in6_addr dst_addr)
{
hdr->ip6_dst = dst_addr;
}
@@ -200,20 +200,20 @@ static inline void ipv6_frag_set_more(struct ip6_frag *frag, bool more)
* print
******************************************************************************/
static inline int ipv6_hdr_to_str(const struct ip6_hdr *hdr, char *buf, size_t size)
static inline int ip6_hdr_to_str(const struct ip6_hdr *hdr, char *buf, size_t size)
{
memset(buf, 0, size);
char src_addr_str[INET6_ADDRSTRLEN] = {0};
char dst_addr_str[INET6_ADDRSTRLEN] = {0};
struct in6_addr src_addr = ipv6_hdr_get_src_in6_addr(hdr);
struct in6_addr dst_addr = ipv6_hdr_get_dst_in6_addr(hdr);
struct in6_addr src_addr = ip6_hdr_get_src_in6_addr(hdr);
struct in6_addr dst_addr = ip6_hdr_get_dst_in6_addr(hdr);
inet_ntop(AF_INET6, &src_addr, src_addr_str, INET6_ADDRSTRLEN);
inet_ntop(AF_INET6, &dst_addr, dst_addr_str, INET6_ADDRSTRLEN);
return snprintf(buf, size, "IPv6: version=%u traffic_class=%u flow_label=%u payload_len=%u next_header=%u hop_limit=%u src_addr=%s dst_addr=%s",
ipv6_hdr_get_version(hdr), ipv6_hdr_get_traffic_class(hdr), ipv6_hdr_get_flow_label(hdr), ipv6_hdr_get_payload_len(hdr),
ipv6_hdr_get_next_header(hdr), ipv6_hdr_get_hop_limit(hdr), src_addr_str, dst_addr_str);
ip6_hdr_get_version(hdr), ip6_hdr_get_traffic_class(hdr), ip6_hdr_get_flow_label(hdr), ip6_hdr_get_payload_len(hdr),
ip6_hdr_get_next_header(hdr), ip6_hdr_get_hop_limit(hdr), src_addr_str, dst_addr_str);
}
#ifdef __cplusplus

View File

@@ -4,8 +4,10 @@
#include "checksum.h"
#include "tcp_utils.h"
#include "udp_utils.h"
#include "ipv4_utils.h"
#include "ipv6_utils.h"
#include "ip4_utils.h"
#include "ip6_utils.h"
#include "gtp1_utils.h"
#include "gtp2_utils.h"
#include "packet_def.h"
#include "packet_utils.h"
#include "packet_layer.h"
@@ -15,7 +17,7 @@
#define PACKET_BUILD_LOG_DEBUG(format, ...) LOG_DEBUG("packet build", format, ##__VA_ARGS__)
#define PACKET_BUILD_LOG_ERROR(format, ...) LOG_ERROR("packet build", format, ##__VA_ARGS__)
struct packet_fingerprint
struct fingerprint
{
// TODO
uint16_t ip_id;
@@ -23,7 +25,7 @@ struct packet_fingerprint
uint16_t tcp_win;
};
static inline void calc_packet_fingerprint(struct packet_fingerprint *finger)
static inline void calc_packet_fingerprint(struct fingerprint *finger)
{
#define RANGE(rand, start, end) (start + rand % (end - start + 1)) // [start, end]
struct timespec time;
@@ -34,39 +36,143 @@ static inline void calc_packet_fingerprint(struct packet_fingerprint *finger)
finger->tcp_win = (uint16_t)(RANGE(random, 1000, 1460));
}
static void update_tcp_hdr(struct tcphdr *tcphdr, uint32_t seq, uint32_t ack, uint16_t win, uint8_t flags, uint16_t opts_len)
static void update_tcp_hdr(struct tcphdr *tcp, uint32_t seq, uint32_t ack, uint16_t win, uint8_t flags, uint16_t opts_len)
{
tcp_hdr_set_seq(tcphdr, seq);
tcp_hdr_set_ack(tcphdr, ack);
tcp_hdr_set_hdr_len(tcphdr, sizeof(struct tcphdr) + opts_len);
tcp_hdr_set_flags(tcphdr, flags);
tcp_hdr_set_window(tcphdr, win);
tcp_hdr_set_urg_ptr(tcphdr, 0);
tcp_hdr_set_checksum(tcphdr, 0);
tcp_hdr_set_seq(tcp, seq);
tcp_hdr_set_ack(tcp, ack);
tcp_hdr_set_hdr_len(tcp, sizeof(struct tcphdr) + opts_len);
tcp_hdr_set_flags(tcp, flags);
tcp_hdr_set_window(tcp, win);
tcp_hdr_set_urg_ptr(tcp, 0);
tcp_hdr_set_checksum(tcp, 0);
}
static void update_udp_hdr(struct udphdr *udphdr, int trim)
static void update_udp_hdr(struct udphdr *udp, int trim_len)
{
uint16_t total = udp_hdr_get_total_len(udphdr);
udp_hdr_set_total_len(udphdr, total - trim);
udp_hdr_set_checksum(udphdr, 0);
uint16_t total = udp_hdr_get_total_len(udp);
udp_hdr_set_total_len(udp, total - trim_len);
udp_hdr_set_checksum(udp, 0);
}
static void update_ip4_hdr(struct ip *iphdr, uint16_t ipid, uint8_t ttl, int trim)
static void update_ip4_hdr(struct ip *ip, uint16_t ipid, uint8_t ttl, int trim_len)
{
int hdr_len = ipv4_hdr_get_hdr_len(iphdr);
uint16_t total = ipv4_hdr_get_total_len(iphdr);
ipv4_hdr_set_total_len(iphdr, total - trim);
ipv4_hdr_set_ipid(iphdr, ipid);
ipv4_hdr_set_ttl(iphdr, ttl);
iphdr->ip_sum = 0;
iphdr->ip_sum = checksum((const char *)iphdr, hdr_len);
int hdr_len = ip4_hdr_get_hdr_len(ip);
uint16_t total = ip4_hdr_get_total_len(ip);
ip4_hdr_set_total_len(ip, total - trim_len);
ip4_hdr_set_ipid(ip, ipid);
ip4_hdr_set_ttl(ip, ttl);
ip->ip_sum = 0;
ip->ip_sum = checksum((const char *)ip, hdr_len);
}
static void update_ip6_hdr(struct ip6_hdr *ip6hdr, int trim)
static void update_ip6_hdr(struct ip6_hdr *ip6, int trim_len)
{
uint16_t len = ipv6_hdr_get_payload_len(ip6hdr);
ipv6_hdr_set_payload_len(ip6hdr, len - trim);
uint16_t len = ip6_hdr_get_payload_len(ip6);
ip6_hdr_set_payload_len(ip6, len - trim_len);
}
static void update_gtp1_hdr(struct gtp1_hdr *gtp, int trim_len)
{
uint16_t msg_len = gtp1_hdr_get_msg_len(gtp);
gtp1_hdr_set_msg_len(gtp, msg_len - trim_len);
if (gtp1_hdr_get_seq_flag(gtp) && gtp1_hdr_get_seq(gtp))
{
PACKET_BUILD_LOG_ERROR("imiated packets may be dropped by intermediate devices, the GTPv1 layer requires a sequence number");
}
}
static void update_gtp2_hdr(struct gtp2_hdr *gtp, int trim_len)
{
uint16_t msg_len = gtp2_hdr_get_msg_len(gtp);
gtp2_hdr_set_msg_len(gtp, msg_len - trim_len);
if (gtp2_hdr_get_seq(gtp))
{
PACKET_BUILD_LOG_ERROR("imiated packets may be dropped by intermediate devices, the GTPv2 layer requires a sequence number");
}
}
static void update_packet_hdr(const struct packet *origin_pkt,
char *new_pkt_data, uint16_t new_pkt_len, int trim_len,
uint32_t tcp_seq, uint32_t tcp_ack, uint8_t tcp_flags, uint16_t tcp_opts_len)
{
uint8_t gtp_version = 0;
char *curr_hdr_ptr = NULL;
struct tcphdr *tcp = NULL;
struct udphdr *udp = NULL;
struct ip *ip4 = NULL;
struct ip6_hdr *ip6 = NULL;
struct gtp1_hdr *gtp1 = NULL;
struct gtp2_hdr *gtp2 = NULL;
struct raw_layer *curr_layer = NULL;
struct raw_layer *last_layer = NULL;
struct fingerprint finger = {0};
calc_packet_fingerprint(&finger);
int count = packet_get_layer_count(origin_pkt);
for (int i = count - 1; i >= 0; i--)
{
curr_layer = (struct raw_layer *)packet_get_raw_layer(origin_pkt, i);
curr_hdr_ptr = new_pkt_data + curr_layer->hdr_offset;
switch (curr_layer->proto)
{
case LAYER_PROTO_TCP:
tcp = (struct tcphdr *)curr_hdr_ptr;
update_tcp_hdr(tcp, tcp_seq, tcp_ack, finger.tcp_win, tcp_flags, tcp_opts_len);
break;
case LAYER_PROTO_UDP:
udp = (struct udphdr *)curr_hdr_ptr;
update_udp_hdr(udp, trim_len);
break;
case LAYER_PROTO_IPV4:
ip4 = (struct ip *)curr_hdr_ptr;
last_layer = (struct raw_layer *)packet_get_raw_layer(origin_pkt, i + 1);
if (last_layer->proto == LAYER_PROTO_TCP)
{
tcp = (struct tcphdr *)(new_pkt_data + last_layer->hdr_offset);
tcp->th_sum = checksum_v4(tcp, new_pkt_len - last_layer->hdr_offset, IPPROTO_TCP, &ip4->ip_src, &ip4->ip_dst);
}
if (last_layer->proto == LAYER_PROTO_UDP)
{
udp = (struct udphdr *)(new_pkt_data + last_layer->hdr_offset);
udp->uh_sum = checksum_v4(udp, new_pkt_len - last_layer->hdr_offset, IPPROTO_UDP, &ip4->ip_src, &ip4->ip_dst);
}
update_ip4_hdr(ip4, finger.ip_id, finger.ip_ttl, trim_len);
break;
case LAYER_PROTO_IPV6:
ip6 = (struct ip6_hdr *)curr_hdr_ptr;
last_layer = (struct raw_layer *)packet_get_raw_layer(origin_pkt, i + 1);
if (last_layer->proto == LAYER_PROTO_TCP)
{
tcp = (struct tcphdr *)(new_pkt_data + last_layer->hdr_offset);
tcp->th_sum = checksum_v6(tcp, new_pkt_len - last_layer->hdr_offset, IPPROTO_TCP, &ip6->ip6_src, &ip6->ip6_dst);
}
if (last_layer->proto == LAYER_PROTO_UDP)
{
udp = (struct udphdr *)(new_pkt_data + last_layer->hdr_offset);
udp->uh_sum = checksum_v6(udp, new_pkt_len - last_layer->hdr_offset, IPPROTO_UDP, &ip6->ip6_src, &ip6->ip6_dst);
}
update_ip6_hdr(ip6, trim_len);
break;
case LAYER_PROTO_GTP_C: /* fall through */
case LAYER_PROTO_GTP_U:
gtp_version = peek_gtp_version(new_pkt_data + curr_layer->hdr_offset, curr_layer->hdr_len);
if (gtp_version == 1)
{
gtp1 = (struct gtp1_hdr *)curr_hdr_ptr;
update_gtp1_hdr(gtp1, trim_len);
}
if (gtp_version == 2)
{
gtp2 = (struct gtp2_hdr *)curr_hdr_ptr;
update_gtp2_hdr(gtp2, trim_len);
}
break;
case LAYER_PROTO_GRE:
// TODO
break;
default:
break;
}
}
}
/*
@@ -98,8 +204,8 @@ struct packet *imitate_tcp_packet(const struct packet *origin_pkt, uint32_t tcp_
}
// calculate the new packet length
int trim = tcp_layer->hdr_len + tcp_layer->pld_len - tcp_options_len - tcp_payload_len - sizeof(struct tcphdr);
uint16_t new_pkt_len = origin_pkt->data_len - origin_pkt->trim_len - trim;
int trim_len = tcp_layer->hdr_len + tcp_layer->pld_len - tcp_options_len - tcp_payload_len - sizeof(struct tcphdr);
uint16_t new_pkt_len = origin_pkt->data_len - origin_pkt->trim_len - trim_len;
struct packet *new_pkt = packet_new(new_pkt_len);
if (new_pkt == NULL)
{
@@ -117,67 +223,7 @@ struct packet *imitate_tcp_packet(const struct packet *origin_pkt, uint32_t tcp_
memcpy(new_pkt_data + tcp_layer->hdr_offset + sizeof(struct tcphdr) + tcp_options_len, tcp_payload, tcp_payload_len);
// update the headers of the new packet
struct tcphdr *tcp_hdr = NULL;
struct udphdr *udp_hdr = NULL;
struct ip *ip4_hdr = NULL;
struct ip6_hdr *ip6_hdr = NULL;
struct raw_layer *curr_layer = NULL;
struct raw_layer *last_layer = NULL;
struct packet_fingerprint finger = {0};
calc_packet_fingerprint(&finger);
for (int i = layers - 1; i >= 0; i--)
{
curr_layer = (struct raw_layer *)packet_get_raw_layer(origin_pkt, i);
switch (curr_layer->proto)
{
case LAYER_PROTO_TCP:
tcp_hdr = (struct tcphdr *)(new_pkt_data + curr_layer->hdr_offset);
update_tcp_hdr(tcp_hdr, tcp_seq, tcp_ack, finger.tcp_win, tcp_flags, tcp_options_len);
break;
case LAYER_PROTO_UDP:
udp_hdr = (struct udphdr *)(new_pkt_data + curr_layer->hdr_offset);
update_udp_hdr(udp_hdr, trim);
break;
case LAYER_PROTO_IPV4:
ip4_hdr = (struct ip *)(new_pkt_data + curr_layer->hdr_offset);
last_layer = (struct raw_layer *)packet_get_raw_layer(origin_pkt, i + 1);
if (last_layer->proto == LAYER_PROTO_TCP)
{
tcp_hdr = (struct tcphdr *)(new_pkt_data + last_layer->hdr_offset);
tcp_hdr->th_sum = checksum_v4(tcp_hdr, new_pkt_len - last_layer->hdr_offset, IPPROTO_TCP, &ip4_hdr->ip_src, &ip4_hdr->ip_dst);
}
if (last_layer->proto == LAYER_PROTO_UDP)
{
udp_hdr = (struct udphdr *)(new_pkt_data + last_layer->hdr_offset);
udp_hdr->uh_sum = checksum_v4(udp_hdr, new_pkt_len - last_layer->hdr_offset, IPPROTO_UDP, &ip4_hdr->ip_src, &ip4_hdr->ip_dst);
}
update_ip4_hdr(ip4_hdr, finger.ip_id, finger.ip_ttl, trim);
break;
case LAYER_PROTO_IPV6:
ip6_hdr = (struct ip6_hdr *)(new_pkt_data + curr_layer->hdr_offset);
last_layer = (struct raw_layer *)packet_get_raw_layer(origin_pkt, i + 1);
if (last_layer->proto == LAYER_PROTO_TCP)
{
tcp_hdr = (struct tcphdr *)(new_pkt_data + last_layer->hdr_offset);
tcp_hdr->th_sum = checksum_v6(tcp_hdr, new_pkt_len - last_layer->hdr_offset, IPPROTO_TCP, &ip6_hdr->ip6_src, &ip6_hdr->ip6_dst);
}
if (last_layer->proto == LAYER_PROTO_UDP)
{
udp_hdr = (struct udphdr *)(new_pkt_data + last_layer->hdr_offset);
udp_hdr->uh_sum = checksum_v6(udp_hdr, new_pkt_len - last_layer->hdr_offset, IPPROTO_UDP, &ip6_hdr->ip6_src, &ip6_hdr->ip6_dst);
}
update_ip6_hdr(ip6_hdr, trim);
break;
case LAYER_PROTO_GTP:
// TODO
break;
case LAYER_PROTO_GRE:
// TODO
break;
default:
break;
}
}
update_packet_hdr(origin_pkt, new_pkt_data, new_pkt_len, trim_len, tcp_seq, tcp_ack, tcp_flags, tcp_options_len);
packet_parse(new_pkt, new_pkt_data, new_pkt_len);
memcpy(&new_pkt->meta, &origin_pkt->meta, sizeof(struct metadata));
@@ -205,8 +251,8 @@ struct packet *imitate_udp_packet(const struct packet *origin_pkt, const char *u
}
// calculate the new packet length
int trim = udp_layer->hdr_len + udp_layer->pld_len - udp_payload_len - sizeof(struct udphdr);
uint16_t new_pkt_len = origin_pkt->data_len - origin_pkt->trim_len - trim;
int trim_len = udp_layer->hdr_len + udp_layer->pld_len - udp_payload_len - sizeof(struct udphdr);
uint16_t new_pkt_len = origin_pkt->data_len - origin_pkt->trim_len - trim_len;
struct packet *new_pkt = packet_new(new_pkt_len);
if (new_pkt == NULL)
{
@@ -220,52 +266,7 @@ struct packet *imitate_udp_packet(const struct packet *origin_pkt, const char *u
memcpy(new_pkt_data + udp_layer->hdr_offset + sizeof(struct udphdr), udp_payload, udp_payload_len);
// update the headers of the new packet
struct udphdr *udp_hdr = NULL;
struct ip *ip4_hdr = NULL;
struct ip6_hdr *ip6_hdr = NULL;
struct raw_layer *curr_layer = NULL;
struct raw_layer *last_layer = NULL;
struct packet_fingerprint finger = {0};
calc_packet_fingerprint(&finger);
for (int i = layers - 1; i >= 0; i--)
{
curr_layer = (struct raw_layer *)packet_get_raw_layer(origin_pkt, i);
switch (curr_layer->proto)
{
case LAYER_PROTO_UDP:
udp_hdr = (struct udphdr *)(new_pkt_data + curr_layer->hdr_offset);
update_udp_hdr(udp_hdr, trim);
break;
case LAYER_PROTO_IPV4:
ip4_hdr = (struct ip *)(new_pkt_data + curr_layer->hdr_offset);
last_layer = (struct raw_layer *)packet_get_raw_layer(origin_pkt, i + 1);
if (last_layer->proto == LAYER_PROTO_UDP)
{
udp_hdr = (struct udphdr *)(new_pkt_data + last_layer->hdr_offset);
udp_hdr->uh_sum = checksum_v4(udp_hdr, new_pkt_len - last_layer->hdr_offset, IPPROTO_UDP, &ip4_hdr->ip_src, &ip4_hdr->ip_dst);
}
update_ip4_hdr(ip4_hdr, finger.ip_id, finger.ip_ttl, trim);
break;
case LAYER_PROTO_IPV6:
ip6_hdr = (struct ip6_hdr *)(new_pkt_data + curr_layer->hdr_offset);
last_layer = (struct raw_layer *)packet_get_raw_layer(origin_pkt, i + 1);
if (last_layer->proto == LAYER_PROTO_UDP)
{
udp_hdr = (struct udphdr *)(new_pkt_data + last_layer->hdr_offset);
udp_hdr->uh_sum = checksum_v6(udp_hdr, new_pkt_len - last_layer->hdr_offset, IPPROTO_UDP, &ip6_hdr->ip6_src, &ip6_hdr->ip6_dst);
}
update_ip6_hdr(ip6_hdr, trim);
break;
case LAYER_PROTO_GTP:
// TODO
break;
case LAYER_PROTO_GRE:
// TODO
break;
default:
break;
}
}
update_packet_hdr(origin_pkt, new_pkt_data, new_pkt_len, trim_len, 0, 0, 0, 0);
packet_parse(new_pkt, new_pkt_data, new_pkt_len);
memcpy(&new_pkt->meta, &origin_pkt->meta, sizeof(struct metadata));
@@ -313,77 +314,97 @@ struct packet *craft_packet_from_scratch(const struct layer layers[], uint16_t l
memcpy(new_pkt_data + offset, payload, payload_len);
// update the headers of the new packet
struct tcphdr *tcp_hdr = NULL;
struct udphdr *udp_hdr = NULL;
struct ip *ip4_hdr = NULL;
struct ip6_hdr *ip6_hdr = NULL;
uint8_t gtp_version = 0;
uint16_t curr_hdr_len = 0;
char *curr_hdr_ptr = NULL;
struct tcphdr *tcp = NULL;
struct udphdr *udp = NULL;
struct ip *ip4 = NULL;
struct ip6_hdr *ip6 = NULL;
struct gtp1_hdr *gtp1 = NULL;
struct gtp2_hdr *gtp2 = NULL;
// update checksums and lengths
uint16_t curr_layer_payload_len = payload_len;
uint16_t curr_payload_len = payload_len;
for (int i = layer_count - 1; i >= 0; i--)
{
curr_hdr_len = layers[i].hdr_len;
curr_hdr_ptr = new_pkt_data + new_pkt_len - curr_hdr_len - curr_payload_len;
switch (layers[i].proto)
{
case LAYER_PROTO_TCP:
tcp_hdr = (struct tcphdr *)(new_pkt_data + new_pkt_len - layers[i].hdr_len - curr_layer_payload_len);
tcp = (struct tcphdr *)curr_hdr_ptr;
// update the TCP header
tcp_hdr_set_hdr_len(tcp_hdr, layers[i].hdr_len);
tcp_hdr_set_checksum(tcp_hdr, 0);
curr_layer_payload_len += layers[i].hdr_len;
tcp_hdr_set_hdr_len(tcp, curr_hdr_len);
tcp_hdr_set_checksum(tcp, 0);
curr_payload_len += curr_hdr_len;
break;
case LAYER_PROTO_UDP:
udp_hdr = (struct udphdr *)(new_pkt_data + new_pkt_len - layers[i].hdr_len - curr_layer_payload_len);
udp = (struct udphdr *)curr_hdr_ptr;
// update the UDP header
udp_hdr_set_total_len(udp_hdr, layers[i].hdr_len + curr_layer_payload_len);
udp_hdr_set_checksum(udp_hdr, 0);
curr_layer_payload_len += layers[i].hdr_len;
udp_hdr_set_total_len(udp, curr_hdr_len + curr_payload_len);
udp_hdr_set_checksum(udp, 0);
curr_payload_len += curr_hdr_len;
break;
case LAYER_PROTO_IPV4:
ip4_hdr = (struct ip *)(new_pkt_data + new_pkt_len - layers[i].hdr_len - curr_layer_payload_len);
ip4 = (struct ip *)curr_hdr_ptr;
// update the checksums of the upper layer
if (i + 1 < layer_count && layers[i + 1].proto == LAYER_PROTO_TCP)
{
tcp_hdr = (struct tcphdr *)(new_pkt_data + new_pkt_len - curr_layer_payload_len);
tcp_hdr->th_sum = checksum_v4(tcp_hdr, curr_layer_payload_len, IPPROTO_TCP, &ip4_hdr->ip_src, &ip4_hdr->ip_dst);
tcp = (struct tcphdr *)(new_pkt_data + new_pkt_len - curr_payload_len);
tcp->th_sum = checksum_v4(tcp, curr_payload_len, IPPROTO_TCP, &ip4->ip_src, &ip4->ip_dst);
}
if (i + 1 < layer_count && layers[i + 1].proto == LAYER_PROTO_UDP)
{
udp_hdr = (struct udphdr *)(new_pkt_data + new_pkt_len - curr_layer_payload_len);
udp_hdr->uh_sum = checksum_v4(udp_hdr, curr_layer_payload_len, IPPROTO_UDP, &ip4_hdr->ip_src, &ip4_hdr->ip_dst);
udp = (struct udphdr *)(new_pkt_data + new_pkt_len - curr_payload_len);
udp->uh_sum = checksum_v4(udp, curr_payload_len, IPPROTO_UDP, &ip4->ip_src, &ip4->ip_dst);
}
// update the IPv4 header
ipv4_hdr_set_hdr_len(ip4_hdr, layers[i].hdr_len);
ipv4_hdr_set_total_len(ip4_hdr, layers[i].hdr_len + curr_layer_payload_len);
ip4_hdr->ip_sum = 0;
ip4_hdr->ip_sum = checksum((const char *)ip4_hdr, layers[i].hdr_len);
curr_layer_payload_len += layers[i].hdr_len;
ip4_hdr_set_hdr_len(ip4, curr_hdr_len);
ip4_hdr_set_total_len(ip4, curr_hdr_len + curr_payload_len);
ip4->ip_sum = 0;
ip4->ip_sum = checksum((const char *)ip4, curr_hdr_len);
curr_payload_len += curr_hdr_len;
break;
case LAYER_PROTO_IPV6:
ip6_hdr = (struct ip6_hdr *)(new_pkt_data + new_pkt_len - layers[i].hdr_len - curr_layer_payload_len);
ip6 = (struct ip6_hdr *)curr_hdr_ptr;
// update the checksums of the upper layer
if (i + 1 < layer_count && layers[i + 1].proto == LAYER_PROTO_TCP)
{
tcp_hdr = (struct tcphdr *)(new_pkt_data + new_pkt_len - curr_layer_payload_len);
tcp_hdr->th_sum = checksum_v6(tcp_hdr, curr_layer_payload_len, IPPROTO_TCP, &ip6_hdr->ip6_src, &ip6_hdr->ip6_dst);
tcp = (struct tcphdr *)(new_pkt_data + new_pkt_len - curr_payload_len);
tcp->th_sum = checksum_v6(tcp, curr_payload_len, IPPROTO_TCP, &ip6->ip6_src, &ip6->ip6_dst);
}
if (i + 1 < layer_count && layers[i + 1].proto == LAYER_PROTO_UDP)
{
udp_hdr = (struct udphdr *)(new_pkt_data + new_pkt_len - curr_layer_payload_len);
udp_hdr->uh_sum = checksum_v6(udp_hdr, curr_layer_payload_len, IPPROTO_UDP, &ip6_hdr->ip6_src, &ip6_hdr->ip6_dst);
udp = (struct udphdr *)(new_pkt_data + new_pkt_len - curr_payload_len);
udp->uh_sum = checksum_v6(udp, curr_payload_len, IPPROTO_UDP, &ip6->ip6_src, &ip6->ip6_dst);
}
// update the IPv6 header
ipv6_hdr_set_payload_len(ip6_hdr, layers[i].hdr_len + curr_layer_payload_len - sizeof(struct ip6_hdr));
curr_layer_payload_len += layers[i].hdr_len;
ip6_hdr_set_payload_len(ip6, curr_hdr_len + curr_payload_len - sizeof(struct ip6_hdr));
curr_payload_len += curr_hdr_len;
break;
case LAYER_PROTO_GTP:
// TODO
curr_layer_payload_len += layers[i].hdr_len;
case LAYER_PROTO_GTP_C: /* fall through */
case LAYER_PROTO_GTP_U:
gtp_version = peek_gtp_version(curr_hdr_ptr, curr_hdr_len);
if (gtp_version == 1)
{
gtp1 = (struct gtp1_hdr *)curr_hdr_ptr;
// update the GTP header
gtp1_hdr_set_msg_len(gtp1, curr_hdr_len + curr_payload_len - sizeof(struct gtp1_hdr));
}
if (gtp_version == 2)
{
gtp2 = (struct gtp2_hdr *)curr_hdr_ptr;
// update the GTP header
gtp2_hdr_set_msg_len(gtp2, curr_hdr_len + curr_payload_len - 4);
}
curr_payload_len += curr_hdr_len;
break;
case LAYER_PROTO_GRE:
// TODO
curr_layer_payload_len += layers[i].hdr_len;
curr_payload_len += curr_hdr_len;
break;
default:
curr_layer_payload_len += layers[i].hdr_len;
curr_payload_len += curr_hdr_len;
break;
}
}
@@ -393,4 +414,4 @@ struct packet *craft_packet_from_scratch(const struct layer layers[], uint16_t l
new_pkt->meta.origin_ctx = NULL;
return new_pkt;
}
}

View File

@@ -9,8 +9,10 @@
#include "gre_utils.h"
#include "udp_utils.h"
#include "tcp_utils.h"
#include "ipv4_utils.h"
#include "ipv6_utils.h"
#include "ip4_utils.h"
#include "ip6_utils.h"
#include "gtp1_utils.h"
#include "gtp2_utils.h"
#include "mpls_utils.h"
#include "l2tp_utils.h"
#include "vlan_utils.h"
@@ -33,20 +35,20 @@
#define PACKET_LOG_UNSUPPORT_PROTO(pkt, layer, next_proto) \
{ \
PACKET_PARSE_LOG_WARN("pkt: %p, layer: %s, unsupport next proto %d", \
PACKET_PARSE_LOG_WARN("pkt: %p, layer: %s, unsupport next proto: %d", \
(pkt), layer_proto_to_str(layer), (next_proto)); \
}
#define PACKET_LOG_UNSUPPORT_ETHPROTO(pkt, next_proto) \
{ \
PACKET_PARSE_LOG_WARN("pkt: %p, layer: l3, unsupport next eth proto %s", \
(pkt), eth_proto_to_str(next_proto)); \
#define PACKET_LOG_UNSUPPORT_ETHPROTO(pkt, next_proto) \
{ \
PACKET_PARSE_LOG_WARN("pkt: %p, layer: L3, unsupport next proto: %d %s", \
(pkt), (next_proto), eth_proto_to_str(next_proto)); \
}
#define PACKET_LOG_UNSUPPORT_IPPROTO(pkt, next_proto) \
{ \
PACKET_PARSE_LOG_WARN("pkt: %p, layer: l4, unsupport next ip proto %s", \
(pkt), ip_proto_to_str(next_proto)); \
#define PACKET_LOG_UNSUPPORT_IPPROTO(pkt, next_proto) \
{ \
PACKET_PARSE_LOG_WARN("pkt: %p, layer: L4, unsupport next proto: %d %s", \
(pkt), (next_proto), ip_proto_to_str(next_proto)); \
}
/******************************************************************************
@@ -55,7 +57,6 @@
static inline const char *layer_proto_to_str(enum layer_proto proto);
static inline struct raw_layer *get_free_layer(struct packet *pkt);
static inline uint16_t get_gtp_hdr_len(const char *data, uint16_t len);
// 数据链路层
static inline const char *parse_ether(struct packet *pkt, const char *data, uint16_t len);
@@ -82,7 +83,8 @@ static inline const char *parse_icmp(struct packet *pkt, const char *data, uint1
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);
static inline const char *parse_gtp_u(struct packet *pkt, const char *data, uint16_t len);
static inline const char *parse_gtp_c(struct packet *pkt, const char *data, uint16_t len);
// L3/L4
static inline const char *parse_l3(struct packet *pkt, uint16_t next_proto, const char *data, uint16_t len);
static inline const char *parse_l4(struct packet *pkt, uint8_t next_proto, const char *data, uint16_t len);
@@ -127,8 +129,10 @@ static inline const char *layer_proto_to_str(enum layer_proto proto)
return "ICMP6";
case LAYER_PROTO_VXLAN:
return "VXLAN";
case LAYER_PROTO_GTP:
return "GTP";
case LAYER_PROTO_GTP_C:
return "GTP-C";
case LAYER_PROTO_GTP_U:
return "GTP-U";
default:
return "UNKNOWN";
}
@@ -163,74 +167,6 @@ static inline struct raw_layer *get_free_layer(struct packet *pkt)
* Private API -- Parses
******************************************************************************/
static inline uint16_t get_gtp_hdr_len(const char *data, uint16_t len)
{
#define GTP_HDR_VER (0xE0)
#define GTP_HDR_FLAG_N_PDU (0x01)
#define GTP_HDR_FLAG_SEQ_NUM (0x02)
#define GTP_HDR_FLAG_EXT_HDR (0x04)
struct gtp_hdr
{
uint8_t flags;
uint8_t msg_type;
uint16_t msg_len;
uint32_t teid;
} __attribute__((__packed__));
struct gtp_opt
{
uint16_t seq_num;
uint8_t npdu;
uint8_t next_ext_hdr;
} __attribute__((__packed__));
uint16_t hdr_offset = 0;
if (len < sizeof(struct gtp_hdr))
{
return 0;
}
const struct gtp_hdr *gtp = (const struct gtp_hdr *)data;
hdr_offset += sizeof(struct gtp_hdr); // skip gre hdr
// GTPv0 Not Supported
if (((gtp->flags & GTP_HDR_VER) >> 5) != 1)
{
return 0;
}
if (gtp->flags & (GTP_HDR_FLAG_SEQ_NUM | GTP_HDR_FLAG_N_PDU | GTP_HDR_FLAG_EXT_HDR))
{
if (hdr_offset + sizeof(struct gtp_opt) > len)
{
return 0;
}
struct gtp_opt *opt_hdr = (struct gtp_opt *)((char *)data + hdr_offset);
uint8_t next_ext_hdr = opt_hdr->next_ext_hdr;
hdr_offset += sizeof(struct gtp_opt); // skip gre opt
while (next_ext_hdr)
{
if (hdr_offset + 1 > len)
{
return 0;
}
uint8_t length = *((char *)data + hdr_offset) * 4 - 2;
hdr_offset += 1; // skip length field
if (hdr_offset + length + 1 > len)
{
return 0;
}
hdr_offset += length; // skip data field
next_ext_hdr = *((char *)data + hdr_offset);
hdr_offset += 1; // skip next ext hdr field
}
}
return hdr_offset;
}
static inline const char *parse_ether(struct packet *pkt, const char *data, uint16_t len)
{
if (unlikely(len < sizeof(struct ethhdr)))
@@ -564,14 +500,14 @@ static inline const char *parse_ipv4(struct packet *pkt, const char *data, uint1
return data;
}
const struct ip *hdr = (const struct ip *)data;
uint16_t hdr_len = ipv4_hdr_get_hdr_len(hdr);
uint16_t hdr_len = ip4_hdr_get_hdr_len(hdr);
if (unlikely(hdr_len > len))
{
PACKET_LOG_DATA_INSUFFICIENCY(pkt, LAYER_PROTO_IPV4);
return data;
}
uint16_t total_len = ipv4_hdr_get_total_len(hdr);
uint16_t total_len = ip4_hdr_get_total_len(hdr);
if (unlikely(total_len > len))
{
PACKET_LOG_DATA_INSUFFICIENCY(pkt, LAYER_PROTO_IPV4);
@@ -586,14 +522,14 @@ static inline const char *parse_ipv4(struct packet *pkt, const char *data, uint1
SET_LAYER(pkt, layer, LAYER_PROTO_IPV4, hdr_len, data, len, trim_len);
// ip fragmented
if (ipv4_hdr_get_mf_flag(hdr) || ipv4_hdr_get_frag_offset(hdr))
if (ip4_hdr_get_mf_flag(hdr) || ip4_hdr_get_frag_offset(hdr))
{
PACKET_PARSE_LOG_WARN("packet %p ip layer %p is fragmented", pkt, layer);
pkt->frag_layer = layer;
return layer->pld_ptr;
}
uint8_t next_proto = ipv4_hdr_get_proto(hdr);
uint8_t next_proto = ip4_hdr_get_proto(hdr);
return parse_l4(pkt, next_proto, layer->pld_ptr, layer->pld_len);
}
@@ -630,13 +566,13 @@ static inline const char *parse_ipv6(struct packet *pkt, const char *data, uint1
return data;
}
const struct ip6_hdr *hdr = (const struct ip6_hdr *)data;
uint16_t pld_len = ipv6_hdr_get_payload_len(hdr);
uint16_t pld_len = ip6_hdr_get_payload_len(hdr);
if (unlikely(pld_len + sizeof(struct ip6_hdr) > len))
{
PACKET_LOG_DATA_INSUFFICIENCY(pkt, LAYER_PROTO_IPV6);
return data;
}
uint8_t next_proto = ipv6_hdr_get_next_header(hdr);
uint8_t next_proto = ip6_hdr_get_next_header(hdr);
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;
@@ -786,17 +722,14 @@ static inline const char *parse_udp(struct packet *pkt, const char *data, uint16
if (dst_port == 2152 || src_port == 2152)
{
// TODO
// check V1 or V2
// GTP1U_PORT 2152
return parse_gtpv1_u(pkt, layer->pld_ptr, layer->pld_len);
// only GTPv1-U, no GTPv2-U
return parse_gtp_u(pkt, layer->pld_ptr, layer->pld_len);
}
if (dst_port == 2123 || src_port == 2123)
{
// TODO
// GTP-C - GTP control 2123
// GTPv1-C or GTPv2-C
return parse_gtp_c(pkt, layer->pld_ptr, layer->pld_len);
}
if (dst_port == 1701 || src_port == 1701)
@@ -826,7 +759,7 @@ static inline const char *parse_udp(struct packet *pkt, const char *data, uint16
return layer->pld_ptr;
}
const struct ip6_hdr *hdr = (const struct ip6_hdr *)layer->pld_ptr;
if (ipv6_hdr_get_version(hdr) != 6)
if (ip6_hdr_get_version(hdr) != 6)
{
return layer->pld_ptr;
}
@@ -914,12 +847,19 @@ static inline const char *parse_vxlan(struct packet *pkt, const char *data, uint
return parse_ether(pkt, layer->pld_ptr, layer->pld_len);
}
static inline const char *parse_gtpv1_u(struct packet *pkt, const char *data, uint16_t len)
static inline const char *parse_gtp_u(struct packet *pkt, const char *data, uint16_t len)
{
uint16_t hdr_len = get_gtp_hdr_len(data, len);
// only GTPv1-U, no GTPv2-U
uint8_t version = peek_gtp_version(data, len);
if (unlikely(version != 1))
{
return data;
}
uint16_t hdr_len = calc_gtp1_hdr_len(data, len);
if (unlikely(hdr_len == 0 || hdr_len > len))
{
PACKET_LOG_DATA_INSUFFICIENCY(pkt, LAYER_PROTO_GTP);
PACKET_LOG_DATA_INSUFFICIENCY(pkt, LAYER_PROTO_GTP_U);
return data;
}
@@ -929,7 +869,7 @@ static inline const char *parse_gtpv1_u(struct packet *pkt, const char *data, ui
return data;
}
uint8_t next_proto = (((const uint8_t *)(data + hdr_len))[0]) >> 4;
SET_LAYER(pkt, layer, LAYER_PROTO_GTP, hdr_len, data, len, 0);
SET_LAYER(pkt, layer, LAYER_PROTO_GTP_U, hdr_len, data, len, 0);
switch (next_proto)
{
@@ -938,11 +878,44 @@ static inline const char *parse_gtpv1_u(struct packet *pkt, const char *data, ui
case 6:
return parse_ipv6(pkt, layer->pld_ptr, layer->pld_len);
default:
PACKET_LOG_UNSUPPORT_PROTO(pkt, LAYER_PROTO_GTP, next_proto);
PACKET_LOG_UNSUPPORT_PROTO(pkt, LAYER_PROTO_GTP_U, next_proto);
return layer->pld_ptr;
}
}
static inline const char *parse_gtp_c(struct packet *pkt, const char *data, uint16_t len)
{
// GTPv1-C or GTPv2-C
uint16_t hdr_len = 0;
uint8_t version = peek_gtp_version(data, len);
switch (version)
{
case 1:
hdr_len = calc_gtp1_hdr_len(data, len);
break;
case 2:
hdr_len = calc_gtp2_hdr_len(data, len);
break;
default:
return data;
}
if (unlikely(hdr_len == 0 || hdr_len > len))
{
PACKET_LOG_DATA_INSUFFICIENCY(pkt, LAYER_PROTO_GTP_C);
return data;
}
struct raw_layer *layer = get_free_layer(pkt);
if (unlikely(layer == NULL))
{
return data;
}
SET_LAYER(pkt, layer, LAYER_PROTO_GTP_C, hdr_len, data, len, 0);
return layer->pld_ptr;
}
static inline const char *parse_l3(struct packet *pkt, uint16_t next_proto, const char *data, uint16_t len)
{
switch (next_proto)
@@ -1052,10 +1025,10 @@ void packet_print(const struct packet *pkt)
break;
break;
case LAYER_PROTO_IPV4:
used = ipv4_hdr_to_str((const struct ip *)layer->hdr_ptr, buffer, sizeof(buffer));
used = ip4_hdr_to_str((const struct ip *)layer->hdr_ptr, buffer, sizeof(buffer));
break;
case LAYER_PROTO_IPV6:
used = ipv6_hdr_to_str((const struct ip6_hdr *)layer->hdr_ptr, buffer, sizeof(buffer));
used = ip6_hdr_to_str((const struct ip6_hdr *)layer->hdr_ptr, buffer, sizeof(buffer));
break;
case LAYER_PROTO_IPAH:
break;
@@ -1075,7 +1048,16 @@ void packet_print(const struct packet *pkt)
case LAYER_PROTO_VXLAN:
used = vxlan_hdr_to_str((const struct vxlan_hdr *)layer->hdr_ptr, buffer, sizeof(buffer));
break;
case LAYER_PROTO_GTP:
case LAYER_PROTO_GTP_C:
case LAYER_PROTO_GTP_U:
if (peek_gtp_version(layer->hdr_ptr, layer->hdr_len) == 1)
{
used = gtp1_hdr_to_str((const struct gtp1_hdr *)layer->hdr_ptr, buffer, sizeof(buffer));
}
if (peek_gtp_version(layer->hdr_ptr, layer->hdr_len) == 2)
{
used = gtp2_hdr_to_str((const struct gtp2_hdr *)layer->hdr_ptr, buffer, sizeof(buffer));
}
break;
default:
break;

View File

@@ -49,7 +49,7 @@ static int is_gtp_tunnel(const struct raw_layer *curr, const struct raw_layer *n
{
if (curr && (curr->proto == LAYER_PROTO_IPV4 || curr->proto == LAYER_PROTO_IPV6) &&
next1 && next1->proto == LAYER_PROTO_UDP &&
next2 && next2->proto == LAYER_PROTO_GTP)
next2 && next2->proto == LAYER_PROTO_GTP_U)
{
return 1;
}

View File

@@ -4,8 +4,8 @@
#include "tuple.h"
#include "tcp_utils.h"
#include "udp_utils.h"
#include "ipv4_utils.h"
#include "ipv6_utils.h"
#include "ip4_utils.h"
#include "ip6_utils.h"
#include "packet_def.h"
#include "packet_utils.h"
@@ -145,16 +145,16 @@ int packet_get_innermost_tuple2(const struct packet *pkt, struct tuple2 *tuple)
{
const struct ip *ip4_hdr = (const struct ip *)layer->hdr_ptr;
tuple->ip_type = IP_TYPE_V4;
tuple->src_addr.v4 = ipv4_hdr_get_src_in_addr(ip4_hdr);
tuple->dst_addr.v4 = ipv4_hdr_get_dst_in_addr(ip4_hdr);
tuple->src_addr.v4 = ip4_hdr_get_src_in_addr(ip4_hdr);
tuple->dst_addr.v4 = ip4_hdr_get_dst_in_addr(ip4_hdr);
return 0;
}
if (layer->proto == LAYER_PROTO_IPV6)
{
const struct ip6_hdr *ip6_hdr = (const struct ip6_hdr *)layer->hdr_ptr;
tuple->ip_type = IP_TYPE_V6;
tuple->src_addr.v6 = ipv6_hdr_get_src_in6_addr(ip6_hdr);
tuple->dst_addr.v6 = ipv6_hdr_get_dst_in6_addr(ip6_hdr);
tuple->src_addr.v6 = ip6_hdr_get_src_in6_addr(ip6_hdr);
tuple->dst_addr.v6 = ip6_hdr_get_dst_in6_addr(ip6_hdr);
return 0;
}
}
@@ -177,16 +177,16 @@ int packet_get_outermost_tuple2(const struct packet *pkt, struct tuple2 *tuple)
{
const struct ip *ip4_hdr = (const struct ip *)layer->hdr_ptr;
tuple->ip_type = IP_TYPE_V4;
tuple->src_addr.v4 = ipv4_hdr_get_src_in_addr(ip4_hdr);
tuple->dst_addr.v4 = ipv4_hdr_get_dst_in_addr(ip4_hdr);
tuple->src_addr.v4 = ip4_hdr_get_src_in_addr(ip4_hdr);
tuple->dst_addr.v4 = ip4_hdr_get_dst_in_addr(ip4_hdr);
return 0;
}
if (layer->proto == LAYER_PROTO_IPV6)
{
const struct ip6_hdr *ip6_hdr = (const struct ip6_hdr *)layer->hdr_ptr;
tuple->ip_type = IP_TYPE_V6;
tuple->src_addr.v6 = ipv6_hdr_get_src_in6_addr(ip6_hdr);
tuple->dst_addr.v6 = ipv6_hdr_get_dst_in6_addr(ip6_hdr);
tuple->src_addr.v6 = ip6_hdr_get_src_in6_addr(ip6_hdr);
tuple->dst_addr.v6 = ip6_hdr_get_dst_in6_addr(ip6_hdr);
return 0;
}
}
@@ -230,8 +230,8 @@ int packet_get_innermost_tuple4(const struct packet *pkt, struct tuple4 *tuple)
{
const struct ip *ip4_hdr = (const struct ip *)layer->hdr_ptr;
tuple->ip_type = IP_TYPE_V4;
tuple->src_addr.v4 = ipv4_hdr_get_src_in_addr(ip4_hdr);
tuple->dst_addr.v4 = ipv4_hdr_get_dst_in_addr(ip4_hdr);
tuple->src_addr.v4 = ip4_hdr_get_src_in_addr(ip4_hdr);
tuple->dst_addr.v4 = ip4_hdr_get_dst_in_addr(ip4_hdr);
layer_l3 = layer;
break;
}
@@ -239,8 +239,8 @@ int packet_get_innermost_tuple4(const struct packet *pkt, struct tuple4 *tuple)
{
const struct ip6_hdr *ip6_hdr = (const struct ip6_hdr *)layer->hdr_ptr;
tuple->ip_type = IP_TYPE_V6;
tuple->src_addr.v6 = ipv6_hdr_get_src_in6_addr(ip6_hdr);
tuple->dst_addr.v6 = ipv6_hdr_get_dst_in6_addr(ip6_hdr);
tuple->src_addr.v6 = ip6_hdr_get_src_in6_addr(ip6_hdr);
tuple->dst_addr.v6 = ip6_hdr_get_dst_in6_addr(ip6_hdr);
layer_l3 = layer;
break;
}
@@ -274,8 +274,8 @@ int packet_get_outermost_tuple4(const struct packet *pkt, struct tuple4 *tuple)
{
const struct ip *ip4_hdr = (const struct ip *)layer->hdr_ptr;
tuple->ip_type = IP_TYPE_V4;
tuple->src_addr.v4 = ipv4_hdr_get_src_in_addr(ip4_hdr);
tuple->dst_addr.v4 = ipv4_hdr_get_dst_in_addr(ip4_hdr);
tuple->src_addr.v4 = ip4_hdr_get_src_in_addr(ip4_hdr);
tuple->dst_addr.v4 = ip4_hdr_get_dst_in_addr(ip4_hdr);
layer_l3 = layer;
continue;
}
@@ -283,8 +283,8 @@ int packet_get_outermost_tuple4(const struct packet *pkt, struct tuple4 *tuple)
{
const struct ip6_hdr *ip6_hdr = (const struct ip6_hdr *)layer->hdr_ptr;
tuple->ip_type = IP_TYPE_V6;
tuple->src_addr.v6 = ipv6_hdr_get_src_in6_addr(ip6_hdr);
tuple->dst_addr.v6 = ipv6_hdr_get_dst_in6_addr(ip6_hdr);
tuple->src_addr.v6 = ip6_hdr_get_src_in6_addr(ip6_hdr);
tuple->dst_addr.v6 = ip6_hdr_get_dst_in6_addr(ip6_hdr);
layer_l3 = layer;
continue;
}
@@ -356,8 +356,8 @@ int packet_get_innermost_tuple6(const struct packet *pkt, struct tuple6 *tuple)
{
const struct ip *ip4_hdr = (const struct ip *)layer->hdr_ptr;
tuple->ip_type = IP_TYPE_V4;
tuple->src_addr.v4 = ipv4_hdr_get_src_in_addr(ip4_hdr);
tuple->dst_addr.v4 = ipv4_hdr_get_dst_in_addr(ip4_hdr);
tuple->src_addr.v4 = ip4_hdr_get_src_in_addr(ip4_hdr);
tuple->dst_addr.v4 = ip4_hdr_get_dst_in_addr(ip4_hdr);
layer_l3 = layer;
break;
}
@@ -365,8 +365,8 @@ int packet_get_innermost_tuple6(const struct packet *pkt, struct tuple6 *tuple)
{
const struct ip6_hdr *ip6_hdr = (const struct ip6_hdr *)layer->hdr_ptr;
tuple->ip_type = IP_TYPE_V6;
tuple->src_addr.v6 = ipv6_hdr_get_src_in6_addr(ip6_hdr);
tuple->dst_addr.v6 = ipv6_hdr_get_dst_in6_addr(ip6_hdr);
tuple->src_addr.v6 = ip6_hdr_get_src_in6_addr(ip6_hdr);
tuple->dst_addr.v6 = ip6_hdr_get_dst_in6_addr(ip6_hdr);
layer_l3 = layer;
break;
}
@@ -401,8 +401,8 @@ int packet_get_outermost_tuple6(const struct packet *pkt, struct tuple6 *tuple)
{
const struct ip *ip4_hdr = (const struct ip *)layer->hdr_ptr;
tuple->ip_type = IP_TYPE_V4;
tuple->src_addr.v4 = ipv4_hdr_get_src_in_addr(ip4_hdr);
tuple->dst_addr.v4 = ipv4_hdr_get_dst_in_addr(ip4_hdr);
tuple->src_addr.v4 = ip4_hdr_get_src_in_addr(ip4_hdr);
tuple->dst_addr.v4 = ip4_hdr_get_dst_in_addr(ip4_hdr);
layer_l3 = layer;
continue;
}
@@ -410,8 +410,8 @@ int packet_get_outermost_tuple6(const struct packet *pkt, struct tuple6 *tuple)
{
const struct ip6_hdr *ip6_hdr = (const struct ip6_hdr *)layer->hdr_ptr;
tuple->ip_type = IP_TYPE_V6;
tuple->src_addr.v6 = ipv6_hdr_get_src_in6_addr(ip6_hdr);
tuple->dst_addr.v6 = ipv6_hdr_get_dst_in6_addr(ip6_hdr);
tuple->src_addr.v6 = ip6_hdr_get_src_in6_addr(ip6_hdr);
tuple->dst_addr.v6 = ip6_hdr_get_dst_in6_addr(ip6_hdr);
layer_l3 = layer;
continue;
}

View File

@@ -7,11 +7,11 @@ target_link_libraries(gtest_udp_utils packet gtest)
add_executable(gtest_tcp_utils gtest_tcp_utils.cpp)
target_link_libraries(gtest_tcp_utils packet gtest)
add_executable(gtest_ipv4_utils gtest_ipv4_utils.cpp)
target_link_libraries(gtest_ipv4_utils packet gtest)
add_executable(gtest_ip4_utils gtest_ip4_utils.cpp)
target_link_libraries(gtest_ip4_utils packet gtest)
add_executable(gtest_ipv6_utils gtest_ipv6_utils.cpp)
target_link_libraries(gtest_ipv6_utils packet gtest)
add_executable(gtest_ip6_utils gtest_ip6_utils.cpp)
target_link_libraries(gtest_ip6_utils packet gtest)
add_executable(gtest_mpls_utils gtest_mpls_utils.cpp)
target_link_libraries(gtest_mpls_utils packet gtest)
@@ -31,6 +31,12 @@ target_link_libraries(gtest_gre_utils packet gtest)
add_executable(gtest_l2tp_utils gtest_l2tp_utils.cpp)
target_link_libraries(gtest_l2tp_utils packet gtest)
add_executable(gtest_gtp1_utils gtest_gtp1_utils.cpp)
target_link_libraries(gtest_gtp1_utils packet gtest)
add_executable(gtest_gtp2_utils gtest_gtp2_utils.cpp)
target_link_libraries(gtest_gtp2_utils packet gtest)
add_executable(gtest_packet_frag gtest_packet_frag.cpp)
target_link_libraries(gtest_packet_frag packet gtest)
@@ -47,14 +53,16 @@ include(GoogleTest)
gtest_discover_tests(gtest_tunnel)
gtest_discover_tests(gtest_udp_utils)
gtest_discover_tests(gtest_tcp_utils)
gtest_discover_tests(gtest_ipv4_utils)
gtest_discover_tests(gtest_ipv6_utils)
gtest_discover_tests(gtest_ip4_utils)
gtest_discover_tests(gtest_ip6_utils)
gtest_discover_tests(gtest_mpls_utils)
gtest_discover_tests(gtest_eth_utils)
gtest_discover_tests(gtest_vlan_utils)
gtest_discover_tests(gtest_vxlan_utils)
gtest_discover_tests(gtest_gre_utils)
gtest_discover_tests(gtest_l2tp_utils)
gtest_discover_tests(gtest_gtp1_utils)
gtest_discover_tests(gtest_gtp2_utils)
gtest_discover_tests(gtest_packet_frag)
gtest_discover_tests(gtest_packet_parse)
gtest_discover_tests(gtest_packet_build)

View File

@@ -0,0 +1,243 @@
#include <gtest/gtest.h>
#include "gtp1_utils.h"
/*
* User Datagram Protocol, Src Port: 2123, Dst Port: 2123
* GPRS Tunneling Protocol
* Flags: 0x32
* 001. .... = Version: GTP release 99 version (1)
* ...1 .... = Protocol type: GTP (1)
* .... 0... = Reserved: 0
* .... .0.. = Is Next Extension Header present?: No
* .... ..1. = Is Sequence Number present?: Yes
* .... ...0 = Is N-PDU number present?: No
* Message Type: Create PDP context request (0x10)
* Length: 151
* TEID: 0x00000000 (0)
* Sequence number: 0x00fe (254)
* IMSI: 27203
* [Association IMSI: 27203]
* Mobile Country Code (MCC): Ireland (272)
* Mobile Network Code (MNC): Eircom Ltd (03)
* Routing Area Identity
* Mobile Country Code (MCC): Ireland (272)
* Mobile Network Code (MNC): Eircom Ltd (03)
* Location Area Code (LAC): 65534
* Routing Area Code (RAC): 255
* Recovery: 93
* Selection mode: MS or network provided APN, subscribed verified
* .... ..00 = Selection mode: MS or network provided APN, subscribed verified (0)
* TEID Data I: 0x372f0000 (925827072)
* TEID Control Plane: 0x372f0000 (925827072)
* NSAPI: 5
* .... 0101 = NSAPI: 5
* End user address (IETF/IPv4)
* Length: 2
* PDP type organization: IETF (1)
* PDP type number: IPv4 (0x21)
* Access Point Name: mms.mymeteor.ie
* APN length: 16
* APN: mms.mymeteor.ie
* Protocol configuration options
* Length: 34
* [Link direction: MS to network (0)]
* 1... .... = Extension: True
* .... .000 = Configuration Protocol: PPP for use with IP PDP type or IP PDN type (0)
* Protocol or Container ID: Password Authentication Protocol (0xc023)
* Length: 0x0b (11)
* PPP Password Authentication Protocol
* Code: Authenticate-Request (1)
* Identifier: 0
* Length: 11
* Data
* Peer-ID-Length: 2
* Peer-ID: my
* Password-Length: 3
* Password: wap
* Protocol or Container ID: Internet Protocol Control Protocol (0x8021)
* Length: 0x10 (16)
* PPP IP Control Protocol
* Code: Configuration Request (1)
* Identifier: 0 (0x00)
* Length: 16
* Options: (12 bytes), Primary DNS Server IP Address, Secondary DNS Server IP Address
* Primary DNS Server IP Address
* Type: Primary DNS Server IP Address (129)
* Length: 6
* Primary DNS Address: 0.0.0.0
* Secondary DNS Server IP Address
* Type: Secondary DNS Server IP Address (131)
* Length: 6
* Secondary DNS Address: 0.0.0.0
* GSN address : 212.129.65.13
* GSN address length: 4
* GSN address IPv4: 212.129.65.13
* GSN address : 212.129.65.23
* GSN address length: 4
* GSN address IPv4: 212.129.65.23
* MS international PSTN/ISDN number
* Length: 7
* 1... .... = Extension: No Extension
* .001 .... = Nature of number: International Number (0x1)
* .... 0001 = Number plan: ISDN/Telephony Numbering (Rec ITU-T E.164) (0x1)
* E.164 number (MSISDN): 353800000000
* Country Code: Ireland (353)
* Quality of Service
* Length: 12
* Allocation/Retention priority: 2
* 00.. .... = Spare: 0
* ..10 0... = QoS delay: Delay class 4 (best effort) (4)
* .... .011 = QoS reliability: Unacknowledged GTP/LLC, Ack RLC, Protected data (3)
* 0110 .... = QoS peak: Up to 32 000 oct/s (6)
* .... 0... = Spare: 0
* .... .010 = QoS precedence: Normal priority (2)
* 000. .... = Spare: 0
* ...1 1111 = QoS mean: Best effort (31)
* 100. .... = Traffic class: Background class (4)
* ...1 0... = Delivery order: Without delivery order ('no') (2)
* .... .011 = Delivery of erroneous SDU: Erroneous SDUs are not delivered ('no') (3)
* Maximum SDU size: 1500 octets
* Maximum bit rate for uplink: 256 kbps
* Maximum bit rate for downlink: 256 kbps
* 0111 .... = Residual BER: 1/100 000 = 1x10^-5 (7)
* .... 0100 = SDU Error ratio: 1/10 000 = 1x10^-4 (4)
* 1111 10.. = Transfer delay: 4000 ms (62)
* .... ..11 = Traffic handling priority: Priority level 3 (3)
* Guaranteed bit rate for uplink: 0 kbps (255)
* Guaranteed bit rate for downlink: 0 kbps (255)
* RAT Type: GERAN
* Length: 1
* RAT Type: GERAN (2)
* IMEI(SV): 3598100185893512
* Length: 8
* IMEI(SV): 3598100185893512
* [Response In: 2]
*/
unsigned char gtp1_c[] = {
0x32, 0x10, 0x00, 0x97, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x02, 0x72, 0x02, 0xf3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0x72, 0xf2, 0x30, 0xff,
0xfe, 0xff, 0x0e, 0x5d, 0x0f, 0xfc, 0x10, 0x37, 0x2f, 0x00, 0x00, 0x11, 0x37, 0x2f, 0x00, 0x00, 0x14, 0x05, 0x80, 0x00, 0x02, 0xf1, 0x21, 0x83, 0x00, 0x10,
0x03, 0x6d, 0x6d, 0x73, 0x08, 0x6d, 0x79, 0x6d, 0x65, 0x74, 0x65, 0x6f, 0x72, 0x02, 0x69, 0x65, 0x84, 0x00, 0x22, 0x80, 0xc0, 0x23, 0x0b, 0x01, 0x00, 0x00,
0x0b, 0x02, 0x6d, 0x79, 0x03, 0x77, 0x61, 0x70, 0x80, 0x21, 0x10, 0x01, 0x00, 0x00, 0x10, 0x81, 0x06, 0x00, 0x00, 0x00, 0x00, 0x83, 0x06, 0x00, 0x00, 0x00,
0x00, 0x85, 0x00, 0x04, 0xd4, 0x81, 0x41, 0x0d, 0x85, 0x00, 0x04, 0xd4, 0x81, 0x41, 0x17, 0x86, 0x00, 0x07, 0x91, 0x53, 0x83, 0x00, 0x00, 0x00, 0x00, 0x87,
0x00, 0x0c, 0x02, 0x23, 0x62, 0x1f, 0x93, 0x96, 0x58, 0x58, 0x74, 0xfb, 0xff, 0xff, 0x97, 0x00, 0x01, 0x02, 0x9a, 0x00, 0x08, 0x53, 0x89, 0x01, 0x10, 0x58,
0x98, 0x53, 0x21};
TEST(GTP1_UTILS, C_GET)
{
const struct gtp1_hdr *hdr = (struct gtp1_hdr *)gtp1_c;
// GTP Fixed Header Length + GTPv1-C Optional Headers + GTPv1-C Extension Headers
EXPECT_TRUE(calc_gtp1_hdr_len((const char *)gtp1_c, sizeof(gtp1_c)) == 12);
EXPECT_TRUE(gtp1_hdr_get_flags(hdr) == 0x32);
EXPECT_TRUE(gtp1_hdr_get_version(hdr) == 1);
EXPECT_TRUE(gtp1_hdr_get_protocol(hdr) == 1);
EXPECT_TRUE(gtp1_hdr_get_reserved(hdr) == 0);
EXPECT_TRUE(gtp1_hdr_get_ext_flag(hdr) == 0);
EXPECT_TRUE(gtp1_hdr_get_seq_flag(hdr) == 1);
EXPECT_TRUE(gtp1_hdr_get_npdu_flag(hdr) == 0);
EXPECT_TRUE(gtp1_hdr_get_msg_type(hdr) == 0x10);
EXPECT_TRUE(gtp1_hdr_get_msg_len(hdr) == 151);
EXPECT_TRUE(gtp1_hdr_get_teid(hdr) == 0);
EXPECT_TRUE(gtp1_hdr_get_seq(hdr) == 254);
EXPECT_TRUE(gtp1_hdr_get_npdu(hdr) == 0);
EXPECT_TRUE(gtp1_hdr_get_next_ext_type(hdr) == 0);
char buff[1024] = {0};
gtp1_hdr_to_str(hdr, buff, sizeof(buff));
printf("%s\n", buff);
}
TEST(GTP1_UTILS, C_SET)
{
char buff[12] = {0};
struct gtp1_hdr *hdr = (struct gtp1_hdr *)buff;
gtp1_hdr_set_flags(hdr, 0x32);
gtp1_hdr_set_version(hdr, 1);
gtp1_hdr_set_protocol(hdr, 1);
gtp1_hdr_set_reserved(hdr, 0);
gtp1_hdr_set_ext_flag(hdr, 0);
gtp1_hdr_set_seq_flag(hdr, 1);
gtp1_hdr_set_npdu_flag(hdr, 0);
gtp1_hdr_set_msg_type(hdr, 0x10);
gtp1_hdr_set_msg_len(hdr, 151);
gtp1_hdr_set_teid(hdr, 0);
gtp1_hdr_set_seq(hdr, 254);
gtp1_hdr_set_npdu(hdr, 0);
gtp1_hdr_set_next_ext_type(hdr, 0);
EXPECT_TRUE(memcmp(buff, gtp1_c, 12) == 0);
}
/*
* User Datagram Protocol, Src Port: 2152, Dst Port: 2152
* GPRS Tunneling Protocol
* Flags: 0x30
* 001. .... = Version: GTP release 99 version (1)
* ...1 .... = Protocol type: GTP (1)
* .... 0... = Reserved: 0
* .... .0.. = Is Next Extension Header present?: No
* .... ..0. = Is Sequence Number present?: No
* .... ...0 = Is N-PDU number present?: No
* Message Type: T-PDU (0xff)
* Length: 40
* TEID: 0x001e849a (2000026)
*/
unsigned char gtp1_u[] = {
0x30, 0xff, 0x00, 0x28, 0x00, 0x1e, 0x84, 0x9a};
TEST(GTP1_UTILS, U_GET)
{
const struct gtp1_hdr *hdr = (struct gtp1_hdr *)gtp1_u;
// GTP Fixed Header Length + GTPv1-U Optional Headers + GTPv1-U Extension Headers
EXPECT_TRUE(calc_gtp1_hdr_len((const char *)gtp1_u, sizeof(gtp1_u)) == 8);
EXPECT_TRUE(gtp1_hdr_get_flags(hdr) == 0x30);
EXPECT_TRUE(gtp1_hdr_get_version(hdr) == 1);
EXPECT_TRUE(gtp1_hdr_get_protocol(hdr) == 1);
EXPECT_TRUE(gtp1_hdr_get_reserved(hdr) == 0);
EXPECT_TRUE(gtp1_hdr_get_ext_flag(hdr) == 0);
EXPECT_TRUE(gtp1_hdr_get_seq_flag(hdr) == 0);
EXPECT_TRUE(gtp1_hdr_get_npdu_flag(hdr) == 0);
EXPECT_TRUE(gtp1_hdr_get_msg_type(hdr) == 0xff);
EXPECT_TRUE(gtp1_hdr_get_msg_len(hdr) == 40);
EXPECT_TRUE(gtp1_hdr_get_teid(hdr) == 2000026);
EXPECT_TRUE(gtp1_hdr_get_seq(hdr) == 0);
EXPECT_TRUE(gtp1_hdr_get_npdu(hdr) == 0);
EXPECT_TRUE(gtp1_hdr_get_next_ext_type(hdr) == 0);
char buff[1024] = {0};
gtp1_hdr_to_str(hdr, buff, sizeof(buff));
printf("%s\n", buff);
}
TEST(GTP1_UTILS, U_SET)
{
char buff[8] = {0};
struct gtp1_hdr *hdr = (struct gtp1_hdr *)buff;
gtp1_hdr_set_flags(hdr, 0x30);
gtp1_hdr_set_version(hdr, 1);
gtp1_hdr_set_protocol(hdr, 1);
gtp1_hdr_set_reserved(hdr, 0);
gtp1_hdr_set_ext_flag(hdr, 0);
gtp1_hdr_set_seq_flag(hdr, 0);
gtp1_hdr_set_npdu_flag(hdr, 0);
gtp1_hdr_set_msg_type(hdr, 0xff);
gtp1_hdr_set_msg_len(hdr, 40);
gtp1_hdr_set_teid(hdr, 2000026);
gtp1_hdr_set_seq(hdr, 0);
gtp1_hdr_set_npdu(hdr, 0);
gtp1_hdr_set_next_ext_type(hdr, 0);
EXPECT_TRUE(memcmp(buff, gtp1_u, 8) == 0);
}
int main(int argc, char **argv)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@@ -0,0 +1,150 @@
#include <gtest/gtest.h>
#include "gtp2_utils.h"
/*
* User Datagram Protocol, Src Port: 2123, Dst Port: 12491
* GPRS Tunneling Protocol V2
* Flags: 0x48
* 010. .... = Version: 2
* ...0 .... = Piggybacking flag (P): 0
* .... 1... = TEID flag (T): 1
* .... .0.. = Message Priority(MP): 0
* Message Type: Delete Session Response (37)
* Message Length: 19
* Tunnel Endpoint Identifier: 0x0e05cd4d (235261261)
* Sequence Number: 0x000ce7 (3303)
* Spare: 0
* Cause : Request accepted (16)
* IE Type: Cause (2)
* IE Length: 2
* 0000 .... = CR flag: 0
* .... 0000 = Instance: 0
* Cause: Request accepted (16)
* 0000 0... = Spare bit(s): 0
* .... .0.. = PCE (PDN Connection IE Error): False
* .... ..0. = BCE (Bearer Context IE Error): False
* .... ...0 = CS (Cause Source): Originated by node sending the message
* Recovery (Restart Counter) : 13
* IE Type: Recovery (Restart Counter) (3)
* IE Length: 1
* 0000 .... = CR flag: 0
* .... 0000 = Instance: 0
* Restart Counter: 13
*/
unsigned char gtp2_c_pkt1[] = {
0x48, 0x25, 0x00, 0x13, 0x0e, 0x05, 0xcd, 0x4d, 0x00, 0x0c, 0xe7, 0x00, 0x02, 0x00, 0x02, 0x00, 0x10, 0x00, 0x03, 0x00, 0x01, 0x00, 0x0d};
// have teid
TEST(GTP2_UTILS, C_GET1)
{
const struct gtp2_hdr *hdr = (struct gtp2_hdr *)gtp2_c_pkt1;
EXPECT_TRUE(calc_gtp2_hdr_len((const char *)gtp2_c_pkt1, sizeof(gtp2_c_pkt1)) == 12);
EXPECT_TRUE(gtp2_hdr_get_flags(hdr) == 0x48);
EXPECT_TRUE(gtp2_hdr_get_version(hdr) == 2);
EXPECT_TRUE(gtp2_hdr_get_piggyback_flag(hdr) == 0);
EXPECT_TRUE(gtp2_hdr_get_teid_flag(hdr) == 1);
EXPECT_TRUE(gtp2_hdr_get_spare_flag(hdr) == 0);
EXPECT_TRUE(gtp2_hdr_get_msg_type(hdr) == 37);
EXPECT_TRUE(gtp2_hdr_get_msg_len(hdr) == 19);
EXPECT_TRUE(gtp2_hdr_get_teid(hdr) == 0x0e05cd4d);
EXPECT_TRUE(gtp2_hdr_get_seq(hdr) == 0x000ce7);
EXPECT_TRUE(gtp2_hdr_get_spare(hdr) == 0);
char buff[1024] = {0};
gtp2_hdr_to_str(hdr, buff, sizeof(buff));
printf("%s\n", buff);
}
TEST(GTP2_UTILS, C_SET1)
{
char buff[12] = {0};
struct gtp2_hdr *hdr = (struct gtp2_hdr *)buff;
gtp2_hdr_set_flags(hdr, 0x48);
gtp2_hdr_set_version(hdr, 2);
gtp2_hdr_set_piggyback_flag(hdr, 0);
gtp2_hdr_set_teid_flag(hdr, 1);
gtp2_hdr_set_spare_flag(hdr, 0);
gtp2_hdr_set_msg_type(hdr, 37);
gtp2_hdr_set_msg_len(hdr, 19);
gtp2_hdr_set_teid(hdr, 0x0e05cd4d);
gtp2_hdr_set_seq(hdr, 0x000ce7);
gtp2_hdr_set_spare(hdr, 0);
EXPECT_TRUE(memcmp(buff, gtp2_c_pkt1, 12) == 0);
}
/*
* User Datagram Protocol, Src Port: 2123, Dst Port: 2123
* GPRS Tunneling Protocol V2
* Flags: 0x40
* 010. .... = Version: 2
* ...0 .... = Piggybacking flag (P): 0
* .... 0... = TEID flag (T): 0
* .... .0.. = Message Priority(MP): 0
* Message Type: Echo Request (1)
* Message Length: 9
* Sequence Number: 0x0041d4 (16852)
* Spare: 0
* Recovery (Restart Counter) : 5
* IE Type: Recovery (Restart Counter) (3)
* IE Length: 1
* 0000 .... = CR flag: 0
* .... 0000 = Instance: 0
* Restart Counter: 5
*/
unsigned char gtp2_c_pkt2[] = {
0x40, 0x01, 0x00, 0x09, 0x00, 0x41, 0xd4, 0x00, 0x03, 0x00, 0x01, 0x00, 0x05};
// no teid
TEST(GTP2_UTILS, C_GET2)
{
const struct gtp2_hdr *hdr = (struct gtp2_hdr *)gtp2_c_pkt2;
EXPECT_TRUE(calc_gtp2_hdr_len((const char *)gtp2_c_pkt2, sizeof(gtp2_c_pkt2)) == 8);
EXPECT_TRUE(gtp2_hdr_get_flags(hdr) == 0x40);
EXPECT_TRUE(gtp2_hdr_get_version(hdr) == 2);
EXPECT_TRUE(gtp2_hdr_get_piggyback_flag(hdr) == 0);
EXPECT_TRUE(gtp2_hdr_get_teid_flag(hdr) == 0);
EXPECT_TRUE(gtp2_hdr_get_spare_flag(hdr) == 0);
EXPECT_TRUE(gtp2_hdr_get_msg_type(hdr) == 1);
EXPECT_TRUE(gtp2_hdr_get_msg_len(hdr) == 9);
EXPECT_TRUE(gtp2_hdr_get_teid(hdr) == 0);
EXPECT_TRUE(gtp2_hdr_get_seq(hdr) == 0x0041d4);
EXPECT_TRUE(gtp2_hdr_get_spare(hdr) == 0);
char buff[1024] = {0};
gtp2_hdr_to_str(hdr, buff, sizeof(buff));
printf("%s\n", buff);
}
TEST(GTP2_UTILS, C_SET2)
{
char buff[8] = {0};
struct gtp2_hdr *hdr = (struct gtp2_hdr *)buff;
gtp2_hdr_set_flags(hdr, 0x40);
gtp2_hdr_set_version(hdr, 2);
gtp2_hdr_set_piggyback_flag(hdr, 0);
gtp2_hdr_set_teid_flag(hdr, 0);
gtp2_hdr_set_spare_flag(hdr, 0);
gtp2_hdr_set_msg_type(hdr, 1);
gtp2_hdr_set_msg_len(hdr, 9);
gtp2_hdr_set_teid(hdr, 0);
gtp2_hdr_set_seq(hdr, 0x0041d4);
gtp2_hdr_set_spare(hdr, 0);
EXPECT_TRUE(memcmp(buff, gtp2_c_pkt2, 8) == 0);
}
int main(int argc, char **argv)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@@ -1,6 +1,6 @@
#include <gtest/gtest.h>
#include "ipv4_utils.h"
#include "ip4_utils.h"
/******************************************************************************
* more fragment
@@ -36,23 +36,23 @@ unsigned char data1[] = {0x45, 0x00, 0x00, 0x2c, 0xff, 0xff, 0x20, 0x00, 0x7f, 0
TEST(IPV4_UTILS, GET1)
{
const struct ip *hdr = (struct ip *)data1;
EXPECT_TRUE(ipv4_hdr_get_version(hdr) == 4);
EXPECT_TRUE(ipv4_hdr_get_hdr_len(hdr) == 20);
EXPECT_TRUE(ipv4_hdr_get_tos(hdr) == 0);
EXPECT_TRUE(ipv4_hdr_get_total_len(hdr) == 44);
EXPECT_TRUE(ipv4_hdr_get_ipid(hdr) == 65535);
EXPECT_TRUE(ipv4_hdr_get_flags(hdr) == 1);
EXPECT_TRUE(ipv4_hdr_get_rf_flag(hdr) == false);
EXPECT_TRUE(ipv4_hdr_get_df_flag(hdr) == false);
EXPECT_TRUE(ipv4_hdr_get_mf_flag(hdr) == true);
EXPECT_TRUE(ipv4_hdr_get_frag_offset(hdr) == 0);
EXPECT_TRUE(ipv4_hdr_get_ttl(hdr) == 127);
EXPECT_TRUE(ipv4_hdr_get_proto(hdr) == 6);
EXPECT_TRUE(ipv4_hdr_get_checksum(hdr) == 0x4d8b);
EXPECT_TRUE(ipv4_hdr_get_src_addr(hdr) == 0xc0a82467);
EXPECT_TRUE(ipv4_hdr_get_dst_addr(hdr) == 0xc0a82889);
EXPECT_TRUE(ipv4_hdr_get_opt_len(hdr) == 0);
EXPECT_TRUE(ipv4_hdr_get_opt_data(hdr) == NULL);
EXPECT_TRUE(ip4_hdr_get_version(hdr) == 4);
EXPECT_TRUE(ip4_hdr_get_hdr_len(hdr) == 20);
EXPECT_TRUE(ip4_hdr_get_tos(hdr) == 0);
EXPECT_TRUE(ip4_hdr_get_total_len(hdr) == 44);
EXPECT_TRUE(ip4_hdr_get_ipid(hdr) == 65535);
EXPECT_TRUE(ip4_hdr_get_flags(hdr) == 1);
EXPECT_TRUE(ip4_hdr_get_rf_flag(hdr) == false);
EXPECT_TRUE(ip4_hdr_get_df_flag(hdr) == false);
EXPECT_TRUE(ip4_hdr_get_mf_flag(hdr) == true);
EXPECT_TRUE(ip4_hdr_get_frag_offset(hdr) == 0);
EXPECT_TRUE(ip4_hdr_get_ttl(hdr) == 127);
EXPECT_TRUE(ip4_hdr_get_proto(hdr) == 6);
EXPECT_TRUE(ip4_hdr_get_checksum(hdr) == 0x4d8b);
EXPECT_TRUE(ip4_hdr_get_src_addr(hdr) == 0xc0a82467);
EXPECT_TRUE(ip4_hdr_get_dst_addr(hdr) == 0xc0a82889);
EXPECT_TRUE(ip4_hdr_get_opt_len(hdr) == 0);
EXPECT_TRUE(ip4_hdr_get_opt_data(hdr) == NULL);
}
TEST(IPV4_UTILS, SET1)
@@ -60,26 +60,26 @@ TEST(IPV4_UTILS, SET1)
char buff[20] = {0};
struct ip *hdr = (struct ip *)buff;
ipv4_hdr_set_version(hdr, 4);
ipv4_hdr_set_hdr_len(hdr, 20);
ipv4_hdr_set_tos(hdr, 0);
ipv4_hdr_set_total_len(hdr, 44);
ipv4_hdr_set_ipid(hdr, 65535);
ipv4_hdr_set_frag_offset(hdr, 0);
ipv4_hdr_set_ttl(hdr, 127);
ipv4_hdr_set_protocol(hdr, 6);
ipv4_hdr_set_checksum(hdr, 0x4d8b);
ipv4_hdr_set_src_addr(hdr, 0xc0a82467);
ipv4_hdr_set_dst_addr(hdr, 0xc0a82889);
ipv4_hdr_set_opt_len(hdr, 0);
ipv4_hdr_set_opt_data(hdr, NULL);
ip4_hdr_set_version(hdr, 4);
ip4_hdr_set_hdr_len(hdr, 20);
ip4_hdr_set_tos(hdr, 0);
ip4_hdr_set_total_len(hdr, 44);
ip4_hdr_set_ipid(hdr, 65535);
ip4_hdr_set_frag_offset(hdr, 0);
ip4_hdr_set_ttl(hdr, 127);
ip4_hdr_set_protocol(hdr, 6);
ip4_hdr_set_checksum(hdr, 0x4d8b);
ip4_hdr_set_src_addr(hdr, 0xc0a82467);
ip4_hdr_set_dst_addr(hdr, 0xc0a82889);
ip4_hdr_set_opt_len(hdr, 0);
ip4_hdr_set_opt_data(hdr, NULL);
ipv4_hdr_set_flags(hdr, 1);
ip4_hdr_set_flags(hdr, 1);
EXPECT_TRUE(memcmp(buff, data1, 20) == 0);
ipv4_hdr_set_rf_flag(hdr, false);
ipv4_hdr_set_df_flag(hdr, false);
ipv4_hdr_set_mf_flag(hdr, true);
ip4_hdr_set_rf_flag(hdr, false);
ip4_hdr_set_df_flag(hdr, false);
ip4_hdr_set_mf_flag(hdr, true);
EXPECT_TRUE(memcmp(buff, data1, 20) == 0);
}
@@ -127,23 +127,23 @@ unsigned char data2[] = {0x45, 0x00, 0x00, 0x2c, 0xff, 0xff, 0x00, 0x03, 0x7f, 0
TEST(IPV4_UTILS, GET2)
{
const struct ip *hdr = (struct ip *)data2;
EXPECT_TRUE(ipv4_hdr_get_version(hdr) == 4);
EXPECT_TRUE(ipv4_hdr_get_hdr_len(hdr) == 20);
EXPECT_TRUE(ipv4_hdr_get_tos(hdr) == 0);
EXPECT_TRUE(ipv4_hdr_get_total_len(hdr) == 44);
EXPECT_TRUE(ipv4_hdr_get_ipid(hdr) == 65535);
EXPECT_TRUE(ipv4_hdr_get_flags(hdr) == 0);
EXPECT_TRUE(ipv4_hdr_get_rf_flag(hdr) == false);
EXPECT_TRUE(ipv4_hdr_get_df_flag(hdr) == false);
EXPECT_TRUE(ipv4_hdr_get_mf_flag(hdr) == false);
EXPECT_TRUE(ipv4_hdr_get_frag_offset(hdr) == 24);
EXPECT_TRUE(ipv4_hdr_get_ttl(hdr) == 127);
EXPECT_TRUE(ipv4_hdr_get_proto(hdr) == 6);
EXPECT_TRUE(ipv4_hdr_get_checksum(hdr) == 0x6d88);
EXPECT_TRUE(ipv4_hdr_get_src_addr(hdr) == 0xc0a82467);
EXPECT_TRUE(ipv4_hdr_get_dst_addr(hdr) == 0xc0a82889);
EXPECT_TRUE(ipv4_hdr_get_opt_len(hdr) == 0);
EXPECT_TRUE(ipv4_hdr_get_opt_data(hdr) == NULL);
EXPECT_TRUE(ip4_hdr_get_version(hdr) == 4);
EXPECT_TRUE(ip4_hdr_get_hdr_len(hdr) == 20);
EXPECT_TRUE(ip4_hdr_get_tos(hdr) == 0);
EXPECT_TRUE(ip4_hdr_get_total_len(hdr) == 44);
EXPECT_TRUE(ip4_hdr_get_ipid(hdr) == 65535);
EXPECT_TRUE(ip4_hdr_get_flags(hdr) == 0);
EXPECT_TRUE(ip4_hdr_get_rf_flag(hdr) == false);
EXPECT_TRUE(ip4_hdr_get_df_flag(hdr) == false);
EXPECT_TRUE(ip4_hdr_get_mf_flag(hdr) == false);
EXPECT_TRUE(ip4_hdr_get_frag_offset(hdr) == 24);
EXPECT_TRUE(ip4_hdr_get_ttl(hdr) == 127);
EXPECT_TRUE(ip4_hdr_get_proto(hdr) == 6);
EXPECT_TRUE(ip4_hdr_get_checksum(hdr) == 0x6d88);
EXPECT_TRUE(ip4_hdr_get_src_addr(hdr) == 0xc0a82467);
EXPECT_TRUE(ip4_hdr_get_dst_addr(hdr) == 0xc0a82889);
EXPECT_TRUE(ip4_hdr_get_opt_len(hdr) == 0);
EXPECT_TRUE(ip4_hdr_get_opt_data(hdr) == NULL);
}
TEST(IPV4_UTILS, SET2)
@@ -151,26 +151,26 @@ TEST(IPV4_UTILS, SET2)
char buff[20] = {0};
struct ip *hdr = (struct ip *)buff;
ipv4_hdr_set_version(hdr, 4);
ipv4_hdr_set_hdr_len(hdr, 20);
ipv4_hdr_set_tos(hdr, 0);
ipv4_hdr_set_total_len(hdr, 44);
ipv4_hdr_set_ipid(hdr, 65535);
ipv4_hdr_set_frag_offset(hdr, 24);
ipv4_hdr_set_ttl(hdr, 127);
ipv4_hdr_set_protocol(hdr, 6);
ipv4_hdr_set_checksum(hdr, 0x6d88);
ipv4_hdr_set_src_addr(hdr, 0xc0a82467);
ipv4_hdr_set_dst_addr(hdr, 0xc0a82889);
ipv4_hdr_set_opt_len(hdr, 0);
ipv4_hdr_set_opt_data(hdr, NULL);
ip4_hdr_set_version(hdr, 4);
ip4_hdr_set_hdr_len(hdr, 20);
ip4_hdr_set_tos(hdr, 0);
ip4_hdr_set_total_len(hdr, 44);
ip4_hdr_set_ipid(hdr, 65535);
ip4_hdr_set_frag_offset(hdr, 24);
ip4_hdr_set_ttl(hdr, 127);
ip4_hdr_set_protocol(hdr, 6);
ip4_hdr_set_checksum(hdr, 0x6d88);
ip4_hdr_set_src_addr(hdr, 0xc0a82467);
ip4_hdr_set_dst_addr(hdr, 0xc0a82889);
ip4_hdr_set_opt_len(hdr, 0);
ip4_hdr_set_opt_data(hdr, NULL);
ipv4_hdr_set_flags(hdr, 0);
ip4_hdr_set_flags(hdr, 0);
EXPECT_TRUE(memcmp(buff, data2, 20) == 0);
ipv4_hdr_set_rf_flag(hdr, false);
ipv4_hdr_set_df_flag(hdr, false);
ipv4_hdr_set_mf_flag(hdr, false);
ip4_hdr_set_rf_flag(hdr, false);
ip4_hdr_set_df_flag(hdr, false);
ip4_hdr_set_mf_flag(hdr, false);
EXPECT_TRUE(memcmp(buff, data2, 20) == 0);
}
@@ -220,23 +220,23 @@ unsigned char data3[] = {
TEST(IPV4_UTILS, GET3)
{
const struct ip *hdr = (struct ip *)data3;
EXPECT_TRUE(ipv4_hdr_get_version(hdr) == 4);
EXPECT_TRUE(ipv4_hdr_get_hdr_len(hdr) == 60);
EXPECT_TRUE(ipv4_hdr_get_tos(hdr) == 0);
EXPECT_TRUE(ipv4_hdr_get_total_len(hdr) == 124);
EXPECT_TRUE(ipv4_hdr_get_ipid(hdr) == 0);
EXPECT_TRUE(ipv4_hdr_get_flags(hdr) == 2);
EXPECT_TRUE(ipv4_hdr_get_rf_flag(hdr) == false);
EXPECT_TRUE(ipv4_hdr_get_df_flag(hdr) == true);
EXPECT_TRUE(ipv4_hdr_get_mf_flag(hdr) == false);
EXPECT_TRUE(ipv4_hdr_get_frag_offset(hdr) == 0);
EXPECT_TRUE(ipv4_hdr_get_ttl(hdr) == 64);
EXPECT_TRUE(ipv4_hdr_get_proto(hdr) == 1);
EXPECT_TRUE(ipv4_hdr_get_checksum(hdr) == 0xfd30);
EXPECT_TRUE(ipv4_hdr_get_src_addr(hdr) == 0x7f000001);
EXPECT_TRUE(ipv4_hdr_get_dst_addr(hdr) == 0x7f000001);
EXPECT_TRUE(ipv4_hdr_get_opt_len(hdr) == 40);
EXPECT_TRUE(ipv4_hdr_get_opt_data(hdr) == (const char *)(data3 + 20));
EXPECT_TRUE(ip4_hdr_get_version(hdr) == 4);
EXPECT_TRUE(ip4_hdr_get_hdr_len(hdr) == 60);
EXPECT_TRUE(ip4_hdr_get_tos(hdr) == 0);
EXPECT_TRUE(ip4_hdr_get_total_len(hdr) == 124);
EXPECT_TRUE(ip4_hdr_get_ipid(hdr) == 0);
EXPECT_TRUE(ip4_hdr_get_flags(hdr) == 2);
EXPECT_TRUE(ip4_hdr_get_rf_flag(hdr) == false);
EXPECT_TRUE(ip4_hdr_get_df_flag(hdr) == true);
EXPECT_TRUE(ip4_hdr_get_mf_flag(hdr) == false);
EXPECT_TRUE(ip4_hdr_get_frag_offset(hdr) == 0);
EXPECT_TRUE(ip4_hdr_get_ttl(hdr) == 64);
EXPECT_TRUE(ip4_hdr_get_proto(hdr) == 1);
EXPECT_TRUE(ip4_hdr_get_checksum(hdr) == 0xfd30);
EXPECT_TRUE(ip4_hdr_get_src_addr(hdr) == 0x7f000001);
EXPECT_TRUE(ip4_hdr_get_dst_addr(hdr) == 0x7f000001);
EXPECT_TRUE(ip4_hdr_get_opt_len(hdr) == 40);
EXPECT_TRUE(ip4_hdr_get_opt_data(hdr) == (const char *)(data3 + 20));
}
TEST(IPV4_UTILS, SET3)
@@ -244,26 +244,26 @@ TEST(IPV4_UTILS, SET3)
char buff[60] = {0};
struct ip *hdr = (struct ip *)buff;
ipv4_hdr_set_version(hdr, 4);
ipv4_hdr_set_hdr_len(hdr, 60);
ipv4_hdr_set_tos(hdr, 0);
ipv4_hdr_set_total_len(hdr, 124);
ipv4_hdr_set_ipid(hdr, 0);
ipv4_hdr_set_frag_offset(hdr, 0);
ipv4_hdr_set_ttl(hdr, 64);
ipv4_hdr_set_protocol(hdr, 1);
ipv4_hdr_set_checksum(hdr, 0xfd30);
ipv4_hdr_set_src_addr(hdr, 0x7f000001);
ipv4_hdr_set_dst_addr(hdr, 0x7f000001);
ipv4_hdr_set_opt_len(hdr, 40);
ipv4_hdr_set_opt_data(hdr, (const char *)(data3 + 20));
ip4_hdr_set_version(hdr, 4);
ip4_hdr_set_hdr_len(hdr, 60);
ip4_hdr_set_tos(hdr, 0);
ip4_hdr_set_total_len(hdr, 124);
ip4_hdr_set_ipid(hdr, 0);
ip4_hdr_set_frag_offset(hdr, 0);
ip4_hdr_set_ttl(hdr, 64);
ip4_hdr_set_protocol(hdr, 1);
ip4_hdr_set_checksum(hdr, 0xfd30);
ip4_hdr_set_src_addr(hdr, 0x7f000001);
ip4_hdr_set_dst_addr(hdr, 0x7f000001);
ip4_hdr_set_opt_len(hdr, 40);
ip4_hdr_set_opt_data(hdr, (const char *)(data3 + 20));
ipv4_hdr_set_flags(hdr, 2);
ip4_hdr_set_flags(hdr, 2);
EXPECT_TRUE(memcmp(buff, data3, 60) == 0);
ipv4_hdr_set_rf_flag(hdr, false);
ipv4_hdr_set_df_flag(hdr, true);
ipv4_hdr_set_mf_flag(hdr, false);
ip4_hdr_set_rf_flag(hdr, false);
ip4_hdr_set_df_flag(hdr, true);
ip4_hdr_set_mf_flag(hdr, false);
EXPECT_TRUE(memcmp(buff, data3, 60) == 0);
}

View File

@@ -1,6 +1,6 @@
#include <gtest/gtest.h>
#include "ipv6_utils.h"
#include "ip6_utils.h"
/*
* Internet Protocol Version 6, Src: fe80::250:56ff:fe69:dc00, Dst: ff02::1:2
@@ -26,14 +26,14 @@ TEST(IPV6_UTILS, GET)
char src_str[INET6_ADDRSTRLEN];
char dst_str[INET6_ADDRSTRLEN];
const struct ip6_hdr *hdr = (struct ip6_hdr *)data;
EXPECT_TRUE(ipv6_hdr_get_version(hdr) == 6);
EXPECT_TRUE(ipv6_hdr_get_traffic_class(hdr) == 0);
EXPECT_TRUE(ipv6_hdr_get_flow_label(hdr) == 0);
EXPECT_TRUE(ipv6_hdr_get_payload_len(hdr) == 60);
EXPECT_TRUE(ipv6_hdr_get_next_header(hdr) == 17);
EXPECT_TRUE(ipv6_hdr_get_hop_limit(hdr) == 1);
struct in6_addr src_addr = ipv6_hdr_get_src_in6_addr(hdr);
struct in6_addr dst_addr = ipv6_hdr_get_dst_in6_addr(hdr);
EXPECT_TRUE(ip6_hdr_get_version(hdr) == 6);
EXPECT_TRUE(ip6_hdr_get_traffic_class(hdr) == 0);
EXPECT_TRUE(ip6_hdr_get_flow_label(hdr) == 0);
EXPECT_TRUE(ip6_hdr_get_payload_len(hdr) == 60);
EXPECT_TRUE(ip6_hdr_get_next_header(hdr) == 17);
EXPECT_TRUE(ip6_hdr_get_hop_limit(hdr) == 1);
struct in6_addr src_addr = ip6_hdr_get_src_in6_addr(hdr);
struct in6_addr dst_addr = ip6_hdr_get_dst_in6_addr(hdr);
inet_ntop(AF_INET6, &src_addr, src_str, INET6_ADDRSTRLEN);
inet_ntop(AF_INET6, &dst_addr, dst_str, INET6_ADDRSTRLEN);
@@ -50,14 +50,14 @@ TEST(IPV6_UTILS, SET)
inet_pton(AF_INET6, "fe80::250:56ff:fe69:dc00", &src_addr);
inet_pton(AF_INET6, "ff02::1:2", &dst_addr);
ipv6_hdr_set_version(hdr, 6);
ipv6_hdr_set_traffic_class(hdr, 0);
ipv6_hdr_set_flow_label(hdr, 0);
ipv6_hdr_set_payload_len(hdr, 60);
ipv6_hdr_set_next_header(hdr, 17);
ipv6_hdr_set_hop_limit(hdr, 1);
ipv6_hdr_set_src_in6_addr(hdr, src_addr);
ipv6_hdr_set_dst_in6_addr(hdr, dst_addr);
ip6_hdr_set_version(hdr, 6);
ip6_hdr_set_traffic_class(hdr, 0);
ip6_hdr_set_flow_label(hdr, 0);
ip6_hdr_set_payload_len(hdr, 60);
ip6_hdr_set_next_header(hdr, 17);
ip6_hdr_set_hop_limit(hdr, 1);
ip6_hdr_set_src_in6_addr(hdr, src_addr);
ip6_hdr_set_dst_in6_addr(hdr, dst_addr);
EXPECT_TRUE(memcmp(buff, data, 40) == 0);
}

View File

@@ -1635,9 +1635,9 @@ TEST(PACKET_PARSE, ETH_IP6_UDP_GTP_IP6_TCP_TLS)
EXPECT_TRUE(outer_udp_record->hdr_len == 8);
EXPECT_TRUE(outer_udp_record->pld_len == 1380);
// LAYER_PROTO_GTP
const struct raw_layer *outer_gtp_record = packet_get_outermost_raw_layer(&handler, LAYER_PROTO_GTP);
const struct raw_layer *inner_gtp_record = packet_get_innermost_raw_layer(&handler, LAYER_PROTO_GTP);
// LAYER_PROTO_GTP_U
const struct raw_layer *outer_gtp_record = packet_get_outermost_raw_layer(&handler, LAYER_PROTO_GTP_U);
const struct raw_layer *inner_gtp_record = packet_get_innermost_raw_layer(&handler, LAYER_PROTO_GTP_U);
EXPECT_TRUE(outer_gtp_record != nullptr);
EXPECT_TRUE(inner_gtp_record != nullptr);
@@ -1892,9 +1892,9 @@ TEST(PACKET_PARSE, ETH_IP6_UDP_GTP_IP4_TCP_TLS)
EXPECT_TRUE(outer_udp_record->hdr_len == 8);
EXPECT_TRUE(outer_udp_record->pld_len == 1408);
// LAYER_PROTO_GTP
const struct raw_layer *outer_gtp_record = packet_get_outermost_raw_layer(&handler, LAYER_PROTO_GTP);
const struct raw_layer *inner_gtp_record = packet_get_innermost_raw_layer(&handler, LAYER_PROTO_GTP);
// LAYER_PROTO_GTP_U
const struct raw_layer *outer_gtp_record = packet_get_outermost_raw_layer(&handler, LAYER_PROTO_GTP_U);
const struct raw_layer *inner_gtp_record = packet_get_innermost_raw_layer(&handler, LAYER_PROTO_GTP_U);
EXPECT_TRUE(outer_gtp_record != nullptr);
EXPECT_TRUE(inner_gtp_record != nullptr);

View File

@@ -2,8 +2,8 @@
#include "udp_utils.h"
#include "gre_utils.h"
#include "ipv4_utils.h"
#include "ipv6_utils.h"
#include "ip4_utils.h"
#include "ip6_utils.h"
#include "vxlan_utils.h"
#include "packet_def.h"
#include "packet_parse.h"
@@ -626,7 +626,7 @@ TEST(TUNNEL, GTP)
EXPECT_TRUE(out.layers[1].proto == LAYER_PROTO_UDP);
EXPECT_TRUE(out.layers[1].hdr_len == 8);
EXPECT_TRUE(out.layers[2].proto == LAYER_PROTO_GTP);
EXPECT_TRUE(out.layers[2].proto == LAYER_PROTO_GTP_U);
EXPECT_TRUE(out.layers[2].hdr_len == 8);
// No tunnel

View File

@@ -1,6 +1,6 @@
#include <gtest/gtest.h>
#include "ipv4_utils.h"
#include "ip4_utils.h"
#include "packet_def.h"
#include "packet_parse.h"
#include "packet_layer.h"
@@ -52,7 +52,7 @@ static void packet_set_ip_id(struct packet *pkt, uint16_t ip_id)
const struct raw_layer *ipv4_layer = packet_get_innermost_raw_layer(pkt, LAYER_PROTO_IPV4);
EXPECT_TRUE(ipv4_layer);
struct ip *hdr = (struct ip *)ipv4_layer->hdr_ptr;
ipv4_hdr_set_ipid(hdr, ip_id);
ip4_hdr_set_ipid(hdr, ip_id);
}
#if 1

View File

@@ -1,7 +1,7 @@
#include <gtest/gtest.h>
#include "macro.h"
#include "ipv4_utils.h"
#include "ip4_utils.h"
#include "packet_def.h"
#include "packet_parse.h"
#include "packet_layer.h"
@@ -54,7 +54,7 @@ static void packet_set_ip_src_addr(struct packet *pkt, uint32_t addr)
const struct raw_layer *ipv4_layer = packet_get_innermost_raw_layer(pkt, LAYER_PROTO_IPV4);
EXPECT_TRUE(ipv4_layer);
struct ip *hdr = (struct ip *)ipv4_layer->hdr_ptr;
ipv4_hdr_set_src_addr(hdr, addr);
ip4_hdr_set_src_addr(hdr, addr);
}
#if 1

View File

@@ -1,7 +1,7 @@
#include <gtest/gtest.h>
#include "macro.h"
#include "ipv4_utils.h"
#include "ip4_utils.h"
#include "packet_def.h"
#include "packet_parse.h"
#include "packet_layer.h"
@@ -54,7 +54,7 @@ static void packet_set_ip_src_addr(struct packet *pkt, uint32_t addr)
const struct raw_layer *ipv4_layer = packet_get_innermost_raw_layer(pkt, LAYER_PROTO_IPV4);
EXPECT_TRUE(ipv4_layer);
struct ip *hdr = (struct ip *)ipv4_layer->hdr_ptr;
ipv4_hdr_set_src_addr(hdr, addr);
ip4_hdr_set_src_addr(hdr, addr);
}
#if 1

View File

@@ -1,6 +1,6 @@
#include <gtest/gtest.h>
#include "ipv4_utils.h"
#include "ip4_utils.h"
#include "packet_def.h"
#include "packet_parse.h"
#include "packet_layer.h"

View File

@@ -3,7 +3,7 @@
#include "tuple.h"
#include "times.h"
#include "ipv4_utils.h"
#include "ip4_utils.h"
#include "packet_def.h"
#include "packet_parse.h"
#include "packet_layer.h"
@@ -441,7 +441,7 @@ TEST(TCP_INIT_TO_OPENING, BY_SYN_RETRANSMISSION)
packet_parse(&pkt, (const char *)syn_retransmission, sizeof(tcp_pkt1_c2s_syn));
const struct raw_layer *ipv4_layer = packet_get_innermost_raw_layer(&pkt, LAYER_PROTO_IPV4);
struct ip *hdr = (struct ip *)ipv4_layer->hdr_ptr;
ipv4_hdr_set_ipid(hdr, 0x1234);
ip4_hdr_set_ipid(hdr, 0x1234);
printf("<= Packet Parse: done\n\n");
// lookup session
@@ -540,7 +540,7 @@ TEST(TCP_INIT_TO_OPENING, BY_SYNACK_RETRANSMISSION)
const struct raw_layer *ipv4_layer = packet_get_innermost_raw_layer(&pkt, LAYER_PROTO_IPV4);
EXPECT_TRUE(ipv4_layer);
struct ip *hdr = (struct ip *)ipv4_layer->hdr_ptr;
ipv4_hdr_set_ipid(hdr, 0x1234);
ip4_hdr_set_ipid(hdr, 0x1234);
printf("<= Packet Parse: done\n\n");
// lookup session

View File

@@ -3,8 +3,8 @@
#include "eth_utils.h"
#include "vlan_utils.h"
#include "ipv4_utils.h"
#include "ipv6_utils.h"
#include "ip4_utils.h"
#include "ip6_utils.h"
#include "tcp_utils.h"
#include "udp_utils.h"
#include "packet_def.h"
@@ -144,8 +144,8 @@ static void tshark_format(const struct runtime *rte, const struct packet *pkt)
str_buff_push(&buff_proto, "ip");
ip4_hdr = (const struct ip *)layer->hdr_ptr;
src_addr_v4 = ipv4_hdr_get_src_in_addr(ip4_hdr);
dst_addr_v4 = ipv4_hdr_get_dst_in_addr(ip4_hdr);
src_addr_v4 = ip4_hdr_get_src_in_addr(ip4_hdr);
dst_addr_v4 = ip4_hdr_get_dst_in_addr(ip4_hdr);
inet_ntop(AF_INET, &src_addr_v4, tmp_src_buff, sizeof(tmp_src_buff));
inet_ntop(AF_INET, &dst_addr_v4, tmp_dst_buff, sizeof(tmp_dst_buff));
str_buff_push(&buff_ipv4_src, tmp_src_buff);
@@ -154,7 +154,7 @@ static void tshark_format(const struct runtime *rte, const struct packet *pkt)
case LAYER_PROTO_IPV6:
str_buff_push(&buff_proto, "ipv6");
ip6_hdr = (const struct ip6_hdr *)layer->hdr_ptr;
switch (ipv6_hdr_get_next_header(ip6_hdr))
switch (ip6_hdr_get_next_header(ip6_hdr))
{
case IPPROTO_HOPOPTS:
str_buff_push(&buff_proto, "ipv6.hopopts");
@@ -175,8 +175,8 @@ static void tshark_format(const struct runtime *rte, const struct packet *pkt)
break;
}
src_addr_v6 = ipv6_hdr_get_src_in6_addr(ip6_hdr);
dst_addr_v6 = ipv6_hdr_get_dst_in6_addr(ip6_hdr);
src_addr_v6 = ip6_hdr_get_src_in6_addr(ip6_hdr);
dst_addr_v6 = ip6_hdr_get_dst_in6_addr(ip6_hdr);
inet_ntop(AF_INET6, &src_addr_v6, tmp_src_buff, sizeof(tmp_src_buff));
inet_ntop(AF_INET6, &dst_addr_v6, tmp_dst_buff, sizeof(tmp_dst_buff));
str_buff_push(&buff_ipv6_src, tmp_src_buff);
@@ -219,7 +219,8 @@ static void tshark_format(const struct runtime *rte, const struct packet *pkt)
case LAYER_PROTO_VXLAN:
str_buff_push(&buff_proto, "vxlan");
break;
case LAYER_PROTO_GTP:
case LAYER_PROTO_GTP_C:
case LAYER_PROTO_GTP_U:
str_buff_push(&buff_proto, "gtp");
break;
default: