ToB企服应用市场:ToB评测及商务社交产业平台

标题: C/C++ 运用Npcap发送UDP数据包 [打印本页]

作者: 曂沅仴駦    时间: 2024-1-10 23:35
标题: C/C++ 运用Npcap发送UDP数据包
Npcap 是一个功能强大的开源网络抓包库,它是 WinPcap 的一个分支,并提供了一些增强和改进。特别适用于在 Windows 环境下进行网络流量捕获和分析。除了支持通常的网络抓包功能外,Npcap 还提供了对数据包的拼合与构造,使其成为实现 UDP 数据包发包的理想选择。本章将通过Npcap库构造一个UDP原始数据包,并实现对特定主机的发包功能,通过本章的学习读者可以掌握如何使用Npcap库伪造特定的数据包格式。
Npcap的主要特点和概述:
UDP 是一种无连接、轻量级的传输层协议,与 TCP 相比,它不提供可靠性、流控制和错误恢复机制,但却更加简单且具有较低的开销。UDP 主要用于那些对传输速度要求较高、可以容忍少量丢失的应用场景。
UDP 数据包结构: UDP 数据包由报头和数据两部分组成。
UDP 的特点:
UDP 的应用场景:
输出网卡

使用 WinPcap(Windows Packet Capture)库列举系统上的网络接口以及它们的 IP 地址。WinPcap 是一个用于 Windows 操作系统的网络数据包捕获库,可以用于网络数据包的捕获和分析。
代码主要做了以下几个事情:
pcap_findalldevs_ex 用于查找系统上所有网络接口的函数。它的原型如下:
  1. int pcap_findalldevs_ex(const char *source, struct pcap_rmtauth *auth, pcap_if_t **alldevs, char *errbuf);
复制代码
函数参数说明:
函数返回值:
函数功能:
pcap_findalldevs_ex 主要用于查找系统上的网络接口信息。当调用成功后,alldevs 将指向一个链表,链表中的每个节点都包含一个网络接口的信息。这个链表的头指针是 alldevs。
pcap_freealldevs 用于释放 pcap_findalldevs_ex 函数分配的资源的函数。其原型如下:
  1. void pcap_freealldevs(pcap_if_t *alldevs);
复制代码
函数参数说明:
函数功能:
pcap_freealldevs 主要用于释放 pcap_findalldevs_ex 函数返回的链表中分配的资源,包括每个节点和节点中保存的接口信息。
输出当前系统中活动网卡信息,可以这样来写,如下代码所示;
  1. #include <WinSock2.h>
  2. #include <Windows.h>
  3. #include <iostream>
  4. #include <pcap.h>
  5. #pragma comment(lib,"ws2_32.lib")
  6. #pragma comment(lib, "packet.lib")
  7. #pragma comment(lib, "wpcap.lib")
  8. // 打开网卡返回的指针
  9. pcap_t* m_adhandle;
  10. unsigned char* FinalPacket;
  11. unsigned int UserDataLen;
  12. int main(int argc, char *argv[])
  13. {
  14.         // 打开网卡
  15.         pcap_if_t* alldevs = NULL, *d = NULL;
  16.         char szErr[MAX_PATH] = { 0 };
  17.         if (-1 == pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, szErr))
  18.         {
  19.                 return 0;
  20.         }
  21.         // 遍历网卡
  22.         char* lpszIP = NULL;
  23.         d = alldevs;
  24.         while (NULL != d)
  25.         {
  26.                 // 遍历网卡IP
  27.                 char szAddress[1024] = { 0 };
  28.                 pcap_addr_t* p = d->addresses;
  29.                 while (p)
  30.                 {
  31.                         lpszIP = inet_ntoa(((sockaddr_in*)p->addr)->sin_addr);
  32.                         strcpy(szAddress, lpszIP);
  33.                         p = p->next;
  34.                 }
  35.                 std::cout << "地址列表: " << szAddress << std::endl;
  36.                 d = d->next;
  37.         }
  38.         // 释放资源
  39.         flags
  40.         system("pause");
  41.         return 0;
  42. }
复制代码
获取匹配网卡的子网掩码。
打开网卡:
  1. if (-1 == pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf))
复制代码
使用 pcap_open 函数打开选择的网卡,该函数的声明如下:
  1. for (d = alldevs; d; d = d->next)
复制代码
这里是对参数的简要解释:
函数返回一个 pcap_t 类型的指针,它是一个表示打开的网络适配器的结构。如果打开失败,返回 NULL。
检查以太网:
  1. m_adhandle = pcap_open(d->name, 65536, PCAP_OPENFLAG_PROMISCUOUS, 1000, NULL, errbuf);
复制代码
pcap_datalink 函数是 PCAP 库中用于获取网络适配器数据链路类型(datalink type)的函数,确保是以太网,如果不是以太网,输出错误信息并返回。
该函数的声明如下:
  1. pcap_t *pcap_open(const char *source, int snaplen, int flags, int read_timeout, struct pcap_rmtauth *auth, char *errbuf);
复制代码
这里是对参数的简要解释:
函数返回一个整数,表示数据链路类型。这个值通常是预定义的常量之一,用于标识不同类型的网络数据链路。
常见的一些数据链路类型常量包括:
释放网卡设备列表:
  1. flags
复制代码
最后,释放 pcap_findalldevs_ex 函数返回的网卡设备列表,避免内存泄漏。
该函数的其他全局变量 m_adhandle,FinalPacket,UserDataLen 已经在文章开头声明和定义。
[code]// 通过传入本机IP地址打开网卡void OpenAdapter(std::string local_address){  pcap_if_t* alldevs = NULL, * d = NULL;  char errbuf[256] = { 0 };  bpf_program fcode;  u_int netmask;  // 获取网卡设备指针  if (-1 == pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf))  {    std::cout addresses;    while (p)    {      if (local_address == inet_ntoa(((sockaddr_in*)p->addr)->sin_addr))      {        flag = 1;        break;      }      p = p->next;    }    if (1 == flag)      break;  }  if (0 == flag)  {    std::cout name, 65536, PCAP_OPENFLAG_PROMISCUOUS, 1000, NULL, errbuf);  if (NULL == m_adhandle)  {    std::cout




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4