/src/PcapPlusPlus/Packet++/src/VlanLayer.cpp
Line | Count | Source |
1 | | #define LOG_MODULE PacketLogModuleVlanLayer |
2 | | |
3 | | #include "VlanLayer.h" |
4 | | #include "IPv4Layer.h" |
5 | | #include "IPv6Layer.h" |
6 | | #include "PayloadLayer.h" |
7 | | #include "ArpLayer.h" |
8 | | #include "PPPoELayer.h" |
9 | | #include "MplsLayer.h" |
10 | | #include "LLCLayer.h" |
11 | | #include <sstream> |
12 | | #include "EndianPortable.h" |
13 | | |
14 | | namespace pcpp |
15 | | { |
16 | | |
17 | | VlanLayer::VlanLayer(const uint16_t vlanID, bool cfi, uint8_t priority, uint16_t etherType) |
18 | 0 | { |
19 | 0 | const size_t headerLen = sizeof(vlan_header); |
20 | 0 | m_DataLen = headerLen; |
21 | 0 | m_Data = new uint8_t[headerLen]; |
22 | 0 | memset(m_Data, 0, headerLen); |
23 | 0 | m_Protocol = VLAN; |
24 | |
|
25 | 0 | vlan_header* vlanHeader = getVlanHeader(); |
26 | 0 | setVlanID(vlanID); |
27 | 0 | setCFI(cfi); |
28 | 0 | setPriority(priority); |
29 | 0 | vlanHeader->etherType = htobe16(etherType); |
30 | 0 | } |
31 | | |
32 | | uint16_t VlanLayer::getVlanID() const |
33 | 16.6k | { |
34 | 16.6k | return be16toh(getVlanHeader()->vlan) & 0xFFF; |
35 | 16.6k | } |
36 | | |
37 | | uint8_t VlanLayer::getCFI() const |
38 | 16.6k | { |
39 | 16.6k | return ((be16toh(getVlanHeader()->vlan) >> 12) & 1); |
40 | 16.6k | } |
41 | | |
42 | | uint8_t VlanLayer::getPriority() const |
43 | 16.6k | { |
44 | 16.6k | return (be16toh(getVlanHeader()->vlan) >> 13) & 7; |
45 | 16.6k | } |
46 | | |
47 | | void VlanLayer::setVlanID(uint16_t id) |
48 | 0 | { |
49 | 0 | getVlanHeader()->vlan = htobe16((be16toh(getVlanHeader()->vlan) & (~0xFFF)) | (id & 0xFFF)); |
50 | 0 | } |
51 | | |
52 | | void VlanLayer::setCFI(bool cfi) |
53 | 0 | { |
54 | 0 | getVlanHeader()->vlan = htobe16((be16toh(getVlanHeader()->vlan) & (~(1 << 12))) | ((cfi & 1) << 12)); |
55 | 0 | } |
56 | | |
57 | | void VlanLayer::setPriority(uint8_t priority) |
58 | 0 | { |
59 | 0 | getVlanHeader()->vlan = htobe16((be16toh(getVlanHeader()->vlan) & (~(7 << 13))) | ((priority & 7) << 13)); |
60 | 0 | } |
61 | | |
62 | | void VlanLayer::parseNextLayer() |
63 | 76.3k | { |
64 | 76.3k | if (m_DataLen <= sizeof(vlan_header)) |
65 | 114 | return; |
66 | | |
67 | 76.2k | uint8_t* payload = m_Data + sizeof(vlan_header); |
68 | 76.2k | size_t payloadLen = m_DataLen - sizeof(vlan_header); |
69 | | |
70 | 76.2k | vlan_header* hdr = getVlanHeader(); |
71 | 76.2k | switch (be16toh(hdr->etherType)) |
72 | 76.2k | { |
73 | 12.1k | case PCPP_ETHERTYPE_IP: |
74 | 12.1k | { |
75 | 12.1k | tryConstructNextLayerWithFallback<IPv4Layer, PayloadLayer>(payload, payloadLen); |
76 | 12.1k | break; |
77 | 0 | } |
78 | 2.46k | case PCPP_ETHERTYPE_IPV6: |
79 | 2.46k | { |
80 | 2.46k | tryConstructNextLayerWithFallback<IPv6Layer, PayloadLayer>(payload, payloadLen); |
81 | 2.46k | break; |
82 | 0 | } |
83 | 3.98k | case PCPP_ETHERTYPE_ARP: |
84 | 3.98k | { |
85 | 3.98k | constructNextLayer<ArpLayer>(payload, payloadLen); |
86 | 3.98k | break; |
87 | 0 | } |
88 | 16.0k | case PCPP_ETHERTYPE_VLAN: |
89 | 16.2k | case PCPP_ETHERTYPE_IEEE_802_1AD: |
90 | 16.2k | { |
91 | 16.2k | constructNextLayer<VlanLayer>(payload, payloadLen); |
92 | 16.2k | break; |
93 | 16.0k | } |
94 | 16.7k | case PCPP_ETHERTYPE_PPPOES: |
95 | 16.7k | { |
96 | 16.7k | tryConstructNextLayerWithFallback<PPPoESessionLayer, PayloadLayer>(payload, payloadLen); |
97 | 16.7k | break; |
98 | 16.0k | } |
99 | 19 | case PCPP_ETHERTYPE_PPPOED: |
100 | 19 | { |
101 | 19 | tryConstructNextLayerWithFallback<PPPoEDiscoveryLayer, PayloadLayer>(payload, payloadLen); |
102 | 19 | break; |
103 | 16.0k | } |
104 | 17.4k | case PCPP_ETHERTYPE_MPLS: |
105 | 17.4k | { |
106 | 17.4k | constructNextLayer<MplsLayer>(payload, payloadLen); |
107 | 17.4k | break; |
108 | 16.0k | } |
109 | 7.25k | default: |
110 | 7.25k | { |
111 | 7.25k | if ((be16toh(hdr->etherType) < 1500)) |
112 | 5.60k | { |
113 | 5.60k | tryConstructNextLayerWithFallback<LLCLayer, PayloadLayer>(payload, payloadLen); |
114 | 5.60k | } |
115 | 1.65k | else |
116 | 1.65k | { |
117 | 1.65k | constructNextLayer<PayloadLayer>(payload, payloadLen); |
118 | 1.65k | } |
119 | 7.25k | break; |
120 | 16.0k | } |
121 | 76.2k | } |
122 | 76.2k | } |
123 | | |
124 | | void VlanLayer::computeCalculateFields() |
125 | 8.32k | { |
126 | 8.32k | if (m_NextLayer == nullptr) |
127 | 30 | return; |
128 | | |
129 | 8.29k | switch (m_NextLayer->getProtocol()) |
130 | 8.29k | { |
131 | 1.83k | case IPv4: |
132 | 1.83k | getVlanHeader()->etherType = htobe16(PCPP_ETHERTYPE_IP); |
133 | 1.83k | break; |
134 | 396 | case IPv6: |
135 | 396 | getVlanHeader()->etherType = htobe16(PCPP_ETHERTYPE_IPV6); |
136 | 396 | break; |
137 | 794 | case ARP: |
138 | 794 | getVlanHeader()->etherType = htobe16(PCPP_ETHERTYPE_ARP); |
139 | 794 | break; |
140 | 1.11k | case VLAN: |
141 | 1.11k | getVlanHeader()->etherType = htobe16(PCPP_ETHERTYPE_VLAN); |
142 | 1.11k | break; |
143 | 4.16k | default: |
144 | 4.16k | return; |
145 | 8.29k | } |
146 | 8.29k | } |
147 | | |
148 | | std::string VlanLayer::toString() const |
149 | 16.6k | { |
150 | 16.6k | std::ostringstream cfiStream; |
151 | 16.6k | cfiStream << (int)getCFI(); |
152 | 16.6k | std::ostringstream priStream; |
153 | 16.6k | priStream << (int)getPriority(); |
154 | 16.6k | std::ostringstream idStream; |
155 | 16.6k | idStream << getVlanID(); |
156 | | |
157 | 16.6k | return "VLAN Layer, Priority: " + priStream.str() + ", Vlan ID: " + idStream.str() + |
158 | 16.6k | ", CFI: " + cfiStream.str(); |
159 | 16.6k | } |
160 | | |
161 | | } // namespace pcpp |