Coverage Report

Created: 2025-07-12 07:37

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