您的位置:首页 > 理论基础 > 计算机网络

网络编程系列之六 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(),这个扩展表现在参数上,从上面可以看出来,前面两个参数是增加的,那么这个增加的参数就使打开查找远端网卡成为可能

下面是最简单的函数示例:

#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在系统中竟然没有找到, 有找到的请告知一下, 多谢。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: