PcapPlusPlus  Next
PPPoELayer.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "Layer.h"
4 #include "TLVData.h"
5 
6 #include <Layer.h>
7 #include <vector>
8 #include <string.h>
9 
11 
14 namespace pcpp
15 {
18 #pragma pack(push, 1)
19  struct pppoe_header
20  {
21 #if (BYTE_ORDER == LITTLE_ENDIAN)
23  uint8_t version : 4;
25  uint8_t type : 4;
27  uint8_t code;
28 #else
30  uint16_t version : 4;
32  uint16_t type : 4;
34  uint16_t code : 8;
35 #endif
37  uint16_t sessionId;
39  uint16_t payloadLength;
40  };
41 #pragma pack(pop)
42  static_assert(sizeof(pppoe_header) == 6, "pppoe_header size is not 6 bytes");
43 
47  class PPPoELayer : public Layer
48  {
49  public:
51  enum PPPoECode
52  {
74  PPPOE_CODE_PADN = 0xd4
75  };
76 
77  ~PPPoELayer() override = default;
78 
83  {
84  return reinterpret_cast<pppoe_header*>(m_Data);
85  }
86 
87  // abstract methods implementation
88 
90  void computeCalculateFields() override;
91 
93  {
94  return OsiModelDataLinkLayer;
95  }
96 
101  {
103  static std::vector<FieldDescriptor> all()
104  {
105  auto result = Layer::SerializedFields::all();
106  std::initializer_list<FieldDescriptor> extra{ Code, Version, Type, SessionID };
107  std::copy(extra.begin(), extra.end(), std::back_inserter(result));
108  return result;
109  }
110 
112  static const FieldDescriptor Code;
113 
115  static const FieldDescriptor Version;
116 
118  static const FieldDescriptor Type;
119 
122 
124  static constexpr uint16_t MaxID = Layer::SerializedFields::MaxID + 4;
125  };
126 
127  protected:
128  // protected c'tor as this class shouldn't be instantiated
129  PPPoELayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet, ProtocolType protocol)
130  : Layer(data, dataLen, prevLayer, packet, protocol)
131  {}
132 
133  // protected c'tor as this class shouldn't be instantiated
134  PPPoELayer(uint8_t version, uint8_t type, PPPoELayer::PPPoECode code, uint16_t sessionId,
135  size_t additionalBytesToAllocate = 0);
136 
137  void serializeLayer(ObjectScope& serializer) const override;
138  };
139 
143  {
144  public:
150  PPPoESessionLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet)
151  : PPPoELayer(data, dataLen, prevLayer, packet, PPPoESession)
152  {}
153 
160  PPPoESessionLayer(uint8_t version, uint8_t type, uint16_t sessionId, uint16_t pppNextProtocol)
161  : PPPoELayer(version, type, PPPoELayer::PPPOE_CODE_SESSION, sessionId, sizeof(uint16_t))
162  {
163  setPPPNextProtocol(pppNextProtocol);
164  }
165 
166  ~PPPoESessionLayer() override = default;
167 
171  uint16_t getPPPNextProtocol() const;
172 
175  void setPPPNextProtocol(uint16_t nextProtocol);
176 
181  static inline bool isDataValid(const uint8_t* data, size_t dataLen);
182 
183  // abstract methods implementation
184 
186  void parseNextLayer() override;
187 
189  size_t getHeaderLen() const override
190  {
191  return sizeof(pppoe_header) + sizeof(uint16_t);
192  }
193 
194  std::string toString() const override;
195  };
196 
200  {
201  public:
204  {
206  PPPOE_TAG_EOL = 0x0000,
228  PPPOE_TAG_HURL = 0x0111,
230  PPPOE_TAG_MOTM = 0x0112,
240  PPPOE_TAG_GENERIC_ERR = 0x0203
241  };
242 
245  class PPPoETag : public TLVRecord<uint16_t, uint16_t>
246  {
247  public:
250  explicit PPPoETag(uint8_t* tagRawData) : TLVRecord(tagRawData)
251  {}
252 
254  ~PPPoETag() override = default;
255 
258 
261  std::string getValueAsString() const
262  {
263  size_t dataSize = getDataSize();
264  if (dataSize < 1)
265  return "";
266 
267  return std::string(reinterpret_cast<const char*>(m_Data->recordValue), dataSize);
268  }
269 
270  // implement abstract methods
271 
272  size_t getTotalSize() const override;
273 
274  size_t getDataSize() const override;
275  };
276 
281  {
282  public:
286  explicit PPPoETagBuilder(PPPoETagTypes tagType)
287  : TLVRecordBuilder(static_cast<uint16_t>(tagType), nullptr, 0)
288  {}
289 
294  PPPoETagBuilder(PPPoETagTypes tagType, uint32_t tagValue)
295  : TLVRecordBuilder(static_cast<uint16_t>(tagType), tagValue)
296  {}
297 
303  PPPoETagBuilder(PPPoETagTypes tagType, uint8_t* tagValue, uint8_t tagValueLen)
304  : TLVRecordBuilder(static_cast<uint16_t>(tagType), tagValue, tagValueLen)
305  {}
306 
309  PPPoETag build() const;
310  };
311 
317  PPPoEDiscoveryLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet)
318  : PPPoELayer(data, dataLen, prevLayer, packet, PPPoEDiscovery)
319  {
320  m_DataLen = getHeaderLen();
321  }
322 
328  PPPoEDiscoveryLayer(uint8_t version, uint8_t type, PPPoELayer::PPPoECode code, uint16_t sessionId)
329  : PPPoELayer(version, type, code, sessionId)
330  {
331  m_Protocol = PPPoEDiscovery;
332  }
333 
339 
343 
349  PPPoETag getNextTag(const PPPoETag& tag) const;
350 
352  int getTagCount() const;
353 
358  PPPoETag addTag(const PPPoETagBuilder& tagBuilder);
359 
365  PPPoETag addTagAfter(const PPPoETagBuilder& tagBuilder, PPPoETagTypes prevTagType);
366 
372 
377 
382  static inline bool isDataValid(const uint8_t* data, size_t dataLen);
383 
384  // abstract methods implementation
385 
387  void parseNextLayer() override
388  {}
389 
391  size_t getHeaderLen() const override;
392 
393  std::string toString() const override
394  {
395  return "PPP-over-Ethernet Discovery (" + codeToString((PPPoELayer::PPPoECode)getPPPoEHeader()->code) + ")";
396  }
397 
402  {
404  static std::vector<FieldDescriptor> all()
405  {
406  auto result = PPPoELayer::SerializedFields::all();
407  std::initializer_list<FieldDescriptor> extra{ Tags };
408  std::copy(extra.begin(), extra.end(), std::back_inserter(result));
409  return result;
410  }
411 
413  static const FieldDescriptor Tags;
414 
417  static const FieldDescriptor Tag;
418  };
419 
420  protected:
421  void serializeLayer(ObjectScope& serializer) const override;
422 
423  private:
424  TLVRecordReader<PPPoETag> m_TagReader;
425 
426  PPPoETag addTagAt(const PPPoETagBuilder& tagBuilder, int offset);
427 
428  uint8_t* getTagBasePtr() const
429  {
430  return m_Data + sizeof(pppoe_header);
431  }
432 
433  std::string codeToString(PPPoECode code) const;
434  };
435 
436  // implementation of inline methods
437 
438  bool PPPoESessionLayer::isDataValid(const uint8_t* data, size_t dataLen)
439  {
440  return data && dataLen >= sizeof(pppoe_header) + sizeof(uint16_t);
441  }
442 
443  bool PPPoEDiscoveryLayer::isDataValid(const uint8_t* data, size_t dataLen)
444  {
445  return data && dataLen >= sizeof(pppoe_header);
446  }
447 
448  // Copied from Wireshark: ppptypes.h
449 
451 #define PCPP_PPP_PADDING 0x1
453 #define PCPP_PPP_ROHC_SCID 0x3
455 #define PCPP_PPP_ROHC_LCID 0x5
457 #define PCPP_PPP_IP 0x21
459 #define PCPP_PPP_OSI 0x23
461 #define PCPP_PPP_XNSIDP 0x25
463 #define PCPP_PPP_DEC4 0x27
465 #define PCPP_PPP_AT 0x29
467 #define PCPP_PPP_IPX 0x2b
469 #define PCPP_PPP_VJC_COMP 0x2d
471 #define PCPP_PPP_VJC_UNCOMP 0x2f
473 #define PCPP_PPP_BCP 0x31
475 #define PCPP_PPP_ST 0x33
477 #define PCPP_PPP_VINES 0x35
479 #define PCPP_PPP_AT_EDDP 0x39
481 #define PCPP_PPP_AT_SB 0x3b
483 #define PCPP_PPP_MP 0x3d
485 #define PCPP_PPP_NB 0x3f
487 #define PCPP_PPP_CISCO 0x41
489 #define PCPP_PPP_ASCOM 0x43
491 #define PCPP_PPP_LBLB 0x45
493 #define PCPP_PPP_RL 0x47
495 #define PCPP_PPP_SDTP 0x49
497 #define PCPP_PPP_LLC 0x4b
499 #define PCPP_PPP_SNA 0x4d
501 #define PCPP_PPP_IPV6HC 0x4f
503 #define PCPP_PPP_KNX 0x51
505 #define PCPP_PPP_ENCRYPT 0x53
507 #define PCPP_PPP_ILE 0x55
509 #define PCPP_PPP_IPV6 0x57
511 #define PCPP_PPP_MUX 0x59
513 #define PCPP_PPP_VSNP 0x5b
515 #define PCPP_PPP_TNP 0x5d
517 #define PCPP_PPP_RTP_FH 0x61
519 #define PCPP_PPP_RTP_CTCP 0x63
521 #define PCPP_PPP_RTP_CNTCP 0x65
523 #define PCPP_PPP_RTP_CUDP8 0x67
525 #define PCPP_PPP_RTP_CRTP8 0x69
527 #define PCPP_PPP_STAMPEDE 0x6f
529 #define PCPP_PPP_MPPLUS 0x73
531 #define PCPP_PPP_NTCITS_IPI 0xc1
533 #define PCPP_PPP_ML_SLCOMP 0xfb
535 #define PCPP_PPP_COMP 0xfd
537 #define PCPP_PPP_STP_HELLO 0x0201
539 #define PCPP_PPP_IBM_SR 0x0203
541 #define PCPP_PPP_DEC_LB 0x0205
543 #define PCPP_PPP_CDP 0x0207
545 #define PCPP_PPP_NETCS 0x0209
547 #define PCPP_PPP_STP 0x020b
549 #define PCPP_PPP_EDP 0x020d
551 #define PCPP_PPP_OSCP 0x0211
553 #define PCPP_PPP_OSCP2 0x0213
555 #define PCPP_PPP_LUXCOM 0x0231
557 #define PCPP_PPP_SIGMA 0x0233
559 #define PCPP_PPP_ACSP 0x0235
561 #define PCPP_PPP_MPLS_UNI 0x0281
563 #define PCPP_PPP_MPLS_MULTI 0x0283
565 #define PCPP_PPP_P12844 0x0285
567 #define PCPP_PPP_TETRA 0x0287
569 #define PCPP_PPP_MFTP 0x0289
571 #define PCPP_PPP_RTP_CTCPND 0x2063
573 #define PCPP_PPP_RTP_CS 0x2065
575 #define PCPP_PPP_RTP_CUDP16 0x2067
577 #define PCPP_PPP_RTP_CRDP16 0x2069
579 #define PCPP_PPP_CCCP 0x4001
581 #define PCPP_PPP_CDPD_MNRP 0x4003
583 #define PCPP_PPP_EXPANDAP 0x4005
585 #define PCPP_PPP_ODSICP 0x4007
587 #define PCPP_PPP_DOCSIS 0x4009
589 #define PCPP_PPP_CETACEANNDP 0x400b
591 #define PCPP_PPP_LZS 0x4021
593 #define PCPP_PPP_REFTEK 0x4023
595 #define PCPP_PPP_FC 0x4025
597 #define PCPP_PPP_EMIT 0x4027
599 #define PCPP_PPP_VSP 0x405b
601 #define PCPP_PPP_TLSP 0x405d
603 #define PCPP_PPP_IPCP 0x8021
605 #define PCPP_PPP_OSINLCP 0x8023
607 #define PCPP_PPP_XNSIDPCP 0x8025
609 #define PCPP_PPP_DECNETCP 0x8027
611 #define PCPP_PPP_ATCP 0x8029
613 #define PCPP_PPP_IPXCP 0x802b
615 #define PCPP_PPP_BRIDGENCP 0x8031
617 #define PCPP_PPP_SPCP 0x8033
619 #define PCPP_PPP_BVCP 0x8035
621 #define PCPP_PPP_MLCP 0x803d
623 #define PCPP_PPP_NBCP 0x803f
625 #define PCPP_PPP_CISCOCP 0x8041
627 #define PCPP_PPP_ASCOMCP 0x8043
629 #define PCPP_PPP_LBLBCP 0x8045
631 #define PCPP_PPP_RLNCP 0x8047
633 #define PCPP_PPP_SDCP 0x8049
635 #define PCPP_PPP_LLCCP 0x804b
637 #define PCPP_PPP_SNACP 0x804d
639 #define PCPP_PPP_IP6HCCP 0x804f
641 #define PCPP_PPP_KNXCP 0x8051
643 #define PCPP_PPP_ECP 0x8053
645 #define PCPP_PPP_ILECP 0x8055
647 #define PCPP_PPP_IPV6CP 0x8057
649 #define PCPP_PPP_MUXCP 0x8059
651 #define PCPP_PPP_VSNCP 0x805b
653 #define PCPP_PPP_TNCP 0x805d
655 #define PCPP_PPP_STAMPEDECP 0x806f
657 #define PCPP_PPP_MPPCP 0x8073
659 #define PCPP_PPP_IPICP 0x80c1
661 #define PCPP_PPP_SLCC 0x80fb
663 #define PCPP_PPP_CCP 0x80fd
665 #define PCPP_PPP_CDPCP 0x8207
667 #define PCPP_PPP_NETCSCP 0x8209
669 #define PCPP_PPP_STPCP 0x820b
671 #define PCPP_PPP_EDPCP 0x820d
673 #define PCPP_PPP_ACSPC 0x8235
675 #define PCPP_PPP_MPLSCP 0x8281
677 #define PCPP_PPP_P12844CP 0x8285
679 #define PCPP_PPP_TETRACP 0x8287
681 #define PCPP_PPP_MFTPCP 0x8289
683 #define PCPP_PPP_LCP 0xc021
685 #define PCPP_PPP_PAP 0xc023
687 #define PCPP_PPP_LQR 0xc025
689 #define PCPP_PPP_SPAP 0xc027
691 #define PCPP_PPP_CBCP 0xc029
693 #define PCPP_PPP_BACP 0xc02b
695 #define PCPP_PPP_BAP 0xc02d
697 #define PCPP_PPP_VSAP 0xc05b
699 #define PCPP_PPP_CONTCP 0xc081
701 #define PCPP_PPP_CHAP 0xc223
703 #define PCPP_PPP_RSAAP 0xc225
705 #define PCPP_PPP_EAP 0xc227
707 #define PCPP_PPP_SIEP 0xc229
709 #define PCPP_PPP_SBAP 0xc26f
711 #define PCPP_PPP_PRPAP 0xc281
713 #define PCPP_PPP_PRPAP2 0xc283
715 #define PCPP_PPP_PRPNIAP 0xc481
716 
717 } // namespace pcpp
Definition: Layer.h:117
Definition: Serializers.h:230
Definition: PPPoELayer.h:281
PPPoETagBuilder(PPPoETagTypes tagType)
Definition: PPPoELayer.h:286
PPPoETagBuilder(PPPoETagTypes tagType, uint8_t *tagValue, uint8_t tagValueLen)
Definition: PPPoELayer.h:303
PPPoETagBuilder(PPPoETagTypes tagType, uint32_t tagValue)
Definition: PPPoELayer.h:294
Definition: PPPoELayer.h:246
std::string getValueAsString() const
Definition: PPPoELayer.h:261
PPPoEDiscoveryLayer::PPPoETagTypes getType() const
PPPoETag(uint8_t *tagRawData)
Definition: PPPoELayer.h:250
size_t getDataSize() const override
~PPPoETag() override=default
A d'tor for this class, currently does nothing.
size_t getTotalSize() const override
Definition: PPPoELayer.h:200
void serializeLayer(ObjectScope &serializer) const override
PPPoETag addTag(const PPPoETagBuilder &tagBuilder)
PPPoEDiscoveryLayer(uint8_t *data, size_t dataLen, Layer *prevLayer, Packet *packet)
Definition: PPPoELayer.h:317
size_t getHeaderLen() const override
PPPoETag getFirstTag() const
PPPoETag addTagAfter(const PPPoETagBuilder &tagBuilder, PPPoETagTypes prevTagType)
std::string toString() const override
Definition: PPPoELayer.h:393
bool removeTag(PPPoEDiscoveryLayer::PPPoETagTypes tagType)
PPPoEDiscoveryLayer(uint8_t version, uint8_t type, PPPoELayer::PPPoECode code, uint16_t sessionId)
Definition: PPPoELayer.h:328
void parseNextLayer() override
Does nothing for this layer (PPPoE discovery is always the last layer)
Definition: PPPoELayer.h:387
PPPoETagTypes
PPPoE tag types.
Definition: PPPoELayer.h:204
@ PPPOE_TAG_SVC_ERR
Service-Name-Error tag type.
Definition: PPPoELayer.h:236
@ PPPOE_TAG_HURL
HURL tag type.
Definition: PPPoELayer.h:228
@ PPPOE_TAG_EOL
End-Of-List tag type.
Definition: PPPoELayer.h:206
@ PPPOE_TAG_CRED_SCALE
Credit Scale Factor tag type.
Definition: PPPoELayer.h:224
@ PPPOE_TAG_METRICS
Metrics tag type.
Definition: PPPoELayer.h:220
@ PPPOE_TAG_RELAY_ID
Relay-Session-Id tag type.
Definition: PPPoELayer.h:226
@ PPPOE_TAG_GENERIC_ERR
Generic-Error tag type.
Definition: PPPoELayer.h:240
@ PPPOE_TAG_SVC_NAME
Service-Name tag type.
Definition: PPPoELayer.h:208
@ PPPOE_TAG_CREDITS
Credits tag type.
Definition: PPPoELayer.h:218
@ PPPOE_TAG_AC_NAME
AC-Name tag type.
Definition: PPPoELayer.h:210
@ PPPOE_TAG_MOTM
MOTM tag type.
Definition: PPPoELayer.h:230
@ PPPOE_TAG_SEQ_NUM
Sequence Number tag type.
Definition: PPPoELayer.h:222
@ PPPOE_TAG_HOST_UNIQ
Host-Uniq tag type.
Definition: PPPoELayer.h:212
@ PPPOE_TAG_MAX_PAYLD
PPP-Max-Payload tag type.
Definition: PPPoELayer.h:232
@ PPPOE_TAG_IP_RT_ADD
IP_Route_Add tag type.
Definition: PPPoELayer.h:234
@ PPPOE_TAG_AC_COOKIE
AC-Cookie tag type.
Definition: PPPoELayer.h:214
@ PPPOE_TAG_AC_ERR
AC-System-Error tag type.
Definition: PPPoELayer.h:238
@ PPPOE_TAG_VENDOR
Vendor-Specific tag type.
Definition: PPPoELayer.h:216
PPPoETag getNextTag(const PPPoETag &tag) const
static bool isDataValid(const uint8_t *data, size_t dataLen)
Definition: PPPoELayer.h:443
PPPoETag getTag(PPPoEDiscoveryLayer::PPPoETagTypes tagType) const
Definition: PPPoELayer.h:48
OsiModelLayer getOsiModelLayer() const override
Definition: PPPoELayer.h:92
void serializeLayer(ObjectScope &serializer) const override
PPPoECode
PPPoE possible codes.
Definition: PPPoELayer.h:52
@ PPPOE_CODE_PADR
PPPoE discovery PADR.
Definition: PPPoELayer.h:66
@ PPPOE_CODE_PADQ
PPPoE discovery PADQ.
Definition: PPPoELayer.h:64
@ PPPOE_CODE_PADI
PPPoE discovery PADI.
Definition: PPPoELayer.h:58
@ PPPOE_CODE_PADS
PPPoE discovery PADS.
Definition: PPPoELayer.h:68
@ PPPOE_CODE_PADN
PPPoE discovery PADN.
Definition: PPPoELayer.h:74
@ PPPOE_CODE_PADC
PPPoE discovery PADC.
Definition: PPPoELayer.h:62
@ PPPOE_CODE_SESSION
PPPoE session code.
Definition: PPPoELayer.h:54
@ PPPOE_CODE_PADM
PPPoE discovery PADM.
Definition: PPPoELayer.h:72
@ PPPOE_CODE_PADT
PPPoE discovery PADT.
Definition: PPPoELayer.h:70
@ PPPOE_CODE_PADO
PPPoE discovery PADO.
Definition: PPPoELayer.h:56
@ PPPOE_CODE_PADG
PPPoE discovery PADG.
Definition: PPPoELayer.h:60
void computeCalculateFields() override
Calculate pppoe_header::payloadLength field.
pppoe_header * getPPPoEHeader() const
Definition: PPPoELayer.h:82
Definition: PPPoELayer.h:143
static bool isDataValid(const uint8_t *data, size_t dataLen)
Definition: PPPoELayer.h:438
PPPoESessionLayer(uint8_t *data, size_t dataLen, Layer *prevLayer, Packet *packet)
Definition: PPPoELayer.h:150
std::string toString() const override
uint16_t getPPPNextProtocol() const
PPPoESessionLayer(uint8_t version, uint8_t type, uint16_t sessionId, uint16_t pppNextProtocol)
Definition: PPPoELayer.h:160
void parseNextLayer() override
Currently identifies the following next layers: IPv4Layer, IPv6Layer. Otherwise sets PayloadLayer.
void setPPPNextProtocol(uint16_t nextProtocol)
size_t getHeaderLen() const override
Definition: PPPoELayer.h:189
Definition: Packet.h:49
Definition: TLVData.h:374
Definition: TLVData.h:20
Definition: TLVData.h:219
uint8_t ProtocolType
Definition: ProtocolType.h:38
const ProtocolType PPPoESession
PPPoE session protocol.
Definition: ProtocolType.h:84
const ProtocolType PPPoEDiscovery
PPPoE discovery protocol.
Definition: ProtocolType.h:87
The main namespace for the PcapPlusPlus lib.
Definition: AssertionUtils.h:19
OsiModelLayer
An enum representing OSI model layers.
Definition: ProtocolType.h:425
@ OsiModelDataLinkLayer
Data link layer (layer 2)
Definition: ProtocolType.h:429
Definition: Serializers.h:18
Definition: Layer.h:212
static std::vector< FieldDescriptor > all()
Definition: Layer.h:214
static constexpr uint16_t MaxID
Maximum field ID used by the layer.
Definition: Layer.h:229
static const FieldDescriptor Tag
Field descriptor for a single entry of the Tags array, written as the tag type name (e....
Definition: PPPoELayer.h:417
static const FieldDescriptor Tags
Field descriptor for the array of PPPoE tags found in the layer.
Definition: PPPoELayer.h:413
static std::vector< FieldDescriptor > all()
Definition: PPPoELayer.h:404
Definition: PPPoELayer.h:101
static const FieldDescriptor Type
Field descriptor for the PPPoE type, written as a number.
Definition: PPPoELayer.h:118
static const FieldDescriptor Code
Field descriptor for the PPPoE code, written as a number.
Definition: PPPoELayer.h:112
static std::vector< FieldDescriptor > all()
Definition: PPPoELayer.h:103
static const FieldDescriptor Version
Field descriptor for the PPPoE version, written as a number.
Definition: PPPoELayer.h:115
static const FieldDescriptor SessionID
Field descriptor for the PPPoE session ID, written as a number in host byte order.
Definition: PPPoELayer.h:121
static constexpr uint16_t MaxID
Maximum field ID used by the layer.
Definition: PPPoELayer.h:124
Definition: PPPoELayer.h:20
uint16_t payloadLength
Length (in bytes) of payload, not including the PPPoE header.
Definition: PPPoELayer.h:39
uint8_t type
PPPoE type.
Definition: PPPoELayer.h:25
uint8_t version
PPPoE version.
Definition: PPPoELayer.h:23
uint8_t code
PPPoE code.
Definition: PPPoELayer.h:27
uint16_t sessionId
PPPoE session ID (relevant for PPPoE session packets only)
Definition: PPPoELayer.h:37