mirror of
https://gitee.com/willfree/min-vpn-client_v2.git
synced 2026-10-04 19:42:00 +08:00
更换目的地址、tcp端口,计算ip包、tcp报文字段中的校验和,并写回tun网卡中。下一步研究tun网卡的流量流向,以及如何、从何读出地址修改后的ip包。
This commit is contained in:
1 parent
9368d21267
commit
de51fdec72
1 file changed
+173
-25
+173
-25
@@ -27,6 +27,7 @@ import java.util.Arrays;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import common.LoggerHelper;
|
import common.LoggerHelper;
|
||||||
|
import jnr.ffi.annotations.In;
|
||||||
import util.ByteHelper;
|
import util.ByteHelper;
|
||||||
|
|
||||||
public class MINVpnLBConnection implements MINVpnConnection {
|
public class MINVpnLBConnection implements MINVpnConnection {
|
||||||
@@ -111,6 +112,7 @@ public class MINVpnLBConnection implements MINVpnConnection {
|
|||||||
builder.setMtu(8000);
|
builder.setMtu(8000);
|
||||||
builder.addAddress(allocatedAddress,24);
|
builder.addAddress(allocatedAddress,24);
|
||||||
builder.addRoute("10.255.0.3",32);
|
builder.addRoute("10.255.0.3",32);
|
||||||
|
builder.addRoute("192.168.0.0",16);
|
||||||
builder.addDnsServer("114.114.114.114");
|
builder.addDnsServer("114.114.114.114");
|
||||||
// 1.2创建一个接口
|
// 1.2创建一个接口
|
||||||
final ParcelFileDescriptor vpnInterface;
|
final ParcelFileDescriptor vpnInterface;
|
||||||
@@ -169,15 +171,67 @@ public class MINVpnLBConnection implements MINVpnConnection {
|
|||||||
}
|
}
|
||||||
int[] ip_address_unsignedInt_first=new int[8];
|
int[] ip_address_unsignedInt_first=new int[8];
|
||||||
if(readLen>0){
|
if(readLen>0){
|
||||||
System.out.println("A new packet,");
|
|
||||||
System.out.println("read from tun , readLen ="+readLen);
|
|
||||||
ip_packet_read_from_tun.position(0);
|
ip_packet_read_from_tun.position(0);
|
||||||
ip_packet_read_from_tun.limit(readLen);
|
ip_packet_read_from_tun.limit(readLen);
|
||||||
|
|
||||||
|
try {
|
||||||
|
//System.out.println("after changing, position is"+ip_NAT_packet.position());
|
||||||
|
System.out.println("直接写入,再读出");
|
||||||
|
//outputStream.write(ip_NAT_packet.array(), 0, ip_NAT_packet.position());
|
||||||
|
outputStream.write(ip_packet_read_from_tun.array(), 0, ip_packet_read_from_tun.position());
|
||||||
|
ByteBuffer temp_buffer = ByteBuffer.allocate(MAX_PACKET_SIZE);
|
||||||
|
int temp_readLen=inputStream.read(temp_buffer.array(), 0, MAX_PACKET_SIZE);
|
||||||
|
System.out.println("temp readLen is "+temp_readLen);
|
||||||
|
byte[] tempData = new byte[temp_readLen];
|
||||||
|
System.arraycopy(temp_buffer.array(), 0, tempData, 0, temp_readLen);
|
||||||
|
printHexString("直接从TUN中读:",tempData);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
System.out.println("将抓转换后的地址写入tun网卡失败");
|
||||||
|
}
|
||||||
|
|
||||||
// String binaryString = Integer.toBinaryString(first);
|
// String binaryString = Integer.toBinaryString(first);
|
||||||
byte[] ipPackageData = new byte[readLen];
|
byte[] ipPackageData = new byte[readLen];
|
||||||
System.arraycopy(ip_packet_read_from_tun.array(), 0, ipPackageData, 0, readLen);
|
System.arraycopy(ip_packet_read_from_tun.array(), 0, ipPackageData, 0, readLen);
|
||||||
System.out.println("ip packet's content is: " + Arrays.toString(ipPackageData));
|
// System.out.println("ip packet's content is: " + Arrays.toString(ipPackageData));
|
||||||
|
|
||||||
|
if(ipPackageData[12]==0 && ipPackageData[13]==0
|
||||||
|
&& ipPackageData[14]==0 && ipPackageData[15]==0){
|
||||||
|
System.out.println("源地址为0.0.0.0,暂时跳过");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("A new packet,");
|
||||||
|
System.out.println("read from tun , readLen ="+readLen);
|
||||||
|
printHexString("ip packet's content is: ",ipPackageData);
|
||||||
|
|
||||||
|
//ip包的各种信息
|
||||||
|
//ip头部长度,tcp报文长度
|
||||||
|
int ip_head_length=(ipPackageData[0] & 0x0F)*4;
|
||||||
|
int tcp_length=readLen-ip_head_length;
|
||||||
|
//源端口、目的端口
|
||||||
|
byte[] source_port=new byte[2];
|
||||||
|
source_port[0]=ipPackageData[ip_head_length];
|
||||||
|
source_port[1]=ipPackageData[ip_head_length+1];
|
||||||
|
byte[] destination_port=new byte[2];
|
||||||
|
destination_port[0]=ipPackageData[ip_head_length+2];
|
||||||
|
destination_port[1]=ipPackageData[ip_head_length+3];
|
||||||
|
|
||||||
|
|
||||||
|
byte[] test_ipPackageData = new byte[readLen];
|
||||||
|
System.arraycopy(ip_packet_read_from_tun.array(), 0, test_ipPackageData, 0, readLen);
|
||||||
|
ByteBuffer test_ip_packet=ByteBuffer.allocate(MAX_PACKET_SIZE);
|
||||||
|
test_ip_packet.put(test_ipPackageData);
|
||||||
|
|
||||||
|
//calculate the head checksum
|
||||||
|
// short ip_checksum=computeChecksum(ipPackageData,20);
|
||||||
|
// System.out.println("the checksum of ip packet is "+ Integer.toHexString(Short.toUnsignedInt(ip_checksum)));
|
||||||
|
// System.out.println("the checksum(unsigned int) of ip packet is "+ Short.toUnsignedInt(ip_checksum));
|
||||||
|
// System.out.println("the checksum(short) of ip packet is "+ ip_checksum);
|
||||||
|
// 将byte数组按16进制输出
|
||||||
|
// byte[] test=new byte[2];
|
||||||
|
// test=ByteHelper.uint16ToByteArray(Short.toUnsignedInt(ip_checksum));
|
||||||
|
// System.out.println("the checksum(hex) of ip packet is "+Integer.toHexString(test[0] & 0xFF)+" "+Integer.toHexString(test[1] & 0xFF));
|
||||||
|
|
||||||
//读取源ip: [0]-[3],10.254.0.2 , 目的ip: [4]-[7],10.255.0.3
|
//读取源ip: [0]-[3],10.254.0.2 , 目的ip: [4]-[7],10.255.0.3
|
||||||
for(int i=12;i<20;i++){
|
for(int i=12;i<20;i++){
|
||||||
@@ -188,12 +242,14 @@ public class MINVpnLBConnection implements MINVpnConnection {
|
|||||||
System.out.print("source ip is "+ip_address_unsignedInt_first[i]);
|
System.out.print("source ip is "+ip_address_unsignedInt_first[i]);
|
||||||
else if(i>=1&&i<=3)
|
else if(i>=1&&i<=3)
|
||||||
System.out.print("."+ip_address_unsignedInt_first[i]);
|
System.out.print("."+ip_address_unsignedInt_first[i]);
|
||||||
else if(i==4)
|
else if(i==4){
|
||||||
|
System.out.print(" source tcp port is "+ByteHelper.new_byteArrayToInt(source_port));
|
||||||
System.out.print("\ndestination ip is "+ip_address_unsignedInt_first[i]);
|
System.out.print("\ndestination ip is "+ip_address_unsignedInt_first[i]);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
System.out.print("."+ip_address_unsignedInt_first[i]);
|
System.out.print("."+ip_address_unsignedInt_first[i]);
|
||||||
}
|
}
|
||||||
System.out.print("\n");
|
System.out.print(" destination tcp port is "+ByteHelper.new_byteArrayToInt(destination_port)+"\n");
|
||||||
|
|
||||||
// 跳转到第3步
|
// 跳转到第3步
|
||||||
//第3.2步,如果目的地址是10.254.0.1,用face发出去【不用实现,打印即可】
|
//第3.2步,如果目的地址是10.254.0.1,用face发出去【不用实现,打印即可】
|
||||||
@@ -206,22 +262,66 @@ public class MINVpnLBConnection implements MINVpnConnection {
|
|||||||
else{
|
else{
|
||||||
System.out.println("目的地址不是10.254.0.1,进行地址转换");
|
System.out.println("目的地址不是10.254.0.1,进行地址转换");
|
||||||
ip_NAT_packet.clear();
|
ip_NAT_packet.clear();
|
||||||
|
ip_NAT_packet.position(0);
|
||||||
|
|
||||||
//更换ip包中目的地址为要转换的地址
|
//更换ip包中目的地址为要转换的地址
|
||||||
byte[] address_to_NAT_byte=new byte[4];
|
byte[] address_to_NAT_byte=new byte[4];
|
||||||
int[] address_to_NAT_unsignedINT={192,168,3,2};
|
int[] address_to_NAT_unsignedINT={192,168,3,12};
|
||||||
for(int i=0;i<4;i++){
|
for(int i=0;i<4;i++){
|
||||||
address_to_NAT_byte[i]=ByteHelper.uint8ToByte(address_to_NAT_unsignedINT[i]);
|
address_to_NAT_byte[i]=ByteHelper.uint8ToByte(address_to_NAT_unsignedINT[i]);
|
||||||
//System.out.print(address_to_NAT_byte[i]+" ");
|
//System.out.print(address_to_NAT_byte[i]+" ");
|
||||||
ipPackageData[i+16]=address_to_NAT_byte[i];
|
ipPackageData[i+16]=address_to_NAT_byte[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//calculate the checksum of ip packet, replace the checksum
|
||||||
|
short ip_checksum=computeChecksum(ipPackageData,ip_head_length,10);
|
||||||
|
byte[] new_ip_checksum;
|
||||||
|
new_ip_checksum=ByteHelper.uint16ToByteArray(Short.toUnsignedInt(ip_checksum));
|
||||||
|
ipPackageData[10]=new_ip_checksum[0];
|
||||||
|
ipPackageData[11]=new_ip_checksum[1];
|
||||||
|
|
||||||
|
//calculate the checksum of tcp,replace the checksum
|
||||||
|
System.out.println("is tcp:"+Byte.toUnsignedInt(ipPackageData[9]));
|
||||||
|
if(Byte.toUnsignedInt(ipPackageData[9])==6){
|
||||||
|
byte[] temp_head_to_calculate_checksum;
|
||||||
|
if((tcp_length+12)%2==0)
|
||||||
|
temp_head_to_calculate_checksum=new byte[tcp_length+12];
|
||||||
|
else
|
||||||
|
temp_head_to_calculate_checksum=new byte[tcp_length+13];
|
||||||
|
//构造tcp伪头部
|
||||||
|
for(int i=0;i<8;i++)
|
||||||
|
temp_head_to_calculate_checksum[i]=ipPackageData[i+12];
|
||||||
|
temp_head_to_calculate_checksum[8]=ByteHelper.uint8ToByte(0);
|
||||||
|
temp_head_to_calculate_checksum[9]=ipPackageData[9];
|
||||||
|
temp_head_to_calculate_checksum[10]=ByteHelper.uint16ToByteArray(tcp_length)[0];
|
||||||
|
temp_head_to_calculate_checksum[11]=ByteHelper.uint16ToByteArray(tcp_length)[1];
|
||||||
|
for(int i=0;i<tcp_length;i++){
|
||||||
|
temp_head_to_calculate_checksum[i+12]=ipPackageData[ip_head_length+i];
|
||||||
|
}
|
||||||
|
if((tcp_length+12)%2!=0)
|
||||||
|
temp_head_to_calculate_checksum[tcp_length+12]=ByteHelper.uint8ToByte(0);
|
||||||
|
|
||||||
|
//printHexString("content of integrity tcp: ",temp_head_to_calculate_checksum);
|
||||||
|
short tcp_checksum=computeChecksum(temp_head_to_calculate_checksum,tcp_length+12,28);
|
||||||
|
//System.out.println("the checksum of tcp datagram is "+ Integer.toHexString(Short.toUnsignedInt(tcp_checksum)));
|
||||||
|
byte[] new_tcp_checksum;
|
||||||
|
new_tcp_checksum=ByteHelper.uint16ToByteArray(Short.toUnsignedInt(tcp_checksum));
|
||||||
|
ipPackageData[ip_head_length+16]=new_tcp_checksum[0];
|
||||||
|
ipPackageData[ip_head_length+17]=new_tcp_checksum[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("before changing, position is"+ip_NAT_packet.position());
|
||||||
//搜一下怎么换ip地址,还要更换包里面其他的内容吗
|
//搜一下怎么换ip地址,还要更换包里面其他的内容吗
|
||||||
ip_NAT_packet.put(ipPackageData);
|
ip_NAT_packet.put(ipPackageData);
|
||||||
|
|
||||||
//从buffer中读取转换后的ip包
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// //从buffer中读取转换后的ip包
|
||||||
// byte[] ipdata_changing= ip_NAT_packet.array();
|
// byte[] ipdata_changing= ip_NAT_packet.array();
|
||||||
// System.out.println("the content of ip packet after changing is: " + Arrays.toString(ipdata_changing));
|
// printHexString("the content of ip packet after changing is: ",ipdata_changing);
|
||||||
// //读取源ip: [12]-[15] , 目的ip: [16]-[19],192.168.3.2
|
// //读取源ip: [12]-[15] , 目的ip: [16]-[19],192.168.3.12
|
||||||
// int[] ip_address_unsignedInt_changing=new int[8];
|
// int[] ip_address_unsignedInt_changing=new int[8];
|
||||||
// //将ip转化为unsigned int
|
// //将ip转化为unsigned int
|
||||||
// for(int i=12;i<20;i++){
|
// for(int i=12;i<20;i++){
|
||||||
@@ -238,13 +338,8 @@ public class MINVpnLBConnection implements MINVpnConnection {
|
|||||||
// System.out.print("."+ip_address_unsignedInt_changing[i]);
|
// System.out.print("."+ip_address_unsignedInt_changing[i]);
|
||||||
// }
|
// }
|
||||||
// System.out.print("\n");
|
// System.out.print("\n");
|
||||||
|
// System.out.println("after changing, position is "+ip_NAT_packet.position());
|
||||||
|
|
||||||
try {
|
|
||||||
outputStream.write(ip_NAT_packet.array(), 0, ip_NAT_packet.position());
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
System.out.println("将抓转换后的地址写入tun网卡失败");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -254,9 +349,19 @@ public class MINVpnLBConnection implements MINVpnConnection {
|
|||||||
readFromTun.start();
|
readFromTun.start();
|
||||||
|
|
||||||
|
|
||||||
|
// Thread writeToTun = new Thread(() -> {
|
||||||
// // 第3.1步,如果目的地址不是10.254.0.1,先将IP包的源端口号和目的IP端口号存入表iptables,
|
// while (!this.stop){
|
||||||
// // 然后做NAT转换,做完NAT转换的IP包写入tun(通过ParcelFileDescriptor) write()
|
// //System.out.println("ip_NAT_packet position"+ip_NAT_packet.position());
|
||||||
|
//
|
||||||
|
// if()
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// ip_NAT_packet.position(0);
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// writeToTun.start();
|
||||||
|
// 第3.1步,如果目的地址不是10.254.0.1,先将IP包的源端口号和目的IP端口号存入表iptables,
|
||||||
|
// 然后做NAT转换,做完NAT转换的IP包写入tun(通过ParcelFileDescriptor) write()
|
||||||
// Thread writeToTun = new Thread(() -> {
|
// Thread writeToTun = new Thread(() -> {
|
||||||
// while(this.stop){
|
// while(this.stop){
|
||||||
// System.out.println("write thread "+temp_buff.position());
|
// System.out.println("write thread "+temp_buff.position());
|
||||||
@@ -310,13 +415,56 @@ public class MINVpnLBConnection implements MINVpnConnection {
|
|||||||
return MINVpnLBConnection.class.getSimpleName() + "[" + mConnectionId + "]";
|
return MINVpnLBConnection.class.getSimpleName() + "[" + mConnectionId + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
private void transfer_ip_packet_from_thread(ByteBuffer ip_packet,int readLen){
|
/**
|
||||||
temp_buff.clear();
|
* 将byte数组以16进制的形式输出
|
||||||
byte[] ipPackageData = new byte[readLen];
|
*
|
||||||
System.arraycopy(ip_packet.array(), 0, ipPackageData, 0, readLen);
|
* @param b
|
||||||
temp_buff.put(ipPackageData);
|
* byte[]
|
||||||
length_of_ip_packet=readLen;
|
* @return void
|
||||||
|
*/
|
||||||
|
public static void printHexString(String hint, byte[] b)
|
||||||
|
{
|
||||||
|
System.out.print(hint);
|
||||||
|
for (int i = 0; i < b.length; i++)
|
||||||
|
{
|
||||||
|
String hex = Integer.toHexString(b[i] & 0xFF);
|
||||||
|
if (hex.length() == 1)
|
||||||
|
{
|
||||||
|
hex = '0' + hex;
|
||||||
|
}
|
||||||
|
System.out.print(hex.toUpperCase() + " ");
|
||||||
|
}
|
||||||
|
System.out.println("");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the IPv4 head checksum on the passed stream of bytes
|
||||||
|
* representing the packet.
|
||||||
|
*
|
||||||
|
* @param data
|
||||||
|
* The byte stream
|
||||||
|
* @param length
|
||||||
|
* The length of the IPv4 packet's head
|
||||||
|
* @return The computed checksum
|
||||||
|
*/
|
||||||
|
short computeChecksum(byte[] data,int length,int checksumStart) {
|
||||||
|
short checkSum;
|
||||||
|
int sum = 0;
|
||||||
|
int wordData;
|
||||||
|
for (int i = 0; i <= length - 1; i = i + 2) {
|
||||||
|
// Skip, if the current bytes are checkSum bytes
|
||||||
|
if (i == checksumStart) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
wordData = (data[i] << 8 & 0xFF00) + (data[i + 1] & 0xFF);
|
||||||
|
sum = sum + wordData;
|
||||||
|
}
|
||||||
|
int carry = sum >> 16 & 0xFF;
|
||||||
|
int finalSum = (sum & 0xFFFF) + carry;
|
||||||
|
checkSum = (short) ~((short) finalSum & 0xFFFF);
|
||||||
|
|
||||||
|
return checkSum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user