Coverage Report

Created: 2026-07-16 07:15

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