Compare commits

..

73 Commits

Author SHA1 Message Date
root
eea016cab4 Merge branch 'master' of https://github.com/wangyu-/udp2raw-tunnel 2017-08-18 00:29:30 +08:00
wangyu
8356b45c3b trival 2017-08-18 00:23:18 +08:00
wangyu
e502076394 fixed help page.some new function in common 2017-08-17 23:40:17 +08:00
wangyu-
1ca79a07b6 Update finalspeed_step_by_step.md 2017-08-16 22:11:29 -07:00
wangyu-
b35d8ecd34 Update kcptun_step_by_step.md 2017-08-16 21:46:54 -07:00
wangyu-
5ed3bae33d Update kcptun_step_by_step.md 2017-08-16 21:46:36 -07:00
wangyu-
ec298b355e Update finalspeed_step_by_step.md 2017-08-16 21:42:04 -07:00
wangyu-
33fb57d6d0 Update finalspeed_step_by_step.md 2017-08-16 21:36:03 -07:00
wangyu-
bdc7e3e43f Update finalspeed_step_by_step.md 2017-08-16 21:30:07 -07:00
wangyu-
b10d9421d3 Update finalspeed_step_by_step.md 2017-08-16 21:29:38 -07:00
wangyu-
bdc1f74f8f Update finalspeed_step_by_step.md 2017-08-16 21:28:18 -07:00
wangyu-
5cca489825 Add files via upload 2017-08-16 21:00:23 -07:00
wangyu-
3897ac3847 Update android_guide.md 2017-08-16 19:47:19 -07:00
wangyu-
231fd05680 Update README.zh-cn.md 2017-08-16 10:20:01 -07:00
wangyu-
3a362f6598 Update README.md 2017-08-16 08:58:00 -07:00
wangyu-
99b3ddf6a1 Update android_guide.md 2017-08-16 06:43:05 -07:00
wangyu-
09b00ef07b Update android_guide.md 2017-08-16 06:24:45 -07:00
wangyu-
c0628959d4 Update README.zh-cn.md 2017-08-16 06:23:22 -07:00
wangyu-
9aa229569d Update README.zh-cn.md 2017-08-16 06:23:03 -07:00
wangyu-
842766ae76 Update README.md 2017-08-16 06:21:33 -07:00
wangyu-
9e5b2140b3 Add files via upload 2017-08-16 06:18:00 -07:00
root
ac02ea91d7 Merge branch 'master' of https://github.com/wangyu-/udp2raw-tunnel 2017-08-16 19:45:26 +08:00
wangyu
837de123b2 added android target to makefile,fixed some log 2017-08-16 19:44:19 +08:00
wangyu-
358c5c47ff Update README.zh-cn.md 2017-08-16 04:42:06 -07:00
wangyu-
19102700a5 Update README.md 2017-08-16 04:41:40 -07:00
wangyu-
f848839232 Update README.zh-cn.md 2017-08-16 04:38:19 -07:00
wangyu-
a13269a0b0 Update README.zh-cn.md 2017-08-16 04:37:39 -07:00
wangyu-
1d8223632b Update README.md 2017-08-16 04:35:46 -07:00
wangyu-
e459b74bdf Update README.md 2017-08-16 04:35:15 -07:00
wangyu-
9429a1c7db Update README.zh-cn.md 2017-08-16 04:32:09 -07:00
wangyu-
f5d93cb80d Update README.md 2017-08-16 04:29:35 -07:00
wangyu-
f591ba101c Update android_guide.md 2017-08-16 04:27:50 -07:00
wangyu-
5236bc2f4e Create android_guide.md 2017-08-16 04:26:06 -07:00
wangyu-
c7d9312cd2 Delete android_guide 2017-08-16 04:25:46 -07:00
wangyu-
85dfdd416f Create android_guide 2017-08-16 04:25:19 -07:00
wangyu-
7a62918b74 Add files via upload 2017-08-16 04:15:39 -07:00
wangyu-
138b34335c Update README.zh-cn.md 2017-08-16 04:12:34 -07:00
wangyu-
c5c74a3f35 Update README.md 2017-08-16 04:10:50 -07:00
wangyu-
0a4f53e579 Update README.md 2017-08-15 08:53:34 -07:00
wangyu-
dc41a3dbad Update README.md 2017-08-15 08:48:31 -07:00
wangyu-
bd08278f1b Update README.zh-cn.md 2017-08-15 08:29:02 -07:00
wangyu-
bcab893c53 Update README.md 2017-08-15 08:25:31 -07:00
wangyu-
f3f43b85d2 Update README.md 2017-08-15 08:24:54 -07:00
wangyu-
ed354347fd Update README.md 2017-08-15 08:23:15 -07:00
wangyu-
fb32c56fb2 Update README.zh-cn.md 2017-08-15 08:09:24 -07:00
wangyu
fb5546f83b Merge branch 'master' of https://github.com/wangyu-/udp2raw-tunnel 2017-08-15 15:48:42 +08:00
wangyu
bb67509179 added lower-level option in help page 2017-08-15 15:48:19 +08:00
wangyu-
4bc4d618db Update README.zh-cn.md 2017-08-14 23:04:51 -07:00
wangyu
9f4c452cf6 Merge branch 'master' of https://github.com/wangyu-/udp2raw-tunnel 2017-08-15 13:04:55 +08:00
wangyu
455dcc1e84 trival 2017-08-15 13:04:21 +08:00
wangyu
cee22ec3dc zero out every sockaddr 2017-08-15 13:03:22 +08:00
wangyu-
0612b73e7e Update README.md 2017-08-14 05:32:54 -07:00
wangyu-
84697a35c9 Update README.md 2017-08-14 05:29:52 -07:00
wangyu-
78bf036e04 Update README.zh-cn.md 2017-08-14 05:24:00 -07:00
wangyu-
3ee73b048e Update README.md 2017-08-14 04:03:57 -07:00
wangyu-
8220cf30fb Update README.zh-cn.md 2017-08-14 03:50:34 -07:00
wangyu-
a061af0b89 Update README.zh-cn.md 2017-08-14 03:44:56 -07:00
wangyu-
746cda08d2 Update README.md 2017-08-14 03:28:31 -07:00
wangyu-
06f5541b2a Update README.zh-cn.md 2017-08-14 03:11:25 -07:00
wangyu-
97b73b06c9 Update README.zh-cn.md 2017-08-14 03:09:36 -07:00
wangyu-
f7319680d9 Update README.zh-cn.md 2017-08-14 03:07:43 -07:00
wangyu-
6dd52326b4 Update README.zh-cn.md 2017-08-14 03:04:16 -07:00
wangyu-
1ebef723bf Update README.zh-cn.md 2017-08-14 02:29:09 -07:00
wangyu-
744bf2dece Update README.zh-cn.md 2017-08-14 00:56:20 -07:00
wangyu-
7538204bd1 Update README.zh-cn.md 2017-08-14 00:54:44 -07:00
wangyu-
ae6dd0b196 Update README.md 2017-08-13 20:32:11 -07:00
wangyu-
fc515c770f Update README.md 2017-08-13 20:31:24 -07:00
wangyu-
491c322148 Update README.md 2017-08-13 07:31:25 -07:00
wangyu
80f1070546 Merge branch 'master' of https://github.com/wangyu-/udp2raw-tunnel 2017-08-13 21:28:05 +08:00
wangyu
5a4e3302e2 added comment about security of zero iv + nonce first data block 2017-08-13 21:27:53 +08:00
wangyu-
e76ad81a04 Update README.zh-cn.md 2017-08-13 05:57:20 -07:00
wangyu
7ac0d3561d improve makefile 2017-08-13 10:30:14 +08:00
wangyu
32166d65ae bug fix 2017-08-13 08:18:23 +08:00
16 changed files with 372 additions and 144 deletions

