Coverage Report

Created: 2026-06-30 07:06

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/PcapPlusPlus/Packet++/src/BgpLayer.cpp
Line
Count
Source
1
125k
#define LOG_MODULE PacketLogModuleBgpLayer
2
3
#include "Logger.h"
4
#include "BgpLayer.h"
5
#include "Packet.h"
6
#include "EndianPortable.h"
7
#include "GeneralUtils.h"
8
#include <algorithm>
9
10
namespace pcpp
11
{
12
  // ~~~~~~~~
13
  // BgpLayer
14
  // ~~~~~~~~
15
16
  size_t BgpLayer::getHeaderLen() const
17
1.48M
  {
18
1.48M
    if (m_DataLen < sizeof(bgp_common_header))
19
0
    {
20
0
      return m_DataLen;
21
0
    }
22
23
1.48M
    uint16_t messageLen = be16toh(getBasicHeader()->length);
24
1.48M
    if (m_DataLen < messageLen)
25
113k
    {
26
113k
      return m_DataLen;
27
113k
    }
28
29
1.37M
    return (size_t)messageLen;
30
1.48M
  }
31
32
  BgpLayer* BgpLayer::parseBgpLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet)
33
231k
  {
34
231k
    if (data == nullptr || dataLen < sizeof(bgp_common_header))
35
22.4k
      return nullptr;
36
37
208k
    auto* bgpHeader = reinterpret_cast<bgp_common_header*>(data);
38
39
    // illegal header data - length is too small
40
208k
    uint16_t messageLen = be16toh(bgpHeader->length);
41
208k
    if (dataLen < messageLen || messageLen < static_cast<uint16_t>(sizeof(bgp_common_header)))
42
11.0k
      return nullptr;
43
44
197k
    switch (bgpHeader->messageType)
45
197k
    {
46
28.2k
    case 1:  // OPEN
47
28.2k
      return BgpOpenMessageLayer::isDataValid(data, dataLen)
48
28.2k
                 ? new BgpOpenMessageLayer(data, dataLen, prevLayer, packet)
49
28.2k
                 : nullptr;
50
154k
    case 2:  // UPDATE
51
154k
      return BgpUpdateMessageLayer::isDataValid(data, dataLen)
52
154k
                 ? new BgpUpdateMessageLayer(data, dataLen, prevLayer, packet)
53
154k
                 : nullptr;
54
4.01k
    case 3:  // NOTIFICATION
55
4.01k
      return new BgpNotificationMessageLayer(data, dataLen, prevLayer, packet);
56
6.91k
    case 4:  // KEEPALIVE
57
6.91k
      return new BgpKeepaliveMessageLayer(data, dataLen, prevLayer, packet);
58
3.08k
    case 5:  // ROUTE-REFRESH
59
3.08k
      return new BgpRouteRefreshMessageLayer(data, dataLen, prevLayer, packet);
60
330
    default:
61
330
      return nullptr;
62
197k
    }
63
197k
  }
64
65
  std::string BgpLayer::getMessageTypeAsString() const
66
69.0k
  {
67
69.0k
    switch (getBgpMessageType())
68
69.0k
    {
69
12.1k
    case BgpLayer::Open:
70
12.1k
      return "OPEN";
71
48.9k
    case BgpLayer::Update:
72
48.9k
      return "UPDATE";
73
2.01k
    case BgpLayer::Notification:
74
2.01k
      return "NOTIFICATION";
75
4.08k
    case BgpLayer::Keepalive:
76
4.08k
      return "KEEPALIVE";
77
1.85k
    case BgpLayer::RouteRefresh:
78
1.85k
      return "ROUTE-REFRESH";
79
0
    default:
80
0
      return "Unknown";
81
69.0k
    }
82
69.0k
  }
83
84
  void BgpLayer::parseNextLayer()
85
194k
  {
86
194k
    size_t headerLen = getHeaderLen();
87
194k
    if (m_DataLen <= headerLen || headerLen == 0)
88
35.3k
      return;
89
90
159k
    uint8_t* payload = m_Data + headerLen;
91
159k
    size_t payloadLen = m_DataLen - headerLen;
92
93
159k
    constructNextLayerFromFactory(BgpLayer::parseBgpLayer, payload, payloadLen);
94
159k
  }
95
96
  std::string BgpLayer::toString() const
97
46.0k
  {
98
46.0k
    return "BGP Layer, " + getMessageTypeAsString() + " message";
99
46.0k
  }
100
101
  void BgpLayer::computeCalculateFields()
102
23.0k
  {
103
23.0k
    bgp_common_header* bgpHeader = getBasicHeader();
104
23.0k
    memset(bgpHeader->marker, 0xff, 16 * sizeof(uint8_t));
105
23.0k
    bgpHeader->messageType = (uint8_t)getBgpMessageType();
106
23.0k
    bgpHeader->length = htobe16(getHeaderLen());
107
23.0k
  }
108
109
  void BgpLayer::setBgpFields(size_t messageLen)
110
0
  {
111
0
    bgp_common_header* bgpHdr = getBasicHeader();
112
0
    memset(bgpHdr->marker, 0xff, 16 * sizeof(uint8_t));
113
0
    bgpHdr->messageType = (uint8_t)getBgpMessageType();
114
0
    if (messageLen != 0)
115
0
    {
116
0
      bgpHdr->length = htobe16((uint16_t)messageLen);
117
0
    }
118
0
    else
119
0
    {
120
0
      bgpHdr->length = m_DataLen;
121
0
    }
122
0
  }
123
124
  bool BgpLayer::extendLayer(int offsetInLayer, size_t numOfBytesToExtend)
125
56.0k
  {
126
56.0k
    if (getAttachedPacket() != nullptr)
127
56.0k
    {
128
56.0k
      int rawPacketLen = getAttachedPacket()->getRawPacket()->getRawDataLen();
129
56.0k
      const uint8_t* rawPacketPtr = getAttachedPacket()->getRawPacket()->getRawData();
130
131
56.0k
      if (m_Data - rawPacketPtr + static_cast<ptrdiff_t>(offsetInLayer) > static_cast<ptrdiff_t>(rawPacketLen))
132
4.43k
      {
133
4.43k
        PCPP_LOG_ERROR("Requested offset is larger than total packet length");
134
4.43k
        return false;
135
4.43k
      }
136
137
51.6k
      if (m_NextLayer != nullptr && static_cast<ptrdiff_t>(offsetInLayer) > m_NextLayer->getData() - m_Data)
138
4.61k
      {
139
4.61k
        PCPP_LOG_ERROR("Requested offset exceeds current layer's boundary");
140
4.61k
        return false;
141
4.61k
      }
142
51.6k
    }
143
144
47.0k
    return Layer::extendLayer(offsetInLayer, numOfBytesToExtend);
145
56.0k
  }
