06-arp.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. #include "limbo/arp/arp_table.hpp"
  2. #include "limbo/arp/state.hpp"
  3. #include "test-utils.h"
  4. using namespace limbo;
  5. uint8_t src_raw[] = {0xbc, 0xa8, 0xa6, 0x83, 0x53, 0x24};
  6. uint8_t dst_raw[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  7. auto ip_src = make_address("192.168.100.15");
  8. auto ip_dst = make_address("192.168.100.3");
  9. auto mac_src = ethernet::MacAddress(src_raw);
  10. auto mac_dst = ethernet::MacAddress(dst_raw);
  11. using State = arp::State<void>;
  12. using Context = typename State::Context;
  13. using Packet = typename State::Packet;
  14. TEST_CASE("send", "[arp]") {
  15. uint8_t example_raw[] = {
  16. 0x00, 0x01, 0x08, 0x00, 0x06, 0x04, 0x00, 0x01, 0xbc, 0xa8,
  17. 0xa6, 0x83, 0x53, 0x24, 0xc0, 0xa8, 0x64, 0x0f, 0x00, 0x00,
  18. 0x00, 0x00, 0x00, 0x00, 0xc0, 0xa8, 0x64, 0x03,
  19. };
  20. auto example_chunk = Chunk(example_raw, sizeof(example_raw));
  21. char buff[sizeof(example_raw)];
  22. auto buff_chunk = Chunk(buff, sizeof(example_raw));
  23. auto ctx = Context{ip_src, ip_dst, mac_src, mac_dst, arp::Operation::request,
  24. nullptr};
  25. auto state = State();
  26. auto result = Packet::send(state, ctx, buff_chunk, {});
  27. REQUIRE(result);
  28. auto res_buff = result.consumed();
  29. CHECK((void *)res_buff.data() == (void *)buff);
  30. CHECK(res_buff.size() == example_chunk.size());
  31. CHECK(res_buff == example_chunk);
  32. }
  33. TEST_CASE("recv/success", "[arp]") {
  34. uint8_t example_raw[] = {
  35. 0x00, 0x01, 0x08, 0x00, 0x06, 0x04, 0x00, 0x01, 0xbc, 0xa8,
  36. 0xa6, 0x83, 0x53, 0x24, 0xc0, 0xa8, 0x64, 0x0f, 0x00, 0x00,
  37. 0x00, 0x00, 0x00, 0x00, 0xc0, 0xa8, 0x64, 0x03,
  38. };
  39. auto example_chunk = Chunk(example_raw, sizeof(example_raw));
  40. auto state = State();
  41. auto result = state.recv(example_chunk, nullptr);
  42. REQUIRE(result);
  43. CHECK(result.consumed() == example_chunk);
  44. CHECK(result.state() == &state);
  45. auto &packet = state.get_parsed();
  46. CHECK(packet.sender_mac == mac_src);
  47. CHECK(packet.target_mac == mac_dst);
  48. CHECK(packet.sender_ip == ip_src);
  49. CHECK(packet.target_ip == ip_dst);
  50. CHECK(packet.target_ip == ip_dst);
  51. CHECK(packet.operation == (uint16_t)arp::Operation::request);
  52. }
  53. TEST_CASE("recv/failure", "[arp]") {
  54. auto state = State();
  55. SECTION("too small packet") {
  56. auto chunk = Chunk(src_raw, 1);
  57. auto result = state.recv(chunk, nullptr);
  58. CHECK(!result);
  59. CHECK(result.state() == &state);
  60. CHECK(result.error_code() == (uint32_t)Errc::arp_malformed);
  61. }
  62. SECTION("wrong signature (unsupported)") {
  63. uint8_t example_raw[] = {
  64. 0x01, 0x01, 0x08, 0x00, 0x06, 0x04, 0x00, 0x01, 0xbc, 0xa8,
  65. 0xa6, 0x83, 0x53, 0x24, 0xc0, 0xa8, 0x64, 0x0f, 0x00, 0x00,
  66. 0x00, 0x00, 0x00, 0x00, 0xc0, 0xa8, 0x64, 0x03,
  67. };
  68. auto chunk = Chunk(example_raw, sizeof(example_raw));
  69. auto result = state.recv(chunk, nullptr);
  70. CHECK(!result);
  71. CHECK(result.state() == &state);
  72. CHECK(result.error_code() == (uint32_t)Errc::arp_unsupported);
  73. }
  74. SECTION("not request nor response") {
  75. uint8_t example_raw[] = {
  76. 0x00, 0x01, 0x08, 0x00, 0x06, 0x04, 0x00, 0x05, 0xbc, 0xa8,
  77. 0xa6, 0x83, 0x53, 0x24, 0xc0, 0xa8, 0x64, 0x0f, 0x00, 0x00,
  78. 0x00, 0x00, 0x00, 0x00, 0xc0, 0xa8, 0x64, 0x03,
  79. };
  80. auto chunk = Chunk(example_raw, sizeof(example_raw));
  81. auto result = state.recv(chunk, nullptr);
  82. CHECK(!result);
  83. CHECK(result.state() == &state);
  84. CHECK(result.error_code() == (uint32_t)Errc::arp_malformed);
  85. }
  86. }
  87. TEST_CASE("arp table", "[arp]") {
  88. using Table = arp::ArpTable<2>;
  89. auto t = Table();
  90. t.update(mac_src, ip_src, 5);
  91. CHECK(*t.get(mac_src, 4) == ip_src);
  92. CHECK(t.get(mac_src, 6) == nullptr);
  93. CHECK(*t.get(ip_src, 4) == mac_src);
  94. CHECK(t.get(ip_src, 6) == nullptr);
  95. CHECK(t.get(ip_dst, 4) == nullptr);
  96. t.update(mac_dst, ip_dst, 10);
  97. CHECK(*t.get(mac_src, 4) == ip_src);
  98. CHECK(t.get(mac_src, 6) == nullptr);
  99. CHECK(*t.get(mac_dst, 4) == ip_dst);
  100. CHECK(*t.get(mac_dst, 6) == ip_dst);
  101. CHECK(t.get(mac_dst, 11) == nullptr);
  102. }