/src/PcapPlusPlus/Packet++/src/SllLayer.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | #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 <string.h> |
13 | | #include "EndianPortable.h" |
14 | | |
15 | | namespace pcpp |
16 | | { |
17 | | |
18 | | SllLayer::SllLayer(uint16_t packetType, uint16_t ARPHRDType) |
19 | 0 | { |
20 | 0 | const size_t headerLen = sizeof(sll_header); |
21 | 0 | m_DataLen = headerLen; |
22 | 0 | m_Data = new uint8_t[headerLen]; |
23 | 0 | memset(m_Data, 0, headerLen); |
24 | 0 | sll_header* sllHdr = (sll_header*)m_Data; |
25 | 0 | sllHdr->packet_type = htobe16(packetType); |
26 | 0 | sllHdr->ARPHRD_type = htobe16(ARPHRDType); |
27 | 0 | m_Protocol = SLL; |
28 | 0 | } |
29 | | |
30 | | bool SllLayer::setLinkLayerAddr(uint8_t* addr, size_t addrLength) |
31 | 0 | { |
32 | 0 | if (addr == nullptr || addrLength == 0 || addrLength > 8) |
33 | 0 | { |
34 | 0 | PCPP_LOG_ERROR("Address length is out of bounds, it must be between 1 and 8"); |
35 | 0 | return false; |
36 | 0 | } |
37 | | |
38 | 0 | sll_header* sllHdr = getSllHeader(); |
39 | 0 | memcpy(sllHdr->link_layer_addr, addr, addrLength); |
40 | 0 | sllHdr->link_layer_addr_len = htobe16(addrLength); |
41 | |
|
42 | 0 | return true; |
43 | 0 | } |
44 | | |
45 | | bool SllLayer::setMacAddressAsLinkLayer(MacAddress const& macAddr) |
46 | 0 | { |
47 | 0 | if (!macAddr.isValid()) |
48 | 0 | { |
49 | 0 | PCPP_LOG_ERROR("MAC address is not valid"); |
50 | 0 | return false; |
51 | 0 | } |
52 | | |
53 | 0 | uint8_t macAddrAsArr[6]; |
54 | 0 | macAddr.copyTo(macAddrAsArr); |
55 | 0 | return setLinkLayerAddr(macAddrAsArr, 6); |
56 | 0 | } |
57 | | |
58 | | void SllLayer::parseNextLayer() |
59 | 59.6k | { |
60 | 59.6k | if (m_DataLen <= sizeof(sll_header)) |
61 | 268 | return; |
62 | | |
63 | 59.4k | uint8_t* payload = m_Data + sizeof(sll_header); |
64 | 59.4k | size_t payloadLen = m_DataLen - sizeof(sll_header); |
65 | | |
66 | 59.4k | sll_header* hdr = getSllHeader(); |
67 | 59.4k | switch (be16toh(hdr->protocol_type)) |
68 | 59.4k | { |
69 | 41.6k | case PCPP_ETHERTYPE_IP: |
70 | 41.6k | m_NextLayer = IPv4Layer::isDataValid(payload, payloadLen) |
71 | 41.6k | ? static_cast<Layer*>(new IPv4Layer(payload, payloadLen, this, m_Packet)) |
72 | 41.6k | : static_cast<Layer*>(new PayloadLayer(payload, payloadLen, this, m_Packet)); |
73 | 41.6k | break; |
74 | 13.3k | case PCPP_ETHERTYPE_IPV6: |
75 | 13.3k | m_NextLayer = IPv6Layer::isDataValid(payload, payloadLen) |
76 | 13.3k | ? static_cast<Layer*>(new IPv6Layer(payload, payloadLen, this, m_Packet)) |
77 | 13.3k | : static_cast<Layer*>(new PayloadLayer(payload, payloadLen, this, m_Packet)); |
78 | 13.3k | break; |
79 | 1.14k | case PCPP_ETHERTYPE_ARP: |
80 | 1.14k | m_NextLayer = new ArpLayer(payload, payloadLen, this, m_Packet); |
81 | 1.14k | break; |
82 | 7 | case PCPP_ETHERTYPE_VLAN: |
83 | 7 | case PCPP_ETHERTYPE_IEEE_802_1AD: |
84 | 7 | m_NextLayer = new VlanLayer(payload, payloadLen, this, m_Packet); |
85 | 7 | break; |
86 | 241 | case PCPP_ETHERTYPE_PPPOES: |
87 | 241 | m_NextLayer = PPPoESessionLayer::isDataValid(payload, payloadLen) |
88 | 241 | ? static_cast<Layer*>(new PPPoESessionLayer(payload, payloadLen, this, m_Packet)) |
89 | 241 | : static_cast<Layer*>(new PayloadLayer(payload, payloadLen, this, m_Packet)); |
90 | 241 | break; |
91 | 0 | case PCPP_ETHERTYPE_PPPOED: |
92 | 0 | m_NextLayer = PPPoEDiscoveryLayer::isDataValid(payload, payloadLen) |
93 | 0 | ? static_cast<Layer*>(new PPPoEDiscoveryLayer(payload, payloadLen, this, m_Packet)) |
94 | 0 | : static_cast<Layer*>(new PayloadLayer(payload, payloadLen, this, m_Packet)); |
95 | 0 | break; |
96 | 0 | case PCPP_ETHERTYPE_MPLS: |
97 | 0 | m_NextLayer = new MplsLayer(payload, payloadLen, this, m_Packet); |
98 | 0 | break; |
99 | 3.01k | default: |
100 | 3.01k | m_NextLayer = new PayloadLayer(payload, payloadLen, this, m_Packet); |
101 | 59.4k | } |
102 | | |
103 | 59.4k | } |
104 | | |
105 | | void SllLayer::computeCalculateFields() |
106 | 11.4k | { |
107 | 11.4k | if (m_NextLayer == nullptr) |
108 | 134 | return; |
109 | | |
110 | 11.3k | sll_header* hdr = getSllHeader(); |
111 | 11.3k | switch (m_NextLayer->getProtocol()) |
112 | 11.3k | { |
113 | 7.48k | case IPv4: |
114 | 7.48k | hdr->protocol_type = htobe16(PCPP_ETHERTYPE_IP); |
115 | 7.48k | break; |
116 | 2.28k | case IPv6: |
117 | 2.28k | hdr->protocol_type = htobe16(PCPP_ETHERTYPE_IPV6); |
118 | 2.28k | break; |
119 | 378 | case ARP: |
120 | 378 | hdr->protocol_type = htobe16(PCPP_ETHERTYPE_ARP); |
121 | 378 | break; |
122 | 1 | case VLAN: |
123 | 1 | hdr->protocol_type = htobe16(PCPP_ETHERTYPE_VLAN); |
124 | 1 | break; |
125 | 1.21k | default: |
126 | 1.21k | return; |
127 | 11.3k | } |
128 | 11.3k | } |
129 | | |
130 | | std::string SllLayer::toString() const |
131 | 22.9k | { |
132 | 22.9k | return "Linux cooked header"; |
133 | 22.9k | } |
134 | | |
135 | | } // namespace pcpp |