146
147
  bool BgpLayer::shortenLayer(int offsetInLayer, size_t numOfBytesToShorten)
148
59.4k
  {
149
59.4k
    if (getAttachedPacket() != nullptr)
150
59.4k
    {
151
59.4k
      int rawPacketLen = getAttachedPacket()->getRawPacket()->getRawDataLen();
152
59.4k
      const uint8_t* rawPacketPtr = getAttachedPacket()->getRawPacket()->getRawData();
153
154
59.4k
      if (m_Data - rawPacketPtr + static_cast<ptrdiff_t>(offsetInLayer) +
155
59.4k
              static_cast<ptrdiff_t>(numOfBytesToShorten) >
156
59.4k
          static_cast<ptrdiff_t>(rawPacketLen))
157
5.32k
      {
158
5.32k
        PCPP_LOG_ERROR("Requested number of bytes to shorten is larger than total packet length");
159
5.32k
        return false;
160
5.32k
      }
161
162
54.1k
      if (m_NextLayer != nullptr &&
163
42.5k
          static_cast<ptrdiff_t>(offsetInLayer) + static_cast<ptrdiff_t>(numOfBytesToShorten) >
164
42.5k
              m_NextLayer->getData() - m_Data)
165
1.82k
      {
166
1.82k
        PCPP_LOG_ERROR("Requested number of bytes to shorten exceeds current layer's boundary");
167
1.82k
        return false;
168
1.82k
      }
169
54.1k
    }
170
171
52.3k
    return Layer::shortenLayer(offsetInLayer, numOfBytesToShorten);
172
59.4k
  }
173
174
  // ~~~~~~~~~~~~~~~~~~~~
175
  // BgpOpenMessageLayer
176
  // ~~~~~~~~~~~~~~~~~~~~
177
178
  BgpOpenMessageLayer::optional_parameter::optional_parameter(uint8_t typeVal, const std::string& valueAsHexString)
179
20.1k
  {
180
20.1k
    type = typeVal;
181
20.1k
    length = hexStringToByteArray(valueAsHexString, value, 32);
182
20.1k
  }
183
184
  bool BgpOpenMessageLayer::isDataValid(const uint8_t* data, size_t dataSize)
185
28.2k
  {
186
28.2k
    if (data == nullptr || dataSize < sizeof(bgp_common_header))
187
0
    {
188
0
      return false;
189
0
    }
190
191
28.2k
    const auto* bgpHeader = reinterpret_cast<const bgp_common_header*>(data);
192
28.2k
    uint16_t messageLen = be16toh(bgpHeader->length);
193
28.2k
    return messageLen >= sizeof(bgp_open_message) && dataSize >= messageLen;
194
28.2k
  }
195
196
  BgpOpenMessageLayer::BgpOpenMessageLayer(uint16_t myAutonomousSystem, uint16_t holdTime, const IPv4Address& bgpId,
197
                                           const std::vector<optional_parameter>& optionalParams)
198
0
  {
199
0
    uint8_t optionalParamsData[1500];
200
0
    size_t optionalParamsDataLen = optionalParamsToByteArray(optionalParams, optionalParamsData, 1500);
201
202
0
    const size_t headerLen = sizeof(bgp_open_message) + optionalParamsDataLen;
203
0
    m_DataLen = headerLen;
204
0
    m_Data = new uint8_t[headerLen];
205
0
    memset(m_Data, 0, headerLen);
206
0
    setBgpFields(headerLen);
207
208
0
    bgp_open_message* msgHdr = getOpenMsgHeader();
209
0
    msgHdr->version = 4;
210
0
    msgHdr->myAutonomousSystem = htobe16(myAutonomousSystem);
211
0
    msgHdr->holdTime = htobe16(holdTime);
212
0
    msgHdr->bgpId = bgpId.toInt();
213
0
    msgHdr->optionalParameterLength = optionalParamsDataLen;
214
0
    if (optionalParamsDataLen > 0)
215
0
    {
216
0
      memcpy(m_Data + sizeof(bgp_open_message), optionalParamsData, optionalParamsDataLen);
217
0
    }
218
219
0
    m_Protocol = BGP;
220
0
  }
221
222
  size_t BgpOpenMessageLayer::optionalParamsToByteArray(const std::vector<optional_parameter>& optionalParams,
223
                                                        uint8_t* resultByteArr, size_t maxByteArrSize)
224
12.1k
  {
225
12.1k
    if (resultByteArr == nullptr || maxByteArrSize == 0)
226
0
    {
227
0
      return 0;
228
0
    }
229
230
12.1k
    size_t dataLen = 0;
231
232
12.1k
    for (const auto& param : optionalParams)
233
47.2k
    {
234
47.2k
      if (param.length > 32)
235
0
      {
236
0
        PCPP_LOG_ERROR("Illegal optional parameter length " << (int)param.length
237
0
                                                            << ", must be 32 bytes or less");
238
0
        break;  // illegal value
239
0
      }
240
241
47.2k
      size_t curDataSize = 2 * sizeof(uint8_t) + (size_t)param.length;
242
243
47.2k
      if (dataLen + curDataSize > maxByteArrSize)
244
0
      {
245
0
        break;
246
0
      }
247
248
47.2k
      resultByteArr[0] = param.type;
249
47.2k
      resultByteArr[1] = param.length;
250
47.2k
      if (param.length > 0)
251
40.0k
      {
252
40.0k
        memcpy(resultByteArr + 2 * sizeof(uint8_t), param.value, param.length);
253
40.0k
      }
254
255
47.2k
      dataLen += curDataSize;
256
47.2k
      resultByteArr += curDataSize;
257
47.2k
    }
258
259
12.1k
    return dataLen;
260
12.1k
  }
261
262
  void BgpOpenMessageLayer::setBgpId(const IPv4Address& newBgpId)
