Coverage Report

Created: 2026-10-17 07:09

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/PcapPlusPlus/Packet++/header/MplsLayer.h
Line
Count
Source
1
#pragma once
2
3
#include "Layer.h"
4
5
/// @file
6
7
/// @namespace pcpp
8
/// @brief The main namespace for the PcapPlusPlus lib
9
namespace pcpp
10
{
11
  /// @class MplsLayer
12
  /// Represents a MPLS (Multi-Protocol Label Switching) layer
13
  class MplsLayer : public Layer
14
  {
15
  private:
16
#pragma pack(push, 1)
17
    struct mpls_header
18
    {
19
      uint16_t hiLabel;
20
      uint8_t misc;
21
      uint8_t ttl;
22
    };
23
#pragma pack(pop)
24
    static_assert(sizeof(mpls_header) == 4, "mpls_header size is not 4 bytes");
25
26
    mpls_header* getMplsHeader() const
27
404k
    {
28
404k
      return reinterpret_cast<mpls_header*>(m_Data);
29
404k
    }
30
31
  public:
32
    /// A constructor that creates the layer from an existing packet raw data
33
    /// @param[in] data A pointer to the raw data
34
    /// @param[in] dataLen Size of the data in bytes
35
    /// @param[in] prevLayer A pointer to the previous layer
36
    /// @param[in] packet A pointer to the Packet instance where layer will be stored in
37
    MplsLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet)
38
343k
        : Layer(data, dataLen, prevLayer, packet, MPLS)
39
343k
    {}
40
41
    /// A constructor that allocates a new MPLS header
42
    /// @param[in] mplsLabel MPLS label
43
    /// @param[in] ttl Time-to-leave value
44
    /// @param[in] experimentalUseValue Experimental use value
45
    /// @param[in] bottomOfStack Bottom-of-stack value which indicate whether the next layer will also be a MPLS
46
    /// label or not
47
    MplsLayer(uint32_t mplsLabel, uint8_t ttl, uint8_t experimentalUseValue, bool bottomOfStack);
48
49
    ~MplsLayer() override = default;
50
51
    /// @return TTL value of the MPLS header
52
    uint8_t getTTL() const
53
11.0k
    {
54
11.0k
      return getMplsHeader()->ttl;
55
11.0k
    }
56
57
    /// Set the TTL value
58
    /// @param[in] ttl The TTL value to set
59
    void setTTL(uint8_t ttl)
60
0
    {
61
0
      getMplsHeader()->ttl = ttl;
62
0
    }
63
64
    /// Get an indication whether the next layer is also be a MPLS label or not
65
    /// @return True if it's the last MPLS layer, false otherwise
66
    bool isBottomOfStack() const;
67
68
    /// Set the bottom-of-stack bit in the MPLS label
69
    /// @param[in] val Set or unset the bit
70
    void setBottomOfStack(bool val);
71
72
    /// @return The exp value (3 bits) of the MPLS label
73
    uint8_t getExperimentalUseValue() const;
74
75
    /// Set the exp value (3 bits) of the MPLS label
76
    /// @param[in] val The exp value to set. val must be a valid number meaning between 0 and 7 (inclusive)
77
    /// @return True if exp value was set successfully or false if val has invalid value
78
    bool setExperimentalUseValue(uint8_t val);
79
80
    /// @return The MPLS label value (20 bits)
81
    uint32_t getMplsLabel() const;
82
83
    /// Set the MPLS label (20 bits)
84
    /// @param[in] label The label to set. label must be a valid number meaning between 0 and 0xFFFFF (inclusive)
85
    /// @return True if label was set successfully or false if label has invalid value
86
    bool setMplsLabel(uint32_t label);
87
88
    // implement abstract methods
89
90
    /// Currently identifies the following next layers: IPv4Layer, IPv6Layer, MplsLayer. Otherwise sets PayloadLayer
91
    void parseNextLayer() override;
92
93
    /// @return Size of MPLS header (4 bytes)
94
    size_t getHeaderLen() const override
95
350k
    {
96
350k
      return sizeof(mpls_header);
97
350k
    }
98
99
    /// Set/unset the bottom-of-stack bit according to next layer: if it's a MPLS layer then bottom-of-stack will be
100
    /// unset. If it's not a MPLS layer this bit will be set
101
    void computeCalculateFields() override;
102
103
    std::string toString() const override;
104
105
    OsiModelLayer getOsiModelLayer() const override
106
5.52k
    {
107
5.52k
      return OsiModelNetworkLayer;
108
5.52k
    }
109
110
    /// A static method that validates the input data
111
    /// @param[in] data The pointer to the beginning of a byte stream of an MPLS layer
112
    /// @param[in] dataLen The length of the byte stream
113
    /// @return True if the data is valid and can represent an MPLS layer
114
    static bool isDataValid(const uint8_t* data, size_t dataLen)
115
343k
    {
116
343k
      return canReinterpretAs<mpls_header>(data, dataLen);
117
343k
    }
118
119
    /// @struct SerializedFields
120
    /// Fields written by MplsLayer's serializeLayer(), in addition to
121
    /// Layer::SerializedFields.
122
    struct SerializedFields : Layer::SerializedFields
123
    {
124
      /// @return All field descriptors for MplsLayer
125
      static std::vector<FieldDescriptor> all()
126
0
      {
127
0
        auto result = Layer::SerializedFields::all();
128
0
        std::initializer_list<FieldDescriptor> extra{ Label, TTL, IsBottomOfStack, ExperimentalUseValue };
129
0
        std::copy(extra.begin(), extra.end(), std::back_inserter(result));
130
0
        return result;
131
0
      }
132
133
      /// @brief MPLS label
134
      static const FieldDescriptor Label;
135
136
      /// @brief Time to live
137
      static const FieldDescriptor TTL;
138
139
      /// @brief True if this is the last label in the stack (S bit)
140
      static const FieldDescriptor IsBottomOfStack;
141
142
      /// @brief Experimental use / traffic class bits
143
      static const FieldDescriptor ExperimentalUseValue;
144
    };
145
146
  protected:
147
    void serializeLayer(ObjectScope& serializer) const override;
148
  };
149
150
}  // namespace pcpp