|
2 | 2 |
|
3 | 3 | #include "Logger.h"
|
4 | 4 | #include "BgpLayer.h"
|
| 5 | +#include "Packet.h" |
5 | 6 | #include "EndianPortable.h"
|
6 | 7 | #include "GeneralUtils.h"
|
7 | 8 |
|
@@ -117,6 +118,50 @@ namespace pcpp
|
117 | 118 | }
|
118 | 119 | }
|
119 | 120 |
|
| 121 | + bool BgpLayer::isValidExtendRange(int offsetInLayer, size_t numOfBytesToExtend) const |
| 122 | + { |
| 123 | + int rawPacketLen = m_Packet->getRawPacket()->getRawDataLen(); |
| 124 | + const uint8_t* rawPacketPtr = m_Packet->getRawPacket()->getRawData(); |
| 125 | + |
| 126 | + if (m_Data - rawPacketPtr + static_cast<ptrdiff_t>(offsetInLayer) > static_cast<ptrdiff_t>(rawPacketLen)) |
| 127 | + { |
| 128 | + PCPP_LOG_ERROR("Requested offset is larger than total packet length"); |
| 129 | + return false; |
| 130 | + } |
| 131 | + |
| 132 | + if (m_NextLayer != nullptr && static_cast<ptrdiff_t>(offsetInLayer) > m_NextLayer->getData() - m_Data) |
| 133 | + { |
| 134 | + PCPP_LOG_ERROR("Requested offset exceeds current layer's boundary"); |
| 135 | + return false; |
| 136 | + } |
| 137 | + |
| 138 | + return true; |
| 139 | + } |
| 140 | + |
| 141 | + bool BgpLayer::isValidShortenRange(int offsetInLayer, size_t numOfBytesToShorten) const |
| 142 | + { |
| 143 | + int rawPacketLen = m_Packet->getRawPacket()->getRawDataLen(); |
| 144 | + const uint8_t* rawPacketPtr = m_Packet->getRawPacket()->getRawData(); |
| 145 | + |
| 146 | + if (m_Data - rawPacketPtr + static_cast<ptrdiff_t>(offsetInLayer) + |
| 147 | + static_cast<ptrdiff_t>(numOfBytesToShorten) > |
| 148 | + static_cast<ptrdiff_t>(rawPacketLen)) |
| 149 | + { |
| 150 | + PCPP_LOG_ERROR("Requested number of bytes to shorten is larger than total packet length"); |
| 151 | + return false; |
| 152 | + } |
| 153 | + |
| 154 | + if (m_NextLayer != nullptr && |
| 155 | + static_cast<ptrdiff_t>(offsetInLayer) + static_cast<ptrdiff_t>(numOfBytesToShorten) > |
| 156 | + m_NextLayer->getData() - m_Data) |
| 157 | + { |
| 158 | + PCPP_LOG_ERROR("Requested number of bytes to shorten exceeds current layer's boundary"); |
| 159 | + return false; |
| 160 | + } |
| 161 | + |
| 162 | + return true; |
| 163 | + } |
| 164 | + |
120 | 165 | // ~~~~~~~~~~~~~~~~~~~~
|
121 | 166 | // BgpOpenMessageLayer
|
122 | 167 | // ~~~~~~~~~~~~~~~~~~~~
|
@@ -261,29 +306,34 @@ namespace pcpp
|
261 | 306 | uint8_t newOptionalParamsData[1500];
|
262 | 307 | size_t newOptionalParamsDataLen = optionalParamsToByteArray(optionalParameters, newOptionalParamsData, 1500);
|
263 | 308 | size_t curOptionalParamsDataLen = getOptionalParametersLength();
|
| 309 | + int offsetInLayer = sizeof(bgp_open_message); |
264 | 310 |
|
265 | 311 | if (newOptionalParamsDataLen > curOptionalParamsDataLen)
|
266 | 312 | {
|
267 |
| - bool res = extendLayer(sizeof(bgp_open_message), newOptionalParamsDataLen - curOptionalParamsDataLen); |
268 |
| - if (!res) |
| 313 | + size_t numOfBytesToExtend = newOptionalParamsDataLen - curOptionalParamsDataLen; |
| 314 | + |
| 315 | + if (!isValidExtendRange(offsetInLayer, numOfBytesToExtend) || |
| 316 | + !extendLayer(offsetInLayer, numOfBytesToExtend)) |
269 | 317 | {
|
270 | 318 | PCPP_LOG_ERROR("Couldn't extend BGP open layer to include the additional optional parameters");
|
271 |
| - return res; |
| 319 | + return false; |
272 | 320 | }
|
273 | 321 | }
|
274 | 322 | else if (newOptionalParamsDataLen < curOptionalParamsDataLen)
|
275 | 323 | {
|
276 |
| - bool res = shortenLayer(sizeof(bgp_open_message), curOptionalParamsDataLen - newOptionalParamsDataLen); |
277 |
| - if (!res) |
| 324 | + size_t numOfBytesToShorten = curOptionalParamsDataLen - newOptionalParamsDataLen; |
| 325 | + |
| 326 | + if (!isValidShortenRange(offsetInLayer, numOfBytesToShorten) || |
| 327 | + !shortenLayer(offsetInLayer, numOfBytesToShorten)) |
278 | 328 | {
|
279 | 329 | PCPP_LOG_ERROR("Couldn't shorten BGP open layer to set the right size of the optional parameters data");
|
280 |
| - return res; |
| 330 | + return false; |
281 | 331 | }
|
282 | 332 | }
|
283 | 333 |
|
284 | 334 | if (newOptionalParamsDataLen > 0)
|
285 | 335 | {
|
286 |
| - memcpy(m_Data + sizeof(bgp_open_message), newOptionalParamsData, newOptionalParamsDataLen); |
| 336 | + memcpy(m_Data + offsetInLayer, newOptionalParamsData, newOptionalParamsDataLen); |
287 | 337 | }
|
288 | 338 |
|
289 | 339 | getOpenMsgHeader()->optionalParameterLength = (uint8_t)newOptionalParamsDataLen;
|
@@ -565,32 +615,34 @@ namespace pcpp
|
565 | 615 | uint8_t newWithdrawnRoutesData[1500];
|
566 | 616 | size_t newWithdrawnRoutesDataLen = prefixAndIPDataToByteArray(withdrawnRoutes, newWithdrawnRoutesData, 1500);
|
567 | 617 | size_t curWithdrawnRoutesDataLen = getWithdrawnRoutesLength();
|
| 618 | + int offsetInLayer = sizeof(bgp_common_header) + sizeof(uint16_t); |
568 | 619 |
|
569 | 620 | if (newWithdrawnRoutesDataLen > curWithdrawnRoutesDataLen)
|
570 | 621 | {
|
571 |
| - bool res = extendLayer(sizeof(bgp_common_header) + sizeof(uint16_t), |
572 |
| - newWithdrawnRoutesDataLen - curWithdrawnRoutesDataLen); |
573 |
| - if (!res) |
| 622 | + size_t numOfBytesToExtend = newWithdrawnRoutesDataLen - curWithdrawnRoutesDataLen; |
| 623 | + |
| 624 | + if (!isValidExtendRange(offsetInLayer, numOfBytesToExtend) || |
| 625 | + !extendLayer(offsetInLayer, numOfBytesToExtend)) |
574 | 626 | {
|
575 |
| - PCPP_LOG_ERROR("Couldn't extend BGP update layer to include the additional withdrawn routes"); |
576 |
| - return res; |
| 627 | + PCPP_LOG_ERROR("Couldn't extend BGP open layer to include the additional optional parameters"); |
| 628 | + return false; |
577 | 629 | }
|
578 | 630 | }
|
579 | 631 | else if (newWithdrawnRoutesDataLen < curWithdrawnRoutesDataLen)
|
580 | 632 | {
|
581 |
| - bool res = shortenLayer(sizeof(bgp_common_header) + sizeof(uint16_t), |
582 |
| - curWithdrawnRoutesDataLen - newWithdrawnRoutesDataLen); |
583 |
| - if (!res) |
| 633 | + size_t numOfBytesToShorten = curWithdrawnRoutesDataLen - newWithdrawnRoutesDataLen; |
| 634 | + |
| 635 | + if (!isValidShortenRange(offsetInLayer, numOfBytesToShorten) || |
| 636 | + !shortenLayer(offsetInLayer, numOfBytesToShorten)) |
584 | 637 | {
|
585 |
| - PCPP_LOG_ERROR("Couldn't shorten BGP update layer to set the right size of the withdrawn routes data"); |
586 |
| - return res; |
| 638 | + PCPP_LOG_ERROR("Couldn't shorten BGP open layer to set the right size of the optional parameters data"); |
| 639 | + return false; |
587 | 640 | }
|
588 | 641 | }
|
589 | 642 |
|
590 | 643 | if (newWithdrawnRoutesDataLen > 0)
|
591 | 644 | {
|
592 |
| - memcpy(m_Data + sizeof(bgp_common_header) + sizeof(uint16_t), newWithdrawnRoutesData, |
593 |
| - newWithdrawnRoutesDataLen); |
| 645 | + memcpy(m_Data + offsetInLayer, newWithdrawnRoutesData, newWithdrawnRoutesDataLen); |
594 | 646 | }
|
595 | 647 |
|
596 | 648 | getBasicHeader()->length =
|
@@ -642,32 +694,34 @@ namespace pcpp
|
642 | 694 | size_t newPathAttributesDataLen = pathAttributesToByteArray(pathAttributes, newPathAttributesData, 1500);
|
643 | 695 | size_t curPathAttributesDataLen = getPathAttributesLength();
|
644 | 696 | size_t curWithdrawnRoutesDataLen = getWithdrawnRoutesLength();
|
| 697 | + int offsetInLayer = sizeof(bgp_common_header) + 2 * sizeof(uint16_t) + curWithdrawnRoutesDataLen; |
645 | 698 |
|
646 | 699 | if (newPathAttributesDataLen > curPathAttributesDataLen)
|
647 | 700 | {
|
648 |
| - bool res = extendLayer(sizeof(bgp_common_header) + 2 * sizeof(uint16_t) + curWithdrawnRoutesDataLen, |
649 |
| - newPathAttributesDataLen - curPathAttributesDataLen); |
650 |
| - if (!res) |
| 701 | + size_t numOfBytesToExtend = newPathAttributesDataLen - curPathAttributesDataLen; |
| 702 | + |
| 703 | + if (!isValidExtendRange(offsetInLayer, numOfBytesToExtend) || |
| 704 | + !extendLayer(offsetInLayer, numOfBytesToExtend)) |
651 | 705 | {
|
652 |
| - PCPP_LOG_ERROR("Couldn't extend BGP update layer to include the additional path attributes"); |
653 |
| - return res; |
| 706 | + PCPP_LOG_ERROR("Couldn't extend BGP open layer to include the additional optional parameters"); |
| 707 | + return false; |
654 | 708 | }
|
655 | 709 | }
|
656 | 710 | else if (newPathAttributesDataLen < curPathAttributesDataLen)
|
657 | 711 | {
|
658 |
| - bool res = shortenLayer(sizeof(bgp_common_header) + 2 * sizeof(uint16_t) + curWithdrawnRoutesDataLen, |
659 |
| - curPathAttributesDataLen - newPathAttributesDataLen); |
660 |
| - if (!res) |
| 712 | + size_t numOfBytesToShorten = curPathAttributesDataLen - newPathAttributesDataLen; |
| 713 | + |
| 714 | + if (!isValidShortenRange(offsetInLayer, numOfBytesToShorten) || |
| 715 | + !shortenLayer(offsetInLayer, numOfBytesToShorten)) |
661 | 716 | {
|
662 |
| - PCPP_LOG_ERROR("Couldn't shorten BGP update layer to set the right size of the path attributes data"); |
663 |
| - return res; |
| 717 | + PCPP_LOG_ERROR("Couldn't shorten BGP open layer to set the right size of the optional parameters data"); |
| 718 | + return false; |
664 | 719 | }
|
665 | 720 | }
|
666 | 721 |
|
667 | 722 | if (newPathAttributesDataLen > 0)
|
668 | 723 | {
|
669 |
| - memcpy(m_Data + sizeof(bgp_common_header) + 2 * sizeof(uint16_t) + curWithdrawnRoutesDataLen, |
670 |
| - newPathAttributesData, newPathAttributesDataLen); |
| 724 | + memcpy(m_Data + offsetInLayer, newPathAttributesData, newPathAttributesDataLen); |
671 | 725 | }
|
672 | 726 |
|
673 | 727 | getBasicHeader()->length =
|
@@ -741,35 +795,35 @@ namespace pcpp
|
741 | 795 | size_t curNlriDataLen = getNetworkLayerReachabilityInfoLength();
|
742 | 796 | size_t curPathAttributesDataLen = getPathAttributesLength();
|
743 | 797 | size_t curWithdrawnRoutesDataLen = getWithdrawnRoutesLength();
|
| 798 | + int offsetInLayer = |
| 799 | + sizeof(bgp_common_header) + 2 * sizeof(uint16_t) + curWithdrawnRoutesDataLen + curPathAttributesDataLen; |
744 | 800 |
|
745 | 801 | if (newNlriDataLen > curNlriDataLen)
|
746 | 802 | {
|
747 |
| - bool res = extendLayer(sizeof(bgp_common_header) + 2 * sizeof(uint16_t) + curWithdrawnRoutesDataLen + |
748 |
| - curPathAttributesDataLen, |
749 |
| - newNlriDataLen - curNlriDataLen); |
750 |
| - if (!res) |
| 803 | + size_t numOfBytesToExtend = newNlriDataLen - curNlriDataLen; |
| 804 | + |
| 805 | + if (!isValidExtendRange(offsetInLayer, numOfBytesToExtend) || |
| 806 | + !extendLayer(offsetInLayer, numOfBytesToExtend)) |
751 | 807 | {
|
752 |
| - PCPP_LOG_ERROR("Couldn't extend BGP update layer to include the additional NLRI data"); |
753 |
| - return res; |
| 808 | + PCPP_LOG_ERROR("Couldn't extend BGP open layer to include the additional optional parameters"); |
| 809 | + return false; |
754 | 810 | }
|
755 | 811 | }
|
756 | 812 | else if (newNlriDataLen < curNlriDataLen)
|
757 | 813 | {
|
758 |
| - bool res = shortenLayer(sizeof(bgp_common_header) + 2 * sizeof(uint16_t) + curWithdrawnRoutesDataLen + |
759 |
| - curPathAttributesDataLen, |
760 |
| - curNlriDataLen - newNlriDataLen); |
761 |
| - if (!res) |
| 814 | + size_t numOfBytesToShorten = curNlriDataLen - newNlriDataLen; |
| 815 | + |
| 816 | + if (!isValidShortenRange(offsetInLayer, numOfBytesToShorten) || |
| 817 | + !shortenLayer(offsetInLayer, numOfBytesToShorten)) |
762 | 818 | {
|
763 |
| - PCPP_LOG_ERROR("Couldn't shorten BGP update layer to set the right size of the NLRI data"); |
764 |
| - return res; |
| 819 | + PCPP_LOG_ERROR("Couldn't shorten BGP open layer to set the right size of the optional parameters data"); |
| 820 | + return false; |
765 | 821 | }
|
766 | 822 | }
|
767 | 823 |
|
768 | 824 | if (newNlriDataLen > 0)
|
769 | 825 | {
|
770 |
| - memcpy(m_Data + sizeof(bgp_common_header) + 2 * sizeof(uint16_t) + curWithdrawnRoutesDataLen + |
771 |
| - curPathAttributesDataLen, |
772 |
| - newNlriData, newNlriDataLen); |
| 826 | + memcpy(m_Data + offsetInLayer, newNlriData, newNlriDataLen); |
773 | 827 | }
|
774 | 828 |
|
775 | 829 | getBasicHeader()->length = htobe16(be16toh(getBasicHeader()->length) + newNlriDataLen - curNlriDataLen);
|
@@ -866,30 +920,34 @@ namespace pcpp
|
866 | 920 | }
|
867 | 921 |
|
868 | 922 | size_t curNotificationDataLen = getNotificationDataLen();
|
| 923 | + int offsetInLayer = sizeof(bgp_notification_message); |
869 | 924 |
|
870 | 925 | if (newNotificationDataLen > curNotificationDataLen)
|
871 | 926 | {
|
872 |
| - bool res = extendLayer(sizeof(bgp_notification_message), newNotificationDataLen - curNotificationDataLen); |
873 |
| - if (!res) |
| 927 | + size_t numOfBytesToExtend = newNotificationDataLen - curNotificationDataLen; |
| 928 | + |
| 929 | + if (!isValidExtendRange(offsetInLayer, numOfBytesToExtend) || |
| 930 | + !extendLayer(offsetInLayer, numOfBytesToExtend)) |
874 | 931 | {
|
875 |
| - PCPP_LOG_ERROR("Couldn't extend BGP notification layer to include the additional notification data"); |
876 |
| - return res; |
| 932 | + PCPP_LOG_ERROR("Couldn't extend BGP open layer to include the additional optional parameters"); |
| 933 | + return false; |
877 | 934 | }
|
878 | 935 | }
|
879 | 936 | else if (newNotificationDataLen < curNotificationDataLen)
|
880 | 937 | {
|
881 |
| - bool res = shortenLayer(sizeof(bgp_notification_message), curNotificationDataLen - newNotificationDataLen); |
882 |
| - if (!res) |
| 938 | + size_t numOfBytesToShorten = curNotificationDataLen - newNotificationDataLen; |
| 939 | + |
| 940 | + if (!isValidShortenRange(offsetInLayer, numOfBytesToShorten) || |
| 941 | + !shortenLayer(offsetInLayer, numOfBytesToShorten)) |
883 | 942 | {
|
884 |
| - PCPP_LOG_ERROR( |
885 |
| - "Couldn't shorten BGP notification layer to set the right size of the notification data"); |
886 |
| - return res; |
| 943 | + PCPP_LOG_ERROR("Couldn't shorten BGP open layer to set the right size of the optional parameters data"); |
| 944 | + return false; |
887 | 945 | }
|
888 | 946 | }
|
889 | 947 |
|
890 | 948 | if (newNotificationDataLen > 0)
|
891 | 949 | {
|
892 |
| - memcpy(m_Data + sizeof(bgp_notification_message), newNotificationData, newNotificationDataLen); |
| 950 | + memcpy(m_Data + offsetInLayer, newNotificationData, newNotificationDataLen); |
893 | 951 | }
|
894 | 952 |
|
895 | 953 | getNotificationMsgHeader()->length = htobe16(sizeof(bgp_notification_message) + newNotificationDataLen);
|
|
0 commit comments