c++实现linux tcpdump功能

在 Linux 中,可以使用套接字(socket)和 libpcap 库来实现类似 tcpdump 的功能。libpcap 库提供了捕获网络数据包的接口,而使用套接字则可以将捕获到的数据包发送到指定目的地。

下面是一个简单的使用 C++ 和 libpcap 库实现 tcpdump 功能的示例代码:

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

void packet_callback(u_char *user, const struct pcap_pkthdr *header, const u_char *packet)
{
    // 获取 IP 报文头
    const struct iphdr* ip_header = (struct iphdr*)(packet + sizeof(struct ethhdr));

    // 判断是否为 TCP 报文
    if (ip_header->protocol == IPPROTO_TCP)
    {
        // 获取 TCP 报文头
        const struct tcphdr* tcp_header = (struct tcphdr*)(packet + sizeof(struct ethhdr) + sizeof(struct iphdr));

        // 打印源地址、目标地址和目标端口
        std::cout << "Source: " << inet_ntoa(*(in_addr*)&ip_header->saddr);
        std::cout << " Destination: " << inet_ntoa(*(in_addr*)&ip_header->daddr);
        std::cout << " Port: " << ntohs(tcp_header->dest) << std::endl;
    }
}

int main(int argc, char* argv[])
{
    char errbuf[PCAP_ERRBUF_SIZE];

    if (argc < 2)
    {
        std::cerr << "Usage: " << argv[0] << " <interface>" << std::endl;
        return 1;
    }

    pcap_t* handle = pcap_open_live(argv[1], BUFSIZ, 1, 1000, errbuf);
    if (handle == nullptr)
    {
        std::cerr << "pcap_open_live() failed: " << errbuf << std::endl;
        return 1;
    }

    // 过滤 TCP 报文
    struct bpf_program tcp_filter;
    if (pcap_compile(handle, &tcp_filter, "tcp", 0, 0) == -1)
    {
        std::cerr << "pcap_compile failed: " << pcap_geterr(handle) << std::endl;
        return 1;
    }
    if (pcap_setfilter(handle, &tcp_filter) == -1)
    {
        std::cerr << "pcap_setfilter failed: " << pcap_geterr(handle) << std::endl;
        return 1;
    }

    // 捕获网络数据包并输出
    pcap_loop(handle, -1, packet_callback, nullptr);

    pcap_close(handle);
    return 0;
}

在上面的代码中,我们使用了 libpcap 库提供的 pcap_open_live 函数打开指定网卡的捕获接口,并使用 pcap_loop 函数循环捕获网络数据包。每当有数据包到达时,回调函数 packet_callback 将被调用,可以在该回调函数中对数据包进行处理。

packet_callback 函数中,我们首先通过偏移量获取 IP 报文头和 TCP 报文头,然后判断是否为 TCP 报文。如果是,我们将打印源地址、目标地址和目标端口等信息。

在程序中,我们使用了 pcap_compilepcap_setfilter 函数来设置过滤器,只捕获 TCP 报文。这样可以避免无用的数据包干扰分析结果。

猜你喜欢

转载自blog.csdn.net/CarryMee/article/details/130689309