Coverage Report

Created: 2025-07-11 07:47

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