From dc4936dc606e282c414b741569cd593d1603356b Mon Sep 17 00:00:00 2001 From: wangyu- Date: Sat, 26 Aug 2017 05:38:33 -0500 Subject: [PATCH] implemented --lower-level auto for client. better makefile --- common.cpp | 48 ++++++++--- common.h | 4 +- encrypt.cpp | 4 +- main.cpp | 82 ++++++++++++------- makefile | 38 +++++---- network.cpp | 226 +++++++++++++++++++++++++++++++++++++++++++++++++++- network.h | 3 +- 7 files changed, 341 insertions(+), 64 deletions(-) diff --git a/common.cpp b/common.cpp index a53a2de..df6d317 100644 --- a/common.cpp +++ b/common.cpp @@ -389,7 +389,31 @@ int char_to_numbers(const char * data,int len,id_t &id1,id_t &id2,id_t &id3) id3=ntohl( *((id_t*)(data+sizeof(id_t)*2)) ); return 0; } - +int hex_to_u32(const string & a,u32_t &output) +{ + //string b="0x"; + //b+=a; + if(sscanf(a.c_str(),"%x",&output)==1) + { + //printf("%s %x\n",a.c_str(),output); + return 0; + } + mylog(log_error,"<%s> doesnt contain a hex\n",a.c_str()); + return -1; +} +int hex_to_u32_with_endian(const string & a,u32_t &output) +{ + //string b="0x"; + //b+=a; + if(sscanf(a.c_str(),"%x",&output)==1) + { + output=htonl(output); + //printf("%s %x\n",a.c_str(),output); + return 0; + } + mylog(log_error,"<%s> doesnt contain a hex\n",a.c_str()); + return -1; +} bool larger_than_u32(u32_t a,u32_t b) { @@ -459,8 +483,13 @@ vector string_to_vec(const char * s,const char * sp) { { res.push_back(p); //printf ("%s\n",p); - p = strtok (NULL, sp); + p = strtok(NULL, sp); } + + /* for(int i=0;i<(int)res.size();i++) + { + printf("<<%s>>\n",res[i].c_str()); + }*/ return res; } @@ -476,9 +505,10 @@ vector< vector > string_to_vec2(const char * s) } return res; } -int read_file(const char * file,char * &output) +int read_file(const char * file,string &output) { - static char buf[1024*1024+100]; + const int max_len=2*1024*1024; + static char buf[max_len+100]; buf[sizeof(buf)-1]=0; int fd=open(file,O_RDONLY); if(fd==-1) @@ -486,23 +516,23 @@ int read_file(const char * file,char * &output) mylog(log_error,"read_file %s fail\n",file); return -1; } - int len=read(fd,buf,1024*1024); - if(len==1024*1024) + int len=read(fd,buf,max_len); + if(len==max_len) { buf[0]=0; - mylog(log_error,"too long,buf not larger enough\n"); + mylog(log_error,"%s too long,buf not large enough\n",file); return -2; } else if(len<0) { buf[0]=0; - mylog(log_error,"read fail %d\n",len); + mylog(log_error,"%s read fail %d\n",file,len); return -3; } else { - output=buf; buf[len]=0; + output=buf; } return 0; } diff --git a/common.h b/common.h index 53c7ab7..b4f0ccf 100644 --- a/common.h +++ b/common.h @@ -159,7 +159,7 @@ const int show_log=0x2; const int show_all=show_command|show_log; int run_command(string command,char * &output,int flag=show_all); //int run_command_no_log(string command,char * &output); -int read_file(const char * file,char * &output); +int read_file(const char * file,string &output); vector string_to_vec(const char * s,const char * sp); vector< vector > string_to_vec2(const char * s); @@ -170,6 +170,8 @@ string trim_conf_line(const string& str); vector parse_conf_line(const string& s); +int hex_to_u32_with_endian(const string & a,u32_t &output); +int hex_to_u32(const string & a,u32_t &output); //extern string iptables_pattern; #endif /* COMMON_H_ */ diff --git a/encrypt.cpp b/encrypt.cpp index 5074c33..a483a53 100755 --- a/encrypt.cpp +++ b/encrypt.cpp @@ -12,10 +12,10 @@ static int8_t zero_iv[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0};//this prog use zero iv,you should make sure first block of data contains a random/nonce data /**** - * important! - * why zero iv + nonce first data block is secure? + * security of zero_iv + nonce first data block * https://crypto.stackexchange.com/questions/5421/using-cbc-with-a-fixed-iv-and-a-random-first-plaintext-block ****/ + unordered_map auth_mode_tostring = {{auth_none, "none"}, {auth_md5, "md5"}, {auth_crc32, "crc32"},{auth_simple,"simple"}}; unordered_map cipher_mode_tostring={{cipher_none,"none"},{cipher_aes128cbc,"aes128cbc"},{cipher_xor,"xor"}}; diff --git a/main.cpp b/main.cpp index f3a2d4d..a5e098d 100755 --- a/main.cpp +++ b/main.cpp @@ -576,6 +576,7 @@ int server_on_raw_recv_ready(conn_info_t &conn_info,char * ip_port,char type,cha int server_on_raw_recv_handshake1(conn_info_t &conn_info,char * ip_port,char * data, int data_len); void process_arg(int argc, char *argv[]); +int find_lower_level_info(u32_t ip,u32_t &dest_ip,string &if_name,string &hw); int DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD; ////////////////=======================declear divider============================= @@ -1988,10 +1989,12 @@ int client_event_loop() { if(lower_level_manual) { + int index; + init_ifindex(if_name,index); //init_ifindex(if_name); memset(&send_info.addr_ll, 0, sizeof(send_info.addr_ll)); send_info.addr_ll.sll_family = AF_PACKET; - send_info.addr_ll.sll_ifindex = ifindex; + send_info.addr_ll.sll_ifindex =index; send_info.addr_ll.sll_halen = ETHER_ADDR_LEN; send_info.addr_ll.sll_protocol = htons(ETH_P_IP); memcpy(&send_info.addr_ll.sll_addr, dest_hw_addr, ETHER_ADDR_LEN); @@ -1999,8 +2002,39 @@ int client_event_loop() } else { - mylog(log_fatal,"--lower-level auto for client hasnt been implemented\n"); - myexit(-1); + u32_t dest_ip; + string if_name_string; + string hw_string; + if(find_lower_level_info(remote_ip_uint32,dest_ip,if_name_string,hw_string)!=0) + { + mylog(log_fatal,"auto detect lower-level info failed for %s,specific it manually\n",remote_ip); + myexit(-1); + } + mylog(log_info,"we are running at lower-level (auto) mode,%s %s %s\n",my_ntoa(dest_ip),if_name_string.c_str(),hw_string.c_str()); + + u32_t hw[6]; + memset(hw, 0, sizeof(hw)); + sscanf(hw_string.c_str(), "%x:%x:%x:%x:%x:%x",&hw[0], &hw[1], &hw[2], + &hw[3], &hw[4], &hw[5]); + + mylog(log_warn, + "make sure this is correct: if_name=<%s> dest_mac_adress=<%02x:%02x:%02x:%02x:%02x:%02x> \n", + if_name_string.c_str(), hw[0], hw[1], hw[2], hw[3], hw[4], hw[5]); + for (int i = 0; i < 6; i++) { + dest_hw_addr[i] = uint8_t(hw[i]); + } + + //mylog(log_fatal,"--lower-level auto for client hasnt been implemented\n"); + int index; + init_ifindex(if_name_string.c_str(),index); + + memset(&send_info.addr_ll, 0, sizeof(send_info.addr_ll)); + send_info.addr_ll.sll_family = AF_PACKET; + send_info.addr_ll.sll_ifindex = index; + send_info.addr_ll.sll_halen = ETHER_ADDR_LEN; + send_info.addr_ll.sll_protocol = htons(ETH_P_IP); + memcpy(&send_info.addr_ll.sll_addr, dest_hw_addr, ETHER_ADDR_LEN); + //mylog(log_info,"we are running at lower-level (manual) mode\n"); } } @@ -2225,6 +2259,7 @@ int server_event_loop() { if(lower_level_manual) { + init_ifindex(if_name,ifindex); mylog(log_info,"we are running at lower-level (manual) mode\n"); } else @@ -2467,13 +2502,7 @@ int process_lower_level_arg() lower_level=1; if(strcmp(optarg,"auto")==0) { - if(program_mode==server_mode) - return 0; - else - { - mylog(log_fatal,"--lower-level auto hasnt be implement at client side,specify it manually\n"); - myexit(-1); - } + return 0; } lower_level_manual=1; @@ -3245,30 +3274,25 @@ void iptables_rule() } + /* int test() { - int fd; - struct ifreq ifr; - - fd = socket(AF_INET, SOCK_DGRAM, 0); - - ifr.ifr_addr.sa_family = AF_INET; - - strncpy(ifr.ifr_name, "eth0", IFNAMSIZ-1); - - ioctl(fd, SIOCGIFADDR, &ifr); - - close(fd); - - printf("%s\n", inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr)); - - return 0; + char ip_str[100]="8.8.8.8"; + u32_t ip=inet_addr(ip_str); + u32_t dest_ip; + string if_name; + string hw; + find_lower_level_info(ip,dest_ip,if_name,hw); + printf("%s %s %s\n",my_ntoa(dest_ip),if_name.c_str(),hw.c_str()); + exit(0); + return 0; }*/ int main(int argc, char *argv[]) { - //printf("%s\n",my_ntoa(0x00ffffff)); + //test(); + printf("%s\n",my_ntoa(0x00ffffff)); //auto a=string_to_vec("a b c d "); //printf("%d\n",(int)a.size()); //printf("%d %d %d %d",larger_than_u32(1,2),larger_than_u32(2,1),larger_than_u32(0xeeaaeebb,2),larger_than_u32(2,0xeeaaeebb)); @@ -3319,10 +3343,6 @@ int main(int argc, char *argv[]) iptables_rule(); init_raw_socket(); - if(lower_level_manual) - { - init_ifindex(if_name); - } if(program_mode==client_mode) { diff --git a/makefile b/makefile index c9efe39..006a022 100755 --- a/makefile +++ b/makefile @@ -1,15 +1,16 @@ cc_cross=/home/wangyu/Desktop/arm-2014.05/bin/arm-none-linux-gnueabi-g++ cc_local=g++ -cc_ar71xx=/home/wangyu/OpenWrt-SDK-ar71xx-for-linux-x86_64-gcc-4.8-linaro_uClibc-0.9.33.2/staging_dir/toolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2/bin/mips-openwrt-linux-g++ -cc_bcm2708=/home/wangyu/raspberry/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf-g++ -cc_arm=/home/wangyu/Desktop/arm-2014.05/bin/arm-none-linux-gnueabi-g++ +cc_mips34kc=/toolchains/OpenWrt-SDK-ar71xx-for-linux-x86_64-gcc-4.8-linaro_uClibc-0.9.33.2/staging_dir/toolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2/bin/mips-openwrt-linux-g++ +cc_arm= /toolchains/arm-2014.05/bin/arm-none-linux-gnueabi-g++ +#cc_bcm2708=/home/wangyu/raspberry/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf-g++ FLAGS= -std=c++11 -Wall -Wextra -Wno-unused-variable -Wno-unused-parameter -Wno-missing-field-initializers SOURCES=main.cpp lib/aes.c lib/md5.c encrypt.cpp log.cpp network.cpp common.cpp -lpthread SOURCES_AES_ACC=$(filter-out lib/aes.c,$(SOURCES)) $(wildcard lib/aes_acc/aes*.c) NAME=udp2raw -TAR=${NAME}_binaries.tar.gz ${NAME}_amd64 ${NAME}_x86 ${NAME}_x86_asm_aes ${NAME}_ar71xx ${NAME}_bcm2708 ${NAME}_arm ${NAME}_amd64_hw_aes ${NAME}_arm_asm_aes ${NAME}_ar71xx_asm_aes +TARGETS=amd64 mips34kc arm amd64_hw_aes arm_asm_aes mips34kc_asm_aes x86 x86_asm_aes +TAR=${NAME}_binaries.tar.gz `echo ${TARGETS}|sed -r 's/([^ ]+)/udp2raw_\1/g'` all: rm -f ${NAME} @@ -20,28 +21,31 @@ fast: debug: rm -f ${NAME} ${cc_local} -o ${NAME} -I. ${SOURCES} ${FLAGS} -lrt -Wformat-nonliteral -D MY_DEBUG +debug2: + rm -f ${NAME} + ${cc_local} -o ${NAME} -I. ${SOURCES} ${FLAGS} -lrt -Wformat-nonliteral -ggdb -ar71xx: - ${cc_ar71xx} -o ${NAME}_ar71xx -I. ${SOURCES} ${FLAGS} -lrt -lgcc_eh -static -O3 +mips34kc: + ${cc_mips34kc} -o ${NAME}_$@ -I. ${SOURCES} ${FLAGS} -lrt -lgcc_eh -static -O3 -ar71xx_asm_aes: - ${cc_ar71xx} -o ${NAME}_ar71xx_asm_aes -I. ${SOURCES_AES_ACC} ${FLAGS} -lrt -lgcc_eh -static -O3 lib/aes_acc/asm/mips_be.S +mips34kc_asm_aes: + ${cc_mips34kc} -o ${NAME}_$@ -I. ${SOURCES_AES_ACC} ${FLAGS} -lrt -lgcc_eh -static -O3 lib/aes_acc/asm/mips_be.S -bcm2708: - ${cc_bcm2708} -o ${NAME}_bcm2708 -I. ${SOURCES} ${FLAGS} -lrt -static -O3 +#bcm2708: +# ${cc_bcm2708} -o ${NAME}_bcm2708 -I. ${SOURCES} ${FLAGS} -lrt -static -O3 amd64: - ${cc_local} -o ${NAME}_amd64 -I. ${SOURCES} ${FLAGS} -lrt -static -O3 + ${cc_local} -o ${NAME}_$@ -I. ${SOURCES} ${FLAGS} -lrt -static -O3 amd64_hw_aes: - ${cc_local} -o ${NAME}_amd64_hw_aes -I. ${SOURCES_AES_ACC} ${FLAGS} -lrt -static -O3 lib/aes_acc/asm/x64.S + ${cc_local} -o ${NAME}_$@ -I. ${SOURCES_AES_ACC} ${FLAGS} -lrt -static -O3 lib/aes_acc/asm/x64.S x86: - ${cc_local} -o ${NAME}_x86 -I. ${SOURCES} ${FLAGS} -lrt -static -O3 -m32 + ${cc_local} -o ${NAME}_$@ -I. ${SOURCES} ${FLAGS} -lrt -static -O3 -m32 x86_asm_aes: - ${cc_local} -o ${NAME}_x86_asm_aes -I. ${SOURCES_AES_ACC} ${FLAGS} -lrt -static -O3 -m32 lib/aes_acc/asm/x86.S + ${cc_local} -o ${NAME}_$@ -I. ${SOURCES_AES_ACC} ${FLAGS} -lrt -static -O3 -m32 lib/aes_acc/asm/x86.S arm: - ${cc_cross} -o ${NAME}_arm -I. ${SOURCES} ${FLAGS} -lrt -static -O3 + ${cc_arm} -o ${NAME}_$@ -I. ${SOURCES} ${FLAGS} -lrt -static -O3 arm_asm_aes: - ${cc_cross} -o ${NAME}_arm_asm_aes -I. ${SOURCES_AES_ACC} ${FLAGS} -lrt -static -O3 lib/aes_acc/asm/arm.S + ${cc_arm} -o ${NAME}_$@ -I. ${SOURCES_AES_ACC} ${FLAGS} -lrt -static -O3 lib/aes_acc/asm/arm.S cross: ${cc_cross} -o ${NAME}_cross -I. ${SOURCES} ${FLAGS} -lrt -O3 @@ -52,7 +56,7 @@ cross2: cross3: ${cc_cross} -o ${NAME}_cross -I. ${SOURCES} ${FLAGS} -lrt -static -O3 -release: amd64 x86 ar71xx bcm2708 arm amd64_hw_aes arm_asm_aes x86_asm_aes ar71xx_asm_aes +release: ${TARGETS} tar -zcvf ${TAR} clean: diff --git a/network.cpp b/network.cpp index d9485bd..67dd4e1 100644 --- a/network.cpp +++ b/network.cpp @@ -289,7 +289,7 @@ void remove_filter() //exit(-1); } } -int init_ifindex(char * if_name) +int init_ifindex(const char * if_name,int &index) { struct ifreq ifr; size_t if_name_len=strlen(if_name); @@ -305,10 +305,230 @@ int init_ifindex(char * if_name) mylog(log_fatal,"SIOCGIFINDEX fail ,%s\n",strerror(errno)); myexit(-1); } - ifindex=ifr.ifr_ifindex; - mylog(log_info,"ifname:%s ifindex:%d\n",if_name,ifindex); + index=ifr.ifr_ifindex; + mylog(log_info,"ifname:%s ifindex:%d\n",if_name,index); return 0; } +bool interface_has_arp(const char * interface) { + struct ifreq ifr; + // int sock = socket(PF_INET6, SOCK_DGRAM, IPPROTO_IP); + int sock=raw_send_fd; + memset(&ifr, 0, sizeof(ifr)); + strcpy(ifr.ifr_name, interface); + if (ioctl(sock, SIOCGIFFLAGS, &ifr) < 0) { + //perror("SIOCGIFFLAGS"); + mylog(log_fatal,"ioctl(sock, SIOCGIFFLAGS, &ifr) failed for interface %s,errno %s\n",interface,strerror(errno)); + myexit(-1); + } + //close(sock); + return !(ifr.ifr_flags & IFF_NOARP); +} +struct route_info_t +{ + string if_name; + u32_t dest; + u32_t mask; + u32_t gw; + u32_t flag; + +}; +int dest_idx=1; +int gw_idx=2; +int if_idx=0; +int mask_idx=7; +int flag_idx=3; +vector find_route_entry(const vector &route_info_vec,u32_t ip) +{ + vector res; + for(u32_t i=0;i<=32;i++) + { + u32_t mask=0xffffffff; + //mask >>=i; + //if(i==32) mask=0; //why 0xffffffff>>32 equals 0xffffffff?? + + mask <<=i; + if(i==32) mask=0; + log_bare(log_debug,"(mask:%x)",mask); + for(u32_t j=0;j>",i,j); + if((info.dest&mask)==(ip&mask)) + { + log_bare(log_debug,"found!"); + res.push_back(j); + } + } + if(res.size()!=0) + { + return res; + } + } + return res; +} +int find_direct_dest(const vector &route_info_vec,u32_t ip,u32_t &dest_ip,string &if_name) +{ + vector res; + for(int i=0;i<1000;i++) + { + res=find_route_entry(route_info_vec,ip); + log_bare(log_debug,"",(u32_t)res.size()); + if(res.size()==0) + { + mylog(log_error,"cant find route entry\n"); + return -1; + } + if(res.size()>1) + { + mylog(log_error,"found duplicated entries\n"); + return -1; + } + if((route_info_vec[res[0]].flag&2)==0) + { + dest_ip=ip; + if_name=route_info_vec[res[0]].if_name; + return 0; + } + else + { + ip=route_info_vec[res[0]].gw; + } + } + mylog(log_error,"dead loop in find_direct_dest\n"); + return -1; +} +struct arp_info_t +{ + u32_t ip; + string hw; + string if_name; +}; +int arp_ip_idx=0; +int arp_hw_idx=3; +int arp_if_idx=5; + + +int find_arp(const vector &arp_info_vec,u32_t ip,string if_name,string &hw) +{ + int pos=-1; + int count=0; + for(u32_t i=0;i1) + { + mylog(log_error,"find multiple arp entry for %s %s\n",my_ntoa(ip),if_name.c_str()); + return -1; + } + hw=arp_info_vec[pos].hw; + return 0; +} +int find_lower_level_info(u32_t ip,u32_t &dest_ip,string &if_name,string &hw) +{ + ip=htonl(ip); + if(ip==htonl(inet_addr("127.0.0.1"))) + { + dest_ip=ntohl(ip); + if_name="lo"; + hw="00:00:00:00:00:00"; + return 0; + } + + string route_file; + if(read_file("/proc/net/route",route_file)!=0) return -1; + string arp_file; + if(read_file("/proc/net/arp",arp_file)!=0) return -1; + + log_bare(log_debug,"/proc/net/route:<<%s>>\n",route_file.c_str()); + log_bare(log_debug,"/proc/net/arp:<<%s>>\n",route_file.c_str()); + + auto route_vec2=string_to_vec2(route_file.c_str()); + vector route_info_vec; + for(u32_t i=1;i",(u32_t)route_vec2[i].size()); + if(route_vec2[i].size()!=11) + { + mylog(log_error,"route coloum %d !=11 \n",int(route_vec2[i].size())); + return -1; + } + route_info_t tmp; + tmp.if_name=route_vec2[i][if_idx]; + if(hex_to_u32_with_endian(route_vec2[i][dest_idx],tmp.dest)!=0) return -1; + if(hex_to_u32_with_endian(route_vec2[i][gw_idx],tmp.gw)!=0) return -1; + if(hex_to_u32_with_endian(route_vec2[i][mask_idx],tmp.mask)!=0) return -1; + if(hex_to_u32(route_vec2[i][flag_idx],tmp.flag)!=0)return -1; + route_info_vec.push_back(tmp); + for(u32_t j=0;j",route_vec2[i][j].c_str()); + } + log_bare(log_debug,"%s dest:%x mask:%x gw:%x flag:%x",tmp.if_name.c_str(),tmp.dest,tmp.mask,tmp.gw,tmp.flag); + log_bare(log_debug,"\n"); + } + + if(find_direct_dest(route_info_vec,ip,dest_ip,if_name)!=0) + { + mylog(log_error,"find_direct_dest failed for ip %s\n",my_ntoa(ntohl(ip))); + return -1; + } + + + log_bare(log_debug,"========\n"); + auto arp_vec2=string_to_vec2(arp_file.c_str()); + vector arp_info_vec; + for(u32_t i=1;i>",(int)arp_vec2[i].size()); + + for(u32_t j=0;j",arp_vec2[i][j].c_str()); + } + if(arp_vec2[i].size()!=6) + { + mylog(log_error,"arp coloum %d !=11 \n",int(arp_vec2[i].size())); + return -1; + } + arp_info_t tmp; + tmp.if_name=arp_vec2[i][arp_if_idx]; + tmp.hw=arp_vec2[i][arp_hw_idx]; + tmp.ip=htonl(inet_addr(arp_vec2[i][arp_ip_idx].c_str())); + arp_info_vec.push_back(tmp); + log_bare(log_debug,"\n"); + } + if(!interface_has_arp(if_name.c_str())) + { + mylog(log_info,"%s is a noarp interface,using 00:00:00:00:00:00\n",if_name.c_str()); + hw="00:00:00:00:00:00"; + } + else if(find_arp(arp_info_vec,dest_ip,if_name,hw)!=0) + { + mylog(log_error,"find_arp failed for dest_ip %s ,if_name %s\n",my_ntoa(ntohl(ip)),if_name.c_str()); + return -1; + } + //printf("%s\n",hw.c_str()); + + dest_ip=ntohl(dest_ip); + return 0; +} + int send_raw_ip(raw_info_t &raw_info,const char * payload,int payloadlen) { diff --git a/network.h b/network.h index b9bfcb8..aa8b645 100644 --- a/network.h +++ b/network.h @@ -86,8 +86,9 @@ int init_raw_socket(); void init_filter(int port); void remove_filter(); -int init_ifindex(char * if_name); +int init_ifindex(const char * if_name,int &index); +int find_lower_level_info(u32_t ip,u32_t &dest_ip,string &if_name,string &hw); int send_raw_ip(raw_info_t &raw_info,const char * payload,int payloadlen);