Android VpnService捕获数据包不会捕获数据包

我一直在寻找我的答案,现在几个小时,我无法弄清楚。 请帮忙。

我想要做的就是使用Android中的VpnService来抓取networking数据包,比如应用程序tPacketCapture

我开始使用谷歌的ToyVpn示例代码,并修改它,所以我不发送数据到服务器。 不过,我不确定这是否正确。

在调用establish()之前,我的configuration方法使用了binder.addAddress()的wlan ip地址。 我使用的是nexus 7,我使用“adb shell netcfg | grep wlan0”来获取地址:

wlan0 UP 192.168.0.6/24 0x00001043 10:bf:48:bf:5f:9d

并将其添加到我的方法中:

private void configure() throws Exception { // If the old interface has exactly the same parameters, use it! if (mInterface != null) { Log.i(TAG, "Using the previous interface"); return; } // Configure a builder while parsing the parameters. Builder builder = new Builder(); builder.setMtu(1500); builder.addAddress("192.168.0.6", 24); try { mInterface.close(); } catch (Exception e) { // ignore } mInterface = builder.establish(); } 

在调用这个之后,我调用了我修改的run方法来传递一个string而不是一个InetSocketAddress,这并不重要,因为我没有在任何地方使用它:

  private void run(String run) throws Exception { configure(); FileInputStream in = new FileInputStream(mInterface.getFileDescriptor()); // Allocate the buffer for a single packet. ByteBuffer packet = ByteBuffer.allocate(32767); // We use a timer to determine the status of the tunnel. It // works on both sides. A positive value means sending, and // any other means receiving. We start with receiving. int timer = 0; // We keep forwarding packets till something goes wrong. while (true) { // Assume that we did not make any progress in this iteration. boolean idle = true; // Read the outgoing packet from the input stream. int length = in.read(packet.array()); if (length > 0) { Log.i(TAG,"************new packet"); while (packet.hasRemaining()) { Log.i(TAG,""+packet.get()); //System.out.print((char) packet.get()); } // Write the outgoing packet to the tunnel. packet.limit(length); // tunnel.write(packet); packet.clear(); // There might be more outgoing packets. idle = false; // If we were receiving, switch to sending. if (timer < 1) { timer = 1; } } } } 

当我做adb logcat时,什么都没有发生。 我正确地处理这个? 我觉得我失去了一些东西。

谢谢!

编辑:

从日志中我看到以下几行:

 I/ActivityManager( 460): START u0 {act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.example.android.toyvpn/.ToyVpnClient} from pid 10247 I/ActivityManager( 460): Start proc com.example.android.toyvpn for activity com.example.android.toyvpn/.ToyVpnClient: pid=10287 uid=10122 gids={50122, 3003, 1028} I/ActivityManager( 460): Displayed com.example.android.toyvpn/.ToyVpnClient: +1s144ms I/Vpn ( 460): Switched from [Legacy VPN] to com.example.android.toyvpn D/Vpn ( 460): setting state=IDLE, reason=prepare I/ToyVpnService(10287): running vpnService D/Vpn ( 460): setting state=CONNECTING, reason=establish D/VpnJni ( 460): Address added on tun0: 192.168.0.6/24 I/Vpn ( 460): Established by com.example.android.toyvpn.ToyVpnService on tun0 W/ContextImpl( 460): Calling a method in the system process without a qualified user: android.app.ContextImpl.bindService:1406 com.android.server.connectivity.Vpn.establish:289 com.android.server.ConnectivityService.establishVpn:3263 android.net.IConnectivityManager$Stub.onTransact:504 android.os.Binder.execTransact:351 D/Vpn ( 460): setting state=AUTHENTICATING, reason=establish 

所以它似乎是连接。

完整来源:

 public class ToyVpnService extends VpnService implements Handler.Callback, Runnable { private static final String TAG = "ToyVpnService"; private Handler mHandler; private Thread mThread; private ParcelFileDescriptor mInterface; @Override public int onStartCommand(Intent intent, int flags, int startId) { // The handler is only used to show messages. if (mHandler == null) { mHandler = new Handler(this); } // Stop the previous session by interrupting the thread. if (mThread != null) { mThread.interrupt(); } // Start a new session by creating a new thread. mThread = new Thread(this, "ToyVpnThread"); mThread.start(); return START_STICKY; } @Override public void onDestroy() { if (mThread != null) { mThread.interrupt(); } } @Override public boolean handleMessage(Message message) { if (message != null) { Toast.makeText(this, message.what, Toast.LENGTH_SHORT).show(); } return true; } @Override public synchronized void run() { Log.i(TAG,"running vpnService"); try { runVpnConnection(); } catch (Exception e) { e.printStackTrace(); //Log.e(TAG, "Got " + e.toString()); } finally { try { mInterface.close(); } catch (Exception e) { // ignore } mInterface = null; mHandler.sendEmptyMessage(R.string.disconnected); Log.i(TAG, "Exiting"); } } private boolean runVpnConnection() throws Exception { configure(); FileInputStream in = new FileInputStream(mInterface.getFileDescriptor()); // Allocate the buffer for a single packet. ByteBuffer packet = ByteBuffer.allocate(32767); // We keep forwarding packets till something goes wrong. while (true) { // Assume that we did not make any progress in this iteration. boolean idle = true; // Read the outgoing packet from the input stream. int length = in.read(packet.array()); if (length > 0) { Log.i(TAG,"************new packet"); System.exit(-1); while (packet.hasRemaining()) { Log.i(TAG,""+packet.get()); //System.out.print((char) packet.get()); } packet.limit(length); // tunnel.write(packet); packet.clear(); // There might be more outgoing packets. idle = false; } Thread.sleep(50); } } public String getLocalIpAddress() { try { for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) { NetworkInterface intf = en.nextElement(); for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) { InetAddress inetAddress = enumIpAddr.nextElement(); Log.i(TAG,"****** INET ADDRESS ******"); Log.i(TAG,"address: "+inetAddress.getHostAddress()); Log.i(TAG,"hostname: "+inetAddress.getHostName()); Log.i(TAG,"address.toString(): "+inetAddress.getHostAddress().toString()); if (!inetAddress.isLoopbackAddress()) { //IPAddresses.setText(inetAddress.getHostAddress().toString()); Log.i(TAG,"IS NOT LOOPBACK ADDRESS: "+inetAddress.getHostAddress().toString()); return inetAddress.getHostAddress().toString(); } else{ Log.i(TAG,"It is a loopback address"); } } } } catch (SocketException ex) { String LOG_TAG = null; Log.e(LOG_TAG, ex.toString()); } return null; } private void configure() throws Exception { // If the old interface has exactly the same parameters, use it! if (mInterface != null) { Log.i(TAG, "Using the previous interface"); return; } // Configure a builder while parsing the parameters. Builder builder = new Builder(); builder.setMtu(1500); builder.addAddress("192.168.0.6", 24); try { mInterface.close(); } catch (Exception e) { // ignore } mInterface = builder.establish(); } } 

好吧,这并不容易,但我想出了如何捕获数据包。 由于我对联网并不是很熟悉(但这个新工作就是要求我),所以我很难正确设置所有的东西。 基本上在VpnService.builder中设置正确的路由后,我正确地接收数据包。

所以:

 builder.addAddress("192.168.0.6", 24); // was wrong, you need to put an internal IP (10.0.2.0 for example) 

 builder.addRoute("0.0.0.0", 0); // needs to be this. 

您不需要通过builder.addDnsServer()来设置DnsServer以使其工作。 希望这有助于任何人!

我的configure方法在调用establish()之前使用了binder.addAddress()的wlan ip地址。 我使用的是nexus 7,我用“adb shell netcfg | grep> wlan0”来获取地址:

wlan0 UP 192.168.0.6/24 0x00001043 10:bf:48:bf:5f:9d

我已经写了一个简单的脚本在Python中向您展示从adbgraphicsnetcfg。 它每秒更新一次。

在这里输入图像描述 https://github.com/ilanben/graphical_netcfg

请享用 :)

Interesting Posts