ソケットがバインドされているのと同じインターフェイスを介してパケットが送信されるように、いくつかのルーティング ルールを設定しました。(C++ の sendto 関数は、宛先アドレスに基づいて最適なインターフェイスを選択しようとします)。ローカル ネットワーク内外の他のデバイスに UDP パケットを送信していますが、その代わりに、同じアドレスに UDP パケットを送信することで応答します。Wiresharkを使用して、これが発生することを確認できます。
ただし、パケットはネットワーク スタックに到着し、Wireshark で読み取ることができますが、特定のインターフェイスにバインドされたソケットでは受信されません。
私の Ubuntu システムのルーティング ルールは次のとおりです。
iptables -A OUTPUT -o wlan0 -t mangle -p udp -s 193.156.108.78 --sport 12346 -j MARK --set-mark 21
ip rule add fwmark 21 table 21
ip route add dev wlan0 default via 193.156.108.1 table 21
着信トラフィック用にiptablesを変更する必要があると思いますが、イーサネット フレームと ip ヘッダーの両方のアドレスが正しいように見えるため、何が機能していないのかわかりません。
編集:
iptables で LOG ターゲットを使用すると、パケットがmangleテーブルのPREROUTINGを使用しているが、natテーブルのPREROUTINGを使用していないことがわかりました。INPUTテーブルも通過しません。現時点では理由はわかりません。
rawのPREROUTINGでルールとして設定されているiptables TRACEは、パケットをトレースします。PREROUTING mangleのルールを通過し(何も試したことはありませんが、どこにも行きませんでした)、最終的にいくつかのポリシー #でそこで停止します。番号は、その特定のテーブルで選択されたルールを表します。どこでもACCEPTであるデフォルト ポリシーは、使用可能な最大数です。(ユーザールールの数 + 1)
受け入れられたパケットとルールの使用iptables -L -nvx
と数を視覚化できます。iptables -S -v
そのため、パケットが受け入れられたように見えても、どこかにドロップされています。私は本当にここでいくつかの助けを借りることができました.
これは、そのようなパケットの 1 つの完全なトレースです。
Nov 1 09:18:23 XXX kernel: [ 2377.505697] TRACE: raw:PREROUTING:policy:3 IN=wlan0 OUT= MAC=XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX SRC=XXX.XXX.XXX.XXX DST=193.156.108.67 LEN=83 TOS=0x00 PREC=0x00 TTL=50 ID=0 DF PROTO=UDP SPT=6428 DPT=12346 LEN=63
Nov 1 09:18:23 XXX kernel: [ 2377.505721] TRACE: mangle:PREROUTING:policy:2 IN=wlan0 OUT= MAC=XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX SRC=XXX.XXX.XXX.XXX DST=193.156.108.67 LEN=83 TOS=0x00 PREC=0x00 TTL=50 ID=0 DF PROTO=UDP SPT=6428 DPT=12346 LEN=63
EDIT2:
同じワイヤレス ネットワーク内のデバイスから送り返される UDP パケットは機能します。また、ローカル ネットワークと外部ネットワークの両方の eth0 にバインドされたソケットでも機能します。これらのルートは通常、nat PREROUTING部分もスキップし、IP ルーティング テーブルに直接進みます。(視覚化) どうやら何かがうまくいかないところです。別のテーブルへのリダイレクトが実際に機能することを確認できませんでした ( MARKまたはを使用ip rule add from "source" table #
)。これに関する提案も歓迎します。また、パケットがINPUTに継続できるようにするために、ルーティング テーブルに何が必要かを理解できませんでした。
不満足な解決策:
/etc/sysctl.confでlog_martians変数を設定すると、おそらくリバース パス フィルタリングが原因で、パケットがドロップされていることがわかります。幸いなことに、同じファイルでrp_filter変数を2に設定すると、問題が解決します。
ここで説明したように、パケットが入ってくるインターフェイスが送信元へのルートを見つけられない場合、パケットはブロックされます。このrp_filter値を 2 に設定すると問題が解決します。これは、デフォルト インターフェイスが実際にこのソースにルーティングできるという事実に依存しているためです。
残りの質問:
何らかの理由で、このrp_filter値を 0 に設定しても常に機能するとは限りません (火星のパケットはまったくドロップされないはずです)。それがなぜなのかわかりません。
さらに、私はこの解決策があまり好きではなく、より良い解決策があれば喜んで実装します。パケットをマークするだけでなく、 wlan0 インターフェイスにこのソースへの標準的なルーティング方法を提供する方法を見つける必要があるように思えます。提案?