基于WinPcap实现的Raw EtherNet 抓包、发包程序
suiw9 2024-11-17 01:39 18 浏览 0 评论
一、背景
二、WinPcap中文技术文档
http://www.ferrisxu.com/WinPcap/html/index.html
二、需要使用到的动态库和外部头文件
① 库文件:Packet.dll、Packet.lib、wpcap.dll、wpcap.lib
② 头文件
三、用vs创建工程(我这里使用的是vs2015)
工程创建完毕需要配置工程属性
① 右键工程属性-->VC++目录-->找到包含目录、库目录,把刚才的库文件路径和头文件的路径添加进去,如下图所示
② 找到链接器--->附加依赖项,添加Packet.lib、wpcap.lib库文件
四、示例代码
① 头文件
/***************************************************************************** * *
* @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);
};
② cpp文件
#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("%02x%02x%02x%02x -> %02x%02x%02x%02x\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("%02x ", *(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 : %04x\n", ethernet_type);
// 获取以太网源地址
mac_string = ethernet_protocol->ether_shost;
printf(" MAC Source Address is === %02x:%02x:%02x:%02x:%02x:%02x",
*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 === %02x:%02x:%02x:%02x:%02x:%02x\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;
}
③ Main.cpp
#include <iostream>
#include "Tools.h"
using namespace std;
int main()
{
RawEtherTools *raw = new RawEtherTools();
raw->CaptureRawEtherFrame();
system("pause");
return 0;
}
五、编译程序
① 错误1 编译程序报错,如下图所示
解决办法:
ws2_32.lib文件,提供了对以下网络相关API的支持,若使用其中的API,则应该将ws2_32.lib加入工程
在工程属性--->链接器--->附加依赖项,添加ws2_32.lib库文件
② 错误2 编译程序报错,如下图所示
解决办法:
1.error C3861: “pcap_findalldevs_ex”: 找不到标识符
2.error C2065: “PCAP_SRC_IF_STRING”: 未声明的标识符
在WinPcap编程调试解决办法 中,需要项目属性-》配置属性-》C/C++-》预处理器-》预处理器定义中添加HAVE_REMOTE,方可编译成功。
相关推荐
- 俄罗斯的 HTTPS 也要被废了?(俄罗斯网站关闭)
-
发布该推文的ScottHelme是一名黑客,SecurityHeaders和ReportUri的创始人、Pluralsight作者、BBC常驻黑客。他表示,CAs现在似乎正在停止为俄罗斯域名颁发...
- 如何强制所有流量使用 HTTPS一网上用户
-
如何强制所有流量使用HTTPS一网上用户使用.htaccess强制流量到https的最常见方法可能是使用.htaccess重定向请求。.htaccess是一个简单的文本文件,简称为“.h...
- https和http的区别(https和http有何区别)
-
“HTTPS和HTTP都是数据传输的应用层协议,区别在于HTTPS比HTTP安全”。区别在哪里,我们接着往下看:...
- 快码住!带你十分钟搞懂HTTP与HTTPS协议及请求的区别
-
什么是协议?网络协议是计算机之间为了实现网络通信从而达成的一种“约定”或“规则”,正是因为这个“规则”的存在,不同厂商的生产设备、及不同操作系统组成的计算机之间,才可以实现通信。简单来说,计算机与网络...
- 简述HTTPS工作原理(简述https原理,以及与http的区别)
-
https是在http协议的基础上加了一层SSL(由网景公司开发),加密由ssl实现,它的目的是为用户提供对网站服务器的身份认证(需要CA),以至于保护交换数据的隐私和完整性,原理如图示。1、客户端发...
- 21、HTTPS 有几次握手和挥手?HTTPS 的原理什么是(高薪 常问)
-
HTTPS是3次握手和4次挥手,和HTTP是一样的。HTTPS的原理...
- 一次安全可靠的通信——HTTPS原理
-
为什么HTTPS协议就比HTTP安全呢?一次安全可靠的通信应该包含什么东西呢,这篇文章我会尝试讲清楚这些细节。Alice与Bob的通信...
- 为什么有的网站没有使用https(为什么有的网站点不开)
-
有的网站没有使用HTTPS的原因可能涉及多个方面,以下是.com、.top域名的一些见解:服务器性能限制:HTTPS使用公钥加密和私钥解密技术,这要求服务器具备足够的计算能力来处理加解密操作。如果服务...
- HTTPS是什么?加密原理和证书。SSL/TLS握手过程
-
秘钥的产生过程非对称加密...
- 图解HTTPS「转」(图解http 完整版 彩色版 pdf)
-
我们都知道HTTPS能够加密信息,以免敏感信息被第三方获取。所以很多银行网站或电子邮箱等等安全级别较高的服务都会采用HTTPS协议。...
- HTTP 和 HTTPS 有何不同?一文带你全面了解
-
随着互联网时代的高速发展,Web服务器和客户端之间的安全通信需求也越来越高。HTTP和HTTPS是两种广泛使用的Web通信协议。本文将介绍HTTP和HTTPS的区别,并探讨为什么HTTPS已成为We...
- HTTP与HTTPS的区别,详细介绍(http与https有什么区别)
-
HTTP与HTTPS介绍超文本传输协议HTTP协议被用于在Web浏览器和网站服务器之间传递信息,HTTP协议以明文方式发送内容,不提供任何方式的数据加密,如果攻击者截取了Web浏览器和网站服务器之间的...
- 一文让你轻松掌握 HTTPS(https详解)
-
一文让你轻松掌握HTTPS原文作者:UC国际研发泽原写在最前:欢迎你来到“UC国际技术”公众号,我们将为大家提供与客户端、服务端、算法、测试、数据、前端等相关的高质量技术文章,不限于原创与翻译。...
- 如何在Spring Boot应用程序上启用HTTPS?
-
HTTPS是HTTP的安全版本,旨在提供传输层安全性(TLS)[安全套接字层(SSL)的后继产品],这是地址栏中的挂锁图标,用于在Web服务器和浏览器之间建立加密连接。HTTPS加密每个数据包以安全方...
- 一文彻底搞明白Http以及Https(http0)
-
早期以信息发布为主的Web1.0时代,HTTP已可以满足绝大部分需要。证书费用、服务器的计算资源都比较昂贵,作为HTTP安全扩展的HTTPS,通常只应用在登录、交易等少数环境中。但随着越来越多的重要...
你 发表评论:
欢迎- 一周热门
-
-
Linux:Ubuntu22.04上安装python3.11,简单易上手
-
宝马阿布达比分公司推出独特M4升级套件,整套升级约在20万
-
MATLAB中图片保存的五种方法(一)(matlab中保存图片命令)
-
别再傻傻搞不清楚Workstation Player和Workstation Pro的区别了
-
Linux上使用tinyproxy快速搭建HTTP/HTTPS代理器
-
如何提取、修改、强刷A卡bios a卡刷bios工具
-
Element Plus 的 Dialog 组件实现点击遮罩层不关闭对话框
-
日本组合“岚”将于2020年12月31日停止团体活动
-
SpringCloud OpenFeign 使用 okhttp 发送 HTTP 请求与 HTTP/2 探索
-
tinymce 号称富文本编辑器世界第一,大家同意么?
-
- 最近发表
- 标签列表
-
- dialog.js (57)
- importnew (44)
- windows93网页版 (44)
- yii2框架的优缺点 (45)
- tinyeditor (45)
- qt5.5 (60)
- windowsserver2016镜像下载 (52)
- okhttputils (51)
- android-gif-drawable (53)
- 时间轴插件 (56)
- docker systemd (65)
- slider.js (47)
- android webview缓存 (46)
- pagination.js (59)
- loadjs (62)
- openssl1.0.2 (48)
- velocity模板引擎 (48)
- pcre library (47)
- zabbix微信报警脚本 (63)
- jnetpcap (49)
- pdfrenderer (43)
- fastutil (48)
- uinavigationcontroller (53)
- bitbucket.org (44)
- python websocket-client (47)