263
0
  {
264
0
    bgp_open_message* msgHdr = getOpenMsgHeader();
265
0
    if (msgHdr == nullptr)
266
0
    {
267
0
      return;
268
0
    }
269
270
0
    msgHdr->bgpId = newBgpId.toInt();
271
0
  }
272
273
  void BgpOpenMessageLayer::getOptionalParameters(std::vector<optional_parameter>& optionalParameters)
274
4.03k
  {
275
4.03k
    size_t headerLen = getHeaderLen();
276
4.03k
    bgp_open_message* msgHdr = getOpenMsgHeader();
277
278
    // Parentheses around std::min avoid clashes with platform min macros (for example on Windows)
279
4.03k
    size_t optionalParamsLen =
280
4.03k
        (std::min)(static_cast<size_t>(msgHdr->optionalParameterLength), headerLen - sizeof(bgp_open_message));
281
282
4.03k
    uint8_t* dataPtr = m_Data + sizeof(bgp_open_message);
283
4.03k
    size_t byteCount = 0;
284
17.5k
    while (byteCount < optionalParamsLen)
285
16.8k
    {
286
16.8k
      size_t remaining = optionalParamsLen - byteCount;
287
16.8k
      constexpr size_t optParamHdrSize = sizeof(optional_parameter::type) + sizeof(optional_parameter::length);
288
16.8k
      if (remaining < optParamHdrSize)
289
586
      {
290
586
        PCPP_LOG_ERROR("Truncated optional parameter header");
291
586
        break;
292
586
      }
293
294
16.2k
      optional_parameter op;
295
16.2k
      op.type = dataPtr[0];
296
16.2k
      op.length = dataPtr[1];
297
298
16.2k
      size_t totalLen = optParamHdrSize + static_cast<size_t>(op.length);
299
16.2k
      if (totalLen > remaining)
300
2.66k
      {
301
2.66k
        PCPP_LOG_ERROR("Optional parameter length is out of bounds: " << static_cast<int>(op.length));
302
2.66k
        break;
303
2.66k
      }
304
305
13.5k
      if (op.length > 0)
306
9.93k
      {
307
9.93k
        memcpy(op.value, dataPtr + optParamHdrSize,
308
9.93k
               (std::min)(static_cast<size_t>(op.length), sizeof(op.value)));
309
9.93k
      }
310
311
13.5k
      optionalParameters.push_back(op);
312
313
13.5k
      byteCount += totalLen;
314
13.5k
      dataPtr += totalLen;
315
13.5k
    }
316
4.03k
  }
317
318
  size_t BgpOpenMessageLayer::getOptionalParametersLength()
319
12.1k
  {
320
12.1k
    size_t headerLen = getHeaderLen();
321
12.1k
    bgp_open_message* msgHdr = getOpenMsgHeader();
322
12.1k
    auto optParamLen = static_cast<size_t>(msgHdr->optionalParameterLength);
323
324
12.1k
    constexpr size_t bgpOpenMsgHeaderSize = sizeof(bgp_open_message);
325
12.1k
    if (headerLen < optParamLen + bgpOpenMsgHeaderSize)
326
1.35k
    {
327
1.35k
      PCPP_LOG_WARN("BGP Layer optional param length exceeds total BGP message. "
328
1.35k
                    "This packet might be malformed! Trimming to maximum allowed by BGP message length.");
329
1.35k
      optParamLen = headerLen >= bgpOpenMsgHeaderSize ? headerLen - bgpOpenMsgHeaderSize : 0;
330
1.35k
    }
331
332
12.1k
    return optParamLen;
333
12.1k
  }
334
335
  bool BgpOpenMessageLayer::setOptionalParameters(const std::vector<optional_parameter>& optionalParameters)
336
12.1k
  {
337
12.1k
    uint8_t newOptionalParamsData[1500];
338
12.1k
    size_t newOptionalParamsDataLen = optionalParamsToByteArray(optionalParameters, newOptionalParamsData, 1500);
339
12.1k
    size_t curOptionalParamsDataLen = getOptionalParametersLength();
340
12.1k
    constexpr int offsetInLayer = sizeof(bgp_open_message);
341
342
12.1k
    if (newOptionalParamsDataLen > curOptionalParamsDataLen)
343
3.90k
    {
344
3.90k
      size_t numOfBytesToExtend = newOptionalParamsDataLen - curOptionalParamsDataLen;
345
346
3.90k
      if (!extendLayer(offsetInLayer, numOfBytesToExtend))
347
79
      {
348
79
        PCPP_LOG_ERROR("Couldn't extend BGP open layer to include the additional optional parameters");
349
79
        return false;
350
79
      }
351
3.90k
    }
352
8.19k
    else if (newOptionalParamsDataLen < curOptionalParamsDataLen)
353
6.28k
    {
354
6.28k
      size_t numOfBytesToShorten = curOptionalParamsDataLen - newOptionalParamsDataLen;
355
356
6.28k
      if (!shortenLayer(offsetInLayer, numOfBytesToShorten))
357
1.01k
      {
358
1.01k
        PCPP_LOG_ERROR("Couldn't shorten BGP open layer to set the right size of the optional parameters data");
359
1.01k
        return false;
360
1.01k
      }
361
6.28k
    }
362
363
11.0k
    if (newOptionalParamsDataLen > 0)
364
5.60k
    {
365
5.60k
      memcpy(m_Data + offsetInLayer, newOptionalParamsData, newOptionalParamsDataLen);
366
5.60k
    }
367
368
11.0k
    getOpenMsgHeader()->optionalParameterLength = static_cast<uint8_t>(newOptionalParamsDataLen);
369
11.0k
    getOpenMsgHeader()->length = htobe16(sizeof(bgp_open_message) + newOptionalParamsDataLen);
370
371
11.0k
    return true;
372
12.1k
  }
373
374
  bool BgpOpenMessageLayer::clearOptionalParameters()
375
4.03k
  {
376
4.03k
    return setOptionalParameters(std::vector<optional_parameter>());
377
4.03k
  }
378
379
  // ~~~~~~~~~~~~~~~~~~~~~
380
  // BgpUpdateMessageLayer
381
  // ~~~~~~~~~~~~~~~~~~~~~
382
383
  BgpUpdateMessageLayer::path_attribute::path_attribute(uint8_t flagsVal, uint8_t typeVal,
384
                                                        const std::string& dataAsHexString)
