Browse Source

added option lower-level

wangyu 8 years ago
parent
commit
307399b00a
9 changed files with 241 additions and 37 deletions
  1. 4 2
      README.md
  2. 2 2
      common.cpp
  3. 1 0
      common.h
  4. 8 3
      doc/README.zh-cn.md
  5. 87 0
      doc/openvpn_guide.md
  6. 20 0
      main.cpp
  7. 9 4
      makefile
  8. 105 26
      network.cpp
  9. 5 0
      network.h

+ 4 - 2
README.md

@@ -10,8 +10,8 @@ Which can help you bypass udp blocking or udp QOS or just poorly supported udp N
 encrypt your traffic with aes128cbc,protects data integrity by md5 or crc32,protect replay attack with an anti-replay window smiliar to ipsec/openvpn.
 encrypt your traffic with aes128cbc,protects data integrity by md5 or crc32,protect replay attack with an anti-replay window smiliar to ipsec/openvpn.
 ### Simulated TCP Handshake
 ### Simulated TCP Handshake
 simulated 3-way handshake,simluated seq ack_seq. Simluated tcp options:MSS,sackOk,TS,TS_ack,wscale. Provides real-time delivery ,no tcp over tcp problem when using openvpn.
 simulated 3-way handshake,simluated seq ack_seq. Simluated tcp options:MSS,sackOk,TS,TS_ack,wscale. Provides real-time delivery ,no tcp over tcp problem when using openvpn.
-### Connnection Recover
-After connection timeouts,the client will re-connect.if re-connection is successful,the previous connection will be recovered,and all existed udp conversations will stay vaild.
+### Connnection Failure Dectection & Recover
+Conection failure detection by hearbeat. After hearbeat timeouts,client will auto change port and re-connect.if re-connection is successful,the previous connection will be recovered,and all existed udp conversations will stay vaild.
 ### Other Features
 ### Other Features
 Multiplexing ,one client supports multi udp connections,all of those traffic will share one raw connection
 Multiplexing ,one client supports multi udp connections,all of those traffic will share one raw connection
 
 
