深度剖析WinPcap之(八)——打开与关闭适配器(3)

本文转自http://eslxf.blog.51cto.com/918801/204274

 

1.4      wpcap.dll中相应函数接口的实现

下面对各函数在wpcap.dll中的实现进行详细分析。

1.4.1        pcap_open函数

函数首先确认参数source的长度不超过PCAP_BUF_SIZE,然后调用pcap_parsesrcstr()函数分析源的种类,是文件,本地主机接口还是远程主机接口,并依据不同的源类型作不同的处理。
如果是文件类型,直接调用pcap_open_offline函数处理。
如果是远程主机接口类型,调用pcap_create()创建一个pcap_t结构体,然后调用函数pcap_opensource_remote()通过打开一个远程主机的适配器,最后给pcap_t结构体几个重要成员设置合适的值,包括捕获数据包长度、读取超时,与pcap_startcapture()需要使用的标识。
如果是本地主机接口类型,直接调用pcap_open_live()函数,然后给NPF驱动设置几个标识。根据需要,可设置禁止回环数据包捕获,还可设置一次读操作所需获得的最小数据长度(字节为单位)。
最后函数返回一个pcap_t结构体指针,供后面的调用使用。
函数主要代码如下:
pcap_t *pcap_open(const char *source,
int snaplen, int flags, int read_timeout,
struct pcap_rmtauth *auth, char *errbuf)
{
char host[PCAP_BUF_SIZE], port[PCAP_BUF_SIZE], name[PCAP_BUF_SIZE];
int type;
pcap_t *fp;
int result;
 
    /*确认source的长度不超过PCAP_BUF_SIZE*/
    if (strlen(source) > PCAP_BUF_SIZE)
    {//错误,函数返回
        …
    }
 
/*分析源的种类,文件,本地主机接口还是远程主机接口)*/
    if (pcap_parsesrcstr(source, &type, host, port, name, errbuf) == -1)
        return NULL;
 
/*依据不同的源类型作不同的处理*/
    switch (type)
    {
        //文件类型,直接调用pcap_open_offline函数处理
        case PCAP_SRC_FILE:
            fp = pcap_open_offline(name, errbuf);
            break;
 
//远程主机接口类型,打开远程主机的适配器,设置几个重要标识的值。
        case PCAP_SRC_IFREMOTE:
            //创建pcap_t结构体
fp= pcap_create(source, errbuf);
            if (fp == NULL)
            {
                return NULL;
            }
 
            //打开一个远程主机的适配器
            result= pcap_opensource_remote(fp, auth);
 
            if (result != 0)
            {
                pcap_close(fp);
                return NULL;
            }
//设置捕获数据包长度、读取超时,
//pcap_startcapture()需要使用的标识。 
            fp->snapshot= snaplen;
            fp->md.timeout= read_timeout;
            fp->rmt_flags= flags;
            break;
 
//本地主机接口类型,直接调用pcap_open_live()函数,
//然后给NPF驱动设置几个标识。
        case PCAP_SRC_IFLOCAL:
 
            fp = pcap_open_live(name, snaplen, (flags &
PCAP_OPENFLAG_PROMISCUOUS), read_timeout, errbuf);
 
#ifdef WIN32
//这些标识仅被Windows支持
            if (fp != NULL && fp->adapter != NULL)
            {
                /* 如果需要,禁止回环数据包捕获*/
                if(flags & PCAP_OPENFLAG_NOCAPTURE_LOCAL)
                {
                    if(!PacketSetLoopbackBehavior(fp->adapter,
                        NPF_DISABLE_LOOPBACK))
                    { //设置失败,函数返回
                        …
                    }
                }
 
        /*如果需要,设置一次读操作所需获得的最小数据长度(字节为单位)*/
                if(flags & PCAP_OPENFLAG_MAX_RESPONSIVENESS)
                {
                    if(!PacketSetMinToCopy(fp->adapter, 0))
                    {//设置失败,函数返回
                    }
                }
            }
#endif //WIN32         
            break;
        default:
            //不支持的源类型
            strcpy(errbuf, "Source type not supported");
            return NULL;
    }
    return fp;
}
其中函数pcap_parsesrcstr()通过解析一个源字符串,来分析源的种类,是文件,本地主机接口还是远程主机接口)并返回分离出来的内容(type,host,port,name)。函数原型如下:
int  pcap_parsesrcstr(const char *source, int *type,
char  *host, char *port, char *name, char *errbuf)
参数source为要分析的源名称。。参数hostportname分别返回源的主机、端口与名称,针对不同的源类型,该三个参数可能为空值。参数errbuf 保存函数的错误信息。
其中参数type返回源的类型,WinPcap内部用来表示源的类型的各标识如下:
PCAP_SRC_FILE指明为一个文件,用户希望从一个本地文件获得数据包。
PCAP_SRC_IFLOCAL指明为一个本机接口,比如用户希望从一个本地主机接口获得数据包。不采用RPCAP协议。
PCAP_SRC_IFREMOTE指明为一个远程接口,比如用户希望从一个远程主机接口获得数据包。需要采用RPCAP协议。
 
其中函数pcap_opensource_remote()通过打开一个RPCAP连接等方式,打开一个远程主机的适配器。函数原型如下:
int pcap_opensource_remote(pcap_t *fp, struct pcap_rmtauth *auth)
参数fp是一个指向pcap_t结构体的指针,该结构体在前面由pcap_create()函数所创建。参数auth是认证权限。
如果函数成功,返回0值,fp指针能够被用来作为后续调用的参数(如pcap_compile()等等)。如果函数失败,返回-1值,fp->errbuf中存储错误信息。
该函数为一个远程接口完成与pcap_open_live()基本类似的功能。不同的是,此处,在调用pcap_startcapture_remote()之前,捕获线程并不启动。因为,在远程捕获时,我们不能在“open adapter”命令一发送出去就开始捕获数据。考虑远程适配器已经负载很重的时候,如果我们开始一个捕获(其默认情况下,具有一个NULL过滤器),新的网络流量将使网络饱和。
作为替代方案,我们想先"open"适配器,接着仅当在我们准备好开始捕获时发送一个"start capture"的命令。该函数作了这样的工作:它发送一个“open adapter”命令(根据RPCAP协议),但是它不开始捕获。
既然其它的libpcap函数并不一定共享该工作方式,我们不得不做一些并不优雅的事情,使得每件事情都能妥善的解决。
    注意:万一在捕获还没有开始时,就调用了pcap_compile()函数,过滤器将被存储到pcap_t结构体中,稍后它将被发送到另一个主机(当pcap_startcapture_remote()被调用时)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值