diff options
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/test_arp.cpp | 89 | ||||
| -rw-r--r-- | tests/test_summarize.cpp | 20 |
2 files changed, 106 insertions, 3 deletions
diff --git a/tests/test_arp.cpp b/tests/test_arp.cpp new file mode 100644 index 0000000..247782b --- /dev/null +++ b/tests/test_arp.cpp @@ -0,0 +1,89 @@ +#include <doctest/doctest.h> + +#include <vector> + +#include "packeteer/net/arp.hpp" + +using namespace packeteer::net; + +namespace { + +std::vector<unsigned char> arp_request() { + return { + 0x00, 0x01, // hardware type = Ethernet + 0x08, 0x00, // protocol type = IPv4 + 0x06, // hardware len = 6 + 0x04, // protocol len = 4 + 0x00, 0x01, // opcode = request + 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0x01, // sender MAC + 10, 0, 0, 1, // sender IP + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // target MAC (unknown, all zero) + 10, 0, 0, 2, // target IP + }; +} + +std::vector<unsigned char> arp_reply() { + return { + 0x00, 0x01, + 0x08, 0x00, + 0x06, + 0x04, + 0x00, 0x02, // opcode = reply + 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0x02, // sender MAC (the one who was asked) + 10, 0, 0, 2, // sender IP + 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0x01, // target MAC (the original requester) + 10, 0, 0, 1, // target IP + }; +} + +} // namespace + +TEST_CASE("parse_arp decodes a request with Ethernet/IPv4 addressing") { + auto arp = parse_arp(arp_request()); + REQUIRE(arp.has_value()); + CHECK(arp->header.opcode == kArpOpRequest); + REQUIRE(arp->sender_ip.has_value()); + REQUIRE(arp->sender_mac.has_value()); + REQUIRE(arp->target_ip.has_value()); + CHECK(arp->sender_ip->bytes == std::array<unsigned char, 4>{10, 0, 0, 1}); + CHECK(arp->target_ip->bytes == std::array<unsigned char, 4>{10, 0, 0, 2}); + CHECK(arp->sender_mac->bytes == std::array<unsigned char, 6>{0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0x01}); +} + +TEST_CASE("parse_arp decodes a reply") { + auto arp = parse_arp(arp_reply()); + REQUIRE(arp.has_value()); + CHECK(arp->header.opcode == kArpOpReply); + REQUIRE(arp->sender_ip.has_value()); + CHECK(arp->sender_ip->bytes == std::array<unsigned char, 4>{10, 0, 0, 2}); +} + +TEST_CASE("parse_arp rejects a truncated header") { + std::vector<unsigned char> bytes(5, 0); + CHECK_FALSE(parse_arp(bytes).has_value()); +} + +TEST_CASE("parse_arp decodes the header but skips addresses for non-Ethernet/IPv4") { + std::vector<unsigned char> bytes = { + 0x00, 0x06, // hardware type = IEEE 802 (arbitrary, just not the common case) + 0x08, 0x00, + 0x08, // hardware len = 8, not 6 + 0x04, + 0x00, 0x01, + }; + auto arp = parse_arp(bytes); + REQUIRE(arp.has_value()); + CHECK(arp->header.hardware_len == 8); + CHECK_FALSE(arp->sender_ip.has_value()); + CHECK_FALSE(arp->sender_mac.has_value()); +} + +TEST_CASE("parse_arp treats a header claiming Ethernet/IPv4 but too short to hold it as header-only") { + std::vector<unsigned char> bytes = { + 0x00, 0x01, 0x08, 0x00, 0x06, 0x04, 0x00, 0x01, + 0xaa, 0xbb, 0xcc, // truncated sender MAC + }; + auto arp = parse_arp(bytes); + REQUIRE(arp.has_value()); + CHECK_FALSE(arp->sender_ip.has_value()); +} diff --git a/tests/test_summarize.cpp b/tests/test_summarize.cpp index ac6f1c0..27e0dd3 100644 --- a/tests/test_summarize.cpp +++ b/tests/test_summarize.cpp @@ -163,13 +163,27 @@ TEST_CASE("summarize_packet reports a truncated Ethernet frame without decoding CHECK(line == "[10 bytes] truncated ethernet frame"); } -TEST_CASE("summarize_packet stops after the Ethernet line for a non-IP ethertype") { +TEST_CASE("summarize_packet stops after the Ethernet line for an unhandled ethertype") { std::vector<unsigned char> bytes = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, - 0x08, 0x06, // ARP, not IPv4/IPv6 + 0x88, 0xCC, // LLDP, not IPv4/IPv6/ARP }; auto line = packeteer::summarize_packet(bytes, DLT_EN10MB); - CHECK(line == "ETH aa:bb:cc:dd:ee:ff -> 11:22:33:44:55:66 ethertype=0x0806"); + CHECK(line == "ETH aa:bb:cc:dd:ee:ff -> 11:22:33:44:55:66 ethertype=0x88cc"); +} + +TEST_CASE("summarize_packet decodes an ARP request end to end") { + std::vector<unsigned char> bytes = { + 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x08, 0x06, // ARP + 0x00, 0x01, 0x08, 0x00, 0x06, 0x04, 0x00, 0x01, + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 10, 0, 0, 1, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 10, 0, 0, 2, + }; + auto line = packeteer::summarize_packet(bytes, DLT_EN10MB); + CHECK(line == + "ETH aa:bb:cc:dd:ee:ff -> 11:22:33:44:55:66 ethertype=0x0806 | " + "ARP who-has 10.0.0.2 tell 10.0.0.1 (aa:bb:cc:dd:ee:ff)"); } TEST_CASE("hex_dump_lines produces one line per 16 bytes, with the right byte count") { |