/src/PcapPlusPlus/Packet++/header/VlanLayer.h
Line | Count | Source |
1 | | #pragma once |
2 | | |
3 | | #include "Layer.h" |
4 | | #include "EthLayer.h" |
5 | | |
6 | | /// @file |
7 | | |
8 | | /// @namespace pcpp |
9 | | /// @brief The main namespace for the PcapPlusPlus lib |
10 | | namespace pcpp |
11 | | { |
12 | | /// @struct vlan_header |
13 | | /// Represents a VLAN header |
14 | | #pragma pack(push, 1) |
15 | | struct vlan_header |
16 | | { |
17 | | /// @code{.unparsed} |
18 | | /// 0 1 2 |
19 | | /// 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 |
20 | | /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
21 | | /// |Prio |C| VLAN ID | |
22 | | /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
23 | | /// @endcode |
24 | | uint16_t vlan; |
25 | | /// Ethernet type for next layer |
26 | | uint16_t etherType; |
27 | | }; |
28 | | #pragma pack(pop) |
29 | | static_assert(sizeof(vlan_header) == 4, "vlan_header size is not 4 bytes"); |
30 | | |
31 | | /// @class VlanLayer |
32 | | /// Represents a VLAN tunnel layer |
33 | | class VlanLayer : public Layer |
34 | | { |
35 | | public: |
36 | | /// A constructor that creates the layer from an existing packet raw data |
37 | | /// @param[in] data A pointer to the raw data |
38 | | /// @param[in] dataLen Size of the data in bytes |
39 | | /// @param[in] prevLayer A pointer to the previous layer |
40 | | /// @param[in] packet A pointer to the Packet instance where layer will be stored in |
41 | | VlanLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) |
42 | 56.0k | : Layer(data, dataLen, prevLayer, packet, VLAN) |
43 | 56.0k | {} |
44 | | |
45 | | /// A constructor that allocates a new VLAN header |
46 | | /// @param[in] vlanID VLAN ID |
47 | | /// @param[in] cfi CFI value |
48 | | /// @param[in] priority Priority value |
49 | | /// @param[in] etherType Protocol EtherType of the next layer. It's an optional parameter, a value of 0 will be |
50 | | /// set if not provided |
51 | | VlanLayer(const uint16_t vlanID, bool cfi, uint8_t priority, uint16_t etherType = 0); |
52 | | |
53 | | ~VlanLayer() override = default; |
54 | | |
55 | | /// Get a pointer to the VLAN header. Notice this points directly to the data, so every change will change the |
56 | | /// actual packet data |
57 | | /// @return A pointer to the vlan_header |
58 | | vlan_header* getVlanHeader() const |
59 | 100k | { |
60 | 100k | return reinterpret_cast<vlan_header*>(m_Data); |
61 | 100k | } |
62 | | |
63 | | /// Get the VLAN ID value. This method differs from vlan_header#vlanID because vlan_header#vlanID is 12 bits |
64 | | /// long in a 16 bit field. This methods extracts only the 12 bit relevant for the VLAN ID |
65 | | /// @return VLAN ID value |
66 | | /// @todo Verify it works in big endian machines as well |
67 | | uint16_t getVlanID() const; |
68 | | |
69 | | /// @return The CFI bit value |
70 | | /// @todo Verify it works in big endian machines as well |
71 | | uint8_t getCFI() const; |
72 | | |
73 | | /// @return The priority value |
74 | | /// @todo Verify it works in big endian machines as well |
75 | | uint8_t getPriority() const; |
76 | | |
77 | | /// Set VLAN ID. This method differs from setting vlan_header#vlanID because vlan_header#vlanID is 12 bits long |
78 | | /// in a 16 bit field. This methods sets only the 12 bit relevant for the VLAN ID |
79 | | /// @param[in] id The VLAN ID to set |
80 | | /// @todo Verify it works in big endian machines as well |
81 | | void setVlanID(uint16_t id); |
82 | | |
83 | | /// Set CFI bit |
84 | | /// @param[in] cfi The CFI bit to set |
85 | | /// @todo Verify it works in big endian machines as well |
86 | | void setCFI(bool cfi); |
87 | | |
88 | | /// Set priority value |
89 | | /// @param[in] priority The priority value to set |
90 | | /// @todo Verify it works in big endian machines as well |
91 | | void setPriority(uint8_t priority); |
92 | | |
93 | | // implement abstract methods |
94 | | |
95 | | /// Currently identifies the following next layers: IPv4Layer, IPv6Layer, ArpLayer, VlanLayer, MplsLayer. |
96 | | /// Otherwise sets PayloadLayer |
97 | | void parseNextLayer() override; |
98 | | |
99 | | /// @return Size of vlan_header |
100 | | size_t getHeaderLen() const override |
101 | 7.29k | { |
102 | 7.29k | return sizeof(vlan_header); |
103 | 7.29k | } |
104 | | |
105 | | /// Calculate the EtherType for known protocols: IPv4, IPv6, ARP, VLAN |
106 | | void computeCalculateFields() override; |
107 | | |
108 | | std::string toString() const override; |
109 | | |
110 | | OsiModelLayer getOsiModelLayer() const override |
111 | 6.52k | { |
112 | 6.52k | return OsiModelDataLinkLayer; |
113 | 6.52k | } |
114 | | |
115 | | /// A static method that validates the input data |
116 | | /// @param[in] data The pointer to the beginning of a byte stream of an VLAN layer |
117 | | /// @param[in] dataLen The length of the byte stream |
118 | | /// @return True if the data is valid and can represent an VLAN layer |
119 | | static bool isDataValid(const uint8_t* data, size_t dataLen) |
120 | 44.3k | { |
121 | 44.3k | return canReinterpretAs<vlan_header>(data, dataLen); |
122 | 44.3k | } |
123 | | }; |
124 | | } // namespace pcpp |