385
48.9k
  {
386
48.9k
    flags = flagsVal;
387
48.9k
    type = typeVal;
388
48.9k
    length = hexStringToByteArray(dataAsHexString, data, 32);
389
48.9k
  }
390
391
  BgpUpdateMessageLayer::BgpUpdateMessageLayer(const std::vector<prefix_and_ip>& withdrawnRoutes,
392
                                               const std::vector<path_attribute>& pathAttributes,
393
                                               const std::vector<prefix_and_ip>& nlri)
394
0
  {
395
0
    uint8_t withdrawnRoutesData[1500];
396
0
    uint8_t pathAttributesData[1500];
397
0
    uint8_t nlriData[1500];
398
0
    size_t withdrawnRoutesDataLen = prefixAndIPDataToByteArray(withdrawnRoutes, withdrawnRoutesData, 1500);
399
0
    size_t pathAttributesDataLen = pathAttributesToByteArray(pathAttributes, pathAttributesData, 1500);
400
0
    size_t nlriDataLen = prefixAndIPDataToByteArray(nlri, nlriData, 1500);
401
402
0
    size_t headerLen = sizeof(bgp_common_header) + 2 * sizeof(uint16_t) + withdrawnRoutesDataLen +
403
0
                       pathAttributesDataLen + nlriDataLen;
404
0
    m_DataLen = headerLen;
405
0
    m_Data = new uint8_t[headerLen];
406
0
    memset(m_Data, 0, headerLen);
407
0
    setBgpFields(headerLen);
408
409
0
    uint8_t* dataPtr = m_Data + sizeof(bgp_common_header);
410
411
    // copy withdrawn routes data
412
0
    uint16_t withdrawnRoutesDataLenBE = htobe16(withdrawnRoutesDataLen);
413
0
    memcpy(dataPtr, &withdrawnRoutesDataLenBE, sizeof(uint16_t));
414
0
    dataPtr += sizeof(uint16_t);
415
0
    if (withdrawnRoutesDataLen > 0)
416
0
    {
417
0
      memcpy(dataPtr, withdrawnRoutesData, withdrawnRoutesDataLen);
418
0
      dataPtr += withdrawnRoutesDataLen;
419
0
    }
420
421
    // copy path attributes data
422
0
    uint16_t pathAttributesDataLenBE = htobe16(pathAttributesDataLen);
423
0
    memcpy(dataPtr, &pathAttributesDataLenBE, sizeof(uint16_t));
424
0
    dataPtr += sizeof(uint16_t);
425
0
    if (pathAttributesDataLen > 0)
426
0
    {
427
0
      memcpy(dataPtr, pathAttributesData, pathAttributesDataLen);
428
0
      dataPtr += pathAttributesDataLen;
429
0
    }
430
431
    // copy nlri data
432
0
    if (nlriDataLen > 0)
433
0
    {
434
0
      memcpy(dataPtr, nlriData, nlriDataLen);
435
0
    }
436
437
0
    m_Protocol = BGP;
438
0
  }
439
440
  void BgpUpdateMessageLayer::parsePrefixAndIPData(uint8_t* dataPtr, size_t dataLen,
441
                                                   std::vector<prefix_and_ip>& result)
442
12.3k
  {
443
12.3k
    size_t byteCount = 0;
444
25.0k
    while (byteCount < dataLen)
445
18.0k
    {
446
18.0k
      prefix_and_ip wr;
447
18.0k
      wr.prefix = dataPtr[0];
448
18.0k
      size_t curByteCount = 1;
449
18.0k
      if (wr.prefix == 32)
450
6.96k
      {
451
6.96k
        uint8_t octets[4] = { dataPtr[1], dataPtr[2], dataPtr[3], dataPtr[4] };
452
6.96k
        wr.ipAddr = IPv4Address(octets);
453
6.96k
        curByteCount += 4;
454
6.96k
      }
455
11.0k
      else if (wr.prefix == 24)
456
5.32k
      {
457
5.32k
        uint8_t octets[4] = { dataPtr[1], dataPtr[2], dataPtr[3], 0 };
458
5.32k
        wr.ipAddr = IPv4Address(octets);
459
5.32k
        curByteCount += 3;
460
5.32k
      }
461
5.73k
      else if (wr.prefix == 16)
462
22
      {
463
22
        uint8_t octets[4] = { dataPtr[1], dataPtr[2], 0, 0 };
464
22
        wr.ipAddr = IPv4Address(octets);
465
22
        curByteCount += 2;
466
22
      }
467
5.71k
      else if (wr.prefix == 8)
468
458
      {
469
458
        uint8_t octets[4] = { dataPtr[1], 0, 0, 0 };
470
458
        wr.ipAddr = IPv4Address(octets);
471
458
        curByteCount += 1;
472
458
      }
473
5.25k
      else
474
5.25k
      {
475
5.25k
        PCPP_LOG_DEBUG("Illegal prefix value " << (int)wr.prefix);
476
5.25k
        break;  // illegal value
477
5.25k
      }
478
479
12.7k
      result.push_back(wr);
480
12.7k
      dataPtr += curByteCount;
481
12.7k
      byteCount += curByteCount;
482
12.7k
    }
483
12.3k
  }
484
485
  size_t BgpUpdateMessageLayer::prefixAndIPDataToByteArray(const std::vector<prefix_and_ip>& prefixAndIpData,
486
                                                           uint8_t* resultByteArr, size_t maxByteArrSize)
