/src/PcapPlusPlus/Packet++/src/PPPoELayer.cpp
Line | Count | Source |
1 | 0 | #define LOG_MODULE PacketLogModulePPPoELayer |
2 | | |
3 | | #include "PPPoELayer.h" |
4 | | #include "IPv4Layer.h" |
5 | | #include "IPv6Layer.h" |
6 | | #include "PayloadLayer.h" |
7 | | #include "Logger.h" |
8 | | #include <unordered_map> |
9 | | #include <sstream> |
10 | | #include "EndianPortable.h" |
11 | | |
12 | | namespace pcpp |
13 | | { |
14 | | |
15 | | /// PPPoELayer |
16 | | /// ~~~~~~~~~~ |
17 | | |
18 | | PPPoELayer::PPPoELayer(uint8_t version, uint8_t type, PPPoELayer::PPPoECode code, uint16_t sessionId, |
19 | | size_t additionalBytesToAllocate) |
20 | 0 | { |
21 | 0 | const size_t dataLen = sizeof(pppoe_header) + additionalBytesToAllocate; |
22 | 0 | allocData(dataLen); |
23 | |
|
24 | 0 | pppoe_header* pppoeHdr = getPPPoEHeader(); |
25 | 0 | pppoeHdr->version = (version & 0xf); |
26 | 0 | pppoeHdr->type = (type & 0x0f); |
27 | 0 | pppoeHdr->code = code; |
28 | 0 | pppoeHdr->sessionId = htobe16(sessionId); |
29 | 0 | pppoeHdr->payloadLength = 0; |
30 | 0 | } |
31 | | |
32 | | void PPPoELayer::computeCalculateFields() |
33 | 0 | { |
34 | 0 | pppoe_header* pppoeHdr = getPPPoEHeader(); |
35 | 0 | pppoeHdr->payloadLength = htobe16(m_DataLen - sizeof(pppoe_header)); |
36 | 0 | } |
37 | | |
38 | | const FieldDescriptor PPPoELayer::SerializedFields::Code{ Layer::SerializedFields::MaxID + 1, "code" }; |
39 | | const FieldDescriptor PPPoELayer::SerializedFields::Version{ Layer::SerializedFields::MaxID + 2, "version" }; |
40 | | const FieldDescriptor PPPoELayer::SerializedFields::Type{ Layer::SerializedFields::MaxID + 3, "type" }; |
41 | | const FieldDescriptor PPPoELayer::SerializedFields::SessionID{ Layer::SerializedFields::MaxID + 4, "sessionID" }; |
42 | | |
43 | | void PPPoELayer::serializeLayer(ObjectScope& serializer) const |
44 | 0 | { |
45 | 0 | auto* header = getPPPoEHeader(); |
46 | 0 | serializer.writeField(SerializedFields::Code, header->code); |
47 | 0 | serializer.writeField(SerializedFields::Version, header->version); |
48 | 0 | serializer.writeField(SerializedFields::Type, header->type); |
49 | 0 | serializer.writeField(SerializedFields::SessionID, be16toh(header->sessionId)); |
50 | 0 | } |
51 | | |
52 | | /// PPPoESessionLayer |
53 | | /// ~~~~~~~~~~~~~~~~~ |
54 | | |
55 | | void PPPoESessionLayer::parseNextLayer() |
56 | 0 | { |
57 | 0 | size_t headerLen = getHeaderLen(); |
58 | 0 | if (m_DataLen <= headerLen) |
59 | 0 | return; |
60 | | |
61 | 0 | uint8_t* payload = m_Data + headerLen; |
62 | 0 | size_t payloadLen = m_DataLen - headerLen; |
63 | |
|
64 | 0 | switch (getPPPNextProtocol()) |
65 | 0 | { |
66 | 0 | case PCPP_PPP_IP: |
67 | 0 | tryConstructNextLayerWithFallback<IPv4Layer, PayloadLayer>(payload, payloadLen); |
68 | 0 | break; |
69 | 0 | case PCPP_PPP_IPV6: |
70 | 0 | tryConstructNextLayerWithFallback<IPv6Layer, PayloadLayer>(payload, payloadLen); |
71 | 0 | break; |
72 | 0 | default: |
73 | 0 | constructNextLayer<PayloadLayer>(payload, payloadLen); |
74 | 0 | break; |
75 | 0 | } |
76 | 0 | } |
77 | | |
78 | | uint16_t PPPoESessionLayer::getPPPNextProtocol() const |
79 | 0 | { |
80 | 0 | if (m_DataLen < getHeaderLen()) |
81 | 0 | { |
82 | 0 | PCPP_LOG_ERROR("ERROR: size of layer is smaller then PPPoE session header"); |
83 | 0 | return 0; |
84 | 0 | } |
85 | | |
86 | 0 | uint16_t pppNextProto = *reinterpret_cast<uint16_t*>(m_Data + sizeof(pppoe_header)); |
87 | 0 | return be16toh(pppNextProto); |
88 | 0 | } |
89 | | |
90 | | void PPPoESessionLayer::setPPPNextProtocol(uint16_t nextProtocol) |
91 | 0 | { |
92 | 0 | if (m_DataLen < getHeaderLen()) |
93 | 0 | { |
94 | 0 | PCPP_LOG_ERROR("ERROR: size of layer is smaller then PPPoE session header"); |
95 | 0 | return; |
96 | 0 | } |
97 | | |
98 | 0 | uint16_t* pppProto = reinterpret_cast<uint16_t*>(m_Data + sizeof(pppoe_header)); |
99 | 0 | *pppProto = htobe16(nextProtocol); |
100 | 0 | } |
101 | | |
102 | | std::unordered_map<uint16_t, std::string> createPPPNextProtoToStringMap() |
103 | 2 | { |
104 | 2 | std::unordered_map<uint16_t, std::string> tempMap; |
105 | 2 | tempMap[PCPP_PPP_PADDING] = "Padding Protocol"; |
106 | 2 | tempMap[PCPP_PPP_ROHC_SCID] = "ROHC small-CID"; |
107 | 2 | tempMap[PCPP_PPP_ROHC_LCID] = "ROHC large-CID"; |
108 | 2 | tempMap[PCPP_PPP_IP] = "Internet Protocol version 4"; |
109 | 2 | tempMap[PCPP_PPP_OSI] = "OSI Network Layer"; |
110 | 2 | tempMap[PCPP_PPP_XNSIDP] = "Xerox NS IDP"; |
111 | 2 | tempMap[PCPP_PPP_DEC4] = "DECnet Phase IV"; |
112 | 2 | tempMap[PCPP_PPP_AT] = "Appletalk"; |
113 | 2 | tempMap[PCPP_PPP_IPX] = "Novell IPX"; |
114 | 2 | tempMap[PCPP_PPP_VJC_COMP] = "Van Jacobson Compressed TCP/IP"; |
115 | 2 | tempMap[PCPP_PPP_VJC_UNCOMP] = "Van Jacobson Uncompressed TCP/IP"; |
116 | 2 | tempMap[PCPP_PPP_BCP] = "Bridging PDU"; |
117 | 2 | tempMap[PCPP_PPP_ST] = "Stream Protocol (ST-II)"; |
118 | 2 | tempMap[PCPP_PPP_VINES] = "Banyan Vines"; |
119 | 2 | tempMap[PCPP_PPP_AT_EDDP] = "AppleTalk EDDP"; |
120 | 2 | tempMap[PCPP_PPP_AT_SB] = "AppleTalk SmartBuffered"; |
121 | 2 | tempMap[PCPP_PPP_MP] = "Multi-Link"; |
122 | 2 | tempMap[PCPP_PPP_NB] = "NETBIOS Framing"; |
123 | 2 | tempMap[PCPP_PPP_CISCO] = "Cisco Systems"; |
124 | 2 | tempMap[PCPP_PPP_ASCOM] = "Ascom Timeplex"; |
125 | 2 | tempMap[PCPP_PPP_LBLB] = "Fujitsu Link Backup and Load Balancing (LBLB)"; |
126 | 2 | tempMap[PCPP_PPP_RL] = "DCA Remote Lan"; |
127 | 2 | tempMap[PCPP_PPP_SDTP] = "Serial Data Transport Protocol (PPP-SDTP)"; |
128 | 2 | tempMap[PCPP_PPP_LLC] = "SNA over 802.2"; |
129 | 2 | tempMap[PCPP_PPP_SNA] = "SNA"; |
130 | 2 | tempMap[PCPP_PPP_IPV6HC] = "IPv6 Header Compression "; |
131 | 2 | tempMap[PCPP_PPP_KNX] = "KNX Bridging Data"; |
132 | 2 | tempMap[PCPP_PPP_ENCRYPT] = "Encryption"; |
133 | 2 | tempMap[PCPP_PPP_ILE] = "Individual Link Encryption"; |
134 | 2 | tempMap[PCPP_PPP_IPV6] = "Internet Protocol version 6"; |
135 | 2 | tempMap[PCPP_PPP_MUX] = "PPP Muxing"; |
136 | 2 | tempMap[PCPP_PPP_VSNP] = "Vendor-Specific Network Protocol (VSNP)"; |
137 | 2 | tempMap[PCPP_PPP_TNP] = "TRILL Network Protocol (TNP)"; |
138 | 2 | tempMap[PCPP_PPP_RTP_FH] = "RTP IPHC Full Header"; |
139 | 2 | tempMap[PCPP_PPP_RTP_CTCP] = "RTP IPHC Compressed TCP"; |
140 | 2 | tempMap[PCPP_PPP_RTP_CNTCP] = "RTP IPHC Compressed Non TCP"; |
141 | 2 | tempMap[PCPP_PPP_RTP_CUDP8] = "RTP IPHC Compressed UDP 8"; |
142 | 2 | tempMap[PCPP_PPP_RTP_CRTP8] = "RTP IPHC Compressed RTP 8"; |
143 | 2 | tempMap[PCPP_PPP_STAMPEDE] = "Stampede Bridging"; |
144 | 2 | tempMap[PCPP_PPP_MPPLUS] = "MP+ Protocol"; |
145 | 2 | tempMap[PCPP_PPP_NTCITS_IPI] = "NTCITS IPI"; |
146 | 2 | tempMap[PCPP_PPP_ML_SLCOMP] = "Single link compression in multilink"; |
147 | 2 | tempMap[PCPP_PPP_COMP] = "Compressed datagram"; |
148 | 2 | tempMap[PCPP_PPP_STP_HELLO] = "802.1d Hello Packets"; |
149 | 2 | tempMap[PCPP_PPP_IBM_SR] = "IBM Source Routing BPDU"; |
150 | 2 | tempMap[PCPP_PPP_DEC_LB] = "DEC LANBridge100 Spanning Tree"; |
151 | 2 | tempMap[PCPP_PPP_CDP] = "Cisco Discovery Protocol"; |
152 | 2 | tempMap[PCPP_PPP_NETCS] = "Netcs Twin Routing"; |
153 | 2 | tempMap[PCPP_PPP_STP] = "STP - Scheduled Transfer Protocol"; |
154 | 2 | tempMap[PCPP_PPP_EDP] = "EDP - Extreme Discovery Protocol"; |
155 | 2 | tempMap[PCPP_PPP_OSCP] = "Optical Supervisory Channel Protocol (OSCP)"; |
156 | 2 | tempMap[PCPP_PPP_OSCP2] = "Optical Supervisory Channel Protocol (OSCP)"; |
157 | 2 | tempMap[PCPP_PPP_LUXCOM] = "Luxcom"; |
158 | 2 | tempMap[PCPP_PPP_SIGMA] = "Sigma Network Systems"; |
159 | 2 | tempMap[PCPP_PPP_ACSP] = "Apple Client Server Protocol"; |
160 | 2 | tempMap[PCPP_PPP_MPLS_UNI] = "MPLS Unicast"; |
161 | 2 | tempMap[PCPP_PPP_MPLS_MULTI] = "MPLS Multicast"; |
162 | 2 | tempMap[PCPP_PPP_P12844] = "IEEE p1284.4 standard - data packets"; |
163 | 2 | tempMap[PCPP_PPP_TETRA] = "ETSI TETRA Network Protocol Type 1"; |
164 | 2 | tempMap[PCPP_PPP_MFTP] = "Multichannel Flow Treatment Protocol"; |
165 | 2 | tempMap[PCPP_PPP_RTP_CTCPND] = "RTP IPHC Compressed TCP No Delta"; |
166 | 2 | tempMap[PCPP_PPP_RTP_CS] = "RTP IPHC Context State"; |
167 | 2 | tempMap[PCPP_PPP_RTP_CUDP16] = "RTP IPHC Compressed UDP 16"; |
168 | 2 | tempMap[PCPP_PPP_RTP_CRDP16] = "RTP IPHC Compressed RTP 16"; |
169 | 2 | tempMap[PCPP_PPP_CCCP] = "Cray Communications Control Protocol"; |
170 | 2 | tempMap[PCPP_PPP_CDPD_MNRP] = "CDPD Mobile Network Registration Protocol"; |
171 | 2 | tempMap[PCPP_PPP_EXPANDAP] = "Expand accelerator protocol"; |
172 | 2 | tempMap[PCPP_PPP_ODSICP] = "ODSICP NCP"; |
173 | 2 | tempMap[PCPP_PPP_DOCSIS] = "DOCSIS DLL"; |
174 | 2 | tempMap[PCPP_PPP_CETACEANNDP] = "Cetacean Network Detection Protocol"; |
175 | 2 | tempMap[PCPP_PPP_LZS] = "Stacker LZS"; |
176 | 2 | tempMap[PCPP_PPP_REFTEK] = "RefTek Protocol"; |
177 | 2 | tempMap[PCPP_PPP_FC] = "Fibre Channel"; |
178 | 2 | tempMap[PCPP_PPP_EMIT] = "EMIT Protocols"; |
179 | 2 | tempMap[PCPP_PPP_VSP] = "Vendor-Specific Protocol (VSP)"; |
180 | 2 | tempMap[PCPP_PPP_TLSP] = "TRILL Link State Protocol (TLSP)"; |
181 | 2 | tempMap[PCPP_PPP_IPCP] = "Internet Protocol Control Protocol"; |
182 | 2 | tempMap[PCPP_PPP_OSINLCP] = "OSI Network Layer Control Protocol"; |
183 | 2 | tempMap[PCPP_PPP_XNSIDPCP] = "Xerox NS IDP Control Protocol"; |
184 | 2 | tempMap[PCPP_PPP_DECNETCP] = "DECnet Phase IV Control Protocol"; |
185 | 2 | tempMap[PCPP_PPP_ATCP] = "AppleTalk Control Protocol"; |
186 | 2 | tempMap[PCPP_PPP_IPXCP] = "Novell IPX Control Protocol"; |
187 | 2 | tempMap[PCPP_PPP_BRIDGENCP] = "Bridging NCP"; |
188 | 2 | tempMap[PCPP_PPP_SPCP] = "Stream Protocol Control Protocol"; |
189 | 2 | tempMap[PCPP_PPP_BVCP] = "Banyan Vines Control Protocol"; |
190 | 2 | tempMap[PCPP_PPP_MLCP] = "Multi-Link Control Protocol"; |
191 | 2 | tempMap[PCPP_PPP_NBCP] = "NETBIOS Framing Control Protocol"; |
192 | 2 | tempMap[PCPP_PPP_CISCOCP] = "Cisco Systems Control Protocol"; |
193 | 2 | tempMap[PCPP_PPP_ASCOMCP] = "Ascom Timeplex"; |
194 | 2 | tempMap[PCPP_PPP_LBLBCP] = "Fujitsu LBLB Control Protocol"; |
195 | 2 | tempMap[PCPP_PPP_RLNCP] = "DCA Remote Lan Network Control Protocol (RLNCP)"; |
196 | 2 | tempMap[PCPP_PPP_SDCP] = "Serial Data Control Protocol (PPP-SDCP)"; |
197 | 2 | tempMap[PCPP_PPP_LLCCP] = "SNA over 802.2 Control Protocol"; |
198 | 2 | tempMap[PCPP_PPP_SNACP] = "SNA Control Protocol"; |
199 | 2 | tempMap[PCPP_PPP_IP6HCCP] = "IP6 Header Compression Control Protocol"; |
200 | 2 | tempMap[PCPP_PPP_KNXCP] = "KNX Bridging Control Protocol"; |
201 | 2 | tempMap[PCPP_PPP_ECP] = "Encryption Control Protocol"; |
202 | 2 | tempMap[PCPP_PPP_ILECP] = "Individual Link Encryption Control Protocol"; |
203 | 2 | tempMap[PCPP_PPP_IPV6CP] = "IPv6 Control Protocol"; |
204 | 2 | tempMap[PCPP_PPP_MUXCP] = "PPP Muxing Control Protocol"; |
205 | 2 | tempMap[PCPP_PPP_VSNCP] = "Vendor-Specific Network Control Protocol (VSNCP)"; |
206 | 2 | tempMap[PCPP_PPP_TNCP] = "TRILL Network Control Protocol"; |
207 | 2 | tempMap[PCPP_PPP_STAMPEDECP] = "Stampede Bridging Control Protocol"; |
208 | 2 | tempMap[PCPP_PPP_MPPCP] = "MP+ Control Protocol"; |
209 | 2 | tempMap[PCPP_PPP_IPICP] = "NTCITS IPI Control Protocol"; |
210 | 2 | tempMap[PCPP_PPP_SLCC] = "Single link compression in multilink control"; |
211 | 2 | tempMap[PCPP_PPP_CCP] = "Compression Control Protocol"; |
212 | 2 | tempMap[PCPP_PPP_CDPCP] = "Cisco Discovery Protocol Control Protocol"; |
213 | 2 | tempMap[PCPP_PPP_NETCSCP] = "Netcs Twin Routing"; |
214 | 2 | tempMap[PCPP_PPP_STPCP] = "STP - Control Protocol"; |
215 | 2 | tempMap[PCPP_PPP_EDPCP] = "EDPCP - Extreme Discovery Protocol Control Protocol"; |
216 | 2 | tempMap[PCPP_PPP_ACSPC] = "Apple Client Server Protocol Control"; |
217 | 2 | tempMap[PCPP_PPP_MPLSCP] = "MPLS Control Protocol"; |
218 | 2 | tempMap[PCPP_PPP_P12844CP] = "IEEE p1284.4 standard - Protocol Control"; |
219 | 2 | tempMap[PCPP_PPP_TETRACP] = "ETSI TETRA TNP1 Control Protocol"; |
220 | 2 | tempMap[PCPP_PPP_MFTPCP] = "Multichannel Flow Treatment Protocol"; |
221 | 2 | tempMap[PCPP_PPP_LCP] = "Link Control Protocol"; |
222 | 2 | tempMap[PCPP_PPP_PAP] = "Password Authentication Protocol"; |
223 | 2 | tempMap[PCPP_PPP_LQR] = "Link Quality Report"; |
224 | 2 | tempMap[PCPP_PPP_SPAP] = "Shiva Password Authentication Protocol"; |
225 | 2 | tempMap[PCPP_PPP_CBCP] = "Callback Control Protocol (CBCP)"; |
226 | 2 | tempMap[PCPP_PPP_BACP] = "BACP Bandwidth Allocation Control Protocol"; |
227 | 2 | tempMap[PCPP_PPP_BAP] = "BAP Bandwidth Allocation Protocol"; |
228 | 2 | tempMap[PCPP_PPP_VSAP] = "Vendor-Specific Authentication Protocol (VSAP)"; |
229 | 2 | tempMap[PCPP_PPP_CONTCP] = "Container Control Protocol"; |
230 | 2 | tempMap[PCPP_PPP_CHAP] = "Challenge Handshake Authentication Protocol"; |
231 | 2 | tempMap[PCPP_PPP_RSAAP] = "RSA Authentication Protocol"; |
232 | 2 | tempMap[PCPP_PPP_EAP] = "Extensible Authentication Protocol"; |
233 | 2 | tempMap[PCPP_PPP_SIEP] = "Mitsubishi Security Information Exchange Protocol (SIEP)"; |
234 | 2 | tempMap[PCPP_PPP_SBAP] = "Stampede Bridging Authorization Protocol"; |
235 | 2 | tempMap[PCPP_PPP_PRPAP] = "Proprietary Authentication Protocol"; |
236 | 2 | tempMap[PCPP_PPP_PRPAP2] = "Proprietary Authentication Protocol"; |
237 | 2 | tempMap[PCPP_PPP_PRPNIAP] = "Proprietary Node ID Authentication Protocol"; |
238 | 2 | return tempMap; |
239 | 2 | } |
240 | | |
241 | | const std::unordered_map<uint16_t, std::string> PPPNextProtoToString = createPPPNextProtoToStringMap(); |
242 | | |
243 | | std::string PPPoESessionLayer::toString() const |
244 | 0 | { |
245 | 0 | auto findResult = PPPNextProtoToString.find(getPPPNextProtocol()); |
246 | 0 | std::string nextProtocol; |
247 | 0 | if (findResult != PPPNextProtoToString.end()) |
248 | 0 | nextProtocol = findResult->second; |
249 | 0 | else |
250 | 0 | { |
251 | 0 | std::ostringstream stream; |
252 | 0 | stream << "Unknown (0x" << std::hex << getPPPNextProtocol() << ")"; |
253 | 0 | nextProtocol = stream.str(); |
254 | 0 | } |
255 | |
|
256 | 0 | return "PPP-over-Ethernet Session (followed by '" + nextProtocol + "')"; |
257 | 0 | } |
258 | | |
259 | | /// PPPoEDiscoveryLayer |
260 | | /// ~~~~~~~~~~~~~~~~~~~ |
261 | | |
262 | | PPPoEDiscoveryLayer::PPPoETagTypes PPPoEDiscoveryLayer::PPPoETag::getType() const |
263 | 0 | { |
264 | 0 | if (m_Data == nullptr) |
265 | 0 | return PPPoEDiscoveryLayer::PPPoETagTypes::PPPOE_TAG_EOL; |
266 | | |
267 | 0 | return static_cast<PPPoEDiscoveryLayer::PPPoETagTypes>(be16toh(m_Data->recordType)); |
268 | 0 | } |
269 | | |
270 | | size_t PPPoEDiscoveryLayer::PPPoETag::getTotalSize() const |
271 | 0 | { |
272 | 0 | if (m_Data == nullptr) |
273 | 0 | return 0; |
274 | | |
275 | 0 | return 2 * sizeof(uint16_t) + be16toh(m_Data->recordLen); |
276 | 0 | } |
277 | | |
278 | | size_t PPPoEDiscoveryLayer::PPPoETag::getDataSize() const |
279 | 0 | { |
280 | 0 | if (m_Data == nullptr) |
281 | 0 | return 0; |
282 | | |
283 | 0 | return be16toh(m_Data->recordLen); |
284 | 0 | } |
285 | | |
286 | | PPPoEDiscoveryLayer::PPPoETag PPPoEDiscoveryLayer::PPPoETagBuilder::build() const |
287 | 0 | { |
288 | 0 | size_t tagSize = 2 * sizeof(uint16_t) + m_RecValueLen; |
289 | 0 | uint8_t* recordBuffer = new uint8_t[tagSize]; |
290 | 0 | uint16_t tagTypeVal = htobe16(static_cast<uint16_t>(m_RecType)); |
291 | 0 | uint16_t tagLength = htobe16(static_cast<uint16_t>(m_RecValueLen)); |
292 | 0 | memcpy(recordBuffer, &tagTypeVal, sizeof(uint16_t)); |
293 | 0 | memcpy(recordBuffer + sizeof(uint16_t), &tagLength, sizeof(uint16_t)); |
294 | 0 | if (tagLength > 0 && m_RecValue != nullptr) |
295 | 0 | memcpy(recordBuffer + 2 * sizeof(uint16_t), m_RecValue, m_RecValueLen); |
296 | |
|
297 | 0 | return PPPoEDiscoveryLayer::PPPoETag(recordBuffer); |
298 | 0 | } |
299 | | |
300 | | PPPoEDiscoveryLayer::PPPoETag PPPoEDiscoveryLayer::getTag(PPPoEDiscoveryLayer::PPPoETagTypes tagType) const |
301 | 0 | { |
302 | 0 | return m_TagReader.getTLVRecord(static_cast<uint32_t>(tagType), getTagBasePtr(), |
303 | 0 | m_DataLen - sizeof(pppoe_header)); |
304 | 0 | } |
305 | | |
306 | | PPPoEDiscoveryLayer::PPPoETag PPPoEDiscoveryLayer::getFirstTag() const |
307 | 0 | { |
308 | 0 | return m_TagReader.getFirstTLVRecord(getTagBasePtr(), m_DataLen - sizeof(pppoe_header)); |
309 | 0 | } |
310 | | |
311 | | PPPoEDiscoveryLayer::PPPoETag PPPoEDiscoveryLayer::getNextTag(const PPPoEDiscoveryLayer::PPPoETag& tag) const |
312 | 0 | { |
313 | 0 | return m_TagReader.getNextTLVRecord(const_cast<PPPoEDiscoveryLayer::PPPoETag&>(tag), getTagBasePtr(), |
314 | 0 | m_DataLen - sizeof(pppoe_header)); |
315 | 0 | } |
316 | | |
317 | | int PPPoEDiscoveryLayer::getTagCount() const |
318 | 0 | { |
319 | 0 | return m_TagReader.getTLVRecordCount(getTagBasePtr(), m_DataLen - sizeof(pppoe_header)); |
320 | 0 | } |
321 | | |
322 | | PPPoEDiscoveryLayer::PPPoETag PPPoEDiscoveryLayer::addTagAt(const PPPoETagBuilder& tagBuilder, int offset) |
323 | 0 | { |
324 | 0 | PPPoETag newTag = tagBuilder.build(); |
325 | 0 | if (newTag.isNull()) |
326 | 0 | { |
327 | 0 | PCPP_LOG_ERROR("Cannot build new tag of type " << (int)newTag.getType()); |
328 | 0 | return newTag; |
329 | 0 | } |
330 | | |
331 | 0 | size_t sizeToExtend = newTag.getTotalSize(); |
332 | |
|
333 | 0 | if (!extendLayer(offset, sizeToExtend)) |
334 | 0 | { |
335 | 0 | PCPP_LOG_ERROR("Could not extend PPPoEDiscoveryLayer in [" << sizeToExtend << "] bytes"); |
336 | 0 | newTag.purgeRecordData(); |
337 | 0 | return PPPoETag(nullptr); |
338 | 0 | } |
339 | | |
340 | 0 | memcpy(m_Data + offset, newTag.getRecordBasePtr(), newTag.getTotalSize()); |
341 | |
|
342 | 0 | uint8_t* newTagPtr = m_Data + offset; |
343 | |
|
344 | 0 | m_TagReader.changeTLVRecordCount(1); |
345 | |
|
346 | 0 | newTag.purgeRecordData(); |
347 | |
|
348 | 0 | getPPPoEHeader()->payloadLength += htobe16(sizeToExtend); |
349 | |
|
350 | 0 | return PPPoETag(newTagPtr); |
351 | 0 | } |
352 | | |
353 | | PPPoEDiscoveryLayer::PPPoETag PPPoEDiscoveryLayer::addTagAfter(const PPPoETagBuilder& tagBuilder, |
354 | | PPPoETagTypes prevTagType) |
355 | 0 | { |
356 | 0 | int offset = 0; |
357 | |
|
358 | 0 | PPPoETag prevTag = getTag(prevTagType); |
359 | |
|
360 | 0 | if (prevTag.isNull()) |
361 | 0 | { |
362 | 0 | offset = getHeaderLen(); |
363 | 0 | } |
364 | 0 | else |
365 | 0 | { |
366 | 0 | offset = prevTag.getRecordBasePtr() + prevTag.getTotalSize() - m_Data; |
367 | 0 | } |
368 | |
|
369 | 0 | return addTagAt(tagBuilder, offset); |
370 | 0 | } |
371 | | |
372 | | PPPoEDiscoveryLayer::PPPoETag PPPoEDiscoveryLayer::addTag(const PPPoETagBuilder& tagBuilder) |
373 | 0 | { |
374 | 0 | return addTagAt(tagBuilder, getHeaderLen()); |
375 | 0 | } |
376 | | |
377 | | size_t PPPoEDiscoveryLayer::getHeaderLen() const |
378 | 0 | { |
379 | 0 | size_t payloadLen = sizeof(pppoe_header) + be16toh(getPPPoEHeader()->payloadLength); |
380 | 0 | if (payloadLen > m_DataLen) |
381 | 0 | return m_DataLen; |
382 | | |
383 | 0 | return payloadLen; |
384 | 0 | } |
385 | | |
386 | | bool PPPoEDiscoveryLayer::removeTag(PPPoEDiscoveryLayer::PPPoETagTypes tagType) |
387 | 0 | { |
388 | 0 | PPPoEDiscoveryLayer::PPPoETag tagToRemove = getTag(tagType); |
389 | 0 | if (tagToRemove.isNull()) |
390 | 0 | { |
391 | 0 | PCPP_LOG_ERROR("Couldn't find tag"); |
392 | 0 | return false; |
393 | 0 | } |
394 | | |
395 | 0 | int offset = tagToRemove.getRecordBasePtr() - m_Data; |
396 | |
|
397 | 0 | uint16_t tagTotalSize = tagToRemove.getTotalSize(); |
398 | |
|
399 | 0 | if (!shortenLayer(offset, tagTotalSize)) |
400 | 0 | { |
401 | 0 | return false; |
402 | 0 | } |
403 | | |
404 | 0 | m_TagReader.changeTLVRecordCount(-1); |
405 | |
|
406 | 0 | getPPPoEHeader()->payloadLength -= htobe16(tagTotalSize); |
407 | 0 | return true; |
408 | 0 | } |
409 | | |
410 | | bool PPPoEDiscoveryLayer::removeAllTags() |
411 | 0 | { |
412 | 0 | size_t tagCount = getTagCount(); |
413 | 0 | int offset = sizeof(pppoe_header); |
414 | 0 | if (!shortenLayer(offset, m_DataLen - offset)) |
415 | 0 | { |
416 | 0 | return false; |
417 | 0 | } |
418 | 0 | m_TagReader.changeTLVRecordCount(0 - tagCount); |
419 | 0 | getPPPoEHeader()->payloadLength = 0; |
420 | 0 | return true; |
421 | 0 | } |
422 | | |
423 | | std::string PPPoEDiscoveryLayer::codeToString(PPPoECode code) const |
424 | 0 | { |
425 | 0 | switch (code) |
426 | 0 | { |
427 | 0 | case PPPoELayer::PPPOE_CODE_SESSION: |
428 | 0 | return std::string("PPPoE Session"); |
429 | 0 | case PPPoELayer::PPPOE_CODE_PADO: |
430 | 0 | return std::string("PADO"); |
431 | 0 | case PPPoELayer::PPPOE_CODE_PADI: |
432 | 0 | return std::string("PADI"); |
433 | 0 | case PPPoELayer::PPPOE_CODE_PADG: |
434 | 0 | return std::string("PADG"); |
435 | 0 | case PPPoELayer::PPPOE_CODE_PADC: |
436 | 0 | return std::string("PADC"); |
437 | 0 | case PPPoELayer::PPPOE_CODE_PADQ: |
438 | 0 | return std::string("PADQ"); |
439 | 0 | case PPPoELayer::PPPOE_CODE_PADR: |
440 | 0 | return std::string("PADR"); |
441 | 0 | case PPPoELayer::PPPOE_CODE_PADS: |
442 | 0 | return std::string("PADS"); |
443 | 0 | case PPPoELayer::PPPOE_CODE_PADT: |
444 | 0 | return std::string("PADT"); |
445 | 0 | case PPPoELayer::PPPOE_CODE_PADM: |
446 | 0 | return std::string("PADM"); |
447 | 0 | case PPPoELayer::PPPOE_CODE_PADN: |
448 | 0 | return std::string("PADN"); |
449 | 0 | default: |
450 | 0 | return std::string("Unknown PPPoE code"); |
451 | 0 | } |
452 | 0 | } |
453 | | |
454 | | static constexpr const char* tagTypeToString(PPPoEDiscoveryLayer::PPPoETagTypes tagType) |
455 | 0 | { |
456 | 0 | switch (tagType) |
457 | 0 | { |
458 | 0 | case PPPoEDiscoveryLayer::PPPOE_TAG_EOL: |
459 | 0 | return "PPPOE_TAG_EOL"; |
460 | 0 | case PPPoEDiscoveryLayer::PPPOE_TAG_SVC_NAME: |
461 | 0 | return "PPPOE_TAG_SVC_NAME"; |
462 | 0 | case PPPoEDiscoveryLayer::PPPOE_TAG_AC_NAME: |
463 | 0 | return "PPPOE_TAG_AC_NAME"; |
464 | 0 | case PPPoEDiscoveryLayer::PPPOE_TAG_HOST_UNIQ: |
465 | 0 | return "PPPOE_TAG_HOST_UNIQ"; |
466 | 0 | case PPPoEDiscoveryLayer::PPPOE_TAG_AC_COOKIE: |
467 | 0 | return "PPPOE_TAG_AC_COOKIE"; |
468 | 0 | case PPPoEDiscoveryLayer::PPPOE_TAG_VENDOR: |
469 | 0 | return "PPPOE_TAG_VENDOR"; |
470 | 0 | case PPPoEDiscoveryLayer::PPPOE_TAG_CREDITS: |
471 | 0 | return "PPPOE_TAG_CREDITS"; |
472 | 0 | case PPPoEDiscoveryLayer::PPPOE_TAG_METRICS: |
473 | 0 | return "PPPOE_TAG_METRICS"; |
474 | 0 | case PPPoEDiscoveryLayer::PPPOE_TAG_SEQ_NUM: |
475 | 0 | return "PPPOE_TAG_SEQ_NUM"; |
476 | 0 | case PPPoEDiscoveryLayer::PPPOE_TAG_CRED_SCALE: |
477 | 0 | return "PPPOE_TAG_CRED_SCALE"; |
478 | 0 | case PPPoEDiscoveryLayer::PPPOE_TAG_RELAY_ID: |
479 | 0 | return "PPPOE_TAG_RELAY_ID"; |
480 | 0 | case PPPoEDiscoveryLayer::PPPOE_TAG_HURL: |
481 | 0 | return "PPPOE_TAG_HURL"; |
482 | 0 | case PPPoEDiscoveryLayer::PPPOE_TAG_MOTM: |
483 | 0 | return "PPPOE_TAG_MOTM"; |
484 | 0 | case PPPoEDiscoveryLayer::PPPOE_TAG_MAX_PAYLD: |
485 | 0 | return "PPPOE_TAG_MAX_PAYLD"; |
486 | 0 | case PPPoEDiscoveryLayer::PPPOE_TAG_IP_RT_ADD: |
487 | 0 | return "PPPOE_TAG_IP_RT_ADD"; |
488 | 0 | case PPPoEDiscoveryLayer::PPPOE_TAG_SVC_ERR: |
489 | 0 | return "PPPOE_TAG_SVC_ERR"; |
490 | 0 | case PPPoEDiscoveryLayer::PPPOE_TAG_AC_ERR: |
491 | 0 | return "PPPOE_TAG_AC_ERR"; |
492 | 0 | case PPPoEDiscoveryLayer::PPPOE_TAG_GENERIC_ERR: |
493 | 0 | return "PPPOE_TAG_GENERIC_ERR"; |
494 | 0 | default: |
495 | 0 | return "Unknown"; |
496 | 0 | } |
497 | 0 | } |
498 | | |
499 | | const FieldDescriptor PPPoEDiscoveryLayer::SerializedFields::Tags{ PPPoELayer::SerializedFields::MaxID + 1, |
500 | | "tags" }; |
501 | | const FieldDescriptor PPPoEDiscoveryLayer::SerializedFields::Tag{ 0, "tag" }; |
502 | | |
503 | | void PPPoEDiscoveryLayer::serializeLayer(ObjectScope& serializer) const |
504 | 0 | { |
505 | 0 | PPPoELayer::serializeLayer(serializer); |
506 | 0 | { |
507 | 0 | auto tags = serializer.writeArray(SerializedFields::Tags); |
508 | 0 | for (auto tag = getFirstTag(); tag.isNotNull(); tag = getNextTag(tag)) |
509 | 0 | { |
510 | 0 | tags.writeField(SerializedFields::Tag, tagTypeToString(tag.getType())); |
511 | 0 | } |
512 | 0 | } |
513 | 0 | } |
514 | | |
515 | | } // namespace pcpp |