Coverage Report

Created: 2023-01-25 06:41

/src/PcapPlusPlus/Packet++/src/IPv6Extensions.cpp
Line
Count
Source (jump to first uncovered line)
1
#define LOG_MODULE PacketLogModuleIPv6ExtensionLayer
2
3
#include <sstream>
4
#include "EndianPortable.h"
5
#include "Logger.h"
6
#include "IPv6Extensions.h"
7
#include "IPv6Layer.h"
8
#include "IPv4Layer.h"
9
#include "PayloadLayer.h"
10
#include "UdpLayer.h"
11
#include "TcpLayer.h"
12
#include "GreLayer.h"
13
14
namespace pcpp
15
{
16
17
// =============
18
// IPv6Extension
19
// =============
20
21
IPv6Extension& IPv6Extension::operator=(const IPv6Extension& other)
22
0
{
23
  // notice this is not necessarily safe - it assumes the current extension has enough memory allocated to consume
24
  // the other extension. That's why the assignment operator isn't public (it's currently used only inside IPv6Layer)
25
0
  memcpy(getDataPtr(), other.getDataPtr(), other.getExtensionLen());
26
0
  m_NextHeader = NULL;
27
0
  m_ExtType = other.m_ExtType;
28
29
0
  return *this;
30
0
}
31
32
uint8_t* IPv6Extension::getDataPtr() const
33
28.5k
{
34
28.5k
  if (m_DataContainer != NULL)
35
28.5k
    return m_DataContainer->getDataPtr(m_Offset);
36
37
0
  return m_ShadowData;
38
28.5k
}
39
40
void IPv6Extension::initShadowPtr(size_t size)
41
0
{
42
0
  m_ShadowData = new uint8_t[size];
43
0
}
44
45
IPv6Extension::~IPv6Extension()
46
9.08k
{
47
9.08k
  if (m_ShadowData != NULL)
48
0
    delete [] m_ShadowData;
49
9.08k
}
50
51
// =======================
52
// IPv6FragmentationHeader
53
// =======================
54
55
IPv6FragmentationHeader::IPv6FragmentationHeader(uint32_t fragId, uint16_t fragOffset, bool lastFragment)
56
0
{
57
0
  initShadowPtr(sizeof(ipv6_frag_header));
58
0
  m_ExtType = IPv6Fragmentation;
59
0
  memset(getDataPtr(), 0, sizeof(ipv6_frag_header));
60
61
0
  ipv6_frag_header* fragHdr = getFragHeader();
62
0
  fragHdr->nextHeader = 0;
63
0
  fragHdr->headerLen = 0;
64
0
  fragHdr->id = htobe32(fragId);
65
66
0
  fragOffset /= 8;
67
0
  fragOffset = htobe16(fragOffset << 3) & (uint16_t)0xf8ff;
68
0
  if (!lastFragment)
69
0
    fragOffset = fragOffset | 0x0100;
70
71
0
  fragHdr->fragOffsetAndFlags = fragOffset;
72
0
}
73
74
bool IPv6FragmentationHeader::isFirstFragment() const
75
0
{
76
0
  return (getFragmentOffset() == 0);
77
0
}
78
79
bool IPv6FragmentationHeader::isLastFragment() const
80
0
{
81
0
  return (!isMoreFragments());
82
0
}
83
84
bool IPv6FragmentationHeader::isMoreFragments() const
85
0
{
86
0
  uint8_t isMoreFragsBit = (getFragHeader()->fragOffsetAndFlags & (uint16_t)0x0100) >> 8;
87
0
  return (isMoreFragsBit == 1);
88
0
}
89
90
uint16_t IPv6FragmentationHeader::getFragmentOffset() const
91
0
{
92
0
  uint16_t fragOffset = (be16toh(getFragHeader()->fragOffsetAndFlags & (uint16_t)0xf8ff) >> 3) * 8;
93
0
  return fragOffset;
94
0
}
95
96
// ====================
97
// IPv6TLVOptionBuilder
98
// ====================
99
100
IPv6TLVOptionHeader::IPv6Option IPv6TLVOptionHeader::IPv6TLVOptionBuilder::build() const
101
0
{
102
0
  size_t optionTotalSize = sizeof(uint8_t);
103
0
  uint8_t recType = static_cast<uint8_t>(m_RecType);
104
0
  if (recType != IPv6TLVOptionHeader::IPv6Option::Pad0OptionType)
105
0
    optionTotalSize += sizeof(uint8_t) + m_RecValueLen;
106
107
0
  uint8_t* recordBuffer = new uint8_t[optionTotalSize];
108
0
  memset(recordBuffer, 0, optionTotalSize);
109
110
0
  if (m_RecType != IPv6TLVOptionHeader::IPv6Option::Pad0OptionType)
111
0
  {
112
0
    recordBuffer[0] = recType;
113
0
    recordBuffer[1] = static_cast<uint8_t>(m_RecValueLen);
114
0
    if (m_RecValueLen > 0)
115
0
      memcpy(recordBuffer+2, m_RecValue, m_RecValueLen);
116
0
  }
117
118
0
  return IPv6Option(recordBuffer);
119
0
}
120
121
// ===================
122
// IPv6TLVOptionHeader
123
// ===================
124
125
IPv6TLVOptionHeader::IPv6Option IPv6TLVOptionHeader::getOption(uint8_t optionType) const
126
0
{
127
0
  return m_OptionReader.getTLVRecord(optionType, getDataPtr() + sizeof(ipv6_ext_base_header), getExtensionLen() - sizeof(ipv6_ext_base_header));
128
0
}
129
130
IPv6TLVOptionHeader::IPv6Option IPv6TLVOptionHeader::getFirstOption() const
131
0
{
132
0
  return m_OptionReader.getFirstTLVRecord(getDataPtr() + sizeof(ipv6_ext_base_header), getExtensionLen() - sizeof(ipv6_ext_base_header));
133
0
}
134
135
IPv6TLVOptionHeader::IPv6Option IPv6TLVOptionHeader::getNextOption(IPv6TLVOptionHeader::IPv6Option& option) const
136
0
{
137
0
  return m_OptionReader.getNextTLVRecord(option, getDataPtr() + sizeof(ipv6_ext_base_header), getExtensionLen() - sizeof(ipv6_ext_base_header));
138
0
}
139
140
size_t IPv6TLVOptionHeader::getOptionCount() const
141
0
{
142
0
  return m_OptionReader.getTLVRecordCount(getDataPtr() + sizeof(ipv6_ext_base_header), getExtensionLen() - sizeof(ipv6_ext_base_header));
143
0
}
144
145
IPv6TLVOptionHeader::IPv6TLVOptionHeader(const std::vector<IPv6TLVOptionBuilder>& options)
146
0
{
147
0
  m_ExtType = IPv6ExtensionUnknown;
148
0
  m_OptionReader.changeTLVRecordCount(options.size());
149
150
0
  size_t totalSize = sizeof(uint16_t); // nextHeader + headerLen
151
152
0
  for (std::vector<IPv6TLVOptionBuilder>::const_iterator iter = options.begin(); iter != options.end(); iter++)
153
0
  {
154
0
    IPv6Option option = iter->build();
155
0
    totalSize += option.getTotalSize();
156
0
    option.purgeRecordData();
157
0
  }
158
159
0
  while (totalSize % 8 != 0)
160
0
    totalSize++;
161
162
0
  initShadowPtr(totalSize);
163
0
  memset(getDataPtr(), 0, totalSize);
164
165
0
  getBaseHeader()->headerLen = ((totalSize / 8) - 1);
166
167
0
  size_t offset = sizeof(uint16_t);
168
169
0
  for (std::vector<IPv6TLVOptionBuilder>::const_iterator iter = options.begin(); iter != options.end(); iter++)
170
0
  {
171
0
    IPv6Option option = iter->build();
172
0
    memcpy(getDataPtr() + offset, option.getRecordBasePtr(), option.getTotalSize());
173
0
    offset += option.getTotalSize();
174
0
    option.purgeRecordData();
175
0
  }
176
0
}
177
178
IPv6TLVOptionHeader::IPv6TLVOptionHeader(IDataContainer* dataContainer, size_t offset) : IPv6Extension(dataContainer, offset)
179
6.59k
{
180
6.59k
}
181
182
// =================
183
// IPv6RoutingHeader
184
// =================
185
186
IPv6RoutingHeader::IPv6RoutingHeader(uint8_t routingType, uint8_t segmentsLeft, const uint8_t* additionalRoutingData, size_t additionalRoutingDataLen)
187
0
{
188
0
  size_t totalSize = sizeof(ipv6_routing_header) + additionalRoutingDataLen;
189
0
  while (totalSize % 8 != 0)
190
0
    totalSize++;
191
192
0
  initShadowPtr(totalSize);
193
0
  memset(getDataPtr(), 0, totalSize);
194
195
0
  m_ExtType = IPv6Routing;
196
197
0
  ipv6_routing_header* routingHeader = getRoutingHeader();
198
0
  routingHeader->nextHeader = 0;
199
0
  routingHeader->headerLen = ((totalSize / 8) - 1);
200
0
  routingHeader->routingType = routingType;
201
0
  routingHeader->segmentsLeft = segmentsLeft;
202
203
0
  if (additionalRoutingDataLen > 0 && additionalRoutingData != NULL)
204
0
  {
205
0
    uint8_t* additionalDataPtr = getDataPtr() + sizeof(ipv6_routing_header);
206
0
    memcpy(additionalDataPtr, additionalRoutingData, additionalRoutingDataLen);
207
0
  }
208
0
}
209
210
uint8_t* IPv6RoutingHeader::getRoutingAdditionalData() const
211
0
{
212
0
  if (getExtensionLen() > sizeof(ipv6_routing_header))
213
0
    return getDataPtr() + sizeof(ipv6_routing_header);
214
215
0
  return NULL;
216
0
}
217
218
size_t IPv6RoutingHeader::getRoutingAdditionalDataLength() const
219
0
{
220
0
  int result = getExtensionLen() - sizeof(ipv6_routing_header);
221
0
  if (result < 0)
222
0
    return (size_t)0;
223
224
0
  return (size_t)result;
225
0
}
226
227
IPv6Address IPv6RoutingHeader::getRoutingAdditionalDataAsIPv6Address(size_t offset) const
228
0
{
229
230
0
  size_t routingAddDataLen = getRoutingAdditionalDataLength();
231
0
  if (routingAddDataLen - offset >= 16)
232
0
    return IPv6Address(getRoutingAdditionalData() + offset);
233
234
0
  return IPv6Address();
235
0
}
236
237
238
// ========================
239
// IPv6AuthenticationHeader
240
// ========================
241
242
IPv6AuthenticationHeader::IPv6AuthenticationHeader(uint32_t securityParametersIndex, uint32_t sequenceNumber, const uint8_t* integrityCheckValue, size_t integrityCheckValueLen)
243
0
{
244
0
  size_t totalSize = sizeof(ipv6_authentication_header) + integrityCheckValueLen;
245
0
  while (totalSize % 8 != 0)
246
0
    totalSize++;
247
248
0
  initShadowPtr(totalSize);
249
0
  memset(getDataPtr(), 0, totalSize);
250
251
0
  m_ExtType = IPv6AuthenticationHdr;
252
253
0
  ipv6_authentication_header* authHeader = getAuthHeader();
254
0
  authHeader->nextHeader = 0;
255
0
  authHeader->headerLen = ((totalSize / 4) - 2);
256
0
  authHeader->securityParametersIndex = htobe32(securityParametersIndex);
257
0
  authHeader->sequenceNumber = htobe32(sequenceNumber);
258
259
0
  if (integrityCheckValueLen > 0 && integrityCheckValue != NULL)
260
0
  {
261
0
    uint8_t* icvPtr = getDataPtr() + sizeof(ipv6_authentication_header);
262
0
    memcpy(icvPtr, integrityCheckValue, integrityCheckValueLen);
263
0
  }
264
0
}
265
266
uint8_t* IPv6AuthenticationHeader::getIntegrityCheckValue() const
267
0
{
268
0
  if (getExtensionLen() > sizeof(ipv6_authentication_header))
269
0
    return getDataPtr() + sizeof(ipv6_authentication_header);
270
271
0
  return NULL;
272
0
}
273
274
size_t IPv6AuthenticationHeader::getIntegrityCheckValueLength() const
275
0
{
276
0
  int result = getExtensionLen() - sizeof(ipv6_authentication_header);
277
0
  if (result < 0)
278
0
    return (size_t)0;
279
280
0
  return (size_t)result;
281
0
}
282
283
}