/**
* \brief This function passes off to link type decoders.
*
* DecodePcap reads packets from the PacketQueue and passes
* them off to the proper link type decoder.
*
* \param t pointer to ThreadVars
* \param p pointer to the current packet
* \param data pointer that gets cast into PcapThreadVars for ptv
* \param pq pointer to the current PacketQueue
*/
TmEcode DecodePcap(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq)
/*data为初始化时填充的DecodeThreadVars,pq为解码模块所嵌入的slot的slot_pre_pq,
postpq则为slot_post_pq(可能为NULL)。*/
{
SCEnter();
DecodeThreadVars *dtv = (DecodeThreadVars *)data;
/* XXX HACK: flow timeout can call us for injected pseudo packets
* see bug: https://redmine.openinfosecfoundation.org/issues/1107 */
if (p->flags & PKT_PSEUDO_STREAM_END)
return TM_ECODE_OK;
/* update counters */
DecodeUpdatePacketCounters(tv, dtv, p);
/* call the decoder */
switch(p->datalink) {
case LINKTYPE_LINUX_SLL:
DecodeSll(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq);
/*libpcap使用的伪协议头,用于从"any"设备抓包或某些链路层头无法获取的情况,
详见:Linux cooked-mode capture (SLL) 。*/
break;
case LINKTYPE_ETHERNET:
DecodeEthernet(tv, dtv, p,GET_PKT_DATA(p), GET_PKT_LEN(p), pq);
/*以太网协议包。LINKTYPE_ETHERNET宏定义为pcap中的DLT_EN10MB
(10Mb命名是历史原因,参考下面的列表)*/
break;
case LINKTYPE_PPP:
DecodePPP(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq);
/*PPP协议包。参见:RFC 1661 - The Point-to-Point Protocol (PPP)。*/
break;
case LINKTYPE_RAW:
DecodeRaw(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq);
/*原始IP数据包。即直接以IPv4或IPv6头开始。LINKTYPE_RAW宏定义为pcap中的DLT_RAW。*/
break;
case LINKTYPE_NULL:
DecodeNull(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq);
break;
default:
SCLogError(SC_ERR_DATALINK_UNIMPLEMENTED, "Error: datalink type %" PRId32 " not yet supported in module DecodePcap", p->datalink);
break;
}
PacketDecodeFinalize(tv, dtv, p);
SCReturnInt(TM_ECODE_OK);
}
注:按照注释,Suricata中是想套用libpcap中的link type定义,完整的列表可参见:LINK-LAYER HEADER TYPES。