[笔记] winpcap编译及使用

简介: [笔记] winpcap编译及使用

前言

winpcap编译

winpcap官网

环境搭建

The last official WinPcap release was 4.1.3

For the list of changes, refer to the changelog.

Version 4.1.3 Installer for Windows

Driver + DLLs

使用

管理员权限双击运行\WpdPack\Examples-pcap\MakeaAll.sln

文件目录:WpdPack\Examples-pcap

  • UDPdump udp包抓取

BPF过滤器:

char packet_filter[] = "port 8080"; 爬取所有8080端口的数据包

#ifdef _MSC_VER
/*
 * we do not want the warnings about the old deprecated and unsecure CRT functions
 * since these examples can be compiled under *nix as well
 */
#define _CRT_SECURE_NO_WARNINGS
#endif
#include "pcap.h"
/* 4 bytes IP address */
typedef struct ip_address
{
  u_char byte1;
  u_char byte2;
  u_char byte3;
  u_char byte4;
}ip_address;
/* IPv4 header */
typedef struct ip_header
{
  u_char  ver_ihl;    // Version (4 bits) + Internet header length (4 bits)
  u_char  tos;      // Type of service 
  u_short tlen;     // Total length 
  u_short identification; // Identification
  u_short flags_fo;   // Flags (3 bits) + Fragment offset (13 bits)
  u_char  ttl;      // Time to live
  u_char  proto;      // Protocol
  u_short crc;      // Header checksum
  ip_address  saddr;    // Source address
  ip_address  daddr;    // Destination address
  u_int op_pad;     // Option + Padding
}ip_header;
/* UDP header*/
typedef struct udp_header
{
  u_short sport;      // Source port
  u_short dport;      // Destination port
  u_short len;      // Datagram length
  u_short crc;      // Checksum
}udp_header;
/* prototype of the packet handler */
void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data);
void got_packet(u_char* param, const struct pcap_pkthdr* header, const u_char* pkt_data);
int main()
{
  pcap_if_t *alldevs;
  pcap_if_t *d;
  int inum;
  int i=0;
  pcap_t *adhandle;
  char errbuf[PCAP_ERRBUF_SIZE];
  u_int netmask;
  char packet_filter[] = "port 8080";
  struct bpf_program fcode;
  /* Retrieve the device list */
  if(pcap_findalldevs(&alldevs, errbuf) == -1)
  {
    fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf);
    exit(1);
  }
  /* Print the list */
  for(d=alldevs; d; d=d->next)
  {
    printf("%d. %s", ++i, d->name);
    if (d->description)
      printf(" (%s)\n", d->description);
    else
      printf(" (No description available)\n");
  }
  if(i==0)
  {
    printf("\nNo interfaces found! Make sure WinPcap is installed.\n");
    return -1;
  }
  printf("Enter the interface number (1-%d):",i);
  scanf("%d", &inum);
  /* Check if the user specified a valid adapter */
  if(inum < 1 || inum > i)
  {
    printf("\nAdapter number out of range.\n");
    /* Free the device list */
    pcap_freealldevs(alldevs);
    return -1;
  }
  /* Jump to the selected adapter */
  for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++);
  /* Open the adapter */
  if ((adhandle= pcap_open_live(d->name,  // name of the device
               65536,     // portion of the packet to capture. 
                      // 65536 grants that the whole packet will be captured on all the MACs.
               1,       // promiscuous mode (nonzero means promiscuous)
               1000,      // read timeout
               errbuf     // error buffer
               )) == NULL)
  {
    fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n");
    /* Free the device list */
    pcap_freealldevs(alldevs);
    return -1;
  }
  /* Check the link layer. We support only Ethernet for simplicity. */
  if(pcap_datalink(adhandle) != DLT_EN10MB)
  {
    fprintf(stderr,"\nThis program works only on Ethernet networks.\n");
    /* Free the device list */
    pcap_freealldevs(alldevs);
    return -1;
  }
  if(d->addresses != NULL)
    /* Retrieve the mask of the first address of the interface */
    netmask=((struct sockaddr_in *)(d->addresses->netmask))->sin_addr.S_un.S_addr;
  else
    /* If the interface is without addresses we suppose to be in a C class network */
    netmask=0xffffff; 
  //compile the filter
  if (pcap_compile(adhandle, &fcode, packet_filter, 1, netmask) <0 )
  {
    fprintf(stderr,"\nUnable to compile the packet filter. Check the syntax.\n");
    /* Free the device list */
    pcap_freealldevs(alldevs);
    return -1;
  }
  //set the filter
  if (pcap_setfilter(adhandle, &fcode)<0)
  {
    fprintf(stderr,"\nError setting the filter.\n");
    /* Free the device list */
    pcap_freealldevs(alldevs);
    return -1;
  }
  printf("\nlistening on %s...\n", d->description);
  /* At this point, we don't need any more the device list. Free it */
  pcap_freealldevs(alldevs);
  /* start the capture */
  //pcap_loop(adhandle, 0, packet_handler, NULL);
  pcap_loop(adhandle, 0, got_packet, NULL);
  return 0;
}
/* Callback function invoked by libpcap for every incoming packet */
void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data)
{
  struct tm *ltime;
  char timestr[16];
  ip_header *ih;
  udp_header *uh;
  u_int ip_len;
  u_short sport,dport;
  time_t local_tv_sec;
  /*
   * unused parameter
   */
  (VOID)(param);
  /* convert the timestamp to readable format */
  local_tv_sec = header->ts.tv_sec;
  ltime=localtime(&local_tv_sec);
  strftime( timestr, sizeof timestr, "%H:%M:%S", ltime);
  /* print timestamp and length of the packet */
  printf("%s.%.6d len:%d ", timestr, header->ts.tv_usec, header->len);
  /* retireve the position of the ip header */
  ih = (ip_header *) (pkt_data +
    14); //length of ethernet header
  /* retireve the position of the udp header */
  ip_len = (ih->ver_ihl & 0xf) * 4;
  uh = (udp_header *) ((u_char*)ih + ip_len);
  /* convert from network byte order to host byte order */
  sport = ntohs( uh->sport );
  dport = ntohs( uh->dport );
  /* print ip addresses and udp ports */
  printf("%d.%d.%d.%d.%d -> %d.%d.%d.%d.%d\n",
    ih->saddr.byte1,
    ih->saddr.byte2,
    ih->saddr.byte3,
    ih->saddr.byte4,
    sport,
    ih->daddr.byte1,
    ih->daddr.byte2,
    ih->daddr.byte3,
    ih->daddr.byte4,
    dport);
}
/* Ethernet header */
struct ethheader {
  u_char  ether_dhost[6];    /* destination host address */
  u_char  ether_shost[6];    /* source host address */
  u_short ether_type;                     /* IP? ARP? RARP? etc */
};
/* IP Header */
struct ipheader {
  unsigned char      iph_ihl : 4, iph_ver : 4; //IP Header length & Version.
  unsigned char      iph_tos; //Type of service
  unsigned short int iph_len; //IP Packet length (Both data and header)
  unsigned short int iph_ident; //Identification
  unsigned short int iph_flag : 3, iph_offset : 13; //Flags and Fragmentation offset
  unsigned char      iph_ttl; //Time to Live
  unsigned char      iph_protocol; //Type of the upper-level protocol
  unsigned short int iph_chksum; //IP datagram checksum
  struct  in_addr    iph_sourceip; //IP Source address (In network byte order)
  struct  in_addr    iph_destip;//IP Destination address (In network byte order)
};
/* TCP Header */
struct tcpheader {
  u_short tcp_sport;               /* source port */
  u_short tcp_dport;               /* destination port */
  u_int   tcp_seq;                 /* sequence number */
  u_int   tcp_ack;                 /* acknowledgement number */
  u_char  tcp_offx2;               /* data offset, rsvd */
#define TH_OFF(th)      (((th)->tcp_offx2 & 0xf0) >> 4)
  u_char  tcp_flags;
#define TH_FIN  0x01
#define TH_SYN  0x02
#define TH_RST  0x04
#define TH_PUSH 0x08
#define TH_ACK  0x10
#define TH_URG  0x20
#define TH_ECE  0x40
#define TH_CWR  0x80
#define TH_FLAGS        (TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG|TH_ECE|TH_CWR)
  u_short tcp_win;                 /* window */
  u_short tcp_sum;                 /* checksum */
  u_short tcp_urp;                 /* urgent pointer */
};
void got_packet(u_char* args, const struct pcap_pkthdr* header, const u_char* packet)
{
  int i = 0;
  int size_data = 0;
  printf("\nGot a packet\n");
  struct ethheader* eth = (struct ethheader*)packet;
  if (ntohs(eth->ether_type) == 0x800)
  {
    struct ipheader* ip = (struct ipheader*)(packet + sizeof(struct ethheader));
    printf("  From: %s\n", inet_ntoa(ip->iph_sourceip));
    printf("  To: %s\n", inet_ntoa(ip->iph_destip));
    struct tcpheader* tcp = (struct tcpheader*)(packet + sizeof(struct ethheader) + sizeof(struct ipheader));
    printf("  Source Port: %d\n", ntohs(tcp->tcp_sport));
    printf("  Destination Port: %d\n", ntohs(tcp->tcp_dport));
    switch (ip->iph_protocol) {
    case IPPROTO_TCP:
      printf("  Protocol: TCP\n");
      break;
    case IPPROTO_UDP:
      printf("  Protocol: UDP\n");
      break;
    case IPPROTO_ICMP:
      printf("  Protocol: ICMP\n");
      break;
    default:
      printf("  Protocol: Others\n");
      break;
    }
    //char* data = (char*)packet + sizeof(struct ethheader) + sizeof(struct ipheader) + sizeof(struct tcpheader);
    //size_data = ntohs(ip->iph_len) - (sizeof(struct ipheader) + sizeof(struct tcpheader));
    //if (size_data > 0) {
    //  printf("   Payload (%d bytes):\n", size_data);
    //  for (i = 0; i < size_data; i++) {
    //    if (isprint(*data))
    //      printf("%c", *data);
    //    else
    //      printf(".");
    //    data++;
    //  }
    //}
  }
  return;
}

