/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 | 24.2k | { |
34 | 24.2k | return be16toh(getVlanHeader()->vlan) & 0xFFF; |
35 | 24.2k | } |
36 | | |
37 | | uint8_t VlanLayer::getCFI() const |
38 | 24.2k | { |
39 | 24.2k | return ((be16toh(getVlanHeader()->vlan) >> 12) & 1); |
40 | 24.2k | } |
41 | | |
42 | | uint8_t VlanLayer::getPriority() const |
43 | 24.2k | { |
44 | 24.2k | return (be16toh(getVlanHeader()->vlan) >> 13) & 7; |
45 | 24.2k | } |
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 | 104k | { |
64 | 104k | if (m_DataLen <= sizeof(vlan_header)) |
65 | 360 | return; |
66 | | |
67 | 104k | uint8_t* payload = m_Data + sizeof(vlan_header); |
68 | 104k | size_t payloadLen = m_DataLen - sizeof(vlan_header); |
69 | | |
70 | 104k | vlan_header* hdr = getVlanHeader(); |
71 | 104k | switch (be16toh(hdr->etherType)) |
72 | 104k | { |
73 | 46.5k | case PCPP_ETHERTYPE_IP: |
74 | 46.5k | m_NextLayer = IPv4Layer::isDataValid(payload, payloadLen) |
75 | 46.5k | ? static_cast<Layer*>(new IPv4Layer(payload, payloadLen, this, m_Packet)) |
76 | 46.5k | : static_cast<Layer*>(new PayloadLayer(payload, payloadLen, this, m_Packet)); |
77 | 46.5k | break; |
78 | 15.5k | case PCPP_ETHERTYPE_IPV6: |
79 | 15.5k | m_NextLayer = IPv6Layer::isDataValid(payload, payloadLen) |
80 | 15.5k | ? static_cast<Layer*>(new IPv6Layer(payload, payloadLen, this, m_Packet)) |
81 | 15.5k | : static_cast<Layer*>(new PayloadLayer(payload, payloadLen, this, m_Packet)); |
82 | 15.5k | break; |
83 | 1.50k | case PCPP_ETHERTYPE_ARP: |
84 | 1.50k | m_NextLayer = new ArpLayer(payload, payloadLen, this, m_Packet); |
85 | 1.50k | break; |
86 | 21.4k | case PCPP_ETHERTYPE_VLAN: |
87 | 21.4k | case PCPP_ETHERTYPE_IEEE_802_1AD: |
88 | 21.4k | m_NextLayer = new VlanLayer(payload, payloadLen, this, m_Packet); |
89 | 21.4k | break; |
90 | 17.9k | case PCPP_ETHERTYPE_PPPOES: |
91 | 17.9k | m_NextLayer = PPPoESessionLayer::isDataValid(payload, payloadLen) |
92 | 17.9k | ? static_cast<Layer*>(new PPPoESessionLayer(payload, payloadLen, this, m_Packet)) |
93 | 17.9k | : static_cast<Layer*>(new PayloadLayer(payload, payloadLen, this, m_Packet)); |
94 | 17.9k | break; |
95 | 15 | case PCPP_ETHERTYPE_PPPOED: |
96 | 15 | m_NextLayer = PPPoEDiscoveryLayer::isDataValid(payload, payloadLen) |
97 | 15 | ? static_cast<Layer*>(new PPPoEDiscoveryLayer(payload, payloadLen, this, m_Packet)) |
98 | 15 | : static_cast<Layer*>(new PayloadLayer(payload, payloadLen, this, m_Packet)); |
99 | 15 | break; |
100 | 378 | case PCPP_ETHERTYPE_MPLS: |
101 | 378 | m_NextLayer = new MplsLayer(payload, payloadLen, this, m_Packet); |
102 | 378 | break; |
103 | 996 | default: |
104 | 996 | m_NextLayer = (be16toh(hdr->etherType) < 1500 && LLCLayer::isDataValid(payload, payloadLen)) |
105 | 996 | ? static_cast<Layer*>(new LLCLayer(payload, payloadLen, this, m_Packet)) |
106 | 996 | : static_cast<Layer*>(new PayloadLayer(payload, payloadLen, this, m_Packet)); |
107 | 104k | } |
108 | 104k | } |
109 | | |
110 | | void VlanLayer::computeCalculateFields() |
111 | 12.1k | { |
112 | 12.1k | if (m_NextLayer == nullptr) |
113 | 120 | return; |
114 | | |
115 | 12.0k | switch (m_NextLayer->getProtocol()) |
116 | 12.0k | { |
117 | 5.41k | case IPv4: |
118 | 5.41k | getVlanHeader()->etherType = htobe16(PCPP_ETHERTYPE_IP); |
119 | 5.41k | break; |
120 | 2.26k | case IPv6: |
121 | 2.26k | getVlanHeader()->etherType = htobe16(PCPP_ETHERTYPE_IPV6); |
122 | 2.26k | break; |
123 | 301 | case ARP: |
124 | 301 | getVlanHeader()->etherType = htobe16(PCPP_ETHERTYPE_ARP); |
125 | 301 | break; |
126 | 2.03k | case VLAN: |
127 | 2.03k | getVlanHeader()->etherType = htobe16(PCPP_ETHERTYPE_VLAN); |
128 | 2.03k | break; |
129 | 1.99k | default: |
130 | 1.99k | return; |
131 | 12.0k | } |
132 | 12.0k | } |
133 | | |
134 | | std::string VlanLayer::toString() const |
135 | 24.2k | { |
136 | 24.2k | std::ostringstream cfiStream; |
137 | 24.2k | cfiStream << (int)getCFI(); |
138 | 24.2k | std::ostringstream priStream; |
139 | 24.2k | priStream << (int)getPriority(); |
140 | 24.2k | std::ostringstream idStream; |
141 | 24.2k | idStream << getVlanID(); |
142 | | |
143 | 24.2k | return "VLAN Layer, Priority: " + priStream.str() + ", Vlan ID: " + idStream.str() + |
144 | 24.2k | ", CFI: " + cfiStream.str(); |
145 | 24.2k | } |
146 | | |
147 | | } // namespace pcpp |