487
97.9k
  {
488
97.9k
    if (resultByteArr == nullptr || maxByteArrSize == 0)
489
0
    {
490
0
      return 0;
491
0
    }
492
493
97.9k
    size_t dataLen = 0;
494
495
97.9k
    for (const auto& prefixAndIp : prefixAndIpData)
496
107k
    {
497
107k
      uint8_t curData[5];
498
107k
      curData[0] = prefixAndIp.prefix;
499
107k
      size_t curDataSize = 1;
500
107k
      const uint8_t* octets = prefixAndIp.ipAddr.toBytes();
501
107k
      if (prefixAndIp.prefix == 32)
502
13.9k
      {
503
13.9k
        curDataSize += 4;
504
13.9k
        curData[1] = octets[0];
505
13.9k
        curData[2] = octets[1];
506
13.9k
        curData[3] = octets[2];
507
13.9k
        curData[4] = octets[3];
508
13.9k
      }
509
93.2k
      else if (prefixAndIp.prefix == 24)
510
75.9k
      {
511
75.9k
        curDataSize += 3;
512
75.9k
        curData[1] = octets[0];
513
75.9k
        curData[2] = octets[1];
514
75.9k
        curData[3] = octets[2];
515
75.9k
      }
516
17.2k
      else if (prefixAndIp.prefix == 16)
517
16.3k
      {
518
16.3k
        curDataSize += 2;
519
16.3k
        curData[1] = octets[0];
520
16.3k
        curData[2] = octets[1];
521
16.3k
      }
522
916
      else if (prefixAndIp.prefix == 8)
523
916
      {
524
916
        curDataSize += 1;
525
916
        curData[1] = octets[0];
526
916
      }
527
0
      else
528
0
      {
529
0
        PCPP_LOG_ERROR("Illegal prefix value " << (int)prefixAndIp.prefix);
530
0
        break;  // illegal value
531
0
      }
532
533
107k
      if (dataLen + curDataSize > maxByteArrSize)
534
0
      {
535
0
        break;
536
0
      }
537
538
107k
      dataLen += curDataSize;
539
540
107k
      memcpy(resultByteArr, curData, curDataSize);
541
107k
      resultByteArr += curDataSize;
542
107k
    }
543
544
97.9k
    return dataLen;
545
97.9k
  }
546
547
  size_t BgpUpdateMessageLayer::pathAttributesToByteArray(const std::vector<path_attribute>& pathAttributes,
548
                                                          uint8_t* resultByteArr, size_t maxByteArrSize)
549
48.9k
  {
550
48.9k
    if (resultByteArr == nullptr || maxByteArrSize == 0)
551
0
    {
552
0
      return 0;
553
0
    }
554
555
48.9k
    size_t dataLen = 0;
556
557
48.9k
    for (const auto& attribute : pathAttributes)
558
104k
    {
559
104k
      if (attribute.length > 32)
560
20.4k
      {
561
20.4k
        PCPP_LOG_ERROR("Illegal path attribute length " << (int)attribute.length);
562
20.4k
        break;  // illegal value
563
20.4k
      }
564
565
83.5k
      size_t curDataSize = 3 * sizeof(uint8_t) + (size_t)attribute.length;
566
567
83.5k
      if (dataLen + curDataSize > maxByteArrSize)
568
0
      {
569
0
        break;
570
0
      }
571
572
83.5k
      resultByteArr[0] = attribute.flags;
573
83.5k
      resultByteArr[1] = attribute.type;
574
83.5k
      resultByteArr[2] = attribute.length;
575
83.5k
      if (attribute.length > 0)
576
61.9k
      {
577
61.9k
        memcpy(resultByteArr + 3 * sizeof(uint8_t), attribute.data, attribute.length);
578
61.9k
      }
579
580
83.5k
      dataLen += curDataSize;
581
83.5k
      resultByteArr += curDataSize;
582
83.5k
    }
583
584
48.9k
    return dataLen;
585
48.9k
  }
586
587
  size_t BgpUpdateMessageLayer::getWithdrawnRoutesLength() const
588
408k
  {
589
408k
    size_t headerLen = getHeaderLen();
590
408k
    size_t minLen = sizeof(bgp_common_header) + sizeof(uint16_t);
591
408k
    if (headerLen >= minLen)
592
393k
    {
593
393k
      uint16_t res = be16toh(*(uint16_t*)(m_Data + sizeof(bgp_common_header)));
594
393k
      if ((size_t)res > headerLen - minLen)
595
48.4k
      {
596
48.4k
        return headerLen - minLen;
597
48.4k
      }
598
599
344k
      return (size_t)res;
600
393k
    }
601
602
15.0k
    return 0;
603
408k
  }
604
605
  void BgpUpdateMessageLayer::getWithdrawnRoutes(std::vector<prefix_and_ip>& withdrawnRoutes)
606
16.3k
  {
607
16.3k
    size_t withdrawnRouteLen = getWithdrawnRoutesLength();
608
16.3k
    if (withdrawnRouteLen == 0)
609
13.3k
    {
610
13.3k
      return;
611
13.3k
    }
612
613
2.94k
    uint8_t* dataPtr = m_Data + sizeof(bgp_common_header) + sizeof(uint16_t);
614
2.94k
    parsePrefixAndIPData(dataPtr, withdrawnRouteLen, withdrawnRoutes);
615
2.94k
  }
616
617
  size_t BgpUpdateMessageLayer::getPathAttributesLength() const
618
180k
  {
619
180k
    size_t headerLen = getHeaderLen();
620
180k
    size_t minLen = sizeof(bgp_common_header) + 2 * sizeof(uint16_t);
621
180k
    if (headerLen >= minLen)
622
167k
    {
623
167k
      size_t withdrawnRouteLen = getWithdrawnRoutesLength();
624
      // Ensure the memory access is within bounds
625
167k
      if (sizeof(bgp_common_header) + sizeof(uint16_t) + withdrawnRouteLen + sizeof(uint16_t) > headerLen)
626
21.8k
      {
627
21.8k
        return 0;  // Invalid access, return 0
628
21.8k
      }
629
145k
      uint16_t res =
630
145k
          be16toh(*(uint16_t*)(m_Data + sizeof(bgp_common_header) + sizeof(uint16_t) + withdrawnRouteLen));
631
145k
      if ((size_t)res > headerLen - minLen - withdrawnRouteLen)
632
14.3k
      {
633
14.3k
        return headerLen - minLen - withdrawnRouteLen;
634
14.3k
      }
635
636
131k
      return (size_t)res;
637
145k
    }
638
639
13.4k
    return 0;
640
180k
  }
641
642
  bool BgpUpdateMessageLayer::setWithdrawnRoutes(const std::vector<prefix_and_ip>& withdrawnRoutes)