总结

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

参考:

Visual Studio 配置Winpcap环境 详细)

https://blog.csdn.net/zhaoxinfan/article/details/6527454

https://blog.csdn.net/yz_kintang/article/details/17228755

https://blog.csdn.net/wqwqh/article/details/105836190#

相关文章
|
Web App开发 存储 缓存
RDMA优化整理(一)
简要的介绍了下RDMA的背景,并给出了一些RDMA编程优化技巧
5387 1
RDMA优化整理(一)
|
监控 编译器 API
[笔记]Windows核心编程《二十二》注入DLL和拦截API(一)
[笔记]Windows核心编程《二十二》注入DLL和拦截API
858 0
|
3月前
|
缓存 网络协议 网络安全
Notion 图片无法查看?一分钟修复的完整实录
本文提供Notion国内访问卡顿、图片转圈/裂图/空白的合法本地解决方案。聚焦DNS解析慢、国际出口拥塞等根因,详解通过修改Hosts文件指定最优IP(如119.28.13.121)加速www.notion.so等关键域名,并附Windows操作避坑指南、一键脚本及排错清单。
875 0
|
自然语言处理 测试技术 开发工具
通义灵码上下文能力解析:自由组合需求描述,生成结果更高效
通义灵码提供智能会话能力,支持智能问答、文件编辑和智能体三种模式,帮助开发者解决编码问题,进行代码修复、调试及运行错误排查。它具备多文件修改、自主决策等能力,可端到端完成编码任务。在智能会话中,支持丰富的上下文(如代码文件、目录、图片、Git Commit 等),并允许用户自由组合提示词与上下文。插件可通过链接下载。此外,还支持多种上下文类型(#file、#folder、#image 等),便于开发者精准表达需求。
1358 10
|
计算机视觉 网络架构
【YOLOv10改进-特征融合】YOLO-MS MSBlock : 分层特征融合策略
YOLOv10专栏介绍了YOLO-MS,一个优化多尺度目标检测的高效框架。YOLO-MS通过MS-Block和异构Kernel选择提升性能,平衡了计算复杂度与准确性。它在不依赖预训练的情况下,在COCO上超越同类模型,如YOLO-v7和RTMDet。MS-Block包含不同大小卷积的分支,用于增强特征表示。代码示例展示了MSBlock类的定义,用于处理不同尺度特征。该模块可应用于其他YOLO模型以提升性能。更多详情和配置参见相关链接。
|
数据采集 自然语言处理 搜索推荐
Python内置函数ord()详解
`ord()` 是 Python 中用于将单个字符转换为对应 Unicode 码点的核心函数,支持 ASCII、多语言字符及特殊符号。其返回值为整数(范围 0-1114111),适用于字符编码验证、数据清洗、自定义排序、基础加解密等场景。使用时需注意参数长度必须为 1,否则会触发 `TypeError`。结合 `chr()` 函数可实现双向转换,进阶技巧包括多字节字符处理、编码范围检测及字符分类验证等。
|
人工智能 NoSQL C语言
程序又崩了?一招精准定位段错误!
在C/C++开发中,程序崩溃(如段错误)是常见问题,但快速定位崩溃原因却颇具挑战。本文介绍了一种精准定位崩溃问题的方法:通过捕获异常信号(如SIGSEGV),结合`backtrace()`和`abi::__cxa_demangle()`打印堆栈信息,从而快速定位问题接口。相比增加日志或生成coredump文件,此方法更高效且无副作用。实现时需注意编译选项(如`-O0 -g -rdynamic`)以保留符号信息,并处理C++名称修饰问题。
1145 0
|
JSON Ubuntu 开发者
ubuntu 22安装lua环境&&编译lua cjson模块
通过上述步骤,可以在 Ubuntu 22.04 系统上成功安装 Lua 环境,并使用 LuaRocks 或手动编译的方式安装 lua-cjson 模块。本文详细介绍了每一步的命令和操作,确保每一步都能顺利完成,适合需要在 Ubuntu 系统上配置 Lua 开发环境的开发者参考和使用。
2261 13

热门文章

最新文章