55#include " PcapFileDevice.h"
66#include " ../Common/PcapFileNamesDef.h"
77#include " ../Common/TestUtils.h"
8+ #include " EndianPortable.h"
89#include < array>
910#include < fstream>
1011#include < chrono>
@@ -1792,17 +1793,88 @@ enum class SnoopPacketHeaderParam
17921793 TimestampSec,
17931794 TimestampUsec,
17941795 Caplen,
1795- TotalLen
1796+ Wirelen,
1797+ Pad
17961798};
17971799
1800+ std::vector<uint8_t > createSnoopPacketHeader (const std::unordered_map<SnoopPacketHeaderParam, uint32_t >& params)
1801+ {
1802+ struct snoop_packet_header
1803+ {
1804+ uint32_t original_length;
1805+ uint32_t included_length;
1806+ uint32_t packet_record_length;
1807+ uint32_t ndrops_cumulative;
1808+ uint32_t time_sec;
1809+ uint32_t time_usec;
1810+ };
1811+
1812+ // Defaults
1813+ uint32_t caplen = 1514 ;
1814+ uint32_t wirelen = 1514 ;
1815+ uint32_t pad = 0 ;
1816+
1817+ auto now = std::chrono::system_clock::now ();
1818+ auto duration = now.time_since_epoch ();
1819+ auto subSec = duration % std::chrono::seconds (1 );
1820+ uint32_t sec = static_cast <uint32_t >(std::chrono::duration_cast<std::chrono::seconds>(duration).count ());
1821+ uint32_t usec = static_cast <uint32_t >(std::chrono::duration_cast<std::chrono::microseconds>(subSec).count ());
1822+
1823+ for (const auto & p : params)
1824+ {
1825+ switch (p.first )
1826+ {
1827+ case SnoopPacketHeaderParam::TimestampSec:
1828+ {
1829+ sec = p.second ;
1830+ break ;
1831+ }
1832+ case SnoopPacketHeaderParam::TimestampUsec:
1833+ {
1834+ usec = p.second ;
1835+ break ;
1836+ }
1837+ case SnoopPacketHeaderParam::Caplen:
1838+ {
1839+ caplen = p.second ;
1840+ break ;
1841+ }
1842+ case SnoopPacketHeaderParam::Wirelen:
1843+ {
1844+ wirelen = p.second ;
1845+ break ;
1846+ }
1847+ case SnoopPacketHeaderParam::Pad:
1848+ {
1849+ pad = p.second ;
1850+ break ;
1851+ }
1852+ }
1853+ }
1854+
1855+ snoop_packet_header header = { htobe32 (wirelen),
1856+ htobe32 (caplen),
1857+ htobe32 (static_cast <uint32_t >(sizeof (snoop_packet_header) + caplen + pad)),
1858+ 0u ,
1859+ htobe32 (sec),
1860+ htobe32 (usec) };
1861+
1862+ std::vector<uint8_t > result (sizeof (snoop_packet_header));
1863+ std::memcpy (result.data (), &header, sizeof (snoop_packet_header));
1864+ return result;
1865+ }
1866+
17981867PTF_TEST_CASE (TestSolarisSnoopFileRead)
17991868{
18001869 SuppressLogs suppressLogs;
18011870
1871+ std::array<uint8_t , 5 > packetData = { 0x01 , 0x02 , 0x03 , 0x04 , 0x05 };
1872+
18021873 // Basic test
18031874 {
18041875 pcpp::SnoopFileReaderDevice readerDev (EXAMPLE_SOLARIS_SNOOP);
18051876 PTF_ASSERT_TRUE (readerDev.open ());
1877+ PTF_ASSERT_TRUE (readerDev.isOpened ());
18061878 pcpp::RawPacket rawPacket;
18071879 int packetCount = 0 ;
18081880 int ethCount = 0 ;
@@ -1831,8 +1903,8 @@ PTF_TEST_CASE(TestSolarisSnoopFileRead)
18311903 pcpp::IPcapDevice::PcapStats readerStatistics;
18321904
18331905 readerDev.getStatistics (readerStatistics);
1834- PTF_ASSERT_EQUAL (( uint32_t ) readerStatistics.packetsRecv , 250 );
1835- PTF_ASSERT_EQUAL (( uint32_t ) readerStatistics.packetsDrop , 0 );
1906+ PTF_ASSERT_EQUAL (readerStatistics.packetsRecv , 250 );
1907+ PTF_ASSERT_EQUAL (readerStatistics.packetsDrop , 0 );
18361908
18371909 PTF_ASSERT_EQUAL (packetCount, 250 );
18381910 PTF_ASSERT_EQUAL (ethCount, 142 );
@@ -1870,6 +1942,65 @@ PTF_TEST_CASE(TestSolarisSnoopFileRead)
18701942 }
18711943
18721944 PTF_ASSERT_EQUAL (packetCount, 16 );
1945+
1946+ pcpp::IPcapDevice::PcapStats readerStatistics;
1947+ readerDev.getStatistics (readerStatistics);
1948+ PTF_ASSERT_EQUAL (readerStatistics.packetsRecv , 16 );
1949+ }
1950+
1951+ // Packet details
1952+ {
1953+ TempFile snoopFile (" snoop" );
1954+ snoopFile << createSnoopHeader ({});
1955+ snoopFile << createSnoopPacketHeader ({
1956+ { SnoopPacketHeaderParam::Caplen, packetData.size () },
1957+ { SnoopPacketHeaderParam::Wirelen, packetData.size () + 5 },
1958+ { SnoopPacketHeaderParam::TimestampSec, 1234 },
1959+ { SnoopPacketHeaderParam::TimestampUsec, 5678 }
1960+ });
1961+ snoopFile << packetData;
1962+ snoopFile.close ();
1963+
1964+ pcpp::SnoopFileReaderDevice readerDev (snoopFile.getFileName ());
1965+ PTF_ASSERT_TRUE (readerDev.open ());
1966+
1967+ pcpp::RawPacket rawPacket;
1968+ PTF_ASSERT_TRUE (readerDev.getNextPacket (rawPacket));
1969+
1970+ PTF_ASSERT_EQUAL (rawPacket.getRawDataLen (), packetData.size ());
1971+ PTF_ASSERT_EQUAL (rawPacket.getFrameLength (), packetData.size () + 5 );
1972+ PTF_ASSERT_EQUAL (rawPacket.getPacketTimeStamp ().tv_sec , 1234 );
1973+ PTF_ASSERT_EQUAL (rawPacket.getPacketTimeStamp ().tv_nsec , 5678000 );
1974+
1975+ PTF_ASSERT_BUF_COMPARE (rawPacket.getRawData (), packetData.data (), packetData.size ());
1976+ }
1977+
1978+ // Packet padding
1979+ {
1980+ TempFile snoopFile (" snoop" );
1981+ snoopFile << createSnoopHeader ({});
1982+ snoopFile << createSnoopPacketHeader ({
1983+ { SnoopPacketHeaderParam::Caplen, packetData.size () },
1984+ { SnoopPacketHeaderParam::Pad, 3 }
1985+ });
1986+ snoopFile << packetData;
1987+ snoopFile << std::array<uint8_t , 3 >{ 0xff , 0xff , 0xff };
1988+ snoopFile << createSnoopPacketHeader ({
1989+ { SnoopPacketHeaderParam::Caplen, packetData.size () }
1990+ });
1991+ snoopFile << packetData;
1992+ snoopFile.close ();
1993+
1994+ pcpp::SnoopFileReaderDevice readerDev (snoopFile.getFileName ());
1995+ PTF_ASSERT_TRUE (readerDev.open ());
1996+
1997+ pcpp::RawPacket rawPacket;
1998+ for (int i = 0 ; i < 2 ; i++)
1999+ {
2000+ PTF_ASSERT_TRUE (readerDev.getNextPacket (rawPacket));
2001+ PTF_ASSERT_EQUAL (rawPacket.getRawDataLen (), packetData.size ());
2002+ PTF_ASSERT_BUF_COMPARE (rawPacket.getRawData (), packetData.data (), packetData.size ());
2003+ }
18732004 }
18742005
18752006 // Device not open
@@ -1888,6 +2019,23 @@ PTF_TEST_CASE(TestSolarisSnoopFileRead)
18882019 " Cannot open snoop reader device for filename 'does_not_exist.snoop'" );
18892020 }
18902021
2022+ // File already open
2023+ {
2024+ pcpp::SnoopFileReaderDevice readerDev (EXAMPLE_SOLARIS_SNOOP);
2025+ PTF_ASSERT_TRUE (readerDev.open ());
2026+
2027+ PTF_ASSERT_FALSE (readerDev.open ());
2028+ PTF_ASSERT_EQUAL (pcpp::Logger::getInstance ().getLastError (), " File already open" );
2029+ }
2030+
2031+ // Read packet from a non-open device
2032+ {
2033+ pcpp::SnoopFileReaderDevice readerDev (EXAMPLE_SOLARIS_SNOOP);
2034+ pcpp::RawPacket rawPacket;
2035+ PTF_ASSERT_FALSE (readerDev.getNextPacket (rawPacket));
2036+ PTF_ASSERT_EQUAL (pcpp::Logger::getInstance ().getLastError (), " File device not open" );
2037+ }
2038+
18912039 // Cannot read file header
18922040 {
18932041 TempFile snoopFile (" snoop" );
@@ -1897,6 +2045,7 @@ PTF_TEST_CASE(TestSolarisSnoopFileRead)
18972045 PTF_ASSERT_FALSE (readerDev.open ());
18982046 PTF_ASSERT_EQUAL (pcpp::Logger::getInstance ().getLastError (),
18992047 " Cannot read snoop file header for '" + snoopFile.getFileName () + " '" );
2048+ PTF_ASSERT_FALSE (readerDev.isOpened ());
19002049 }
19012050
19022051 // Wrong magic number
@@ -1953,6 +2102,36 @@ PTF_TEST_CASE(TestSolarisSnoopFileRead)
19532102 PTF_ASSERT_FALSE (readerDev.getNextPacket (rawPacket));
19542103 PTF_ASSERT_EQUAL (pcpp::Logger::getInstance ().getLastError (), " Failed to read packet metadata" );
19552104 }
2105+
2106+ // Packet data too large
2107+ {
2108+ TempFile snoopFile (" snoop" );
2109+ snoopFile << createSnoopHeader ({});
2110+ snoopFile << createSnoopPacketHeader ({
2111+ { SnoopPacketHeaderParam::Caplen, 15'500 }
2112+ });
2113+ snoopFile.close ();
2114+
2115+ pcpp::SnoopFileReaderDevice readerDev (snoopFile.getFileName ());
2116+ PTF_ASSERT_TRUE (readerDev.open ());
2117+ pcpp::RawPacket rawPacket;
2118+ PTF_ASSERT_FALSE (readerDev.getNextPacket (rawPacket));
2119+ PTF_ASSERT_EQUAL (pcpp::Logger::getInstance ().getLastError (), " Packet length 15500 is too large" );
2120+ }
2121+
2122+ // Cannot read packet data
2123+ {
2124+ TempFile snoopFile (" snoop" );
2125+ snoopFile << createSnoopHeader ({});
2126+ snoopFile << createSnoopPacketHeader ({});
2127+ snoopFile.close ();
2128+
2129+ pcpp::SnoopFileReaderDevice readerDev (snoopFile.getFileName ());
2130+ PTF_ASSERT_TRUE (readerDev.open ());
2131+ pcpp::RawPacket rawPacket;
2132+ PTF_ASSERT_FALSE (readerDev.getNextPacket (rawPacket));
2133+ PTF_ASSERT_EQUAL (pcpp::Logger::getInstance ().getLastError (), " Failed to read packet data" );
2134+ }
19562135} // TestSolarisSnoopFileRead
19572136
19582137PTF_TEST_CASE (TestPcapFileWriterDeviceDestructor)
0 commit comments