643
48.9k
  {
644
48.9k
    uint8_t newWithdrawnRoutesData[1500];
645
48.9k
    size_t newWithdrawnRoutesDataLen = prefixAndIPDataToByteArray(withdrawnRoutes, newWithdrawnRoutesData, 1500);
646
48.9k
    size_t curWithdrawnRoutesDataLen = getWithdrawnRoutesLength();
647
48.9k
    int offsetInLayer = sizeof(bgp_common_header) + sizeof(uint16_t);
648
649
48.9k
    if (newWithdrawnRoutesDataLen > curWithdrawnRoutesDataLen)
650
14.6k
    {
651
14.6k
      size_t numOfBytesToExtend = newWithdrawnRoutesDataLen - curWithdrawnRoutesDataLen;
652
653
14.6k
      if (!extendLayer(offsetInLayer, numOfBytesToExtend))
654
2.58k
      {
655
2.58k
        PCPP_LOG_ERROR("Couldn't extend BGP update layer to include the additional withdrawn routes");
656
2.58k
        return false;
657
2.58k
      }
658
14.6k
    }
659
34.2k
    else if (newWithdrawnRoutesDataLen < curWithdrawnRoutesDataLen)
660
18.0k
    {
661
18.0k
      size_t numOfBytesToShorten = curWithdrawnRoutesDataLen - newWithdrawnRoutesDataLen;
662
663
18.0k
      if (!shortenLayer(offsetInLayer, numOfBytesToShorten))
664
5.41k
      {
665
5.41k
        PCPP_LOG_ERROR("Couldn't shorten BGP update layer to set the right size of the withdrawn routes data");
666
5.41k
        return false;
667
5.41k
      }
668
18.0k
    }
669
670
40.9k
    if (newWithdrawnRoutesDataLen > 0)
671
12.5k
    {
672
12.5k
      memcpy(m_Data + offsetInLayer, newWithdrawnRoutesData, newWithdrawnRoutesDataLen);
673
12.5k
    }
674
675
40.9k
    getBasicHeader()->length =
676
40.9k
        htobe16(be16toh(getBasicHeader()->length) + newWithdrawnRoutesDataLen - curWithdrawnRoutesDataLen);
677
678
40.9k
    uint16_t newWithdrawnRoutesDataLenBE = htobe16(newWithdrawnRoutesDataLen);
679
40.9k
    memcpy(m_Data + sizeof(bgp_common_header), &newWithdrawnRoutesDataLenBE, sizeof(uint16_t));
680
681
40.9k
    return true;
682
48.9k
  }
683
684
  bool BgpUpdateMessageLayer::clearWithdrawnRoutes()
685
16.3k
  {
686
16.3k
    return setWithdrawnRoutes(std::vector<prefix_and_ip>());
687
16.3k
  }
688
689
  void BgpUpdateMessageLayer::getPathAttributes(std::vector<path_attribute>& pathAttributes)
690
16.3k
  {
691
16.3k
    size_t pathAttrLen = getPathAttributesLength();
692
16.3k
    if (pathAttrLen == 0)
693
5.41k
    {
694
5.41k
      return;
695
5.41k
    }
696
697
10.9k
    uint8_t* dataPtr = m_Data + sizeof(bgp_common_header) + 2 * sizeof(uint16_t) + getWithdrawnRoutesLength();
698
10.9k
    size_t byteCount = 0;
699
53.9k
    while (byteCount < pathAttrLen)
700
43.0k
    {
701
43.0k
      path_attribute pa;
702
43.0k
      pa.flags = dataPtr[0];
703
43.0k
      pa.type = dataPtr[1];
704
43.0k
      pa.length = dataPtr[2];
705
43.0k
      size_t curByteCount = 3 + pa.length;
706
43.0k
      if (pa.length > 0)
707
32.1k
      {
708
32.1k
        size_t dataLenToCopy = (pa.length <= 32 ? pa.length : 32);
709
32.1k
        memcpy(pa.data, dataPtr + 3, dataLenToCopy);
710
32.1k
      }
711
712
43.0k
      pathAttributes.push_back(pa);
713
43.0k
      dataPtr += curByteCount;
714
43.0k
      byteCount += curByteCount;
715
43.0k
    }
716
10.9k
  }
717
718
  bool BgpUpdateMessageLayer::setPathAttributes(const std::vector<path_attribute>& pathAttributes)
719
48.9k
  {
720
48.9k
    uint8_t newPathAttributesData[1500];
721
48.9k
    size_t newPathAttributesDataLen = pathAttributesToByteArray(pathAttributes, newPathAttributesData, 1500);
722
48.9k
    size_t curPathAttributesDataLen = getPathAttributesLength();
723
48.9k
    size_t curWithdrawnRoutesDataLen = getWithdrawnRoutesLength();
724
48.9k
    int offsetInLayer = sizeof(bgp_common_header) + 2 * sizeof(uint16_t) + curWithdrawnRoutesDataLen;
725
726
48.9k
    if (newPathAttributesDataLen > curPathAttributesDataLen)
727
16.1k
    {
728
16.1k
      size_t numOfBytesToExtend = newPathAttributesDataLen - curPathAttributesDataLen;
729
730
16.1k
      if (!extendLayer(offsetInLayer, numOfBytesToExtend))
731
3.96k
      {
732
3.96k
        PCPP_LOG_ERROR("Couldn't extend BGP update layer to include the additional path attributes");
733
3.96k
        return false;
734
3.96k
      }
735
16.1k
    }
736
32.8k
    else if (newPathAttributesDataLen < curPathAttributesDataLen)
737
22.4k
    {
738
22.4k
      size_t numOfBytesToShorten = curPathAttributesDataLen - newPathAttributesDataLen;
739
740
22.4k
      if (!shortenLayer(offsetInLayer, numOfBytesToShorten))
741
1.35k
      {
742
1.35k
        PCPP_LOG_ERROR("Couldn't shorten BGP update layer to set the right size of the path attributes data");
743
1.35k
        return false;
744
1.35k
      }
745
22.4k
    }
746
747
43.6k
    if (newPathAttributesDataLen > 0)
748
21.5k
    {
749
21.5k
      memcpy(m_Data + offsetInLayer, newPathAttributesData, newPathAttributesDataLen);
750
21.5k
    }
751
752
43.6k
    getBasicHeader()->length =
753
43.6k
        htobe16(be16toh(getBasicHeader()->length) + newPathAttributesDataLen - curPathAttributesDataLen);
754
755
43.6k
    uint16_t newWithdrawnRoutesDataLenBE = htobe16(newPathAttributesDataLen);
756
43.6k
    memcpy(m_Data + sizeof(bgp_common_header) + sizeof(uint16_t) + curWithdrawnRoutesDataLen,
757
43.6k
           &newWithdrawnRoutesDataLenBE, sizeof(uint16_t));
758
759
43.6k
    return true;
760
48.9k
  }
761
762
  bool BgpUpdateMessageLayer::clearPathAttributes()
