123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142 |
- #include "limbo/errc.h"
- #include "limbo/ip/state.hpp"
- #include "limbo/udp/state.hpp"
- #include "test-utils.h"
- using namespace limbo;
- using IpState = ip::State<void>;
- using IpContext = typename IpState::Context;
- using State = udp::State<IpState>;
- using Context = typename State::Context;
- using Packet = typename State::Packet;
- static_assert(!details::has_lower_state_v<IpState>, "check0");
- static_assert(details::has_lower_state_v<State>, "check1");
- static_assert(std::is_same_v<typename Context::LowerContext, IpContext>,
- "check2");
- uint8_t example_raw[]{0x14, 0xe9, 0x14, 0xe9, 0x00, 0x24, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x04, 0x77, 0x70, 0x61, 0x64, 0x05, 0x6c,
- 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x01, 0x00, 0x01};
- auto example_chunk = Chunk(example_raw, sizeof(example_raw));
- uint8_t payload[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x04, 0x77, 0x70, 0x61, 0x64, 0x05, 0x6c, 0x6f,
- 0x63, 0x61, 0x6c, 0x00, 0x00, 0x01, 0x00, 0x01};
- auto payload_chunk = Chunk(payload, sizeof(payload));
- auto src = make_address("10.0.31.124");
- auto dst = make_address("224.0.0.251");
- TEST_CASE("send", "[udp]") {
- char buff[8 + sizeof(payload)];
- auto ip_ctx = IpContext{src, dst, 1, ip::Proto::udp, 0, nullptr};
- auto ctx = Context{5353, 5353, &ip_ctx};
- auto state = State{};
- SECTION("no enough space") {
- auto zero_chunk = Chunk(buff, 0);
- auto result = Packet::send(state, ctx, zero_chunk, payload_chunk);
- REQUIRE(!result);
- CHECK(result.state() == &state);
- CHECK(result.error_code() == (uint32_t)Errc::no_enough_space);
- }
- auto buff_chunk = Chunk(buff, example_chunk.size());
- auto result = Packet::send(state, ctx, buff_chunk, payload_chunk);
- REQUIRE(result);
- auto res_buff = result.consumed();
- CHECK((void *)res_buff.data() == (void *)buff);
- CHECK(res_buff.size() == example_chunk.size());
- CHECK(res_buff == example_chunk);
- }
- TEST_CASE("recv", "[udp]") {
- auto ip_state = IpState();
- auto state = State{};
- auto result = state.recv(example_chunk, &ip_state);
- REQUIRE(result);
- CHECK(result.state() == &state);
- CHECK(result.consumed() == example_chunk);
- auto &packet = state.get_parsed();
- CHECK(packet.source_port == 5353);
- CHECK(packet.dest_port == 5353);
- CHECK(packet.length == example_chunk.size());
- CHECK(packet.checksum == 0);
- CHECK(packet.container == &ip_state.get_parsed());
- CHECK(packet.payload == payload_chunk);
- }
- TEST_CASE("recv/incomplete", "[udp]") {
- auto ip_state = IpState();
- auto state = State{};
- auto empty_chunk = Chunk(example_raw, 0);
- SECTION("less then header sz") {
- auto result = state.recv(Chunk(example_raw, 6), &ip_state);
- CHECK(result);
- CHECK(result.consumed() == empty_chunk);
- CHECK(result.demand() == 2);
- }
- SECTION("incomplete payload") {
- auto chunk = Chunk(example_raw, example_chunk.size() - 1);
- auto result = state.recv(chunk, &ip_state);
- CHECK(result);
- CHECK(result.consumed() == empty_chunk);
- CHECK(result.demand() == 1);
- }
- }
- TEST_CASE("checksums", "[udp]") {
- using State = udp::State<IpState, udp::Opts::validate_checksum>;
- uint8_t example_raw[]{0x00, 0x14, 0x00, 0x0a, 0x00,
- 0x0A, 0x35, 0xC5, 0x48, 0x69};
- auto example_chunk = Chunk(example_raw, sizeof(example_raw));
- auto ip_state = IpState();
- auto &ip = ip_state.get_parsed();
- ip.source = ip::IPv4Address::from_native(0xC0A8001F);
- ip.destination = ip::IPv4Address::from_native(0xC0A8001E);
- auto state = State();
- auto result = state.recv(example_chunk, &ip_state);
- REQUIRE(result);
- CHECK(result.state() == &state);
- CHECK(result.consumed() == example_chunk);
- }
- TEST_CASE("send/recv + checksum", "[udp]") {
- constexpr auto opts =
- udp::Opts::calculate_checksum | udp::Opts::validate_checksum;
- using IpState = ip::State<void>;
- using IpContext = typename IpState::Context;
- using State = udp::State<IpState, opts>;
- using Context = typename State::Context;
- using Packet = typename State::Packet;
- auto ip_state = IpState();
- char buff[8 + sizeof(payload)];
- auto ip_ctx = IpContext{src, dst, 1, ip::Proto::udp, 0, nullptr};
- auto ctx = Context{5353, 5353, &ip_ctx};
- auto state = State{};
- auto buff_chunk = Chunk(buff, example_chunk.size());
- auto result = Packet::send(state, ctx, buff_chunk, payload_chunk);
- REQUIRE(result);
- auto res_buff = result.consumed();
- CHECK((void *)res_buff.data() == (void *)buff);
- CHECK(res_buff.size() == example_chunk.size());
- /* needed for correct pseudo header calculation */
- ip_state.init(0x6155);
- auto &ip_packet = ip_state.get_parsed();
- ip_packet.source = src;
- ip_packet.destination = dst;
- result = state.recv(buff_chunk, &ip_state);
- REQUIRE(result);
- CHECK(result.state() == &state);
- }
|