@@ -916,7 +916,13 @@ namespace pcpp
916
916
917
917
bool PcapLiveDevice::doMtuCheck (int packetPayloadLength) const
918
918
{
919
- if (packetPayloadLength > static_cast <int >(m_DeviceMtu))
919
+ if (packetPayloadLength < 0 )
920
+ {
921
+ PCPP_LOG_ERROR (" Payload length [" << packetPayloadLength << " ] is negative" );
922
+ return false ;
923
+ }
924
+
925
+ if (!isPayloadWithinMtu (packetPayloadLength))
920
926
{
921
927
PCPP_LOG_ERROR (" Payload length [" << packetPayloadLength << " ] is larger than device MTU [" << m_DeviceMtu
922
928
<< " ]" );
@@ -925,64 +931,144 @@ namespace pcpp
925
931
return true ;
926
932
}
927
933
928
- bool PcapLiveDevice::sendPacket (Packet const & packet, bool checkMtu)
934
+ bool PcapLiveDevice::isPayloadWithinMtu ( size_t packetPayloadLength) const
929
935
{
930
- RawPacket const * rawPacket = packet.getRawPacketReadOnly ();
931
-
932
- if (!checkMtu)
933
- {
934
- return sendPacket (*rawPacket, false );
935
- }
936
+ return packetPayloadLength <= static_cast <size_t >(m_DeviceMtu);
937
+ }
936
938
937
- int packetPayloadLength = 0 ;
939
+ bool PcapLiveDevice::isPayloadWithinMtu (Packet const & packet, bool allowUnknownLength,
940
+ size_t * outPayloadLength) const
941
+ {
942
+ size_t packetPayloadLength = 0 ;
938
943
switch (packet.getFirstLayer ()->getOsiModelLayer ())
939
944
{
940
- case ( pcpp::OsiModelDataLinkLayer) :
941
- packetPayloadLength = static_cast < int >( packet.getFirstLayer ()->getLayerPayloadSize () );
945
+ case pcpp::OsiModelDataLinkLayer:
946
+ packetPayloadLength = packet.getFirstLayer ()->getLayerPayloadSize ();
942
947
break ;
943
- case ( pcpp::OsiModelNetworkLayer) :
944
- packetPayloadLength = static_cast < int >( packet.getFirstLayer ()->getDataLen () );
948
+ case pcpp::OsiModelNetworkLayer:
949
+ packetPayloadLength = packet.getFirstLayer ()->getDataLen ();
945
950
break ;
946
951
default :
947
- // if packet layer is not known, do not perform MTU check.
948
- return sendPacket (*rawPacket, false );
952
+ {
953
+ // If the packet length is unknown, the MTU check is skipped.
954
+ // In such cases the output payload length is set to the maximum size and the return value is the
955
+ // allowUnknownLength value.
956
+ if (outPayloadLength != nullptr )
957
+ {
958
+ *outPayloadLength = (std::numeric_limits<size_t >::max)();
959
+ }
960
+ return allowUnknownLength;
961
+ }
962
+ }
963
+
964
+ if (outPayloadLength != nullptr )
965
+ {
966
+ *outPayloadLength = packetPayloadLength;
967
+ }
968
+ return isPayloadWithinMtu (packetPayloadLength);
969
+ }
970
+
971
+ bool PcapLiveDevice::isPayloadWithinMtu (RawPacket const & rawPacket, bool allowUnknownLength,
972
+ size_t * outPayloadLength) const
973
+ {
974
+ // Const cast because Packet requires a non-const RawPacket pointer
975
+ // and we don't modify the RawPacket in this function.
976
+ return isPayloadWithinMtu (Packet (const_cast <RawPacket*>(&rawPacket), OsiModelDataLinkLayer), allowUnknownLength,
977
+ outPayloadLength);
978
+ }
979
+
980
+ bool PcapLiveDevice::isPayloadWithinMtu (uint8_t const * packetData, size_t packetLen, LinkLayerType linkType,
981
+ bool allowUnknown, size_t * outPayloadLength) const
982
+ {
983
+ timeval time;
984
+ gettimeofday (&time, nullptr );
985
+ return isPayloadWithinMtu (RawPacket (packetData, packetLen, time, false , linkType), allowUnknown,
986
+ outPayloadLength);
987
+ }
988
+
989
+ bool PcapLiveDevice::sendPacket (Packet const & packet, bool checkMtu)
990
+ {
991
+ if (checkMtu)
992
+ {
993
+ size_t packetPayloadLength = 0 ;
994
+ // Unknown length is allowed due to legacy behavior of this function
995
+ if (!isPayloadWithinMtu (packet, true , &packetPayloadLength))
996
+ {
997
+ PCPP_LOG_ERROR (" Packet payload length [" << packetPayloadLength << " ] is larger than device MTU ["
998
+ << m_DeviceMtu << " ]" );
999
+ return false ;
1000
+ }
949
1001
}
950
- return doMtuCheck (packetPayloadLength) && sendPacket (*rawPacket, false );
1002
+
1003
+ return sendPacketUnchecked (*packet.getRawPacketReadOnly ());
951
1004
}
952
1005
953
1006
bool PcapLiveDevice::sendPacket (RawPacket const & rawPacket, bool checkMtu)
954
1007
{
955
- if (! checkMtu)
1008
+ if (checkMtu)
956
1009
{
957
- return sendPacketDirect (rawPacket.getRawData (), rawPacket.getRawDataLen ());
1010
+ size_t packetPayloadLength = 0 ;
1011
+ // Unknown length is allowed due to legacy behavior of this function
1012
+ if (!isPayloadWithinMtu (rawPacket, true , &packetPayloadLength))
1013
+ {
1014
+ PCPP_LOG_ERROR (" Packet payload length [" << packetPayloadLength << " ] is larger than device MTU ["
1015
+ << m_DeviceMtu << " ]" );
1016
+ return false ;
1017
+ }
958
1018
}
959
1019
960
- RawPacket* rPacket = const_cast <RawPacket*>(&rawPacket);
961
- Packet parsedPacket = Packet (rPacket, OsiModelDataLinkLayer);
962
- return sendPacket (parsedPacket, true );
1020
+ return sendPacketUnchecked (rawPacket);
963
1021
}
964
1022
965
1023
bool PcapLiveDevice::sendPacket (const uint8_t * packetData, int packetDataLength, int packetPayloadLength)
966
1024
{
967
- return doMtuCheck (packetPayloadLength) && sendPacketDirect (packetData, packetDataLength);
1025
+ if (packetDataLength < 0 )
1026
+ {
1027
+ PCPP_LOG_ERROR (" Packet data length is negative: " << packetDataLength);
1028
+ return false ;
1029
+ }
1030
+
1031
+ if (packetPayloadLength < 0 )
1032
+ {
1033
+ PCPP_LOG_ERROR (" Payload length is negative: " << packetPayloadLength);
1034
+ return false ;
1035
+ }
1036
+
1037
+ if (!isPayloadWithinMtu (packetPayloadLength))
1038
+ {
1039
+ PCPP_LOG_ERROR (" Packet payload length [" << packetPayloadLength << " ] is larger than device MTU ["
1040
+ << m_DeviceMtu << " ]" );
1041
+ return false ;
1042
+ }
1043
+
1044
+ return sendPacketUnchecked (packetData, packetDataLength);
968
1045
}
969
1046
970
1047
bool PcapLiveDevice::sendPacket (const uint8_t * packetData, int packetDataLength, bool checkMtu,
971
1048
pcpp::LinkLayerType linkType)
972
1049
{
973
- if (!checkMtu)
1050
+ if (packetDataLength < 0 )
1051
+ {
1052
+ PCPP_LOG_ERROR (" Packet data length is negative: " << packetDataLength);
1053
+ return false ;
1054
+ }
1055
+
1056
+ if (checkMtu)
974
1057
{
975
- return sendPacketDirect (packetData, packetDataLength);
1058
+ size_t packetPayloadLength = 0 ;
1059
+ // Unknown length is allowed due to legacy behavior of this function
1060
+ if (!isPayloadWithinMtu (packetData, packetDataLength, linkType, true , &packetPayloadLength))
1061
+ {
1062
+ PCPP_LOG_ERROR (" Packet payload length [" << packetPayloadLength << " ] is larger than device MTU ["
1063
+ << m_DeviceMtu << " ]" );
1064
+ return false ;
1065
+ }
976
1066
}
977
1067
978
- timeval time;
979
- gettimeofday (&time, nullptr );
980
- pcpp::RawPacket rawPacket (packetData, packetDataLength, time, false , linkType);
981
- Packet parsedPacket = Packet (&rawPacket, pcpp::OsiModelDataLinkLayer);
982
- return sendPacket (parsedPacket, true );
1068
+ return sendPacketUnchecked (packetData, packetDataLength);
983
1069
}
984
1070
985
- bool PcapLiveDevice::sendPacketDirect (uint8_t const * packetData, int packetDataLength)
1071
+ bool PcapLiveDevice::sendPacketUnchecked (uint8_t const * packetData, int packetDataLength)
986
1072
{
987
1073
if (!m_DeviceOpened)
988
1074
{
0 commit comments