diff --git a/.gitignore b/.gitignore index 31e3b60..1858299 100644 --- a/.gitignore +++ b/.gitignore @@ -6,5 +6,9 @@ *.lst *.map *.swp + +*.profdata +*.profraw +tests/inputs/ test kernel diff --git a/tests/Makefile b/tests/Makefile index 856a7af..d14a906 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -1,16 +1,16 @@ SRCDIR = ../src TESTDIR = . -SRCOBJS := net-utils.o net-arp.o net-ethernet.o -TESTOBJS := test.o net-arp.o net-utils.o -OBJS := $(addprefix $(TESTDIR)/, $(TESTOBJS)) $(addprefix $(SRCDIR)/, $(SRCOBJS)) +SRCOBJS := $(addprefix $(SRCDIR)/, net-utils.o net-arp.o net-ethernet.o) +TESTOBJS := $(addprefix $(TESTDIR)/, test.o net-arp.o net-utils.o) +OBJS := $(SRCOBJS) $(TESTOBJS) INCLUDE = -I../uspi/include/ -I.. CC := clang CXX := clang++ -CFLAGS += $(ARCH) $(INCLUDE) -MMD -MP -Wall -Wno-psabi -fsigned-char -fno-builtin -g -DNDEBUG +CFLAGS += $(ARCH) $(INCLUDE) -MMD -MP -Wall -Wno-psabi -fsigned-char -fno-builtin -g -DNDEBUG -fprofile-instr-generate -fcoverage-mapping -fsanitize=address,undefined -fno-omit-frame-pointer CXXFLAGS := $(CFLAGS) $(CXXFLAGS) -std=c++11 CFLAGS += -fno-delete-null-pointer-checks -fdata-sections -ffunction-sections -u _printf_float -std=gnu99 @@ -23,8 +23,12 @@ DEPENDS := $(patsubst %.o,%.d,$(OBJS)) all: $(TARGET) +coverage: $(TARGET) + LLVM_PROFILE_FILE="$(TARGET).profraw" ./$(TARGET) + llvm-profdata merge -sparse "$(TARGET).profraw" -o "$(TARGET).profdata" + llvm-cov show ./$(TARGET) -instr-profile="$(TARGET).profdata" ../src + $(TARGET): $(OBJS) - @echo "$(OBJS)" @echo " LINK $@" $(Q)$(CXX) $(CFLAGS) -o $(TARGET) $(OBJS) diff --git a/tests/net-arp.cpp b/tests/net-arp.cpp index 39be104..39d5e83 100644 --- a/tests/net-arp.cpp +++ b/tests/net-arp.cpp @@ -1,3 +1,6 @@ +#include +#include + #define TEST_NO_MAIN #include "acutest.h" @@ -43,18 +46,22 @@ static void netArpCheckSentPacket( TEST_CHECK(packet.targetIp == targetIp); } -void TestNetArpPacket() +void TestNetArpPacketSerializeDeserialize() { constexpr auto expectedSize = Arp::Packet::SerializedLength(); - const auto packet = Arp::Packet(Arp::ARP_OPERATION_REQUEST); + const Arp::Packet packet(Arp::ARP_OPERATION_REQUEST); + // Serialize uint8_t buffer[expectedSize]; - packet.Serialize(buffer, sizeof(buffer)); - - Arp::Packet deserialized; - const auto size = deserialized.Deserialize(buffer, sizeof(buffer)); + auto size = packet.Serialize(buffer, expectedSize); TEST_CHECK(size == expectedSize); + // Deserialize + Arp::Packet deserialized; + size = deserialized.Deserialize(buffer, expectedSize); + TEST_CHECK(size == expectedSize); + + // Check if the packet was deserialized correctly TEST_CHECK(packet.hardwareType == deserialized.hardwareType); TEST_CHECK(packet.protocolType == deserialized.protocolType); TEST_CHECK(packet.hardwareAddressLength == deserialized.hardwareAddressLength); @@ -64,6 +71,10 @@ void TestNetArpPacket() TEST_CHECK(packet.senderIp == deserialized.senderIp); TEST_CHECK(packet.targetMac == deserialized.targetMac); TEST_CHECK(packet.targetIp == deserialized.targetIp); + + // Check serialization and deserialization with a too small buffer + TEST_CHECK(packet.Serialize(buffer, expectedSize - 1) == 0); + TEST_CHECK(deserialized.Deserialize(buffer, expectedSize - 1) == 0); } void TestNetArpSendPacket() @@ -89,3 +100,63 @@ void TestNetArpSendAnnouncement() Arp::SendAnnouncement(senderMac, senderIp); netArpCheckSentPacket(Arp::ARP_OPERATION_REPLY, Utils::MacBroadcast, senderIp); } + +void loadFrame(const std::string path) +{ + std::ifstream stream(path); + stream.read(reinterpret_cast(uspiBuffer), sizeof(uspiBuffer)); +} + +void TestNetArpHandlePacketInvalid() +{ + Ethernet::Header ethernetHeader; + + std::array bufferRef = {}; + auto buffer = bufferRef; + + Arp::HandlePacket(ethernetHeader, buffer.data(), Arp::Packet::SerializedLength() - 1); + TEST_CHECK(buffer == bufferRef); + + Arp::Packet reference(Arp::ARP_OPERATION_REQUEST); + reference.targetIp = Utils::Ipv4Address; + + { + auto packet = reference; + packet.hardwareType = 2; + const auto size = packet.Serialize(bufferRef.data(), bufferRef.size()); + + buffer = bufferRef; + Arp::HandlePacket(ethernetHeader, buffer.data(), size); + TEST_CHECK(buffer == bufferRef); + } + + { + auto packet = reference; + packet.protocolType = static_cast(1337); + const auto size = packet.Serialize(bufferRef.data(), bufferRef.size()); + + buffer = bufferRef; + Arp::HandlePacket(ethernetHeader, buffer.data(), size); + TEST_CHECK(buffer == bufferRef); + } + + { + auto packet = reference; + packet.targetIp = 0xFEEDFEED; + const auto size = packet.Serialize(bufferRef.data(), bufferRef.size()); + + buffer = bufferRef; + Arp::HandlePacket(ethernetHeader, buffer.data(), size); + TEST_CHECK(buffer == bufferRef); + } + + { + auto packet = reference; + packet.operation = static_cast(31337); + const auto size = packet.Serialize(bufferRef.data(), bufferRef.size()); + + buffer = bufferRef; + Arp::HandlePacket(ethernetHeader, buffer.data(), size); + TEST_CHECK(buffer == bufferRef); + } +} diff --git a/tests/net-arp.h b/tests/net-arp.h index 95eefea..0d02595 100644 --- a/tests/net-arp.h +++ b/tests/net-arp.h @@ -1,7 +1,8 @@ #pragma once -void TestNetArpPacket(); +void TestNetArpPacketSerializeDeserialize(); void TestNetArpSendPacket(); void TestNetArpSendRequest(); void TestNetArpSendReply(); void TestNetArpSendAnnouncement(); +void TestNetArpHandlePacketInvalid(); diff --git a/tests/test.cpp b/tests/test.cpp index a53999a..e348239 100644 --- a/tests/test.cpp +++ b/tests/test.cpp @@ -31,10 +31,11 @@ TEST_LIST = { {"Net::Utils::InternetChecksum", TestNetUtilsInternetChecksum}, {"Net::Utils::Crc32", TestNetUtilsCrc32}, {"Net::Utils::GetMacAddress", TestNetUtilsGetMacAddress}, - {"Net::Arp::Packet", TestNetArpPacket}, + {"Net::Arp::PacketSerializeDeserialize", TestNetArpPacketSerializeDeserialize}, {"Net::Arp::SendPacket", TestNetArpSendPacket}, {"Net::Arp::SendRequest", TestNetArpSendRequest}, {"Net::Arp::SendReply", TestNetArpSendReply}, {"Net::Arp::SendAnnouncement", TestNetArpSendAnnouncement}, + {"Net::Arp::HandlePacket Invalid", TestNetArpHandlePacketInvalid}, {nullptr, nullptr}, };