2

dstとsrcのTCPポート番号を出力する簡単なアプリケーションを作成しようとしています。テストするために、ポート80との間でパケットをスニッフィングするためだけにpcapフィルターを適用しようとしました。しかし、すべてが正しいように見えても、ポート番号は0のままです。5桁のポート番号を取得する時間の約10%。誰かが私が間違っているかもしれないことについて私に何かヒントを与えることができますか?

#include<pcap.h>
#include<stdio.h>
#include<net/ethernet.h>
#include<netinet/ip.h>
#include<netinet/tcp.h>
#include<arpa/inet.h>

void handle_packet(u_char* args, const struct pcap_pkthdr* pkthdr, const u_char* p)
{
    struct iphdr* ip_hdr;
    struct tcphdr* tcp_hdr;

    ip_hdr = (struct iphdr*) (p+sizeof(struct ether_header));
    tcp_hdr = (struct tcphdr*) (ip_hdr+sizeof(struct iphdr));
    printf("src:%d\n", ntohs(tcp_hdr->source));
    printf("dst:%d\n", ntohs(tcp_hdr->dest));
}

int main(int argc, char** argv)
{
    pcap_t *handle;                /* Session handle */
    char *dev;                     /* The device to sniff on */
    char errbuf[PCAP_ERRBUF_SIZE]; /* Error string */
    struct bpf_program filter;     /* The compiled filter */
    char filter_app[] = "tcp port 80"; /* The filter expression */
    bpf_u_int32 mask;              /* Our netmask */
    bpf_u_int32 net;               /* Our IP */

    /* Define the device */
    dev = pcap_lookupdev(errbuf);

    /* Find the properties for the device */
    pcap_lookupnet(dev, &net, &mask, errbuf);

    /* Open the session in promiscuous mode */
    handle = pcap_open_live(dev, BUFSIZ, 0, 0, errbuf);

    /* Compile and apply the filter */
    pcap_compile(handle, &filter, filter_app, 0, net);
    pcap_setfilter(handle, &filter);

    pcap_loop(handle, 10, handle_packet, NULL);

    pcap_close(handle);
    return(0);
}
4

1 に答える 1

4

ここに2つの問題があります。1つは、Cのポインタ演算がスケーリングされることを覚えておいてください。だから、あなたが次のようなことを言うとき:

tcp_hdr = (struct tcphdr*) (ip_hdr+sizeof(struct iphdr));

実際、意図したよりもはるかに多くのバイトを進めています(sizeof(struct iphdr) * sizeof(struct iphdr)正確には)。あなたが望むことを達成するためにあなたは言うことができます:

tcp_hdr = (struct tcphdr*) &ip_hdr[1];

しかし、これも機能しません。IPヘッダーの長さは固定されていません。代わりに、ヘッダーのihlフィールドを確認する必要があり、計算は次のようになります。

tcp_hdr = (struct tcphdr*) ((char*)ip_hdr + 4*ip_hdr->ihl); /* ihl is the number of 32-bit words in the header */

警告:イーサネットフレームとそのヘッダーの長さが固定されているかどうかはわかりません。それも確認する必要があります。

于 2013-03-02T20:15:52.593 に答える