Coverage Report

Created: 2026-10-17 07:09

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/PcapPlusPlus/Packet++/src/EthLayer.cpp
Line
Count
Source
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
    allocData(headerLen);
20
21
0
    ether_header* ethHdr = getEthHeader();
22
0
    destMac.copyTo(ethHdr->dstMac);
23
0
    sourceMac.copyTo(ethHdr->srcMac);
24
0
    ethHdr->etherType = htobe16(etherType);
25
0
    m_Protocol = Ethernet;
26
0
  }
27
28
  void EthLayer::parseNextLayer()
29
878k
  {
30
878k
    if (m_DataLen <= sizeof(ether_header))
31
256
      return;
32
33
878k
    ether_header* hdr = getEthHeader();
34
878k
    uint8_t* payload = m_Data + sizeof(ether_header);
35
878k
    size_t payloadLen = m_DataLen - sizeof(ether_header);
36
37
878k
    switch (be16toh(hdr->etherType))
38
878k
    {
39
667k
    case PCPP_ETHERTYPE_IP:
40
667k
      tryConstructNextLayerWithFallback<IPv4Layer, PayloadLayer>(payload, payloadLen);
41
667k
      break;
42
144k
    case PCPP_ETHERTYPE_IPV6:
43
144k
      tryConstructNextLayerWithFallback<IPv6Layer, PayloadLayer>(payload, payloadLen);
44
144k
      break;
45
11.1k
    case PCPP_ETHERTYPE_ARP:
46
11.1k
      tryConstructNextLayerWithFallback<ArpLayer, PayloadLayer>(payload, payloadLen);
47
11.1k
      break;
48
29.1k
    case PCPP_ETHERTYPE_VLAN:
49
39.3k
    case PCPP_ETHERTYPE_IEEE_802_1AD:
50
39.3k
      tryConstructNextLayerWithFallback<VlanLayer, PayloadLayer>(payload, payloadLen);
51
39.3k
      break;
52
3.56k
    case PCPP_ETHERTYPE_PPPOES:
53
3.56k
      tryConstructNextLayerWithFallback<PPPoESessionLayer, PayloadLayer>(payload, payloadLen);
54
3.56k
      break;
55
3.10k
    case PCPP_ETHERTYPE_PPPOED:
56
3.10k
      tryConstructNextLayerWithFallback<PPPoEDiscoveryLayer, PayloadLayer>(payload, payloadLen);
57
3.10k
      break;
58
5.56k
    case PCPP_ETHERTYPE_MPLS:
59
5.56k
      tryConstructNextLayerWithFallback<MplsLayer, PayloadLayer>(payload, payloadLen);
60
5.56k
      break;
61
342
    case PCPP_ETHERTYPE_WAKE_ON_LAN:
62
342
      tryConstructNextLayerWithFallback<WakeOnLanLayer, PayloadLayer>(payload, payloadLen);
63
342
      break;
64
878k
    }
65
66
    // If no next layer was constructed, assume it's a payload layer
67
878k
    if (!hasNextLayer())
68
2.90k
      constructNextLayer<PayloadLayer>(payload, payloadLen);
69
878k
  }
70
71
  void EthLayer::computeCalculateFields()
72
168k
  {
73
168k
    if (m_NextLayer == nullptr)
74
128
      return;
75
76
168k
    switch (m_NextLayer->getProtocol())
77
168k
    {
78
127k
    case IPv4:
79
127k
      getEthHeader()->etherType = htobe16(PCPP_ETHERTYPE_IP);
80
127k
      break;
81
29.0k
    case IPv6:
82
29.0k
      getEthHeader()->etherType = htobe16(PCPP_ETHERTYPE_IPV6);
83
29.0k
      break;
84
3.01k
    case ARP:
85
3.01k
      getEthHeader()->etherType = htobe16(PCPP_ETHERTYPE_ARP);
86
3.01k
      break;
87
5.41k
    case VLAN:
88
5.41k
      getEthHeader()->etherType = htobe16(PCPP_ETHERTYPE_VLAN);
89
5.41k
      break;
90
3.39k
    default:
91
3.39k
      return;
92
168k
    }
93
168k
  }
94
95
  std::string EthLayer::toString() const
96
336k
  {
97
336k
    return "Ethernet II Layer, Src: " + getSourceMac().toString() + ", Dst: " + getDestMac().toString();
98
336k
  }
99
100
  bool EthLayer::isDataValid(const uint8_t* data, size_t dataLen)
101
888k
  {
102
888k
    if (dataLen >= sizeof(ether_header))
103
888k
    {
104
      // Ethertypes: These are 16-bit identifiers appearing as the initial
105
      // two octets after the MAC destination and source (or after a
106
      // tag) which, when considered as an unsigned integer, are equal
107
      // to or larger than 0x0600.
108
      //
109
      // From: https://tools.ietf.org/html/rfc5342#section-2.3.2.1
110
      // More: IEEE Std 802.3 Clause 3.2.6
111
888k
      return be16toh(*reinterpret_cast<const uint16_t*>(data + 12)) >= static_cast<uint16_t>(0x0600);
112
888k
    }
113
73
    else
114
73
    {
115
73
      return false;
116
73
    }
117
888k
  }
118
119
  const FieldDescriptor EthLayer::SerializedFields::SrcMacAddress{ Layer::SerializedFields::MaxID + 1,
120
                                                                 "srcMacAddress" };
121
  const FieldDescriptor EthLayer::SerializedFields::DstMacAddress{ Layer::SerializedFields::MaxID + 2,
122
                                                                 "dstMacAddress" };
123
  const FieldDescriptor EthLayer::SerializedFields::EtherType{ Layer::SerializedFields::MaxID + 3, "etherType" };
124
125
  void EthLayer::serializeLayer(ObjectScope& serializer) const
126
0
  {
127
0
    auto* header = getEthHeader();
128
0
    serializer.writeField(SerializedFields::SrcMacAddress, getSourceMac().toString());
129
0
    serializer.writeField(SerializedFields::DstMacAddress, getDestMac().toString());
130
    serializer.writeField(SerializedFields::EtherType, be16toh(header->etherType));
131
0
  }
132
}  // namespace pcpp