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

本文详细解析了pcap_open_live函数的工作原理及其内部实现机制,包括如何创建pcap_t结构体、设置捕获参数、激活捕捉实例等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

 

1.4.2       pcap_open_live函数

函数首先创建pcap_t结构体,设置捕获数据包的长度,设置网卡为混杂模式,设置读取超时时间,最后激活该已打开的捕捉实例。
函数的重要代码如下:
pcap_t *pcap_open_live(const char *source, int snaplen,
int promisc, int to_ms, char *errbuf)
{
    pcap_t *p;
    int status;
 
    /*创建pcap_t结构体*/
    p = pcap_create(source, errbuf);
    if (p == NULL)
        return (NULL);
 
    /*设置捕获数据包的长度*/
    status = pcap_set_snaplen(p, snaplen);
    if (status < 0)
        goto fail;
 
/*设置混杂模式*/
    status = pcap_set_promisc(p, promisc);
    if (status < 0)
        goto fail;
 
/*设置读取超时时间*/
    status = pcap_set_timeout(p, to_ms);
    if (status < 0)
        goto fail; 
 
   /*如果使用pcap_open_live()函数,就设置为1*/
    p->oldstyle = 1;
   
/*激活该已打开的捕捉实例p*/
status = pcap_activate(p);
    if (status < 0)
        goto fail;
    return (p);
fail:
    //出错处理
    …
}
 
1.4.2.1     pcap_create函数
函数首先检查参数device是否为unicode字符串,如果是则转换为ASCII字符串, 然后设置p->activate_op函数指针指向pcap_activate_win32函数。
函数的重要代码如下:
pcap_t *pcap_create(const char *device, char *ebuf)
{
    pcap_t *p;
 
/*检查device是否为unicode字符串,如果是转换为ASCII字符串 */
    if (strlen(device) == 1)
    {
//可能是unicode字符串
//转换为ASCII字符串,
//并把转换结果传递给pcap_create_common()函数       
        size_t length;
        char* deviceAscii;
 
        length = wcslen((wchar_t*)device);
 
        deviceAscii = (char*)malloc(length + 1);
        …
        snprintf(deviceAscii, length + 1, "%ws", (wchar_t*)device);
        p = pcap_create_common(deviceAscii, ebuf);
        free(deviceAscii);
    }
    else
    {
        p = pcap_create_common(device, ebuf);
    }
   
    …
    /*设置p->activate_oppcap_activate_win32*/
    p->activate_op = pcap_activate_win32;
    …
 
    return (p);
}
 
1.4.2.2     pcap_create_common函数
函数pcap_create_common()创建一个pcap_t结构体,并对结构体中的一些字段进行初始化,如果成功将返回指向pcap_t结构体内存的指针。参数source是所要打开源的名称,参数ebuf存储函数的错误信息。
函数的重要代码如下:
pcap_t *pcap_create_common(const char *source, char *ebuf)
{
    pcap_t *p;
 
   /*分配pcap_t的内存空间*/
    p = malloc(sizeof(*p));
    if (p == NULL) {
        //分配失败,函数退出
    }
    memset(p, 0, sizeof(*p));
 
   /* p->opt.source复制源字符串*/
    p->opt.source = strdup(source);
    if (p->opt.source == NULL) {
        //失败,函数退出
    }
 
    /*
*默认为"不能设置rfmon模式"
*如果被平台支持,可以设置该操作句柄,
*使用所设置的例程检测设备是否支持。
    */
    p->can_set_rfmon_op = pcap_cant_set_rfmon;
 
    /*
*一些操作只有在pcap_t是激活状态下才能执行
*把这些操作句柄设为“不支持”的句柄,直到pcap_t被激活
    */
    p->read_op = (read_op_t)pcap_not_initialized;
    p->inject_op = (inject_op_t)pcap_not_initialized;
    p->setfilter_op = (setfilter_op_t)pcap_not_initialized;
    p->setdirection_op = (setdirection_op_t)pcap_not_initialized;
    p->set_datalink_op = (set_datalink_op_t)pcap_not_initialized;
    p->getnonblock_op = (getnonblock_op_t)pcap_not_initialized;
    p->setnonblock_op = (setnonblock_op_t)pcap_not_initialized;
    p->stats_op = (stats_op_t)pcap_not_initialized;
#ifdef WIN32
    p->setbuff_op = (setbuff_op_t)pcap_not_initialized;
    p->setmode_op = (setmode_op_t)pcap_not_initialized;
    p->setmintocopy_op = (setmintocopy_op_t)pcap_not_initialized;
#endif
    p->cleanup_op = pcap_cleanup_live_common;
 
    /* 把一些只设为默认的*/
    pcap_set_timeout(p, 0);
    pcap_set_snaplen(p, 65535);
    p->opt.promisc = 0;
    p->opt.buffer_size = 0;
    return (p);
}
函数首先分配一个pcap_t结构体的内存空间,并对其清零。
然后给p->opt.source复制源字符串,然后设置p->can_set_rfmon_op操作句柄,使用所设置的例程pcap_cant_set_rfmon检测设备是否支持rfmon模式。
接着把一些只有在pcap_t是激活状态下才能执行的操作的句柄,设置为“不支持”的句柄pcap_not_initialized()
p->cleanup_op清除操作设置为pcap_cleanup_live_common()函数,使得与pcap_open_live()函数对应的pcap_close()函数调用,调用该函数正确释放各种资源。
最后把读取超时时间设为0,设置捕获数据包的长度为65535个字节,混杂模式p->opt.promisc设置为0,把缓冲区大小p->opt.buffer_size设为0
 
其中函数pcap_cant_set_rfmon()的实现如下
static int pcap_cant_set_rfmon(pcap_t *p _U_)
{
    return (0);
}
可见系统不支持rfmon模式。
函数pcap_not_initialized()的实现如下:
int pcap_not_initialized(pcap_t *pcap)
{
    /*意味着“不初始化”*/
    return PCAP_ERROR_NOT_ACTIVATED;
}
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值