Coverage Report

Created: 2026-10-17 07:07

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/PcapPlusPlus/Packet++/header/EthLayer.h
Line
Count
Source
1
#pragma once
2
3
#include "Layer.h"
4
#include "MacAddress.h"
5
#include <algorithm>
6
#include <iterator>
7
8
/// @file
9
10
/// @namespace pcpp
11
/// @brief The main namespace for the PcapPlusPlus lib
12
namespace pcpp
13
{
14
15
  /// @struct ether_header
16
  /// Represents an Ethernet II header
17
#pragma pack(push, 1)
18
  struct ether_header
19
  {
20
    /// Destination MAC
21
    uint8_t dstMac[6];
22
    /// Source MAC
23
    uint8_t srcMac[6];
24
    /// EtherType
25
    uint16_t etherType;
26
  };
27
#pragma pack(pop)
28
  static_assert(sizeof(ether_header) == 14, "ether_header size is not 14 bytes");
29
30
  // Ethernet protocol ID's
31
32
  /// IP
33
0
#define PCPP_ETHERTYPE_IP 0x0800
34
  /// Address resolution
35
0
#define PCPP_ETHERTYPE_ARP 0x0806
36
  /// Transparent Ethernet Bridging
37
0
#define PCPP_ETHERTYPE_ETHBRIDGE 0x6558
38
  /// Reverse ARP
39
#define PCPP_ETHERTYPE_REVARP 0x8035
40
  /// AppleTalk protocol
41
#define PCPP_ETHERTYPE_AT 0x809B
42
  /// AppleTalk ARP
43
#define PCPP_ETHERTYPE_AARP 0x80F3
44
  /// IEEE 802.1Q VLAN tagging
45
0
#define PCPP_ETHERTYPE_VLAN 0x8100
46
  /// IPX
47
#define PCPP_ETHERTYPE_IPX 0x8137
48
  /// IP protocol version 6
49
0
#define PCPP_ETHERTYPE_IPV6 0x86dd
50
  /// used to test interfaces
51
#define PCPP_ETHERTYPE_LOOPBACK 0x9000
52
  /// PPPoE discovery
53
0
#define PCPP_ETHERTYPE_PPPOED 0x8863
54
  /// PPPoE session
55
0
#define PCPP_ETHERTYPE_PPPOES 0x8864
56
  /// MPLS
57
0
#define PCPP_ETHERTYPE_MPLS 0x8847
58
  /// Point-to-point protocol (PPP)
59
0
#define PCPP_ETHERTYPE_PPP 0x880B
60
  /// RDMA over Converged Ethernet (RoCEv1)
61
#define PCPP_ETHERTYPE_ROCEV1 0x8915
62
  /// IEEE 802.1ad Provider Bridge, Q-in-Q
63
0
#define PCPP_ETHERTYPE_IEEE_802_1AD 0x88A8
64
  /// Wake on LAN
65
0
#define PCPP_ETHERTYPE_WAKE_ON_LAN 0x0842
66
67
  /// @class EthLayer
68
  /// Represents an Ethernet II protocol layer
69
  class EthLayer : public Layer
70
  {
71
  public:
72
    /// A constructor that creates the layer from an existing packet raw data
73
    /// @param[in] data A pointer to the raw data (will be casted to ether_header)
74
    /// @param[in] dataLen Size of the data in bytes
75
    /// @param[in] packet A pointer to the Packet instance where layer will be stored in
76
0
    EthLayer(uint8_t* data, size_t dataLen, Packet* packet) : Layer(data, dataLen, nullptr, packet, Ethernet)
77
0
    {}
78
79
    /// A constructor that creates the layer from an existing packet raw data
80
    /// @param[in] data A pointer to the raw data (will be casted to ether_header)
81
    /// @param[in] dataLen Size of the data in bytes
82
    /// @param[in] prevLayer A pointer to the previous layer
83
    /// @param[in] packet A pointer to the Packet instance where layer will be stored in
84
    EthLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet)
85
0
        : Layer(data, dataLen, prevLayer, packet, Ethernet)
86
0
    {}
87
88
    /// A constructor that creates a new Ethernet header and allocates the data
89
    /// @param[in] sourceMac The source MAC address
90
    /// @param[in] destMac The destination MAC address
91
    /// @param[in] etherType The EtherType to be used. It's an optional parameter, a value of 0 will be set if not
92
    /// provided
93
    EthLayer(const MacAddress& sourceMac, const MacAddress& destMac, uint16_t etherType = 0);
94
95
    ~EthLayer() override = default;
96
97
    /// Get a pointer to the Ethernet header. Notice this points directly to the data, so every change will change
98
    /// the actual packet data
99
    /// @return A pointer to the ether_header
100
    inline ether_header* getEthHeader() const
101
0
    {
102
0
      return reinterpret_cast<ether_header*>(m_Data);
103
0
    }
104
105
    /// Get the source MAC address
106
    /// @return The source MAC address
107
    inline MacAddress getSourceMac() const
108
0
    {
109
0
      return MacAddress(getEthHeader()->srcMac);
110
0
    }
111
112
    /// Set source MAC address
113
    /// @param sourceMac Source MAC to set
114
    inline void setSourceMac(const MacAddress& sourceMac)
115
0
    {
116
0
      sourceMac.copyTo(getEthHeader()->srcMac);
117
0
    }
118
119
    /// Get the destination MAC address
120
    /// @return The destination MAC address
121
    inline MacAddress getDestMac() const
122
0
    {
123
0
      return MacAddress(getEthHeader()->dstMac);
124
0
    }
125
126
    /// Set destination MAC address
127
    /// @param destMac Destination MAC to set
128
    inline void setDestMac(const MacAddress& destMac)
129
0
    {
130
0
      destMac.copyTo(getEthHeader()->dstMac);
131
0
    }
132
133
    // implement abstract methods
134
135
    /// Currently identifies the following next layers: IPv4Layer, IPv6Layer, ArpLayer, VlanLayer,
136
    /// PPPoESessionLayer, PPPoEDiscoveryLayer, MplsLayer. Otherwise sets PayloadLayer
137
    void parseNextLayer() override;
138
139
    /// @return Size of ether_header
140
    size_t getHeaderLen() const override
141
0
    {
142
0
      return sizeof(ether_header);
143
0
    }
144
145
    /// Calculate ether_header#etherType for known protocols: IPv4, IPv6, ARP, VLAN
146
    void computeCalculateFields() override;
147
148
    std::string toString() const override;
149
150
    OsiModelLayer getOsiModelLayer() const override
151
0
    {
152
0
      return OsiModelDataLinkLayer;
153
0
    }
154
155
    /// A static method that validates the input data
156
    /// @param[in] data The pointer to the beginning of a byte stream of an Ethernet II packet
157
    /// @param[in] dataLen The length of the byte stream
158
    /// @return True if the data is valid and can represent an Ethernet II packet
159
    static bool isDataValid(const uint8_t* data, size_t dataLen);
160
161
    /// @struct SerializedFields
162
    /// Fields written by EthLayer's serializeLayer(), in addition to
163
    /// Layer::SerializedFields.
164
    struct SerializedFields : Layer::SerializedFields
165
    {
166
      /// @return All field descriptors for EthLayer
167
      static std::vector<FieldDescriptor> all()
168
0
      {
169
0
        auto result = Layer::SerializedFields::all();
170
0
        std::initializer_list<FieldDescriptor> extra{ SrcMacAddress, DstMacAddress, EtherType };
171
0
        std::copy(extra.begin(), extra.end(), std::back_inserter(result));
172
0
        return result;
173
0
      }
174
175
      /// @brief Source MAC address, as a string
176
      static const FieldDescriptor SrcMacAddress;
177
178
      /// @brief Destination MAC address, as a string
179
      static const FieldDescriptor DstMacAddress;
180
181
      /// @brief EtherType, in host byte order (e.g. 2048 for IPv4)
182
      static const FieldDescriptor EtherType;
183
    };
184
185
  protected:
186
    void serializeLayer(ObjectScope& serializer) const override;
187
  };
188
189
}  // namespace pcpp