快捷搜索:  汽车  科技

抓包服务器数据(基于WinPcap实现的RawEtherNet抓包)

抓包服务器数据(基于WinPcap实现的RawEtherNet抓包)  ① 右键工程属性-->VC 目录-->找到包含目录、库目录,把刚才的库文件路径和头文件的路径添加进去,如下图所示  工程创建完毕需要配置工程属性  ① 库文件:Packet.dll、Packet.lib、wpcap.dll、wpcap.lib   ② 头文件 三、用vs创建工程(我这里使用的是vs2015)

一、背景

二、WinPcap中文技术文档

  http://www.ferrisxu.com/WinPcap/html/index.html

二、需要使用到的动态库和外部头文件

  ① 库文件:Packet.dll、Packet.lib、wpcap.dll、wpcap.lib

抓包服务器数据(基于WinPcap实现的RawEtherNet抓包)(1)

  ② 头文件

抓包服务器数据(基于WinPcap实现的RawEtherNet抓包)(2)

三、用vs创建工程(我这里使用的是vs2015)

  工程创建完毕需要配置工程属性

  ① 右键工程属性-->VC 目录-->找到包含目录、库目录,把刚才的库文件路径和头文件的路径添加进去,如下图所示

抓包服务器数据(基于WinPcap实现的RawEtherNet抓包)(3)

  ② 找到链接器--->附加依赖项,添加Packet.lib、wpcap.lib库文件

抓包服务器数据(基于WinPcap实现的RawEtherNet抓包)(4)

四、示例代码

  ① 头文件

抓包服务器数据(基于WinPcap实现的RawEtherNet抓包)(5)

/***************************************************************************** * * * @file RawEtherSniffer.h * * @brief 通过原始以太网解析FPGA发送的数据 * * Details. * * * * @author jiang shuang * * @email * * @version 1.0.0.0(版本号) * * @date * * @license * * * *----------------------------------------------------------------------------* * Remark : Description * *----------------------------------------------------------------------------* * Change History : * * <Date> | <Version> | <Author> | <Description> * *----------------------------------------------------------------------------* * 2019/09/10 | 1.0.0.0 | jiangshuang | Create file * *----------------------------------------------------------------------------* * * *****************************************************************************/ #pragma once #define WIN32 #include <iostream> #include <stdio.h> #include <stdlib.h> #include <pcap.h> class RawEtherTools { public: RawEtherTools(); ~RawEtherTools(); /** * @brief 以太网数据数据帧嗅探器 * @input 无 * @output 无 * @return 无 */ void CaptureRawEtherFrame(); int ethernet_protocol_packet_handle(u_char *argument const struct pcap_pkthdr *packet_header const u_char *packet_content); };

抓包服务器数据(基于WinPcap实现的RawEtherNet抓包)(6)

  ② cpp文件

抓包服务器数据(基于WinPcap实现的RawEtherNet抓包)(7)

