diff options
| author | lijia <[email protected]> | 2020-02-21 17:18:09 +0800 |
|---|---|---|
| committer | lijia <[email protected]> | 2020-02-21 17:18:09 +0800 |
| commit | d4d89b42c3210eb98c1d016544114bc8c9b33188 (patch) | |
| tree | e78a2e7d5b2a5040941994e4202780f1648abbf1 | |
| parent | 7010e12cdb69f399c94b30d4e46b4b61ee1956bc (diff) | |
增加基于tun虚设备的双卡串联模式, 用于在虚拟机单网卡环境下, 使用sapp串联模式.
| -rw-r--r-- | CMakeLists.txt | 10 | ||||
| -rw-r--r-- | Makefile | 11 | ||||
| -rw-r--r-- | include/private/packet_io.h | 3 | ||||
| -rw-r--r-- | include/private/packet_io_internal.h | 25 | ||||
| -rw-r--r-- | src/Makefile | 8 | ||||
| -rw-r--r-- | src/config/config_parse.cpp | 4 | ||||
| -rw-r--r-- | src/entry/CMakeLists.txt | 4 | ||||
| -rw-r--r-- | src/entry/sapp_init.c | 1 | ||||
| -rw-r--r-- | src/packet_io/CMakeLists.txt | 9 | ||||
| -rw-r--r-- | src/packet_io/Makefile | 9 | ||||
| -rw-r--r-- | src/packet_io/packet_io_lib_load.c | 125 | ||||
| -rw-r--r-- | src/packet_io/packet_io_tun.c | 386 | ||||
| -rw-r--r-- | test/eth_tun_bridge.c | 459 | ||||
| -rw-r--r-- | test/test_app_sapp.c | 32 |
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) @@ -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()����α��� */ |
