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