Coverage Report

Created: 2023-01-17 06:15

/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
#include <string.h>
14
15
namespace pcpp
16
{
17
18
19
EthLayer::EthLayer(const MacAddress& sourceMac, const MacAddress& destMac, uint16_t etherType) : Layer()
20
0
{
21
0
  const size_t headerLen = sizeof(ether_header);
22
0
  m_DataLen = headerLen;
23
0
  m_Data = new uint8_t[headerLen];
24
0
  memset(m_Data, 0, headerLen);
25
26
0
  ether_header* ethHdr = (ether_header*)m_Data;
27
0
  destMac.copyTo(ethHdr->dstMac);
28
0
  sourceMac.copyTo(ethHdr->srcMac);
29
0
  ethHdr->etherType = htobe16(etherType);
30
0
  m_Protocol = Ethernet;
31
0
}
32
33
void EthLayer::parseNextLayer()
34
16.0k
{
35
16.0k
  if (m_DataLen <= sizeof(ether_header))
36
237
    return;
37
38
15.7k
  ether_header* hdr = getEthHeader();
39
15.7k
  uint8_t* payload = m_Data + sizeof(ether_header);
40
15.7k
  size_t payloadLen = m_DataLen - sizeof(ether_header);
41
42
15.7k
  switch (be16toh(hdr->etherType))
43
15.7k
  {
44
2.72k
  case PCPP_ETHERTYPE_IP:
45
2.72k
    m_NextLayer = IPv4Layer::isDataValid(payload, payloadLen)
46
2.72k
      ? static_cast<Layer*>(new IPv4Layer(payload, payloadLen, this, m_Packet))
47
2.72k
      : static_cast<Layer*>(new PayloadLayer(payload, payloadLen, this, m_Packet));
48
2.72k
    break;
49
552
  case PCPP_ETHERTYPE_IPV6:
50
552
    m_NextLayer = IPv6Layer::isDataValid(payload, payloadLen)
51
552
      ? static_cast<Layer*>(new IPv6Layer(payload, payloadLen, this, m_Packet))
52
552
      : static_cast<Layer*>(new PayloadLayer(payload, payloadLen, this, m_Packet));
53
552
    break;
54
493
  case PCPP_ETHERTYPE_ARP:
55
493
    m_NextLayer = new ArpLayer(payload, payloadLen, this, m_Packet);
56
493
    break;
57
4.87k
  case PCPP_ETHERTYPE_VLAN:
58
5.97k
  case PCPP_ETHERTYPE_IEEE_802_1AD:
59
5.97k
    m_NextLayer = new VlanLayer(payload, payloadLen, this, m_Packet);
60
5.97k
    break;
61
1.74k
  case PCPP_ETHERTYPE_PPPOES:
62
1.74k
    m_NextLayer = PPPoESessionLayer::isDataValid(payload, payloadLen)
63
1.74k
      ? static_cast<Layer*>(new PPPoESessionLayer(payload, payloadLen, this, m_Packet))
64
1.74k
      : static_cast<Layer*>(new PayloadLayer(payload, payloadLen, this, m_Packet));
65
1.74k
    break;
66
517
  case PCPP_ETHERTYPE_PPPOED:
67
517
    m_NextLayer = PPPoEDiscoveryLayer::isDataValid(payload, payloadLen)
68
517
      ? static_cast<Layer*>(new PPPoEDiscoveryLayer(payload, payloadLen, this, m_Packet))
69
517
      : static_cast<Layer*>(new PayloadLayer(payload, payloadLen, this, m_Packet));
70
517
    break;
71
1.13k
  case PCPP_ETHERTYPE_MPLS:
72
1.13k
    m_NextLayer = new MplsLayer(payload, payloadLen, this, m_Packet);
73
1.13k
    break;
74
724
  case PCPP_ETHERTYPE_WAKE_ON_LAN:
75
724
    m_NextLayer = WakeOnLanLayer::isDataValid(payload, payloadLen)
76
724
      ? static_cast<Layer*>(new WakeOnLanLayer(payload, payloadLen, this, m_Packet))
77
724
      : static_cast<Layer*>(new PayloadLayer(payload, payloadLen, this, m_Packet));
78
724
    break;
79
1.90k
  default:
80
1.90k
    m_NextLayer = new PayloadLayer(payload, payloadLen, this, m_Packet);
81
15.7k
  }
82
15.7k
}
83
84
void EthLayer::computeCalculateFields()
85
0
{
86
0
  if (m_NextLayer == NULL)
87
0
    return;
88
89
0
  switch (m_NextLayer->getProtocol())
90
0
  {
91
0
  case IPv4:
92
0
    getEthHeader()->etherType = htobe16(PCPP_ETHERTYPE_IP);
93
0
    break;
94
0
  case IPv6:
95
0
    getEthHeader()->etherType = htobe16(PCPP_ETHERTYPE_IPV6);
96
0
    break;
97
0
  case ARP:
98
0
    getEthHeader()->etherType = htobe16(PCPP_ETHERTYPE_ARP);
99
0
    break;
100
0
  case VLAN:
101
0
    getEthHeader()->etherType = htobe16(PCPP_ETHERTYPE_VLAN);
102
0
    break;
103
0
  default:
104
0
    return;
105
0
  }
106
0
}
107
108
std::string EthLayer::toString() const
109
0
{
110
0
  return "Ethernet II Layer, Src: " + getSourceMac().toString() + ", Dst: " + getDestMac().toString();
111
0
}
112
113
bool EthLayer::isDataValid(const uint8_t* data, size_t dataLen)
114
23.1k
{
115
23.1k
  if (dataLen >= sizeof(ether_header))
116
21.3k
  {
117
    /**
118
     * Ethertypes: These are 16-bit identifiers appearing as the initial
119
     * two octets after the MAC destination and source (or after a
120
     * tag) which, when considered as an unsigned integer, are equal
121
     * to or larger than 0x0600.
122
     *
123
     * From: https://tools.ietf.org/html/rfc5342#section-2.3.2.1
124
     * More: IEEE Std 802.3 Clause 3.2.6
125
     */
126
21.3k
    return be16toh(*(uint16_t*)(data + 12)) >= (uint16_t)0x0600;
127
21.3k
  }
128
1.78k
  else
129
1.78k
  {
130
1.78k
    return false;
131
1.78k
  }
132
23.1k
}
133
134
} // namespace pcpp