diff --git a/src/net_common.c b/src/net_common.c index fdbb2fa..c4b88fe 100644 --- a/src/net_common.c +++ b/src/net_common.c @@ -102,13 +102,33 @@ static int gtp_jump_to_layer(const char *raw_data, int raw_layer_type, int expe }else if((*next_ip_layer_hdr & 0x60) == 0x60){ skip_len = ipv6_jump_to_layer((char *)next_ip_layer_hdr, __ADDR_TYPE_IP_PAIR_V6, expect_layer_type); }else{ - ////sapp_runtime_log(20, "TODO: jmp unsupport type in GTP, 0x%x!\n", (*next_ip_layer_hdr)); + printf("TODO: jmp unsupport type in GTP, 0x%x!\n", (*next_ip_layer_hdr)); return -1; } return opt_len + sizeof(struct gtp_hdr) + skip_len; } +#define TEREDO_AUTH_HDR_FLAG (0x0001) +#define TEREDO_INDICATION_HDR_FLAG (0x0000) + +#define TEREDO_INDICATION_HDR_LEN (8) + +struct teredo_auth_hdr{ +#if __BYTE_ORDER == __LITTLE_ENDIAN + unsigned short flags; + unsigned char id_len; + unsigned char au_len; +#elif __BYTE_ORDER == __BIG_ENDIAN + unsigned char au_len; + unsigned char id_len; + unsigned short flags; +#else +#error "Please check " +#endif +}; + + static int udp_jump_to_layer(const char *raw_data, int raw_layer_type, int expect_layer_type) { const struct mesa_udp_hdr *uh = (const struct mesa_udp_hdr *)raw_data; @@ -132,11 +152,38 @@ static int udp_jump_to_layer(const char *raw_data, int raw_layer_type, int expe } skip_len += 8; /* skip vxlan header */ }else if((3544 == usport) || (3544 == udport)){ - /* teredo实际没有数据包头, 直接跳转到ipv6层即可 */ - skip_len = ipv6_jump_to_layer(raw_data+sizeof(struct mesa_udp_hdr), __ADDR_TYPE_IP_PAIR_V6, expect_layer_type); + /* teredo实际没有数据包头, 直接跳转到ipv6层即可 , before 20181204*/ + const char *next_layer_hdr = raw_data+sizeof(struct mesa_udp_hdr); + struct teredo_auth_hdr *p_teredo_hdr; + int teredo_layer_len = 0, tmp_hdr_len = 0; + while((*next_layer_hdr & 0xF0) != 0x60) + { + p_teredo_hdr = (struct teredo_auth_hdr *)next_layer_hdr; + if(p_teredo_hdr->flags == ntohs(TEREDO_AUTH_HDR_FLAG)) + { + //rfc4380 5.1.1 teredo 负载0x0001时为Teredo authentication headers,需要跳过 + tmp_hdr_len += sizeof(struct teredo_auth_hdr) + ntohs(p_teredo_hdr->au_len) + ntohs + (p_teredo_hdr->id_len) + 8 + 1; + next_layer_hdr += tmp_hdr_len; + teredo_layer_len += tmp_hdr_len; + } + else if(p_teredo_hdr->flags == ntohs(TEREDO_INDICATION_HDR_FLAG)) + { + //rfc4380 teredo 负载0x0000时为Teredo indication headers,需要跳过 + next_layer_hdr += TEREDO_INDICATION_HDR_LEN; + teredo_layer_len += TEREDO_INDICATION_HDR_LEN; + } + else + { + printf("udp_jump_to_layer(): unsupport teredo hdr:0x%d!\n", *(unsigned int *)(next_layer_hdr)); + return -1; + } + } + skip_len = ipv6_jump_to_layer(next_layer_hdr, __ADDR_TYPE_IP_PAIR_V6, expect_layer_type); if(skip_len < 0){ return -1; } + skip_len += teredo_layer_len; }else{ /* 其他UDP类型不支持再跳转 */ return -1; @@ -147,21 +194,20 @@ static int udp_jump_to_layer(const char *raw_data, int raw_layer_type, int expe static int ipv4_jump_to_layer(const char *raw_data, int raw_layer_type, int expect_layer_type) { - struct ip *p_ip_hdr = (struct ip *)raw_data; + struct mesa_ip4_hdr *p_ip_hdr = (struct mesa_ip4_hdr *)raw_data; int skip_len = 0; - int ip_hdr_len = IP_HL(p_ip_hdr) * 4; + int ip_hdr_len = p_ip_hdr->ip_hl * 4; //const char *next_layer_data = raw_data + ip_hdr_len; if(raw_layer_type == expect_layer_type){ return 0; } - /* IP分片不再继续跳转 */ - unsigned short *iphdr_off = (unsigned short *)&p_ip_hdr->ip_off[0]; - if((htons(*iphdr_off) & IP_MF) || (htons(*iphdr_off) & IP_OFFMASK)){ + if((ntohs(p_ip_hdr->ip_off) & IP_MF ) || (ntohs(p_ip_hdr->ip_off) & IP_OFFMASK)){ + /* IP分片不再继续向内层跳转 */ return -1; } - + switch(p_ip_hdr->ip_p){ case IPPROTO_TCP: if(ADDR_TYPE_TCP == expect_layer_type){ @@ -202,6 +248,23 @@ static int ipv4_jump_to_layer(const char *raw_data, int raw_layer_type, int exp return skip_len + sizeof(struct ip); } +/* + * NextHeader field of IPv6 header + */ +#define NEXTHDR_HOP 0 /* Hop-by-hop option header. */ +#define NEXTHDR_IPIP 4 /* IPIP header. */ +#define NEXTHDR_TCP 6 /* TCP segment. */ +#define NEXTHDR_UDP 17 /* UDP message. */ +#define NEXTHDR_IPV6 41 /* IPv6 in IPv6 */ +#define NEXTHDR_ROUTING 43 /* Routing header. */ +#define NEXTHDR_FRAGMENT 44 /* Fragmentation/reassembly header. */ +#define NEXTHDR_ESP 50 /* Encapsulating security payload. */ +#define NEXTHDR_AUTH 51 /* Authentication header. */ +#define NEXTHDR_ICMP 58 /* ICMP for IPv6. */ +#define NEXTHDR_NONE 59 /* No next header */ +#define NEXTHDR_DEST 60 /* Destination options header. */ +#define NEXTHDR_MOBILITY 135 /* Mobility header. */ + static int ipv6_jump_to_layer(const char *raw_data, int raw_layer_type, int expect_layer_type) { const struct mesa_ip6_hdr *a_packet = (const struct mesa_ip6_hdr *)raw_data; @@ -218,14 +281,14 @@ static int ipv6_jump_to_layer(const char *raw_data, int raw_layer_type, int exp offset_to_ip6 = 0; switch(next_hdr_type) { - case 0: //NEXTHDR_HOP: - case 43://NEXTHDR_ROUTING: - case 51://NEXTHDR_AUTH: - case 60://NEXTHDR_DEST: + case NEXTHDR_HOP: + case NEXTHDR_ROUTING: + case NEXTHDR_AUTH: + case NEXTHDR_DEST: offset_to_ip6 = (*(next_hdr_ptr + 1))*8 + 8; /* 选项长度以8字节为单位 */ break; - case 4://NEXTHDR_IPIP: + case NEXTHDR_IPIP: if(__ADDR_TYPE_IP_PAIR_V4 == expect_layer_type){ skip_len = next_hdr_ptr - (UINT8 *)raw_data; }else{ @@ -239,17 +302,17 @@ static int ipv6_jump_to_layer(const char *raw_data, int raw_layer_type, int exp goto done; break; - case 59://NEXTHDR_NONE: + case NEXTHDR_NONE: skip_len = -1; goto done; break; - case 58://NEXTHDR_ICMP: /* IMCP不再承载其他协议 */ + case NEXTHDR_ICMP: /* IMCP不再承载其他协议 */ skip_len = -1; goto done; break; - case 6://NEXTHDR_TCP: + case NEXTHDR_TCP: if(ADDR_TYPE_TCP == expect_layer_type){ skip_len = next_hdr_ptr - (UINT8 *)raw_data; }else{ @@ -258,7 +321,7 @@ static int ipv6_jump_to_layer(const char *raw_data, int raw_layer_type, int exp goto done; break; - case 17://NEXTHDR_UDP: + case NEXTHDR_UDP: if(ADDR_TYPE_UDP == expect_layer_type){ skip_len = next_hdr_ptr - (UINT8 *)raw_data; }else{ @@ -268,17 +331,18 @@ static int ipv6_jump_to_layer(const char *raw_data, int raw_layer_type, int exp goto done; break; - case 44:///NEXTHDR_FRAGMENT: - /* IP分片不再继续跳转 */ - return -1; + case NEXTHDR_FRAGMENT: + /* IP分片不再继续向内层跳转 */ + skip_len = -1; + goto done; break; - case 50://NEXTHDR_ESP: + case NEXTHDR_ESP: skip_len = -1; goto done; default: - printf("TODO:jmp Unknown IPv6 header type:0x%x!\n", next_hdr_type); + printf("ipv6_jump_to_layer(): unknown IPv6 header type:0x%x!\n", next_hdr_type); skip_len = -1; goto done; break; @@ -330,7 +394,7 @@ static int ppp_jump_to_layer(const char *raw_data, int raw_layer_type, int expe case PPP_IPCP: case PPP_PAP: case PPP_CHAP: - case 0xC025: ///PPP_LQR: + case PPP_LQM: case PPP_PROTOCOL_LCP: /* 不承载应用层协议 */ @@ -338,7 +402,7 @@ static int ppp_jump_to_layer(const char *raw_data, int raw_layer_type, int expe break; default: - printf("TODO: jmp unsupport ppp pro:0x%x!\n", ntohs(pppoe_ses_hdr->ppp_protocol)); + printf("ppp_jump_to_layer(): unsupport ppp pro:0x%x!\n", ntohs(pppoe_ses_hdr->ppp_protocol)); break; } @@ -349,33 +413,118 @@ static int ppp_jump_to_layer(const char *raw_data, int raw_layer_type, int expe return skip_len + sizeof(struct mesa_pppoe_session_hdr); } +static int guess_mpls_with_control_word(const unsigned char *maybe_eth_hdr) +{ + const struct mesa_ethernet_hdr *ehdr = (struct mesa_ethernet_hdr *)(maybe_eth_hdr); + /* + MPLS没有字段表示承载的协议类型, 靠猜!! + RFC4623, or https://wiki.mikrotik.com/wiki/Manual:VPLS_Control_Word + 除标准的ipv4, ipv6之外, 还有可能是ethernet, 还有可能是带PW Ethernet Control Word的, 格式如下: + + 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 2 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |0 0 0 0| flags |frag|len(6bit) | Sequence Number(16bit) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + 实际情况证明, 靠4bit是否==0为条件, 还是可能猜错, 再判断一下以太类型是否为常见类型. + */ + + switch(ntohs(ehdr->ether_type)){ + case ETH_P_IP: + case ETH_P_IPV6: + case ETH_P_8021Q: + case ETH_P_MPLS_UC: + case ETH_P_PPP_SES: + return 0; /* 合法的ethernet类型, 不含CW */ + break; + } + + ehdr = (struct mesa_ethernet_hdr *)(maybe_eth_hdr + 4); + switch(ntohs(ehdr->ether_type)){ + case ETH_P_IP: + case ETH_P_IPV6: + case ETH_P_8021Q: + case ETH_P_MPLS_UC: + case ETH_P_PPP_SES: + return 1; /* 合法的ethernet类型, 包含CW */ + break; + } + + /* TODO: 以上都不是, 此处应该返回个什么值? */ + return 0; +} + +static int set_mpls_addr(struct layer_addr_mpls *addr, const unsigned char *raw_mpls_pkt_data) +{ + const struct mesa_mpls_hdr *this_mpls_hdr; + int i; + + memset(addr, 0, sizeof(struct layer_addr_mpls)); + for(i = 0; i < MAX_MPLS_ADDR_LAYER; i++) + { + this_mpls_hdr = (const struct mesa_mpls_hdr *)raw_mpls_pkt_data; + memcpy(&addr->src_mpls_pkt[i], raw_mpls_pkt_data, sizeof(struct mesa_mpls_hdr)); + addr->src_mpls_layer_num += 1; + if(1 == this_mpls_hdr->mpls_bls){ + raw_mpls_pkt_data += sizeof(struct mesa_mpls_hdr); /* 为了后面方便判断是否还有ctrl word */ + break; + } + raw_mpls_pkt_data += sizeof(struct mesa_mpls_hdr); + } + + if(1 != this_mpls_hdr->mpls_bls) /* 超过MAX_MPLS_ADDR_LAYER, MPLS还没有结束 */ + { + printf("MPLS layer number over load, only support %d\n", MAX_MPLS_ADDR_LAYER); + return -1; + } + + if(((*raw_mpls_pkt_data & 0xF0) != 0x40) && ((*raw_mpls_pkt_data & 0xF0) != 0x60)){ //VPLS, MPLS with Control Word + if(guess_mpls_with_control_word(raw_mpls_pkt_data) > 0){ + memcpy(&addr->src_mpls_ctrl_word, raw_mpls_pkt_data, sizeof(int)); + addr->src_has_ctrl_word = 1; + } + } + + return 0; +} static int mpls_jump_to_layer(const char *raw_data, int raw_layer_type, int expect_layer_type) { int skip_len = 0; - const struct mesa_mpls_hdr *mpls_hdr = (const struct mesa_mpls_hdr *)raw_data; - const char *next_layer_data = raw_data + sizeof(struct mesa_mpls_hdr); + struct layer_addr_mpls mpls_addr = {}; + const char *next_layer_data; + int mpls_layer_len; if(raw_layer_type == expect_layer_type){ return 0; } - if(0 == mpls_hdr->mpls_bls){ /* 非MPLS栈底, 递归调用自身 */ - return mpls_jump_to_layer(next_layer_data, ADDR_TYPE_MPLS, expect_layer_type) + sizeof(struct mesa_mpls_hdr); + set_mpls_addr(&mpls_addr, (unsigned char *)raw_data); + mpls_layer_len = mpls_addr.src_mpls_layer_num * sizeof(int); + if(mpls_addr.src_has_ctrl_word){ + mpls_layer_len += sizeof(int); } + next_layer_data = raw_data + mpls_layer_len; + /* MPLS没有字段标识下一层是什么, 靠猜测下一层的IP类型 */ - if((*next_layer_data & 0x40) == 0x40){ + if((*next_layer_data & 0xF0) == 0x40){ skip_len = ipv4_jump_to_layer(next_layer_data, __ADDR_TYPE_IP_PAIR_V4, expect_layer_type); - }else if((*next_layer_data & 0x60) == 0x60){ + }else if((*next_layer_data & 0xF0) == 0x60){ skip_len = ipv6_jump_to_layer(next_layer_data, __ADDR_TYPE_IP_PAIR_V6, expect_layer_type); - }else{ - //sapp_runtime_log(20, "TODO: jmp unsupport type in MPLS, 0x%x!\n", (unsigned char)(*next_layer_data)); - return -1; + }else{ + /* VPLS和不带control word一并处理, 在set_mpls_addr()函数中, 如果包括Control word, next_layer_data已经跳过了四字节的control word */ + skip_len = eth_jump_to_layer(next_layer_data, ADDR_TYPE_MAC, expect_layer_type); + if(skip_len < 0){ + printf("WARNING: jmp unsupport type in MPLS to Ethernet, 0x%x!\n", + (unsigned char)(*next_layer_data)); + return -1; + } } - return skip_len + sizeof(struct mesa_mpls_hdr); /* mpls header is 4 byte */ + return skip_len + mpls_layer_len; } static int __common_eth_type_dispatch(UINT16 eth_type, const char *next_layer_data, int raw_layer_type, int expect_layer_type) @@ -443,17 +592,50 @@ static int __common_eth_type_dispatch(UINT16 eth_type, const char *next_layer_da return skip_len; } +static int set_vlan_addr(struct layer_addr_vlan *addr, const unsigned char *vlan_tag) +{ + int i; + const struct mesa_vlan_hdr *vhdr; + int vlan_layer_len = 0; + + memset(addr, 0, sizeof(struct layer_addr_vlan)); + + addr->vlan_id = ntohs(*(unsigned short *)vlan_tag) & VLAN_ID_MASK; //compat old value + + for(i = 0; i < MAX_VLAN_ADDR_LAYER; i++){ + vhdr = (struct mesa_vlan_hdr *)vlan_tag; + memcpy(&addr->src_vlan_pkt[i], vlan_tag, sizeof(struct mesa_vlan_hdr)); + vlan_tag += sizeof(struct mesa_vlan_hdr); + addr->src_vlan_layer_num++; + vlan_layer_len += sizeof(struct mesa_vlan_hdr); + if(ETH_P_8021Q != ntohs(vhdr->type)){ + break; + } + } + + return vlan_layer_len; +} + static int vlan8021q_jump_to_layer(const char *raw_data, int raw_layer_type, int expect_layer_type) { int skip_len = 0; - const struct mesa_vlan_hdr *vlan_hdr = (const struct mesa_vlan_hdr *)raw_data; - const char *next_layer_data = raw_data + sizeof(struct mesa_vlan_hdr); + struct layer_addr_vlan vlan_addr; + const char *next_layer_data; + const struct mesa_vlan_hdr *vhdr; + unsigned short next_layer_type; + int vlan_layer_len; if(raw_layer_type == expect_layer_type){ return 0; } + + set_vlan_addr(&vlan_addr, raw_data); + vlan_layer_len = sizeof(struct mesa_vlan_hdr) * vlan_addr.src_vlan_layer_num; + next_layer_data = raw_data + vlan_layer_len; + vhdr = (struct mesa_vlan_hdr *)&vlan_addr.src_vlan_pkt[vlan_addr.src_vlan_layer_num-1]; + next_layer_type = ntohs(vhdr->type); - switch(ntohs(vlan_hdr->type)){ + switch(next_layer_type){ case ETH_P_ARP: if(ADDR_TYPE_ARP == expect_layer_type){ break; @@ -490,12 +672,18 @@ static int vlan8021q_jump_to_layer(const char *raw_data, int raw_layer_type, in skip_len = -1; break; - case 0x8200: /* XinJing捕包发现此类型, 未知什么包 */ - skip_len = -1; + /* QinQ */ + case ETH_P_8021Q: + printf("vlan8021q_jump_to_layer(): multiple VLAN combine to one layer!\n"); + assert(0); + break; + + case ETH_P_MPLS_UC: + skip_len = mpls_jump_to_layer(next_layer_data, ADDR_TYPE_MPLS, expect_layer_type); break; default: - printf("unsupport type in vlan8021q, 0x%x, You can try set the '--vlan-as-mac-in-mac' arg!\n", ntohs(vlan_hdr->type)); + printf("vlan8021q_jump_to_layer(): unsupport type: 0x%x!\n", next_layer_type); skip_len = -1; } @@ -503,7 +691,7 @@ static int vlan8021q_jump_to_layer(const char *raw_data, int raw_layer_type, in return -1; } - return skip_len + sizeof(struct mesa_vlan_hdr); + return skip_len + vlan_layer_len; } static int eth_jump_to_layer(const char *raw_data, int raw_layer_type, int expect_layer_type) @@ -564,6 +752,7 @@ const void *MESA_net_jump_to_layer(const void *raw_data, int raw_layer_type, in return NULL; } + if(ADDR_TYPE_IPV4 == expect_layer_type){ /* 转成纯IPv4地址类型 */ expect_layer_type = __ADDR_TYPE_IP_PAIR_V4; @@ -587,7 +776,7 @@ const void *MESA_net_jump_to_layer(const void *raw_data, int raw_layer_type, in ret = arp_jump_to_layer((const char *)raw_data, raw_layer_type, expect_layer_type); break; case ADDR_TYPE_VLAN: - if(treat_vlan_as_mac_in_mac_sw){ + if(treat_vlan_as_mac_in_mac_sw == 1){ ret = mac_in_mac_jump_to_layer((const char *)raw_data, raw_layer_type, expect_layer_type); }else{ ret = vlan8021q_jump_to_layer((const char *)raw_data, raw_layer_type, expect_layer_type); @@ -609,12 +798,15 @@ const void *MESA_net_jump_to_layer(const void *raw_data, int raw_layer_type, in case ADDR_TYPE_UDP: ret = udp_jump_to_layer((const char *)raw_data, raw_layer_type, expect_layer_type); break; - - case ADDR_TYPE_PPPOE_SES: - case ADDR_TYPE_MPLS: + + case ADDR_TYPE_MPLS: + 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: default: - printf("TODO: jmp 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; } @@ -652,8 +844,7 @@ const void *MESA_net_jump_to_layer_greedy(const void *raw_data, int raw_layer_ty if((ntohs(ip4hdr->ip_off) & IP_MF ) || (ntohs(ip4hdr->ip_off) & IP_OFFMASK)){ /* IP分片不再继续向内层跳转 */ goto done; - } - + } 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. */ @@ -667,13 +858,12 @@ const void *MESA_net_jump_to_layer_greedy(const void *raw_data, int raw_layer_ty case __ADDR_TYPE_IP_PAIR_V6: { //TODO2, - //sapp_runtime_log(20, "MESA_net_jump_to_layer_greedy() not support IPv6 layer yet\n"); goto done; } break; default: - //sapp_runtime_log(20, "MESA_net_jump_to_layer_greedy() not support layer type:%d\n", expect_layer_type); + printf("MESA_net_jump_to_layer_greedy() not support layer type:%d\n", expect_layer_type); goto done; } @@ -710,7 +900,7 @@ UINT8 net_layer_to_ipv4_protocol(int addr_type) break; default: - printf("unknown ip4 protocolr:%d\n", addr_type); + printf("net_layer_to_ipv4_protocol(): unknown ip4 protocolr:%d\n", addr_type); proto = 0xFF; break; } @@ -724,19 +914,19 @@ UINT8 net_layer_to_ipv6_protocol(int addr_type) switch(addr_type){ case ADDR_TYPE_TCP: - proto = 6; //NEXTHDR_TCP; + proto = NEXTHDR_TCP; break; case ADDR_TYPE_UDP: - proto = 17;///NEXTHDR_UDP; + proto = NEXTHDR_UDP; break; case __ADDR_TYPE_IP_PAIR_V4: - proto = 4;///NEXTHDR_IPIP; + proto = NEXTHDR_IPIP; break; default: - printf("unknown ip6 next-hdr:%d\n", addr_type); + printf("net_layer_to_ipv6_protocol(): unknown ip6 next-hdr:%d\n", addr_type); return 0xFF; break; } @@ -756,10 +946,12 @@ UINT16 net_layer_to_ethernet_protocol(int addr_type) switch(addr_type){ case __ADDR_TYPE_IP_PAIR_V4: + case ADDR_TYPE_IPV4: ether_type = ETH_P_IP; break; case __ADDR_TYPE_IP_PAIR_V6: + case ADDR_TYPE_IPV6: ether_type = ETH_P_IPV6; break; @@ -769,7 +961,7 @@ UINT16 net_layer_to_ethernet_protocol(int addr_type) case ADDR_TYPE_TCP: case ADDR_TYPE_UDP: - //sapp_runtime_log(RLOG_LV_FATAL, "%s:%d: Ethernet can't carry addr type:%d directly!\n", __FILE__, __LINE__,addr_type); + printf("%s:%d: Ethernet can't carry addr type:%d directly!\n", __FILE__, __LINE__,addr_type); //assert(0); ether_type = -1; break; @@ -785,10 +977,18 @@ UINT16 net_layer_to_ethernet_protocol(int addr_type) case ADDR_TYPE_ARP: ether_type = ETH_P_ARP; break; + + case ADDR_TYPE_MAC: + if(treat_vlan_as_mac_in_mac_sw==1){ + ether_type = ETHERTYPE_VLAN; + }else{ + ether_type = ETHERTYPE_PANGU_MAC_IN_MAC; + } + break; default: /* to do, unknown type */ - ///sapp_runtime_log(RLOG_LV_FATAL, "%s:%d: Ethernet addr type:%d!\n", __FILE__, __LINE__, addr_type); + printf("%s:%d: unknown ethernet carry addr type:%d!\n", __FILE__, __LINE__, addr_type); ether_type = -1; break; } @@ -797,6 +997,53 @@ UINT16 net_layer_to_ethernet_protocol(int addr_type) } +/* + 将标准Ethernet类型转换为MESA地址类型; +*/ +enum addr_type_t ethernet_protocol_to_net_layer(UINT16 ether_type_host) +{ + enum addr_type_t addrtype = __ADDR_TYPE_INIT; + + switch(ether_type_host){ + case ETH_P_IP: + addrtype = __ADDR_TYPE_IP_PAIR_V4; + break; + + case ETH_P_IPV6: + addrtype = __ADDR_TYPE_IP_PAIR_V6; + break; + + case ETHERTYPE_VLAN: + addrtype = ADDR_TYPE_VLAN; + break; + + case ETH_P_PPP_SES: + addrtype = ADDR_TYPE_PPPOE_SES; + break; + + case ETH_P_MPLS_UC : + addrtype = ADDR_TYPE_MPLS; + break; + + case ETH_P_ARP: + addrtype = ADDR_TYPE_ARP; + break; + + case ETHERTYPE_PANGU_MAC_IN_MAC: + addrtype = ADDR_TYPE_MAC_IN_MAC; + break; + + default: + /* to do, unknown type */ + printf("%s:%d: unknown ethernet carry addr type:0x%x\n", __FILE__, __LINE__, ether_type_host); + ; + break; + } + + return addrtype; +} + + /* 删除末尾的换行符"\r\n" */ void del_last_rn(char *data, int max_len) { @@ -842,6 +1089,8 @@ int get_pkt_len_from_eth_hdr(const struct mesa_ethernet_hdr *ehdr) } + + #ifdef __cplusplus } #endif diff --git a/src/stream_base.h b/src/stream_base.h index 2311cee..33a1a24 100644 --- a/src/stream_base.h +++ b/src/stream_base.h @@ -1,9 +1,10 @@ #ifndef _APP_STREAM_BASE_H_ #define _APP_STREAM_BASE_H_ -#define STREAM_BASE_H_VERSION (20170616) +#define STREAM_BASE_H_VERSION (20201009) #include +#include #include #include @@ -87,6 +88,11 @@ enum addr_type_t{ #define APP_STATE_FAWPKT 0x00 #define APP_STATE_DROPPKT 0x10 + +#define APP_STATE_KILL_FOLLOW 0x40 /* 强制CLOSE当前插件后续的所有插件 */ +#define APP_STATE_KILL_OTHER 0x80 /* 强制CLOSE除当前插件外的所有插件 */ + + /* CHN : 流的类型定义 */ /* ENG : stream type */ enum stream_type_t{ @@ -112,13 +118,14 @@ enum stream_type_t{ enum stream_carry_tunnel_t{ STREAM_TUNNLE_NON = 0, /* default is 0, not tunnel; 默认为0, 非隧道; */ STREAM_TUNNLE_6OVER4 = 1 << 0, - STREAM_TUNNLE_4OVER6 = 1 << 1, - STREAM_TUNNLE_GRE = 1 << 2, + STREAM_TUNNLE_4OVER6 = 1 << 1, + STREAM_TUNNLE_GRE = 1 << 2, STREAM_TUNNLE_IP_IN_IP = 1 << 3, STREAM_TUNNLE_PPTP = 1 << 4, STREAM_TUNNLE_L2TP = 1 << 5, - STREAM_TUNNLE_TEREDO = 1 << 6, + STREAM_TUNNLE_TEREDO = 1 << 6, STREAM_TUNNEL_GPRS_TUNNEL = 1 << 7, + STREAM_TUNNEL_MULTI_MAC = 1 << 8, /* is obsoulte */ }; typedef struct raw_ipfrag_list{ @@ -179,15 +186,15 @@ struct layer_addr_gre #define VLAN_ID_MASK (0x0FFF) #define VLAN_TAG_LEN (4) +#define MAX_VLAN_ADDR_LAYER (3) + struct layer_addr_vlan { - UINT16 vlan_id; /* network order */ -}; - -#define VLAN_ID_LEN 4 -struct tuplevlan -{ - UCHAR vlan_id[VLAN_ID_LEN]; + UINT16 vlan_id; /* network order, old value, to be obsoleted */ + UCHAR src_vlan_layer_num; + UCHAR dst_vlan_layer_num; + UINT32 src_vlan_pkt[MAX_VLAN_ADDR_LAYER]; /* network order */ + UINT32 dst_vlan_pkt[MAX_VLAN_ADDR_LAYER]; /* network order */ }; struct layer_addr_pppoe_session @@ -209,8 +216,16 @@ struct layer_addr_pppoe_session struct layer_addr_mac { - UCHAR dst_mac[MAC_ADDR_LEN]; /* network order */ - UCHAR src_mac[MAC_ADDR_LEN]; /* network order */ + /* + C2S和S2C方向来自不同的链路和设备, 会导致两个方向的mac地址全不一样, 反向注入时不能用传统方式, 即简单的颠倒src和dst, + 修改定义如下, mirror模式下, 还是存储在src_addr中, + API不同了, ABI还是向前兼容的, 结构体内存分布与之前的一致. + */ + struct ethhdr src_addr; + struct ethhdr dst_addr; + + //UCHAR dst_mac[MAC_ADDR_LEN]; /* network order */ + //UCHAR src_mac[MAC_ADDR_LEN]; /* network order */ }; struct layer_addr_ipv4 @@ -276,8 +291,14 @@ struct layer_addr_l2tp #define MAX_MPLS_ADDR_LAYER 4 struct layer_addr_mpls { - unsigned int mpls_pkt[MAX_MPLS_ADDR_LAYER]; - char mpls_layer_num; + unsigned int src_mpls_pkt[MAX_MPLS_ADDR_LAYER]; + unsigned int dest_mpls_pkt[MAX_MPLS_ADDR_LAYER]; + char src_mpls_layer_num; + char dest_mpls_layer_num; + char src_has_ctrl_word; + char dst_has_ctrl_word; + unsigned int src_mpls_ctrl_word; /* refer to RFC4623 */ + unsigned int dst_mpls_ctrl_word; /* refer to RFC4623 */ }; struct layer_addr_pptp @@ -288,9 +309,9 @@ struct layer_addr_pptp struct layer_addr_gtp { - unsigned long long source; + unsigned long long source; /* From Client */ unsigned int src_seq; - unsigned long long dest; + unsigned long long dest; /* From Server */ unsigned int dest_seq; }__attribute__ ((aligned (1))); @@ -327,7 +348,9 @@ struct layer_addr struct layer_addr_pptp *pptp; struct layer_addr_mac_in_mac *mimac; struct layer_addr_gtp *gtp; - void *paddr; + struct layer_addr_mpls *mpls; + + void *paddr; }; }; @@ -399,6 +422,18 @@ struct streaminfo }; +typedef struct { + unsigned int type; + unsigned int length; + union{ + char char_value; + short short_value; + int int_value; + long long_value; + char array_value[8]; + void *ptr_value; /* more than 8bytes data, or complex struct. */ + }; +}SAPP_TLV_T; #ifdef __cplusplus extern "C" { @@ -517,4 +552,3 @@ const raw_ipfrag_list_t *ip_plug_get_raw_ipfrag_list(int thread_num, enum addr_t #endif #endif -