summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlijia <[email protected]>2020-02-21 17:18:09 +0800
committerlijia <[email protected]>2020-02-21 17:18:09 +0800
commitd4d89b42c3210eb98c1d016544114bc8c9b33188 (patch)
treee78a2e7d5b2a5040941994e4202780f1648abbf1
parent7010e12cdb69f399c94b30d4e46b4b61ee1956bc (diff)
增加基于tun虚设备的双卡串联模式, 用于在虚拟机单网卡环境下, 使用sapp串联模式.
-rw-r--r--CMakeLists.txt10
-rw-r--r--Makefile11
-rw-r--r--include/private/packet_io.h3
-rw-r--r--include/private/packet_io_internal.h25
-rw-r--r--src/Makefile8
-rw-r--r--src/config/config_parse.cpp4
-rw-r--r--src/entry/CMakeLists.txt4
-rw-r--r--src/entry/sapp_init.c1
-rw-r--r--src/packet_io/CMakeLists.txt9
-rw-r--r--src/packet_io/Makefile9
-rw-r--r--src/packet_io/packet_io_lib_load.c125
-rw-r--r--src/packet_io/packet_io_tun.c386
-rw-r--r--test/eth_tun_bridge.c459
-rw-r--r--test/test_app_sapp.c32
14 files changed, 1015 insertions, 71 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ec08fa5..73d1d31 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -82,7 +82,7 @@ set(MESA_SDK_PREFIX "/opt/MESA/" CACHE STRING "MESA Framework Prefix")
set(CAPTURE_MODE "PCAP" CACHE STRING
"CAPTURE_MODE set Capture network traffic chosen by the user, using PCAP as default")
-set_property(CACHE CAPTURE_MODE PROPERTY STRINGS PCAP MARSIO PAG)
+set_property(CACHE CAPTURE_MODE PROPERTY STRINGS PCAP MARSIO PAG TUN)
message(STATUS "CAPTURE_MODE='${CAPTURE_MODE}'")
@@ -102,6 +102,10 @@ if(CAPTURE_MODE MATCHES "MARSIO")
add_definitions(-DIOMODE_MARSIO=1)
endif()
+if(CAPTURE_MODE MATCHES "TUN")
+ set(CAPTURE_DEFINITIONS -DCAPTURE_MODE_TUN)
+ add_definitions(-DIOMODE_TUN=1)
+endif()
# Memory Allocator
set(MEM_POOL "OFF" CACHE STRING
@@ -207,6 +211,10 @@ if(CAPTURE_MODE MATCHES "PCAP")
install(FILES ${CMAKE_BINARY_DIR}/src/packet_io/packet_io_pcap.so DESTINATION platform_lib)
endif()
+if(CAPTURE_MODE MATCHES "TUN")
+ install(FILES ${CMAKE_BINARY_DIR}/src/packet_io/packet_io_tun.so DESTINATION platform_lib)
+endif()
+
endif()
#install(FILES bin/plug/protocol/conflist_protocol.inf DESTINATION plug/protocol)
diff --git a/Makefile b/Makefile
index 833b4f7..dad568e 100644
--- a/Makefile
+++ b/Makefile
@@ -28,8 +28,9 @@ _MODE_SMITH=smith
_MODE_DPDK_VXLAN=dpdk_vxlan
_MODE_PAG_MARSIO=pag_marsio
_MODE_IPFILE=ipfile
+_MODE_TUN=tun
_MODE_CHK=0
-iomode=marsio
+iomode=tun
_OPT0=0
_OPT1=1
@@ -137,6 +138,10 @@ ifeq ($(iomode), $(_MODE_IPFILE))
_MODE_CHK=1
endif
+ifeq ($(iomode), $(_MODE_TUN))
+_MODE_CHK=1
+endif
+
ifneq ($(_MODE_CHK), 0)
else
ifeq ($(iomode), "pcap")
@@ -220,6 +225,8 @@ export _MODE_SMITH
export _MODE_DPDK_VXLAN
export _MODE_IPFILE
export _MODE_PAG_MARSIO
+export _MODE_TUN
+
export target_mode
export __TARGET_MODE_ELF
export __TARGET_MODE_SO
@@ -238,7 +245,7 @@ help:
@echo -e "\treserved args:"
@echo -e "\t\t\033[31;49;1m debug={0,1,2},0:release version; 1:-g; 2:-g -DDEBUG, default is 2.\033[0m"
@echo -e "\t\t\033[31;49;1m opt={0,1,2,3,high_perf}, optimize level, default is 0.\033[0m"
- @echo -e "\t\t\033[31;49;1m iomode={pcap,ppf,pag,prfing,dpdk,tilera,topsec,ipfile,marsio,smith,dpdk_vxlan,pag_marsio}, default is pcap.\033[0m"
+ @echo -e "\t\t\033[31;49;1m iomode={pcap,ppf,pag,prfing,dpdk,tilera,topsec,ipfile,marsio,smith,dpdk_vxlan,pag_marsio,tun}, default is pcap.\033[0m"
@echo -e "\t\t\033[31;49;1m target_mode={elf, so}, default is elf.\033[0m"
@echo -e "\t\t\033[31;49;1m link_mode={dynamic, static}, default is static.\033[0m"
diff --git a/include/private/packet_io.h b/include/private/packet_io.h
index f8f66cb..4caaa5e 100644
--- a/include/private/packet_io.h
+++ b/include/private/packet_io.h
@@ -63,7 +63,8 @@ enum cap_mode_t{
CAP_MODEL_DPDK_VXLAN = 14, /* 2016-11-01 lijia add, for DPDK-3.0, vxlan������� */
CAP_MODEL_MARSIOV4_VXLAN= 15, /* 2016-11-01 lijia add, for MARSIO-4.0, vxlan������� */
CAP_MODEL_PAG_MARSIO = 16, /* 2017-04-07 lijia add, for marsio compat pag */
- __CAP_MODEL_MAX = 17,
+ CAP_MODEL_TUN = 17, /* 2020-02-20 lijia add, for tun mode */
+ __CAP_MODEL_MAX = 18,
};
enum send_packet_way{
diff --git a/include/private/packet_io_internal.h b/include/private/packet_io_internal.h
index 83526d0..4321a82 100644
--- a/include/private/packet_io_internal.h
+++ b/include/private/packet_io_internal.h
@@ -298,6 +298,31 @@ extern void * marsio_dl_io_device_alias(unsigned int target_id, char *device_arg
/********************** marsio funcitons for dynamic link *********************/
+/********************** tun funcitons for dynamic link ***********************/
+extern int tun_dl_io_set_cap_level(int cap_level);
+extern int tun_dl_io_set_cap_mode(int cap_mode);
+extern int tun_dl_io_set_topology_mode(int topology_mode);
+extern int tun_dl_io_set_capdev_parallel(const char *cap_dev);
+extern int tun_dl_io_set_capdev_serial(const char *up_dev, const char *down_dev);
+extern int tun_dl_io_set_capture_filter(const char *filter_rule);
+extern int tun_dl_io_set_cap_buf_queue(int queue_num_max);
+extern int tun_dl_io_set_work_thread_num(int thread_num_max);
+extern long tun_dl_io_get_app_drop_num(int thread_num);
+extern long tun_dl_io_get_lib_drop_num(void);
+extern unsigned char * tun_dl_io_get_sendbuf(void *, int );
+extern void tun_dl_io_free_sendbuf(void *, int thread_num);
+extern void * tun_dl_io_get_send_handle(int thread_num);
+extern int tun_dl_io_low_level_send(void *phandle, unsigned char *data,int datalen,
+ int eth_carry_layer_addr_type, int dir,int thread_num); /* ����ethernet�� */
+extern int tun_dl_io_raw_pkt_send(void *phandle, unsigned char *data,int datalen, void *arg, int thread_num); /* ȫ��ԭʼ�� */
+extern int tun_dl_io_init(int argc, char *argv[]);
+extern void tun_dl_io_run(void);
+extern int tun_dl_io_register_cb(PACKET_IO_CB_T fun);
+extern int tun_dl_io_register_exit_cb(PACKET_IO_EXIT_CB_T exit_fun);
+extern int tun_dl_io_get_version(void);
+extern void * tun_dl_io_device_alias(unsigned int target_id, char *device_args);
+
+/********************** tun funcitons for dynamic link ***********************/
#ifdef __cplusplus
diff --git a/src/Makefile b/src/Makefile
index efb527b..4288742 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -27,8 +27,9 @@ _MODE_SMITH=smith
_MODE_DPDK_VXLAN=dpdk_vxlan
_MODE_PAG_MARSIO=pag_marsio
_MODE_IPFILE=ipfile
+_MODE_TUN=tun
_MODE_CHK=0
-iomode=pcap
+iomode=tun
_OPT0=0
_OPT1=1
@@ -136,6 +137,11 @@ ifeq ($(iomode), $(_MODE_IPFILE))
_MODE_CHK=1
endif
+ifeq ($(iomode), $(_MODE_TUN))
+_MODE_CHK=1
+endif
+
+
ifneq ($(_MODE_CHK), 0)
else
ifeq ($(iomode), "pcap")
diff --git a/src/config/config_parse.cpp b/src/config/config_parse.cpp
index a396ca6..d1250dd 100644
--- a/src/config/config_parse.cpp
+++ b/src/config/config_parse.cpp
@@ -312,6 +312,8 @@ static int config_expression_convert(void)
pconfig->packet_io.internal.interface.type_bin = CAP_MODEL_PAG;
}else if(strncasecmp(tmp_str, "marsio", strlen("marsio")) == 0){
pconfig->packet_io.internal.interface.type_bin = CAP_MODEL_MARSIOV4;
+ }else if(strncasecmp(tmp_str, "tun", strlen("tun")) == 0){
+ pconfig->packet_io.internal.interface.type_bin = CAP_MODEL_TUN;
}
tmp_str = pconfig->packet_io.external.interface.type_str;
@@ -321,6 +323,8 @@ static int config_expression_convert(void)
pconfig->packet_io.external.interface.type_bin = CAP_MODEL_PAG;
}else if(strncasecmp(tmp_str, "marsio", strlen("marsio")) == 0){
pconfig->packet_io.external.interface.type_bin = CAP_MODEL_MARSIOV4;
+ }else if(strncasecmp(tmp_str, "tun", strlen("tun")) == 0){
+ pconfig->packet_io.external.interface.type_bin = CAP_MODEL_TUN;
}
/*
diff --git a/src/entry/CMakeLists.txt b/src/entry/CMakeLists.txt
index 7ef1e10..0ac3e5a 100644
--- a/src/entry/CMakeLists.txt
+++ b/src/entry/CMakeLists.txt
@@ -53,6 +53,10 @@ if(ENABLE_STATIC_LINK)
if(CAPTURE_MODE MATCHES "MARSIO")
target_link_libraries(sapp packet_io_marsio)
endif()
+
+ if(CAPTURE_MODE MATCHES "TUN")
+ target_link_libraries(sapp packet_io_tun)
+ endif()
endif()
# Target Install
#install(TARGETS sapp DESTINATION ${CMAKE_SOURCE_DIR}/bin/)
diff --git a/src/entry/sapp_init.c b/src/entry/sapp_init.c
index c0f39e4..89937ff 100644
--- a/src/entry/sapp_init.c
+++ b/src/entry/sapp_init.c
@@ -245,6 +245,7 @@ int MESA_platform_init(int argc, char *argv[])
case CAP_MODEL_PPF:
case CAP_MODEL_TOPSEC:
case CAP_MODEL_IPFILE:
+ case CAP_MODEL_TUN:
packet_io_set_cap_level(CAP_LEVEL_IPV4);
break;
diff --git a/src/packet_io/CMakeLists.txt b/src/packet_io/CMakeLists.txt
index 9c1111f..acd1e25 100644
--- a/src/packet_io/CMakeLists.txt
+++ b/src/packet_io/CMakeLists.txt
@@ -56,6 +56,15 @@ if(CAPTURE_MODE MATCHES "MARSIO")
set_target_properties(packet_io_marsio PROPERTIES PREFIX "")
endif()
+if(CAPTURE_MODE MATCHES "TUN")
+ set(PACKET_IO_SOURCE ${PACKET_IO_SOURCE} packet_io_tun.c)
+ if(ENABLE_STATIC_LINK)
+ add_library(packet_io_tun STATIC ${PACKET_IO_SOURCE})
+ else()
+ add_library(packet_io_tun SHARED ${PACKET_IO_SOURCE})
+ endif()
+endif()
+
set(PACKET_IO_STATIC_SOURCE cycle_pkt_dump_through_write_offset.c packet_io_lib_load.c pkt_dispatch_new.c
iknow_info.c packet_io_log.c sendpacket.c
packet_io.c
diff --git a/src/packet_io/Makefile b/src/packet_io/Makefile
index ab1652d..cb3eb31 100644
--- a/src/packet_io/Makefile
+++ b/src/packet_io/Makefile
@@ -107,6 +107,11 @@ CFLAGS += -DIOMODE_PAG_MARSIO=1
DLL_LIB += packet_io_pag_marsio.so
endif
+ifeq ($(iomode), $(_MODE_TUN))
+CFLAGS += -DIOMODE_TUN=1
+DLL_LIB += packet_io_tun.so
+endif
+
TARGET = libpacket_io.a
@@ -176,6 +181,10 @@ packet_io_pag_marsio.so:packet_io_pag_marsio.o
gcc -o $@ -fPIC -shared -g -Wall $^ $(LIBPATH) $(LIBS) -L$(LIBPATH) -lmarsio;
cp $@ $(RELEASE_PATH)
+packet_io_tun.so:packet_io_tun.o
+ gcc -o $@ -fPIC -shared -g -Wall $^ $(LIBPATH) $(LIBS) -L$(LIBPATH);
+ cp $@ $(RELEASE_PATH)
+
clean:
rm -f *.o packet_io*.so *.a $(TARGET) $(DLL_LIB) *~
diff --git a/src/packet_io/packet_io_lib_load.c b/src/packet_io/packet_io_lib_load.c
index acbd790..a82937d 100644
--- a/src/packet_io/packet_io_lib_load.c
+++ b/src/packet_io/packet_io_lib_load.c
@@ -30,6 +30,7 @@ const struct dl_io_lib_name g_dl_io_lib_info[__CAP_MODEL_MAX] =
{CAP_MODEL_DPDK_VXLAN , "dpdkvxlan", (char *)"packet_io_dpdk_vxlan.so"},
{CAP_MODEL_MARSIOV4_VXLAN , "marsio_vxlan", (char *)"packet_io_marsio_vxlan.so"},
{CAP_MODEL_PAG_MARSIO , "marsio_pag", (char *)"packet_io_pag_marsio.so"},
+ {CAP_MODEL_TUN , "tun", (char *)"packet_io_tun.so"},
};
static inline void __print_err_msg(void *fun_ptr, const char *libname, const char *fun_name)
@@ -100,57 +101,61 @@ static dl_io_fun_list_t dl_io_fun_list_static_link[__CAP_MODEL_MAX];
static int packet_io_lib_load_by_mode(int cap_mode, const char *no_use)
{
#ifdef IOMODE_PCAP
- dl_io_fun_list_static_link[CAP_MODEL_PCAP_ONLINE].dl_io_set_cap_level = (int (*)(int cap_level))pcap_dl_io_set_cap_level;
- dl_io_fun_list_static_link[CAP_MODEL_PCAP_ONLINE].dl_io_set_cap_mode = (int (*)(int cap_mode))pcap_dl_io_set_cap_mode;
- dl_io_fun_list_static_link[CAP_MODEL_PCAP_ONLINE].dl_io_set_topology_mode = (int (*)(int topology_mode))pcap_dl_io_set_topology_mode;
- dl_io_fun_list_static_link[CAP_MODEL_PCAP_ONLINE].dl_io_set_capdev_parallel = (int (*)(const char *cap_dev))pcap_dl_io_set_capdev_parallel;
- dl_io_fun_list_static_link[CAP_MODEL_PCAP_ONLINE].dl_io_set_capdev_serial = (int (*)(const char *up_dev, const char *down_dev))pcap_dl_io_set_capdev_serial;
- dl_io_fun_list_static_link[CAP_MODEL_PCAP_ONLINE].dl_io_set_capture_filter = (int (*)(const char *filter_rule))pcap_dl_io_set_capture_filter;
- dl_io_fun_list_static_link[CAP_MODEL_PCAP_ONLINE].dl_io_set_cap_buf_queue = (int (*)(int queue_num_max))pcap_dl_io_set_cap_buf_queue;
- dl_io_fun_list_static_link[CAP_MODEL_PCAP_ONLINE].dl_io_set_work_thread_num = (int (*)(int thread_num_max))pcap_dl_io_set_work_thread_num;
- dl_io_fun_list_static_link[CAP_MODEL_PCAP_ONLINE].dl_io_get_app_drop_num = (long (*)(int thread_num))pcap_dl_io_get_app_drop_num;
- dl_io_fun_list_static_link[CAP_MODEL_PCAP_ONLINE].dl_io_get_lib_drop_num = (long (*)(void))pcap_dl_io_get_lib_drop_num;
- dl_io_fun_list_static_link[CAP_MODEL_PCAP_ONLINE].dl_io_get_sendbuf = (unsigned char * (*)(void *, int thread_num))pcap_dl_io_get_sendbuf;
- dl_io_fun_list_static_link[CAP_MODEL_PCAP_ONLINE].dl_io_free_sendbuf = (void (*)(void *, int thread_num))pcap_dl_io_free_sendbuf;
- dl_io_fun_list_static_link[CAP_MODEL_PCAP_ONLINE].dl_io_get_send_handle = (void * (*)(int thread_num))pcap_dl_io_get_send_handle;
- dl_io_fun_list_static_link[CAP_MODEL_PCAP_ONLINE].dl_io_low_level_send = (int (*)(void *, unsigned char *,int ,int , int ,int ))pcap_dl_io_low_level_send;
- dl_io_fun_list_static_link[CAP_MODEL_PCAP_ONLINE].dl_io_raw_pkt_send = (int (*)(void *, unsigned char *,int , void *,int ))pcap_dl_io_raw_pkt_send;
- dl_io_fun_list_static_link[CAP_MODEL_PCAP_ONLINE].dl_io_init = (int (*)(int argc, char *argv[]))pcap_dl_io_init;
- dl_io_fun_list_static_link[CAP_MODEL_PCAP_ONLINE].dl_io_run = (void (*)(void))pcap_dl_io_run;
- dl_io_fun_list_static_link[CAP_MODEL_PCAP_ONLINE].dl_io_register_cb = (int (*)(PACKET_IO_CB_T fun))pcap_dl_io_register_cb;
- dl_io_fun_list_static_link[CAP_MODEL_PCAP_ONLINE].dl_io_register_exit_cb = (int (*)(PACKET_IO_EXIT_CB_T exit_fun))pcap_dl_io_register_exit_cb;
- dl_io_fun_list_static_link[CAP_MODEL_PCAP_ONLINE].dl_io_get_version = (int (*)(void))pcap_dl_io_get_version;
- dl_io_fun_list_static_link[CAP_MODEL_PCAP_ONLINE].dl_io_device_alias = (void * (*)(unsigned int , char *))pcap_dl_io_device_alias;
-
- memcpy(&dl_io_fun_list_static_link[CAP_MODEL_PCAP_DUMPFILE], &dl_io_fun_list_static_link[CAP_MODEL_PCAP_ONLINE], sizeof(dl_io_fun_list_t));
+ if((CAP_MODEL_PCAP_ONLINE == cap_mode) || (CAP_MODEL_PCAP_DUMPFILE == cap_mode)){
+ dl_io_fun_list_static_link[CAP_MODEL_PCAP_ONLINE].dl_io_set_cap_level = (int (*)(int cap_level))pcap_dl_io_set_cap_level;
+ dl_io_fun_list_static_link[CAP_MODEL_PCAP_ONLINE].dl_io_set_cap_mode = (int (*)(int cap_mode))pcap_dl_io_set_cap_mode;
+ dl_io_fun_list_static_link[CAP_MODEL_PCAP_ONLINE].dl_io_set_topology_mode = (int (*)(int topology_mode))pcap_dl_io_set_topology_mode;
+ dl_io_fun_list_static_link[CAP_MODEL_PCAP_ONLINE].dl_io_set_capdev_parallel = (int (*)(const char *cap_dev))pcap_dl_io_set_capdev_parallel;
+ dl_io_fun_list_static_link[CAP_MODEL_PCAP_ONLINE].dl_io_set_capdev_serial = (int (*)(const char *up_dev, const char *down_dev))pcap_dl_io_set_capdev_serial;
+ dl_io_fun_list_static_link[CAP_MODEL_PCAP_ONLINE].dl_io_set_capture_filter = (int (*)(const char *filter_rule))pcap_dl_io_set_capture_filter;
+ dl_io_fun_list_static_link[CAP_MODEL_PCAP_ONLINE].dl_io_set_cap_buf_queue = (int (*)(int queue_num_max))pcap_dl_io_set_cap_buf_queue;
+ dl_io_fun_list_static_link[CAP_MODEL_PCAP_ONLINE].dl_io_set_work_thread_num = (int (*)(int thread_num_max))pcap_dl_io_set_work_thread_num;
+ dl_io_fun_list_static_link[CAP_MODEL_PCAP_ONLINE].dl_io_get_app_drop_num = (long (*)(int thread_num))pcap_dl_io_get_app_drop_num;
+ dl_io_fun_list_static_link[CAP_MODEL_PCAP_ONLINE].dl_io_get_lib_drop_num = (long (*)(void))pcap_dl_io_get_lib_drop_num;
+ dl_io_fun_list_static_link[CAP_MODEL_PCAP_ONLINE].dl_io_get_sendbuf = (unsigned char * (*)(void *, int thread_num))pcap_dl_io_get_sendbuf;
+ dl_io_fun_list_static_link[CAP_MODEL_PCAP_ONLINE].dl_io_free_sendbuf = (void (*)(void *, int thread_num))pcap_dl_io_free_sendbuf;
+ dl_io_fun_list_static_link[CAP_MODEL_PCAP_ONLINE].dl_io_get_send_handle = (void * (*)(int thread_num))pcap_dl_io_get_send_handle;
+ dl_io_fun_list_static_link[CAP_MODEL_PCAP_ONLINE].dl_io_low_level_send = (int (*)(void *, unsigned char *,int ,int , int ,int ))pcap_dl_io_low_level_send;
+ dl_io_fun_list_static_link[CAP_MODEL_PCAP_ONLINE].dl_io_raw_pkt_send = (int (*)(void *, unsigned char *,int , void *,int ))pcap_dl_io_raw_pkt_send;
+ dl_io_fun_list_static_link[CAP_MODEL_PCAP_ONLINE].dl_io_init = (int (*)(int argc, char *argv[]))pcap_dl_io_init;
+ dl_io_fun_list_static_link[CAP_MODEL_PCAP_ONLINE].dl_io_run = (void (*)(void))pcap_dl_io_run;
+ dl_io_fun_list_static_link[CAP_MODEL_PCAP_ONLINE].dl_io_register_cb = (int (*)(PACKET_IO_CB_T fun))pcap_dl_io_register_cb;
+ dl_io_fun_list_static_link[CAP_MODEL_PCAP_ONLINE].dl_io_register_exit_cb = (int (*)(PACKET_IO_EXIT_CB_T exit_fun))pcap_dl_io_register_exit_cb;
+ dl_io_fun_list_static_link[CAP_MODEL_PCAP_ONLINE].dl_io_get_version = (int (*)(void))pcap_dl_io_get_version;
+ dl_io_fun_list_static_link[CAP_MODEL_PCAP_ONLINE].dl_io_device_alias = (void * (*)(unsigned int , char *))pcap_dl_io_device_alias;
+
+ memcpy(&dl_io_fun_list_static_link[CAP_MODEL_PCAP_DUMPFILE], &dl_io_fun_list_static_link[CAP_MODEL_PCAP_ONLINE], sizeof(dl_io_fun_list_t));
+ }
#endif
#ifdef IOMODE_MARSIO
- dl_io_fun_list_static_link[CAP_MODEL_MARSIOV4].dl_io_set_cap_level = (int (*)(int cap_level))marsio_dl_io_set_cap_level;
- dl_io_fun_list_static_link[CAP_MODEL_MARSIOV4].dl_io_set_cap_mode = (int (*)(int cap_mode))marsio_dl_io_set_cap_mode;
- dl_io_fun_list_static_link[CAP_MODEL_MARSIOV4].dl_io_set_topology_mode = (int (*)(int topology_mode))marsio_dl_io_set_topology_mode;
- dl_io_fun_list_static_link[CAP_MODEL_MARSIOV4].dl_io_set_capdev_parallel = (int (*)(const char *cap_dev))marsio_dl_io_set_capdev_parallel;
- dl_io_fun_list_static_link[CAP_MODEL_MARSIOV4].dl_io_set_capdev_serial = (int (*)(const char *up_dev, const char *down_dev))marsio_dl_io_set_capdev_serial;
- dl_io_fun_list_static_link[CAP_MODEL_MARSIOV4].dl_io_set_capture_filter = (int (*)(const char *filter_rule))marsio_dl_io_set_capture_filter;
- dl_io_fun_list_static_link[CAP_MODEL_MARSIOV4].dl_io_set_cap_buf_queue = (int (*)(int queue_num_max))marsio_dl_io_set_cap_buf_queue;
- dl_io_fun_list_static_link[CAP_MODEL_MARSIOV4].dl_io_set_work_thread_num = (int (*)(int thread_num_max))marsio_dl_io_set_work_thread_num;
- dl_io_fun_list_static_link[CAP_MODEL_MARSIOV4].dl_io_get_app_drop_num = (long (*)(int thread_num))marsio_dl_io_get_app_drop_num;
- dl_io_fun_list_static_link[CAP_MODEL_MARSIOV4].dl_io_get_lib_drop_num = (long (*)(void))marsio_dl_io_get_lib_drop_num;
- dl_io_fun_list_static_link[CAP_MODEL_MARSIOV4].dl_io_get_sendbuf = (unsigned char * (*)(void *, int thread_num))marsio_dl_io_get_sendbuf;
- dl_io_fun_list_static_link[CAP_MODEL_MARSIOV4].dl_io_free_sendbuf = (void (*)(void *, int thread_num))marsio_dl_io_free_sendbuf;
- dl_io_fun_list_static_link[CAP_MODEL_MARSIOV4].dl_io_get_send_handle = (void * (*)(int thread_num))marsio_dl_io_get_send_handle;
- dl_io_fun_list_static_link[CAP_MODEL_MARSIOV4].dl_io_low_level_send = (int (*)(void *, unsigned char *,int ,int , int ,int ))marsio_dl_io_low_level_send;
- dl_io_fun_list_static_link[CAP_MODEL_MARSIOV4].dl_io_raw_pkt_send = (int (*)(void *, unsigned char *,int , void *,int ))marsio_dl_io_raw_pkt_send;
- dl_io_fun_list_static_link[CAP_MODEL_MARSIOV4].dl_io_init = (int (*)(int argc, char *argv[]))marsio_dl_io_init;
- dl_io_fun_list_static_link[CAP_MODEL_MARSIOV4].dl_io_run = (void (*)(void))marsio_dl_io_run;
- dl_io_fun_list_static_link[CAP_MODEL_MARSIOV4].dl_io_register_cb = (int (*)(PACKET_IO_CB_T fun))marsio_dl_io_register_cb;
- //dl_io_fun_list_static_link[CAP_MODEL_MARSIOV4].dl_io_register_exit_cb = (int (*)(PACKET_IO_EXIT_CB_T exit_fun))marsio_dl_io_register_exit_cb;
- dl_io_fun_list_static_link[CAP_MODEL_MARSIOV4].dl_io_get_version = (int (*)(void))marsio_dl_io_get_version;
- dl_io_fun_list_static_link[CAP_MODEL_MARSIOV4].dl_io_device_alias = (void * (*)(unsigned int , char *))marsio_dl_io_device_alias;
-
+ if(CAP_MODEL_MARSIOV4 == cap_mode){
+ dl_io_fun_list_static_link[CAP_MODEL_MARSIOV4].dl_io_set_cap_level = (int (*)(int cap_level))marsio_dl_io_set_cap_level;
+ dl_io_fun_list_static_link[CAP_MODEL_MARSIOV4].dl_io_set_cap_mode = (int (*)(int cap_mode))marsio_dl_io_set_cap_mode;
+ dl_io_fun_list_static_link[CAP_MODEL_MARSIOV4].dl_io_set_topology_mode = (int (*)(int topology_mode))marsio_dl_io_set_topology_mode;
+ dl_io_fun_list_static_link[CAP_MODEL_MARSIOV4].dl_io_set_capdev_parallel = (int (*)(const char *cap_dev))marsio_dl_io_set_capdev_parallel;
+ dl_io_fun_list_static_link[CAP_MODEL_MARSIOV4].dl_io_set_capdev_serial = (int (*)(const char *up_dev, const char *down_dev))marsio_dl_io_set_capdev_serial;
+ dl_io_fun_list_static_link[CAP_MODEL_MARSIOV4].dl_io_set_capture_filter = (int (*)(const char *filter_rule))marsio_dl_io_set_capture_filter;
+ dl_io_fun_list_static_link[CAP_MODEL_MARSIOV4].dl_io_set_cap_buf_queue = (int (*)(int queue_num_max))marsio_dl_io_set_cap_buf_queue;
+ dl_io_fun_list_static_link[CAP_MODEL_MARSIOV4].dl_io_set_work_thread_num = (int (*)(int thread_num_max))marsio_dl_io_set_work_thread_num;
+ dl_io_fun_list_static_link[CAP_MODEL_MARSIOV4].dl_io_get_app_drop_num = (long (*)(int thread_num))marsio_dl_io_get_app_drop_num;
+ dl_io_fun_list_static_link[CAP_MODEL_MARSIOV4].dl_io_get_lib_drop_num = (long (*)(void))marsio_dl_io_get_lib_drop_num;
+ dl_io_fun_list_static_link[CAP_MODEL_MARSIOV4].dl_io_get_sendbuf = (unsigned char * (*)(void *, int thread_num))marsio_dl_io_get_sendbuf;
+ dl_io_fun_list_static_link[CAP_MODEL_MARSIOV4].dl_io_free_sendbuf = (void (*)(void *, int thread_num))marsio_dl_io_free_sendbuf;
+ dl_io_fun_list_static_link[CAP_MODEL_MARSIOV4].dl_io_get_send_handle = (void * (*)(int thread_num))marsio_dl_io_get_send_handle;
+ dl_io_fun_list_static_link[CAP_MODEL_MARSIOV4].dl_io_low_level_send = (int (*)(void *, unsigned char *,int ,int , int ,int ))marsio_dl_io_low_level_send;
+ dl_io_fun_list_static_link[CAP_MODEL_MARSIOV4].dl_io_raw_pkt_send = (int (*)(void *, unsigned char *,int , void *,int ))marsio_dl_io_raw_pkt_send;
+ dl_io_fun_list_static_link[CAP_MODEL_MARSIOV4].dl_io_init = (int (*)(int argc, char *argv[]))marsio_dl_io_init;
+ dl_io_fun_list_static_link[CAP_MODEL_MARSIOV4].dl_io_run = (void (*)(void))marsio_dl_io_run;
+ dl_io_fun_list_static_link[CAP_MODEL_MARSIOV4].dl_io_register_cb = (int (*)(PACKET_IO_CB_T fun))marsio_dl_io_register_cb;
+ //dl_io_fun_list_static_link[CAP_MODEL_MARSIOV4].dl_io_register_exit_cb = (int (*)(PACKET_IO_EXIT_CB_T exit_fun))marsio_dl_io_register_exit_cb;
+ dl_io_fun_list_static_link[CAP_MODEL_MARSIOV4].dl_io_get_version = (int (*)(void))marsio_dl_io_get_version;
+ dl_io_fun_list_static_link[CAP_MODEL_MARSIOV4].dl_io_device_alias = (void * (*)(unsigned int , char *))marsio_dl_io_device_alias;
+ }
#endif
#ifdef IOMODE_PAG
+ if(CAP_MODEL_PAG == cap_mode){
dl_io_fun_list_static_link[CAP_MODEL_PAG].dl_io_set_cap_level = (int (*)(int cap_level))pag_dl_io_set_cap_level;
dl_io_fun_list_static_link[CAP_MODEL_PAG].dl_io_set_cap_mode = (int (*)(int cap_mode))pag_dl_io_set_cap_mode;
dl_io_fun_list_static_link[CAP_MODEL_PAG].dl_io_set_topology_mode = (int (*)(int topology_mode))pag_dl_io_set_topology_mode;
@@ -172,12 +177,40 @@ static int packet_io_lib_load_by_mode(int cap_mode, const char *no_use)
//dl_io_fun_list_static_link[CAP_MODEL_PAG].dl_io_register_exit_cb = (int (*)(PACKET_IO_EXIT_CB_T exit_fun))pag_dl_io_register_exit_cb;
dl_io_fun_list_static_link[CAP_MODEL_PAG].dl_io_get_version = (int (*)(void))pag_dl_io_get_version;
//dl_io_fun_list_static_link[CAP_MODEL_PAG].dl_io_device_alias = (void * (*)(unsigned int , char *))pag_dl_io_device_alias;
+ }
#endif
+#ifdef IOMODE_TUN
+
+ dl_io_fun_list_static_link[CAP_MODEL_TUN].dl_io_set_cap_level = (int (*)(int cap_level))tun_dl_io_set_cap_level;
+ dl_io_fun_list_static_link[CAP_MODEL_TUN].dl_io_set_cap_mode = (int (*)(int cap_mode))tun_dl_io_set_cap_mode;
+ dl_io_fun_list_static_link[CAP_MODEL_TUN].dl_io_set_topology_mode = (int (*)(int topology_mode))tun_dl_io_set_topology_mode;
+ dl_io_fun_list_static_link[CAP_MODEL_TUN].dl_io_set_capdev_parallel = (int (*)(const char *cap_dev))tun_dl_io_set_capdev_parallel;
+ dl_io_fun_list_static_link[CAP_MODEL_TUN].dl_io_set_capdev_serial = (int (*)(const char *up_dev, const char *down_dev))tun_dl_io_set_capdev_serial;
+ dl_io_fun_list_static_link[CAP_MODEL_TUN].dl_io_set_capture_filter = (int (*)(const char *filter_rule))tun_dl_io_set_capture_filter;
+ dl_io_fun_list_static_link[CAP_MODEL_TUN].dl_io_set_cap_buf_queue = (int (*)(int queue_num_max))tun_dl_io_set_cap_buf_queue;
+ dl_io_fun_list_static_link[CAP_MODEL_TUN].dl_io_set_work_thread_num = (int (*)(int thread_num_max))tun_dl_io_set_work_thread_num;
+ dl_io_fun_list_static_link[CAP_MODEL_TUN].dl_io_get_app_drop_num = (long (*)(int thread_num))tun_dl_io_get_app_drop_num;
+ dl_io_fun_list_static_link[CAP_MODEL_TUN].dl_io_get_lib_drop_num = (long (*)(void))tun_dl_io_get_lib_drop_num;
+ dl_io_fun_list_static_link[CAP_MODEL_TUN].dl_io_get_sendbuf = (unsigned char * (*)(void *, int thread_num))tun_dl_io_get_sendbuf;
+ dl_io_fun_list_static_link[CAP_MODEL_TUN].dl_io_free_sendbuf = (void (*)(void *, int thread_num))tun_dl_io_free_sendbuf;
+ dl_io_fun_list_static_link[CAP_MODEL_TUN].dl_io_get_send_handle = (void * (*)(int thread_num))tun_dl_io_get_send_handle;
+ dl_io_fun_list_static_link[CAP_MODEL_TUN].dl_io_low_level_send = (int (*)(void *, unsigned char *,int ,int , int ,int ))tun_dl_io_low_level_send;
+ dl_io_fun_list_static_link[CAP_MODEL_TUN].dl_io_raw_pkt_send = (int (*)(void *, unsigned char *,int , void *,int ))0;
+ dl_io_fun_list_static_link[CAP_MODEL_TUN].dl_io_init = (int (*)(int argc, char *argv[]))tun_dl_io_init;
+ dl_io_fun_list_static_link[CAP_MODEL_TUN].dl_io_run = (void (*)(void))tun_dl_io_run;
+ dl_io_fun_list_static_link[CAP_MODEL_TUN].dl_io_register_cb = (int (*)(PACKET_IO_CB_T fun))tun_dl_io_register_cb;
+ //dl_io_fun_list_static_link[CAP_MODEL_TUN].dl_io_register_exit_cb = (int (*)(PACKET_IO_EXIT_CB_T exit_fun))pag_dl_io_register_exit_cb;
+ dl_io_fun_list_static_link[CAP_MODEL_TUN].dl_io_get_version = (int (*)(void))tun_dl_io_get_version;
+ dl_io_fun_list_static_link[CAP_MODEL_TUN].dl_io_device_alias = (void * (*)(unsigned int , char *))tun_dl_io_device_alias;
+#endif
+
+
if((cap_mode != CAP_MODEL_PCAP_ONLINE)
&& (cap_mode != CAP_MODEL_PCAP_DUMPFILE)
&& (cap_mode != CAP_MODEL_MARSIOV4)
- && (cap_mode != CAP_MODEL_PAG)){
+ && (cap_mode != CAP_MODEL_PAG)
+ && (cap_mode != CAP_MODEL_TUN)){
abort(); /* only support these mode static link yet! */
}
diff --git a/src/packet_io/packet_io_tun.c b/src/packet_io/packet_io_tun.c
new file mode 100644
index 0000000..bd6f0e6
--- /dev/null
+++ b/src/packet_io/packet_io_tun.c
@@ -0,0 +1,386 @@
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "sapp_api.h"
+#include "sapp_private_api.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <netpacket/packet.h>
+#include <fcntl.h>
+#include <netinet/in.h>
+#include <net/if.h>
+#include <string.h>
+#include <linux/if_ether.h>
+#include <linux/if_tun.h>
+#include <assert.h>
+#include <errno.h>
+#include <pcap.h>
+
+
+static char *tun_up_dev_name;
+static char *tun_down_dev_name;
+static int g_tun_fd[2]; /* DIR_ROUTE_UP */
+static PACKET_IO_CB_T g_tun_work_fun;
+static int g_tun_topology_mode = NET_CONN_SERIAL_2CARD;
+static int g_tun_version = 20200220;
+
+static MESA_lqueue_head g_tun_work_queue;
+
+typedef struct{
+ int thread_num;
+ UINT8 send_buf[SENDPACKET_BUF_LEN];
+}tun_send_handle;
+
+
+/* 为了一次性把数据全部copy到queue里, 使用连续内存结构 */
+typedef struct{
+ raw_pkt_t raw_pkt;
+ char pkt_buf[SENDPACKET_BUF_LEN];
+}tun_raw_pkt_t;
+
+int tun_dl_io_set_topology_mode(int topology_mode)
+{
+ return 0;
+}
+
+int tun_dl_io_set_cap_level(int cap_level)
+{
+ return 0;
+}
+
+int tun_dl_io_set_cap_mode(int cap_mode)
+{
+ return 0;
+}
+
+int tun_dl_io_set_capdev_parallel(const char *cap_dev)
+{
+ tun_up_dev_name = strdup(cap_dev);
+
+ return 0;
+}
+
+int tun_dl_io_set_capdev_serial(const char *up_dev, const char *down_dev)
+{
+ tun_up_dev_name = strdup(up_dev);
+ tun_down_dev_name = strdup(down_dev);
+
+ return 0;
+}
+
+int tun_dl_io_set_capture_filter(const char *filter_rule)
+{
+ return 0;
+}
+
+int tun_dl_io_set_cap_buf_queue(int queue_num_max)
+{
+ return 0;
+}
+
+int tun_dl_io_set_work_thread_num(int thread_num_max)
+{
+ return 0;
+}
+
+long tun_dl_io_get_app_drop_num(int thread_num)
+{
+ return 0;
+}
+
+long tun_dl_io_get_lib_drop_num(void)
+{
+ return 0;
+}
+
+void * tun_dl_io_device_alias(unsigned int target_id, char *device_args)
+{
+ /* 对于tun模式来说, 就是设备名称 eth1, eth2, etc. */
+ return (void *)strdup(device_args);
+}
+
+int tun_dl_io_register_cb(PACKET_IO_CB_T fun)
+{
+ g_tun_work_fun = fun;
+
+ return 0;
+}
+
+unsigned char *tun_dl_io_get_sendbuf(void *phandle, int thread_num)
+{
+ tun_send_handle *send_handle = (tun_send_handle *)phandle;
+
+ return send_handle->send_buf;
+}
+
+void tun_dl_io_free_sendbuf(void *phandle, int thread_num)
+{
+ (void)phandle;
+ (void)thread_num;
+
+ /* TUN模式无需释放 */
+ return;
+}
+
+void *tun_dl_io_get_send_handle(int thread_num)
+{
+ tun_send_handle *send_handle = (tun_send_handle *)calloc(1, sizeof(tun_send_handle));
+
+ send_handle->thread_num = thread_num;
+
+ return send_handle;
+}
+
+int tun_dl_io_low_level_send(void *phandle, UINT8 *data,int datalen,
+ int eth_carry_layer_addr_type, int dir,int thread_num)
+{
+ tun_send_handle *send_handle = (tun_send_handle *)phandle;
+ int dir_reverse, ret;
+
+send_again:
+ /* 发包时, dir要取反一次, 因为从tun0收的包,rcv_dir=0, 如果send_dir=0, 即同向发送,实际是从tun1发走 */
+ ret = write(g_tun_fd[(dir & 0x1) ^ 1], data, datalen);
+ if(ret < 0){
+ if((EAGAIN == errno) || (EINTR == errno) ){
+ goto send_again;
+ }else{
+ return -1;
+ }
+ }
+
+ return ret;
+}
+
+
+int tun_dl_io_get_version(void)
+{
+ return g_tun_version;
+}
+
+
+static int ifconfig_device_up(const char *interface_name)
+{
+ int err;
+ int ret;
+ int socket_fd;
+ struct ifreq ifr;
+ //struct sockaddr_in sin;
+
+ if(interface_name == NULL)
+ {
+ return -1;
+ }
+
+ socket_fd = socket(AF_INET, SOCK_DGRAM, 0);
+ if (socket_fd < 0)
+ {
+ printf("Create Socket Failed.\n");
+ return -2;
+ }
+ //指定网卡名称且up
+ sprintf(ifr.ifr_name, "%s", interface_name);
+ /* 获得接口的标志 */
+ if ((err = ioctl(socket_fd, SIOCGIFFLAGS, (void *)&ifr)) < 0) {
+ perror("ioctl SIOCGIFADDR");
+ close(socket_fd);
+ return -3;
+ }
+ ifr.ifr_flags |= IFF_UP;
+ ret = ioctl(socket_fd, SIOCSIFFLAGS, &ifr);
+ if (ret != 0)
+ {
+ printf("Up Device %s Failed.\n", interface_name);
+ close(socket_fd);
+ return -3;
+ }
+
+ close(socket_fd);
+
+ return 0;
+}
+
+int getifindex(int fd,char *ifname)
+{
+ struct ifreq ifr;
+ memset(&ifr,0,sizeof(ifr));
+ strcpy(ifr.ifr_name,ifname);
+ if(-1 == ioctl(fd,SIOCGIFINDEX,&ifr))
+ {
+ printf("ioctl error\n");
+ return -1;
+ }
+ return ifr.ifr_ifindex;
+}
+
+
+int tun_alloc(char *dev, int flags)
+{
+ assert(dev != NULL);
+
+ struct ifreq ifr;
+ int fd, err;
+
+ char *clonedev = "/dev/net/tun";
+
+ if ((fd = open(clonedev, O_RDWR)) < 0) {
+ return fd;
+ }
+
+ memset(&ifr, 0, sizeof(ifr));
+ ifr.ifr_flags = flags;
+
+ if (*dev != '\0') {
+ strncpy(ifr.ifr_name, dev, IFNAMSIZ);
+ }
+ if ((err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0) {
+ close(fd);
+ return err;
+ }
+
+ // 一旦设备开启成功,系统会给设备分配一个名称,对于tun设备,一般为tunX,X为从0开始的编号;
+ // 对于tap设备,一般为tapX
+ strcpy(dev, ifr.ifr_name);
+
+ return fd;
+}
+
+
+int create_dev_fd(const char *dev_name)
+{
+ int tun_fd;
+ char tun_name[IFNAMSIZ];
+
+ strcpy(tun_name, dev_name);
+
+ /* Flags: IFF_TUN - TUN device (no Ethernet headers)
+ * IFF_TAP - TAP device
+ * IFF_NO_PI - Do not provide packet information
+ */
+ tun_fd = tun_alloc(tun_name, IFF_TUN | IFF_NO_PI);
+
+ if (tun_fd < 0) {
+ sapp_runtime_log(30, "create tun device '%s' error!\n", dev_name);
+ exit(1);
+ }
+
+ return tun_fd;
+}
+
+static int tun_forward_pkt(int thread_num, const unsigned char *data,int data_len, unsigned char this_pkt_rcv_dir)
+{
+ int sn;
+ unsigned char snd_dir = this_pkt_rcv_dir ^ 1;
+
+ sn = write(g_tun_fd[snd_dir], data, data_len);
+ if(sn < 0){
+ sapp_runtime_log(30, "tun write error, %s\n", strerror(errno));
+ }
+
+ return sn;
+}
+
+
+void *tun_work_thread(void *arg)
+{
+ int sapp_ret, queue_ret;
+ tun_raw_pkt_t tun_raw_pkt;
+ long buf_len;
+
+ while(1){
+ buf_len = sizeof(tun_raw_pkt);
+ queue_ret = MESA_lqueue_get_head(g_tun_work_queue, &tun_raw_pkt, &buf_len);
+ if(queue_ret >= 0){
+ tun_raw_pkt.raw_pkt.__lib_raw_pkt_data = tun_raw_pkt.pkt_buf;
+ tun_raw_pkt.raw_pkt.raw_pkt_data = tun_raw_pkt.pkt_buf;
+
+ sapp_ret = g_tun_work_fun(&tun_raw_pkt.raw_pkt, tun_raw_pkt.raw_pkt.route_dir, 0);
+ if((g_tun_topology_mode & __NET_CONN_SERIAL) && (PASS == sapp_ret)){
+ tun_forward_pkt(0, tun_raw_pkt.pkt_buf, tun_raw_pkt.raw_pkt.raw_pkt_len, tun_raw_pkt.raw_pkt.route_dir);
+ }
+ }
+ }
+
+ return NULL;
+}
+
+
+void *tun_rcv_thread(void *arg)
+{
+ int rn0, queue_ret;
+ tun_raw_pkt_t tun_raw_pkt;
+ long route_dir_arg = (long)arg;
+ unsigned char route_dir = (unsigned char)route_dir_arg;
+ unsigned char reverse_route_dir = route_dir ^ 1;
+
+ memset(&tun_raw_pkt, 0, sizeof(tun_raw_pkt));
+
+ tun_raw_pkt.raw_pkt.magic_num = RAW_PKT_MAGIC_NUM;
+ tun_raw_pkt.raw_pkt.raw_pkt_ts.tv_sec = 0;
+ tun_raw_pkt.raw_pkt.raw_pkt_ts.tv_usec = 0;
+ tun_raw_pkt.raw_pkt.low_layer_type = __ADDR_TYPE_IP_PAIR_V4;
+ tun_raw_pkt.raw_pkt.hd_hash = 0;
+ tun_raw_pkt.raw_pkt.io_lib_pkt_reference = NULL;
+ tun_raw_pkt.raw_pkt.route_dir = route_dir;
+
+ while(1){
+ rn0 = read(g_tun_fd[route_dir], tun_raw_pkt.pkt_buf, sizeof(tun_raw_pkt.pkt_buf));
+ if(rn0 > 0){
+ //tun_raw_pkt.raw_pkt.__lib_raw_pkt_data = pkt;
+ //tun_raw_pkt.raw_pkt.raw_pkt_data = pkt;
+ tun_raw_pkt.raw_pkt.__lib_raw_pkt_len = rn0;
+ tun_raw_pkt.raw_pkt.raw_pkt_len = rn0;
+ tun_raw_pkt.raw_pkt.route_dir = route_dir;
+ queue_ret = MESA_lqueue_join_tail(g_tun_work_queue, &tun_raw_pkt, sizeof(tun_raw_pkt));
+ if(queue_ret < 0){
+ sapp_runtime_log(30, "tun join queue error, ret = %d!", queue_ret);
+ }
+ }
+ }
+
+ return NULL;
+}
+
+
+
+int tun_dl_io_init(int argc, char *argv[])
+{
+ g_tun_fd[0] = create_dev_fd(tun_up_dev_name);
+ if(g_tun_fd[0] < 0){
+ return -1;
+ }
+ g_tun_fd[1] = create_dev_fd(tun_down_dev_name);
+ if(g_tun_fd[1] < 0){
+ return -1;
+ }
+
+ g_tun_work_queue = MESA_lqueue_create(1, 10000);
+
+ ifconfig_device_up(tun_up_dev_name);
+ ifconfig_device_up(tun_down_dev_name);
+
+ return 0;
+}
+
+
+void tun_dl_io_run(void)
+{
+ pthread_t pid;
+
+ pthread_create(&pid, NULL, tun_work_thread, NULL);
+
+ /* tun模式暂时只支持1个线程, 非阻塞模式分别处理两个tun虚拟网卡 */
+ pthread_create(&pid, NULL, tun_rcv_thread, (void *)DIR_ROUTE_UP);
+ pthread_create(&pid, NULL, tun_rcv_thread, (void *)DIR_ROUTE_DOWN);
+
+
+}
+
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/test/eth_tun_bridge.c b/test/eth_tun_bridge.c
new file mode 100644
index 0000000..bc05cfc
--- /dev/null
+++ b/test/eth_tun_bridge.c
@@ -0,0 +1,459 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <netinet/in.h>
+#include <unistd.h>
+#include <string.h>
+#include <linux/if_ether.h>
+#include <linux/if_arp.h>
+#include <errno.h>
+#include <pcap.h>
+#include <linux/if_tun.h>
+#include <assert.h>
+#include <netinet/ip.h>
+#include <ctype.h>
+#include <arpa/inet.h>
+#include <pthread.h>
+//#include <net/if.h>
+//#include <netpacket/packet.h>
+
+
+/*
+ 此程序可以跑通单机单网卡模式下的串联功能,
+ 一个卡是本程序创建的tun0, 另一个是物理网卡ens33.
+*/
+
+#define USE_TUN_MODE (1) /* 虚拟设备用tun还是TAP, 1:tun; 0:tap */
+
+static pcap_t * tun_pcap_handle;
+static pcap_t * phy_pcap_handle;
+
+static char *phy_dev_name;
+static char *tun_dev_name;
+
+static struct sockaddr tun_sock_addr;
+static struct sockaddr phy_sock_addr;
+
+static int phy_dev_fd, tun_dev_fd;
+
+static unsigned int local_phy_dev_ip_net;
+
+static unsigned char local_phy_mac_addr[ETH_ALEN];
+static unsigned char default_gw_mac_addr[ETH_ALEN];
+
+
+static char MESA_ascii_to_hex(char ascii)
+{
+ char c = 0;
+
+ switch(ascii)
+ {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ c = ascii - 0x30;
+ break;
+
+ case 'a':
+ case 'b':
+ case 'c':
+ case 'd':
+ case 'e':
+ case 'f':
+ c = 10 + ascii - 0x61;
+ break;
+
+ case 'A':
+ case 'B':
+ case 'C':
+ case 'D':
+ case 'E':
+ case 'F':
+ c = 10 + ascii - 0x41;
+ break;
+ }
+
+ return c;
+}
+
+static int MESA_mac_pton(const char *str, int delim, unsigned char *mac)
+{
+#define MAC_STR_LEN_DELIM (17) /* length of "11:22:33:44:55:66" */
+#define MAC_STR_LEN_NODELIM (12) /* length of "112233445566" */
+ const char *s = str;
+ int i;
+
+ /* �������Ϸ��� */
+ if(delim != -1)
+ {
+ if(strlen(str) != MAC_STR_LEN_DELIM)
+ {
+ printf("MAC string length error!\n");
+ return -1;
+ }
+ }
+ else
+ {
+ if(strlen(str) != MAC_STR_LEN_NODELIM)
+ {
+ printf("MAC string length error!\n");
+ return -1;
+ }
+ }
+
+ /* �������Ϸ��ԣ�ͬʱת����16����ֵ */
+ for(i = 0; i < 6; i++)
+ {
+ mac[i] = 0; /* �����㣬��ֵ��䶼�ǻ���� */
+ if(isxdigit(*s)==0)
+ {
+ printf("MAC string type error!\n");
+ return -1;
+ }
+ mac[i] |= MESA_ascii_to_hex(*s) << 4;
+ s++;
+
+ if(isxdigit(*s)==0)
+ {
+ printf("MAC string type error!\n");
+ return -1;
+ }
+ mac[i] |= MESA_ascii_to_hex(*s);
+ s++;
+
+ if((delim != -1) && i<5 && (*s++ != (char)delim))
+ {
+ printf("MAC string type error!\n");
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+static int MESA_get_dev_mac(const char *device, unsigned char mac[6])
+{
+ struct ifreq ifr;
+ int fd;
+
+ fd = socket(AF_INET, SOCK_DGRAM, 0);
+ if(fd < 0)
+ {
+ return -1;
+ }
+
+ memset(ifr.ifr_ifrn.ifrn_name, 0, sizeof(ifr.ifr_ifrn.ifrn_name));
+ strncpy(ifr.ifr_ifrn.ifrn_name, device, sizeof(ifr.ifr_ifrn.ifrn_name));
+ if(ioctl(fd, SIOCGIFHWADDR, &ifr) == -1)
+ {
+ printf("Cann't get hwaddr of %s:%s\n", device, strerror(errno));
+ goto err_exit;
+ }
+
+ if(ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER)
+ {
+ printf("'%s' is not ethernet interface!\n", device);
+ goto err_exit;
+ }
+
+ memcpy(mac, ifr.ifr_ifru.ifru_addr.sa_data, 6);
+
+ close(fd);
+
+ return 0;
+
+err_exit:
+ close(fd);
+ return -1;
+}
+
+static int MESA_get_dev_ipv4(const char *device, unsigned int *ip_add_net)
+{
+ struct ifreq ifr;
+ int fd;
+
+ fd = socket(AF_INET, SOCK_DGRAM, 0);
+ if(fd < 0)
+ {
+ return -1;
+ }
+
+ memset(ifr.ifr_ifrn.ifrn_name, 0, sizeof(ifr.ifr_ifrn.ifrn_name));
+ strncpy(ifr.ifr_ifrn.ifrn_name, device, sizeof(ifr.ifr_ifrn.ifrn_name));
+ if(ioctl(fd, SIOCGIFADDR, &ifr) == -1)
+ {
+ //perror("Cann't get ip addr:");
+ goto err_exit;
+ }
+
+ *ip_add_net = ((struct sockaddr_in*)&ifr.ifr_ifru.ifru_addr)->sin_addr.s_addr;
+
+ close(fd);
+
+ return 0;
+
+err_exit:
+ close(fd);
+ return -1;
+}
+
+int getifindex(int fd,char *ifname)
+{
+ struct ifreq ifr;
+ memset(&ifr,0,sizeof(ifr));
+ strcpy(ifr.ifr_name,ifname);
+ if(-1 == ioctl(fd,SIOCGIFINDEX,&ifr))
+ {
+ printf("ioctl error\n");
+ return -1;
+ }
+ return ifr.ifr_ifindex;
+}
+
+static inline int is_private_addr_v4(unsigned int ip_add_host)
+{
+/* 10/8 */
+#define IPV4_LOCAL_CLASS_A(_add) (((_add&0xFF000000)==0x0A000000)?1:0)
+/* 172.16/12 */
+#define IPV4_LOCAL_CLASS_B(_add) (((_add&0xFFF00000)==0xAC100000)?1:0)
+/* 192.168/16 */
+#define IPV4_LOCAL_CLASS_C(_add) (((_add&0xFFFF0000)==0xC0A80000)?1:0)
+
+ if((int)IPV4_LOCAL_CLASS_A(ip_add_host)
+ || (int)IPV4_LOCAL_CLASS_B(ip_add_host)
+ || (int)IPV4_LOCAL_CLASS_C(ip_add_host))
+ {
+ return 1;
+ }
+
+ return 0;
+}
+
+
+void phy_pkt_cb(u_char * arg, const struct pcap_pkthdr * pkthdr, const u_char * packet)
+{
+ int sn;
+ const struct ip *ihdr = (struct ip *)(packet + 14);
+ //char ip_str[64];
+
+ if((packet[12] != 0x08) || (packet[13] != 0x00)){ /* drop ipv6, arp, etc.. */
+ return;
+ }
+
+ if(local_phy_dev_ip_net != ihdr->ip_dst.s_addr){
+ //inet_ntop(AF_INET, &ihdr->ip_dst.s_addr, ip_str, sizeof(ip_str));
+ //printf("packet from %s dst ip '%s' is not local device, ignore it!\n", phy_dev_name, ip_str);
+ return;
+ }
+
+ if(is_private_addr_v4(ntohl(ihdr->ip_src.s_addr)) != 0){
+ //inet_ntop(AF_INET, &ihdr->ip_src.s_addr, ip_str, sizeof(ip_str));
+ //printf("packet from %s src ip '%s' is same submask, ignore it!\n", phy_dev_name, ip_str);
+ return;
+ }
+
+ /* 从phy捕到的包, 发给tun设备之前要剥去mac头部 */
+ sn = sendto(tun_dev_fd, packet+14, pkthdr->caplen-14, 0, (struct sockaddr *)&tun_sock_addr, sizeof(struct sockaddr));
+ if(sn < 0){
+ printf("sendto tun error, len=%d, %s\n", pkthdr->caplen-14, strerror(errno));
+ }
+ return;
+}
+
+
+void tun_pkt_cb(u_char * arg, const struct pcap_pkthdr * pkthdr, const u_char * packet)
+{
+ int sn;
+
+ unsigned char buf[2048];
+
+#if USE_TUN_MODE
+ memcpy(buf+14, packet, pkthdr->caplen); /* tun模式预留mac头部空间 */
+ memcpy(buf, default_gw_mac_addr, 6);
+ memcpy(buf+6, local_phy_mac_addr, 6);
+ buf[12] = 0x08;
+ buf[13] = 0x0;
+#else
+ memcpy(buf, packet, pkthdr->caplen);
+ memcpy(buf, default_gw_mac_addr, 6);
+ memcpy(buf+6, local_phy_mac_addr, 6);
+ buf[12] = 0x08;
+ buf[13] = 0x0;
+#endif
+
+#if USE_TUN_MODE
+ sn = sendto(phy_dev_fd, buf, pkthdr->caplen+14, 0, (struct sockaddr *)&phy_sock_addr, sizeof(struct sockaddr));
+#else
+ sn = sendto(phy_dev_fd, buf, pkthdr->caplen, 0, (struct sockaddr *)&phy_sock_addr, sizeof(struct sockaddr));
+#endif
+ if(sn < 0){
+ printf("sendto phy error, len=%d, %s\n", pkthdr->caplen+14, strerror(errno));
+ }
+}
+
+static int pcap_set_filter(pcap_t *handle, const char *filter_str)
+{
+ struct bpf_program bpf_filter;
+
+ if((NULL == handle) || (NULL == filter_str) || ('\0' == *filter_str)){
+ return 0;
+ }
+
+ if(pcap_compile(handle, &bpf_filter, (char *)filter_str, 1, 0) < 0)
+ {
+ printf("Compile pcap filter '%s' error:%s\n", filter_str, pcap_geterr(handle));
+ return -1;
+ }
+
+ if(pcap_setfilter(handle, &bpf_filter) < 0){
+ printf("Set pcap filter '%s' error:%s\n", filter_str, pcap_geterr(handle));
+ return -1;
+ }
+
+ return 0;
+}
+
+int pcap_init(void)
+{
+ char errBuf[65535];
+ char local_ip_str[64];
+ char pcap_filter_str[256];
+
+ /* open a device, wait until a packet arrives */
+ phy_pcap_handle = pcap_open_live(phy_dev_name, 65535, 1, 0, errBuf);
+ if(!phy_pcap_handle)
+ {
+ printf("error: pcap_open_live(): %s\n", errBuf);
+ exit(1);
+ }
+
+ inet_ntop(AF_INET, &local_phy_dev_ip_net, local_ip_str, sizeof(local_ip_str));
+ snprintf(pcap_filter_str, sizeof(pcap_filter_str), "ip and dst host %s", local_ip_str);
+
+ pcap_setdirection(phy_pcap_handle, PCAP_D_IN);
+ pcap_set_filter(phy_pcap_handle, pcap_filter_str);
+ printf("capture phy dev %s use filter '%s'.\n", phy_dev_name, pcap_filter_str);
+
+ tun_pcap_handle = pcap_open_live(tun_dev_name, 65535, 1, 0, errBuf);
+ if(!tun_pcap_handle)
+ {
+ printf("error: pcap_open_live(): %s\n", errBuf);
+ exit(1);
+ }
+
+ pcap_setdirection(tun_pcap_handle, PCAP_D_IN);
+
+
+ return 0;
+}
+
+
+
+void *phy_pcap_rcv_thread(void *arg)
+{
+ while(1){
+ pcap_loop(phy_pcap_handle, -1, phy_pkt_cb, NULL);
+ }
+
+ return NULL;
+}
+
+void *tun_pcap_rcv_thread(void *arg)
+{
+ while(1){
+ pcap_loop(tun_pcap_handle, -1, tun_pkt_cb, NULL);
+ }
+
+ return NULL;
+}
+
+int sock_init(void)
+{
+ phy_dev_fd = socket(PF_INET, SOCK_PACKET, htons(ETH_P_ALL));
+ if(phy_dev_fd < 0)
+ {
+ printf("Create socket error!\n");
+ return -1;
+ }
+
+ tun_dev_fd = socket(PF_INET, SOCK_PACKET, htons(ETH_P_ALL));
+ if(tun_dev_fd < 0)
+ {
+ printf("Create socket error!\n");
+ return -1;
+ }
+
+ strcpy(phy_sock_addr.sa_data, phy_dev_name);
+ phy_sock_addr.sa_family = PF_INET;
+
+ strcpy(tun_sock_addr.sa_data, tun_dev_name);
+ tun_sock_addr.sa_family = PF_INET;
+
+ if(MESA_get_dev_ipv4(phy_dev_name, &local_phy_dev_ip_net) < 0){
+ printf("get device '%s' ip address error!\n", phy_dev_name);
+ return -1;
+ }
+
+ if(MESA_get_dev_mac(phy_dev_name, local_phy_mac_addr) < 0){
+ printf("get device '%s' MAC address error!\n", phy_dev_name);
+ return -1;
+ }
+
+ return 0;
+}
+
+
+static void usage(void)
+{
+ printf("usage: ./eth_tun_bridge <phy_device> <tun_device> <gw_mac>\n");
+ printf("\t for example: ./eth_tun_bridge eth0 tun1 50:d2:f5:f3:8e:93.\n");
+ exit(1);
+}
+
+
+int main(int argc, char *argv[])
+{
+ //int rphy, rtun;
+ pthread_t pid;
+
+ if(argc != 4){
+ usage();
+ }
+
+ phy_dev_name = strdup(argv[1]);
+ tun_dev_name = strdup(argv[2]);
+ if(MESA_mac_pton(argv[3], ':', default_gw_mac_addr) < 0){
+ printf("gw_mac is invalid!\n");
+ usage();
+ }
+
+ if(sock_init() < 0){
+ return -1;
+ }
+
+ if(pcap_init() < 0){
+ return -1;
+ }
+
+ printf("init succ, start capturing...\n");
+
+ pthread_create(&pid, NULL, phy_pcap_rcv_thread, NULL);
+ pthread_create(&pid, NULL, tun_pcap_rcv_thread, NULL);
+
+ while(1){
+ pause();
+
+ }
+
+ return 0;
+}
+
diff --git a/test/test_app_sapp.c b/test/test_app_sapp.c
index 17a3a3e..f7a134b 100644
--- a/test/test_app_sapp.c
+++ b/test/test_app_sapp.c
@@ -1402,32 +1402,24 @@ char test_sendfake_udp_pkt(struct streaminfo *stream,void **pme, int thread_seq,
char test_inject_tcp_pkt(struct streaminfo *stream,void **pme, int thread_seq,const void *raw_pkt)
{
- char fake_http_data[] = "HTTP/1.1 200 OK\r\nServer: Apache-Coyote/1.1\r\nContent-Type: text/html;charset=UTF-8\r\nContent-Language: zh-CN\r\nContent-Length: 32\r\nDate: Tue, 09 Sep 2014 08:21:07 GMT\r\n\r\n<html><head>hahaha</head></html>";
- //struct layer_addr *tuple;
- char ip1[16], ip2[16];
- struct stream_tuple4_v4 *tuple_v4;
-
+ char fake_http_data[] = "HTTP/1.1 200 OK\r\nServer: Apache-Coyote/1.1\r\nContent-Type: text/html;charset=UTF-8\r\nContent-Language: zh-CN\r\nContent-Length: 32\r\nDate: Tue, 09 Sep 2014 08:21:07 GMT\r\n\r\n<html><head>HaHaHa</head></html>";
+ char plug_ret = APP_STATE_DROPME;
+
if(OP_STATE_CLOSE == stream->opstate){
- return APP_STATE_DROPME;
+ return plug_ret;
}
- tuple_v4 = (struct stream_tuple4_v4 *)(stream->addr.paddr);
-
- // for test MESA_kill_tcp
- //if(((0xC0A80A9F) == ntohl(tuple_v4->daddr) || (0xC0A80A9F) == ntohl(tuple_v4->saddr))
- //&& ((80 == ntohs(tuple_v4->source)) ||(80 == ntohs(tuple_v4->dest))))
- {
- //if(DIR_C2S == stream->curdir)
- {
- inet_ntop(AF_INET, &tuple_v4->saddr, ip1, 16);
- inet_ntop(AF_INET, &tuple_v4->daddr, ip2, 16);
- MESA_inject_pkt(stream, fake_http_data, strlen(fake_http_data), raw_pkt, stream->routedir^1);
- printf("MESA inject : ,%s:%u -- %s:%u\n", ip1, ntohs(tuple_v4->source),
- ip2, ntohs(tuple_v4->dest));
+ if(OP_STATE_PENDING == stream->opstate){
+ if((DIR_C2S == stream->curdir)
+ && (memmem(stream->ptcpdetail->pdata, stream->ptcpdetail->datalen, "hijack", 6) != NULL)){
+ printf("found key 'hijack', send fake http response ' hahaha'!\n");
+ MESA_inject_pkt(stream, fake_http_data, sizeof(fake_http_data), raw_pkt, stream->routedir ^ 1);
+ plug_ret |= APP_STATE_DROPPKT;
}
}
+
- return APP_STATE_DROPME;
+ return plug_ret;
}
/* ʹ���µķ����ӿ� sapp_inject_pkt()����α��� */