3

データグラムソケットで BPF を使用してパケットをフィルタリングすることは可能ですか?

フィルタをアタッチしようとしてもエラーは発生しませんが、パケットを受信しません。libpcap を使用してフィルターをコンパイルしました。フィルターは tcpdump で動作します。

これが私のコードの短縮版です:

static const char filter[] = "udp[8] == 0x00";
int sock = socket(AF_INET, SOCK_DGRAM, 0);
pcap_t *pcap = pcap_open_dead(DLT_RAW, 1024);
struct bpf_program bpf_prog;
pcap_compile(pcap, &bpf_prog, filter, 0, PCAP_NETMASK_UNKNOWN);
struct sock_fprog linux_bpf = {
    .len = bpf_prog.bf_len,
    .filter = (struct sock_filter *) bpf_prog.bf_insns,
};
setsockopt(sock, SOL_SOCKET, SO_ATTACH_FILTER, &linux_bpf, sizeof(linux_bpf));

私のマシンはubuntu 12.04 x86です。

4

1 に答える 1

6

まあ、いくつかのテストと試行の後、それは可能です。ただし、libpcap は直接サポートしていません。

すべきことは、イーサネット データ タイプを指定する pcap ハンドラを開き、イーサネット パケットにアクセスするかのように udp パケット内のバイトにアクセスすることです。フィルタ オフセットはパケットの先頭から始まりますが、「パケット」はソケットを開いたレイヤによって異なります。でソケットを開くとSOCK_DGRAM、bpf 命令ldb 0は udp ヘッダーの最初のバイトをロードします。そのため、フィルタ libpcap にアクセスするether[0]と、目的のファイルにコンパイルされますldb 0

したがって、修正されたコードは次のようになります。

static const char filter[] = "ether[8] == 0x00";
int sock = socket(AF_INET, SOCK_DGRAM, 0);
pcap_t *pcap = pcap_open_dead(DLT_EN10MB, 1024);
struct bpf_program bpf_prog;
pcap_compile(pcap, &bpf_prog, filter, 0, PCAP_NETMASK_UNKNOWN);
struct sock_fprog linux_bpf = {
    .len = bpf_prog.bf_len,
    .filter = (struct sock_filter *) bpf_prog.bf_insns,
};
setsockopt(sock, SOL_SOCKET, SO_ATTACH_FILTER, &linux_bpf, sizeof(linux_bpf));
于 2014-07-02T18:06:27.010 に答える