C libpcap:如何查看标头/数据包中的内容?

发布于 2024-11-26 16:37:52 字数 1743 浏览 1 评论 0原文

我有以下 C 代码,用于分析端口 80 上的数据:

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


void callback(u_char *useless,const struct pcap_pkthdr* header,const u_char* packet){
    //How do I look inside the packet and the header????
    static int count = 1;
    fprintf(stdout,"%d, ",count);
    fflush(stdout);
    count++;
}
int main(void) {
    pcap_t *handle;                 /* Session handle */
    char dev[] = "eth0";            /* Device to sniff on */
    char errbuf[PCAP_ERRBUF_SIZE];  /* Error string */
    struct bpf_program fp;          /* The compiled filter expression */
    char filter_exp[] = "port 80";  /* The filter expression */
    bpf_u_int32 mask;               /* The netmask of our sniffing device */
    bpf_u_int32 net;                /* The IP of our sniffing device */

    if(pcap_lookupnet(dev,&net,&mask,errbuf)==-1){
        fprintf(stderr, "Can't get netmask for device %s\n", dev);
        net = 0;
        mask = 0;
    }
    handle = pcap_open_live(dev, BUFSIZ, 1, 1000, errbuf);
    if (handle == NULL) {
        fprintf(stderr, "Couldn't open device %s: %s\n", dev, errbuf);
        return(2);
    }
    if (pcap_compile(handle, &fp, filter_exp, 0, net) == -1) {
        fprintf(stderr, "Couldn't parse filter %s: %s\n", filter_exp, pcap_geterr(handle));
        return(2);
    }
    if (pcap_setfilter(handle, &fp) == -1) {
        fprintf(stderr, "Couldn't install filter %s: %s\n", filter_exp, pcap_geterr(handle));
        return(2);
    }

    /*Actual sniffing*/
    pcap_loop(handle,-1,callback,NULL);

    return 0;
}

我试图查看标头内部以获取源地址和目标地址。并尝试查看数据包内部以获取有效负载。我该怎么做呢?我在网上似乎找不到任何API。

预先非常感谢,

I have the following C code which is to be used for analysing data on port 80:

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


void callback(u_char *useless,const struct pcap_pkthdr* header,const u_char* packet){
    //How do I look inside the packet and the header????
    static int count = 1;
    fprintf(stdout,"%d, ",count);
    fflush(stdout);
    count++;
}
int main(void) {
    pcap_t *handle;                 /* Session handle */
    char dev[] = "eth0";            /* Device to sniff on */
    char errbuf[PCAP_ERRBUF_SIZE];  /* Error string */
    struct bpf_program fp;          /* The compiled filter expression */
    char filter_exp[] = "port 80";  /* The filter expression */
    bpf_u_int32 mask;               /* The netmask of our sniffing device */
    bpf_u_int32 net;                /* The IP of our sniffing device */

    if(pcap_lookupnet(dev,&net,&mask,errbuf)==-1){
        fprintf(stderr, "Can't get netmask for device %s\n", dev);
        net = 0;
        mask = 0;
    }
    handle = pcap_open_live(dev, BUFSIZ, 1, 1000, errbuf);
    if (handle == NULL) {
        fprintf(stderr, "Couldn't open device %s: %s\n", dev, errbuf);
        return(2);
    }
    if (pcap_compile(handle, &fp, filter_exp, 0, net) == -1) {
        fprintf(stderr, "Couldn't parse filter %s: %s\n", filter_exp, pcap_geterr(handle));
        return(2);
    }
    if (pcap_setfilter(handle, &fp) == -1) {
        fprintf(stderr, "Couldn't install filter %s: %s\n", filter_exp, pcap_geterr(handle));
        return(2);
    }

    /*Actual sniffing*/
    pcap_loop(handle,-1,callback,NULL);

    return 0;
}

I'm trying to look inside the header to get the source and destination address. And trying to look inside the packet to get the payload. How would I go about doing this? I can't seem to find any API online.

Many thanks in advance,

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

不爱素颜 2024-12-03 16:37:52

在你的回调函数中,你可以有这样的东西(假设在 Linux 上通过以太网 TCP/IP):

#include <netinet/ip.h>
#include <netinet/tcp.h>

const uint16_t ETHER_TYPE_IP = 0x0800;
const size_t ETHER_TYPE_OFFSET = 12;
const size_t ETHER_IP_OFFSET = 14;
const uint8_t IP_PROTO_TCP = 0x06;

uint16_t ether_type = ntohs(*((const uint16_t*) (packet + ETHER_TYPE_OFFSET)));

if (ether_type == ETHER_TYPE_IP) {
    const struct ip* ip_header = (const struct ip*) (packet + ETHER_IP_OFFSET);

    const unsigned char* ip_data = ((const unsigned char*) ip_header) + (ip_header->ip_hl << 2);
    uint16_t ip_data_len = ntohs(ip_header->ip_len) - (ip_header->ip_hl << 2);

    if (ip_header->ip_p == IP_PROTO_TCP) {
        const struct tcphdr* tcp_header = (const struct tcphdr*) ip_data;

        const unsigned char* data = ((const unsigned char*) tcp_header) + (tcp_header->doff << 2);
        uint16_t data_len = ip_data_len - (tcp_header->doff << 2);

        /* do something with the data here ... */
    }
}

In your callback function, you could have something like this (assuming TCP/IP over ethernet, on Linux) :

#include <netinet/ip.h>
#include <netinet/tcp.h>

const uint16_t ETHER_TYPE_IP = 0x0800;
const size_t ETHER_TYPE_OFFSET = 12;
const size_t ETHER_IP_OFFSET = 14;
const uint8_t IP_PROTO_TCP = 0x06;

uint16_t ether_type = ntohs(*((const uint16_t*) (packet + ETHER_TYPE_OFFSET)));

if (ether_type == ETHER_TYPE_IP) {
    const struct ip* ip_header = (const struct ip*) (packet + ETHER_IP_OFFSET);

    const unsigned char* ip_data = ((const unsigned char*) ip_header) + (ip_header->ip_hl << 2);
    uint16_t ip_data_len = ntohs(ip_header->ip_len) - (ip_header->ip_hl << 2);

    if (ip_header->ip_p == IP_PROTO_TCP) {
        const struct tcphdr* tcp_header = (const struct tcphdr*) ip_data;

        const unsigned char* data = ((const unsigned char*) tcp_header) + (tcp_header->doff << 2);
        uint16_t data_len = ip_data_len - (tcp_header->doff << 2);

        /* do something with the data here ... */
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文