/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 |