/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 | allocData(sizeof(vlan_header)); |
20 | 0 | m_Protocol = VLAN; |
21 | |
|
22 | 0 | vlan_header* vlanHeader = getVlanHeader(); |
23 | 0 | setVlanID(vlanID); |
24 | 0 | setCFI(cfi); |
25 | 0 | setPriority(priority); |
26 | 0 | vlanHeader->etherType = htobe16(etherType); |
27 | 0 | } |
28 | | |
29 | | uint16_t VlanLayer::getVlanID() const |
30 | 61.2k | { |
31 | 61.2k | return be16toh(getVlanHeader()->vlan) & 0xFFF; |
32 | 61.2k | } |
33 | | |
34 | | uint8_t VlanLayer::getCFI() const |
35 | 61.2k | { |
36 | 61.2k | return ((be16toh(getVlanHeader()->vlan) >> 12) & 1); |
37 | 61.2k | } |
38 | | |
39 | | uint8_t VlanLayer::getPriority() const |
40 | 61.2k | { |
41 | 61.2k | return (be16toh(getVlanHeader()->vlan) >> 13) & 7; |
42 | 61.2k | } |
43 | | |
44 | | void VlanLayer::setVlanID(uint16_t id) |
45 | 0 | { |
46 | 0 | getVlanHeader()->vlan = htobe16((be16toh(getVlanHeader()->vlan) & (~0xFFF)) | (id & 0xFFF)); |
47 | 0 | } |
48 | | |
49 | | void VlanLayer::setCFI(bool cfi) |
50 | 0 | { |
51 | 0 | getVlanHeader()->vlan = htobe16((be16toh(getVlanHeader()->vlan) & (~(1 << 12))) | ((cfi & 1) << 12)); |
52 | 0 | } |
53 | | |
54 | | void VlanLayer::setPriority(uint8_t priority) |
55 | 0 | { |
56 | 0 | getVlanHeader()->vlan = htobe16((be16toh(getVlanHeader()->vlan) & (~(7 << 13))) | ((priority & 7) << 13)); |
57 | 0 | } |
58 | | |
59 | | void VlanLayer::parseNextLayer() |
60 | 255k | { |
61 | 255k | if (m_DataLen <= sizeof(vlan_header)) |
62 | 236 | return; |
63 | | |
64 | 255k | uint8_t* payload = m_Data + sizeof(vlan_header); |
65 | 255k | size_t payloadLen = m_DataLen - sizeof(vlan_header); |
66 | | |
67 | 255k | vlan_header* hdr = getVlanHeader(); |
68 | 255k | switch (be16toh(hdr->etherType)) |
69 | 255k | { |
70 | 93.7k | case PCPP_ETHERTYPE_IP: |
71 | 93.7k | { |
72 | 93.7k | tryConstructNextLayerWithFallback<IPv4Layer, PayloadLayer>(payload, payloadLen); |
73 | 93.7k | break; |
74 | 0 | } |
75 | 19.1k | case PCPP_ETHERTYPE_IPV6: |
76 | 19.1k | { |
77 | 19.1k | tryConstructNextLayerWithFallback<IPv6Layer, PayloadLayer>(payload, payloadLen); |
78 | 19.1k | break; |
79 | 0 | } |
80 | 5.82k | case PCPP_ETHERTYPE_ARP: |
81 | 5.82k | { |
82 | 5.82k | constructNextLayer<ArpLayer>(payload, payloadLen); |
83 | 5.82k | break; |
84 | 0 | } |
85 | 59.4k | case PCPP_ETHERTYPE_VLAN: |
86 | 59.5k | case PCPP_ETHERTYPE_IEEE_802_1AD: |
87 | 59.5k | { |
88 | 59.5k | constructNextLayer<VlanLayer>(payload, payloadLen); |
89 | 59.5k | break; |
90 | 59.4k | } |
91 | 67.7k | case PCPP_ETHERTYPE_PPPOES: |
92 | 67.7k | { |
93 | 67.7k | tryConstructNextLayerWithFallback<PPPoESessionLayer, PayloadLayer>(payload, payloadLen); |
94 | 67.7k | break; |
95 | 59.4k | } |
96 | 1.06k | case PCPP_ETHERTYPE_PPPOED: |
97 | 1.06k | { |
98 | 1.06k | tryConstructNextLayerWithFallback<PPPoEDiscoveryLayer, PayloadLayer>(payload, payloadLen); |
99 | 1.06k | break; |
100 | 59.4k | } |
101 | 1.17k | case PCPP_ETHERTYPE_MPLS: |
102 | 1.17k | { |
103 | 1.17k | constructNextLayer<MplsLayer>(payload, payloadLen); |
104 | 1.17k | break; |
105 | 59.4k | } |
106 | 7.39k | default: |
107 | 7.39k | { |
108 | 7.39k | if ((be16toh(hdr->etherType) < 1500)) |
109 | 5.97k | { |
110 | 5.97k | tryConstructNextLayerWithFallback<LLCLayer, PayloadLayer>(payload, payloadLen); |
111 | 5.97k | } |
112 | 1.42k | else |
113 | 1.42k | { |
114 | 1.42k | constructNextLayer<PayloadLayer>(payload, payloadLen); |
115 | 1.42k | } |
116 | 7.39k | break; |
117 | 59.4k | } |
118 | 255k | } |
119 | 255k | } |
120 | | |
121 | | void VlanLayer::computeCalculateFields() |
122 | 30.6k | { |
123 | 30.6k | if (m_NextLayer == nullptr) |
124 | 76 | return; |
125 | | |
126 | 30.5k | switch (m_NextLayer->getProtocol()) |
127 | 30.5k | { |
128 | 11.7k | case IPv4: |
129 | 11.7k | getVlanHeader()->etherType = htobe16(PCPP_ETHERTYPE_IP); |
130 | 11.7k | break; |
131 | 3.08k | case IPv6: |
132 | 3.08k | getVlanHeader()->etherType = htobe16(PCPP_ETHERTYPE_IPV6); |
133 | 3.08k | break; |
134 | 1.15k | case ARP: |
135 | 1.15k | getVlanHeader()->etherType = htobe16(PCPP_ETHERTYPE_ARP); |
136 | 1.15k | break; |
137 | 5.99k | case VLAN: |
138 | 5.99k | getVlanHeader()->etherType = htobe16(PCPP_ETHERTYPE_VLAN); |
139 | 5.99k | break; |
140 | 8.60k | default: |
141 | 8.60k | return; |
142 | 30.5k | } |
143 | 30.5k | } |
144 | | |
145 | | std::string VlanLayer::toString() const |
146 | 61.2k | { |
147 | 61.2k | std::ostringstream cfiStream; |
148 | 61.2k | cfiStream << (int)getCFI(); |
149 | 61.2k | std::ostringstream priStream; |
150 | 61.2k | priStream << (int)getPriority(); |
151 | 61.2k | std::ostringstream idStream; |
152 | 61.2k | idStream << getVlanID(); |
153 | | |
154 | 61.2k | return "VLAN Layer, Priority: " + priStream.str() + ", Vlan ID: " + idStream.str() + |
155 | 61.2k | ", CFI: " + cfiStream.str(); |
156 | 61.2k | } |
157 | | |
158 | | } // namespace pcpp |