diff options
| author | lijia <[email protected]> | 2018-10-24 09:36:45 +0800 |
|---|---|---|
| committer | lijia <[email protected]> | 2018-10-24 09:36:45 +0800 |
| commit | 86a43b4d325ddc850fa9dc4711670880f35b11e8 (patch) | |
| tree | 8356a056ac9bfb8cf14fcf57f113dd306b4277d1 /src/common/flwd_common_tool.c | |
create new project.
Diffstat (limited to 'src/common/flwd_common_tool.c')
| -rw-r--r-- | src/common/flwd_common_tool.c | 911 |
1 files changed, 911 insertions, 0 deletions
diff --git a/src/common/flwd_common_tool.c b/src/common/flwd_common_tool.c new file mode 100644 index 0000000..e2e1b36 --- /dev/null +++ b/src/common/flwd_common_tool.c @@ -0,0 +1,911 @@ +#include "flowood.h" +#include "flowood_fun.h" +#include "flwd_net.h" +#include "MESA_handle_logger.h" +#include "stream.h" +#include <linux/if_ether.h> +#include <linux/if_arp.h> +#include <arpa/inet.h> +#include <stdio.h> +#include <unistd.h> +#include <pthread.h> +#include <string.h> +#include <assert.h> + + +static const unsigned char flwd_adapt_sleep_time_table[100] = +{ + 5, 5, 5, 5, 5, 3, 3, 3, 3, 3, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ��Ϊ������pollģʽ, ����ɹ��ɹ��հ�����30%����, ˵��ϵͳ���رȽ�����, �Ͳ���usleep */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + + +void flwd_adapt_sleep(int success_work_times_in_recent_100) +{ + assert(success_work_times_in_recent_100 < 100); + + if(flwd_adapt_sleep_time_table[success_work_times_in_recent_100] > 0){ + usleep(flwd_adapt_sleep_time_table[success_work_times_in_recent_100]); + } +} + + +flwd_ip_region_type_t flwd_ipv4_location(unsigned int ip4addr_host_order) +{ + +#if FLWD_RUN_IN_CEIEC_TEST + /* �ڲ����Ե�ַ�����ж�!!! */ + if((ip4addr_host_order & 0xFFFFFF00) == 0xAC100A00){ /* 172.16.10.5Ϊ���������, ��λ���� */ + return FLWD_IP_REGION_OUTLAND; + } + if((ip4addr_host_order & 0xFFFFFF00) == 0xAC100B00){/* 172.16.11.xxΪ�ͻ���IP, ��λ���� */ + return FLWD_IP_REGION_INLAND; + } +#endif + /* TODO, ����IP��ַ���жϵ���λ��, �˴���д���������ڲ�IP */ + if(((ip4addr_host_order & 0xFF000000) == 0x0a000000) /* 10/8 */ + ||((ip4addr_host_order & 0xFFF00000) == 0xAC100000 ) /* 172.16/12 */ + ||((ip4addr_host_order & 0xFFFF0000) == 0xC0A80000)){ /* 192.168/16 */ + return FLWD_IP_REGION_INLAND; + } + + return FLWD_IP_REGION_OUTLAND; +} + +flwd_ip_region_type_t flwd_ipv6_location(const struct in6_addr *ip6addr_net) +{ + /* TODO, IP��ַ�� */ + + return FLWD_IP_REGION_INLAND; +} + + +/* ͨ��IP��ַ��λ��, �õ���ǰ���ʵ�Ŀ��IP���ڵ���λ�� */ +flwd_ip_region_type_t flwd_dstip_location(const flwd_tuple5_t *tuple5) +{ + unsigned int actual_dip_v4_host; + + if(FLWD_IP_ADDR_TYPE_V4 == tuple5->addr_type){ + if(tuple5->dir_reverse != 0){ + actual_dip_v4_host = ntohl(tuple5->ippair_v4.sip_net_order); + }else{ + actual_dip_v4_host = ntohl(tuple5->ippair_v4.dip_net_order); + } + + return flwd_ipv4_location(actual_dip_v4_host); + }else{ + /* TODO, IPv6 */ + flwd_log(30, "recv ipv6 packet, but not support ipv6 addr location yet!\n"); + return FLWD_IP_REGION_INLAND; + } + + return FLWD_IP_REGION_INLAND; +} + + +const char *flwd_ip_region_ntop(int ip_region_type) +{ + if((int)FLWD_IP_REGION_INLAND == ip_region_type){ + return "inland"; + } + + return "outland"; +} + + +const char *flwd_tuple5_ntop(int tid, const flwd_tuple5_t *tuple5) +{ + static char str_mbuf[FLWD_MAX_THREAD_NUM][256]; + char ip_src_str[64], ip_dst_str[64]; + unsigned short actual_sport, actual_dport; + + if(flwd_likely(FLWD_IP_ADDR_TYPE_V4 == tuple5->addr_type)){ + if(tuple5->dir_reverse){ + inet_ntop(AF_INET, &tuple5->ippair_v4.dip_net_order, ip_src_str, 64); + inet_ntop(AF_INET, &tuple5->ippair_v4.sip_net_order, ip_dst_str, 64); + actual_sport = ntohs(tuple5->dport_net_order); + actual_dport = ntohs(tuple5->sport_net_order); + }else{ + inet_ntop(AF_INET, &tuple5->ippair_v4.sip_net_order, ip_src_str, 64); + inet_ntop(AF_INET, &tuple5->ippair_v4.dip_net_order, ip_dst_str, 64); + actual_sport = ntohs(tuple5->sport_net_order); + actual_dport = ntohs(tuple5->dport_net_order); + } + }else{ + if(tuple5->dir_reverse){ + inet_ntop(AF_INET6, &tuple5->ippair_v6->dip_net_order, ip_src_str, 64); + inet_ntop(AF_INET6, &tuple5->ippair_v6->sip_net_order, ip_dst_str, 64); + actual_sport = ntohs(tuple5->dport_net_order); + actual_dport = ntohs(tuple5->sport_net_order); + }else{ + inet_ntop(AF_INET6, &tuple5->ippair_v6->sip_net_order, ip_src_str, 64); + inet_ntop(AF_INET6, &tuple5->ippair_v6->dip_net_order, ip_dst_str, 64); + actual_sport = ntohs(tuple5->sport_net_order); + actual_dport = ntohs(tuple5->dport_net_order); + } + } + + snprintf(str_mbuf[tid], 256, "%s.%u > %s.%u", ip_src_str, actual_sport, + ip_dst_str, actual_dport); + + return str_mbuf[tid]; +} + + +const char *flwd_tuple5_ntop_r(const flwd_tuple5_t *tuple5, char *str_mbuf, int mbuf_len) +{ + char ip_src_str[64], ip_dst_str[64]; + unsigned short actual_sport, actual_dport; + + if(flwd_likely(FLWD_IP_ADDR_TYPE_V4 == tuple5->addr_type)){ + if(tuple5->dir_reverse){ + inet_ntop(AF_INET, &tuple5->ippair_v4.dip_net_order, ip_src_str, 64); + inet_ntop(AF_INET, &tuple5->ippair_v4.sip_net_order, ip_dst_str, 64); + actual_sport = ntohs(tuple5->dport_net_order); + actual_dport = ntohs(tuple5->sport_net_order); + }else{ + inet_ntop(AF_INET, &tuple5->ippair_v4.sip_net_order, ip_src_str, 64); + inet_ntop(AF_INET, &tuple5->ippair_v4.dip_net_order, ip_dst_str, 64); + actual_sport = ntohs(tuple5->sport_net_order); + actual_dport = ntohs(tuple5->dport_net_order); + } + }else{ + if(tuple5->dir_reverse){ + inet_ntop(AF_INET6, &tuple5->ippair_v6->dip_net_order, ip_src_str, 64); + inet_ntop(AF_INET6, &tuple5->ippair_v6->sip_net_order, ip_dst_str, 64); + actual_sport = ntohs(tuple5->dport_net_order); + actual_dport = ntohs(tuple5->sport_net_order); + }else{ + inet_ntop(AF_INET6, &tuple5->ippair_v6->sip_net_order, ip_src_str, 64); + inet_ntop(AF_INET6, &tuple5->ippair_v6->dip_net_order, ip_dst_str, 64); + actual_sport = ntohs(tuple5->sport_net_order); + actual_dport = ntohs(tuple5->dport_net_order); + } + } + + snprintf(str_mbuf, mbuf_len, "%s.%u > %s.%u", + ip_src_str, actual_sport, + ip_dst_str, actual_dport); + + return str_mbuf; +} + +/* + �ж�flwd_ip_t��ַ�Ƿ����. + 1:��ͬ; + 0:��ͬ; +*/ +int flwd_ipt_equal(const flwd_ip_t *ip1, const flwd_ip_t *ip2) +{ + int diff = 0; + if(ip1->addr_type != ip2->addr_type){ + return 0; + } + + if(FLWD_IP_ADDR_TYPE_V4 == ip1->addr_type){ + if(ip1->addr_ipv4 == ip2->addr_ipv4){ + diff = 1; + }else{ + diff = 0; + } + }else{ + if(memcmp(&ip1->addr_ipv6, &ip2->addr_ipv6, sizeof(struct in6_addr)) == 0){ + diff = 1; + }else{ + diff = 0; + } + } + + return diff; +} + + +const char *flwd_ipt_ntop_r(const flwd_ip_t *ipbin, char *str_mbuf, int mbuf_len) +{ + ///char ip_str[64]; + + if(flwd_likely(FLWD_IP_ADDR_TYPE_V4 == ipbin->addr_type)){ + inet_ntop(AF_INET, &ipbin->addr_ipv4, str_mbuf, mbuf_len); + }else{ + inet_ntop(AF_INET6, &ipbin->addr_ipv6, str_mbuf, mbuf_len); + } + + return str_mbuf; +} + +/* + ��ַmemcpy, + ��ַ��ָ��ָ��ǰ�̵߳�ȫ�ֱ���, ֻ���ڵ�ǰ��������ջ��ʹ��, ���غ��ַ��ʧЧ. +*/ +flwd_tuple5_t *flwd_tuple5_dup_to_stack(int tid, flwd_tuple5_t *dst_tuple5, const flwd_tuple5_t *src_tuple5) +{ + memcpy(dst_tuple5, src_tuple5, sizeof(flwd_tuple5_t)); + + if(FLWD_IP_ADDR_TYPE_V6 == src_tuple5->addr_type){ + memcpy(&flwd_thread_val[tid].nat_key_ipv6_buf, src_tuple5->ippair_v6, sizeof(flwd_ippair_v6_t)); + dst_tuple5->ippair_v6 = &flwd_thread_val[tid].nat_key_ipv6_buf; + } + + return dst_tuple5; +} + +/* + ��ַmemcpy, + ��ַ��ָ��ָ��malloc��ȫ���ڴ�, ʹ�ú�ע��free. +*/ +flwd_tuple5_t *flwd_tuple5_dup_to_heap(flwd_tuple5_t *dst_tuple5, const flwd_tuple5_t *src_tuple5) +{ + memcpy(dst_tuple5, src_tuple5, sizeof(flwd_tuple5_t)); + + if(FLWD_IP_ADDR_TYPE_V6 == src_tuple5->addr_type){ + dst_tuple5->ippair_v6 = (flwd_ippair_v6_t *)malloc(sizeof(flwd_ippair_v6_t)); + memcpy(dst_tuple5->ippair_v6, src_tuple5->ippair_v6, sizeof(flwd_ippair_v6_t)); + } + + return dst_tuple5; +} + +/* + ��Ϊtuple5�Ĵ洢Ϊ�˷���hash����, ʹ�ô��ַ��ΪԴ��Ĭ�Ϲ���, �����ܵߵ�����ʵ��Ԫ��ķ�������, + �˺�������dir�ķ���, �ָ�������ԭʼ��Ԫ��, ��sip�϶���ԭʼ����������ԴIP! +*/ +void flwd_tuple5_adjust_dir(flwd_tuple5_t *tuple5) +{ + unsigned short tshort; + unsigned int tint; + struct in6_addr tin6; + + if(0 == tuple5->dir_reverse){ + return; + } + + tshort = tuple5->sport_net_order; + tuple5->sport_net_order = tuple5->dport_net_order; + tuple5->dport_net_order = tshort; + + if(flwd_likely(FLWD_IP_ADDR_TYPE_V4 == tuple5->addr_type)){ + tint = tuple5->ippair_v4.sip_net_order; + tuple5->ippair_v4.sip_net_order = tuple5->ippair_v4.dip_net_order; + tuple5->ippair_v4.dip_net_order = tint; + }else{ + memcpy(&tin6, &tuple5->ippair_v6->sip_net_order, sizeof(struct in6_addr)); + memcpy(&tuple5->ippair_v6->sip_net_order, &tuple5->ippair_v6->dip_net_order, sizeof(struct in6_addr)); + memcpy(&tuple5->ippair_v6->dip_net_order, &tin6, sizeof(struct in6_addr)); + } + + return; +} + + +void *flwd_calloc(int tid, size_t nmemb, size_t size) +{ + /* todo: dictator */ + return calloc(nmemb, size); +} + + +void *flwd_malloc(int tid, size_t size) +{ + /* todo: dictator */ + return malloc(size); +} + + +void flwd_free(int tid, void *ptr) +{ + /* todo: dictator */ + free(ptr); +} + +static int inline flwd_build_tuple4v4_key(flwd_tuple5_t *nat_key_v4, const flwd_raw_pkt_t *raw_pkt) +{ + const flwd_ipv4_hdr_t *flwd_iphdr = (flwd_ipv4_hdr_t *)raw_pkt->inner_ip_layer_hdr; + unsigned short raw_sport, raw_dport; + const flwd_tcp_hdr_t *flwd_tcphdr; + const flwd_udp_hdr_t *flwd_udphdr; + + nat_key_v4->addr_type = FLWD_IP_ADDR_TYPE_V4; + + if(IPPROTO_TCP == flwd_iphdr->ip_p){ + flwd_tcphdr = (flwd_tcp_hdr_t *)((char *)flwd_iphdr + flwd_iphdr->ip_hl * 4); + raw_sport = flwd_tcphdr->th_sport; + raw_dport = flwd_tcphdr->th_dport; + nat_key_v4->protocol = IPPROTO_TCP; + }else if(IPPROTO_UDP == flwd_iphdr->ip_p){ + flwd_udphdr = (flwd_udp_hdr_t *)((char *)flwd_iphdr + flwd_iphdr->ip_hl * 4); + raw_sport = flwd_udphdr->uh_sport; + raw_dport = flwd_udphdr->uh_dport; + nat_key_v4->protocol = IPPROTO_UDP; + }else{ + flwd_log(30, "ip protocol is:%d, not support yet!\n", flwd_iphdr->ip_p); + return -1; + } + + /* key�Ķ������: + IP��ַ�����ΪԴ, �����ַһ��, �˿ڴ����ΪԴ, + ����Ǹ����Դ��涨, ����ν˭�����С, + Ϊ��Ч��, ֱ��ʹ�������ַ�����ֵ�Ƚϴ�С, ����ÿ�ζ���ntoh�任; + */ + if(flwd_iphdr->ip_src.s_addr > flwd_iphdr->ip_dst.s_addr){ + nat_key_v4->ippair_v4.sip_net_order = flwd_iphdr->ip_src.s_addr; + nat_key_v4->ippair_v4.dip_net_order = flwd_iphdr->ip_dst.s_addr; + nat_key_v4->sport_net_order = raw_sport; + nat_key_v4->dport_net_order = raw_dport; + nat_key_v4->dir_reverse = 0; + }else if(flwd_iphdr->ip_src.s_addr < flwd_iphdr->ip_dst.s_addr){ + nat_key_v4->ippair_v4.sip_net_order = flwd_iphdr->ip_dst.s_addr; + nat_key_v4->ippair_v4.dip_net_order = flwd_iphdr->ip_src.s_addr; + nat_key_v4->sport_net_order = raw_dport; + nat_key_v4->dport_net_order = raw_sport; + nat_key_v4->dir_reverse = 1; + }else{ + if(raw_sport > raw_dport){ + nat_key_v4->ippair_v4.sip_net_order = flwd_iphdr->ip_src.s_addr; + nat_key_v4->ippair_v4.dip_net_order = flwd_iphdr->ip_dst.s_addr; + nat_key_v4->sport_net_order = raw_sport; + nat_key_v4->dport_net_order = raw_dport; + nat_key_v4->dir_reverse = 0; + }else{ + nat_key_v4->ippair_v4.sip_net_order = flwd_iphdr->ip_dst.s_addr; + nat_key_v4->ippair_v4.dip_net_order = flwd_iphdr->ip_src.s_addr; + nat_key_v4->sport_net_order = raw_dport; + nat_key_v4->dport_net_order = raw_sport; + nat_key_v4->dir_reverse = 1; + } + } + + return nat_key_v4->dir_reverse; +} + +static inline int flwd_build_tuple4v6_key(int tid, flwd_tuple5_t *nat_key_v6, const flwd_raw_pkt_t *raw_pkt) +{ + const flwd_ipv6_hdr_t *flwd_ip6hdr = (flwd_ipv6_hdr_t *)raw_pkt->inner_ip_layer_hdr; + unsigned short raw_sport, raw_dport; + const flwd_tcp_hdr_t *flwd_tcphdr; + const flwd_udp_hdr_t *flwd_udphdr; + flwd_ippair_v6_t *nat_key_ipv6_buf = &flwd_thread_val[tid].nat_key_ipv6_buf; /* ����ջ����ʱ��ַ, ʹ��ȫ�ֱ����Ļ�����, ����malloc/free */ + int diff; + + nat_key_v6->addr_type = FLWD_IP_ADDR_TYPE_V6; + + if(IPPROTO_TCP == flwd_ip6hdr->ip6_nxt_hdr){ + flwd_tcphdr = (flwd_tcp_hdr_t *)((char *)flwd_ip6hdr + sizeof(flwd_ipv6_hdr_t)); + raw_sport = flwd_tcphdr->th_sport; + raw_dport = flwd_tcphdr->th_dport; + nat_key_v6->protocol = IPPROTO_TCP; + }if(IPPROTO_UDP == flwd_ip6hdr->ip6_nxt_hdr){ + flwd_udphdr = (flwd_udp_hdr_t *)((char *)flwd_ip6hdr + sizeof(flwd_ipv6_hdr_t)); + raw_sport = flwd_udphdr->uh_sport; + raw_dport = flwd_udphdr->uh_dport; + nat_key_v6->protocol = IPPROTO_UDP; + }else{ + /* ����Э���ݲ�֧�� */ + return -1; + } + + nat_key_v6->ippair_v6 = nat_key_ipv6_buf; + + /* key�Ķ������: + IP��ַ�����ΪԴ, �����ַһ��, �˿ڴ����ΪԴ, + ��Ϊ���Ǹ����Դ��涨, ����ν˭�����С, + Ϊ��Ч��, ֱ��ʹ�������ַ�����ֵ�Ƚϴ�С, ����ÿ�ζ���ntoh�任; + */ + diff = memcmp(&flwd_ip6hdr->ip6_src, &flwd_ip6hdr->ip6_dst, sizeof( struct in6_addr)); + if(diff > 0){ + memcpy(&nat_key_ipv6_buf->sip_net_order, &flwd_ip6hdr->ip6_src, sizeof( struct in6_addr)); + memcpy(&nat_key_ipv6_buf->dip_net_order, &flwd_ip6hdr->ip6_dst, sizeof( struct in6_addr)); + nat_key_v6->sport_net_order = raw_sport; + nat_key_v6->dport_net_order = raw_dport; + nat_key_v6->dir_reverse = 0; + }else if(diff < 0){ + memcpy(&nat_key_ipv6_buf->sip_net_order, &flwd_ip6hdr->ip6_dst, sizeof( struct in6_addr)); + memcpy(&nat_key_ipv6_buf->dip_net_order, &flwd_ip6hdr->ip6_src, sizeof( struct in6_addr)); + nat_key_v6->sport_net_order = raw_dport; + nat_key_v6->dport_net_order = raw_sport; + nat_key_v6->dir_reverse = 1; + }else{ + if(raw_sport > raw_dport){ + memcpy(&nat_key_ipv6_buf->sip_net_order, &flwd_ip6hdr->ip6_src, sizeof( struct in6_addr)); + memcpy(&nat_key_ipv6_buf->dip_net_order, &flwd_ip6hdr->ip6_dst, sizeof( struct in6_addr)); + nat_key_v6->sport_net_order = raw_sport; + nat_key_v6->dport_net_order = raw_dport; + nat_key_v6->dir_reverse = 0; + }else{ + memcpy(&nat_key_ipv6_buf->sip_net_order, &flwd_ip6hdr->ip6_dst, sizeof( struct in6_addr)); + memcpy(&nat_key_ipv6_buf->dip_net_order, &flwd_ip6hdr->ip6_src, sizeof( struct in6_addr)); + nat_key_v6->sport_net_order = raw_dport; + nat_key_v6->dport_net_order = raw_sport; + nat_key_v6->dir_reverse = 1; + } + } + + return 0; +} + +/* + TODO: + IP��Ƭ��ô��? ��DNS��Ӧ���, ���ж��additionl-records, �ͳ�����MTU,Ҫ��Ƭ. + NAT��key����Ԫ��, IP��Ƭֻ�е�һƬ����Я���˿�, (��������������Ƭ��С��20�ֽ�, TCP��ͷҲ��ȫ, �װ�Ҳû�ж˿�), + + ���ȡ����: ���������Ƚ���������IP��Ƭ��, ������ɺ�, ����NATת��, ����ʱ��������Ƭ. + + HASH����ʱ, + ��ΪSNAT->C2S����, SNAT->S2C����, DNAT->C2S����, DNAT->S2C����, + ��������ĵ�ַ��ͬ, + ����, ����һ�����ӵ��ڲ���ַ���ⲿ��ַ��˵, Ҫ��������key, ָ��ͬһ��nat_info. + + return value: + 1: key�ĵ�ַ��ԭ��ʵ��Ԫ�����˷�ת; + 0: key�ĵ�ַ����ʵ��Ԫ���ַ; +*/ +int flwd_build_tuple4_key(int tid, flwd_tuple5_t *nat_key, const flwd_raw_pkt_t *raw_pkt) +{ + int ret; + const flwd_eth_hdr_t *flwd_ethhdr = (flwd_eth_hdr_t *)raw_pkt->inner_pkt_data; + unsigned short eth_type = ntohs(flwd_ethhdr->h_proto); + + if(ETH_P_IP == eth_type){ + ret = flwd_build_tuple4v4_key(nat_key, raw_pkt); + }else if(ETH_P_IPV6 == eth_type){ + ret = flwd_build_tuple4v6_key(tid, nat_key, raw_pkt); + }else{ + /* unsuport or unknown protocol */ + //flwd_log(20, "unsupport ethernet protocol, 0x%x", eth_type); + ret = -1; + } + + return ret; +} + +/* + IP����ϵͳ�ڲ���ַ��ƽ̨, Maat��ַ�ṹ��һ��, ɨ��֮ǰҪ��ת��. +*/ +int flwd_tuple5_to_stream_addr(int tid, const flwd_tuple5_t *tuple5, struct ipaddr *stream_addr) +{ + if(FLWD_IP_ADDR_TYPE_V4 == tuple5->addr_type){ + stream_addr->addrtype = ADDR_TYPE_IPV4; + stream_addr->addrlen = sizeof(int); + if(0 == tuple5->dir_reverse){ + flwd_thread_val[tid].addrv4_convert_buf.saddr = tuple5->ippair_v4.sip_net_order; + flwd_thread_val[tid].addrv4_convert_buf.daddr = tuple5->ippair_v4.dip_net_order; + flwd_thread_val[tid].addrv4_convert_buf.source = tuple5->sport_net_order; + flwd_thread_val[tid].addrv4_convert_buf.dest = tuple5->dport_net_order; + }else{ + flwd_thread_val[tid].addrv4_convert_buf.saddr = tuple5->ippair_v4.dip_net_order; + flwd_thread_val[tid].addrv4_convert_buf.daddr = tuple5->ippair_v4.sip_net_order; + flwd_thread_val[tid].addrv4_convert_buf.source = tuple5->dport_net_order; + flwd_thread_val[tid].addrv4_convert_buf.dest = tuple5->sport_net_order; + } + + stream_addr->v4 = &flwd_thread_val[tid].addrv4_convert_buf; + }else{ + stream_addr->addrtype = ADDR_TYPE_IPV6; + stream_addr->addrlen = sizeof(sizeof(struct in6_addr)); + if(0 == tuple5->dir_reverse){ + memcpy(flwd_thread_val[tid].addrv6_convert_buf.saddr, &tuple5->ippair_v6->sip_net_order, sizeof(struct in6_addr)); + memcpy(flwd_thread_val[tid].addrv6_convert_buf.daddr, &tuple5->ippair_v6->dip_net_order, sizeof(struct in6_addr)); + flwd_thread_val[tid].addrv6_convert_buf.source = tuple5->sport_net_order; + flwd_thread_val[tid].addrv6_convert_buf.dest = tuple5->dport_net_order; + }else{ + memcpy(flwd_thread_val[tid].addrv6_convert_buf.saddr, &tuple5->ippair_v6->dip_net_order, sizeof(struct in6_addr)); + memcpy(flwd_thread_val[tid].addrv6_convert_buf.daddr, &tuple5->ippair_v6->sip_net_order, sizeof(struct in6_addr)); + flwd_thread_val[tid].addrv6_convert_buf.source = tuple5->dport_net_order; + flwd_thread_val[tid].addrv6_convert_buf.dest = tuple5->sport_net_order; + } + + stream_addr->v6 = &flwd_thread_val[tid].addrv6_convert_buf; + } + + return 0; +} + +/* + �յ�ԭʼ����, Ԥ����, ���ݲ���ģʽ, topģʽ��ͬ, ���ò�ͬ���ָ���ַ. + +*/ +int flwd_pre_process_pkt_input(flwd_device_handle_t *rcv_device_handle, flwd_raw_pkt_t *raw_pkt) +{ + if((TOPO_ACC_LINK_FWD == rcv_device_handle->io_para.topo_mode) + || (TOPO_FWD_LINK_ACC == rcv_device_handle->io_para.topo_mode)){ + /* �������ش�ת�����ط����հ�, ����vxlan��. */ + raw_pkt->inner_ip_layer_hdr = (const char *)raw_pkt->outer_pkt_data+ FLWD_VXLAN_OUTER_PACKET_LEN + sizeof(flwd_eth_hdr_t); /* �����������vxlanͷ�����ڲ�ethernetͷ�� */ + raw_pkt->inner_pkt_data = (char *)raw_pkt->outer_pkt_data + FLWD_VXLAN_OUTER_PACKET_LEN; /* ָ���ڲ�ethernet��ʼ��ַ */ + raw_pkt->inner_pkt_len = raw_pkt->outer_pkt_len - FLWD_VXLAN_OUTER_PACKET_LEN; + }else if(TOPO_ACC_LINK_USER == rcv_device_handle->io_para.topo_mode){ + /* �û��˽��붼����ͨEthernet��, TODO, �����tap�豸��??? */ + raw_pkt->inner_ip_layer_hdr = (const char *)raw_pkt->outer_pkt_data + sizeof(flwd_eth_hdr_t); + raw_pkt->inner_pkt_data = (char *)raw_pkt->outer_pkt_data; + raw_pkt->inner_pkt_len = raw_pkt->outer_pkt_len; + }else if(TOPO_FWD_LINK_GDEV == rcv_device_handle->io_para.topo_mode){ +#if FLWD_NO_GDEV_ENV + raw_pkt->inner_ip_layer_hdr = (const char *)raw_pkt->outer_pkt_data + sizeof(flwd_eth_hdr_t); + raw_pkt->inner_pkt_data = (char *)raw_pkt->outer_pkt_data; + raw_pkt->inner_pkt_len = raw_pkt->outer_pkt_len; +#else + /* mrtunnat�����Ѿ�ж����vxlanͷ�� */ + raw_pkt->inner_ip_layer_hdr = (const char *)raw_pkt->outer_pkt_data + sizeof(flwd_eth_hdr_t); + raw_pkt->inner_pkt_data = (char *)raw_pkt->outer_pkt_data; + raw_pkt->inner_pkt_len = raw_pkt->outer_pkt_len; +#endif + } + + return 0; +} + + +/* + dynamic, static����, htable�������ݵķ�ʽ��һ��, ��Ҫ�����. +*/ +flwd_active_ip_t *flwd_ip_pool_search(unsigned char act_ip_origin, const MESA_htable_handle table, const uchar * key, uint size) +{ + flwd_active_ip_t *act_ip_list_head; + + if(FLWD_ACT_IP_DYNAMIC == act_ip_origin){ + return (flwd_active_ip_t *)MESA_htable_search(table, key, size); + } + + /* ��̬IP����group_idΪkey, IP_listΪdata */ + act_ip_list_head = (flwd_active_ip_t *)MESA_htable_search(table, key, size); +#if 1 + return act_ip_list_head; +#else + if(NULL == act_ip_list_head){ + return NULL; + } + + tmp_ip = act_ip_list_head; + do{ + /* ʹ������֮��Ƚϳ���ipv6�ı�����ַ���бȽ� */ + if(memcmp(key, &tmp_ip->active_ip_net_order.addr_ipv6, size) == 0){ + break; + } + if(tmp_ip->active_ip_list_node.nextele){ + tmp_ip = (flwd_active_ip_t *)tmp_ip->active_ip_list_node.nextele->quiddity; + }else{ + tmp_ip = NULL; + break; + } + }while(tmp_ip != act_ip_list_head); + + return tmp_ip; +#endif +} + + +static void __phony_del_cb(void *arg) +{ + return; /* ֻɾ��htable�����ṹ��key, ��ɾ��data */ +} + +/* + TODO: dynamic, static����, htable�������ݵķ�ʽ��һ��, ��Ҫ�����. +*/ +void flwd_ip_pool_del(unsigned char act_ip_origin, MESA_htable_handle table, unsigned int policy_group_id, + void (* del_cb)(void *), const flwd_active_ip_t *maat_cb_tobe_del_ip) +{ + flwd_active_ip_t *act_ip_list_head, *tmp_ip; + MESA_list_t *list_node; + ///flwd_active_ip_t *in_htable_tobe_del_ip; + const unsigned char *hkey; + unsigned int hsize; + unsigned char static_ip_group_key[64]; + int static_ip_group_key_len = 64; + int found = 0; + int to_be_free_group_id_key = 0; + char ip_str[64]; + + /* ��̬IPֱ��ɾ�� */ + if(FLWD_ACT_IP_DYNAMIC == act_ip_origin){ + MESA_htable_del(table, (unsigned char *)&maat_cb_tobe_del_ip->active_ip_net_order.addr_value, maat_cb_tobe_del_ip->active_ip_net_order.addr_len, del_cb); + return; + } + + flwd_policy_group_id_key_gen(policy_group_id, static_ip_group_key, &static_ip_group_key_len); + + act_ip_list_head = (flwd_active_ip_t *)MESA_htable_search(table, static_ip_group_key, static_ip_group_key_len); + if(NULL == act_ip_list_head){ + flwd_log(30, "del static ip pool, but '%s' not in htable!\n", flwd_ipt_ntop_r(&maat_cb_tobe_del_ip->active_ip_net_order, ip_str, 64)); + return; + } + + if(FLWD_IP_ADDR_TYPE_V4 == maat_cb_tobe_del_ip->active_ip_net_order.addr_type){ + hkey = (unsigned char *)&maat_cb_tobe_del_ip->active_ip_net_order.addr_ipv4; + hsize = sizeof(int); + }else{ + hkey = (unsigned char *)&maat_cb_tobe_del_ip->active_ip_net_order.addr_ipv6; + hsize = sizeof(struct in6_addr); + } + + list_node = &act_ip_list_head->active_ip_list_node; + + do{ + tmp_ip = (flwd_active_ip_t *)list_node->quiddity; + if(memcmp(hkey, &tmp_ip->active_ip_net_order.addr_value, hsize) == 0){ + found = 1; + break; + } + list_node = list_node->nextele; + }while(list_node != &act_ip_list_head->active_ip_list_node); + + if(found != 0){ + if(MESA_list_is_empty(&act_ip_list_head->active_ip_list_node)){ + /* �˴���empty��ʾֻ��һ��ͷ�ڵ�, ������IRϵͳ��˵, ͷ�ڵ�Ҳ�洢������, ������������empty! */ + to_be_free_group_id_key = 1; + } + + MESA_list_del(&act_ip_list_head->active_ip_list_node, &tmp_ip->active_ip_list_node); + + /* �˴�ֻ��htableɾ����ip_key���������ݽṹ, ʵ�ʵ�data��act_ip_list_head, ��ɾ��, ������IP����ɾ�����ɾ����ip_list */ + MESA_htable_del(table, hkey, hsize, __phony_del_cb); + + del_cb((void *)tmp_ip); /* ɾ������IP */ + + if(to_be_free_group_id_key != 0){ + /* static_pool��ǰpolicy_idɾ�����һ��IP, �Ѿ�����, ��Ҫ��HASH����ɾ����policy_idΪkey�Ľṹ */ + MESA_htable_del(table, static_ip_group_key, strlen((const char *)static_ip_group_key), __phony_del_cb); + } + } + + return; +} + + +void flwd_del_last_rn(char *data, int max_len) +{ + int i; + for(i = 0; i < max_len; i++){ + if(('\r' == data[i]) || ('\n' == data[i])){ + data[i] = '\0'; + return; + } + } + + return; +} + + +unsigned char *flwd_policy_group_id_key_gen(unsigned int policy_group_id, unsigned char *out_key, int *out_key_len) +{ + int actual_key_len; + + if(NULL == out_key_len || *out_key_len < 16){ + return (unsigned char *)"ERROR"; + } + + actual_key_len = snprintf((char *)out_key, *out_key_len, "GPID%u", policy_group_id); + + *out_key_len = actual_key_len; + + return out_key; +} + + +/* + ����sapp�������, ��ӡ��ǰ������Ԫ��, ����ֱ��ʹ��printadd, ��Ϊ������ʱ���ܻ�ߵ�Դ��Ŀ���ַ. +*/ +const char *flwd_debug_print_tuple4(const void *a_packet, int tid) +{ + char debug_ip_src_str[64], debug_ip_dst_str[64]; + unsigned short debug_sport, debug_dport; + const flwd_ipv4_hdr_t *ipv4_hdr; + const flwd_ipv6_hdr_t *ipv6_hdr; + const flwd_tcp_hdr_t *thdr; + const flwd_udp_hdr_t *uhdr; + static char tuple4_str[FLWD_MAX_THREAD_NUM][128]; + unsigned char *ip_hdr = (unsigned char *)a_packet; + unsigned char protocol; + + if(tid >= FLWD_MAX_THREAD_NUM){ + assert(0); + } + + if(NULL == a_packet){ + return "NULL"; + } + + if(flwd_cfg_val.flwd_log_level <= 10){ + if(0x40 == (ip_hdr[0] & 0xF0)){ /* sapp������IP��ͷ, ���Ի�ȡraw_pkt, ���߿�IPͷ����һ����IPV4����IPV6 */ + ipv4_hdr = (flwd_ipv4_hdr_t *)a_packet; + protocol = ipv4_hdr->ip_p; + }else{ + ipv6_hdr = (flwd_ipv6_hdr_t *)a_packet; + protocol = ipv6_hdr->ip6_nxt_hdr; + } + + inet_ntop(AF_INET, &ipv4_hdr->ip_src.s_addr, debug_ip_src_str, 64); + inet_ntop(AF_INET, &ipv4_hdr->ip_dst.s_addr, debug_ip_dst_str, 64); + if(6 == protocol){ + thdr = (flwd_tcp_hdr_t *)((char *)a_packet + ipv4_hdr->ip_hl * 4); + debug_sport = ntohs(thdr->th_sport); + debug_dport = ntohs(thdr->th_dport); + }else if (17 == protocol){ + uhdr = (flwd_udp_hdr_t *)((char *)a_packet + ipv4_hdr->ip_hl * 4); + debug_sport = ntohs(uhdr->uh_sport); + debug_dport = ntohs(uhdr->uh_dport); + }else{ + debug_sport = 0; + debug_dport = 0; + } + } + + snprintf(tuple4_str[tid], 128, "%s,%u ---> %s,%u", debug_ip_src_str, debug_sport, debug_ip_dst_str, debug_dport); + + return tuple4_str[tid]; +} + + +/* + ����sapp�������, ��ӡ��ǰ������Ԫ��, IPID, UDP_CHECKSUM����Ψһ��ʶһ��������Ϣ, + ������������DEBUG��λ����. +*/ +const char *flwd_debug_print_tuple4_detail(const void *a_packet, int tid) +{ + char debug_ip_src_str[64], debug_ip_dst_str[64]; + unsigned short debug_sport, debug_dport; + const flwd_ipv4_hdr_t *ipv4_hdr; + const flwd_ipv6_hdr_t *ipv6_hdr; + const flwd_tcp_hdr_t *thdr; + const flwd_udp_hdr_t *uhdr; + static char tuple4_str[FLWD_MAX_THREAD_NUM][256]; + unsigned char *ip_hdr = (unsigned char *)a_packet; + unsigned char protocol; + unsigned short ip_id; + unsigned short tu_checksum; + + if(tid >= FLWD_MAX_THREAD_NUM){ + assert(0); + } + + if(NULL == a_packet){ + return "NULL"; + } + + if(flwd_cfg_val.flwd_log_level <= 10){ + if(0x40 == (ip_hdr[0] & 0xF0)){ /* sapp������IP��ͷ, ���Ի�ȡraw_pkt, ���߿�IPͷ����һ����IPV4����IPV6 */ + ipv4_hdr = (flwd_ipv4_hdr_t *)a_packet; + protocol = ipv4_hdr->ip_p; + ip_id = ntohs(ipv4_hdr->ip_id); + }else{ + ipv6_hdr = (flwd_ipv6_hdr_t *)a_packet; + protocol = ipv6_hdr->ip6_nxt_hdr; + ip_id = 0; + } + + inet_ntop(AF_INET, &ipv4_hdr->ip_src.s_addr, debug_ip_src_str, 64); + inet_ntop(AF_INET, &ipv4_hdr->ip_dst.s_addr, debug_ip_dst_str, 64); + if(6 == protocol){ + thdr = (flwd_tcp_hdr_t *)((char *)a_packet + ipv4_hdr->ip_hl * 4); + debug_sport = ntohs(thdr->th_sport); + debug_dport = ntohs(thdr->th_dport); + tu_checksum = ntohs(thdr->th_sum); + }else if (17 == protocol){ + uhdr = (flwd_udp_hdr_t *)((char *)a_packet + ipv4_hdr->ip_hl * 4); + debug_sport = ntohs(uhdr->uh_sport); + debug_dport = ntohs(uhdr->uh_dport); + tu_checksum = ntohs(uhdr->uh_sum); + }else{ + debug_sport = 0; + debug_dport = 0; + } + } + + snprintf(tuple4_str[tid], 256, "%s,%u ---> %s,%u, pro:%u, ipid:0x%04x, checksum:0x%04x", + debug_ip_src_str, debug_sport, debug_ip_dst_str, debug_dport, + protocol, + ip_id, + tu_checksum); + + return tuple4_str[tid]; +} + + +/* + ����sapp�������, ��ӡ��ǰ������Ԫ��, IPID, UDP_CHECKSUM����Ψһ��ʶһ��������Ϣ, + ������������DEBUG��λ����. +*/ +const char *flwd_debug_print_tuple4_detail_r(const void *a_packet, char *buf, int buf_max_len) +{ + char debug_ip_src_str[64], debug_ip_dst_str[64]; + unsigned short debug_sport, debug_dport; + const flwd_ipv4_hdr_t *ipv4_hdr; + const flwd_ipv6_hdr_t *ipv6_hdr; + const flwd_tcp_hdr_t *thdr; + const flwd_udp_hdr_t *uhdr; + unsigned char *ip_hdr = (unsigned char *)a_packet; + unsigned char protocol; + unsigned short ip_id; + unsigned short tu_checksum; + + if(NULL == a_packet){ + return "NULL"; + } + + if(flwd_cfg_val.flwd_log_level <= 10){ + if(0x40 == (ip_hdr[0] & 0xF0)){ /* sapp������IP��ͷ, ���Ի�ȡraw_pkt, ���߿�IPͷ����һ����IPV4����IPV6 */ + ipv4_hdr = (flwd_ipv4_hdr_t *)a_packet; + protocol = ipv4_hdr->ip_p; + ip_id = ntohs(ipv4_hdr->ip_id); + }else{ + ipv6_hdr = (flwd_ipv6_hdr_t *)a_packet; + protocol = ipv6_hdr->ip6_nxt_hdr; + ip_id = 0; + } + + inet_ntop(AF_INET, &ipv4_hdr->ip_src.s_addr, debug_ip_src_str, 64); + inet_ntop(AF_INET, &ipv4_hdr->ip_dst.s_addr, debug_ip_dst_str, 64); + if(6 == protocol){ + thdr = (flwd_tcp_hdr_t *)((char *)a_packet + ipv4_hdr->ip_hl * 4); + debug_sport = ntohs(thdr->th_sport); + debug_dport = ntohs(thdr->th_dport); + tu_checksum = ntohs(thdr->th_sum); + }else if (17 == protocol){ + uhdr = (flwd_udp_hdr_t *)((char *)a_packet + ipv4_hdr->ip_hl * 4); + debug_sport = ntohs(uhdr->uh_sport); + debug_dport = ntohs(uhdr->uh_dport); + tu_checksum = ntohs(uhdr->uh_sum); + }else{ + debug_sport = 0; + debug_dport = 0; + } + } + + snprintf(buf, buf_max_len, "%s,%u ---> %s,%u, pro:%u, ipid:0x%04x, checksum:0x%04x", + debug_ip_src_str, debug_sport, debug_ip_dst_str, debug_dport, + protocol, + ip_id, + tu_checksum); + + return buf; +} + + +const char *flwd_debug_print_tuple4_r(const void *a_packet, char *buf, int buf_max_len) +{ + char debug_ip_src_str[64], debug_ip_dst_str[64]; + unsigned short debug_sport, debug_dport; + const flwd_ipv4_hdr_t *ipv4_hdr; + const flwd_ipv6_hdr_t *ipv6_hdr; + const flwd_tcp_hdr_t *thdr; + const flwd_udp_hdr_t *uhdr; + unsigned char *ip_hdr = (unsigned char *)a_packet; + unsigned char protocol; + + if(flwd_cfg_val.flwd_log_level <= 10){ + if(0x40 == (ip_hdr[0] & 0xF0)){ /* ��һ����IPV4����IPV6 */ + ipv4_hdr = (flwd_ipv4_hdr_t *)a_packet; + protocol = ipv4_hdr->ip_p; + }else{ + ipv6_hdr = (flwd_ipv6_hdr_t *)a_packet; + protocol = ipv6_hdr->ip6_nxt_hdr; + } + + inet_ntop(AF_INET, &ipv4_hdr->ip_src.s_addr, debug_ip_src_str, 64); + inet_ntop(AF_INET, &ipv4_hdr->ip_dst.s_addr, debug_ip_dst_str, 64); + if(6 == protocol){ + thdr = (flwd_tcp_hdr_t *)((char *)a_packet + ipv4_hdr->ip_hl * 4); + debug_sport = ntohs(thdr->th_sport); + debug_dport = ntohs(thdr->th_dport); + }else if (17 == protocol){ + uhdr = (flwd_udp_hdr_t *)((char *)a_packet + ipv4_hdr->ip_hl * 4); + debug_sport = ntohs(uhdr->uh_sport); + debug_dport = ntohs(uhdr->uh_dport); + }else{ + debug_sport = 0; + debug_dport = 0; + } + } + + snprintf(buf, buf_max_len, "%s,%u ---> %s,%u", debug_ip_src_str, debug_sport, debug_ip_dst_str, debug_dport); + + return buf; +} + + |
