Coverage Report

Created: 2023-01-17 06:15

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