1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
#ifndef PACKETPP_SLL2_LAYER
#define PACKETPP_SLL2_LAYER
#include "MacAddress.h"
#include "Layer.h"
/// @file
/**
* \namespace pcpp
* \brief The main namespace for the PcapPlusPlus lib
*/
namespace pcpp
{
/**
* @struct sll2_header
* Represents SLL2 header
*/
#pragma pack(push, 1)
struct sll2_header
{
/** Contains an Ethernet protocol type of the next layer */
uint16_t protocol_type;
/** The "Reserved (MBZ)" field is reserved, and must be set to zero */
uint16_t reserved;
/** The interface index field is a signed integer in network byte
* order and contains the 1-based index of the interface on which the packet was observed
**/
uint32_t interface_index;
/** Contains a Linux ARPHRD_ value for the link-layer device type */
uint16_t ARPHRD_type;
/** Specifies whether packet was: specifically sent to us by somebody else (value=0);
* broadcast by somebody else (value=1); multicast, but not broadcast, by somebody else (value=2);
* sent to somebody else by somebody else (value=3); sent by us (value=4)
**/
uint8_t packet_type;
/** Contains the length of the link-layer address of the sender of the packet. That length could be zero */
uint8_t link_layer_addr_len;
/** Contains the link-layer address of the sender of the packet; the number of bytes of that field that are
* meaningful is specified by the link-layer address length field
**/
uint8_t link_layer_addr[8];
};
#pragma pack(pop)
/**
* @class Sll2Layer
* Represents an SLL2 (Linux cooked capture) protocol layer
*/
class Sll2Layer : public Layer
{
public:
/**
* A constructor that creates the layer from an existing packet raw data
* @param[in] data A pointer to the raw data (will be casted to ether_header)
* @param[in] dataLen Size of the data in bytes
* @param[in] packet A pointer to the Packet instance where layer will be stored in
*/
Sll2Layer(uint8_t* data, size_t dataLen, Packet* packet) : Layer(data, dataLen, nullptr, packet) { m_Protocol = SLL2; }
/**
* A constructor that creates a new SLL2 header and allocates the data
* @param[in] interfaceIndex The interface index
* @param[in] ARPHRDType The ARPHRD type
* @param[in] packetType The packet type
*/
Sll2Layer(uint32_t interfaceIndex, uint16_t ARPHRDType, uint8_t packetType);
~Sll2Layer() {}
/**
* Get a pointer to the Sll header. Notice this points directly to the data, so every change will change the actual packet data
* @return A pointer to the sll2_header
*/
sll2_header* getSll2Header() const { return (sll2_header*)m_Data; }
/**
* A static method that validates the input data
* @param[in] data The pointer to the beginning of a byte stream of an IEEE 802.3 Eth packet
* @param[in] dataLen The length of the byte stream
* @return True if the data is valid and can represent an IEEE 802.3 Eth packet
*/
static bool isDataValid(const uint8_t* data, size_t dataLen);
/**
* Get a protocol type of this layer
* @return protocol type
*/
uint16_t getProtocolType() const;
/**
* Set protocol type of this layer
* @param[in] protocolType type to set
*/
void setProtocolType(uint16_t protocolType);
/**
* Get interface index of this layer
* @return interface index
*/
uint32_t getInterfaceIndex() const;
/**
* Set interface index of this layer
* @param[in] interfaceIndex interface index to set
*/
void setInterfaceIndex(uint32_t interfaceIndex);
/**
* Get arphrd type of this layer
* @return arphrd type
*/
uint16_t getArphrdType() const;
/**
* Set arphrd type of this layer
* @param[in] arphrdType arphrd type to set
*/
void setArphrdType(uint16_t arphrdType);
/**
* Get packet type of this layer
* @return packet type
*/
uint8_t getPacketType() const;
/**
* Set packet type of this layer
* @param[in] packetType packet type to set
*/
void setPacketType(uint8_t packetType);
/**
* Get link layer address length
* @return link layer address length
*/
uint8_t getLinkLayerAddrLen() const;
/**
* Get link layer address data pointer
* @return link layer address data pointer
*/
const uint8_t* getLinkLayerAddr() const;
/**
* A setter for the link layer address field
* @param[in] addr The address to set. Memory will be copied to packet
* @param[in] addrLength Address length, must be lower or equal to 8 (which is max length for SLL2 address)
* @return True if address was set successfully, or false of addrLength is out of bounds (0 or larger than 8)
*/
bool setLinkLayerAddr(const uint8_t* addr, size_t addrLength);
/**
* Get a MAC address in the link layer address field
* @return return macAddress pointer was set successfully, null pointer if d MAC address isn't valid or if set failed
*/
MacAddress getLinkLayerAsMacAddress();
/**
* Set a MAC address in the link layer address field
* @param[in] macAddr MAC address to set
* @return True if address was set successfully, false if MAC address isn't valid or if set failed
*/
bool setMacAddressAsLinkLayer(const MacAddress& macAddr);
// implement abstract methods
/**
* Currently identifies the following next layers: IPv4Layer, IPv6Layer, ArpLayer, VlanLayer, PPPoESessionLayer, PPPoEDiscoveryLayer,
* MplsLayer.
* Otherwise sets PayloadLayer
*/
void parseNextLayer();
/**
* Calculate the next protocol type for known protocols: IPv4, IPv6, ARP, VLAN
*/
void computeCalculateFields();
/**
* @return Size of sll2_header
*/
size_t getHeaderLen() const { return sizeof(sll2_header); }
std::string toString() const;
OsiModelLayer getOsiModelLayer() const { return OsiModelDataLinkLayer; }
};
} // namespace pcpp
#endif /* PACKETPP_SLL2_LAYER */