diff options
| author | lijia <[email protected]> | 2020-03-18 22:01:54 +0800 |
|---|---|---|
| committer | lijia <[email protected]> | 2020-03-18 22:01:54 +0800 |
| commit | 2e6da7600c366f3ff36d4d4db3cabcd245b5c3ec (patch) | |
| tree | 10d5be75c061ccf41626d103a092141e2438b3fa /test | |
| parent | 1d23241d7bb60cb443a521c2ed5281190d3f096e (diff) | |
1.packet_io_tun模式增加static NAT, 修改ip使kni, tfe收到的数据包与外部原始包不同,避免协议栈冲突;
2.更新tun_transparent初始化脚本;
3.修复packet_io_tun模式的tcpdump_mesa捕包流程.
Diffstat (limited to 'test')
| -rw-r--r-- | test/Makefile | 1 | ||||
| -rw-r--r-- | test/eth_tun_bridge.c | 459 | ||||
| -rw-r--r-- | test/test_app_sapp.c | 67 |
3 files changed, 66 insertions, 461 deletions
diff --git a/test/Makefile b/test/Makefile index 5f8b757..712c7ac 100644 --- a/test/Makefile +++ b/test/Makefile @@ -53,6 +53,7 @@ wangyan_gdev_measurement.so:wangyan_gdev_measurement.c $(CC) -o $@ -shared -fPIC $(INCS) $(CFLAGS) -DIOMODE_MARSIO=1 $^ $(MODULES) cp $@ ../bin/plug/business/wangyan_gdev_measurement/$@ + sapp_so_run:test_sapp_so.o $(CC) -o $@ -g $(INCS) $(CFLAGS) $^ -lpcap -ldl cp $@ ../bin; diff --git a/test/eth_tun_bridge.c b/test/eth_tun_bridge.c deleted file mode 100644 index bc05cfc..0000000 --- a/test/eth_tun_bridge.c +++ /dev/null @@ -1,459 +0,0 @@ -#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 f7a134b..90e69d5 100644 --- a/test/test_app_sapp.c +++ b/test/test_app_sapp.c @@ -1400,10 +1400,68 @@ char test_sendfake_udp_pkt(struct streaminfo *stream,void **pme, int thread_seq, } +static void test_inject_tcp_pkt_with_this_hdr(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\nConnection: Close\r\n\r\n<html><head>HaHaHa</head></html>"; + + char pkt_header_payload[2048]; + struct mesa_ip4_hdr *send_ihdr; + struct mesa_tcp_hdr *send_thdr; + + const struct mesa_ip4_hdr *raw_ihdr; + const struct mesa_tcp_hdr *raw_thdr; + int raw_tcp_payload_len; + int send_pkt_len; + + raw_ihdr = (struct mesa_ip4_hdr *)raw_pkt; + raw_thdr = (struct mesa_tcp_hdr *)((char *)raw_ihdr + raw_ihdr->ip_hl*4); + raw_tcp_payload_len = ntohs(raw_ihdr->ip_len) - raw_ihdr->ip_hl*4 - raw_thdr->th_off * 4; + + /* 当前包是C2S方向的GET, 需要回复一个虚假的S2C方向的RESPONSE */ + send_ihdr = pkt_header_payload; + send_thdr = (struct mesa_tcp_hdr *)((char *)send_ihdr + sizeof(struct mesa_ip4_hdr)); + + sendpacket_build_tcp(ntohs(raw_thdr->th_dport), + ntohs(raw_thdr->th_sport), + ntohl(raw_thdr->th_ack), + ntohl(raw_thdr->th_seq)+raw_tcp_payload_len, + 0x18, + 100, + 0, + NULL, + 0, + (unsigned char *)send_thdr); + + sendpacket_build_ipv4(sizeof(struct mesa_tcp_hdr) + sizeof(fake_http_data), + 0, + 0x1111, + IP_DF, + 100, + IPPROTO_TCP, + raw_ihdr->ip_dst.s_addr, + raw_ihdr->ip_src.s_addr, + NULL, + 0, + (unsigned char *)send_ihdr); + memcpy(pkt_header_payload + sizeof(struct mesa_ip4_hdr) + sizeof(struct mesa_tcp_hdr), + fake_http_data, + sizeof(fake_http_data)); + + sendpacket_do_checksum(send_ihdr, IPPROTO_IP, sizeof(struct mesa_ip4_hdr)); + sendpacket_do_checksum(send_ihdr, IPPROTO_TCP, sizeof(struct mesa_tcp_hdr) + sizeof(fake_http_data)); + + send_pkt_len = sizeof(struct mesa_ip4_hdr) + sizeof(struct mesa_tcp_hdr) + sizeof(fake_http_data); + + sapp_inject_pkt(stream, SIO_EXCLUDE_THIS_LAYER_HDR, pkt_header_payload, send_pkt_len, stream->routedir ^ 1); + + return; +} + 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>"; + 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\nConnection: Close\r\n\r\n<html><head>HaHaHa</head></html>"; char plug_ret = APP_STATE_DROPME; + int optval; if(OP_STATE_CLOSE == stream->opstate){ return plug_ret; @@ -1413,8 +1471,13 @@ char test_inject_tcp_pkt(struct streaminfo *stream,void **pme, int thread_seq,co 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); + //MESA_inject_pkt(stream, fake_http_data, sizeof(fake_http_data), raw_pkt, stream->routedir ^ 1); + //sapp_inject_pkt(stream, SIO_DEFAULT, fake_http_data, sizeof(fake_http_data), stream->routedir ^ 1); + test_inject_tcp_pkt_with_this_hdr(stream, pme, thread_seq, raw_pkt); plug_ret |= APP_STATE_DROPPKT; + + optval = 1; + MESA_set_stream_opt(stream, MSO_DROP_STREAM, &optval, sizeof(int)); } } |