763
16.3k
  {
764
16.3k
    return setPathAttributes(std::vector<path_attribute>());
765
16.3k
  }
766
767
  size_t BgpUpdateMessageLayer::getNetworkLayerReachabilityInfoLength() const
768
65.2k
  {
769
65.2k
    size_t headerLen = getHeaderLen();
770
65.2k
    size_t minLen = sizeof(bgp_common_header) + 2 * sizeof(uint16_t);
771
65.2k
    if (headerLen >= minLen)
772
57.3k
    {
773
57.3k
      size_t withdrawnRouteLen = getWithdrawnRoutesLength();
774
57.3k
      size_t pathAttrLen = getPathAttributesLength();
775
57.3k
      int nlriSize = headerLen - minLen - withdrawnRouteLen - pathAttrLen;
776
57.3k
      if (nlriSize >= 0)
777
49.5k
      {
778
49.5k
        return (size_t)nlriSize;
779
49.5k
      }
780
781
7.81k
      return 0;
782
57.3k
    }
783
784
7.95k
    return 0;
785
65.2k
  }
786
787
  void BgpUpdateMessageLayer::getNetworkLayerReachabilityInfo(std::vector<prefix_and_ip>& nlri)
788
16.3k
  {
789
16.3k
    size_t nlriSize = getNetworkLayerReachabilityInfoLength();
790
16.3k
    if (nlriSize == 0)
791
6.93k
    {
792
6.93k
      return;
793
6.93k
    }
794
795
9.38k
    uint8_t* dataPtr = m_Data + sizeof(bgp_common_header) + 2 * sizeof(uint16_t) + getWithdrawnRoutesLength() +
796
9.38k
                       getPathAttributesLength();
797
9.38k
    parsePrefixAndIPData(dataPtr, nlriSize, nlri);
798
9.38k
  }
799
800
  bool BgpUpdateMessageLayer::isDataValid(const uint8_t* data, size_t dataSize)
801
154k
  {
802
154k
    if (dataSize < sizeof(bgp_common_header) + 2 * sizeof(uint16_t))
803
10
      return false;
804
805
154k
    uint16_t withdrLen = be16toh(*(uint16_t*)(data + sizeof(bgp_common_header)));
806
154k
    if (dataSize < sizeof(bgp_common_header) + 2 * sizeof(uint16_t) + withdrLen)
807
1.05k
      return false;
808
809
153k
    uint16_t attrLen = be16toh(*(uint16_t*)(data + sizeof(bgp_common_header) + sizeof(uint16_t) + withdrLen));
810
153k
    if (dataSize < sizeof(bgp_common_header) + 2 * sizeof(uint16_t) + withdrLen + attrLen)
811
863
      return false;
812
813
153k
    return true;
814
153k
  }
815
816
  bool BgpUpdateMessageLayer::setNetworkLayerReachabilityInfo(const std::vector<prefix_and_ip>& nlri)
817
48.9k
  {
818
48.9k
    uint8_t newNlriData[1500];
819
48.9k
    size_t newNlriDataLen = prefixAndIPDataToByteArray(nlri, newNlriData, 1500);
820
48.9k
    size_t curNlriDataLen = getNetworkLayerReachabilityInfoLength();
821
48.9k
    size_t curPathAttributesDataLen = getPathAttributesLength();
822
48.9k
    size_t curWithdrawnRoutesDataLen = getWithdrawnRoutesLength();
823
48.9k
    int offsetInLayer =
824
48.9k
        sizeof(bgp_common_header) + 2 * sizeof(uint16_t) + curWithdrawnRoutesDataLen + curPathAttributesDataLen;
825
826
48.9k
    if (newNlriDataLen > curNlriDataLen)
827
21.3k
    {
828
21.3k
      size_t numOfBytesToExtend = newNlriDataLen - curNlriDataLen;
829
830
21.3k
      if (!extendLayer(offsetInLayer, numOfBytesToExtend))
831
4.27k
      {
832
4.27k
        PCPP_LOG_ERROR("Couldn't extend BGP update layer to include the additional NLRI data");
833
4.27k
        return false;
834
4.27k
      }
835
21.3k
    }
836
27.6k
    else if (newNlriDataLen < curNlriDataLen)
837
12.6k
    {
838
12.6k
      size_t numOfBytesToShorten = curNlriDataLen - newNlriDataLen;
839
840
12.6k
      if (!shortenLayer(offsetInLayer, numOfBytesToShorten))
841
406
      {
842
406
        PCPP_LOG_ERROR("Couldn't shorten BGP update layer to set the right size of the NLRI data");
843
406
        return false;
844
406
      }
845
12.6k
    }
846
847
44.2k
    if (newNlriDataLen > 0)
848
19.3k
    {
849
19.3k
      memcpy(m_Data + offsetInLayer, newNlriData, newNlriDataLen);
850
19.3k
    }
851
852
44.2k
    getBasicHeader()->length = htobe16(be16toh(getBasicHeader()->length) + newNlriDataLen - curNlriDataLen);
853
854
44.2k
    return true;
855
48.9k
  }
856
857
  bool BgpUpdateMessageLayer::clearNetworkLayerReachabilityInfo()
858
16.3k
  {
859
16.3k
    return setNetworkLayerReachabilityInfo(std::vector<prefix_and_ip>());
860
16.3k
  }
861
862
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~
863
  // BgpNotificationMessageLayer
864
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~
865
866
  BgpNotificationMessageLayer::BgpNotificationMessageLayer(uint8_t errorCode, uint8_t errorSubCode)
867
0
  {
868
0
    initMessageData(errorCode, errorSubCode, nullptr, 0);
869
0
  }
870
871
  BgpNotificationMessageLayer::BgpNotificationMessageLayer(uint8_t errorCode, uint8_t errorSubCode,
872
                                                           const uint8_t* notificationData,
873
                                                           size_t notificationDataLen)
874
0
  {
875
0
    initMessageData(errorCode, errorSubCode, notificationData, notificationDataLen);
876
0
  }
877
878
  BgpNotificationMessageLayer::BgpNotificationMessageLayer(uint8_t errorCode, uint8_t errorSubCode,
879
                                                           const std::string& notificationData)
880
0
  {
881
0
    uint8_t notificationDataByteArr[1500];
882
0
    size_t notificationDataLen = hexStringToByteArray(notificationData, notificationDataByteArr, 1500);
883
0
    initMessageData(errorCode, errorSubCode, notificationDataByteArr, notificationDataLen);
884
0
  }
