动态 版块 发帖 消息 我的
小绿叶技术博客
小绿叶技术博客
小绿叶技术Lv154   
libpcap 统计 Nginx TCP 请求的 IP 地址     



#include <pcap.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>

// 定义一个全局的 IP 地址统计哈希表或数组
// 这里为了简单,我们使用一个简单的数组来模拟统计功能
#define MAX_IPS 10000 // 假设我们只统计这么多个不同的 IP 地址
int ip_counts[MAX_IPS]; // 用于存储每个 IP 地址的出现次数
int ip_index = 0; // 当前 IP 地址的索引

// 回调函数,每当 pcap_loop() 或 pcap_dispatch() 捕获一个包时,就会调用这个函数
void packet_handler(u_char *user, const struct pcap_pkthdr *pkthdr, const u_char *packet) {
    struct ip *ip_header = (struct ip *)(packet); // 指向 IP 头部的指针
    struct tcp *tcp_header = (struct tcp *)((u_char *)ip_header + ip_header->ip_hl * 4); // 指向 TCP 头部的指针
    
    // 检查是否为 TCP 包,并且目的端口是 Nginx 监听的端口(例如 80 或 443)
    if (ip_header->ip_p == IPPROTO_TCP && tcp_header->th_dport == htons(80)) {
        // 获取源 IP 地址
        struct in_addr src_ip = ip_header->ip_src;
        
        // 统计该 IP 地址的出现次数
        for (int i = 0; i < MAX_IPS; i++) {
            if (ip_counts[i] == 0) {
                // 如果 ip_counts[i] 为 0,表示尚未记录该 IP,进行记录
                ip_counts[i] = ntohl(src_ip.s_addr);
                break;
            } else if (ip_counts[i] == ntohl(src_ip.s_addr)) {
                // 如果已经记录过该 IP,则增加计数
                ip_counts[i]++;
                break;
            }
        }
    }
}

int main() {
    char errbuf[PCAP_ERRBUF_SIZE];
    pcap_t *handle;
    char *dev, *filter_exp;
    struct bpf_program fp;

    dev = pcap_lookupdev(errbuf);
    if (dev == NULL) {
        fprintf(stderr, "Couldn't find default device: %s\n", errbuf);
        exit(EXIT_FAILURE);
    }

    // 打开网络设备
    handle = pcap_open_live(dev, BUFSIZ, 1, 1000, errbuf);
    if (handle == NULL) {
        fprintf(stderr, "Couldn't open device %s: %s\n", dev, errbuf);
        exit(EXIT_FAILURE);
    }

    // 定义过滤表达式,这里我们只过滤 Nginx 监听的端口(例如 80)
    filter_exp = "tcp port 80";
    if (pcap_compile(handle, &fp, filter_exp, 0, PCAP_NETMASK_UNKNOWN) == -1) {
        fprintf(stderr, "Couldn't parse filter %s: %s\n", filter_exp, pcap_geterr(handle));
        exit(EXIT_FAILURE);
    }

    // 设置过滤器
    if (pcap_setfilter(handle, &fp) == -1) {
        fprintf(stderr, "Couldn't install filter %s: %s\n", filter_exp, pcap_geterr(handle));
        exit(EXIT_FAILURE);
    }

    // 开始捕获数据包
    pcap_loop(handle, 0, packet_handler, NULL);

    // 关闭 pcap 句柄
    pcap_close(handle);

    return 0;
}








 2  已被阅读了182次  楼主 2024-05-22 18:15:45
回复列表

回复:libpcap 统计 Nginx TCP 请求的 IP 地址

guest
登录之后更精彩~
Powered by HadSky 7.12.10
© 2015-2024 PuYueTian
您的IP:44.221.66.130,2024-06-20 13:49:33,Processed in 0.01693 second(s).
Powered by HadSky
小绿叶技术博客