suricata 3.1 源码分析19 (数据包获取)

初始化完成后,TmThreadsSlotPktAcqLoop函数将进入一个while循环,调用slot的PktAcqLoop函数获取并处理数据包。对应的模块函数原型为:
TmEcode ReceivePcapLoop(ThreadVars *tv, void *data, void *slot)
其中,data即为初始化阶段生成的PcapThreadVars结构体,而slot就是包含该模块的那个slot,传入进来的目的主要是获取线程中后续的slot(这里对应DecodePcap),以调用后续的数据包处理流程。

/**
 *  \brief Main PCAP reading Loop function
 */
TmEcode ReceivePcapLoop(ThreadVars *tv, void *data, void *slot)
{
    SCEnter();

    int packet_q_len = 64;
    PcapThreadVars *ptv = (PcapThreadVars *)data;
//获取初始化时生成的PcapThreadVars结构体
    int r;
    TmSlot *s = (TmSlot *)slot;
//获取当前slot(此处是与“ReceivePcap”对应的slot)

    ptv->slot = s->slot_next;
//将PcapThreadVars指向下一个slot(此处是与“DecodePcap”对应的slot)
    ptv->cb_result = TM_ECODE_OK;

    while (1) {
        if (suricata_ctl_flags & (SURICATA_STOP | SURICATA_KILL)) {
            SCReturnInt(TM_ECODE_OK);
/*检查suricata_ctl_flags是否包含STOP或KILL标志,即Suricata是否需要退出,
若是的话则立即返回。这里让子线程去检查全局控制标志的处理方式感觉的不是很优雅,
最好是只检查自己的线程标志。*/
        }

        /* make sure we have at least one packet in the packet pool, to prevent
         * us from alloc'ing packets at line rate */
        PacketPoolWait();
//等待packet pool中有空闲数据包结构(通过cond或sleep实现)

        /* Right now we just support reading packets one at a time. */
        r = pcap_dispatch(ptv->pcap_handle, packet_q_len,
                          (pcap_handler)PcapCallbackLoop, (u_char *)ptv);
/*调用pcap_dispatch获取并处理数据包。其中,第2个参数表示最多处理的数据包个数,
传入的值packet_q_len为packet pool的当前大小;第3个参数为包处理回调函数
PcapCallbackLoop;最后一个参数为传给前面的回调函数的用户数据,这里传入的是
PcapThreadVars结构体。*/

        if (unlikely(r < 0)) {
            int dbreak = 0;
            SCLogError(SC_ERR_PCAP_DISPATCH, "error code %" PRId32 " %s",
                       r, pcap_geterr(ptv->pcap_handle));
#ifdef PCAP_ERROR_BREAK
            if (r == PCAP_ERROR_BREAK) {
                SCReturnInt(ptv->cb_result);
            }
#endif
            do {
                usleep(PCAP_RECONNECT_TIMEOUT);
                if (suricata_ctl_flags != 0) {
                    dbreak = 1;
                    break;
                }
                r = PcapTryReopen(ptv);
            } while (r < 0);
//检查返回值,若出错则尝试不断调用PcapTryReopen重新开启抓包。
            if (dbreak) {
                break;
            }
        } else if (ptv->cb_result == TM_ECODE_FAILED) {
            SCLogError(SC_ERR_PCAP_DISPATCH, "Pcap callback PcapCallbackLoop failed");
            SCReturnInt(TM_ECODE_FAILED);
        } else if (unlikely(r == 0)) {
            TmThreadsCaptureInjectPacket(tv, ptv->slot, NULL);
        }

        StatsSyncCountersIfSignalled(tv);
//同步stats counters
    }

    PcapDumpCounters(ptv);
    StatsSyncCountersIfSignalled(tv);
    SCReturnInt(TM_ECODE_OK);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

高晓伟_Steven

相逢即是有缘,动力源于金钱。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值