/src/PcapPlusPlus/Packet++/src/SllLayer.cpp
Line | Count | Source |
1 | 0 | #define LOG_MODULE PacketLogModuleSllLayer |
2 | | |
3 | | #include "SllLayer.h" |
4 | | #include "Logger.h" |
5 | | #include "IPv4Layer.h" |
6 | | #include "IPv6Layer.h" |
7 | | #include "PayloadLayer.h" |
8 | | #include "ArpLayer.h" |
9 | | #include "VlanLayer.h" |
10 | | #include "PPPoELayer.h" |
11 | | #include "MplsLayer.h" |
12 | | #include "EndianPortable.h" |
13 | | #include "GeneralUtils.h" |
14 | | |
15 | | namespace pcpp |
16 | | { |
17 | | |
18 | | SllLayer::SllLayer(uint16_t packetType, uint16_t ARPHRDType) |
19 | 0 | { |
20 | 0 | allocData(sizeof(sll_header)); |
21 | |
|
22 | 0 | auto* sllHdr = reinterpret_cast<sll_header*>(m_Data); |
23 | 0 | sllHdr->packet_type = htobe16(packetType); |
24 | 0 | sllHdr->ARPHRD_type = htobe16(ARPHRDType); |
25 | 0 | m_Protocol = SLL; |
26 | 0 | } |
27 | | |
28 | | bool SllLayer::setLinkLayerAddr(uint8_t* addr, size_t addrLength) |
29 | 0 | { |
30 | 0 | if (addr == nullptr || addrLength == 0 || addrLength > 8) |
31 | 0 | { |
32 | 0 | PCPP_LOG_ERROR("Address length is out of bounds, it must be between 1 and 8"); |
33 | 0 | return false; |
34 | 0 | } |
35 | | |
36 | 0 | sll_header* sllHdr = getSllHeader(); |
37 | 0 | memcpy(sllHdr->link_layer_addr, addr, addrLength); |
38 | 0 | sllHdr->link_layer_addr_len = htobe16(addrLength); |
39 | |
|
40 | 0 | return true; |
41 | 0 | } |
42 | | |
43 | | bool SllLayer::setMacAddressAsLinkLayer(MacAddress const& macAddr) |
44 | 0 | { |
45 | 0 | uint8_t macAddrAsArr[6]; |
46 | 0 | macAddr.copyTo(macAddrAsArr); |
47 | 0 | return setLinkLayerAddr(macAddrAsArr, 6); |
48 | 0 | } |
49 | | |
50 | | void SllLayer::parseNextLayer() |
51 | 13.3k | { |
52 | 13.3k | if (m_DataLen <= sizeof(sll_header)) |
53 | 388 | return; |
54 | | |
55 | 12.9k | uint8_t* payload = m_Data + sizeof(sll_header); |
56 | 12.9k | size_t payloadLen = m_DataLen - sizeof(sll_header); |
57 | | |
58 | 12.9k | sll_header* hdr = getSllHeader(); |
59 | 12.9k | switch (be16toh(hdr->protocol_type)) |
60 | 12.9k | { |
61 | 8.57k | case PCPP_ETHERTYPE_IP: |
62 | 8.57k | { |
63 | 8.57k | tryConstructNextLayerWithFallback<IPv4Layer, PayloadLayer>(payload, payloadLen); |
64 | 8.57k | break; |
65 | 0 | } |
66 | 1.00k | case PCPP_ETHERTYPE_IPV6: |
67 | 1.00k | { |
68 | 1.00k | tryConstructNextLayerWithFallback<IPv6Layer, PayloadLayer>(payload, payloadLen); |
69 | 1.00k | break; |
70 | 0 | } |
71 | 1.77k | case PCPP_ETHERTYPE_ARP: |
72 | 1.77k | { |
73 | 1.77k | tryConstructNextLayerWithFallback<ArpLayer, PayloadLayer>(payload, payloadLen); |
74 | 1.77k | break; |
75 | 0 | } |
76 | 0 | case PCPP_ETHERTYPE_VLAN: |
77 | 0 | case PCPP_ETHERTYPE_IEEE_802_1AD: |
78 | 0 | { |
79 | 0 | tryConstructNextLayerWithFallback<VlanLayer, PayloadLayer>(payload, payloadLen); |
80 | 0 | break; |
81 | 0 | } |
82 | 0 | case PCPP_ETHERTYPE_PPPOES: |
83 | 0 | { |
84 | 0 | tryConstructNextLayerWithFallback<PPPoESessionLayer, PayloadLayer>(payload, payloadLen); |
85 | 0 | break; |
86 | 0 | } |
87 | 0 | case PCPP_ETHERTYPE_PPPOED: |
88 | 0 | { |
89 | 0 | tryConstructNextLayerWithFallback<PPPoEDiscoveryLayer, PayloadLayer>(payload, payloadLen); |
90 | 0 | break; |
91 | 0 | } |
92 | 723 | case PCPP_ETHERTYPE_MPLS: |
93 | 723 | { |
94 | 723 | tryConstructNextLayerWithFallback<MplsLayer, PayloadLayer>(payload, payloadLen); |
95 | 723 | break; |
96 | 0 | } |
97 | 855 | default: |
98 | 855 | { |
99 | 855 | constructNextLayer<PayloadLayer>(payload, payloadLen); |
100 | 855 | break; |
101 | 0 | } |
102 | 12.9k | } |
103 | 12.9k | } |
104 | | |
105 | | void SllLayer::computeCalculateFields() |
106 | 3.24k | { |
107 | 3.24k | if (m_NextLayer == nullptr) |
108 | 194 | return; |
109 | | |
110 | 3.05k | sll_header* hdr = getSllHeader(); |
111 | 3.05k | switch (m_NextLayer->getProtocol()) |
112 | 3.05k | { |
113 | 1.65k | case IPv4: |
114 | 1.65k | hdr->protocol_type = htobe16(PCPP_ETHERTYPE_IP); |
115 | 1.65k | break; |
116 | 202 | case IPv6: |
117 | 202 | hdr->protocol_type = htobe16(PCPP_ETHERTYPE_IPV6); |
118 | 202 | break; |
119 | 473 | case ARP: |
120 | 473 | hdr->protocol_type = htobe16(PCPP_ETHERTYPE_ARP); |
121 | 473 | break; |
122 | 0 | case VLAN: |
123 | 0 | hdr->protocol_type = htobe16(PCPP_ETHERTYPE_VLAN); |
124 | 0 | break; |
125 | 720 | default: |
126 | 720 | return; |
127 | 3.05k | } |
128 | 3.05k | } |
129 | | |
130 | | std::string SllLayer::toString() const |
131 | 6.49k | { |
132 | 6.49k | return "Linux cooked header"; |
133 | 6.49k | } |
134 | | |
135 | | const FieldDescriptor SllLayer::SerializedFields::PacketType{ Layer::SerializedFields::MaxID + 1, "packetType" }; |
136 | | const FieldDescriptor SllLayer::SerializedFields::ArpHeaderType{ Layer::SerializedFields::MaxID + 2, |
137 | | "arpHeaderType" }; |
138 | | const FieldDescriptor SllLayer::SerializedFields::ProtocolType{ Layer::SerializedFields::MaxID + 3, |
139 | | "protocolType" }; |
140 | | const FieldDescriptor SllLayer::SerializedFields::LinkLayerAddress{ Layer::SerializedFields::MaxID + 4, |
141 | | "linkLayerAddress" }; |
142 | | |
143 | | void SllLayer::serializeLayer(ObjectScope& serializer) const |
144 | 0 | { |
145 | 0 | auto* header = getSllHeader(); |
146 | 0 | serializer.writeField(SerializedFields::PacketType, be16toh(header->packet_type)); |
147 | 0 | serializer.writeField(SerializedFields::ArpHeaderType, be16toh(header->ARPHRD_type)); |
148 | 0 | serializer.writeField(SerializedFields::ProtocolType, be16toh(header->protocol_type)); |
149 | | auto linkLayerAddrLen = (std::min)(be16toh(header->link_layer_addr_len), static_cast<uint16_t>(8)); |
150 | 0 | serializer.writeField(SerializedFields::LinkLayerAddress, |
151 | 0 | byteArrayToHexString(header->link_layer_addr, linkLayerAddrLen)); |
152 | 0 | } |
153 | | |
154 | | } // namespace pcpp |