@@ -118,6 +118,8 @@ raw_mode: faketcp  cipher_mode: aes128cbc  auth_mode: md5
 2. no TCP ovr tcp problem (tcp over tcp problem http://sites.inka.de/bigred/devel/tcp-tcp.html ,https://community.openvpn.net/openvpn/ticket/2 )
 2. no TCP ovr tcp problem (tcp over tcp problem http://sites.inka.de/bigred/devel/tcp-tcp.html ,https://community.openvpn.net/openvpn/ticket/2 )
 
 
 3. openvpn over icmp also becomes a choice
 3. openvpn over icmp also becomes a choice
+
+more details at [openvpn+udp2raw_guide](/doc/openvpn_guide.md)
 ### tunneling kcptun
 ### tunneling kcptun
 make kcptun support tcp mode.
 make kcptun support tcp mode.
 (kcptun, https://github.com/xtaci/kcptun)
 (kcptun, https://github.com/xtaci/kcptun)

+ 2 - 2
common.cpp

@@ -198,12 +198,12 @@ int set_buf_size(int fd)
 {
 {
     if(setsockopt(fd, SOL_SOCKET, SO_SNDBUFFORCE, &socket_buf_size, sizeof(socket_buf_size))<0)
     if(setsockopt(fd, SOL_SOCKET, SO_SNDBUFFORCE, &socket_buf_size, sizeof(socket_buf_size))<0)
     {
     {
-    	mylog(log_fatal,"SO_SNDBUFFORCE fail\n");
+    	mylog(log_fatal,"SO_SNDBUFFORCE fail,fd %d\n",fd);
     	myexit(1);
     	myexit(1);
     }
     }
     if(setsockopt(fd, SOL_SOCKET, SO_RCVBUFFORCE, &socket_buf_size, sizeof(socket_buf_size))<0)
     if(setsockopt(fd, SOL_SOCKET, SO_RCVBUFFORCE, &socket_buf_size, sizeof(socket_buf_size))<0)
     {
     {
-    	mylog(log_fatal,"SO_RCVBUFFORCE fail\n");
+    	mylog(log_fatal,"SO_RCVBUFFORCE fail,fd %d\n",fd);
     	myexit(1);
     	myexit(1);
     }
     }
 	return 0;
 	return 0;

+ 1 - 0
common.h

@@ -42,6 +42,7 @@
 #include <arpa/inet.h>
 #include <arpa/inet.h>
 #include <stdarg.h>
 #include <stdarg.h>
 #include <assert.h>
 #include <assert.h>
+#include <linux/if_packet.h>
 
 
 
 
 
 

+ 8 - 3
doc/README.zh-cn.md

@@ -18,10 +18,12 @@ Udp2raw-tunnel
 ### 模拟TCP3次握手
 ### 模拟TCP3次握手
 模拟TCP3次握手,模拟seq ack过程。另外还模拟了一些tcp option:MSS,sackOk,TS,TS_ack,wscale,用来使流量看起来更像是由普通的linux tcp协议栈发送的。
 模拟TCP3次握手,模拟seq ack过程。另外还模拟了一些tcp option:MSS,sackOk,TS,TS_ack,wscale,用来使流量看起来更像是由普通的linux tcp协议栈发送的。
 
 
-### 连接快速恢复
+### 连接保持,连接快速恢复
 心跳机制检查连接是否中断,一旦心跳超时。client会立即换raw socket的端口重连,重连成功后会恢复之前中断的连接。虽然raw端的端口变了,但是udp端的所有连接都会继续有效。udp这边感觉不到raw端的重连,只会感觉到短暂断流,这跟普通的短暂丢包是类似的,不会导致上层应用重连。
 心跳机制检查连接是否中断,一旦心跳超时。client会立即换raw socket的端口重连,重连成功后会恢复之前中断的连接。虽然raw端的端口变了,但是udp端的所有连接都会继续有效。udp这边感觉不到raw端的重连,只会感觉到短暂断流,这跟普通的短暂丢包是类似的,不会导致上层应用重连。
 
 
-另一个优化是,重连只需要client发起,就可以立即被server处理,不需要等到server端的连接超时后。
+另一个优化是,重连只需要client发起,就可以立即被server处理,不需要等到server端的连接超时后。这个在单向连接失效的情况下有用。
+
+另外,对于有大量client的情况,对于不同client,server发送的心跳是错开时间发送的,不会因为短时间发送大量的心跳而造成拥塞和延迟抖动。
 
 
 ### 其他特性
 ### 其他特性
 信道复用,client的udp端支持多个连接。
 信道复用,client的udp端支持多个连接。
@@ -32,7 +34,10 @@ NAT 穿透 ,tcp icmp udp模式都支持nat穿透。
 
 
 支持Openvz,配合finalspeed使用,可以在openvz上用tcp模式的finalspeed
 支持Openvz,配合finalspeed使用,可以在openvz上用tcp模式的finalspeed
 
 
-支持Openwrt,没有编译以来,容易编译到任何平台上。release中提供了ar71xx版本的binary
+支持Openwrt,没有编译依赖,容易编译到任何平台上。release中提供了ar71xx版本的binary
+
+单进程,纯异步,无锁,高并发,除了回收过期连接外,所有操作的时间复杂度都跟连接数无关。回收过期连接这个操作是个批量操作,会定期进行,但是会保证一次回收的数量不超过总数的1/10(可配置),不会造成延迟抖动。
+
 ### 关键词
 ### 关键词
 突破udp qos,突破udp屏蔽,openvpn tcp over tcp problem,openvpn over icmp,udp to icmp tunnel,udp to tcp tunnel,udp via icmp,udp via tcp
 突破udp qos,突破udp屏蔽,openvpn tcp over tcp problem,openvpn over icmp,udp to icmp tunnel,udp to tcp tunnel,udp via icmp,udp via tcp
 
 

+ 87 - 0
doc/openvpn_guide.md

@@ -1 +1,88 @@
+# udp2raw+openvpn config guide
+![image_vpn](/images/openvpn.PNG)
 
 
+![image4](/images/image4.PNG)
+# udp2raw command
+#### run at server side
+```
+./udp2raw_amd64 -s -l0.0.0.0:8855 -r 127.0.0.1:7777 -k "passwd" --raw-mode faketcp -a
+```
+#### run at client side
+assume server ip is 45.66.77.88
+```
+./udp2raw_amd64 -s -l0.0.0.0:3333 -r 45.66.77.88:8855 -k "passwd" --raw-mode faketcp -a
+```
+
+
+# openvpn config
+
+#### client side config
+```
+
+remote 127.0.0.1 3333
+resolv-retry infinite 
+nobind 
+persist-key 
+persist-tun  
+
+ca /root/add-on/openvpn/ca.crt
+cert /root/add-on/openvpn/client.crt
+key /root/add-on/openvpn/client.key
+
+keepalive 3 20
+verb 3
+mute 20
+
+comp-lzo no
+cipher none      ##### disable openvpn 's cipher and auth for maxmized peformance. 
+auth none        ##### you can enable openvpn's cipher and auth,if you dont care about peformance,oryou dont trust udp2raw 's encryption
+
+fragment 1200       ##### very important    you can turn it up a bit. but,the lower the safer
+mssfix 1200         ##### very important
+
+sndbuf 2000000      ##### important
+rcvbuf 2000000      ##### important
+txqueuelen 4000     ##### suggested
+```
+
+
+#### server side config
+```
+local 0.0.0.0
+port 7777 
+proto udp
+dev tun 
+
+ca /etc/openvpn/easy-rsa/2.0/keys/ca.crt
+cert /etc/openvpn/easy-rsa/2.0/keys/server.crt
+key /etc/openvpn/easy-rsa/2.0/keys/server.key
+dh /etc/openvpn/easy-rsa/2.0/keys/dh1024.pem
+
+server 10.222.2.0 255.255.255.0 
+ifconfig 10.222.2.1 10.222.2.6
+
+client-to-client
+duplicate-cn 
+keepalive 10 60 
+
+max-clients 50
+
+persist-key
+persist-tun
+
+status /etc/openvpn/openvpn-status.log
+
+verb 3
+mute 20  
+
+comp-lzo no
+cipher none      ##### disable openvpn 's cipher and auth for maxmized peformance. 
+auth none        ##### you can enable openvpn's cipher and auth,if you dont care about peformance,oryou dont trust udp2raw 's encryption
+
+fragment 1200       ##### very important    you can turn it up a bit. but,the lower the safer
+mssfix 1200         ##### very important
+
+sndbuf 2000000      ##### important
+rcvbuf 2000000      ##### important
+txqueuelen 4000     ##### suggested
+```

+ 20 - 0
main.cpp

@@ -38,6 +38,7 @@ int disable_anti_replay=0;
 char key_string[1000]= "secret key";
 char key_string[1000]= "secret key";
 char key[16];//,key2[16];
 char key[16];//,key2[16];
 
 
+
 //uint64_t current_time_rough=0;
 //uint64_t current_time_rough=0;
 
 
 
 
@@ -2351,6 +2352,7 @@ void process_arg(int argc, char *argv[])
 		{"gen-rule", no_argument,    0, 'g'},
 		{"gen-rule", no_argument,    0, 'g'},
 		{"debug", no_argument,    0, 1},
 		{"debug", no_argument,    0, 1},
 		{"clear", no_argument,    0, 1},
 		{"clear", no_argument,    0, 1},
+		{"lower-level", required_argument,    0, 1},
 		{"sock-buf", required_argument,    0, 1},
 		{"sock-buf", required_argument,    0, 1},
 		{"seq-mode", required_argument,    0, 1},
 		{"seq-mode", required_argument,    0, 1},
 		{NULL, 0, 0, 0}
 		{NULL, 0, 0, 0}
@@ -2544,6 +2546,24 @@ void process_arg(int argc, char *argv[])
 			else if(strcmp(long_options[option_index].name,"log-level")==0)
 			else if(strcmp(long_options[option_index].name,"log-level")==0)
 			{
 			{
 			}
 			}
+			else if(strcmp(long_options[option_index].name,"lower-level")==0)
+			{
+				if(strchr(optarg,'#')==0)
+				{
+					mylog(log_fatal,"lower-level parameter invaild,should be if_name#mac_adress  ,ie eth0#00:23:45:67:89:b9\n");
+					myexit(-1);
+				}
+				lower_level=1;
+				u32_t hw[6];
+				memset(hw,0,sizeof(hw));
+				sscanf(optarg,"%[^#]#%x:%x:%x:%x:%x:%x",if_name,&hw[0],&hw[1],&hw[2],&hw[3],&hw[4],&hw[5]);
+
+				mylog(log_warn,"make sure this is correct:   ifname=<%s>  gateway_hw_hd=<%x:%x:%x:%x:%x:%x>  \n",if_name,hw[0],hw[1],hw[2],hw[3],hw[4],hw[5]);
+				for(int i=0;i<6;i++)
+				{
+					oppsite_hw_addr[i]=uint8_t(hw[i]);
+				}
+			}
 			else if(strcmp(long_options[option_index].name,"disable-color")==0)
 			else if(strcmp(long_options[option_index].name,"disable-color")==0)
 			{
 			{
 				//enable_log_color=0;
 				//enable_log_color=0;

+ 9 - 4
makefile

@@ -4,13 +4,18 @@ FLAGS2= -O3
 all:
 all:
 	sudo killall udp2raw||true
 	sudo killall udp2raw||true
 	sleep 0.2
 	sleep 0.2
-	g++ main.cpp -o udp2raw_amd64 -static  -ggdb -I. lib/aes.c lib/md5.c encrypt.cpp log.cpp network.cpp common.cpp -lrt -std=c++11    ${FLAGS} ${FLAGS2}
-	${ccmips} main.cpp -o udp2raw_ar71xx  -lrt -I. lib/aes.c lib/md5.c encrypt.cpp log.cpp network.cpp common.cpp -std=c++11 ${FLAGS} ${FLAGS2}
+	g++ main.cpp -o udp2raw  -static  -ggdb -I. lib/aes.c lib/md5.c encrypt.cpp log.cpp network.cpp common.cpp -lrt -std=c++11    ${FLAGS} ${FLAGS2}
+#	${ccmips} main.cpp -o udp2raw_ar71xx  -lrt -I. lib/aes.c lib/md5.c encrypt.cpp log.cpp network.cpp common.cpp -std=c++11 ${FLAGS} ${FLAGS2}
 fast:
 fast:
 	sudo killall udp2raw||true
 	sudo killall udp2raw||true
 	sleep 0.2
 	sleep 0.2
-	g++ main.cpp -o udp2raw_amd64 -ggdb -I. lib/aes.c lib/md5.c encrypt.cpp log.cpp network.cpp common.cpp -lrt -std=c++11    ${FLAGS} 
+	g++ main.cpp -o udp2raw -ggdb -I. lib/aes.c lib/md5.c encrypt.cpp log.cpp network.cpp common.cpp -lrt -std=c++11    ${FLAGS} 
 
 
 
 
 debug:
 debug:
-	g++ main.cpp -o udp2raw_amd64 -static  -ggdb -I. -Ilib lib/aes.c lib/md5.c encrypt.cpp log.cpp network.cpp common.cpp -lrt -std=c++11    ${FLAGS} -Wformat-nonliteral -D MY_DEBUG
+	g++ main.cpp -o udp2raw -static  -ggdb -I. -Ilib lib/aes.c lib/md5.c encrypt.cpp log.cpp network.cpp common.cpp -lrt -std=c++11    ${FLAGS} -Wformat-nonliteral -D MY_DEBUG
+
+release:
+	g++ main.cpp -o udp2raw_amd64  -static  -ggdb -I. lib/aes.c lib/md5.c encrypt.cpp log.cpp network.cpp common.cpp -lrt -std=c++11    ${FLAGS} ${FLAGS2}
+	${ccmips} main.cpp -o udp2raw_ar71xx  -lrt -I. lib/aes.c lib/md5.c encrypt.cpp log.cpp network.cpp common.cpp -std=c++11 ${FLAGS} ${FLAGS2}
+	

+ 105 - 26
network.cpp

@@ -20,7 +20,13 @@ int disable_bpf_filter=0;  //for test only,most time no need to disable this
 
 
 u32_t bind_address_uint32=0;
 u32_t bind_address_uint32=0;
 
 
+int lower_level=0;
+int ifindex=-1;
+char if_name[100]="";
 
 
+unsigned char oppsite_hw_addr[6]=
+    {0xff,0xff,0xff,0xff,0xff,0xff};
+//{0x00,0x23,0x45,0x67,0x89,0xb9};
 
 
 struct sock_filter code_tcp_old[] = {
 struct sock_filter code_tcp_old[] = {
 		{ 0x28, 0, 0, 0x0000000c },//0
 		{ 0x28, 0, 0, 0x0000000c },//0
@@ -156,20 +162,47 @@ packet_info_t::packet_info_t()
 int init_raw_socket()
 int init_raw_socket()
 {
 {
 
 
-	raw_send_fd = socket(AF_INET , SOCK_RAW , IPPROTO_TCP);
+	if(lower_level==0)
+	{
+		raw_send_fd = socket(AF_INET , SOCK_RAW , IPPROTO_TCP);
 
 
+	    if(raw_send_fd == -1) {
+	    	mylog(log_fatal,"Failed to create raw_send_fd\n");
+	        //perror("Failed to create raw_send_fd");
+	        myexit(1);
+	    }
 
 
-    if(raw_send_fd == -1) {
-    	mylog(log_fatal,"Failed to create raw_send_fd\n");
-        //perror("Failed to create raw_send_fd");
-        myexit(1);
-    }
+	    int one = 1;
+	    const int *val = &one;
+	    if (setsockopt (raw_send_fd, IPPROTO_IP, IP_HDRINCL, val, sizeof (one)) < 0) {
+	    	mylog(log_fatal,"Error setting IP_HDRINCL %d\n",errno);
+	        //perror("Error setting IP_HDRINCL");
+	        myexit(2);
+	    }
+
+
+	}
+	else
+	{
+		raw_send_fd = socket(PF_PACKET , SOCK_DGRAM , htons(ETH_P_IP));
+
+	    if(raw_send_fd == -1) {
+	    	mylog(log_fatal,"Failed to create raw_send_fd\n");
+	        //perror("Failed to create raw_send_fd");
+	        myexit(1);
+	    }
+		init_ifindex(if_name);
+
+	}
 
 
     if(setsockopt(raw_send_fd, SOL_SOCKET, SO_SNDBUFFORCE, &socket_buf_size, sizeof(socket_buf_size))<0)
     if(setsockopt(raw_send_fd, SOL_SOCKET, SO_SNDBUFFORCE, &socket_buf_size, sizeof(socket_buf_size))<0)
     {
     {
     	mylog(log_fatal,"SO_SNDBUFFORCE fail\n");
     	mylog(log_fatal,"SO_SNDBUFFORCE fail\n");
     	myexit(1);
     	myexit(1);
     }
     }
+
+
+
 	//raw_fd = socket(AF_PACKET, SOCK_DGRAM, htons(ETH_P_ALL));
 	//raw_fd = socket(AF_PACKET, SOCK_DGRAM, htons(ETH_P_ALL));
 
 
 	raw_recv_fd= socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP));
 	raw_recv_fd= socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP));
@@ -188,13 +221,7 @@ int init_raw_socket()
 
 
     //IP_HDRINCL to tell the kernel that headers are included in the packet
     //IP_HDRINCL to tell the kernel that headers are included in the packet
 
 
-    int one = 1;
-    const int *val = &one;
-    if (setsockopt (raw_send_fd, IPPROTO_IP, IP_HDRINCL, val, sizeof (one)) < 0) {
-    	mylog(log_fatal,"Error setting IP_HDRINCL %d\n",errno);
-        //perror("Error setting IP_HDRINCL");
-        myexit(2);
-    }
+
 
 
     setnonblocking(raw_send_fd); //not really necessary
     setnonblocking(raw_send_fd); //not really necessary
     setnonblocking(raw_recv_fd);
     setnonblocking(raw_recv_fd);
@@ -258,8 +285,26 @@ void remove_filter()
 		//exit(-1);
 		//exit(-1);
 	}
 	}
 }
 }
+int init_ifindex(char * if_name)
+{
+	struct ifreq ifr;
+	size_t if_name_len=strlen(if_name);
+	if (if_name_len<sizeof(ifr.ifr_name)) {
+		memcpy(ifr.ifr_name,if_name,if_name_len);
+		ifr.ifr_name[if_name_len]=0;
+	} else {
+		mylog(log_fatal,"interface name is too long\n");
+		myexit(-1);
+	}
+	if (ioctl(raw_send_fd,SIOCGIFINDEX,&ifr)==-1) {
 
 
-
+		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);
+	return 0;
+}
 
 
 
 
 int send_raw_ip(raw_info_t &raw_info,const char * payload,int payloadlen)
 int send_raw_ip(raw_info_t &raw_info,const char * payload,int payloadlen)
@@ -271,17 +316,20 @@ int send_raw_ip(raw_info_t &raw_info,const char * payload,int payloadlen)
 	struct iphdr *iph = (struct iphdr *) send_raw_ip_buf;
 	struct iphdr *iph = (struct iphdr *) send_raw_ip_buf;
     memset(iph,0,sizeof(iphdr));
     memset(iph,0,sizeof(iphdr));
 
 
-	struct sockaddr_in sin;
-    sin.sin_family = AF_INET;
-    //sin.sin_port = htons(info.dst_port); //dont need this
-    sin.sin_addr.s_addr = send_info.dst_ip;
+    static unsigned short ip_id=1;
 
 
     iph->ihl = sizeof(iphdr)/4;  //we dont use ip options,so the length is just sizeof(iphdr)
     iph->ihl = sizeof(iphdr)/4;  //we dont use ip options,so the length is just sizeof(iphdr)
     iph->version = 4;
     iph->version = 4;
     iph->tos = 0;
     iph->tos = 0;
 
 
-   // iph->id = htonl (ip_id++); //Id of this packet
-    // iph->id = 0; //Id of this packet  ,kernel will auto fill this if id is zero
+    if(lower_level)
+    {
+    	iph->id=0;
+    	//iph->id = htons (ip_id++); //Id of this packet
+    }
+    else
+    	iph->id = 0; //Id of this packet  ,kernel will auto fill this if id is zero  ,or really?????// todo //seems like there is a problem
+
     iph->frag_off = htons(0x4000); //DF set,others are zero
     iph->frag_off = htons(0x4000); //DF set,others are zero
    // iph->frag_off = htons(0x0000); //DF set,others are zero
    // iph->frag_off = htons(0x0000); //DF set,others are zero
     iph->ttl = 64;
     iph->ttl = 64;
@@ -291,20 +339,51 @@ int send_raw_ip(raw_info_t &raw_info,const char * payload,int payloadlen)
     iph->daddr = send_info.dst_ip;
     iph->daddr = send_info.dst_ip;
 
 
     uint16_t ip_tot_len=sizeof (struct iphdr)+payloadlen;
     uint16_t ip_tot_len=sizeof (struct iphdr)+payloadlen;
-   // iph->tot_len = htons(ip_tot_len);            //this is not necessary ,kernel will always auto fill this  //http://man7.org/linux/man-pages/man7/raw.7.html
-    //iph->tot_len = ip_tot_len;
+    if(lower_level)iph->tot_len = htons(ip_tot_len);            //this is not necessary ,kernel will always auto fill this  //http://man7.org/linux/man-pages/man7/raw.7.html
+    else
+    	iph->tot_len = 0;
+
     memcpy(send_raw_ip_buf+sizeof(iphdr) , payload, payloadlen);
     memcpy(send_raw_ip_buf+sizeof(iphdr) , payload, payloadlen);
 
 
-    //iph->check = csum ((unsigned short *) send_raw_ip_buf, ip_tot_len); //this is not necessary ,kernel will always auto fill this
+    if(lower_level) iph->check =
+    		csum ((unsigned short *) send_raw_ip_buf, iph->ihl*4); //this is not necessary ,kernel will always auto fill this
+    else
+    	iph->check=0;
+
+    int ret;
+    if(lower_level==0)
+    {
+		struct sockaddr_in sin;
+		sin.sin_family = AF_INET;
+		//sin.sin_port = htons(info.dst_port); //dont need this
+		sin.sin_addr.s_addr = send_info.dst_ip;
+		ret = sendto(raw_send_fd, send_raw_ip_buf, ip_tot_len ,  0, (struct sockaddr *) &sin, sizeof (sin));
+
+    }
+    else
+    {
 
 
-    int ret = sendto(raw_send_fd, send_raw_ip_buf, ip_tot_len ,  0, (struct sockaddr *) &sin, sizeof (sin));
+    	struct sockaddr_ll addr;
+    	memset(&addr,0,sizeof(addr));
 
 
+    	addr.sll_family=AF_PACKET;
+    	addr.sll_ifindex=ifindex;
+    	addr.sll_halen=ETHER_ADDR_LEN;
+    	addr.sll_protocol=htons(ETH_P_IP);
+    	memcpy(addr.sll_addr,oppsite_hw_addr,ETHER_ADDR_LEN);
+    	ret = sendto(raw_send_fd, send_raw_ip_buf, ip_tot_len ,  0, (struct sockaddr *) &addr, sizeof (addr));
+    }
     if(ret==-1)
     if(ret==-1)
     {
     {
-    	mylog(log_debug,"sendto failed\n");
+
+    	mylog(log_trace,"sendto failed\n");
     	//perror("why?");
     	//perror("why?");
     	return -1;
     	return -1;
     }
     }
+    else
+    {
+    	//mylog(log_info,"sendto succ\n");
+    }
     return 0;
     return 0;
 }
 }
 int peek_raw(packet_info_t &peek_info)
 int peek_raw(packet_info_t &peek_info)
@@ -426,7 +505,7 @@ int recv_raw_ip(raw_info_t &raw_info,char * &payload,int &payloadlen)
 
 
     if(ip_chk!=0)
     if(ip_chk!=0)
      {
      {
-    	mylog(log_debug,"ip header error %d\n",ip_chk);
+    	mylog(log_debug,"ip header error %x\n",ip_chk);
      	return -1;
      	return -1;
      }
      }
 
 

+ 5 - 0
network.h

@@ -15,6 +15,10 @@ extern int filter_port;
 extern u32_t bind_address_uint32;
 extern u32_t bind_address_uint32;
 extern int disable_bpf_filter;
 extern int disable_bpf_filter;
 
 
+extern int lower_level;
+extern char if_name[100];
+extern unsigned char oppsite_hw_addr[];
+
 struct icmphdr
 struct icmphdr
 {
 {
 	uint8_t type;
 	uint8_t type;
@@ -76,6 +80,7 @@ int init_raw_socket();
 void init_filter(int port);
 void init_filter(int port);
 
 
 void remove_filter();
 void remove_filter();
+int init_ifindex(char * if_name);
 
 
 
 
 int send_raw_ip(raw_info_t &raw_info,const char * payload,int payloadlen);
 int send_raw_ip(raw_info_t &raw_info,const char * payload,int payloadlen);