[笔记] libpcap编译及使用


前言

官网

libpcap库安装

环境:
centos 7.9

安装编译

libpcap 下载

tar -zxvf libpcap-1.10.4
cd libpcap-1.10.4 
./configure
make && make install

./configure 时 报错:Neither flex nor lex was found

yum install flex lex

libpcap库使用

https://www.tcpdump.org/pcap.html

此处实现的是抓tcp syn包

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

void packetHandler(unsigned char* userData, const struct pcap_pkthdr* pkthdr, const unsigned char* packetData) {
    struct ethhdr* ethHeader = (struct ethhdr*)packetData;

    if (ntohs(ethHeader->h_proto) == ETH_P_IP) {
        struct iphdr* ipHeader = (struct iphdr*)(packetData + sizeof(struct ethhdr));

        if (ipHeader->protocol == IPPROTO_TCP) {
            struct tcphdr* tcpHeader = (struct tcphdr*)(packetData + sizeof(struct ethhdr) + ipHeader->ihl * 4);
            if (tcpHeader->syn) {
                char source_ip[INET_ADDRSTRLEN];
                char dest_ip[INET_ADDRSTRLEN];
                inet_ntop(AF_INET, &ipHeader->saddr, source_ip, INET_ADDRSTRLEN);
                inet_ntop(AF_INET, &ipHeader->daddr, dest_ip, INET_ADDRSTRLEN);
                printf("Received TCP SYN packet from %s:%u to %s:%u\n",
                        source_ip, ntohs(tcpHeader->source),
                        dest_ip, ntohs(tcpHeader->dest));
            }
        }
    }
}

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

	dev = pcap_lookupdev(errbuf);
	if (dev == NULL) {
		fprintf(stderr, "Couldn't find default device: %s\n", errbuf);
		return(2);
	}
	printf("Device: %s\n", dev);
	return(0);
}

int main3() {
    char errbuf[PCAP_ERRBUF_SIZE];
    pcap_if_t* alldevs;
    pcap_if_t* device;

    // 获取系统上的所有网络设备
    if (pcap_findalldevs(&alldevs, errbuf) == -1) {
        std::cerr << "Error finding devices: " << errbuf << std::endl;
        return 1;
    }

    // 遍历并打印设备列表
    int deviceCount = 0;
    for (device = alldevs; device != nullptr; device = device->next) {
        deviceCount++;
        std::cout << "Device " << deviceCount << ": " << device->name << std::endl;
        if (device->description)
            std::cout << "    Description: " << device->description << std::endl;
        else
            std::cout << "    Description: N/A" << std::endl;
    }

    // 释放设备列表
    pcap_freealldevs(alldevs);

    return 0;
}

int main() {
    char errbuf[PCAP_ERRBUF_SIZE];
    pcap_t* handle;

    // 打开网络设备或捕获文件,这里使用默认网络设备 "eth0",你需要根据实际情况修改
    handle = pcap_open_live("ens33", BUFSIZ, 1, 1000, errbuf);

    if (handle == nullptr) {
        std::cerr << "Error opening device: " << errbuf << std::endl;
        return 1;
    }

    // 开始捕获数据包,packetHandler 是回调函数,每捕获一个数据包都会调用它
    if (pcap_loop(handle, 0, packetHandler, nullptr) < 0) {
        std::cerr << "Error in pcap_loop" << std::endl;
        return 1;
    }

    // 关闭捕获会话
    pcap_close(handle);

    return 0;
}

注意:
使用vscode,c++ debug时 链接pcap库 g++执行加“-lpcap“
并且 加 “-std=gnu++0x” 避免c++11特性不支持报错

常见错误码

/usr/local/include/pcap/pcap.h

#define PCAP_ERROR			-1	/* generic error code */
#define PCAP_ERROR_BREAK		-2	/* loop terminated by pcap_breakloop */
#define PCAP_ERROR_NOT_ACTIVATED	-3	/* the capture needs to be activated */
#define PCAP_ERROR_ACTIVATED		-4	/* the operation can't be performed on already activated captures */
#define PCAP_ERROR_NO_SUCH_DEVICE	-5	/* no such device exists */
#define PCAP_ERROR_RFMON_NOTSUP		-6	/* this device doesn't support rfmon (monitor) mode */
#define PCAP_ERROR_NOT_RFMON		-7	/* operation supported only in monitor mode */
#define PCAP_ERROR_PERM_DENIED		-8	/* no permission to open the device */
#define PCAP_ERROR_IFACE_NOT_UP		-9	/* interface isn't up */
#define PCAP_ERROR_CANTSET_TSTAMP_TYPE	-10	/* this device doesn't support setting the time stamp type */
#define PCAP_ERROR_PROMISC_PERM_DENIED	-11	/* you don't have permission to capture in promiscuous mode */
#define PCAP_ERROR_TSTAMP_PRECISION_NOTSUP -12  /* the requested time stamp precision is not supported */

常见问题

一、pcap_open_live 指定网卡为"any" 对应的packet_content会得到

在这里插入图片描述
在这里插入图片描述

对比指定网卡的内容为:
在这里插入图片描述
主要区别就是

  • any网卡数据包为非标准Linux cooked capture v1,而指定网卡名的数据包为标准Ethernet II,所以解析数据包的方式是不同的要注意。

总结

以上就是今天要讲的内容,本文仅仅简单介绍了libpcap安装和使用。

参考:
libpcap库使用
libpcap简单使用


关于博主

wx/qq:binary-monster/1113673178
CSDN:https://blog.csdn.net/qq1113673178
码云:https://gitee.com/shiver
Github: https://github.com/ShiverZm
个人博客:www.shiver.fun

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

二进制怪兽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值