Coverage Report

Created: 2026-03-31 07:53

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/PcapPlusPlus/Packet++/src/MplsLayer.cpp
Line
Count
Source
1
0
#define LOG_MODULE PacketLogModuleMplsLayer
2
3
#include "MplsLayer.h"
4
#include "IPv4Layer.h"
5
#include "IPv6Layer.h"
6
#include "PayloadLayer.h"
7
#include "Logger.h"
8
#include <sstream>
9
#include "EndianPortable.h"
10
11
namespace pcpp
12
{
13
14
  MplsLayer::MplsLayer(uint32_t mplsLabel, uint8_t ttl, uint8_t experimentalUseValue, bool bottomOfStack)
15
0
  {
16
0
    const size_t headerLen = sizeof(mpls_header);
17
0
    m_DataLen = headerLen;
18
0
    m_Data = new uint8_t[headerLen];
19
0
    memset(m_Data, 0, headerLen);
20
0
    m_Protocol = MPLS;
21
22
0
    setMplsLabel(mplsLabel);
23
0
    setTTL(ttl);
24
0
    setExperimentalUseValue(experimentalUseValue);
25
0
    setBottomOfStack(bottomOfStack);
26
0
  }
27
28
  bool MplsLayer::isBottomOfStack() const
29
4.87k
  {
30
4.87k
    return (getMplsHeader()->misc & 0x01);
31
4.87k
  }
32
33
  void MplsLayer::setBottomOfStack(bool val)
34
439
  {
35
439
    if (!val)
36
308
      getMplsHeader()->misc &= 0xFE;
37
131
    else
38
131
      getMplsHeader()->misc |= 0x1;
39
439
  }
40
41
  uint8_t MplsLayer::getExperimentalUseValue() const
42
878
  {
43
878
    return ((getMplsHeader()->misc & 0x0E) >> 1);
44
878
  }
45
46
  bool MplsLayer::setExperimentalUseValue(uint8_t val)
47
0
  {
48
    // exp value is only 3 bits
49
0
    if (val > 7)
50
0
    {
51
0
      PCPP_LOG_ERROR("Set ExperimentalUse value got an illegal value: " << (int)val
52
0
                                                                        << ". Value must be lower than 8");
53
0
      return false;
54
0
    }
55
56
0
    mpls_header* hdr = getMplsHeader();
57
58
    // clear the 3 exp bits
59
0
    hdr->misc &= 0xF1;
60
61
    // move the 3 bits to their place
62
0
    val = val << 1;
63
64
0
    hdr->misc |= val;
65
66
0
    return true;
67
0
  }
68
69
  uint32_t MplsLayer::getMplsLabel() const
70
878
  {
71
878
    return (htobe16(getMplsHeader()->hiLabel) << 4) | ((getMplsHeader()->misc & 0xF0) >> 4);
72
878
  }
73
74
  bool MplsLayer::setMplsLabel(uint32_t label)
75
0
  {
76
0
    if (label > 0xFFFFF)
77
0
    {
78
0
      PCPP_LOG_ERROR(
79
0
          "MPLS label mustn't exceed 20 bits which is the value 0xffff. Got a parameter with the value 0x"
80
0
          << std::hex << label);
81
0
      return false;
82
0
    }
83
84
0
    mpls_header* hdr = getMplsHeader();
85
86
    // clear the 4 label bits in misc field
87
0
    hdr->misc &= 0x0F;
88
89
    // take the last nibble of the label value and move this nibble to its place in misc
90
0
    uint8_t miscVal = (label & 0x0F) << 4;
91
92
    // update misc field
93
0
    hdr->misc |= miscVal;
94
95
    // get rid of the nibble that went to misc
96
0
    label = label >> 4;
97
98
    // set the high 2 bytes of the label
99
0
    hdr->hiLabel = (uint16_t)htobe16(label);
100
101
0
    return true;
102
0
  }
103
104
  void MplsLayer::parseNextLayer()
105
3.99k
  {
106
3.99k
    size_t headerLen = getHeaderLen();
107
3.99k
    if (m_DataLen < headerLen + 1)
108
0
      return;
109
110
3.99k
    uint8_t* payload = m_Data + sizeof(mpls_header);
111
3.99k
    size_t payloadLen = m_DataLen - sizeof(mpls_header);
112
113
3.99k
    if (!isBottomOfStack())
114
2.87k
    {
115
2.87k
      constructNextLayer<MplsLayer>(payload, payloadLen);
116
2.87k
      return;
117
2.87k
    }
118
119
1.11k
    uint8_t nextNibble = (*((uint8_t*)(m_Data + headerLen)) & 0xF0) >> 4;
120
1.11k
    switch (nextNibble)
121
1.11k
    {
122
15
    case 4:
123
15
      tryConstructNextLayerWithFallback<IPv4Layer, PayloadLayer>(payload, payloadLen);
124
15
      break;
125
750
    case 6:
126
750
      tryConstructNextLayerWithFallback<IPv6Layer, PayloadLayer>(payload, payloadLen);
127
750
      break;
128
351
    default:
129
351
      constructNextLayer<PayloadLayer>(payload, payloadLen);
130
1.11k
    }
131
1.11k
  }
132
133
  void MplsLayer::computeCalculateFields()
134
439
  {
135
439
    Layer* nextLayer = getNextLayer();
136
439
    if (nextLayer != nullptr)
137
439
    {
138
439
      setBottomOfStack((nextLayer->getProtocol() != MPLS));
139
439
    }
140
439
  }
141
142
  std::string MplsLayer::toString() const
143
878
  {
144
878
    std::ostringstream labelStream;
145
878
    labelStream << getMplsLabel();
146
878
    std::ostringstream expStream;
147
878
    expStream << (int)getExperimentalUseValue();
148
878
    std::ostringstream ttlStream;
149
878
    ttlStream << (int)getTTL();
150
878
    std::string bottomOfStack = isBottomOfStack() ? "true" : "false";
151
152
878
    return "MPLS Layer, Label: " + labelStream.str() + ", Exp: " + expStream.str() + ", TTL: " + ttlStream.str() +
153
878
           ", Bottom of stack: " + bottomOfStack;
154
878
  }
155
156
}  // namespace pcpp