2016-11-30 12 views
0

でTCPソケットにフィルタを取り付けは、私はTCPソケットを作成するLinuxの

sudo tcpdump tcp -d port 9000 
(000) ldh  [12] 
(001) jeq  #0x86dd   jt 2 jf 8 
(002) ldb  [20] 
(003) jeq  #0x6    jt 4 jf 19 
(004) ldh  [54] 
(005) jeq  #0x2328   jt 18 jf 6 
(006) ldh  [56] 
(007) jeq  #0x2328   jt 18 jf 19 
(008) jeq  #0x800   jt 9 jf 19 
(009) ldb  [23] 
(010) jeq  #0x6    jt 11 jf 19 
(011) ldh  [20] 
(012) jset  #0x1fff   jt 19 jf 13 
(013) ldxb  4*([14]&0xf) 
(014) ldh  [x + 14] 
(015) jeq  #0x2328   jt 18 jf 16 
(016) ldh  [x + 16] 
(017) jeq  #0x2328   jt 18 jf 19 
(018) ret  #65535 
(019) ret  #0 

このフィルタを接続すると、プログラムはポート9000に何も送信できません。 しかし、私は1つのinstr出席:

(018) ret  #65535 

すべてがOKです。 正しいフィルタコードを生成する方法は?

答えて

1

私はこの問題がfor this questionと同じであると信じています。

Tcpdumpは、最初のイーサネットヘッダーバイトから始まるイーサネットフレームで動作します。したがって、これらのBPF命令では、次のようになります。tcpdumpはパケットがIP(4または6)であることをチェックします。あなたはIPパケット上で動作するので、生のソケット上

は、あなたが、正確に同じことを行うことができない、意味すなわちイーサネットペイロード:

  • をイーサタイプを見ては意味がありません、それが到達不能です。
  • パケット内で検査するフィールドに到達するオフセットは異なります(イーサネットヘッダーのサイズは14バイト低くなります)。

私はテストしていませんが、このようなものを試すことがあります。あなたはIPv4とTCPで動作するように見えるので、私はIPv6部分の指示を破棄し、パケットがTCPであるかどうかを確認します(ソケットがソケットを受け取った場合、それはすでにわかっています)。これは、最初の11命令を削除することを意味します。

(000) ldh  [6]        // Load fragment offset field 
(001) jset  #0x1fff   jt 8 jf 2  // Jump to end if packet is a fragment 
(002) ldxb  4*([0]&0xf)      // Add size of IP header (inc. options) to X 
               // Now X points to the beginning of TCP hdr 
(003) ldh  [x + 0]       // Load src port field 
(004) jeq  #0x2328   jt 7 jf 5  // Is it equal to 9000? 
(005) ldh  [x + 2]       // Else jump to dst port field 
(006) jeq  #0x2328   jt 7 jf 8  // Is it equal to 9000? 
(007) ret  #65535       // (If port 9000) return 0x65535 
(008) ret  #0        // Return 0 

私は、フラグメントオフセットチェックとdstポート番号チェックの手順をそのまま保存しました。私はオフセットとジャンプ命令のリファレンスを適用しました。残りの命令は変更されません。しかし、再び私はそれをテストしていないので、保証はありません。

+0

あなたは 'SOCK_STREAM'ソケットでIPヘッダにアクセスすることさえできるのだろうかと思います。私のプログラムはrawソケット上でのみ有効です(私が引用した質問は 'socket(PF_INET、SOCK_RAW、IPPROTO_TCP);を使用しています)、もしそうなら、最後の6つの命令を保持し、' X'レジスタを使用せずにフィールドをロードしてみてください。 – Qeole

+0

ありがとう、私はそれが動作することをテストします。私はSOCK_STREAMを使用してIPヘッダーにアクセスしようとしますlinux bpf拡張子を使用します。 – flypig

関連する問題