Coverage Report

Created: 2025-11-09 07:08

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/PcapPlusPlus/Packet++/src/VlanLayer.cpp
Line
Count
Source
1
#define LOG_MODULE PacketLogModuleVlanLayer
2
3
#include "VlanLayer.h"
4
#include "IPv4Layer.h"
5
#include "IPv6Layer.h"
6
#include "PayloadLayer.h"
7
#include "ArpLayer.h"
8
#include "PPPoELayer.h"
9
#include "MplsLayer.h"
10
#include "LLCLayer.h"
11
#include <sstream>
12
#include "EndianPortable.h"
13
14
namespace pcpp
15
{
16
17
  VlanLayer::VlanLayer(const uint16_t vlanID, bool cfi, uint8_t priority, uint16_t etherType)
18
0
  {
19
0
    const size_t headerLen = sizeof(vlan_header);
20
0
    m_DataLen = headerLen;
21
0
    m_Data = new uint8_t[headerLen];
22
0
    memset(m_Data, 0, headerLen);
23
0
    m_Protocol = VLAN;
24
25
0
    vlan_header* vlanHeader = getVlanHeader();
26
0
    setVlanID(vlanID);
27
0
    setCFI(cfi);
28
0
    setPriority(priority);
29
0
    vlanHeader->etherType = htobe16(etherType);
30
0
  }
31
32
  uint16_t VlanLayer::getVlanID() const
33
0
  {
34
0
    return be16toh(getVlanHeader()->vlan) & 0xFFF;
35
0
  }
36
37
  uint8_t VlanLayer::getCFI() const
38
0
  {
39
0
    return ((be16toh(getVlanHeader()->vlan) >> 12) & 1);
40
0
  }
41
42
  uint8_t VlanLayer::getPriority() const
43
0
  {
44
0
    return (be16toh(getVlanHeader()->vlan) >> 13) & 7;
45
0
  }
46
47
  void VlanLayer::setVlanID(uint16_t id)
48
0
  {
49
0
    getVlanHeader()->vlan = htobe16((be16toh(getVlanHeader()->vlan) & (~0xFFF)) | (id & 0xFFF));
50
0
  }
51
52
  void VlanLayer::setCFI(bool cfi)
53
0
  {
54
0
    getVlanHeader()->vlan = htobe16((be16toh(getVlanHeader()->vlan) & (~(1 << 12))) | ((cfi & 1) << 12));
55
0
  }
56
57
  void VlanLayer::setPriority(uint8_t priority)
58
0
  {
59
0
    getVlanHeader()->vlan = htobe16((be16toh(getVlanHeader()->vlan) & (~(7 << 13))) | ((priority & 7) << 13));
60
0
  }
61
62
  void VlanLayer::parseNextLayer()
63
0
  {
64
0
    if (m_DataLen <= sizeof(vlan_header))
65
0
      return;
66
67
0
    uint8_t* payload = m_Data + sizeof(vlan_header);
68
0
    size_t payloadLen = m_DataLen - sizeof(vlan_header);
69
70
0
    vlan_header* hdr = getVlanHeader();
71
0
    switch (be16toh(hdr->etherType))
72
0
    {
73
0
    case PCPP_ETHERTYPE_IP:
74
0
      m_NextLayer = IPv4Layer::isDataValid(payload, payloadLen)
75
0
                        ? static_cast<Layer*>(new IPv4Layer(payload, payloadLen, this, m_Packet))
76
0
                        : static_cast<Layer*>(new PayloadLayer(payload, payloadLen, this, m_Packet));
77
0
      break;
78
0
    case PCPP_ETHERTYPE_IPV6:
79
0
      m_NextLayer = IPv6Layer::isDataValid(payload, payloadLen)
80
0
                        ? static_cast<Layer*>(new IPv6Layer(payload, payloadLen, this, m_Packet))
81
0
                        : static_cast<Layer*>(new PayloadLayer(payload, payloadLen, this, m_Packet));
82
0
      break;
83
0
    case PCPP_ETHERTYPE_ARP:
84
0
      m_NextLayer = new ArpLayer(payload, payloadLen, this, m_Packet);
85
0
      break;
86
0
    case PCPP_ETHERTYPE_VLAN:
87
0
    case PCPP_ETHERTYPE_IEEE_802_1AD:
88
0
      m_NextLayer = new VlanLayer(payload, payloadLen, this, m_Packet);
89
0
      break;
90
0
    case PCPP_ETHERTYPE_PPPOES:
91
0
      m_NextLayer = PPPoESessionLayer::isDataValid(payload, payloadLen)
92
0
                        ? static_cast<Layer*>(new PPPoESessionLayer(payload, payloadLen, this, m_Packet))
93
0
                        : static_cast<Layer*>(new PayloadLayer(payload, payloadLen, this, m_Packet));
94
0
      break;
95
0
    case PCPP_ETHERTYPE_PPPOED:
96
0
      m_NextLayer = PPPoEDiscoveryLayer::isDataValid(payload, payloadLen)
97
0
                        ? static_cast<Layer*>(new PPPoEDiscoveryLayer(payload, payloadLen, this, m_Packet))
98
0
                        : static_cast<Layer*>(new PayloadLayer(payload, payloadLen, this, m_Packet));
99
0
      break;
100
0
    case PCPP_ETHERTYPE_MPLS:
101
0
      m_NextLayer = new MplsLayer(payload, payloadLen, this, m_Packet);
102
0
      break;
103
0
    default:
104
0
      m_NextLayer = (be16toh(hdr->etherType) < 1500 && LLCLayer::isDataValid(payload, payloadLen))
105
0
                        ? static_cast<Layer*>(new LLCLayer(payload, payloadLen, this, m_Packet))
106
0
                        : static_cast<Layer*>(new PayloadLayer(payload, payloadLen, this, m_Packet));
107
0
    }
108
0
  }
109
110
  void VlanLayer::computeCalculateFields()
111
0
  {
112
0
    if (m_NextLayer == nullptr)
113
0
      return;
114
115
0
    switch (m_NextLayer->getProtocol())
116
0
    {
117
0
    case IPv4:
118
0
      getVlanHeader()->etherType = htobe16(PCPP_ETHERTYPE_IP);
119
0
      break;
120
0
    case IPv6:
121
0
      getVlanHeader()->etherType = htobe16(PCPP_ETHERTYPE_IPV6);
122
0
      break;
123
0
    case ARP:
124
0
      getVlanHeader()->etherType = htobe16(PCPP_ETHERTYPE_ARP);
125
0
      break;
126
0
    case VLAN:
127
0
      getVlanHeader()->etherType = htobe16(PCPP_ETHERTYPE_VLAN);
128
0
      break;
129
0
    default:
130
0
      return;
131
0
    }
132
0
  }
133
134
  std::string VlanLayer::toString() const
135
0
  {
136
0
    std::ostringstream cfiStream;
137
0
    cfiStream << (int)getCFI();
138
0
    std::ostringstream priStream;
139
0
    priStream << (int)getPriority();
140
0
    std::ostringstream idStream;
141
0
    idStream << getVlanID();
142
143
0
    return "VLAN Layer, Priority: " + priStream.str() + ", Vlan ID: " + idStream.str() +
144
0
           ", CFI: " + cfiStream.str();
145
0
  }
146
147
}  // namespace pcpp