8

実際の VPN サーバーを使用せずに、VPN 経由で VPN から適切なハードウェアにパケットを送信しようとしているので、送信されたパケットをログに記録できます。

InetAddressパケットを実際に送信したいインターフェイスのを取得できwlan0ますが、それが正しい場所であるかどうかはよくわかりません (現在の IP アドレスが表示されます)。

次に、DatagramChannel(と呼ばれsocketIntetAddressis uplink) を使用します。

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

そしてそれにパケットを書き込みます:

socket.write(packet);

しかし、何も固執しない、私はただ得ます

java.net.SocketException: sendto failed: EINVAL (Invalid argument)
4

3 に答える 3

15

Android用のファイアウォール/フィルタリングアプリケーションを作成する際に、似たようなことをしようとしています. 私はこの真っ只中にいるので、適切な大きさの塩の粒で私が言うことを受け取ってください. :-)

あなた/私の状況の問題は、VpnService によって提供された仮想ネットワーク インターフェイスからパケットを取得しているが、それらのパケットを取得してソケットで書き込んでいることです。ソケットは、パケットではなく、クライアントとサーバー間のアプリケーション ペイロードの転送を処理することを目的としています。

ソケットは、渡されたデータを受け取り、そのデータを独自に作成したパケット内にラップします (Socket を使用する場合は TCP、DatagramSocket を使用する場合は UDP)。あなたの場合、ソケットを処理しているデータ自体がパケットであるため、最終的にパケット内のパケットになります (UDP パケット内の TCP パケットの可能性があります)。

ラップされたパケットがソケットのサーバーに到着すると、その側のネットワーク インターフェイスと ServerSocket はペイロードをラップ解除し、それが別のパケットであることを検出します。サーバー側のソケット (Web サーバーなど) から読み取っているものはすべて、アプリケーションのペイロード (HTTP ヘッダーなど) を予期しているため、おそらく機能しません。

実際の VPN トンネルがある場合、そのトンネルのサーバー側はおそらく、受信した UDP パケットから「ラップされたパケット」ペイロードを引き出し、そのパケットを、パケット自体を解釈できるネットワーク インターフェイスに直接渡します。 .

この実際の VPN トンネルがなければ、VpnService impl は本質的にそれ自体が仮想ネットワーク インターフェイスになり、TCP/UDP などを処理する必要があります。仮想ネットワーク インターフェイスとコードの間のプロトコル。基本的に、VPN インターフェースから読み取られたパケットは、送信ソケットに書き込む前に、アプリケーション データ ストリーム (パケットを照合して再構成) として処理する必要があります。次に、インターフェイスから消費したばかりのパケットを何らかの方法で確認する必要があります。次に、ソケット (ペイロード データ ストリーム) から着信データを取得し、VPN インターフェースの出力ストリームに送り返すことができるパケットに分割する必要があります。最後に、仮想 VPN インターフェイスが、送信したパケットに応答して送信する受信確認トラフィックを処理する必要があります。これは簡単なことではありません。

このすべてについて私が間違っていることを本当に願っています.Javaで書かれた単純な「仮想ネットワークインターフェイス」を誰かが持っているので、実際のVPNトンネルの代わりに使用できます. 私はそれを見つけることができませんでした。

于 2013-03-15T19:04:21.583 に答える
1

NetworkInterface APIを使用して、wlan0 アドレスをプログラムで取得できます。

私も同様のことをしようとしています..仮想インターフェースでパケットを見ることができます..しかし、ローカルインターフェース経由でパケットを送信することはできません..

wlan0 には DatagramChannel で接続できるのですが、wlan0 から外部サーバーへの接続が SYN_SEND で止まってしまいます。

于 2013-01-28T20:43:56.297 に答える
0

より高いポートを試すことができます。これは私のために働く: InetSocketAddress(uplink, 3022)

ポートが使用されていないことを確認する方法がわかりません。

どうやって wlan0 のアドレスを取得しましたか? adb shell ifconfig を使用して、アドレスを貼り付けました。

于 2012-09-17T20:48:17.957 に答える