/src/PcapPlusPlus/Packet++/src/CiscoHdlcLayer.cpp
Line | Count | Source |
1 | | #include "CiscoHdlcLayer.h" |
2 | | #include "Layer.h" |
3 | | #include "IPv4Layer.h" |
4 | | #include "IPv6Layer.h" |
5 | | #include "PayloadLayer.h" |
6 | | #include "EndianPortable.h" |
7 | | #include <string.h> |
8 | | |
9 | | namespace pcpp |
10 | | { |
11 | | |
12 | | // Protocol types for Cisco HDLC |
13 | | constexpr uint16_t CiscoHdlcTypeIp = 0x0800; |
14 | | constexpr uint16_t CiscoHdlcTypeIpv6 = 0x86DD; |
15 | | |
16 | | CiscoHdlcLayer::CiscoHdlcLayer(AddressType address) |
17 | 0 | { |
18 | 0 | allocData(sizeof(cisco_hdlc_header)); |
19 | |
|
20 | 0 | cisco_hdlc_header* hdlcHdr = getCiscoHdlcHeader(); |
21 | 0 | hdlcHdr->address = static_cast<uint8_t>(address == AddressType::Unknown ? AddressType::Unicast : address); |
22 | 0 | hdlcHdr->control = 0; // Always 0 for Cisco HDLC |
23 | 0 | } |
24 | | |
25 | | void CiscoHdlcLayer::computeCalculateFields() |
26 | 147 | { |
27 | 147 | if (m_NextLayer != nullptr) |
28 | 147 | { |
29 | 147 | switch (m_NextLayer->getProtocol()) |
30 | 147 | { |
31 | 0 | case IPv4: |
32 | 0 | { |
33 | 0 | setNextProtocol(CiscoHdlcTypeIp); |
34 | 0 | break; |
35 | 0 | } |
36 | 0 | case IPv6: |
37 | 0 | { |
38 | 0 | setNextProtocol(CiscoHdlcTypeIpv6); |
39 | 0 | break; |
40 | 0 | } |
41 | 147 | } |
42 | 147 | } |
43 | 147 | } |
44 | | |
45 | | void CiscoHdlcLayer::parseNextLayer() |
46 | 441 | { |
47 | 441 | auto payload = m_Data + sizeof(cisco_hdlc_header); |
48 | 441 | auto payloadLen = m_DataLen - sizeof(cisco_hdlc_header); |
49 | | |
50 | 441 | auto nextProtocol = be16toh(getCiscoHdlcHeader()->protocol); |
51 | | |
52 | 441 | switch (nextProtocol) |
53 | 441 | { |
54 | 0 | case CiscoHdlcTypeIp: |
55 | 0 | { |
56 | 0 | tryConstructNextLayerWithFallback<IPv4Layer, PayloadLayer>(payload, payloadLen); |
57 | 0 | break; |
58 | 0 | } |
59 | 0 | case CiscoHdlcTypeIpv6: |
60 | 0 | { |
61 | 0 | tryConstructNextLayerWithFallback<IPv6Layer, PayloadLayer>(payload, payloadLen); |
62 | 0 | break; |
63 | 0 | } |
64 | 441 | default: |
65 | 441 | { |
66 | 441 | constructNextLayer<PayloadLayer>(payload, payloadLen); |
67 | 441 | break; |
68 | 0 | } |
69 | 441 | } |
70 | 441 | } |
71 | | |
72 | | std::string CiscoHdlcLayer::toString() const |
73 | 294 | { |
74 | 294 | return "Cisco HDLC Layer"; |
75 | 294 | } |
76 | | |
77 | | CiscoHdlcLayer::AddressType CiscoHdlcLayer::getAddress() const |
78 | 0 | { |
79 | 0 | switch (static_cast<AddressType>(getAddressValue())) |
80 | 0 | { |
81 | 0 | case AddressType::Unicast: |
82 | 0 | case AddressType::Multicast: |
83 | 0 | { |
84 | 0 | return static_cast<AddressType>(getAddressValue()); |
85 | 0 | } |
86 | 0 | default: |
87 | 0 | { |
88 | 0 | return AddressType::Unknown; |
89 | 0 | } |
90 | 0 | } |
91 | 0 | } |
92 | | |
93 | | uint8_t CiscoHdlcLayer::getAddressValue() const |
94 | 0 | { |
95 | 0 | return getCiscoHdlcHeader()->address; |
96 | 0 | } |
97 | | |
98 | | void CiscoHdlcLayer::setAddress(AddressType address) |
99 | 0 | { |
100 | 0 | if (address == AddressType::Unknown) |
101 | 0 | { |
102 | 0 | throw std::invalid_argument("Cannot set the address to Address::Unknown"); |
103 | 0 | } |
104 | | |
105 | 0 | setAddressValue(static_cast<uint8_t>(address)); |
106 | 0 | } |
107 | | |
108 | | void CiscoHdlcLayer::setAddressValue(uint8_t address) |
109 | 0 | { |
110 | 0 | getCiscoHdlcHeader()->address = address; |
111 | 0 | } |
112 | | |
113 | | uint16_t CiscoHdlcLayer::getNextProtocol() const |
114 | 0 | { |
115 | 0 | return be16toh(getCiscoHdlcHeader()->protocol); |
116 | 0 | } |
117 | | |
118 | | void CiscoHdlcLayer::setNextProtocol(uint16_t protocol) |
119 | 0 | { |
120 | | getCiscoHdlcHeader()->protocol = htobe16(protocol); |
121 | 0 | } |
122 | | } // namespace pcpp |