以太網(wǎng)數(shù)據(jù)幀解碼

以太網(wǎng)數(shù)據(jù)幀解碼

先了解數(shù)據(jù)鏈路層的數(shù)據(jù)構(gòu)成(數(shù)據(jù)鏈路層會(huì)在包頭和包尾添加數(shù)據(jù),這里僅介紹包頭的數(shù)據(jù))。數(shù)據(jù)鏈路層數(shù)據(jù)由6位目標(biāo)MAC地址,6位源MAC地址以及2位的下層協(xié)議標(biāo)識(shí)組成。
數(shù)據(jù)幀頭的數(shù)據(jù)結(jié)構(gòu)如下:

typedef struct EthernetHdr_ {
  uint8_t eth_dst[6]; // 目標(biāo) MAC 地址
  uint8_t eth_src[6]; // 源 MAC 地址
  uint16_t eth_type;  // 上層協(xié)議類型
} __attribute__((__packed__)) EthernetHdr;

獲取數(shù)據(jù)鏈路層數(shù)據(jù)

suricata 數(shù)據(jù)進(jìn)入decode-ethernet.c中的DecodeEthernet()進(jìn)行數(shù)據(jù)幀的解碼,檢查數(shù)據(jù)包長(zhǎng)度后記錄數(shù)據(jù)鏈路層數(shù)據(jù)頭指針(解碼數(shù)據(jù)包未新開辟空間,而是通過構(gòu)造相應(yīng)的結(jié)構(gòu)體,在需要使用相應(yīng)數(shù)據(jù)時(shí)使用結(jié)構(gòu)體數(shù)據(jù)偏移取出數(shù)據(jù))。

// 解析鏈路層數(shù)據(jù)
p->ethh = (EthernetHdr *)pkt;
if (unlikely(p->ethh == NULL))
  return TM_ECODE_FAILED;

p為Package,用于保存數(shù)據(jù)包相應(yīng)的數(shù)據(jù),但是具體的生命周期不知道是多少。在package中保存了部分?jǐn)?shù)據(jù)。

選擇剩余數(shù)據(jù)的解碼方式

在數(shù)據(jù)鏈路層數(shù)據(jù)的最后有下層協(xié)議的標(biāo)識(shí),通過標(biāo)識(shí)我們可以使用對(duì)應(yīng)的函數(shù)來對(duì)后面數(shù)據(jù)進(jìn)行進(jìn)一步解碼。

switch (ntohs(p->ethh->eth_type)) {
  case ETHERNET_TYPE_IP:
    //printf("DecodeEthernet ip4\n");
    DecodeIPV4(tv, dtv, p, pkt + ETHERNET_HEADER_LEN,
                len - ETHERNET_HEADER_LEN, pq);
    break;
  case ETHERNET_TYPE_IPV6:
    //printf("DecodeEthernet ip6\n");
    DecodeIPV6(tv, dtv, p, pkt + ETHERNET_HEADER_LEN,
                len - ETHERNET_HEADER_LEN, pq);
    break;
  case ETHERNET_TYPE_PPPOE_SESS:
    //printf("DecodeEthernet PPPOE Session\n");
    DecodePPPOESession(tv, dtv, p, pkt + ETHERNET_HEADER_LEN,
                        len - ETHERNET_HEADER_LEN, pq);
    break;
  case ETHERNET_TYPE_PPPOE_DISC:
    //printf("DecodeEthernet PPPOE Discovery\n");
    DecodePPPOEDiscovery(tv, dtv, p, pkt + ETHERNET_HEADER_LEN,
                          len - ETHERNET_HEADER_LEN, pq);
    break;
  case ETHERNET_TYPE_VLAN:
  case ETHERNET_TYPE_8021QINQ:
    DecodeVLAN(tv, dtv, p, pkt + ETHERNET_HEADER_LEN,
                len - ETHERNET_HEADER_LEN, pq);
    break;
  case ETHERNET_TYPE_MPLS_UNICAST:
  case ETHERNET_TYPE_MPLS_MULTICAST:
    DecodeMPLS(tv, dtv, p, pkt + ETHERNET_HEADER_LEN,
                len - ETHERNET_HEADER_LEN, pq);
    break;
  case ETHERNET_TYPE_DCE:
    if (unlikely(len < ETHERNET_DCE_HEADER_LEN)) {
      ENGINE_SET_INVALID_EVENT(p, DCE_PKT_TOO_SMALL);
    } else {
      DecodeEthernet(tv, dtv, p, pkt + ETHERNET_DCE_HEADER_LEN,
                      len - ETHERNET_DCE_HEADER_LEN, pq);
    }
    break;
  default:
    SCLogDebug("p %p pkt %p ether type %04x not supported", p,
                pkt, ntohs(p->ethh->eth_type));
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容