1

#include を使用して、さまざまなタイプのネットワーク パケット (VLAN としてタグ付けされているものとそうでないもの) を含む pcap ファイルを解析しようとしています。これまでの私のコードは次のとおりです。

pcap_t *pcap;
const unsigned char *packet;
char errbuf[PCAP_ERRBUF_SIZE];
struct pcap_pkthdr header;
pcap = pcap_open_offline(argv[0], errbuf);
if (pcap == NULL)
    {
    fprintf(stderr, "error reading pcap file: %s\n", errbuf);
    exit(1);
}
while ((packet = pcap_next(pcap, &header)) != NULL)
{
    struct ip_header *ip;
    unsigned int IP_header_length;
    packet += sizeof(struct ether_header);
    capture_len -= sizeof(struct ether_header);
    ip = (struct ip_header*) packet;
    IP_header_length = ip->vhl * 4; /* ip_hl is in 4-byte words */
    char *sinfo = strdup(inet_ntoa(ip->src));
    char *dinfo = strdup(inet_ntoa(ip->dst));
    printf ("%s<-__->%s\n", sinfo ,dinfo);
    free (sinfo);
    free (dinfo);
}

VLAN をチェックして正しくジャンプするには、コードのどこかにある必要があります。VLAN パケットと非 VLAN パケットを区別するにはどうすればよいですか?

4

1 に答える 1

1

(「ライブ」環境でこれをテストしている場合は、非トランキング回線に転送する前に、ルーターが 802.1q タグを削除できることを覚えておくことが重要です。)

特定のプラットフォームとプロトコルを念頭に置いている場合、これを行う最も速い方法は、常にフレームを「手動で」チェックすることです。

htonl( ((uint32_t)(ETH_P_8021Q) << 16U)
     | ((uint32_t)customer_tci & 0xFFFFU) ) T

ただし、BPF フィルターをコンパイルし、それらをパケットのストリームに適用するlibpcapための関数の形式で、移植可能でクリーンなパケット フィルターを提供します (ただし、オンザワイヤとオフライン フィルタリング)

このようにpcap_offline_filterして、コンパイルされた BPF フィルター ディレクティブを PCAP ファイルに適用するために使用できます。vlanここではフィルター式を使用しましたvlan or ip。より複雑なものが必要な場合は、ドキュメントを参照してください)

...

pcap_t *pcap;
char errbuf[PCAP_ERRBUF_SIZE];
const unsigned char *packet;
struct pcap_pkthdr header;
struct bpf_program fp; // Our filter expression
pcap = pcap_open_offline(argv[0], errbuf);
if (pcap == NULL) {
    fprintf(stderr, "error reading pcap file: %s\n", errbuf);
    exit(1);
}

// Compile a basic filter expression, you can exam
if (pcap_compile(pcap, &fp, "vlan", 0, net) == -1) {
    fprintf(stderr, "Couldn't parse filter %s: %s\n", filter_exp, pcap_geterr(handle));
    return 2;
}

while ((packet = pcap_next(pcap, &header) != NULL)
       && pcap_offline_filter(&fp, header, packet)) {
    struct ip_header *ip;
    unsigned int IP_header_length;
    packet += sizeof(struct ether_header);
    capture_len -= sizeof(struct ether_header);
    ip = (struct ip_header*) packet;
    IP_header_length = ip->vhl * 4; /* ip_hl is in 4-byte words */
    char *sinfo = strdup(inet_ntoa(ip->src));
    char *dinfo = strdup(inet_ntoa(ip->dst));
    printf ("%s<-__->%s\n", sinfo ,dinfo);
    free (sinfo);
    free (dinfo);
}

...
于 2016-09-25T20:43:00.110 に答える