diff options
| author | yangwei <[email protected]> | 2021-08-26 20:36:27 +0800 |
|---|---|---|
| committer | yangwei <[email protected]> | 2021-08-26 20:36:27 +0800 |
| commit | 240efaec395961ad55a85dd7f15fde784de1f065 (patch) | |
| tree | f2e03e3a6d383a714ace55c4b927457e57e519db /src/net_common.c | |
| parent | faa4eba4f74b7a7cb0c4e0045d9db8015e679baf (diff) | |
Diffstat (limited to 'src/net_common.c')
| -rw-r--r-- | src/net_common.c | 269 |
1 files changed, 267 insertions, 2 deletions
diff --git a/src/net_common.c b/src/net_common.c index c4b88fe..22a4e85 100644 --- a/src/net_common.c +++ b/src/net_common.c @@ -26,6 +26,7 @@ static int eth_jump_to_layer(const char *raw_data, int raw_layer_type, int expe static int vlan8021q_jump_to_layer(const char *raw_data, int raw_layer_type, int expect_layer_type);
static int ipv4_jump_to_layer(const char *raw_data, int raw_layer_type, int expect_layer_type);
static int ipv6_jump_to_layer(const char *raw_data, int raw_layer_type, int expect_layer_type);
+static int gre_jump_to_layer(const char *raw_data, int raw_layer_type, int expect_layer_type);
int treat_vlan_as_mac_in_mac_sw = 0; /* ��vlanǿ�ư�mac_in_mac��ʽ����, �Ȳ����ݸ�sapp, ��ΪӰ��sappȫ�ִ������� */
@@ -80,6 +81,7 @@ static int arp_jump_to_layer(const char *raw_data, int raw_layer_type, int expe }
+
static int gtp_jump_to_layer(const char *raw_data, int raw_layer_type, int expect_layer_type)
{
const struct gtp_hdr *gh = (struct gtp_hdr *)raw_data;
@@ -235,6 +237,14 @@ static int ipv4_jump_to_layer(const char *raw_data, int raw_layer_type, int exp skip_len = ipv6_jump_to_layer(raw_data+ip_hdr_len, __ADDR_TYPE_IP_PAIR_V6, expect_layer_type);
}
break;
+ case IPPROTO_GRE:
+ if((ADDR_TYPE_GRE == expect_layer_type) || (ADDR_TYPE_PPTP == expect_layer_type)){
+ skip_len = 0;
+ break;
+ }else{
+ skip_len = gre_jump_to_layer(raw_data+ip_hdr_len, ADDR_TYPE_GRE, expect_layer_type);
+ }
+ break;
default:
skip_len = -1;
@@ -735,6 +745,253 @@ static int mac_in_mac_jump_to_layer(const char *raw_data, int raw_layer_type, i return layer_skip_len + sizeof(struct ethhdr) * 2;
}
+static inline int calc_gre_hdr_len_v0(const struct mesa_gre_base_hdr_v0 *gre_base_hdr_v0)
+{
+ int gre_hdr_len = sizeof(struct mesa_gre_base_hdr_v0);
+
+ if(gre_base_hdr_v0->checksum_flag || gre_base_hdr_v0->route_flag){
+ gre_hdr_len += sizeof(short) * 2; /* checksum and offset */
+ }
+
+ if(gre_base_hdr_v0->key_flag){
+ gre_hdr_len += sizeof(int );
+ }
+
+ if(gre_base_hdr_v0->seq_flag){
+ gre_hdr_len += sizeof(int );
+ }
+
+ return gre_hdr_len;
+}
+
+static inline int calc_gre_hdr_len_v1(const struct mesa_gre_base_hdr_v1 *gre_base_hdr_v1)
+{
+ int gre_hdr_len = sizeof(struct mesa_gre_base_hdr_v1);
+
+ if(gre_base_hdr_v1->checksum_flag != 0){
+ printf("error! in gre version1, checksum flag not zero!\n");
+ return -1;
+ }
+
+ if(gre_base_hdr_v1->route_flag != 0){
+ printf("error! in gre version1, route flag not zero!\n");
+ return -1;
+ }
+
+ if(gre_base_hdr_v1->recur != 0){
+ printf("error! in gre version1, recur flag not zero!\n");
+ return -1;
+ }
+
+ if(gre_base_hdr_v1->strict_src_route_flag != 0){
+ printf("error! in gre version1, strict_src_route flag not zero!\n");
+ return -1;
+ }
+
+ if(ntohs(gre_base_hdr_v1->protocol) != GRE_PRO_PPP){
+ printf("error! in gre version1, protocol not 0x%x!\n", GRE_PRO_PPP);
+ return -1;
+ }
+
+ gre_hdr_len += sizeof(short) * 2; /* payload_len and callid */
+
+ if(gre_base_hdr_v1->seq_flag){
+ gre_hdr_len += sizeof(int);
+ }
+
+ /* version 1 has ack number */
+ if(gre_base_hdr_v1->ack_flag){
+ gre_hdr_len += sizeof(int);
+ }
+
+ return gre_hdr_len;
+}
+
+int calc_gre_hdr_len(const struct mesa_gre_hdr *gre_hdr)
+{
+ int gre_hdr_len = -1;
+
+ if(0 == gre_hdr->gre_base.version){
+ gre_hdr_len = calc_gre_hdr_len_v0(&gre_hdr->gre_base);
+ }else if(1 == gre_hdr->gre_base.version){
+ gre_hdr_len = calc_gre_hdr_len_v1((const struct mesa_gre_base_hdr_v1 *)&gre_hdr->gre_base);
+ }else{
+ gre_hdr_len = -1;
+ }
+
+ return gre_hdr_len;
+}
+
+static int set_gre_hdr_ver0(struct mesa_gre_hdr *stack_gre_addr, const struct mesa_gre_hdr *net_gre_addr)
+{
+ struct mesa_gre_extend_hdr *stack_gre_ext = &stack_gre_addr->gre_extend;
+ const struct mesa_gre_base_hdr_v0 *net_gre_base = &net_gre_addr->gre_base;
+ const char *net_ext_hdr_value = (const char *)(&net_gre_addr->gre_extend);
+ //const struct gre_source_route_entry_hdr *rse_hdr;
+
+ if(net_gre_base->checksum_flag || net_gre_base->route_flag){
+ stack_gre_ext->checksum = *((unsigned short *)net_ext_hdr_value);
+ net_ext_hdr_value += sizeof(short);
+
+ /* ���checksum����, ��offsetҲ�ش��� */
+ stack_gre_ext->offset = *((unsigned short *)net_ext_hdr_value);
+ net_ext_hdr_value += sizeof(short);
+ }
+
+ if(net_gre_base->key_flag){
+ stack_gre_ext->key = *((unsigned int *)net_ext_hdr_value);
+ net_ext_hdr_value += sizeof(int);
+ }
+
+ if(net_gre_base->seq_flag){
+ stack_gre_ext->seq_num = *((unsigned int *)net_ext_hdr_value);
+ net_ext_hdr_value += sizeof(int);
+ }
+
+ /* SRE��Ϣ��GREͷ�������, ��Ϊ������, �������� */
+ if(net_gre_base->route_flag){
+ //rse_hdr = (const struct gre_source_route_entry_hdr *)net_ext_hdr_value;
+ //TODO 1, copy SRE
+ printf("found GRE SRE data, but not parse yet, TODO!\n");
+ return -1;
+ }
+
+ return sizeof(struct mesa_gre_base_hdr_v1) + (net_ext_hdr_value - (char *)&net_gre_addr->gre_extend);
+}
+
+
+static int set_gre_hdr_ver1(struct mesa_gre_hdr *stack_gre_addr, const struct mesa_gre_hdr *net_gre_addr)
+{
+ //struct mesa_gre_base_hdr_v1 *stack_gre_base = (struct mesa_gre_base_hdr_v1 *)&stack_gre_addr->gre_base;
+ struct mesa_gre_extend_hdr *stack_gre_ext = &stack_gre_addr->gre_extend;
+ const struct mesa_gre_base_hdr_v1 *net_gre_base = (struct mesa_gre_base_hdr_v1 *)&net_gre_addr->gre_base;
+ //const struct mesa_gre_extend_hdr *net_gre_ext = &net_gre_addr->gre_extend;
+ const char *net_ext_hdr_value = (const char *)(&net_gre_addr->gre_extend);
+
+ if(net_gre_base->checksum_flag != 0){
+ printf("error! in gre version1, checksum flag not zero!\n");
+ return -1;
+ }
+
+ if(net_gre_base->route_flag != 0){
+ printf("error! in gre version1, route flag not zero!\n");
+ return -1;
+ }
+
+ if(net_gre_base->recur != 0){
+ printf("error! in gre version1, recur flag not zero!\n");
+ return -1;
+ }
+
+ if(net_gre_base->strict_src_route_flag != 0){
+ printf("error! in gre version1, strict_src_route flag not zero!\n");
+ return -1;
+ }
+
+ if(ntohs(net_gre_base->protocol) != GRE_PRO_PPP){
+ printf("error! in gre version1, protocol not 0x%x!\n", GRE_PRO_PPP);
+ return -1;
+ }
+
+ stack_gre_ext->payload_len = *((unsigned short *)net_ext_hdr_value);
+ net_ext_hdr_value += sizeof(short);
+
+ stack_gre_ext->call_id = *((unsigned short *)net_ext_hdr_value);
+ net_ext_hdr_value += sizeof(short);
+
+ if(net_gre_base->seq_flag){
+ stack_gre_ext->seq_num = *((unsigned int *)net_ext_hdr_value);
+ net_ext_hdr_value += sizeof(int);
+ }
+
+ /* version 1 has ack number */
+ if(net_gre_base->ack_flag){
+ stack_gre_ext->ack_num = *((unsigned int *)net_ext_hdr_value);
+ net_ext_hdr_value += sizeof(int);
+ }
+
+ return sizeof(struct mesa_gre_base_hdr_v1) + (net_ext_hdr_value - (char *)&net_gre_addr->gre_extend);
+}
+
+
+int set_gre_hdr(struct mesa_gre_hdr *stack_gre_addr, const void *this_layer_data)
+{
+ int gre_hdr_len = 0;
+ const struct mesa_gre_hdr *net_gre_addr = (const struct mesa_gre_hdr *)this_layer_data;
+
+ memcpy(&stack_gre_addr->gre_base, &net_gre_addr->gre_base, sizeof(struct mesa_gre_base_hdr_v0));
+ memset(&stack_gre_addr->gre_extend, 0, sizeof(struct mesa_gre_extend_hdr));
+
+ if(0 == net_gre_addr->gre_base.version){
+ gre_hdr_len = set_gre_hdr_ver0(stack_gre_addr, net_gre_addr);
+ }else if(1 == net_gre_addr->gre_base.version){
+ gre_hdr_len = set_gre_hdr_ver1(stack_gre_addr, net_gre_addr);
+ }else{
+ //TODO 1, δ֪�汾
+ printf("Unknown gre hdr version:%d\n", net_gre_addr->gre_base.version);
+ gre_hdr_len = -1;
+ }
+
+ return gre_hdr_len;
+}
+
+static int gre_jump_to_layer(const char *raw_data, int raw_layer_type, int expect_layer_type)
+{
+ int skip_len = 0;
+ int this_gre_layer_len;
+ struct mesa_gre_hdr this_layer_hdr;
+
+ if(raw_layer_type == expect_layer_type){
+ return 0;
+ }
+
+ this_gre_layer_len = set_gre_hdr(&this_layer_hdr, (void *)raw_data);
+ if(this_gre_layer_len < 0){
+ return -1;
+ }
+
+ switch(ntohs(this_layer_hdr.gre_base.protocol))
+ {
+ case GRE_PRO_IPV4:
+ if(expect_layer_type == ADDR_TYPE_IPV4){
+ skip_len = 0;
+ break;
+ }else{
+ skip_len=ipv4_jump_to_layer(raw_data+this_gre_layer_len, __ADDR_TYPE_IP_PAIR_V4, expect_layer_type);
+ }
+ break;
+
+ case GRE_PRO_IPV6:
+ if(expect_layer_type == ADDR_TYPE_IPV4){
+ skip_len = 0;
+ break;
+ }else{
+ skip_len=ipv6_jump_to_layer(raw_data+this_gre_layer_len, __ADDR_TYPE_IP_PAIR_V6, expect_layer_type);
+ }
+ break;
+
+ case GRE_PRO_PPP:
+ if((expect_layer_type == ADDR_TYPE_PPP) || (expect_layer_type == ADDR_TYPE_PPTP)){
+ skip_len = this_gre_layer_len;
+ break;
+ }else{
+ skip_len = ppp_jump_to_layer(raw_data+this_gre_layer_len, ADDR_TYPE_PPP, expect_layer_type);
+ }
+ break;
+
+ default:
+ printf("gre_jump_to_layer(): unknown gre protocol:0x%x!\n", ntohs(this_layer_hdr.gre_base.protocol));
+ return -1;
+ break;
+ }
+
+ if(skip_len < 0){
+ printf("gre_jump_to_layer() error!\n");
+ return -1;
+ }
+
+ return skip_len + this_gre_layer_len;
+}
/*
return value:
Non-NULL: the pointer to expect layer;
@@ -803,8 +1060,13 @@ const void *MESA_net_jump_to_layer(const void *raw_data, int raw_layer_type, in ret = mpls_jump_to_layer((const char *)raw_data, raw_layer_type, expect_layer_type);
break;
- case ADDR_TYPE_PPPOE_SES:
case ADDR_TYPE_GRE:
+ ret = gre_jump_to_layer((const char *)raw_data, raw_layer_type, expect_layer_type);
+ break;
+
+ case ADDR_TYPE_PPPOE_SES:
+ return NULL;
+ break;
default:
printf("MESA_net_jump_to_layer(): unsupport raw_layer_type:%d in MESA_net_jump_to_layer()!\n", raw_layer_type);
return NULL;
@@ -848,8 +1110,11 @@ const void *MESA_net_jump_to_layer_greedy(const void *raw_data, int raw_layer_ty if(IPPROTO_UDP == ip4hdr->ip_p){
new_next_layer_data = (char *)expect_layer + ip4hdr->ip_hl * 4;
new_raw_layer_type = ADDR_TYPE_UDP; /* IP�������������һ��ƫ��, ֻ֧��UDP, IPIP, GRE, L2TPv3. */
+ }else if(IPPROTO_GRE == ip4hdr->ip_p){
+ new_next_layer_data = (char *)expect_layer + ip4hdr->ip_hl * 4;
+ new_raw_layer_type = ADDR_TYPE_GRE; /* GRE */
}else{
- //TODO 2, GRE, IPIP, L2TPv3
+ //TODO 2, IPIP, L2TPv3
goto done;
}
}
|
