瀏覽代碼

implemented --lower-level auto for client. better makefile

wangyu- 8 年之前
父節點
當前提交
dc4936dc60
共有 7 個文件被更改,包括 341 次插入64 次删除
  1. 39 9
      common.cpp
  2. 3 1
      common.h
  3. 2 2
      encrypt.cpp
  4. 51 31
      main.cpp
  5. 21 17
      makefile
  6. 223 3
      network.cpp
  7. 2 1
      network.h

+ 39 - 9
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> 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> > 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;
 }

+ 3 - 1
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> string_to_vec(const char * s,const char * sp);
 vector< vector <string> > string_to_vec2(const char * s);
@@ -170,6 +170,8 @@ string trim_conf_line(const string& str);
 
 vector<string> 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_ */

+ 2 - 2
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<int, const char *> auth_mode_tostring = {{auth_none, "none"}, {auth_md5, "md5"}, {auth_crc32, "crc32"},{auth_simple,"simple"}};
 unordered_map<int, const char *> cipher_mode_tostring={{cipher_none,"none"},{cipher_aes128cbc,"aes128cbc"},{cipher_xor,"xor"}};
 

+ 51 - 31
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)
 	{

+ 21 - 17
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:	

+ 223 - 3
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<int> find_route_entry(const vector<route_info_t> &route_info_vec,u32_t ip)
+{
+	vector<int> 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<route_info_vec.size();j++)
+		{
+			const route_info_t & info=route_info_vec[j];
+			if(info.mask!=mask)
+				continue;
+			log_bare(log_debug,"<<%d,%d>>",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_t> &route_info_vec,u32_t ip,u32_t &dest_ip,string &if_name)
+{
+	vector<int> res;
+	for(int i=0;i<1000;i++)
+	{
+		res=find_route_entry(route_info_vec,ip);
+		log_bare(log_debug,"<entry:%u>",(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_t> &arp_info_vec,u32_t ip,string if_name,string &hw)
+{
+	int pos=-1;
+	int count=0;
+	for(u32_t i=0;i<arp_info_vec.size();i++)
+	{
+		const arp_info_t & info=arp_info_vec[i];
+		if(info.if_name!=if_name) continue;
+		if(info.ip==ip)
+		{
+			count++;
+			pos=i;
+		}
+	}
+	if(count==0)
+	{
+		//mylog(log_warn,"cant find arp entry for %s %s,using 00:00:00:00:00:00\n",my_ntoa(ip),if_name.c_str());
+		//hw="00:00:00:00:00:00";
+		mylog(log_error,"cant find arp entry for %s %s\n",my_ntoa(ip),if_name.c_str());
+		return -1;
+	}
+	if(count>1)
+	{
+		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_t> route_info_vec;
+	for(u32_t i=1;i<route_vec2.size();i++)
+	{
+		log_bare(log_debug,"<size:%u>",(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].size();j++)
+		{
+			log_bare(log_debug,"<%s>",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_t> arp_info_vec;
+	for(u32_t i=1;i<arp_vec2.size();i++)
+	{
+		log_bare(log_debug,"<<arp_vec2[i].size(): %d>>",(int)arp_vec2[i].size());
+
+		for(u32_t j=0;j<arp_vec2[i].size();j++)
+		{
+			log_bare(log_debug,"<%s>",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)
 {

+ 2 - 1
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);