5
#include <stdio.h>
#include <stdlib.h>
#include <pcap.h>

#define BUFFER_SIZE 65535

char errbuf[PCAP_ERRBUF_SIZE];

int main(int argc, char **argv)
{
    int d;
    pcap_if_t *alldevsp;
    pcap_t *pkt_handle;

    if((pcap_findalldevs(&alldevsp,errbuf))==-1)
    {
        printf("findalldevices: %s\n",errbuf);
        exit(1);
    }
    printf("Availabel network devices are\n");
    pcap_if_t *temp = alldevsp;
    while((temp)!=NULL)
    {
        printf("%s: %s\n",(temp)->name,(temp)->description);
        (temp)=(temp)->next;
    }
    pcap_freealldevs(alldevsp);

    pkt_handle = pcap_create("wlan1",errbuf);
    if(pkt_handle==NULL)
    {
        printf("create: %s\n",errbuf);
        exit(1);
    }


    if((pcap_set_rfmon(pkt_handle, 1))!=0)
    {
        printf("Monitor mode could not be set\n");
        exit(1);
    }

    if((pcap_set_buffer_size(pkt_handle, BUFFER_SIZE))!=0)
        {
        printf("ERROR\n");
        exit(1);
    }

    if((d=(pcap_activate(pkt_handle)))!=0)
    {
        if(d==PCAP_ERROR_RFMON_NOTSUP)
            printf("%d : PCAP_ERROR_RFMON_NOTSUP\n",d);
        if(d==PCAP_WARNING)
            printf("%d : PCAP_WARNING\n",d);
        if(d==PCAP_ERROR)
            printf("%d : PCAP_ERROR\n",d);
        pcap_perror(pkt_handle,"Activate");
        exit(1);
    }
    printf("d=%d\n",d);

    while(1)
    {
        scanf("%d",&d);
        if(d==-1)
            break;
    }

    pcap_close(pkt_handle);
    printf("Bye\n");

    return 0;
}

上記のプログラムを使用して実行する場合:

gcc -Wall -lpcap sample.c -o sample

次のエラーが発生します:

-1 : PCAP_ERROR
Activate: can't mmap rx ring: Invalid argument

ただし、関数呼び出しを含むコードのセクションをコメントアウトするpcap_set_buffer_size()と、プログラムは完全に正常に機能します。

それで、この問題はpcap_set_buffer_size()何ですか?

なぜpcap_activate()失敗するのですか?

4

1 に答える 1

12

最近の 64 ビット Linux の場合:

65616 以上の任意のバッファ サイズで十分です。

値の計算方法については、ソースからの実装create_ring()を参照してください。pcap-linux.clibpcap

デフォルトは 2*1024*1024 = 2097152 です。

Windows のデフォルトのバッファ サイズは 1000000 です。


アップデート:

によって設定されるバッファ サイズpcap_set_buffer_size()は、既に受信したパッケージを格納する (リング) バッファを参照します。最適なサイズは、ユース ケースと手頃な価格のシステム リソース (ページング不可能なメモリ) によって異なります。

からの受信バッファーのサイズについては、次のステートメントを参照してください man pcap

キャプチャのために到着したパケットはバッファに格納されるため、到着後すぐにアプリケーションで読み取る必要はありません。一部のプラットフォームでは、バッファーのサイズを設定できます。サイズが小さすぎると、キャプチャされるパケットが多すぎて、スナップショットの長さがバッファリングされるデータの量を制限しない場合、アプリケーションがバッファからパケットを読み取る前にバッファがいっぱいになると、パケットがドロップされる可能性があります。サイズが大きすぎると、パケットのドロップを防ぐのに必要な以上の非ページング オペレーティング システム メモリが使用される可能性があります。


更新 1:

とにかく、バッファのサイズは、使用中のハンドルに設定されたスナップの長さよりも小さく、バッファ自体を適切に整列させるために必要なバイトを加えたものでなければなりません。

を使用して、ハンドルの現在のスナップ長を取得できますpcap_snapshot()。デフォルトのスナップ長は 65535 バイトです。

于 2012-07-09T16:38:49.540 に答える