Coverage Report

Created: 2026-11-12 06:50

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
    allocData(sizeof(vlan_header));
20
0
    m_Protocol = VLAN;
21
22
0
    vlan_header* vlanHeader = getVlanHeader();
23
0
    setVlanID(vlanID);
24
0
    setCFI(cfi);
25
0
    setPriority(priority);
26
0
    vlanHeader->etherType = htobe16(etherType);
27
0
  }
28
29
  uint16_t VlanLayer::getVlanID() const
30
14.9k
  {
31
14.9k
    return be16toh(getVlanHeader()->vlan) & 0xFFF;
32
14.9k
  }
33
34
  uint8_t VlanLayer::getCFI() const
35
14.9k
  {
36
14.9k
    return ((be16toh(getVlanHeader()->vlan) >> 12) & 1);
37
14.9k
  }
38
39
  uint8_t VlanLayer::getPriority() const
40
14.9k
  {
41
14.9k
    return (be16toh(getVlanHeader()->vlan) >> 13) & 7;
42
14.9k
  }
43
44
  void VlanLayer::setVlanID(uint16_t id)
45
0
  {
46
0
    getVlanHeader()->vlan = htobe16((be16toh(getVlanHeader()->vlan) & (~0xFFF)) | (id & 0xFFF));
47
0
  }
48
49
  void VlanLayer::setCFI(bool cfi)
50
0
  {
51
0
    getVlanHeader()->vlan = htobe16((be16toh(getVlanHeader()->vlan) & (~(1 << 12))) | ((cfi & 1) << 12));
52
0
  }
53
54
  void VlanLayer::setPriority(uint8_t priority)
55
0
  {
56
0
    getVlanHeader()->vlan = htobe16((be16toh(getVlanHeader()->vlan) & (~(7 << 13))) | ((priority & 7) << 13));
57
0
  }
58
59
  void VlanLayer::parseNextLayer()
60
73.8k
  {
61
73.8k
    if (m_DataLen <= sizeof(vlan_header))
62
0
      return;
63
64
73.8k
    uint8_t* payload = m_Data + sizeof(vlan_header);
65
73.8k
    size_t payloadLen = m_DataLen - sizeof(vlan_header);
66
67
73.8k
    vlan_header* hdr = getVlanHeader();
68
73.8k
    switch (be16toh(hdr->etherType))
69
73.8k
    {
70
13.7k
    case PCPP_ETHERTYPE_IP:
71
13.7k
    {
72
13.7k
      tryConstructNextLayerWithFallback<IPv4Layer, PayloadLayer>(payload, payloadLen);
73
13.7k
      break;
74
0
    }
75
2.15k
    case PCPP_ETHERTYPE_IPV6:
76
2.15k
    {
77
2.15k
      tryConstructNextLayerWithFallback<IPv6Layer, PayloadLayer>(payload, payloadLen);
78
2.15k
      break;
79
0
    }
80
5.41k
    case PCPP_ETHERTYPE_ARP:
81
5.41k
    {
82
5.41k
      tryConstructNextLayerWithFallback<ArpLayer, PayloadLayer>(payload, payloadLen);
83
5.41k
      break;
84
0
    }
85
18.0k
    case PCPP_ETHERTYPE_VLAN:
86
18.0k
    case PCPP_ETHERTYPE_IEEE_802_1AD:
87
18.0k
    {
88
18.0k
      tryConstructNextLayerWithFallback<VlanLayer, PayloadLayer>(payload, payloadLen);
89
18.0k
      break;
90
18.0k
    }
91
18.3k
    case PCPP_ETHERTYPE_PPPOES:
92
18.3k
    {
93
18.3k
      tryConstructNextLayerWithFallback<PPPoESessionLayer, PayloadLayer>(payload, payloadLen);
94
18.3k
      break;
95
18.0k
    }
96
8
    case PCPP_ETHERTYPE_PPPOED:
97
8
    {
98
8
      tryConstructNextLayerWithFallback<PPPoEDiscoveryLayer, PayloadLayer>(payload, payloadLen);
99
8
      break;
100
18.0k
    }
101
11.6k
    case PCPP_ETHERTYPE_MPLS:
102
11.6k
    {
103
11.6k
      tryConstructNextLayerWithFallback<MplsLayer, PayloadLayer>(payload, payloadLen);
104
11.6k
      break;
105
18.0k
    }
106
4.42k
    default:
107
4.42k
    {
108
4.42k
      if ((be16toh(hdr->etherType) < 1500))
109
3.54k
      {
110
3.54k
        tryConstructNextLayerWithFallback<LLCLayer, PayloadLayer>(payload, payloadLen);
111
3.54k
      }
112
877
      else
113
877
      {
114
877
        constructNextLayer<PayloadLayer>(payload, payloadLen);
115
877
      }
116
4.42k
      break;
117
18.0k
    }
118
73.8k
    }
119
73.8k
  }
120
121
  void VlanLayer::computeCalculateFields()
122
7.48k
  {
123
7.48k
    if (m_NextLayer == nullptr)
124
0
      return;
125
126
7.48k
    switch (m_NextLayer->getProtocol())
127
7.48k
    {
128
2.07k
    case IPv4:
129
2.07k
      getVlanHeader()->etherType = htobe16(PCPP_ETHERTYPE_IP);
130
2.07k
      break;
131
343
    case IPv6:
132
343
      getVlanHeader()->etherType = htobe16(PCPP_ETHERTYPE_IPV6);
133
343
      break;
134
1.05k
    case ARP:
135
1.05k
      getVlanHeader()->etherType = htobe16(PCPP_ETHERTYPE_ARP);
136
1.05k
      break;
137
936
    case VLAN:
138
936
      getVlanHeader()->etherType = htobe16(PCPP_ETHERTYPE_VLAN);
139
936
      break;
140
3.07k
    default:
141
3.07k
      return;
142
7.48k
    }
143
7.48k
  }
144
145
  std::string VlanLayer::toString() const
146
14.9k
  {
147
14.9k
    std::ostringstream cfiStream;
148
14.9k
    cfiStream << (int)getCFI();
149
14.9k
    std::ostringstream priStream;
150
14.9k
    priStream << (int)getPriority();
151
14.9k
    std::ostringstream idStream;
152
14.9k
    idStream << getVlanID();
153
154
14.9k
    return "VLAN Layer, Priority: " + priStream.str() + ", Vlan ID: " + idStream.str() +
155
14.9k
           ", CFI: " + cfiStream.str();
156
14.9k
  }
157
158
  const FieldDescriptor VlanLayer::SerializedFields::VlanID{ Layer::SerializedFields::MaxID + 1, "vlanID" };
159
  const FieldDescriptor VlanLayer::SerializedFields::CFI{ Layer::SerializedFields::MaxID + 2, "cfi" };
160
  const FieldDescriptor VlanLayer::SerializedFields::Priority{ Layer::SerializedFields::MaxID + 3, "priority" };
161
162
  const FieldDescriptor VlanLayer::SerializedFields::EtherType{ Layer::SerializedFields::MaxID + 4, "etherType" };
163
164
  void VlanLayer::serializeLayer(ObjectScope& serializer) const
165
0
  {
166
0
    serializer.writeField(SerializedFields::VlanID, getVlanID());
167
0
    serializer.writeField(SerializedFields::CFI, getCFI());
168
0
    serializer.writeField(SerializedFields::Priority, getPriority());
169
    serializer.writeField(SerializedFields::EtherType, be16toh(getVlanHeader()->etherType));
170
0
  }
171
}  // namespace pcpp