885
886
  void BgpNotificationMessageLayer::initMessageData(uint8_t errorCode, uint8_t errorSubCode,
887
                                                    const uint8_t* notificationData, size_t notificationDataLen)
888
0
  {
889
0
    size_t headerLen = sizeof(bgp_notification_message);
890
0
    if (notificationData != nullptr && notificationDataLen > 0)
891
0
    {
892
0
      headerLen += notificationDataLen;
893
0
    }
894
0
    m_DataLen = headerLen;
895
0
    m_Data = new uint8_t[headerLen];
896
0
    memset(m_Data, 0, headerLen);
897
0
    setBgpFields(headerLen);
898
0
    bgp_notification_message* msgHdr = getNotificationMsgHeader();
899
0
    msgHdr->errorCode = errorCode;
900
0
    msgHdr->errorSubCode = errorSubCode;
901
0
    memcpy(m_Data + sizeof(bgp_notification_message), notificationData, notificationDataLen);
902
0
    m_Protocol = BGP;
903
0
  }
904
905
  size_t BgpNotificationMessageLayer::getNotificationDataLen() const
906
900
  {
907
900
    size_t headerLen = getHeaderLen();
908
900
    if (headerLen > sizeof(bgp_notification_message))
909
460
    {
910
460
      return headerLen - sizeof(bgp_notification_message);
911
460
    }
912
913
440
    return 0;
914
900
  }
915
916
  uint8_t* BgpNotificationMessageLayer::getNotificationData() const
917
670
  {
918
670
    if (getNotificationDataLen() > 0)
919
230
    {
920
230
      return m_Data + sizeof(bgp_notification_message);
921
230
    }
922
923
440
    return nullptr;
924
670
  }
925
926
  std::string BgpNotificationMessageLayer::getNotificationDataAsHexString() const
927
670
  {
928
670
    uint8_t* notificationData = getNotificationData();
929
670
    if (notificationData == nullptr)
930
440
    {
931
440
      return "";
932
440
    }
933
934
230
    return byteArrayToHexString(notificationData, getNotificationDataLen());
935
670
  }
936
937
  bool BgpNotificationMessageLayer::setNotificationData(const uint8_t* newNotificationData,
938
                                                        size_t newNotificationDataLen)
939
0
  {
940
0
    if (newNotificationData == nullptr)
941
0
    {
942
0
      newNotificationDataLen = 0;
943
0
    }
944
945
0
    size_t curNotificationDataLen = getNotificationDataLen();
946
0
    int offsetInLayer = sizeof(bgp_notification_message);
947
948
0
    if (newNotificationDataLen > curNotificationDataLen)
949
0
    {
950
0
      size_t numOfBytesToExtend = newNotificationDataLen - curNotificationDataLen;
951
952
0
      if (!extendLayer(offsetInLayer, numOfBytesToExtend))
953
0
      {
954
0
        PCPP_LOG_ERROR("Couldn't extend BGP notification layer to include the additional notification data");
955
0
        return false;
956
0
      }
957
0
    }
958
0
    else if (newNotificationDataLen < curNotificationDataLen)
959
0
    {
960
0
      size_t numOfBytesToShorten = curNotificationDataLen - newNotificationDataLen;
961
962
0
      if (!shortenLayer(offsetInLayer, numOfBytesToShorten))
963
0
      {
964
0
        PCPP_LOG_ERROR(
965
0
            "Couldn't shorten BGP notification layer to set the right size of the notification data");
966
0
        return false;
967
0
      }
968
0
    }
969
970
0
    if (newNotificationDataLen > 0)
971
0
    {
972
0
      memcpy(m_Data + offsetInLayer, newNotificationData, newNotificationDataLen);
973
0
    }
974
975
0
    getNotificationMsgHeader()->length = htobe16(sizeof(bgp_notification_message) + newNotificationDataLen);
976
977
0
    return true;
978
0
  }
979
980
  bool BgpNotificationMessageLayer::setNotificationData(const std::string& newNotificationDataAsHexString)
981
0
  {
982
0
    if (newNotificationDataAsHexString.empty())
983
0
    {
984
0
      return setNotificationData(nullptr, 0);
985
0
    }
986
987
0
    uint8_t newNotificationData[1500];
988
0
    size_t newNotificationDataLen = hexStringToByteArray(newNotificationDataAsHexString, newNotificationData, 1500);
989
990
0
    if (newNotificationDataLen == 0)
991
0
    {
992
0
      PCPP_LOG_ERROR("newNotificationDataAsHexString is not a valid hex string");
993
0
      return false;
994
0
    }
995
996
0
    return setNotificationData(newNotificationData, newNotificationDataLen);
997
0
  }
998
999
  // ~~~~~~~~~~~~~~~~~~~~~~~~
1000
  // BgpKeepaliveMessageLayer
1001
  // ~~~~~~~~~~~~~~~~~~~~~~~~
1002
1003
0
  BgpKeepaliveMessageLayer::BgpKeepaliveMessageLayer() : BgpLayer()
1004
0
  {
1005
0
    const size_t headerLen = sizeof(bgp_common_header);
1006
0
    m_DataLen = headerLen;
1007
0
    m_Data = new uint8_t[headerLen];
1008
0
    memset(m_Data, 0, headerLen);
1009
0
    setBgpFields(headerLen);
1010
0
    m_Protocol = BGP;
1011
0
  }
1012
1013
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~
1014
  // BgpRouteRefreshMessageLayer
1015
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~
1016
1017
  BgpRouteRefreshMessageLayer::BgpRouteRefreshMessageLayer(uint16_t afi, uint8_t safi)
1018
0
  {
1019
0
    const size_t headerLen = sizeof(bgp_route_refresh_message);
1020
0
    m_DataLen = headerLen;
1021
0
    m_Data = new uint8_t[headerLen];
1022
0
    memset(m_Data, 0, headerLen);
1023
0
    setBgpFields(headerLen);
1024
0
    bgp_route_refresh_message* msgHdr = getRouteRefreshHeader();
1025
    msgHdr->afi = htobe16(afi);
1026
0
    msgHdr->safi = safi;
1027
0
    m_Protocol = BGP;
1028
0
  }
1029
1030
}  // namespace pcpp