summaryrefslogtreecommitdiff
path: root/src/common/flwd_common_tool.c
diff options
context:
space:
mode:
authorlijia <[email protected]>2018-10-24 09:36:45 +0800
committerlijia <[email protected]>2018-10-24 09:36:45 +0800
commit86a43b4d325ddc850fa9dc4711670880f35b11e8 (patch)
tree8356a056ac9bfb8cf14fcf57f113dd306b4277d1 /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.c911
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;
+}
+
+