feat(greedy模式支持跳过gre):

This commit is contained in:
yangwei
2021-08-26 20:36:27 +08:00
parent faa4eba4f7
commit 240efaec39
2 changed files with 273 additions and 2 deletions

View File

@@ -510,6 +510,12 @@ enum pptp_control_message_type{
PPTP_CTRL_SET_LINK_INFO = 15, PPTP_CTRL_SET_LINK_INFO = 15,
}; };
#define GRE_PRO_IPV4 (0x0800)
#define GRE_PRO_IPV6 (0x86DD)
#define GRE_PRO_ARP (0x0806)
#define GRE_PRO_PPP (0x880B)
struct mesa_pptp_control_hdr{ struct mesa_pptp_control_hdr{
unsigned short length; /* ȫ<><C8AB><EFBFBD><EFBFBD><EFBFBD>ݳ<EFBFBD><DDB3><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7> */ unsigned short length; /* ȫ<><C8AB><EFBFBD><EFBFBD><EFBFBD>ݳ<EFBFBD><DDB3><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7> */
unsigned short pptp_message_type; unsigned short pptp_message_type;

View File

@@ -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 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 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 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; /* <20><>vlanǿ<6E>ư<EFBFBD>mac_in_mac<61><63>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD>, <20>Ȳ<EFBFBD><C8B2><EFBFBD><EFBFBD>ݸ<EFBFBD>sapp, <20><>ΪӰ<CEAA><D3B0>sappȫ<70>ִ<EFBFBD><D6B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */ int treat_vlan_as_mac_in_mac_sw = 0; /* <20><>vlanǿ<6E>ư<EFBFBD>mac_in_mac<61><63>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD>, <20>Ȳ<EFBFBD><C8B2><EFBFBD><EFBFBD>ݸ<EFBFBD>sapp, <20><>ΪӰ<CEAA><D3B0>sappȫ<70>ִ<EFBFBD><D6B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
@@ -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) 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; 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); skip_len = ipv6_jump_to_layer(raw_data+ip_hdr_len, __ADDR_TYPE_IP_PAIR_V6, expect_layer_type);
} }
break; 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: default:
skip_len = -1; 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; 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);
/* <20><><EFBFBD><EFBFBD>checksum<75><6D><EFBFBD><EFBFBD>, <20><>offsetҲ<74>ش<EFBFBD><D8B4><EFBFBD> */
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<52><45>Ϣ<EFBFBD><CFA2>GREͷ<45><CDB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
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, δ֪<CEB4>
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: return value:
Non-NULL: the pointer to expect layer; 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); ret = mpls_jump_to_layer((const char *)raw_data, raw_layer_type, expect_layer_type);
break; break;
case ADDR_TYPE_PPPOE_SES:
case ADDR_TYPE_GRE: 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: default:
printf("MESA_net_jump_to_layer(): unsupport raw_layer_type:%d in MESA_net_jump_to_layer()!\n", raw_layer_type); printf("MESA_net_jump_to_layer(): unsupport raw_layer_type:%d in MESA_net_jump_to_layer()!\n", raw_layer_type);
return NULL; 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){ if(IPPROTO_UDP == ip4hdr->ip_p){
new_next_layer_data = (char *)expect_layer + ip4hdr->ip_hl * 4; new_next_layer_data = (char *)expect_layer + ip4hdr->ip_hl * 4;
new_raw_layer_type = ADDR_TYPE_UDP; /* IP<49><50><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>ƫ<EFBFBD><C6AB>, ֻ֧<D6BB><D6A7>UDP, IPIP, GRE, L2TPv3. */ new_raw_layer_type = ADDR_TYPE_UDP; /* IP<49><50><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>ƫ<EFBFBD><C6AB>, ֻ֧<D6BB><D6A7>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{ }else{
//TODO 2, GRE, IPIP, L2TPv3 //TODO 2, IPIP, L2TPv3
goto done; goto done;
} }
} }