/src/PcapPlusPlus/Packet++/src/GreLayer.cpp
Line | Count | Source |
1 | 0 | #define LOG_MODULE PacketLogModuleGreLayer |
2 | | |
3 | | #include "GreLayer.h" |
4 | | #include "EthLayer.h" |
5 | | #include "EthDot3Layer.h" |
6 | | #include "IPv4Layer.h" |
7 | | #include "IPv6Layer.h" |
8 | | #include "PPPoELayer.h" |
9 | | #include "VlanLayer.h" |
10 | | #include "MplsLayer.h" |
11 | | #include "PayloadLayer.h" |
12 | | #include "PacketUtils.h" |
13 | | #include "Logger.h" |
14 | | #include "EndianPortable.h" |
15 | | |
16 | | // ============== |
17 | | // GreLayer class |
18 | | // ============== |
19 | | |
20 | | namespace pcpp |
21 | | { |
22 | | |
23 | | ProtocolType GreLayer::getGREVersion(uint8_t* greData, size_t greDataLen) |
24 | 121k | { |
25 | 121k | if (greDataLen < sizeof(gre_basic_header)) |
26 | 70 | return UnknownProtocol; |
27 | | |
28 | 121k | uint8_t version = *(greData + 1); |
29 | 121k | version &= 0x07; |
30 | 121k | if (version == 0) |
31 | 11.1k | return GREv0; |
32 | 109k | else if (version == 1) |
33 | 109k | return GREv1; |
34 | 351 | else |
35 | 351 | return UnknownProtocol; |
36 | 121k | } |
37 | | |
38 | | uint8_t* GreLayer::getFieldValue(GreField field, bool returnOffsetEvenIfFieldMissing) const |
39 | 24.8k | { |
40 | 24.8k | uint8_t* ptr = m_Data + sizeof(gre_basic_header); |
41 | | |
42 | 24.8k | auto* header = reinterpret_cast<gre_basic_header*>(m_Data); |
43 | | |
44 | 24.8k | constexpr int numGreField = 4; |
45 | 67.8k | for (int curFieldAsInt = static_cast<int>(GreChecksumOrRouting); curFieldAsInt < numGreField; ++curFieldAsInt) |
46 | 67.8k | { |
47 | 67.8k | const GreField curField = static_cast<GreField>(curFieldAsInt); |
48 | 67.8k | bool curFieldExists = false; |
49 | | |
50 | 67.8k | uint8_t* origPtr = ptr; |
51 | | |
52 | 67.8k | switch (curField) |
53 | 67.8k | { |
54 | 24.8k | case GreChecksumOrRouting: |
55 | 24.8k | if (header->checksumBit == 1 || header->routingBit == 1) |
56 | 9.59k | { |
57 | 9.59k | curFieldExists = true; |
58 | 9.59k | ptr += sizeof(uint32_t); |
59 | 9.59k | } |
60 | 24.8k | break; |
61 | 18.4k | case GreKey: |
62 | 18.4k | if (header->keyBit == 1) |
63 | 16.6k | { |
64 | 16.6k | curFieldExists = true; |
65 | 16.6k | ptr += sizeof(uint32_t); |
66 | 16.6k | } |
67 | 18.4k | break; |
68 | 17.8k | case GreSeq: |
69 | 17.8k | if (header->sequenceNumBit == 1) |
70 | 16.8k | { |
71 | 16.8k | curFieldExists = true; |
72 | 16.8k | ptr += sizeof(uint32_t); |
73 | 16.8k | } |
74 | 17.8k | break; |
75 | 6.64k | case GreAck: |
76 | 6.64k | if (header->ackSequenceNumBit == 1) |
77 | 6.64k | { |
78 | 6.64k | curFieldExists = true; |
79 | 6.64k | ptr += sizeof(uint32_t); |
80 | 6.64k | } |
81 | 6.64k | break; |
82 | 0 | default: // shouldn't get there |
83 | 0 | return nullptr; |
84 | 67.8k | } |
85 | | |
86 | 67.8k | if (field == curField) |
87 | 24.8k | { |
88 | 24.8k | if (curFieldExists || returnOffsetEvenIfFieldMissing) |
89 | 24.8k | return origPtr; |
90 | | |
91 | 0 | return nullptr; |
92 | 24.8k | } |
93 | 67.8k | } // for |
94 | | |
95 | 0 | return nullptr; |
96 | 24.8k | } |
97 | | |
98 | | void GreLayer::computeCalculateFieldsInner() |
99 | 13.1k | { |
100 | 13.1k | gre_basic_header* header = (gre_basic_header*)m_Data; |
101 | 13.1k | if (m_NextLayer != nullptr) |
102 | 13.1k | { |
103 | 13.1k | switch (m_NextLayer->getProtocol()) |
104 | 13.1k | { |
105 | 47 | case IPv4: |
106 | 47 | header->protocol = htobe16(PCPP_ETHERTYPE_IP); |
107 | 47 | break; |
108 | 2 | case IPv6: |
109 | 2 | header->protocol = htobe16(PCPP_ETHERTYPE_IPV6); |
110 | 2 | break; |
111 | 3 | case VLAN: |
112 | 3 | header->protocol = htobe16(PCPP_ETHERTYPE_VLAN); |
113 | 3 | break; |
114 | 18 | case MPLS: |
115 | 18 | header->protocol = htobe16(PCPP_ETHERTYPE_MPLS); |
116 | 18 | break; |
117 | 9.38k | case PPP_PPTP: |
118 | 9.38k | header->protocol = htobe16(PCPP_ETHERTYPE_PPP); |
119 | 9.38k | break; |
120 | 0 | case Ethernet: |
121 | 0 | header->protocol = htobe16(PCPP_ETHERTYPE_ETHBRIDGE); |
122 | 0 | break; |
123 | 3.65k | default: |
124 | 3.65k | break; |
125 | 13.1k | } |
126 | 13.1k | } |
127 | 13.1k | } |
128 | | |
129 | | bool GreLayer::getSequenceNumber(uint32_t& seqNumber) const |
130 | 13.1k | { |
131 | 13.1k | gre_basic_header* header = (gre_basic_header*)m_Data; |
132 | | |
133 | 13.1k | if (header->sequenceNumBit == 0) |
134 | 1.98k | return false; |
135 | | |
136 | 11.1k | uint32_t* val = (uint32_t*)getFieldValue(GreSeq, false); |
137 | 11.1k | if (val == nullptr) |
138 | 0 | return false; |
139 | | |
140 | 11.1k | seqNumber = be32toh(*val); |
141 | 11.1k | return true; |
142 | 11.1k | } |
143 | | |
144 | | bool GreLayer::setSequenceNumber(uint32_t seqNumber) |
145 | 0 | { |
146 | 0 | gre_basic_header* header = (gre_basic_header*)m_Data; |
147 | |
|
148 | 0 | bool needToExtendLayer = false; |
149 | |
|
150 | 0 | if (header->sequenceNumBit == 0) |
151 | 0 | needToExtendLayer = true; |
152 | |
|
153 | 0 | uint8_t* offsetPtr = getFieldValue(GreSeq, true); |
154 | |
|
155 | 0 | int offset = offsetPtr - m_Data; |
156 | 0 | if (needToExtendLayer && !extendLayer(offset, sizeof(uint32_t))) |
157 | 0 | { |
158 | 0 | header->sequenceNumBit = 0; |
159 | 0 | PCPP_LOG_ERROR("Couldn't extend layer to set sequence number"); |
160 | 0 | return false; |
161 | 0 | } |
162 | | |
163 | 0 | header = (gre_basic_header*)m_Data; |
164 | 0 | header->sequenceNumBit = 1; |
165 | 0 | uint32_t* seqPtr = (uint32_t*)(m_Data + offset); |
166 | 0 | *seqPtr = htobe32(seqNumber); |
167 | |
|
168 | 0 | return true; |
169 | 0 | } |
170 | | |
171 | | bool GreLayer::unsetSequenceNumber() |
172 | 0 | { |
173 | 0 | gre_basic_header* header = (gre_basic_header*)m_Data; |
174 | |
|
175 | 0 | if (header->sequenceNumBit == 0) |
176 | 0 | { |
177 | 0 | PCPP_LOG_ERROR("Couldn't unset sequence number as it's already unset"); |
178 | 0 | return false; |
179 | 0 | } |
180 | | |
181 | 0 | uint8_t* offsetPtr = getFieldValue(GreSeq, true); |
182 | |
|
183 | 0 | int offset = offsetPtr - m_Data; |
184 | 0 | if (!shortenLayer(offset, sizeof(uint32_t))) |
185 | 0 | { |
186 | 0 | PCPP_LOG_ERROR("Couldn't shorted layer to unset sequence number"); |
187 | 0 | return false; |
188 | 0 | } |
189 | | |
190 | 0 | header = (gre_basic_header*)m_Data; |
191 | 0 | header->sequenceNumBit = 0; |
192 | 0 | return true; |
193 | 0 | } |
194 | | |
195 | | void GreLayer::parseNextLayer() |
196 | 120k | { |
197 | 120k | size_t headerLen = getHeaderLen(); |
198 | 120k | if (m_DataLen <= headerLen) |
199 | 2.47k | return; |
200 | | |
201 | 118k | gre_basic_header* header = (gre_basic_header*)m_Data; |
202 | 118k | uint8_t* payload = m_Data + headerLen; |
203 | 118k | size_t payloadLen = m_DataLen - headerLen; |
204 | | |
205 | 118k | switch (be16toh(header->protocol)) |
206 | 118k | { |
207 | 1.53k | case PCPP_ETHERTYPE_IP: |
208 | 1.53k | tryConstructNextLayerWithFallback<IPv4Layer, PayloadLayer>(payload, payloadLen); |
209 | 1.53k | break; |
210 | 23 | case PCPP_ETHERTYPE_IPV6: |
211 | 23 | tryConstructNextLayerWithFallback<IPv6Layer, PayloadLayer>(payload, payloadLen); |
212 | 23 | break; |
213 | 24 | case PCPP_ETHERTYPE_VLAN: |
214 | 24 | constructNextLayer<VlanLayer>(payload, payloadLen); |
215 | 24 | break; |
216 | 154 | case PCPP_ETHERTYPE_MPLS: |
217 | 154 | tryConstructNextLayerWithFallback<MplsLayer, PayloadLayer>(payload, payloadLen); |
218 | 154 | break; |
219 | 101k | case PCPP_ETHERTYPE_PPP: |
220 | 101k | tryConstructNextLayerWithFallback<PPP_PPTPLayer, PayloadLayer>(payload, payloadLen); |
221 | 101k | break; |
222 | 0 | case PCPP_ETHERTYPE_ETHBRIDGE: |
223 | 0 | { |
224 | 0 | if (tryConstructNextLayer<EthLayer>(payload, payloadLen) != nullptr) |
225 | 0 | { |
226 | 0 | break; |
227 | 0 | } |
228 | | |
229 | 0 | tryConstructNextLayerWithFallback<EthDot3Layer, PayloadLayer>(payload, payloadLen); |
230 | 0 | break; |
231 | 0 | } |
232 | 15.2k | default: |
233 | 15.2k | constructNextLayer<PayloadLayer>(payload, payloadLen); |
234 | 118k | } |
235 | 118k | } |
236 | | |
237 | | size_t GreLayer::getHeaderLen() const |
238 | 146k | { |
239 | 146k | size_t result = sizeof(gre_basic_header); |
240 | | |
241 | 146k | gre_basic_header const* header = reinterpret_cast<gre_basic_header const*>(m_Data); |
242 | | |
243 | 146k | if (header->checksumBit == 1 || header->routingBit == 1) |
244 | 18.6k | result += 4; |
245 | 146k | if (header->keyBit == 1) |
246 | 131k | result += 4; |
247 | 146k | if (header->sequenceNumBit == 1) |
248 | 132k | result += 4; |
249 | 146k | if (header->ackSequenceNumBit == 1) |
250 | 73.2k | result += 4; |
251 | | |
252 | 146k | return result; |
253 | 146k | } |
254 | | |
255 | | // ================ |
256 | | // GREv0Layer class |
257 | | // ================ |
258 | | |
259 | | GREv0Layer::GREv0Layer() |
260 | 0 | { |
261 | 0 | allocData(sizeof(gre_basic_header)); |
262 | 0 | m_Protocol = GREv0; |
263 | 0 | } |
264 | | |
265 | | bool GREv0Layer::getChecksum(uint16_t& checksum) |
266 | 2.17k | { |
267 | 2.17k | if (getGreHeader()->checksumBit == 0) |
268 | 502 | return false; |
269 | | |
270 | 1.67k | uint16_t* val = (uint16_t*)getFieldValue(GreChecksumOrRouting, false); |
271 | 1.67k | if (val == nullptr) |
272 | 0 | return false; |
273 | | |
274 | 1.67k | checksum = be16toh(*val); |
275 | 1.67k | return true; |
276 | 1.67k | } |
277 | | |
278 | | bool GREv0Layer::setChecksum(uint16_t checksum) |
279 | 3.35k | { |
280 | 3.35k | gre_basic_header* header = getGreHeader(); |
281 | | |
282 | 3.35k | bool needToExtendLayer = false; |
283 | | |
284 | 3.35k | if (header->routingBit == 0 && header->checksumBit == 0) |
285 | 0 | needToExtendLayer = true; |
286 | | |
287 | 3.35k | uint8_t* offsetPtr = getFieldValue(GreChecksumOrRouting, true); |
288 | 3.35k | int offset = offsetPtr - m_Data; |
289 | | // extend layer in 4 bytes to keep 4-byte alignment |
290 | 3.35k | if (needToExtendLayer && !extendLayer(offset, sizeof(uint32_t))) |
291 | 0 | { |
292 | 0 | PCPP_LOG_ERROR("Couldn't extend layer to set checksum"); |
293 | 0 | return false; |
294 | 0 | } |
295 | | |
296 | 3.35k | uint16_t* checksumPtr = (uint16_t*)(m_Data + offset); |
297 | 3.35k | *checksumPtr = htobe16(checksum); |
298 | | |
299 | | // if layer was extended in 4 bytes, make sure the offset field stays 0 |
300 | 3.35k | if (needToExtendLayer) |
301 | 0 | { |
302 | 0 | checksumPtr++; |
303 | 0 | *checksumPtr = 0; |
304 | 0 | } |
305 | | |
306 | 3.35k | header = getGreHeader(); |
307 | 3.35k | header->checksumBit = 1; |
308 | | |
309 | 3.35k | return true; |
310 | 3.35k | } |
311 | | |
312 | | bool GREv0Layer::unsetChecksum() |
313 | 0 | { |
314 | 0 | gre_basic_header* header = getGreHeader(); |
315 | |
|
316 | 0 | if (header->checksumBit == 0) |
317 | 0 | { |
318 | 0 | PCPP_LOG_ERROR("Couldn't unset checksum as it's already unset"); |
319 | 0 | return false; |
320 | 0 | } |
321 | | |
322 | | // if both routing and checksum are unset we need to shorted the layer |
323 | 0 | bool needToShortenLayer = (header->routingBit == 0); |
324 | |
|
325 | 0 | uint8_t* offsetPtr = getFieldValue(GreChecksumOrRouting, true); |
326 | 0 | int offset = offsetPtr - m_Data; |
327 | 0 | if (needToShortenLayer && !shortenLayer(offset, sizeof(uint32_t))) |
328 | 0 | { |
329 | 0 | PCPP_LOG_ERROR("Couldn't extend layer to unset checksum"); |
330 | 0 | return false; |
331 | 0 | } |
332 | | |
333 | 0 | if (!needToShortenLayer) // meaning routing bit is set - only zero the checksum field |
334 | 0 | { |
335 | 0 | uint16_t* checksumPtr = (uint16_t*)(m_Data + offset); |
336 | 0 | *checksumPtr = 0; |
337 | 0 | } |
338 | |
|
339 | 0 | header = getGreHeader(); |
340 | 0 | header->checksumBit = 0; |
341 | |
|
342 | 0 | return true; |
343 | 0 | } |
344 | | |
345 | | bool GREv0Layer::getOffset(uint16_t& offset) const |
346 | 2.17k | { |
347 | 2.17k | if (getGreHeader()->routingBit == 0) |
348 | 798 | return false; |
349 | | |
350 | 1.37k | uint8_t* val = (uint8_t*)getFieldValue(GreChecksumOrRouting, false); |
351 | 1.37k | if (val == nullptr) |
352 | 0 | return false; |
353 | | |
354 | 1.37k | offset = be16toh(*(val + 2)); |
355 | 1.37k | return true; |
356 | 1.37k | } |
357 | | |
358 | | bool GREv0Layer::getKey(uint32_t& key) const |
359 | 2.17k | { |
360 | 2.17k | if (getGreHeader()->keyBit == 0) |
361 | 1.54k | return false; |
362 | | |
363 | 628 | uint32_t* val = (uint32_t*)getFieldValue(GreKey, false); |
364 | 628 | if (val == nullptr) |
365 | 0 | return false; |
366 | | |
367 | 628 | key = be32toh(*val); |
368 | 628 | return true; |
369 | 628 | } |
370 | | |
371 | | bool GREv0Layer::setKey(uint32_t key) |
372 | 0 | { |
373 | 0 | gre_basic_header* header = getGreHeader(); |
374 | |
|
375 | 0 | bool needToExtendLayer = false; |
376 | |
|
377 | 0 | if (header->keyBit == 0) |
378 | 0 | needToExtendLayer = true; |
379 | |
|
380 | 0 | uint8_t* offsetPtr = getFieldValue(GreKey, true); |
381 | |
|
382 | 0 | int offset = offsetPtr - m_Data; |
383 | 0 | if (needToExtendLayer && !extendLayer(offset, sizeof(uint32_t))) |
384 | 0 | { |
385 | 0 | header->keyBit = 0; |
386 | 0 | PCPP_LOG_ERROR("Couldn't extend layer to set key"); |
387 | 0 | return false; |
388 | 0 | } |
389 | | |
390 | 0 | header = getGreHeader(); |
391 | 0 | header->keyBit = 1; |
392 | 0 | uint32_t* keyPtr = (uint32_t*)(m_Data + offset); |
393 | 0 | *keyPtr = htobe32(key); |
394 | |
|
395 | 0 | return true; |
396 | 0 | } |
397 | | |
398 | | bool GREv0Layer::unsetKey() |
399 | 0 | { |
400 | 0 | gre_basic_header* header = getGreHeader(); |
401 | |
|
402 | 0 | if (header->keyBit == 0) |
403 | 0 | { |
404 | 0 | PCPP_LOG_ERROR("Couldn't unset key as it's already unset"); |
405 | 0 | return false; |
406 | 0 | } |
407 | | |
408 | 0 | uint8_t* offsetPtr = getFieldValue(GreKey, true); |
409 | |
|
410 | 0 | int offset = offsetPtr - m_Data; |
411 | 0 | if (!shortenLayer(offset, sizeof(uint32_t))) |
412 | 0 | { |
413 | 0 | PCPP_LOG_ERROR("Couldn't shorted layer to unset key"); |
414 | 0 | return false; |
415 | 0 | } |
416 | | |
417 | 0 | header = (gre_basic_header*)m_Data; |
418 | 0 | header->keyBit = 0; |
419 | 0 | return true; |
420 | 0 | } |
421 | | |
422 | | void GREv0Layer::computeCalculateFields() |
423 | 2.17k | { |
424 | 2.17k | computeCalculateFieldsInner(); |
425 | | |
426 | 2.17k | if (getGreHeader()->checksumBit == 0) |
427 | 502 | return; |
428 | | |
429 | | // calculate checksum |
430 | 1.67k | setChecksum(0); |
431 | | |
432 | 1.67k | ScalarBuffer<uint16_t> buffer; |
433 | 1.67k | buffer.buffer = (uint16_t*)m_Data; |
434 | 1.67k | buffer.len = m_DataLen; |
435 | 1.67k | size_t checksum = computeChecksum(&buffer, 1); |
436 | | |
437 | 1.67k | setChecksum(checksum); |
438 | 1.67k | } |
439 | | |
440 | | std::string GREv0Layer::toString() const |
441 | 4.35k | { |
442 | 4.35k | return "GRE Layer, version 0"; |
443 | 4.35k | } |
444 | | |
445 | | // ================ |
446 | | // GREv1Layer class |
447 | | // ================ |
448 | | |
449 | | GREv1Layer::GREv1Layer(uint16_t callID) |
450 | 0 | { |
451 | 0 | allocData(sizeof(gre1_header)); |
452 | 0 | m_Protocol = GREv1; |
453 | |
|
454 | 0 | gre1_header* header = getGreHeader(); |
455 | 0 | header->keyBit = 1; |
456 | 0 | header->version = 1; |
457 | 0 | header->callID = htobe16(callID); |
458 | 0 | } |
459 | | |
460 | | bool GREv1Layer::getAcknowledgmentNum(uint32_t& ackNum) const |
461 | 11.0k | { |
462 | 11.0k | if (getGreHeader()->ackSequenceNumBit == 0) |
463 | 4.36k | return false; |
464 | | |
465 | 6.64k | uint32_t* val = (uint32_t*)getFieldValue(GreAck, false); |
466 | 6.64k | if (val == nullptr) |
467 | 0 | return false; |
468 | | |
469 | 6.64k | ackNum = be32toh(*val); |
470 | 6.64k | return true; |
471 | 6.64k | } |
472 | | |
473 | | bool GREv1Layer::setAcknowledgmentNum(uint32_t ackNum) |
474 | 0 | { |
475 | 0 | bool needToExtendLayer = false; |
476 | |
|
477 | 0 | gre1_header* header = getGreHeader(); |
478 | |
|
479 | 0 | if (header->ackSequenceNumBit == 0) |
480 | 0 | needToExtendLayer = true; |
481 | |
|
482 | 0 | uint8_t* offsetPtr = getFieldValue(GreAck, true); |
483 | 0 | int offset = offsetPtr - m_Data; |
484 | 0 | if (needToExtendLayer && !extendLayer(offset, sizeof(uint32_t))) |
485 | 0 | { |
486 | 0 | PCPP_LOG_ERROR("Couldn't extend layer to set ack number"); |
487 | 0 | return false; |
488 | 0 | } |
489 | | |
490 | 0 | header = getGreHeader(); |
491 | 0 | header->ackSequenceNumBit = 1; |
492 | 0 | uint32_t* ackPtr = (uint32_t*)(m_Data + offset); |
493 | 0 | *ackPtr = htobe32(ackNum); |
494 | 0 | return true; |
495 | 0 | } |
496 | | |
497 | | bool GREv1Layer::unsetAcknowledgmentNum() |
498 | 0 | { |
499 | 0 | gre1_header* header = getGreHeader(); |
500 | |
|
501 | 0 | if (header->ackSequenceNumBit == 0) |
502 | 0 | { |
503 | 0 | PCPP_LOG_ERROR("Couldn't unset ack number as it's already unset"); |
504 | 0 | return false; |
505 | 0 | } |
506 | | |
507 | 0 | uint8_t* offsetPtr = getFieldValue(GreAck, true); |
508 | |
|
509 | 0 | int offset = offsetPtr - m_Data; |
510 | 0 | if (!shortenLayer(offset, sizeof(uint32_t))) |
511 | 0 | { |
512 | 0 | PCPP_LOG_ERROR("Couldn't shorted layer to unset ack number"); |
513 | 0 | return false; |
514 | 0 | } |
515 | | |
516 | 0 | header = getGreHeader(); |
517 | 0 | header->ackSequenceNumBit = 0; |
518 | 0 | return true; |
519 | 0 | } |
520 | | |
521 | | void GREv1Layer::computeCalculateFields() |
522 | 11.0k | { |
523 | 11.0k | computeCalculateFieldsInner(); |
524 | | |
525 | 11.0k | getGreHeader()->payloadLength = htobe16(m_DataLen - getHeaderLen()); |
526 | 11.0k | } |
527 | | |
528 | | std::string GREv1Layer::toString() const |
529 | 22.0k | { |
530 | 22.0k | return "GRE Layer, version 1"; |
531 | 22.0k | } |
532 | | |
533 | | // =================== |
534 | | // PPP_PPTPLayer class |
535 | | // =================== |
536 | | |
537 | | PPP_PPTPLayer::PPP_PPTPLayer(uint8_t address, uint8_t control) |
538 | 0 | { |
539 | 0 | allocData(sizeof(ppp_pptp_header)); |
540 | 0 | m_Protocol = PPP_PPTP; |
541 | |
|
542 | 0 | ppp_pptp_header* header = getPPP_PPTPHeader(); |
543 | 0 | header->address = address; |
544 | 0 | header->control = control; |
545 | 0 | } |
546 | | |
547 | | void PPP_PPTPLayer::parseNextLayer() |
548 | 101k | { |
549 | 101k | size_t headerLen = getHeaderLen(); |
550 | 101k | if (m_DataLen <= headerLen) |
551 | 27 | return; |
552 | | |
553 | 101k | uint8_t* payload = m_Data + headerLen; |
554 | 101k | size_t payloadLen = m_DataLen - headerLen; |
555 | | |
556 | 101k | switch (be16toh(getPPP_PPTPHeader()->protocol)) |
557 | 101k | { |
558 | 100k | case PCPP_PPP_IP: |
559 | 100k | tryConstructNextLayerWithFallback<IPv4Layer, PayloadLayer>(payload, payloadLen); |
560 | 100k | break; |
561 | 71 | case PCPP_PPP_IPV6: |
562 | 71 | tryConstructNextLayerWithFallback<IPv6Layer, PayloadLayer>(payload, payloadLen); |
563 | 71 | break; |
564 | 790 | default: |
565 | 790 | constructNextLayer<PayloadLayer>(payload, payloadLen); |
566 | 790 | break; |
567 | 101k | } |
568 | 101k | } |
569 | | |
570 | | void PPP_PPTPLayer::computeCalculateFields() |
571 | 9.38k | { |
572 | 9.38k | ppp_pptp_header* header = getPPP_PPTPHeader(); |
573 | 9.38k | if (m_NextLayer != nullptr) |
574 | 9.38k | { |
575 | 9.38k | switch (m_NextLayer->getProtocol()) |
576 | 9.38k | { |
577 | 9.23k | case IPv4: |
578 | 9.23k | header->protocol = htobe16(PCPP_PPP_IP); |
579 | 9.23k | break; |
580 | 0 | case IPv6: |
581 | 0 | header->protocol = htobe16(PCPP_PPP_IPV6); |
582 | 0 | break; |
583 | 157 | default: |
584 | 157 | break; |
585 | 9.38k | } |
586 | 9.38k | } |
587 | 0 | else |
588 | 0 | header->protocol = 0; |
589 | 9.38k | } |
590 | | |
591 | | } // namespace pcpp |