将原始数据包发送到 Android 中的网络接口不起作用?



我正试图通过VPN将数据包从VPN发送到适当的硬件上,而不使用任何真正的VPN服务器,这样我就可以记录发送的数据包。

我可以为我希望数据包实际到达的wlan0接口获取InetAddress,但我不太确定那是否是正确的位置(它显示了我当前的IP地址)。

然后我在上面使用DatagramChannel(称为socketIntetAddressuplink):

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并粘贴了地址。

最新更新