View File

@@ -1,9 +1,15 @@
# Udp2raw-tunnel
![image0](images/image0.PNG)
An Encrpyted,Anti-Replay,Multiplexed UDP Tunnel which can help you Bypass UDP Block or QoS by tunneling UDP traffic through Fake-TCP or ICMP by using raw socket.It aslo acts as a Connection Stablizer.
A UDP Tunnel which tunnels UDP via FakeTCP/UDP/ICMP Traffic by using Raw Socket,helps you Bypass UDP FireWalls(or Unstable UDP Environment).Its Encrpyted,Anti-Replay and Multiplexed.It aslo acts as a Connection Stablizer.
[简体中文](/doc/README.zh-cn.md)
# Support Platforms
A Linux host (including desktop Linux,Android phone/tablet,OpenWRT router,or Raspberry PI) with root access.
For Winodws/MacOS,virtual image with udp2raw pre-installed has been released,you can load it with Vmware/VirtualBox.The virtual image has been set to auto obtain ip,udp2raw can be run imidiately after boot finished(make sure network mode of virtual machine has been set to bridged)(only udp2raw has to be run under virtual machine,all other programs runs under Windows/MacOS as usual).
# Features
### Send / Receive UDP Packet with fake-tcp/icmp headers
Fake-tcp/icmp headers help you bypass UDP blocking, UDP QOS or improper UDP NAT behavior on some ISPs. Raw packets with UDP headers are also supported.In UDP header mode,it behaves just like a normal UDP tunnel,and you can just make use of the other features.
@@ -11,11 +17,11 @@ Fake-tcp/icmp headers help you bypass UDP blocking, UDP QOS or improper UDP NAT
### Simulate TCP Handshake
Simulates the 3-way handshake, along with seq and ack_seq. TCP options MSS, sackOk, TS, TS_ack, wscale are also simulated. Real-time delivery guaranteed, no TCP over TCP problem when using OpenVPN.
### Encrpytion, Anti-Replay, Anti-MITM
### Encrpytion, Anti-Replay, No MITM
* Encrypt your traffic with AES-128-CBC.
* Protect data integrity by MD5 or CRC32.
* Defense replay attack with an anti-replay window, smiliar to IPSec and OpenVPN.
* Authenticate mutually, no more MITM attacks.
* Authenticate mutually, no MITM attacks.
### Failure Dectection & Stablization (Connection Recovery)
Conection failures are detected by heartbeats. If timed-out,client will automatically change port number and reconnect. If reconnection is successful, the previous connection will be recovered, and all existing UDP conversations will stay vaild.
@@ -34,21 +40,9 @@ For example, if you use UDP2RAW + OpenVPN, OpenVPN won't lose connection after a
* **OpenWRT Support** No dependencies, easy to build. Binary for ar71xx are included in release.
### Keywords
* UDP QoS Bypass
* UDP Blocking Bypass
* OpenVPN TCP over TCP problem
* OpenVPN over ICMP
* UDP to ICMP tunnel
* UDP to TCP tunnel
* UDP over ICMP
* UDP over TCP
`UDP QoS Bypass` `UDP Blocking Bypass` `OpenVPN TCP over TCP problem` `OpenVPN over ICMP` `UDP to ICMP tunnel` `UDP to TCP tunnel` `UDP over ICMP` `UDP over TCP`
# Getting Started
### Prerequisites
A Linux host (including desktop Linux, OpenWRT router, or Raspberry PI) with root access.
If you want to use it on MICRO$OFT Windows, you can use VMware or Hyper-V (both bridged mode and <del>NAT mode</del> are supported).
### Installing
Download binary release from https://github.com/wangyu-/udp2raw-tunnel/releases
@@ -56,15 +50,22 @@ Download binary release from https://github.com/wangyu-/udp2raw-tunnel/releases
Assume your UDP is blocked or being QOS-ed or just poorly supported. Assume your server ip is 44.55.66.77, you have a service listening on udp port 7777.
```bash
# Run at client side
./udp2raw_amd64 -c -l0.0.0.0:3333 -r44.55.66.77:4096 -a -k "passwd" --raw-mode faketcp
# Run at server side:
./udp2raw_amd64 -s -l0.0.0.0:4096 -r 127.0.0.1:7777 -a -k "passwd" --raw-mode faketcp
# Run at client side
./udp2raw_amd64 -c -l0.0.0.0:3333 -r44.55.66.77:4096 -a -k "passwd" --raw-mode faketcp
```
###### Server Output:
![](images/output_server.PNG)
###### Client Output:
![](images/output_client.PNG)
Now,an encrypted raw tunnel has been established between client and server through TCP port 4096. Connecting to UDP port 3333 at the client side is equivalent to connecting to port 7777 at the server side. No UDP traffic will be exposed.
### Note
to run on Android, see [Android_Guide](/doc/android_guide.md)
# Advanced Topic
### Usage
```
@@ -185,3 +186,12 @@ https://github.com/ccsexyz/kcpraw
Transparently tunnel your IP traffic through ICMP echo and reply packets.
https://github.com/DhavalKapil/icmptunnel
### Tcp Minion
Tcp Minion is a project which modifid the code of tcp stack in kernel,and implemented real-time out-order udp packet delivery through this modified tcp stack.I failed to find the implementation,but there are some papers avaliable:
https://arxiv.org/abs/1103.0463
http://korz.cs.yale.edu/2009/tng/papers/pfldnet10.pdf
https://pdfs.semanticscholar.org/9e6f/e2306f4385b4eb5416d1fcab16e9361d6ba3.pdf

View File

@@ -55,13 +55,15 @@ int add_iptables_rule(char * s)
strcpy(iptables_rule,s);
char buf[300]="iptables -I ";
strcat(buf,s);
if(system(buf)==0)
char *output;
if(run_command(buf,output)==0)
{
mylog(log_warn,"auto added iptables rule by: %s\n",buf);
}
else
{
mylog(log_fatal,"auto added iptables failed by: %s\n",buf);
//mylog(log_fatal,"reason : %s\n",strerror(errno));
myexit(-1);
}
return 0;
@@ -73,13 +75,15 @@ int clear_iptables_rule()
{
char buf[300]="iptables -D ";
strcat(buf,iptables_rule);
if(system(buf)==0)
char *output;
if(run_command(buf,output)==0)
{
mylog(log_warn,"iptables rule cleared by: %s \n",buf);
}
else
{
mylog(log_error,"clear iptables failed by: %s\n",buf);
//mylog(log_error,"reason : %s\n",strerror(errno));
}
}
@@ -135,7 +139,7 @@ u64_t ntoh64(u64_t a)
{
if(__BYTE_ORDER == __LITTLE_ENDIAN)
{
return __bswap_64( a);
return bswap_64( a);
}
else return a;
@@ -144,7 +148,7 @@ u64_t hton64(u64_t a)
{
if(__BYTE_ORDER == __LITTLE_ENDIAN)
{
return __bswap_64( a);
return bswap_64( a);
}
else return a;
@@ -310,3 +314,101 @@ bool larger_than_u16(uint16_t a,uint16_t b)
}
}
}
vector<string> string_to_vec(const char * s,const char * sp) {
vector<string> res;
string str=s;
char *p = strtok ((char *)str.c_str(),sp);
while (p != NULL)
{
res.push_back(p);
//printf ("%s\n",p);
p = strtok (NULL, sp);
}
return res;
}
vector< vector <string> > string_to_vec2(const char * s)
{
vector< vector <string> > res;
vector<string> lines=string_to_vec(s,"\n");
for(int i=0;i<int(lines.size());i++)
{
vector<string> tmp;
tmp=string_to_vec(lines[i].c_str(),"\t ");
res.push_back(tmp);
}
return res;
}
int read_file(const char * file,char * &output)
{
static char buf[1024*1024+100];
buf[sizeof(buf)-1]=0;
int fd=open(file,O_RDONLY);
if(fd==-1)
{
mylog(log_error,"read_file %s fail\n",file);
return -1;
}
int len=read(fd,buf,1024*1024);
if(len==1024*1024)
{
buf[0]=0;
mylog(log_error,"too long,buf not larger enough\n");
return -2;
}
else if(len<0)
{
buf[0]=0;
mylog(log_error,"read fail %d\n");
return -3;
}
else
{
output=buf;
buf[len]=0;
}
return 0;
}
int run_command(const char * command,char * &output) {
FILE *in;
mylog(log_debug,"run_command %s\n",command);
static char buf[1024*1024+100];
buf[sizeof(buf)-1]=0;
if(!(in = popen(command, "r"))){
mylog(log_error,"command %s popen failed,errno %s\n",command,strerror(errno));
return -1;
}
int len =fread(buf, 1024*1024, 1, in);
if(len==1024*1024)
{
buf[0]=0;
mylog(log_error,"too long,buf not larger enough\n");
return -2;
}
else
{
buf[len]=0;
}
int ret;
if(( ret=ferror(in) ))
{
mylog(log_error,"command %s fread failed,ferror return value %d \n",command,ret);
return -2;
}
//if(output!=0)
output=buf;
ret= pclose(in);
int ret2=WEXITSTATUS(ret);
if(ret!=0||ret2!=0)
{
mylog(log_error,"commnad %s ,pclose returned %d ,WEXITSTATUS %d,errnor :%s \n",command,ret,ret2,strerror(errno));
return -3;
}
return 0;
}

View File

@@ -43,11 +43,12 @@
#include <stdarg.h>
#include <assert.h>
#include <linux/if_packet.h>
#include <byteswap.h>
#include<unordered_map>
#include<vector>
#include<string>
using namespace std;
@@ -144,4 +145,10 @@ int add_iptables_rule(char *);
int clear_iptables_rule();
int run_command(const char * command,char * &output);
int read_file(const char * file,char * &output);
vector<string> string_to_vec(const char * s,const char * sp);
vector< vector <string> > string_to_vec2(const char * s);
#endif /* COMMON_H_ */

View File

@@ -1,6 +1,10 @@
Udp2raw-tunnel
![image2](/images/image2.PNG)
加密、防重放攻击的、信道复用的udp tunnel利用raw socket中转udp流量.同时有心跳保活,且在断线重连后保持上层连接不掉线的功能
udp2raw tunnel通过raw socket给UDP包加上TCP或ICMP header进而绕过UDP屏蔽或QoS或在UDP不稳定的环境下提升稳定性。可以有效防止在使用kcptun或者finalspeed的情况下udp端口被运营商限速
支持心跳保活、自动重连,重连后会恢复上次连接,在底层掉线的情况下可以保持上层不掉线。同时有加密、防重放攻击、信道复用的功能。
**欢迎任何形式的转载**
[English](/README.md)
@@ -11,6 +15,12 @@ Udp2raw-tunnel
如果你需要加速跨国网游、网页浏览解决方案在另一个repo
https://github.com/wangyu-/UDPspeeder
# 支持的平台
Linux主机有root权限。可以是PC、android手机/平板、openwrt路由器、树莓派。主机上最好安装了iptables命令(apt/yum很容易安装)。
在windows和mac上预装了udp2raw的虚拟机镜像已发布可以用Vmware或VirtualBox加载容量4.4mb已经配置好了自动获取网卡ip开机即用稳定性能很好。
udp2raw跑在虚拟机里其他应用照常跑在windows上确保虚拟机网卡工作在桥接模式Vmware player 75mb,VirtualBox 118mb,很容易安装)。
# 功能特性
### 把udp流量伪装成tcp /icmp
用raw socket给udp包加上tcp/icmp包头可以突破udp流量限制或Udp QOS。或者在udp nat有问题的环境下提升稳定性。  另外也支持用raw 发udp包这样流量不会被伪装只会被加密。
@@ -26,7 +36,7 @@ Client能用单倍的超时时间检测到单向链路的失效不管是上
对于有大量client的情况对于不同client,server发送的心跳是错开时间发送的不会因为短时间发送大量的心跳而造成拥塞和延迟抖动。
### 加密 防重放攻击 防中间人攻击
用aes128cbc加密md5/crc32做数据完整校验。用类似ipsec/openvpn的 replay windows机制来防止重放攻击。
用aes128cbc加密md5/crc32做数据完整校验。用类似ipsec/openvpn的 replay window机制来防止重放攻击。
设计目标是即使攻击者可以监听到tunnel的所有包可以选择性丢弃tunnel的任意包可以重放任意包攻击者也没办法获得tunnel承载的任何数据也没办法向tunnel的数据流中通过包构造/包重放插入任何数据。client和server互相认证对方无法被中间人攻击。
@@ -48,9 +58,6 @@ epoll纯异步高并发除了回收过期连接外所有操作的时间
# 简明操作说明
### 环境要求
Linux主机有root权限。主机上最好安装了iptables命令(apt/yum很容易安装)。在windows和mac上可以开虚拟机桥接模式和<del>NAT模式</del>经测试都可用)。
### 安装
下载编译好的二进制文件,解压到任意目录。
@@ -60,16 +67,22 @@ https://github.com/wangyu-/udp2raw-tunnel/releases
假设你有一个serverip为44.55.66.77有一个服务监听在udp 7777端口。 假设你本地的主机到44.55.66.77的UDP流量被屏蔽了或者被qos了
```
在client端运行:
./udp2raw_amd64 -c -l0.0.0.0:3333 -r44.55.66.77:4096 -a -k "passwd" --raw-mode faketcp
在server端运行:
./udp2raw_amd64 -s -l0.0.0.0:4096 -r 127.0.0.1:7777 -a -k "passwd" --raw-mode faketcp
在client端运行:
./udp2raw_amd64 -c -l0.0.0.0:3333 -r44.55.66.77:4096 -a -k "passwd" --raw-mode faketcp
```
###### Server端输出:
![](/images/output_server.PNG)
###### Client端输出:
![](/images/output_client.PNG)
现在client和server之间建立起了tunnel。想要在本地连接44.55.66.77:7777只需要连接 127.0.0.1:3333。来回的所有的udp流量会被经过tunneling发送。在外界看起来是tcp流量不会有udp流量暴露到公网。
### 提醒
如果要在anroid上运行请看[Android简明教程](/doc/android_guide.md)
# 进阶操作说明
### 命令选项

29
doc/android_guide.md Normal file
View File

@@ -0,0 +1,29 @@
# How to run udp2raw on a rooted android device(arm cpu)
There is currently no GUI for udp2raw on android.Make sure you have installed Terminal to run it.
Download udp2raw_arm from https://github.com/wangyu-/udp2raw-tunnel/releases.
Copy udp2raw_arm to any dir of your **internal storage** .Copying it to **SD card wont work**.
# Steps
1. run udp2raw_arm as usual, except you must change the -a option to -g
```
./udp2raw_arm -c -r 44.55.66.77:9966 -l 0.0.0.0:4000 -k1234 --cipher xor -g
```
2. find the generated iptables rule from udp2raw's output,add it manually by running:
```
iptables -I INPUT -s 44.55.66.77/32 -p tcp -m tcp --sport 9966 -j DROP
```
3. run udp2raw_ram without -g command
```
./udp2raw_arm -c -r 44.55.66.77:9966 -l 0.0.0.0:4000 -k1234 --cipher xor
```
# ScreenShot
zoom-in if not large enough
![](/images/android.png)

View File

@@ -8,7 +8,7 @@
##### 摘要
udp2raw是一个把udp流量通过raw socket包装成tcp流量的工具。通过用udp2raw配合udp模式的 finalspeed一样可以达到在底层发tcp包绕过QOS的效果。支持openvz,稳定性也好很多。原理上相当于在finalspeed外面再包了一层tunnel。
本教程会一步一步演示用udp2raw+kcptun加速http流量的过程。加速任何其他tcp流量也一样。
本教程会一步一步演示用udp2raw+finalspeed加速http流量的过程。加速任何其他tcp流量也一样包括ss。本文避免讨论科学上网所以只演示加速http流量
udp2raw也支持把udp流量包装成Icmp发送本教程不做演示。
@@ -17,12 +17,14 @@ udp2raw也支持把udp流量包装成Icmp发送本教程不做演示。
本地主机是windows,本地有openwrt路由器或树莓派或安装了linux虚拟机网卡设置为桥接模式
(如果嫌给虚拟机安装linux麻烦可以下载别人提供好的linux虚拟机镜像比如https://www.kali.org/downloads/ ,不过我没有测试过这个镜像,我用的是debian 7)
(如果嫌给虚拟机安装linux麻烦可以用release里发布的预装了udp2raw的openwrt_x86虚拟机镜像容量4.4mb)
下面的教程按虚拟机演示如果你有openwrt路由器或树莓派可以直接运行再路由器或树莓派上就不需要虚拟机了。
### 安装
下载好udp2raw的压缩包解压分别解压到服务器和本地的虚拟机。
https://github.com/xtaci/kcptun/releases
https://github.com/wangyu-/udp2raw-tunnel/releases
在服务器端安装好finalspeed服务端在本地windows安装好finalspeed的客户端。服务端我以前是用91yun的一键安装脚本安装的没装过的可以去网上搜一键安装脚本。
@@ -52,7 +54,7 @@ netstat -nlp|grep java
记下红框中的ip,这是虚拟机的网卡ip
在server端也会显示server_reay
在server端也会显示server_ready
![image](finalspeed_step_by_step/Capture4.PNG)
4.在本地windows,按图配置好finalspeed的客户端。注意192.168.205.8改成你刚才记下来的IP带宽也要按实际的填。传输协议要选UDP.

View File

@@ -4,7 +4,9 @@
本教程会一步一步演示用udp2raw+kcptun加速SSH流量的过程。加速任何其他tcp流量也一样包括ss本文避免涉及科学上网所以演示ssh。
### 环境要求
两边的主机都是linux有root权限。 可以是openwrt路由器或树莓派windows上桥接模式的虚拟机也可用
两边的主机都是linux有root权限。 可以是openwrt路由器或树莓派也可以是root了的android。
(windows和mac可以用release里发布的预装了udp2raw的openwrt_x86虚拟机镜像容量4.4mb,开机即用)
### 安装

View File

@@ -11,12 +11,15 @@
//static uint64_t seq=1;
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?
* 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"}};
auth_mode_t auth_mode=auth_crc32;
auth_mode_t auth_mode=auth_md5;
cipher_mode_t cipher_mode=cipher_aes128cbc;
@@ -213,7 +216,7 @@ int auth_crc32_verify(const char *data,int &len)
{
if(len<int(sizeof(unsigned int)))
{
mylog(log_debug,"auth_crc32_verify len<16\n");
mylog(log_debug,"auth_crc32_verify len<%d\n",int(sizeof(unsigned int)));
return -1;
}
unsigned int ret=crc32h((unsigned char *)data,len-sizeof(unsigned int));

BIN
images/android.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 366 KiB

BIN
images/output_client.PNG Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

BIN
images/output_server.PNG Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

BIN
images/speed_test.PNG Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

175
main.cpp
View File

@@ -3,8 +3,10 @@
#include "log.h"
#include "lib/md5.h"
char local_address[100]="0.0.0.0", remote_address[100]="255.255.255.255",source_address[100]="0.0.0.0";
u32_t local_address_uint32,remote_address_uint32,source_address_uint32;
char local_ip[100]="0.0.0.0", remote_ip[100]="255.255.255.255",source_ip[100]="0.0.0.0";
u32_t local_ip_uint32,remote_ip_uint32,source_ip_uint32;
int force_source_ip=0;
int source_port=0,local_port = -1, remote_port = -1;
id_t const_id=0;
@@ -234,6 +236,8 @@ struct conv_manager_t //TODO change map to unordered map
int size=conv_last_active_time.size();
int num_to_clean=size/conv_clear_ratio+conv_clear_min; //clear 1/10 each time,to avoid latency glitch
num_to_clean=min(num_to_clean,size);
u64_t current_time=get_current_time();
for(;;)
{
@@ -860,12 +864,12 @@ int try_to_list_and_bind(int port)
close(old_bind_fd);
}
struct sockaddr_in temp_bind_addr;
bzero(&temp_bind_addr, sizeof(temp_bind_addr));
struct sockaddr_in temp_bind_addr={0};
//bzero(&temp_bind_addr, sizeof(temp_bind_addr));
temp_bind_addr.sin_family = AF_INET;
temp_bind_addr.sin_port = htons(port);
temp_bind_addr.sin_addr.s_addr = local_address_uint32;
temp_bind_addr.sin_addr.s_addr = local_ip_uint32;
if (bind(bind_fd, (struct sockaddr*)&temp_bind_addr, sizeof(temp_bind_addr)) !=0)
{
@@ -959,8 +963,7 @@ int set_timer_server(int epollfd,int &timer_fd)
}
return 0;
}
int get_src_adress(u32_t &ip);
int client_on_timer(conn_info_t &conn_info) //for client
{
packet_info_t &send_info=conn_info.raw_info.send_info;
@@ -985,6 +988,18 @@ int client_on_timer(conn_info_t &conn_info) //for client
conn_info.blob->anti_replay.re_init();
conn_info.my_id = get_true_random_number_nz(); ///todo no need to do this everytime
u32_t new_ip=0;
if(!force_source_ip&&get_src_adress(new_ip)==0)
{
if(new_ip!=source_ip_uint32)
{
mylog(log_info,"source ip changed from %s to",my_ntoa(source_ip_uint32));
log_bare(log_info,"%s\n",my_ntoa(new_ip));
source_ip_uint32=new_ip;
send_info.src_ip=new_ip;
}
}
if (source_port == 0)
{
send_info.src_port = client_bind_to_a_new_port();
@@ -1375,7 +1390,7 @@ int client_on_raw_recv(conn_info_t &conn_info)
u64_t u64=conn_info.blob->conv_manager.find_u64_by_conv(tmp_conv_id);
sockaddr_in tmp_sockaddr;
sockaddr_in tmp_sockaddr={0};
tmp_sockaddr.sin_family = AF_INET;
tmp_sockaddr.sin_addr.s_addr=(u64>>32u);
@@ -1417,10 +1432,13 @@ int server_on_raw_recv_multi()
{
recv(raw_recv_fd, 0,0, 0 );//
//struct sockaddr saddr;
//socklen_t saddr_size;
//socklen_t saddr_size=sizeof(saddr);
///recvfrom(raw_recv_fd, 0,0, 0 ,&saddr , &saddr_size);//
mylog(log_trace,"peek_raw failed\n");
return -1;
}else
{
mylog(log_trace,"peek_raw success\n");
}
u32_t ip=peek_info.src_ip;uint16_t port=peek_info.src_port;
@@ -1544,9 +1562,11 @@ int server_on_raw_recv_multi()
if(conn_info.state.server_current_state==server_ready)
{
char type;
//mylog(log_info,"before recv_safer\n");
if (recv_safer(conn_info,type, data, data_len) != 0) {
return -1;
}
//mylog(log_info,"after recv_safer\n");
return server_on_raw_recv_ready(conn_info,ip_port,type,data,data_len);
}
return 0;
@@ -1663,13 +1683,13 @@ int server_on_raw_recv_ready(conn_info_t &conn_info,char * ip_port,char type,cha
tmp_conv_id);
return 0;
}
struct sockaddr_in remote_addr_in;
struct sockaddr_in remote_addr_in={0};
socklen_t slen = sizeof(sockaddr_in);
memset(&remote_addr_in, 0, sizeof(remote_addr_in));
//memset(&remote_addr_in, 0, sizeof(remote_addr_in));
remote_addr_in.sin_family = AF_INET;
remote_addr_in.sin_port = htons(remote_port);
remote_addr_in.sin_addr.s_addr = remote_address_uint32;
remote_addr_in.sin_addr.s_addr = remote_ip_uint32;
int new_udp_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (new_udp_fd < 0) {
@@ -1857,13 +1877,13 @@ int server_on_raw_recv_pre_ready(conn_info_t &conn_info,char * ip_port,u32_t tmp
int get_src_adress(u32_t &ip)
{
struct sockaddr_in remote_addr_in;
struct sockaddr_in remote_addr_in={0};
socklen_t slen = sizeof(sockaddr_in);
memset(&remote_addr_in, 0, sizeof(remote_addr_in));
//memset(&remote_addr_in, 0, sizeof(remote_addr_in));
remote_addr_in.sin_family = AF_INET;
remote_addr_in.sin_port = htons(remote_port);
remote_addr_in.sin_addr.s_addr = remote_address_uint32;
remote_addr_in.sin_addr.s_addr = remote_ip_uint32;
int new_udp_fd=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
@@ -1872,7 +1892,7 @@ int get_src_adress(u32_t &ip)
mylog(log_warn,"create udp_fd error\n");
return -1;
}
set_buf_size(new_udp_fd);
//set_buf_size(new_udp_fd);
mylog(log_debug,"created new udp_fd %d\n",new_udp_fd);
int ret = connect(new_udp_fd, (struct sockaddr *) &remote_addr_in, slen);
@@ -1883,8 +1903,8 @@ int get_src_adress(u32_t &ip)
return -1;
}
struct sockaddr_in my_addr;
unsigned int len=sizeof(my_addr);
struct sockaddr_in my_addr={0};
socklen_t len=sizeof(my_addr);
if(getsockname(new_udp_fd, (struct sockaddr *) &my_addr, &len)!=0) return -1;
@@ -1894,6 +1914,7 @@ int get_src_adress(u32_t &ip)
return 0;
}
int client_event_loop()
{
char buf[buf_len];
@@ -1906,17 +1927,17 @@ int client_event_loop()
packet_info_t &recv_info=conn_info.raw_info.recv_info;
//printf("?????\n");
if(source_address_uint32==0)
if(source_ip_uint32==0)
{
mylog(log_info,"get_src_adress called\n");
if(get_src_adress(source_address_uint32)!=0)
if(get_src_adress(source_ip_uint32)!=0)
{
mylog(log_fatal,"the trick to auto get source ip failed,you should specific an ip by --source-ip\n");
myexit(-1);
}
}
in_addr tmp;
tmp.s_addr=source_address_uint32;
tmp.s_addr=source_ip_uint32;
mylog(log_info,"source ip = %s\n",inet_ntoa(tmp));
//printf("done\n");
@@ -1927,13 +1948,13 @@ int client_event_loop()
myexit(-1);
}
send_info.src_port=source_port;
send_info.src_ip = source_address_uint32;
send_info.src_ip = source_ip_uint32;
int i, j, k;int ret;
init_raw_socket();
//init_filter(source_port);
send_info.dst_ip=remote_address_uint32;
send_info.dst_ip=remote_ip_uint32;
send_info.dst_port=remote_port;
//g_packet_info.src_ip=source_address_uint32;
@@ -1945,13 +1966,13 @@ int client_event_loop()
int yes = 1;
//setsockopt(udp_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes));
struct sockaddr_in local_me;
struct sockaddr_in local_me={0};
socklen_t slen = sizeof(sockaddr_in);
memset(&local_me, 0, sizeof(local_me));
//memset(&local_me, 0, sizeof(local_me));
local_me.sin_family = AF_INET;
local_me.sin_port = htons(local_port);
local_me.sin_addr.s_addr = local_address_uint32;
local_me.sin_addr.s_addr = local_ip_uint32;
if (bind(udp_fd, (struct sockaddr*) &local_me, slen) == -1) {
@@ -2033,9 +2054,10 @@ int client_event_loop()
{
int recv_len;
struct sockaddr_in udp_new_addr_in;
struct sockaddr_in udp_new_addr_in={0};
socklen_t udp_new_addr_len = sizeof(sockaddr_in);
if ((recv_len = recvfrom(udp_fd, buf, max_data_len, 0,
(struct sockaddr *) &udp_new_addr_in, &slen)) == -1) {
(struct sockaddr *) &udp_new_addr_in, &udp_new_addr_len)) == -1) {
mylog(log_error,"recv_from error,this shouldnt happen at client\n");
myexit(1);
};
@@ -2119,7 +2141,7 @@ int server_event_loop()
int i, j, k;int ret;
bind_address_uint32=local_address_uint32;//only server has bind adress,client sets it to zero
bind_address_uint32=local_ip_uint32;//only server has bind adress,client sets it to zero
if(raw_mode==mode_faketcp)
@@ -2131,12 +2153,12 @@ int server_event_loop()
bind_fd=socket(AF_INET,SOCK_DGRAM,0);
}
struct sockaddr_in temp_bind_addr;
bzero(&temp_bind_addr, sizeof(temp_bind_addr));
struct sockaddr_in temp_bind_addr={0};
// bzero(&temp_bind_addr, sizeof(temp_bind_addr));
temp_bind_addr.sin_family = AF_INET;
temp_bind_addr.sin_port = htons(local_port);
temp_bind_addr.sin_addr.s_addr = local_address_uint32;
temp_bind_addr.sin_addr.s_addr = local_ip_uint32;
if (bind(bind_fd, (struct sockaddr*)&temp_bind_addr, sizeof(temp_bind_addr)) !=0)
{
@@ -2313,7 +2335,8 @@ int server_event_loop()
if(recv_len<0)
{
mylog(log_debug,"udp fd,recv_len<0 continue\n");
mylog(log_debug,"udp fd,recv_len<0 continue,%s\n",strerror(errno));
continue;
}
@@ -2347,7 +2370,26 @@ int server_event_loop()
}
return 0;
}
void process_lower_level()
{
if (strchr(optarg, '#') == 0) {
mylog(log_fatal,
"lower-level parameter invaild,check help page for format\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: if_name=<%s> dest_mac_adress=<%02x:%02x:%02x:%02x:%02x:%02x> \n",
if_name, 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]);
}
}
void print_help()
{
printf("udp2raw-tunnel\n");
@@ -2361,8 +2403,8 @@ void print_help()
printf("common options,these options must be same on both side:\n");
printf(" --raw-mode <string> avaliable values:faketcp(default),udp,icmp\n");
printf(" -k,--key <string> password to gen symetric key,default:\"secret key\"\n");
printf(" --auth-mode <string> avaliable values:aes128cbc(default),xor,none\n");
printf(" --cipher-mode <string> avaliable values:md5(default),crc32,simple,none\n");
printf(" --cipher-mode <string> avaliable values:aes128cbc(default),xor,none\n");
printf(" --auth-mode <string> avaliable values:md5(default),crc32,simple,none\n");
printf(" -a,--auto-rule auto add (and delete) iptables rule\n");
printf(" -g,--gen-rule generate iptables rule then exit\n");
printf(" --disable-anti-replay disable anti-replay,not suggested\n");
@@ -2388,6 +2430,8 @@ void print_help()
printf(" 1:increase every packet\n");
printf(" 2:increase randomly, about every 3 packets (default)\n");
// printf("\n");
printf(" --lower-level <string> send packet at OSI level 2, format:'if_name#dest_mac_adress'\n");
printf(" ie:'eth0#00:23:45:67:89:b9'.Beta.\n");
printf(" -h,--help print this help message\n");
//printf("common options,these options must be same on both side\n");
@@ -2472,7 +2516,7 @@ void process_arg(int argc, char *argv[])
case 'l':
no_l = 0;
if (strchr(optarg, ':') != 0) {
sscanf(optarg, "%[^:]:%d", local_address, &local_port);
sscanf(optarg, "%[^:]:%d", local_ip, &local_port);
if(local_port==22)
{
mylog(log_fatal,"port 22 not allowed\n");
@@ -2487,7 +2531,7 @@ void process_arg(int argc, char *argv[])
case 'r':
no_r = 0;
if (strchr(optarg, ':') != 0) {
sscanf(optarg, "%[^:]:%d", remote_address, &remote_port);
sscanf(optarg, "%[^:]:%d", remote_ip, &remote_port);
if(remote_port==22)
{
mylog(log_fatal,"port 22 not allowed\n");
@@ -2536,7 +2580,10 @@ void process_arg(int argc, char *argv[])
mylog(log_debug,"option_index: %d\n",option_index);
if(strcmp(long_options[option_index].name,"clear")==0)
{
int ret =system("iptables-save |grep udp2raw_dWRwMnJhdw|sed -n 's/^-A/iptables -D/p'|sh");
char *output;
//int ret =system("iptables-save |grep udp2raw_dWRwMnJhdw|sed -n 's/^-A/iptables -D/p'|sh");
int ret =run_command("iptables -S|sed -n '/udp2raw_dWRwMnJhdw/p'|sed -n 's/^-A/iptables -D/p'|sh",output);
//system("iptables-save |grep udp2raw_dWRwMnJhdw|sed 's/^-A/iptables -D/'|sh");
//system("iptables-save|grep -v udp2raw_dWRwMnJhdw|iptables-restore");
mylog(log_info,"tried to clear all iptables rule created previously,return value %d\n",ret);
@@ -2545,8 +2592,9 @@ void process_arg(int argc, char *argv[])
else if(strcmp(long_options[option_index].name,"source-ip")==0)
{
mylog(log_debug,"parsing long option :source-ip\n");
sscanf(optarg, "%s", source_address);
mylog(log_debug,"source: %s\n",source_address);
sscanf(optarg, "%s", source_ip);
mylog(log_debug,"source: %s\n",source_ip);
force_source_ip=1;
}
else if(strcmp(long_options[option_index].name,"source-port")==0)
{
@@ -2600,7 +2648,7 @@ void process_arg(int argc, char *argv[])
}
if(i==cipher_end)
{
mylog(log_fatal,"no such cipher_mode %s\n",optarg);
myexit(-1);
}
}
@@ -2609,21 +2657,7 @@ void process_arg(int argc, char *argv[])
}
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]);
}
process_lower_level();
}
else if(strcmp(long_options[option_index].name,"disable-color")==0)
{
@@ -2709,11 +2743,11 @@ void process_arg(int argc, char *argv[])
log_bare(log_info,"key=%s ",key_string);
log_bare(log_info,"local_ip=%s ",local_address);
log_bare(log_info,"local_ip=%s ",local_ip);
log_bare(log_info,"local_port=%d ",local_port);
log_bare(log_info,"remote_ip=%s ",remote_address);
log_bare(log_info,"remote_ip=%s ",remote_ip);
log_bare(log_info,"remote_port=%d ",remote_port);
log_bare(log_info,"source_ip=%s ",source_address);
log_bare(log_info,"source_ip=%s ",source_ip);
log_bare(log_info,"source_port=%d ",source_port);
log_bare(log_info,"socket_buf_size=%d ",socket_buf_size);
@@ -2727,17 +2761,17 @@ void iptables_rule()
{
if(raw_mode==mode_faketcp)
{
sprintf(rule,"INPUT -s %s/32 -p tcp -m tcp --sport %d -j DROP",remote_address,remote_port);
sprintf(rule,"INPUT -s %s/32 -p tcp -m tcp --sport %d -j DROP",remote_ip,remote_port);
//mylog(log_warn,"make sure you have run once: iptables -A INPUT -s %s/32 -p tcp -m tcp --sport %d -j DROP\n",remote_address,remote_port);
}
if(raw_mode==mode_udp)
{
sprintf(rule,"INPUT -s %s/32 -p udp -m udp --sport %d -j DROP",remote_address,remote_port);
sprintf(rule,"INPUT -s %s/32 -p udp -m udp --sport %d -j DROP",remote_ip,remote_port);
//mylog(log_warn,"make sure you have run once: iptables -A INPUT -s %s/32 -p udp -m udp --sport %d -j DROP\n",remote_address,remote_port);
}
if(raw_mode==mode_icmp)
{
sprintf(rule,"INPUT -s %s/32 -p icmp -j DROP",remote_address);
sprintf(rule,"INPUT -s %s/32 -p icmp -j DROP",remote_ip);
//mylog(log_warn,"make sure you have run once: iptables -A INPUT -s %s/32 -p icmp -j DROP\n",remote_address);
}
}
@@ -2756,14 +2790,14 @@ void iptables_rule()
}
if(raw_mode==mode_icmp)
{
if(local_address_uint32==0)
if(local_ip_uint32==0)
{
sprintf(rule,"INPUT -p icmp -j DROP");
//mylog(log_warn,"make sure you have run once: iptables -A INPUT -p icmp -j DROP\n");
}
else
{
sprintf(rule,"INPUT -d %s/32 -p icmp -j DROP",local_address);
sprintf(rule,"INPUT -d %s/32 -p icmp -j DROP",local_ip);
//mylog(log_warn,"make sure you have run once: iptables -A INPUT -d %s/32 -p icmp -j DROP\n",local_address);
}
}
@@ -2802,6 +2836,8 @@ void iptables_rule()
}
int main(int argc, char *argv[])
{
//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));
//assert(0==1);
dup2(1, 2);//redirect stderr to stdout
@@ -2813,9 +2849,14 @@ int main(int argc, char *argv[])
process_arg(argc,argv);
local_address_uint32=inet_addr(local_address);
remote_address_uint32=inet_addr(remote_address);
source_address_uint32=inet_addr(source_address);
if(geteuid() != 0)
{
mylog(log_error,"root check failed,make sure you run this program with root,we can try to continue,but it will likely fail\n");
}
local_ip_uint32=inet_addr(local_ip);
remote_ip_uint32=inet_addr(remote_ip);
source_ip_uint32=inet_addr(source_ip);
//current_time_rough=get_current_time();

View File

@@ -1,37 +1,47 @@
cc_cross=/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_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++
FLAGS= -std=c++11 -Wall -Wextra -Wno-unused-variable -Wno-unused-parameter
cc_arm=/home/wangyu/Desktop/arm-2014.05/bin/arm-none-linux-gnueabi-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
TAR=udp2raw_binaries.tar.gz udp2raw_amd64 udp2raw_x86 udp2raw_ar71xx udp2raw_bcm2708
NAME=udp2raw
TAR=${NAME}_binaries.tar.gz ${NAME}_amd64 ${NAME}_x86 ${NAME}_ar71xx ${NAME}_bcm2708 ${NAME}_arm
all:
rm -f udp2raw
${cc_local} -o udp2raw -I. ${SOURCES} ${FLAGS} -lrt -static -O3
rm -f ${NAME}
${cc_local} -o ${NAME} -I. ${SOURCES} ${FLAGS} -lrt -static -O3
fast:
rm -f udp2raw
${cc_local} -o udp2raw -I. ${SOURCES} ${FLAGS} -lrt
rm -f ${NAME}
${cc_local} -o ${NAME} -I. ${SOURCES} ${FLAGS} -lrt
debug:
rm -f udp2raw
${cc_local} -o udp2raw -I. ${SOURCES} ${FLAGS} -lrt -Wformat-nonliteral -D MY_DEBUG
rm -f ${NAME}
${cc_local} -o ${NAME} -I. ${SOURCES} ${FLAGS} -lrt -Wformat-nonliteral -D MY_DEBUG
ar71xx:
${cc_ar71xx} -o udp2raw_ar71xx -I. ${SOURCES} ${FLAGS} -lrt -lgcc_eh -static -O3
${cc_ar71xx} -o ${NAME}_ar71xx -I. ${SOURCES} ${FLAGS} -lrt -lgcc_eh -static -O3
bcm2708:
${cc_bcm2708} -o udp2raw_bcm2708 -I. ${SOURCES} ${FLAGS} -lrt -static -O3
${cc_bcm2708} -o ${NAME}_bcm2708 -I. ${SOURCES} ${FLAGS} -lrt -static -O3
amd64:
${cc_local} -o ${NAME}_amd64 -I. ${SOURCES} ${FLAGS} -lrt -static -O3
x86:
${cc_local} -o ${NAME}_x86 -I. ${SOURCES} ${FLAGS} -lrt -static -O3 -m32
arm:
${cc_cross} -o ${NAME}_arm -I. ${SOURCES} ${FLAGS} -lrt -static -O3
cross:
${cc_cross} -o udp2raw_cross -I. ${SOURCES} ${FLAGS} -lrt -static -lgcc_eh -O3
${cc_cross} -o ${NAME}_cross -I. ${SOURCES} ${FLAGS} -lrt -O3
cross2:
${cc_cross} -o udp2raw_cross -I. ${SOURCES} ${FLAGS} -lrt -O3
${cc_cross} -o ${NAME}_cross -I. ${SOURCES} ${FLAGS} -lrt -static -lgcc_eh -O3
release: ar71xx bcm2708
${cc_local} -o udp2raw_amd64 -I. ${SOURCES} ${FLAGS} -lrt -static -O3
${cc_local} -o udp2raw_x86 -I. ${SOURCES} ${FLAGS} -lrt -m32 -static -O3
cross3:
${cc_cross} -o ${NAME}_cross -I. ${SOURCES} ${FLAGS} -lrt -static -O3
release: amd64 x86 ar71xx bcm2708 arm
tar -zcvf ${TAR}
clean:
rm -f ${TAR}
rm -f udp2raw udp2raw_cross

View File

@@ -24,7 +24,9 @@ int lower_level=0;
int ifindex=-1;
char if_name[100]="";
unsigned char oppsite_hw_addr[6]=
unsigned short g_ip_id_counter=0;
unsigned char dest_hw_addr[6]=
{0xff,0xff,0xff,0xff,0xff,0xff};
//{0x00,0x23,0x45,0x67,0x89,0xb9};
@@ -162,6 +164,7 @@ packet_info_t::packet_info_t()
int init_raw_socket()
{
g_ip_id_counter=get_true_random_number()%65535;
if(lower_level==0)
{
raw_send_fd = socket(AF_INET , SOCK_RAW , IPPROTO_TCP);
@@ -306,7 +309,6 @@ int init_ifindex(char * if_name)
return 0;
}
int send_raw_ip(raw_info_t &raw_info,const char * payload,int payloadlen)
{
const packet_info_t &send_info=raw_info.send_info;
@@ -316,19 +318,18 @@ int send_raw_ip(raw_info_t &raw_info,const char * payload,int payloadlen)
struct iphdr *iph = (struct iphdr *) send_raw_ip_buf;
memset(iph,0,sizeof(iphdr));
static unsigned short ip_id=1;
iph->ihl = sizeof(iphdr)/4; //we dont use ip options,so the length is just sizeof(iphdr)
iph->version = 4;
iph->tos = 0;
if(lower_level)
{
iph->id=0;
//iph->id = htons (ip_id++); //Id of this packet
//iph->id=0;
iph->id = htons (g_ip_id_counter++); //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->id = htons (g_ip_id_counter++); //Id of this packet
//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(0x0000); //DF set,others are zero
@@ -353,7 +354,7 @@ int send_raw_ip(raw_info_t &raw_info,const char * payload,int payloadlen)
int ret;
if(lower_level==0)
{
struct sockaddr_in sin;
struct sockaddr_in sin={0};
sin.sin_family = AF_INET;
//sin.sin_port = htons(info.dst_port); //dont need this
sin.sin_addr.s_addr = send_info.dst_ip;
@@ -363,14 +364,14 @@ int send_raw_ip(raw_info_t &raw_info,const char * payload,int payloadlen)
else
{
struct sockaddr_ll addr;
memset(&addr,0,sizeof(addr));
struct sockaddr_ll addr={0};
//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);
memcpy(addr.sll_addr,dest_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)
@@ -389,13 +390,15 @@ int send_raw_ip(raw_info_t &raw_info,const char * payload,int payloadlen)
int peek_raw(packet_info_t &peek_info)
{ static char peek_raw_buf[buf_len];
char *ip_begin=peek_raw_buf+link_level_header_len;
struct sockaddr saddr;
socklen_t saddr_size;
struct sockaddr saddr={0};
socklen_t saddr_size=sizeof(saddr);
int recv_len = recvfrom(raw_recv_fd, peek_raw_buf,max_data_len, MSG_PEEK ,&saddr , &saddr_size);//change max_data_len to something smaller,we only need header here
iphdr * iph = (struct iphdr *) (ip_begin);
//mylog(log_info,"recv_len %d\n",recv_len);
if(recv_len<int(sizeof(iphdr)))
{
mylog(log_trace,"failed here %d %d\n",recv_len,int(sizeof(iphdr)));
mylog(log_trace,"%s\n ",strerror(errno));
return -1;
}
peek_info.src_ip=iph->saddr;
@@ -407,10 +410,17 @@ int peek_raw(packet_info_t &peek_info)
{
case mode_faketcp:
{
if(iph->protocol!=IPPROTO_TCP) return -1;
if(iph->protocol!=IPPROTO_TCP)
{
mylog(log_trace,"failed here");
return -1;
}
struct tcphdr *tcph=(tcphdr *)payload;
if(recv_len<int( iphdrlen+sizeof(tcphdr) ))
{
mylog(log_trace,"failed here");
return -1;
}
peek_info.src_port=ntohs(tcph->source);
peek_info.syn=tcph->syn;
break;
@@ -445,11 +455,9 @@ int recv_raw_ip(raw_info_t &raw_info,char * &payload,int &payloadlen)
static char recv_raw_ip_buf[buf_len];
iphdr * iph;
struct sockaddr saddr;
socklen_t saddr_size;
saddr_size = sizeof(saddr);
struct sockaddr saddr={0};
socklen_t saddr_size = sizeof(saddr);
int flag=0;
int recv_len = recvfrom(raw_recv_fd, recv_raw_ip_buf, max_data_len, flag ,&saddr , &saddr_size);
if(recv_len<0)
@@ -481,6 +489,7 @@ int recv_raw_ip(raw_info_t &raw_info,char * &payload,int &payloadlen)
if(bind_address_uint32!=0 &&recv_info.dst_ip!=bind_address_uint32)
{
mylog(log_trace,"bind adress doenst match, dropped\n");
//printf(" bind adress doenst match, dropped\n");
return -1;
}

View File

@@ -17,7 +17,7 @@ extern int disable_bpf_filter;
extern int lower_level;
extern char if_name[100];
extern unsigned char oppsite_hw_addr[];
extern unsigned char dest_hw_addr[];
struct icmphdr
{