Android VpnService для захвата пакетов не будет захватывать пакеты

Я искал свой ответ уже пару часов, и я не могу понять это. Пожалуйста помоги.

Что я хочу сделать, так это использовать VpnService в Android для захвата сетевых пакетов, таких как приложение tPacketCapture

Я начал с использования кода образца ToyVpn из Google и изменил его, чтобы я не отправлял данные на сервер. Однако я не уверен, что это правильно.

Мой метод configure использует IP-адрес wlan для binder.addAddress () перед вызовом функции setup (). Я использую 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(); } } 

Solutions Collecting From Web of "Android VpnService для захвата пакетов не будет захватывать пакеты"

Хорошо, это было совсем не просто, но я понял, как захватить пакеты. Поскольку я не очень хорошо знаком с сетью (но эта новая работа требует, чтобы я была), я с трудом установил все правильно. В основном после установки правильного маршрута в 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. 

Вам не нужно настраивать DnsServer через builder.addDnsServer (), чтобы он работал. Надеюсь, это поможет кому угодно!

Мой метод configure использует IP-адрес wlan для binder.addAddress () перед> вызовом install (). Я использую nexus 7, и я использовал «adb shell netcfg | grep> wlan0», чтобы получить адрес:

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

Я написал простой скрипт в python, чтобы показать вам netcfg графически из adb. Он обновляется каждую секунду.

Введите описание изображения здесь https://github.com/ilanben/graphical_netcfg

Наслаждаться 🙂