Coverage Report

Created: 2024-02-25 06:29

/src/PcapPlusPlus/Packet++/header/Layer.h
Line
Count
Source (jump to first uncovered line)
1
#pragma once
2
3
#include <stdint.h>
4
#include <stdio.h>
5
#include "ProtocolType.h"
6
#include <string>
7
8
/// @file
9
10
/**
11
 * \namespace pcpp
12
 * \brief The main namespace for the PcapPlusPlus lib
13
 */
14
namespace pcpp
15
{
16
17
  /**
18
   * @class IDataContainer
19
   * An interface (virtual abstract class) that indicates an object that holds a pointer to a buffer data. The Layer class is an example
20
   * of such object, hence it inherits this interface
21
   */
22
  class IDataContainer
23
  {
24
  public:
25
    /**
26
     * Get a pointer to the data
27
     * @param[in] offset Get a pointer in a certain offset. Default is 0 - get a pointer to start of data
28
     * @return A pointer to the data
29
     */
30
    virtual uint8_t* getDataPtr(size_t offset = 0) const = 0;
31
32
4.50M
    virtual ~IDataContainer() {}
33
  };
34
35
  class Packet;
36
37
  /**
38
   * @class Layer
39
   * Layer is the base class for all protocol layers. Each protocol supported in PcapPlusPlus has a class that inherits Layer.
40
   * The protocol layer class expose all properties and methods relevant for viewing and editing protocol fields.
41
   * For example: a pointer to a structured header (e.g tcphdr, iphdr, etc.), protocol header size, payload size, compute
42
   * fields that can be automatically computed, print protocol data to string, etc.
43
   * Each protocol instance is obviously part of a protocol stack (which construct a packet). This protocol stack is represented
44
   * in PcapPlusPlus in a linked list, and each layer is an element in this list. That's why each layer has properties to the next and previous
45
   * layer in the protocol stack
46
   * The Layer class, as a base class, is abstract and the user can't create an instance of it (it has a private constructor)
47
   * Each layer holds a pointer to the relevant place in the packet. The layer sees all the data from this pointer forward until the
48
   * end of the packet. Here is an example packet showing this concept:
49
   *
50
   @verbatim
51
   ====================================================
52
   |Eth       |IPv4       |TCP       |Packet          |
53
   |Header    |Header     |Header    |Payload         |
54
   ====================================================
55
56
   |--------------------------------------------------|
57
   EthLayer data
58
              |---------------------------------------|
59
              IPv4Layer data
60
                          |---------------------------|
61
                          TcpLayer data
62
                                     |----------------|
63
                                     PayloadLayer data
64
   @endverbatim
65
   *
66
  */
67
  class Layer : public IDataContainer
68
  {
69
    friend class Packet;
70
  public:
71
    /**
72
     * A destructor for this class. Frees the data if it was allocated by the layer constructor (see isAllocatedToPacket() for more info)
73
     */
74
    virtual ~Layer();
75
76
    /**
77
     * @return A pointer to the next layer in the protocol stack or NULL if the layer is the last one
78
     */
79
82.6M
    Layer* getNextLayer() const { return m_NextLayer; }
80
81
    /**
82
     * @return A pointer to the previous layer in the protocol stack or NULL if the layer is the first one
83
     */
84
2.32M
    Layer* getPrevLayer() const { return m_PrevLayer; }
85
86
    /**
87
     * @return The protocol enum
88
     */
89
61.9M
    ProtocolType getProtocol() const { return m_Protocol; }
90
91
    /**
92
     * Check if the layer's protocol matches a protocol family
93
     * @param protocolTypeFamily The protocol family to check
94
     * @return True if the layer's protocol matches the protocol family, false otherwise
95
     */
96
    bool isMemberOfProtocolFamily(ProtocolTypeFamily protocolTypeFamily) const;
97
98
    /**
99
     * @return A pointer to the layer raw data. In most cases it'll be a pointer to the first byte of the header
100
     */
101
285k
    uint8_t* getData() const { return m_Data; }
102
103
    /**
104
     * @return The length in bytes of the data from the first byte of the header until the end of the packet
105
     */
106
2.08M
    size_t getDataLen() const { return m_DataLen; }
107
108
    /**
109
     * @return A pointer for the layer payload, meaning the first byte after the header
110
     */
111
0
    uint8_t* getLayerPayload() const { return m_Data + getHeaderLen(); }
112
113
    /**
114
     * @return The size in bytes of the payload
115
     */
116
51.0k
    size_t getLayerPayloadSize() const { return m_DataLen - getHeaderLen(); }
117
118
    /**
119
     * Raw data in layers can come from one of sources:
120
     * 1. from an existing packet - this is the case when parsing packets received from files or the network. In this case the data was
121
     * already allocated by someone else, and layer only holds the pointer to the relevant place inside this data
122
     * 2. when creating packets, data is allocated when layer is created. In this case the layer is responsible for freeing it as well
123
     *
124
     * @return Returns true if the data was allocated by an external source (a packet) or false if it was allocated by the layer itself
125
     */
126
4.50M
    bool isAllocatedToPacket() const { return m_Packet != NULL; }
127
128
    /**
129
     * Copy the raw data of this layer to another array
130
     * @param[out] toArr The destination byte array
131
     */
132
    void copyData(uint8_t* toArr) const;
133
134
    // implement abstract methods
135
136
117k
    uint8_t* getDataPtr(size_t offset = 0) const { return (uint8_t*)(m_Data + offset); }
137
138
139
    // abstract methods
140
141
    /**
142
     * Each layer is responsible for parsing the next layer
143
     */
144
    virtual void parseNextLayer() = 0;
145
146
    /**
147
     * @return The header length in bytes
148
     */
149
    virtual size_t getHeaderLen() const = 0;
150
151
    /**
152
     * Each layer can compute field values automatically using this method. This is an abstract method
153
     */
154
    virtual void computeCalculateFields() = 0;
155
156
    /**
157
     * @return A string representation of the layer most important data (should look like the layer description in Wireshark)
158
     */
159
    virtual std::string toString() const = 0;
160
161
    /**
162
     * @return The OSI Model layer this protocol belongs to
163
     */
164
    virtual OsiModelLayer getOsiModelLayer() const = 0;
165
166
  protected:
167
    uint8_t* m_Data;
168
    size_t m_DataLen;
169
    Packet* m_Packet;
170
    ProtocolType m_Protocol;
171
    Layer* m_NextLayer;
172
    Layer* m_PrevLayer;
173
    bool m_IsAllocatedInPacket;
174
175
0
    Layer() : m_Data(NULL), m_DataLen(0), m_Packet(NULL), m_Protocol(UnknownProtocol), m_NextLayer(NULL), m_PrevLayer(NULL), m_IsAllocatedInPacket(false) { }
176
177
    Layer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) :
178
      m_Data(data), m_DataLen(dataLen),
179
      m_Packet(packet), m_Protocol(UnknownProtocol),
180
4.34M
      m_NextLayer(NULL), m_PrevLayer(prevLayer), m_IsAllocatedInPacket(false) {}
181
182
    // Copy c'tor
183
    Layer(const Layer& other);
184
    Layer& operator=(const Layer& other);
185
186
23.7k
    void setNextLayer(Layer* nextLayer) { m_NextLayer = nextLayer; }
187
0
    void setPrevLayer(Layer* prevLayer) { m_PrevLayer = prevLayer; }
188
189
    virtual bool extendLayer(int offsetInLayer, size_t numOfBytesToExtend);
190
    virtual bool shortenLayer(int offsetInLayer, size_t numOfBytesToShorten);
191
  };
192
193
} // namespace pcpp
194
195
inline std::ostream& operator<<(std::ostream& os, const pcpp::Layer &layer)
196
0
{
197
0
  os << layer.toString();
198
0
  return os;
199
0
}