#define _CRT_SECURE_NO_WARNINGS #include "Tools.h" using namespace std; // 以太网协议格式的定义 typedef struct ether_header { u_char ether_dhost[6]; // 目标MAC地址 u_char ether_shost[6]; // 源MAC地址 u_short ether_type; // 以太网类型 }ether_header; // 用户保存4字节的IP地址 typedef struct ip_address { u_char byte1; u_char byte2; u_char byte3; u_char byte4; }ip_address; // 用于保存IPV4的首部 typedef struct ip_header { #ifdef WORDS_BIGENDIAN u_char ip_version : 4 header_length : 4; #else u_char header_length : 4 ip_version : 4; #endif u_char ver_ihl; // 版本以及首部长度,各4位 u_char tos; // 服务质量 u_short tlen; // 总长度 u_short identification; // 身份识别 u_short offset; // 分组偏移 u_char ttl; // 生命周期 u_char proto; // 协议类型 u_short checksum; // 包头测验码 ip_address saddr; // 源IP地址 ip_address daddr; // 目的IP地址 u_int op_pad; // 可选 填充字段 }ip_header; RawEtherTools::RawEtherTools() { } RawEtherTools::~RawEtherTools() { } /** * @brief * @input 无 * @output 无 * @return 无 */ void RawEtherTools::CaptureRawEtherFrame() { struct pcap_pkthdr *header; pcap_if_t * allDevs; pcap_if_t * dev; u_int netmask; int inum; int i = 0; int res; const u_char *pkt_data; time_t local_tv_sec; struct tm *ltime; char timestr[16]; ip_header *ih; char errbuf[PCAP_ERRBUF_SIZE]; if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING NULL &allDevs errbuf) > 0) { printf("pcap_findallDevs_ex failed\n"); } for (dev = allDevs; dev; dev = dev->next) { printf("%d. %s" i dev->name); if (dev->description) { printf("(%s)\n" dev->description); } else { printf("No description available\n"); } } if (0 == i) { printf("\nNo interface found!Make sure WinPcap is installed\n"); return; } printf("Enter the interface number(1-%d):" i); scanf_s("%d" &inum); if (inum < 1 || inum > i) { printf("\nInterface number out of range.\n"); pcap_freealldevs(allDevs); return; } for (dev = allDevs i = 0; i < inum - 1; dev = dev->next i ); pcap_t * handler; // 设备名,要捕捉的数据包的部分(65536保证能捕获到不同数据链路层上的每个数据包的全部内容),混杂模式,读取超时时间,错误缓冲池 if ((handler = pcap_open_live(dev->name 65536 1 1000 errbuf)) == NULL) { fprintf(stderr "\nUnable to open the adapter.%s is not supported by WinPcap\n" errbuf); pcap_freealldevs(allDevs); return; } // 检查数据链路层(只考虑了以太网) if (pcap_datalink(handler) != DLT_EN10MB) { fprintf(stderr "\nThis program works only on Ethernet networks.\n"); pcap_freealldevs(allDevs); return; } if (dev->addresses != NULL) { // 获得接口的第一个地址的掩码 netmask = ((struct sockaddr_in*)(dev->addresses->netmask))->sin_addr.S_un.S_addr; } else { netmask = 0xffffff; } while ((res = pcap_next_ex(handler &header &pkt_data)) >= 0) { // 请求超时 if (0 == res) { continue; } // 分析数据包 int ret = ethernet_protocol_packet_handle(NULL header pkt_data); if (ret == -1) continue; // 将时间戳转换成可识别的格式 local_tv_sec = header->ts.tv_sec; ltime = localtime(&local_tv_sec); strftime(timestr sizeof(timestr) "%H:%M:%S" ltime); ih = (ip_header *)(pkt_data 14); //以太网头部长度 // 输出时间和IP信息 //printf("%s.%.6d len:%d " timestr header->ts.tv_usec header->len); printf(" len:%d " header->len); printf("%d.%d.%d.%d -> %d.%d.%d.%d\n" ih->saddr.byte1 ih->saddr.byte2 ih->saddr.byte3 ih->saddr.byte4 ih->daddr.byte1 ih->daddr.byte2 ih->daddr.byte3 ih->daddr.byte4); printf("xxxx -> xxxx\n" ih->saddr.byte1 ih->saddr.byte2 ih->saddr.byte3 ih->saddr.byte4 ih->daddr.byte1 ih->daddr.byte2 ih->daddr.byte3 ih->daddr.byte4); //输出每个包的byte数据ws2_32.lib for (int k = 0; k < header->len; k ) { if (k % 16 == 0 && k != 0)//输出美观 printf("\n"); printf("x " *(pkt_data k)); } printf("\n"); } if (-1 == res) { printf("Error reading the packet:%s\n" pcap_geterr(handler)); return; } pcap_freealldevs(allDevs); } /** * @brief 抓取以太网协议包 * @input 无 * @output 无 * @return 无 */ int RawEtherTools::ethernet_protocol_packet_handle(u_char *argument const struct pcap_pkthdr *packet_header const u_char *packet_content) { u_short ethernet_type; // 以太网类型 struct ether_header *ethernet_protocol; // 以太网协议变量 u_char *mac_string; // 以太网地址 ethernet_protocol = (struct ether_header*)packet_content;// 获取以太网数据内容 ethernet_type = ntohs(ethernet_protocol->ether_type); // 获取以太网类型 if (ethernet_type != 0x00FF) { return -1; } printf("Ethernet type is : x\n" ethernet_type); // 获取以太网源地址 mac_string = ethernet_protocol->ether_shost; printf(" MAC Source Address is === x:x:x:x:x:x" *mac_string *(mac_string 1) *(mac_string 2) *(mac_string 3) *(mac_string 4) *(mac_string 5) ); // 获取以太网目的地址 mac_string = ethernet_protocol->ether_dhost; printf(" MAC Target Address === x:x:x:x:x:x\n" *mac_string *(mac_string 1) *(mac_string 2) *(mac_string 3) *(mac_string 4) *(mac_string 5) ); printf("%d" sizeof(packet_content)); return 0; }

抓包服务器数据(基于WinPcap实现的RawEtherNet抓包)(8)

  ③ Main.cpp

抓包服务器数据(基于WinPcap实现的RawEtherNet抓包)(9)

#include <iostream> #include "Tools.h" using namespace std; int main() { RawEtherTools *raw = new RawEtherTools(); raw->CaptureRawEtherFrame(); system("pause"); return 0; }

抓包服务器数据(基于WinPcap实现的RawEtherNet抓包)(10)

五、编译程序

  ① 错误1 编译程序报错,如下图所示

抓包服务器数据(基于WinPcap实现的RawEtherNet抓包)(11)

  解决办法:

    ws2_32.lib文件,提供了对以下网络相关API的支持,若使用其中的API,则应该将ws2_32.lib加入工程

    在工程属性--->链接器--->附加依赖项,添加ws2_32.lib库文件

抓包服务器数据(基于WinPcap实现的RawEtherNet抓包)(12)

  ② 错误2 编译程序报错,如下图所示

抓包服务器数据(基于WinPcap实现的RawEtherNet抓包)(13)

解决办法:    

1.error C3861: “pcap_findalldevs_ex”: 找不到标识符

2.error C2065: “PCAP_SRC_IF_STRING”: 未声明的标识符

在WinPcap编程调试解决办法 中,需要项目属性-》配置属性-》C/C -》预处理器-》预处理器定义中添加HAVE_REMOTE,方可编译成功。

猜您喜欢: