我正试图通过VPN将数据包从VPN发送到适当的硬件上,而不使用任何真正的VPN服务器,这样我就可以记录发送的数据包。
我可以为我希望数据包实际到达的wlan0
接口获取InetAddress
,但我不太确定那是否是正确的位置(它显示了我当前的IP地址)。
然后我在上面使用DatagramChannel
(称为socket
,IntetAddress
是uplink
):
socket.connect(new InetSocketAddress(uplink, 0));
并将数据包写入其中:
socket.write(packet);
但什么都不粘,我只得到
java.net.SocketException: sendto failed: EINVAL (Invalid argument)
我正在尝试为Android创建一个防火墙/过滤应用程序。我正处于这中间,所以用合适大小的盐来接受我所说的。:-)
你/我的情况的问题是,你从VpnService提供给你的虚拟网络接口上取下了数据包,但随后你又取下了这些数据包,并用套接字将它们写出来。套接字用于处理客户端和服务器之间应用程序有效负载的传输,而不是数据包。
套接字将接收你交给它的任何数据,并将这些数据封装在它自己创建的数据包中(如果使用套接字,则为TCP,如果使用DatagramSocket,则为UDP)。在您的情况下,您向套接字传递的数据本身就是一个数据包,因此您最终得到的是数据包中的数据包(很可能是UDP包中的TCP数据包)。
当包装好的数据包到达套接字的服务器时,网络接口和该端的ServerSocket将打开有效负载,并发现它是另一个数据包。可能不起作用,因为从服务器端套接字(例如web服务器)读取的内容都期望应用程序有效负载(例如HTTP头等)
现在,当你有一个真正的VPN隧道时,该隧道的服务器端可能会从它接收的UDP数据包中提取你的"包裹数据包"有效载荷,然后将该数据包直接交给可以解释数据包本身的网络接口。
如果没有这个真正的VPN隧道,你的VpnService impl本质上必须成为一个虚拟网络接口,处理TCP/UDP/等。虚拟网络接口和代码之间的协议。基本上,在写入传出套接字之前,从VPN接口读取的数据包必须被视为应用程序数据流(经过整理和重新组装的数据包)。然后,您必须以某种方式确认刚刚从接口消耗的数据包。然后,你必须从你的套接字中获取传入数据(这是一个有效负载数据流),并将其分解为数据包,然后发送回VPN接口的输出流。最后,你需要处理你的虚拟VPN接口将发送的确认流量,以响应你发送的数据包。这不是一件小事。
我真的希望我错了,有人用Java编写了一个简单的"虚拟网络接口",可以用来代替真正的VPN隧道。我一直找不到它。
您可以使用NetworkInterface API以编程方式获取wlan0地址。
我也在尝试做类似的事情。。我可以在虚拟接口上看到数据包。。但我无法通过本地接口发送数据包。。
我可以使用DatagramChannel连接到wlan0,但从wlan0到外部服务器的连接被困在SYN_SEND。。
您可以尝试更高的端口。这对我很有用:InetSocketAddress(uplink, 3022)
我不知道如何确保端口没有被使用。
你是怎么得到世界的地址的?我使用了adb shell ifconfig并粘贴了地址。