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