Coverage Report

Created: 2025-07-12 07:37

/src/PcapPlusPlus/Packet++/src/EthLayer.cpp
Line
Count
Source (jump to first uncovered line)
1
#define LOG_MODULE PacketLogModuleEthLayer
2
3
#include "EthLayer.h"
4
#include "IPv4Layer.h"
5
#include "IPv6Layer.h"
6
#include "PayloadLayer.h"
7
#include "ArpLayer.h"
8
#include "VlanLayer.h"
9
#include "PPPoELayer.h"
10
#include "MplsLayer.h"
11
#include "WakeOnLanLayer.h"
12
#include "EndianPortable.h"
13
14
namespace pcpp
15
{
16
0
  EthLayer::EthLayer(const MacAddress& sourceMac, const MacAddress& destMac, uint16_t etherType) : Layer()
17
0
  {
18
0
    const size_t headerLen = sizeof(ether_header);
19
0
    m_DataLen = headerLen;
20
0
    m_Data = new uint8_t[headerLen];
21
0
    memset(m_Data, 0, headerLen);
22
23
0
    ether_header* ethHdr = getEthHeader();
24
0
    destMac.copyTo(ethHdr->dstMac);
25
0
    sourceMac.copyTo(ethHdr->srcMac);
26
0
    ethHdr->etherType = htobe16(etherType);
27
0
    m_Protocol = Ethernet;
28
0
  }
29
30
  void EthLayer::parseNextLayer()
31
288k
  {
32
288k
    if (m_DataLen <= sizeof(ether_header))
33
430
      return;
34
35
287k
    ether_header* hdr = getEthHeader();
36
287k
    uint8_t* payload = m_Data + sizeof(ether_header);
37
287k
    size_t payloadLen = m_DataLen - sizeof(ether_header);
38
39
287k
    switch (be16toh(hdr->etherType))
40
287k
    {
41
218k
    case PCPP_ETHERTYPE_IP:
42
218k
      tryConstructNextLayerWithFallback<IPv4Layer, PayloadLayer>(payload, payloadLen, m_Packet);
43
218k
      break;
44
23.6k
    case PCPP_ETHERTYPE_IPV6:
45
23.6k
      tryConstructNextLayerWithFallback<IPv6Layer, PayloadLayer>(payload, payloadLen, m_Packet);
46
23.6k
      break;
47
365
    case PCPP_ETHERTYPE_ARP:
48
365
      tryConstructNextLayerWithFallback<ArpLayer, PayloadLayer>(payload, payloadLen, m_Packet);
49
365
      break;
50
44.3k
    case PCPP_ETHERTYPE_VLAN:
51
44.3k
    case PCPP_ETHERTYPE_IEEE_802_1AD:
52
44.3k
      tryConstructNextLayerWithFallback<VlanLayer, PayloadLayer>(payload, payloadLen, m_Packet);
53
44.3k
      break;
54
0
    case PCPP_ETHERTYPE_PPPOES:
55
0
      tryConstructNextLayerWithFallback<PPPoESessionLayer, PayloadLayer>(payload, payloadLen, m_Packet);
56
0
      break;
57
0
    case PCPP_ETHERTYPE_PPPOED:
58
0
      tryConstructNextLayerWithFallback<PPPoEDiscoveryLayer, PayloadLayer>(payload, payloadLen, m_Packet);
59
0
      break;
60
0
    case PCPP_ETHERTYPE_MPLS:
61
0
      tryConstructNextLayerWithFallback<MplsLayer, PayloadLayer>(payload, payloadLen, m_Packet);
62
0
      break;
63
0
    case PCPP_ETHERTYPE_WAKE_ON_LAN:
64
0
      tryConstructNextLayerWithFallback<WakeOnLanLayer, PayloadLayer>(payload, payloadLen, m_Packet);
65
0
      break;
66
287k
    }
67
68
    // If no next layer was constructed, assume it's a payload layer
69
287k
    if (!hasNextLayer())
70
1.12k
      constructNextLayer<PayloadLayer>(payload, payloadLen, m_Packet);
71
287k
  }
72
73
  void EthLayer::computeCalculateFields()
74
54.7k
  {
75
54.7k
    if (m_NextLayer == nullptr)
76
215
      return;
77
78
54.5k
    switch (m_NextLayer->getProtocol())
79
54.5k
    {
80
43.5k
    case IPv4:
81
43.5k
      getEthHeader()->etherType = htobe16(PCPP_ETHERTYPE_IP);
82
43.5k
      break;
83
4.79k
    case IPv6:
84
4.79k
      getEthHeader()->etherType = htobe16(PCPP_ETHERTYPE_IPV6);
85
4.79k
      break;
86
110
    case ARP:
87
110
      getEthHeader()->etherType = htobe16(PCPP_ETHERTYPE_ARP);
88
110
      break;
89
5.35k
    case VLAN:
90
5.35k
      getEthHeader()->etherType = htobe16(PCPP_ETHERTYPE_VLAN);
91
5.35k
      break;
92
723
    default:
93
723
      return;
94
54.5k
    }
95
54.5k
  }
96
97
  std::string EthLayer::toString() const
98
109k
  {
99
109k
    return "Ethernet II Layer, Src: " + getSourceMac().toString() + ", Dst: " + getDestMac().toString();
100
109k
  }
101
102
  bool EthLayer::isDataValid(const uint8_t* data, size_t dataLen)
103
288k
  {
104
288k
    if (dataLen >= sizeof(ether_header))
105
288k
    {
106
      // Ethertypes: These are 16-bit identifiers appearing as the initial
107
      // two octets after the MAC destination and source (or after a
108
      // tag) which, when considered as an unsigned integer, are equal
109
      // to or larger than 0x0600.
110
      //
111
      // From: https://tools.ietf.org/html/rfc5342#section-2.3.2.1
112
      // More: IEEE Std 802.3 Clause 3.2.6
113
288k
      return be16toh(*reinterpret_cast<const uint16_t*>(data + 12)) >= static_cast<uint16_t>(0x0600);
114
288k
    }
115
2
    else
116
2
    {
117
2
      return false;
118
2
    }
119
288k
  }
120
}  // namespace pcpp