diff --git a/Packet++/header/FtpLayer.h b/Packet++/header/FtpLayer.h index e51abb6fa5..ea26aac2ec 100644 --- a/Packet++/header/FtpLayer.h +++ b/Packet++/header/FtpLayer.h @@ -2,6 +2,7 @@ #define PACKETPP_FTP_LAYER #include "SingleCommandTextProtocol.h" +#include "PayloadLayer.h" /// @file @@ -24,11 +25,17 @@ namespace pcpp public: /** - * A static method that checks whether the port is considered as FTP + * A static method that checks whether the port is considered as FTP control * @param[in] port The port number to be checked */ static bool isFtpPort(uint16_t port) { return port == 21; } + /** + * A static method that checks whether the port is considered as FTP data + * @param[in] port The port number to be checked + */ + static bool isFtpDataPort(uint16_t port) { return port == 20; } + // overridden methods /// FTP is the always last so does nothing for this layer @@ -465,6 +472,27 @@ namespace pcpp */ std::string toString() const; }; + + /** + * Class for representing the data of FTP Layer + */ + class FtpDataLayer : public PayloadLayer + { + public: + + /** A constructor that creates the layer from an existing packet raw data + * @param[in] data A pointer to the raw data + * @param[in] dataLen Size of the data in bytes + * @param[in] prevLayer A pointer to the previous layer + * @param[in] packet A pointer to the Packet instance where layer will be stored in + */ + FtpDataLayer(uint8_t *data, size_t dataLen, Layer *prevLayer, Packet *packet) : PayloadLayer(data, dataLen, prevLayer, packet) { m_Protocol = FTP; }; + + /** + * @return Returns the protocol info as readable string + */ + std::string toString() const; + }; } // namespace pcpp #endif /* PACKETPP_FTP_LAYER */ diff --git a/Packet++/src/FtpLayer.cpp b/Packet++/src/FtpLayer.cpp index 9319e32520..0e69eb4a83 100644 --- a/Packet++/src/FtpLayer.cpp +++ b/Packet++/src/FtpLayer.cpp @@ -379,4 +379,9 @@ namespace pcpp return "FTP Response: " + getStatusCodeString(); } + std::string FtpDataLayer::toString() const + { + return "FTP Data"; + } + } // namespace pcpp diff --git a/Packet++/src/TcpLayer.cpp b/Packet++/src/TcpLayer.cpp index 727183fef3..71958e15c1 100644 --- a/Packet++/src/TcpLayer.cpp +++ b/Packet++/src/TcpLayer.cpp @@ -387,6 +387,8 @@ void TcpLayer::parseNextLayer() m_NextLayer = new FtpResponseLayer(payload, payloadLen, this, m_Packet); else if (FtpLayer::isFtpPort(portDst) && FtpLayer::isDataValid(payload, payloadLen)) m_NextLayer = new FtpRequestLayer(payload, payloadLen, this, m_Packet); + else if (FtpLayer::isFtpDataPort(portSrc) || FtpLayer::isFtpDataPort(portDst)) + m_NextLayer = new FtpDataLayer(payload, payloadLen, this, m_Packet); else if (SomeIpLayer::isSomeIpPort(portSrc) || SomeIpLayer::isSomeIpPort(portDst)) m_NextLayer = SomeIpLayer::parseSomeIpLayer(payload, payloadLen, this, m_Packet); else if (TpktLayer::isDataValid(payload, payloadLen) && TpktLayer::isTpktPort(portSrc, portDst)) diff --git a/Tests/Packet++Test/PacketExamples/Ftp.pcap b/Tests/Packet++Test/PacketExamples/Ftp.pcap index fef5689d61..8ae4ec45ab 100644 Binary files a/Tests/Packet++Test/PacketExamples/Ftp.pcap and b/Tests/Packet++Test/PacketExamples/Ftp.pcap differ diff --git a/Tests/Packet++Test/PacketExamples/ftp-data.dat b/Tests/Packet++Test/PacketExamples/ftp-data.dat new file mode 100644 index 0000000000..55a79f9197 --- /dev/null +++ b/Tests/Packet++Test/PacketExamples/ftp-data.dat @@ -0,0 +1 @@ +0016ce6e8b240015f24076ef0800450005d4296e400080064932c0a800c1c0a8007200140474eaaf92951baa1e4d5010ffffbfd6000049443303000000001f7654414c4200000026000000556e6b6e6f776e20416c62756d2028322f32362f323030362031313a31323a323020414d295449543200000008000000547261636b20324d43444900000028000033002b00390036002b0034004200300043002b0038003700450037002b00440044003400320000005452434b000000020000003254434f4e00000008000000556e6b6e6f776e505249560000000e00005065616b56616c756500145b000050524956000000110000417665726167654c6576656c00840d0000545045310000000f000000556e6b6e6f776e20417274697374544c454e00000008000000323037373230000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 \ No newline at end of file diff --git a/Tests/Packet++Test/Tests/FtpTests.cpp b/Tests/Packet++Test/Tests/FtpTests.cpp index 1d45165c79..ebae434370 100644 --- a/Tests/Packet++Test/Tests/FtpTests.cpp +++ b/Tests/Packet++Test/Tests/FtpTests.cpp @@ -96,6 +96,17 @@ PTF_TEST_CASE(FtpParsingTests) PTF_ASSERT_EQUAL( pcpp::FtpResponseLayer::getStatusCodeAsString(pcpp::FtpResponseLayer::FtpStatusCode::COMMAND_NOT_IMPLEMENTED), "Command not implemented"); + + // Test FTP Data + READ_FILE_AND_CREATE_PACKET(6, "PacketExamples/ftp-data.dat"); + + pcpp::Packet ftpDataPacket(&rawPacket6); + pcpp::FtpDataLayer *ftpDataLayer = ftpDataPacket.getLayerOfType(); + + PTF_ASSERT_NOT_NULL(ftpDataLayer); + + PTF_ASSERT_EQUAL(ftpDataLayer->getDataLen(), 1452); + PTF_ASSERT_EQUAL(ftpDataLayer->toString(), "FTP Data"); } PTF_TEST_CASE(FtpCreationTests)