Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
440 views
in Technique[技术] by (71.8m points)

ip - Sending a raw packet to a NetworkInterface in Android doesn't work?

I'm trying to send packets via a VPN out of the VPN onto the proper hardware without any real VPN server used, so I can log the packets being sent through.

I'm able to get an InetAddress for the wlan0 interface I want the packet to actually go to, but I'm not too sure if that's the right place at all (it shows my current IP address).

I then use a DatagramChannel (called socket and the IntetAddress is uplink) on it:

socket.connect(new InetSocketAddress(uplink, 0));

And write packets to it:

socket.write(packet);

But nothing sticks, I just get

java.net.SocketException: sendto failed: EINVAL (Invalid argument)
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I'm trying to do something similar in creating a firewall/filtering application for Android. I'm in the middle of this, so take what I say with the appropriate sized grain of salt. :-)

The trouble with your/my situation is that you're taking packets off the virtual network interface given to you by VpnService, but then you're taking those packets and writing them out with a socket. A socket is intended to handle the transfer of application payload between client and server, not packets.

The socket will take any data you hand it, and wrap that data within a packet of its own creation (TCP if using Socket, UDP if using DatagramSocket as you are). In your case, the data you are handing the socket is itself a packet, and thus you end up with a packet within a packet (likely a TCP packet inside a UDP packet).

When the wrapped packet arrives at the server for your socket, the network interface and ServerSocket on that end will unwrap the payload and find that it is another packet. Probably not going to work because whatever is reading from the server-side socket (e.g. web server) is expecting application payload (e.g. HTTP headers/etc.).

Now, when you have a real VPN tunnel, the server-side of that tunnel is probably pulling your 'wrapped packet' payload out of the UDP packet it receives and is then handing that packet directly to a network interface that can interpret the packet itself.

Without this real VPN tunnel, your VpnService impl essentially has to become a virtual network interface itself, handling the TCP/UDP/etc. protocol between the virtual network interface and your code. Basically, packets read from your VPN interface have to be treated as an application data stream (packets collated and reassembled) before writing to your outgoing socket. Then, you have to somehow acknowledge the packets you just consumed from the interface. Then, you have to take incoming data from your Socket (which is a payload data stream), and break it up into packets that you can then send back to the output stream of your VPN interface. Finally, you need to handle acknowledgement traffic your virtual VPN interface will send in response to the packets you send it. This is not trivial to do.

I really hope I'm wrong about all this, and someone has a simple 'virtual network interface' written in Java that could be used to take the place of the real VPN tunnel. I haven't been able to find it.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...