网络编程系列之六 pcap库拾遗与结构体
2015-07-30 14:27
537 查看
上篇文章把经常用到的libpcap库讲解了一遍和使用实例来验证。 现在来看看上一篇中遗漏的经常用到的函数:
1) pcap_next_ex (pcap_next增强版)
pcap_next_ex(pcap_t* p,struct pcap_pkthdr** pkt_header,const u_char** pkt_data)
函数释义:从一个设备接口,或从一个脱机文件中,读取一个数据包,第一个参数代表设备句柄,第二个参数代表包头,第三个参数代表数据.
一般就是对第三个参数进行处理。 如果是pcap_loop的话,回调函数中也有这里的第二个参数和第三个参数,也同样进行处理。
2) pcap_findalldevs_ex(pcap_findalldevs增强版)
int pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth, pcap_if_t **alldevs, char *errbuf);
遗憾的是在我的Centos系统当前开发环境中,没有找到扩展函数,只有pcap_findalldevs
函数释义:
创建一个网络设备列表,它们可以由 pcap_open()打开。对比pcap_findalldevs(),这个扩展表现在参数上,从上面可以看出来,前面两个参数是增加的,那么这个增加的参数就使打开查找远端网卡成为可能
下面是最简单的函数示例:
libpcap库设计到的经常用到的结构体如下:
1) pcap_next_ex (pcap_next增强版)
pcap_next_ex(pcap_t* p,struct pcap_pkthdr** pkt_header,const u_char** pkt_data)
函数释义:从一个设备接口,或从一个脱机文件中,读取一个数据包,第一个参数代表设备句柄,第二个参数代表包头,第三个参数代表数据.
一般就是对第三个参数进行处理。 如果是pcap_loop的话,回调函数中也有这里的第二个参数和第三个参数,也同样进行处理。
2) pcap_findalldevs_ex(pcap_findalldevs增强版)
int pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth, pcap_if_t **alldevs, char *errbuf);
遗憾的是在我的Centos系统当前开发环境中,没有找到扩展函数,只有pcap_findalldevs
函数释义:
创建一个网络设备列表,它们可以由 pcap_open()打开。对比pcap_findalldevs(),这个扩展表现在参数上,从上面可以看出来,前面两个参数是增加的,那么这个增加的参数就使打开查找远端网卡成为可能
下面是最简单的函数示例:
#include <stdio.h> #include <stdlib.h> #include <pcap.h> #include <arpa/inet.h> #define CAP_LEN 1024 int main() { char device[100] = {0}; //用来存放设备名 char ebuf[PCAP_ERRBUF_SIZE]; //错放错误信息 int cap_len = CAP_LEN; //捕获数据长度 int dev_flag = 1; //是否处于混杂模式 int dev_time = 1000; //设置超时时间 pcap_t *pd; //存放数据包捕获描述字 struct bpf_program fcode;// 存放捕获规则 pcap_if_t *alldevs; pcap_if_t *dev; //char *source; //struct pcap_rmtauth *auth; if(pcap_findalldevs(&alldevs, ebuf) == -1) printf("find devs error\n"); for(dev = alldevs; dev; dev = dev->next) { if( strcmp(dev->name,"eth0") == 0) { strcpy(device, dev->name); printf("device is %s\n",device); } printf("dev name is: %s\n", dev->name); } //获得捕获描述字 pd = pcap_open_live(device, cap_len,dev_flag,dev_time,ebuf); if(NULL == pd) printf("pcap_open_live error\n"); //设置过滤规则 if(pcap_compile(pd, &fcode, NULL,1, 0) < 0) printf("pcap_compile error\n"); //设置过滤器 if(pcap_setfilter(pd, &fcode) < 0) printf("pcap_setfilter error\n"); struct pcap_pkthdr *pkt_header; const u_char *pkt_data; while(pcap_next_ex(pd, &pkt_header, &pkt_data) > 0) { printf("a packet receive\n"); //对pkt_header 和 pkt_data进行数据处理。 主要是pkt_data,这是捕获的数据 continue; } //关闭资源 pcap_close(pd); return 0; }
libpcap库设计到的经常用到的结构体如下:
// 1) pcap_t struct pcap { int fd; /* 文件描述字,实际就是 socket */ /* 在 socket 上,可以使用 select() 和 poll() 等 I/O 复用类型函数 */ int selectable_fd; int snapshot; /* 用户期望的捕获数据包最大长度 */ int linktype; /* 设备类型 */ int tzoff; /* 时区位置,实际上没有被使用 */ int offset; /* 边界对齐偏移量 */ int break_loop; /* 强制从读数据包循环中跳出的标志 */ struct pcap_sf sf; /* 数据包保存到文件的相关配置数据结构 */ struct pcap_md md; /* 具体描述如下 */ int bufsize; /* 读缓冲区的长度 */ u_char buffer; /* 读缓冲区指针 */ u_char *bp; int cc; u_char *pkt; /* 相关抽象操作的函数指针,最终指向特定操作系统的处理函数 */ int (*read_op)(pcap_t *, int cnt, pcap_handler, u_char *); int (*setfilter_op)(pcap_t *, struct bpf_program *); int (*set_datalink_op)(pcap_t *, int); int (*getnonblock_op)(pcap_t *, char *); int (*setnonblock_op)(pcap_t *, int, char *); int (*stats_op)(pcap_t *, struct pcap_stat *); void (*close_op)(pcap_t *); /*如果 BPF 过滤代码不能在内核中执行,则将其保存并在用户空间执行 */ struct bpf_program fcode; /* 函数调用出错信息缓冲区 */ char errbuf[PCAP_ERRBUF_SIZE + 1]; /* 当前设备支持的、可更改的数据链路类型的个数 */ int dlt_count; /* 可更改的数据链路类型号链表,在 linux 下没有使用 */ int *dlt_list; /* 数据包自定义头部,对数据包捕获时间、捕获长度、真实长度进行描述 [pcap.h] */ struct pcap_pkthdr pcap_header; }; // 2) in_addr struct in_addr { in_addr_t s_addr; }; //结构体in_addr 用来表示一个32位的IPv4地址. //in_addr_t 一般为 32位的unsigned int,其字节顺序为网络顺序(network byte ordered),即该无符号整数采用大端字节序。 // 3)bpf_program 其实就是用来存放规则的结构体 struct bpf_program { u_int bf_len; struct bpf_insn *bf_insns; }; // 4)pcap_stat 用来计算数据包的统计信息,这些信息实际上是来自struct pcap struct pcap_stat { u_int ps_recv; /* number of packets received */ u_int ps_drop; /* number of packets dropped */ u_int ps_ifdrop; /* drops by interface -- only supported on some platforms */ }; // 5) pcap_if_t 用来存放网卡信息 struct pcap_if { struct pcap_if *next; char *name; /* name to hand to "pcap_open_live()" */ char *description; /* textual description of interface, or NULL */ struct pcap_addr *addresses; bpf_u_int32 flags; /* PCAP_IF_ interface flags */ }; // 6) pcap_pkthdr 存放捕获的数据包相关信息,包括时间戳和捕获的长度 struct pcap_pkthdr { struct timeval ts; /* time stamp */ bpf_u_int32 caplen; /* length of portion present */ bpf_u_int32 len; /* length this packet (off wire) */ }; //其中 pcap_dumper_t和pcap_handler在系统中竟然没有找到, 有找到的请告知一下, 多谢。
相关文章推荐
- httpWebRequest 文件下载
- 利用HttpWebRequest访问WebApi
- 网络中数据传输过程的分析
- 【转载】深入浅出http请求
- cmd (网络命令大全)
- 好霸气!Windows 10发布首日全球网络流量飙升35%
- Socket 通信原理(Android客户端和服务器以TCP UDP方式互通)
- $http
- Web Server 和 HTTP协议
- HTTP 和 HTTPS 协议
- 毕向东day23--java基础-网络总结
- HTTP状态码
- 【HttpClient4.5中文教程】【第一章 :基础】1.1执行请求(二)
- HttpClient 发送 HTTP、HTTPS 请求的简单封装
- SpringMVC 流程(4)-- HttpMessageConverter
- 使用genymotion和chares网络调试设置代理方法
- [Tool] Chrome内的本地网页,使用XMLHttpRequest读取本地档案
- 网络请求开源库volley和AsyncHttp的使用
- Xutils框架-HTTP源码详解
- HTTP协议中的GET和POST方法