文章目录
前言
libpcap库安装
环境:
centos 7.9
安装编译
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安装和使用。
关于博主
wx/qq:binary-monster/1113673178
CSDN:https://blog.csdn.net/qq1113673178
码云:https://gitee.com/shiver
Github: https://github.com/ShiverZm
个人博客:www.shiver.fun