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