-
Notifications
You must be signed in to change notification settings - Fork 1
/
VlanLayer.h
141 lines (118 loc) · 3.92 KB
/
VlanLayer.h
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
#ifndef PACKETPP_VLAN_LAYER
#define PACKETPP_VLAN_LAYER
#include <Layer.h>
#include <EthLayer.h>
#if defined(WIN32) || defined(WINx64)
#include <winsock2.h>
#endif
/// @file
/**
* \namespace pcpp
* \brief The main namespace for the PcapPlusPlus lib
*/
namespace pcpp
{
/**
* @struct vlan_header
* Represents a VLAN header
*/
#pragma pack(push, 1)
struct vlan_header {
#if (BYTE_ORDER == LITTLE_ENDIAN)
/** Priority code point (PCP) */
uint16_t priority:3,
/** Drop eligible indicator (DEI) - formerly CFI */
cfi:1,
/** VLAN ID */
vlanID:12;
#else
uint16_t vlanID:12,
cfi:1,
priority:3;
#endif
/** Ethernet type for next layer */
uint16_t etherType;
};
#pragma pack(pop)
/**
* @class VlanLayer
* Represents a VLAN tunnel layer
*/
class VlanLayer : public Layer
{
public:
/** A constructor that creates the layer from an existing packet raw data
* @param[in] data A pointer to the raw data
* @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
*/
VlanLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : Layer(data, dataLen, prevLayer, packet) { m_Protocol = VLAN; }
/**
* A constructor that allocates a new VLAN header
* @param[in] vlanID VLAN ID
* @param[in] cfi CFI value
* @param[in] priority Priority value
* @param[in] etherType Protocol EtherType of the next layer
*/
VlanLayer(const uint16_t vlanID, bool cfi, uint8_t priority, uint16_t etherType);
~VlanLayer() {}
/**
* Get a pointer to the VLAN header. Notice this points directly to the data, so every change will change the actual packet data
* @return A pointer to the vlan_header
*/
inline vlan_header* getVlanHeader() { return (vlan_header*)m_Data; }
/**
* Get the VLAN ID value. This method differs from vlan_header#vlanID because vlan_header#vlanID is 12 bits long in a 16 bit field.
* This methods extracts only the 12 bit relevant for the VLAN ID
* @return VLAN ID value
* @todo Verify it works in big endian machines as well
*/
inline uint16_t getVlanID() { return getVlanHeader()->vlanID >> 4; }
/**
* @return The CFI bit value
* @todo Verify it works in big endian machines as well
*/
inline uint8_t getCFI() { return getVlanHeader()->vlanID & 0x1; }
/**
* @return The priority value
* @todo Verify it works in big endian machines as well
*/
inline uint8_t getPriority() { return (getVlanHeader()->vlanID & 0xF) >> 1; }
/**
* Set VLAN ID. This method differs from setting vlan_header#vlanID because vlan_header#vlanID is 12 bits long in a 16 bit field.
* This methods sets only the 12 bit relevant for the VLAN ID
* @param[in] id The VLAN ID to set
* @todo Verify it works in big endian machines as well
*/
inline void setVlanID(uint16_t id) { getVlanHeader()->vlanID = ((id << 4) & 0xff0) | (id >> 8); }
/**
* Set CFI bit
* @param[in] cfi The CFI bit to set
* @todo Verify it works in big endian machines as well
*/
inline void setCFI(bool cfi) { getVlanHeader()->vlanID |= cfi; }
/**
* Set priority value
* @param[in] priority The priority value to set
* @todo Verify it works in big endian machines as well
*/
inline void setPriority(uint8_t priority) { getVlanHeader()->vlanID |= ((priority & 0x7) << 1); }
// implement abstract methods
/**
* Currently identifies the following next layers: IPv4Layer, IPv6Layer, ArpLayer, VlanLayer, MplsLayer. Otherwise sets PayloadLayer
*/
void parseNextLayer();
/**
* @return Size of vlan_header
*/
inline size_t getHeaderLen() { return sizeof(vlan_header); }
/**
* Does nothing for this layer
*/
void computeCalculateFields() {}
std::string toString();
OsiModelLayer getOsiModelLayer() { return OsiModelDataLinkLayer; }
};
} // namespace pcpp
#endif /* PACKETPP_VLAN_LAYER */