Search code examples
javaandroidfileinputstreambytebuffer

Android VPN service Bytebuffer can't be written


I am developing a packet sniffer Android app with VPN service but I had a trouble on read the packet from Fileinputstream to bytebuffer. The problem is that every time I write the packet to bytebuffer, it doesn't have any data inside the bytebuffer. Please give a help to me. Thanks

 FileInputStream in = new FileInputStream(traffic_interface.getFileDescriptor());

                FileOutputStream out = new FileOutputStream(traffic_interface.getFileDescriptor());
                DatagramChannel tunnel = DatagramChannel.open();
                if (!protect(tunnel.socket())) {throw new IllegalStateException("Cannot protect the tunnel");}

                tunnel.connect((new InetSocketAddress("127.0.0.1",0)));
                tunnel.configureBlocking(false);
                int n = 0;

                while (!Thread.interrupted()){
                    packet = ByteBuffer.allocate(65535);

                    int packet_length = in.read(packet.array());
                    Log.d("UDPinStream","UDP:" +packet_length);

                    if(packet_length != -1 && packet_length > 0){
                        Log.d("UDPinStream","UDP:" + packet_length);
                        Log.d("UDPinStream","packet:" + packet);

                        packet.clear();
                    }

The problem occupy in the following code

                int packet_length = in.read(packet.array());

                if(packet_length != -1 && packet_length > 0){
                    Log.d("UDPinStream","UDP:" + packet_length);
                    Log.d("UDPinStream","packet:" + packet);

                    packet.clear();
                }

although it successfully read the packet from the tunnel (packet_length >0), there is also no data in Bytebuffer packet the pos of the bytebuffer doesn't change. java.nio.HeapByteBuffer[pos=0 lim=65535 cap=65535]


Solution

  • ByteBuffers are designed to work with channels. You should use any read/write(ByteBuffer buf) interfaces of channels to get proper use of ByteBuffers.

    Anyway, in your snippet, read() gets byte[], writes into it but ByteBuffer is unaware of its backed array is filled. So, you can do,

    if (packet_length != -1 && packet_length > 0) {
        packet.position(packet_length);  // filled till that pos
        packet.flip();                   // No more writes, make it ready for reading
    
       // Do read from packet buffer
       // then, packet.clear() or packet.compact() to read again.
    }
    

    Please have a look at NIO / ByteBuffer examples before keep going.