您的位置:首页 > 数据库 > Oracle

Oracle查询语句的优化-记录一

2013-09-05 14:57 330 查看

1.4.2.3 pcap_activate_win32函数

[align=left]在函数pcap_create()中把p->activate_op操作句柄设为 pcap_activate_win32()函数。函数pcap_activate_win32()为激活捕捉实例做各种准备工作。[/align]
[align=left]函数的主要代码如下:[/align]

[align=left]static int pcap_activate_win32(pcap_t *p)[/align]

[align=left]{[/align]
[align=left] NetType type;[/align]
[align=left] [/align]
[align=left] /* 初始化WinSock*/[/align]
[align=left] wsockinit();[/align]
[align=left] [/align]
[align=left]/*调用packet.dll的函数PacketOpenAdapter()打开适配器*/[/align]
[align=left] p->adapter = PacketOpenAdapter(p->opt.source);[/align]
[align=left] [/align]
[align=left] if (p->adapter == NULL)[/align]
[align=left] {//错误,函数返回[/align]
[align=left] …[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] /*调用packet.dll的函数PacketGetNetType()获取网络类型*/[/align]
[align=left] if(PacketGetNetType (p->adapter,&type) == FALSE)[/align]
[align=left] {[/align]
[align=left] //错误,函数返回[/align]
[align=left] …[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] /*设置链路类型*/[/align]
[align=left] switch (type.LinkType) [/align]
[align=left] {[/align]
[align=left] case NdisMediumWan:[/align]
[align=left] p->linktype = DLT_EN10MB;[/align]
[align=left] break;[/align]
[align=left] [/align]
[align=left] case NdisMedium802_3:[/align]
[align=left] p->linktype = DLT_EN10MB;[/align]
[align=left] /*[/align]
[align=left] * 这大概是一个真正的以太网捕获;给它数据链路层类型链表设置为DLT_EN10MB与 DLT_DOCSIS,因此一个应用程序可以让你选择它的类型,以防万一正在捕获DOCSIS网络数据包,是由一个Cisco网线调制器终端系统发送到以太网上的(它不发送一个以太网协议头到线上,而是发送原始的DOCSIS数据帧到线上)。[/align]
[align=left] */[/align]
[align=left] p->dlt_list = (u_int *) malloc(sizeof(u_int) * 2);[/align]
[align=left] /*如果分配失败,仅留下空链表*/[/align]
[align=left] if (p->dlt_list != NULL) {[/align]
[align=left] p->dlt_list[0] = DLT_EN10MB;[/align]
[align=left] p->dlt_list[1] = DLT_DOCSIS;[/align]
[align=left] p->dlt_count = 2;[/align]
[align=left] }[/align]
[align=left] break;[/align]
[align=left] [/align]
[align=left] …[/align]
[align=left] [/align]
[align=left] default:[/align]
[align=left] p->linktype = DLT_EN10MB; /*一个未知的适配器假定为以太网适配器*/[/align]
[align=left] break;[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] /* 设置网络适配器的过滤模式为混杂模式*/[/align]
[align=left] if (p->opt.promisc) [/align]
[align=left] {//混杂模式[/align]
[align=left] if (PacketSetHwFilter(p->adapter,[/align]
[align=left]NDIS_PACKET_TYPE_PROMISCUOUS) == FALSE)[/align]
[align=left] {[/align]
[align=left] //错误,函数返回[/align]
[align=left] …[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left] else [/align]
[align=left] {//非混杂模式[/align]
[align=left] if (PacketSetHwFilter(p->adapter,[/align]
[align=left]NDIS_PACKET_TYPE_ALL_LOCAL) == FALSE)[/align]
[align=left] {[/align]
[align=left] //错误,函数返回[/align]
[align=left] …[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] /*设置pcap_t结构体中的缓冲区大小*/[/align]
[align=left] p->bufsize = WIN32_DEFAULT_USER_BUFFER_SIZE;[/align]
[align=left] [/align]
[align=left] /*分配在捕获过程中使用的数据包结构体*/[/align]
[align=left] if((p->Packet = PacketAllocatePacket())==NULL)[/align]
[align=left] {[/align]
[align=left] //错误,函数返回[/align]
[align=left] …[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] if(!(p->adapter->Flags & INFO_FLAG_DAG_CARD))[/align]
[align=left] {[/align]
[align=left] /* [/align]
[align=left] * 传统的适配器[/align]
[align=left] */[/align]
[align=left] /*[/align]
[align=left] * 如果缓冲区的大小不是显式的设定,默认为 WIN32_DEFAULT_USER_BUFFER_SIZE。[/align]
[align=left] */[/align]
[align=left] if (p->opt.buffer_size == 0)[/align]
[align=left] p->opt.buffer_size = WIN32_DEFAULT_KERNEL_BUFFER_SIZE;[/align]
[align=left] //设置内核NPF的缓冲区[/align]
[align=left] if(PacketSetBuff(p->adapter,p->opt.buffer_size)==FALSE)[/align]
[align=left] {[/align]
[align=left] //错误,函数返回[/align]
[align=left] …[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] p->buffer = (u_char *)malloc(p->bufsize);[/align]
[align=left] if (p->buffer == NULL) [/align]
[align=left] {[/align]
[align=left] //错误,函数返回[/align]
[align=left] …[/align]
[align=left] }[/align]
[align=left]/*初始化捕获过程中使用的数据包结构体*/[/align]
[align=left]PacketInitPacket(p->Packet,(BYTE*)p->buffer,p->bufsize);[/align]
[align=left] [/align]
[align=left] /* 告诉驱动程序 只有存储了至少16K的数据后,才能复制数据*/[/align]
[align=left] if(PacketSetMinToCopy(p->adapter,16000)==FALSE)[/align]
[align=left] {[/align]
[align=left] //错误,函数返回[/align]
[align=left] …[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] /*设置读取超时时间*/[/align]
[align=left] PacketSetReadTimeout(p->adapter, p->md.timeout);[/align]
[align=left] [/align]
[align=left]/*设置常规的NPF进行读取与设置过滤的操作句柄*/[/align]
[align=left] p->read_op = pcap_read_win32_npf;[/align]
[align=left] p->setfilter_op = pcap_setfilter_win32_npf;[/align]
[align=left] [/align]
[align=left] p->setdirection_op = NULL; /*没有实现*/[/align]
[align=left] [/align]
[align=left]p->inject_op = pcap_inject_win32;/* 发送单个数据包的操作*/[/align]
[align=left] p->set_datalink_op = NULL; /*不能改变数据链路层的类型*/[/align]
[align=left] p->getnonblock_op = pcap_getnonblock_win32;[/align]
[align=left] p->setnonblock_op = pcap_setnonblock_win32;[/align]
[align=left] p->stats_op = pcap_stats_win32;[/align]
[align=left] p->setbuff_op = pcap_setbuff_win32;[/align]
[align=left] p->setmode_op = pcap_setmode_win32;[/align]
[align=left] p->setmintocopy_op = pcap_setmintocopy_win32;[/align]
[align=left] p->cleanup_op = pcap_cleanup_win32;[/align]
[align=left] [/align]
[align=left] return (0);[/align]
[align=left]bad:[/align]
[align=left] pcap_cleanup_win32(p);[/align]
[align=left] return (PCAP_ERROR);[/align]

}

[align=left]函数首先调用wsockinit()函数初始化WinSock,然后调用packet.dll提供的函数PacketOpenAdapter()打开适配器。[/align]
[align=left]接着调用packet.dll提供的函数PacketGetNetType()获取网络类型。根据网络类型设置链路类型。此处我们只分析常规的以太网捕获。[/align]
接下来调用packet.dll提供的函数PacketSetHwFilter()设置网络适配器的过滤模式为混杂模式。
然后设置用户层与内核捕获数据的缓冲区大小分别为WIN32_DEFAULT_USER_BUFFER_SIZE(256KB)与WIN32_DEFAULT_KERNEL_BUFFER_SIZE(1MB),并设置内核缓冲区,分配用户缓冲区,并进行初始化。
设置驱动程序只有存储了至少16K的数据后,才能复制数据到用户空间,设置读取超时时间。
设置NPF进行读取的操作句柄为pcap_read_win32_npf()函数与设置过滤的操作句柄为pcap_setfilter_win32_npf函数。
设置发送单个数据包的操作句柄为pcap_inject_win32函数。设置下列函数句柄。
p->getnonblock_op = pcap_getnonblock_win32;
p->setnonblock_op = pcap_setnonblock_win32;
p->stats_op = pcap_stats_win32;
p->setbuff_op = pcap_setbuff_win32;
p->setmode_op = pcap_setmode_win32;
p->setmintocopy_op = pcap_setmintocopy_win32;
p->cleanup_op = pcap_cleanup_win32;
最后函数返回 。

其中函数wsockinit()主要调用WSAStartup()系统函数实现Winsocket的初始化。
[align=left]把p->cleanup_op清除操作设置为pcap_cleanup_win32 ()函数,使得与pcap_open_live()函数对应的pcap_close()函数调用,调用该函数正确释放各种资源。[/align]
本文出自 “千江月” 博客,请务必保留此出处http://eslxf.blog.51cto.com/918801/205038
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: