/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 | 64.1k | { |
31 | 64.1k | return be16toh(getVlanHeader()->vlan) & 0xFFF; |
32 | 64.1k | } |
33 | | |
34 | | uint8_t VlanLayer::getCFI() const |
35 | 64.1k | { |
36 | 64.1k | return ((be16toh(getVlanHeader()->vlan) >> 12) & 1); |
37 | 64.1k | } |
38 | | |
39 | | uint8_t VlanLayer::getPriority() const |
40 | 64.1k | { |
41 | 64.1k | return (be16toh(getVlanHeader()->vlan) >> 13) & 7; |
42 | 64.1k | } |
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 | 281k | { |
61 | 281k | if (m_DataLen <= sizeof(vlan_header)) |
62 | 378 | return; |
63 | | |
64 | 281k | uint8_t* payload = m_Data + sizeof(vlan_header); |
65 | 281k | size_t payloadLen = m_DataLen - sizeof(vlan_header); |
66 | | |
67 | 281k | vlan_header* hdr = getVlanHeader(); |
68 | 281k | switch (be16toh(hdr->etherType)) |
69 | 281k | { |
70 | 117k | case PCPP_ETHERTYPE_IP: |
71 | 117k | { |
72 | 117k | tryConstructNextLayerWithFallback<IPv4Layer, PayloadLayer>(payload, payloadLen); |
73 | 117k | break; |
74 | 0 | } |
75 | 19.2k | case PCPP_ETHERTYPE_IPV6: |
76 | 19.2k | { |
77 | 19.2k | tryConstructNextLayerWithFallback<IPv6Layer, PayloadLayer>(payload, payloadLen); |
78 | 19.2k | break; |
79 | 0 | } |
80 | 1.81k | case PCPP_ETHERTYPE_ARP: |
81 | 1.81k | { |
82 | 1.81k | constructNextLayer<ArpLayer>(payload, payloadLen); |
83 | 1.81k | break; |
84 | 0 | } |
85 | 77.2k | case PCPP_ETHERTYPE_VLAN: |
86 | 77.3k | case PCPP_ETHERTYPE_IEEE_802_1AD: |
87 | 77.3k | { |
88 | 77.3k | constructNextLayer<VlanLayer>(payload, payloadLen); |
89 | 77.3k | break; |
90 | 77.2k | } |
91 | 60.0k | case PCPP_ETHERTYPE_PPPOES: |
92 | 60.0k | { |
93 | 60.0k | tryConstructNextLayerWithFallback<PPPoESessionLayer, PayloadLayer>(payload, payloadLen); |
94 | 60.0k | break; |
95 | 77.2k | } |
96 | 1.43k | case PCPP_ETHERTYPE_PPPOED: |
97 | 1.43k | { |
98 | 1.43k | tryConstructNextLayerWithFallback<PPPoEDiscoveryLayer, PayloadLayer>(payload, payloadLen); |
99 | 1.43k | break; |
100 | 77.2k | } |
101 | 2.11k | case PCPP_ETHERTYPE_MPLS: |
102 | 2.11k | { |
103 | 2.11k | tryConstructNextLayerWithFallback<MplsLayer, PayloadLayer>(payload, payloadLen); |
104 | 2.11k | break; |
105 | 77.2k | } |
106 | 1.96k | default: |
107 | 1.96k | { |
108 | 1.96k | if ((be16toh(hdr->etherType) < 1500)) |
109 | 1.20k | { |
110 | 1.20k | tryConstructNextLayerWithFallback<LLCLayer, PayloadLayer>(payload, payloadLen); |
111 | 1.20k | } |
112 | 753 | else |
113 | 753 | { |
114 | 753 | constructNextLayer<PayloadLayer>(payload, payloadLen); |
115 | 753 | } |
116 | 1.96k | break; |
117 | 77.2k | } |
118 | 281k | } |
119 | 281k | } |
120 | | |
121 | | void VlanLayer::computeCalculateFields() |
122 | 32.0k | { |
123 | 32.0k | if (m_NextLayer == nullptr) |
124 | 126 | return; |
125 | | |
126 | 31.9k | switch (m_NextLayer->getProtocol()) |
127 | 31.9k | { |
128 | 14.1k | case IPv4: |
129 | 14.1k | getVlanHeader()->etherType = htobe16(PCPP_ETHERTYPE_IP); |
130 | 14.1k | break; |
131 | 3.09k | case IPv6: |
132 | 3.09k | getVlanHeader()->etherType = htobe16(PCPP_ETHERTYPE_IPV6); |
133 | 3.09k | break; |
134 | 365 | case ARP: |
135 | 365 | getVlanHeader()->etherType = htobe16(PCPP_ETHERTYPE_ARP); |
136 | 365 | break; |
137 | 7.59k | case VLAN: |
138 | 7.59k | getVlanHeader()->etherType = htobe16(PCPP_ETHERTYPE_VLAN); |
139 | 7.59k | break; |
140 | 6.76k | default: |
141 | 6.76k | return; |
142 | 31.9k | } |
143 | 31.9k | } |
144 | | |
145 | | std::string VlanLayer::toString() const |
146 | 64.1k | { |
147 | 64.1k | std::ostringstream cfiStream; |
148 | 64.1k | cfiStream << (int)getCFI(); |
149 | 64.1k | std::ostringstream priStream; |
150 | 64.1k | priStream << (int)getPriority(); |
151 | 64.1k | std::ostringstream idStream; |
152 | 64.1k | idStream << getVlanID(); |
153 | | |
154 | 64.1k | return "VLAN Layer, Priority: " + priStream.str() + ", Vlan ID: " + idStream.str() + |
155 | 64.1k | ", CFI: " + cfiStream.str(); |
156 | 64.1k | } |
157 | | |
158 | | } // namespace pcpp |