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