diff options
Diffstat (limited to 'test/network_tests/malicious_data_tests/malicious_data_test_msg_sender.cpp')
-rw-r--r-- | test/network_tests/malicious_data_tests/malicious_data_test_msg_sender.cpp | 1597 |
1 files changed, 1597 insertions, 0 deletions
diff --git a/test/network_tests/malicious_data_tests/malicious_data_test_msg_sender.cpp b/test/network_tests/malicious_data_tests/malicious_data_test_msg_sender.cpp new file mode 100644 index 0000000..3446ea0 --- /dev/null +++ b/test/network_tests/malicious_data_tests/malicious_data_test_msg_sender.cpp @@ -0,0 +1,1597 @@ +// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <iostream> +#include <memory> +#include <thread> +#include <chrono> +#include <cstring> +#include <future> + +#include <gtest/gtest.h> + +#include <boost/asio.hpp> + +#include <vsomeip/vsomeip.hpp> + +#include "../../implementation/utility/include/byteorder.hpp" +#include "../../implementation/message/include/deserializer.hpp" +#include "../../implementation/service_discovery/include/service_discovery.hpp" +#include "../../implementation/service_discovery/include/message_impl.hpp" +#include "../../implementation/service_discovery/include/constants.hpp" +#include "../../implementation/service_discovery/include/enumeration_types.hpp" +#include "../../implementation/service_discovery/include/eventgroupentry_impl.hpp" +#include "../../implementation/service_discovery/include/serviceentry_impl.hpp" +#include "../../implementation/message/include/message_impl.hpp" +#include "../../implementation/service_discovery/include/option_impl.hpp" +#include "../../implementation/service_discovery/include/ipv4_option_impl.hpp" +#include "malicious_data_test_globals.hpp" + +static char* remote_address; +static char* local_address; + +class malicious_data : public ::testing::Test { +public: + malicious_data() : + work_(std::make_shared<boost::asio::io_context::work>(io_)), + io_thread_(std::bind(&malicious_data::io_run, this)) {} +protected: + + void TearDown() { + work_.reset(); + io_thread_.join(); + io_.stop(); + } + + void io_run() { + io_.run(); + } + + boost::asio::io_context io_; + std::shared_ptr<boost::asio::io_context::work> work_; + std::thread io_thread_; +}; + +TEST_F(malicious_data, send_malicious_events) +{ + std::promise<bool> client_subscribed; + + boost::asio::ip::tcp::socket tcp_socket(io_); + boost::asio::ip::udp::socket udp_socket(io_, + boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 30490)); + + std::thread receive_thread([&](){ + std::atomic<bool> keep_receiving(true); + std::function<void()> receive; + std::vector<std::uint8_t> receive_buffer(4096); + std::vector<vsomeip::event_t> its_received_events; + + const std::function<void(const boost::system::error_code&, std::size_t)> receive_cbk = [&]( + const boost::system::error_code& error, std::size_t bytes_transferred) { + if (error) { + keep_receiving = false; + ADD_FAILURE() << __func__ << " error: " << error.message(); + return; + } + #if 0 + std::stringstream str; + for (size_t i = 0; i < bytes_transferred; i++) { + str << std::hex << std::setw(2) << std::setfill('0') << std::uint32_t(receive_buffer[i]) << " "; + } + std::cout << __func__ << " received: " << std::dec << bytes_transferred << " bytes: " << str.str() << std::endl; + #endif + + vsomeip::deserializer its_deserializer(&receive_buffer[0], bytes_transferred, 0); + vsomeip::service_t its_service = VSOMEIP_BYTES_TO_WORD(receive_buffer[VSOMEIP_SERVICE_POS_MIN], + receive_buffer[VSOMEIP_SERVICE_POS_MAX]); + vsomeip::method_t its_method = VSOMEIP_BYTES_TO_WORD(receive_buffer[VSOMEIP_METHOD_POS_MIN], + receive_buffer[VSOMEIP_METHOD_POS_MAX]); + if (its_service == vsomeip::sd::service && its_method == vsomeip::sd::method) { + vsomeip::sd::message_impl sd_msg; + EXPECT_TRUE(sd_msg.deserialize(&its_deserializer)); + EXPECT_EQ(1u, sd_msg.get_entries().size()); + for (const auto& e : sd_msg.get_entries()) { + if (e->get_type() == vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP) { + EXPECT_TRUE(e->is_eventgroup_entry()); + EXPECT_EQ(vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP, e->get_type()); + EXPECT_EQ(1,e->get_num_options(1)); + EXPECT_EQ(std::uint32_t(0xFFFFFF), e->get_ttl()); + EXPECT_EQ(malicious_data_test::service.service_id, e->get_service()); + EXPECT_EQ(malicious_data_test::service.instance_id, e->get_instance()); + EXPECT_EQ(1u, sd_msg.get_options().size()); + if (e->get_type() == vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP) { + std::shared_ptr<vsomeip::sd::eventgroupentry_impl> its_casted_entry = + std::static_pointer_cast<vsomeip::sd::eventgroupentry_impl>(e); + EXPECT_EQ(1u, its_casted_entry->get_eventgroup()); + } + client_subscribed.set_value(true); + keep_receiving = false; + } + } + } + + + }; + + receive = [&]() { + udp_socket.async_receive(boost::asio::buffer(receive_buffer, receive_buffer.capacity()), + receive_cbk); + }; + + receive(); + while(keep_receiving) { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + }); + + std::thread send_thread([&]() { + try { + std::promise<bool> client_connected; + boost::asio::ip::tcp::socket::endpoint_type local( + boost::asio::ip::address::from_string(std::string(local_address)), + 40001); + boost::asio::ip::tcp::acceptor its_acceptor(io_); + boost::system::error_code ec; + its_acceptor.open(local.protocol(), ec); + boost::asio::detail::throw_error(ec, "acceptor open"); + its_acceptor.set_option(boost::asio::socket_base::reuse_address(true), ec); + boost::asio::detail::throw_error(ec, "acceptor set_option"); + its_acceptor.bind(local, ec); + boost::asio::detail::throw_error(ec, "acceptor bind"); + its_acceptor.listen(boost::asio::socket_base::max_connections, ec); + boost::asio::detail::throw_error(ec, "acceptor listen"); + its_acceptor.async_accept(tcp_socket, [&](boost::system::error_code _error) { + if (!_error) { + // Nagle algorithm off + tcp_socket.set_option(boost::asio::ip::tcp::no_delay(true)); + client_connected.set_value(true); + } else { + ADD_FAILURE() << "accept_cbk: " << _error.message(); + } + }); + + + // offer the service + std::uint8_t its_offer_service_message[] = { + 0xff, 0xff, 0x81, 0x00, + 0x00, 0x00, 0x00, 0x30, // length + 0x00, 0x00, 0x00, 0x01, + 0x01, 0x01, 0x02, 0x00, + 0xc0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10, // length entries array + 0x01, 0x00, 0x00, 0x20, + 0x33, 0x44, 0x00, 0x01, // service / instance + 0x00, 0xff, 0xff, 0xff, // major / ttl + 0x00, 0x00, 0x00, 0x00, // minor + 0x00, 0x00, 0x00, 0x0c, // length options array + 0x00, 0x09, 0x04, 0x00, + 0xff, 0xff, 0xff, 0xff, // slave address + 0x00, 0x06, 0x9c, 0x41, + }; + boost::asio::ip::address its_local_address = + boost::asio::ip::address::from_string(std::string(local_address)); + std::memcpy(&its_offer_service_message[48], &its_local_address.to_v4().to_bytes()[0], 4); + + boost::asio::ip::udp::socket::endpoint_type target_sd( + boost::asio::ip::address::from_string(std::string(remote_address)), + 30490); + udp_socket.send_to(boost::asio::buffer(its_offer_service_message), target_sd); + + // wait until client established TCP connection + if (std::future_status::timeout == client_connected.get_future().wait_for(std::chrono::seconds(10))) { + ADD_FAILURE() << "Client didn't connect within time"; + } + + // wait until client subscribed + if (std::future_status::timeout == client_subscribed.get_future().wait_for(std::chrono::seconds(10))) { + ADD_FAILURE() << "Client didn't subscribe within time"; + } + + // send malicious data as server + std::uint8_t its_malicious_data[] = { + 0x33, 0x44, 0x80, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x11, 0x3f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x24, 0x02, 0x00, 0x4e, 0xb3, 0xe4, 0x7a, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x44, 0x80, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x38, 0x4f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x8a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x24, 0x02, 0x00, 0x4e, 0xb3, 0xe4, 0x7a, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x44, 0x80, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x5f, 0x5f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x8b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x24, 0x02, 0x00, 0x4e, 0xb3, 0xe4, 0x7a, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x44, 0x80, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x86, 0x6f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x24, 0x02, 0x00, 0x4e, 0xb3, 0xe4, 0x7a, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x44, 0x80, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xad, 0x7f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x8d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x24, 0x02, 0x00, 0x4e, 0xb3, 0xe4, 0x7a, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x44, 0x80, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xd4, 0x8f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x24, 0x02, 0x00, 0x4e, 0xb3, 0xe4, 0x7a, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x44, 0x80, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xfb, 0x9f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x24, 0x02, 0x00, 0x4e, 0xb3, 0xe4, 0x7a, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x44, 0x80, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x22, 0xaf, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x24, 0x02, 0x00, 0x4e, 0xb3, 0xe4, 0x7a, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x44, 0x80, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, // payload missing + 0x33, 0x44, 0x80, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x49, 0xbf, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x24, 0x02, 0x00, 0x4e, 0xb3, 0xe4, 0x7a, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x44, 0x80, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x70, 0xcf, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x43, 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x6d, 0x80, 0x00, 0x45, 0x22, 0x80, 0x00, 0x45, 0x3b, 0x80, 0x00, 0x43, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x44, 0x80, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x97, 0xdf, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x93, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x23, 0x99, 0x00, 0x4e, 0xb3, 0xe4, 0x4e, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x48, 0x00, 0x00, 0x45, 0x96, 0x00, 0x00, 0x45, 0x16, 0x00, 0x00, 0x45, 0x22, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x44, 0x80, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x22, 0x91, 0x00, 0x4e, 0xb3, 0xe3, 0xd7, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x83, 0x40, 0x00, 0x44, 0x48, 0x00, 0x00, 0x45, 0x9c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x44, 0x80, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0xe5, 0xff, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x21, 0x6c, 0x00, 0x4e, 0xb3, 0xe3, 0x55, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x00, 0x20, 0x00, 0x44, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x44, 0x80, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x0d, 0x0f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x20, 0xa9, 0x00, 0x4e, 0xb3, 0xe3, 0x56, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x83, 0x40, 0x00, 0x45, 0x6d, 0x80, 0x00, 0x44, 0xfa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x44, 0x80, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x34, 0x1f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x97, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x1f, 0xc6, 0x00, 0x4e, 0xb3, 0xe3, 0x87, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x96, 0x00, 0x00, 0x45, 0x83, 0x40, 0x00, 0x44, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x44, 0x80, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x5b, 0x2f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x1e, 0xf1, 0x00, 0x4e, 0xb3, 0xe3, 0x5e, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x16, 0x00, 0x00, 0x45, 0x9c, 0x40, 0x00, 0x45, 0x22, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x44, 0x80, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x82, 0x3f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x1d, 0xad, 0x00, 0x4e, 0xb3, 0xe3, 0xa8, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x48, 0x00, 0x00, 0x45, 0x16, 0x00, 0x00, 0x44, 0xaf, 0x00, 0x00, 0x45, 0x3b, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x44, 0x80, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xa9, 0x4f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x1d, 0xec, 0x00, 0x4e, 0xb3, 0xe3, 0xd8, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0xa8, 0xc0, 0x00, 0x44, 0xaf, 0x00, 0x00, 0x45, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x44, 0x80, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xd0, 0x5f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x1d, 0xf9, 0x00, 0x4e, 0xb3, 0xe3, 0xdd, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0xfa, 0x00, 0x00, 0x44, 0xfa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x44, 0x80, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xf7, 0x6f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x9c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x1d, 0xf9, 0x00, 0x4e, 0xb3, 0xe3, 0xdd, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x19, 0x20, 0x00, 0x43, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x44, 0x80, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x1e, 0x7f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x9d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x1d, 0xf9, 0x00, 0x4e, 0xb3, 0xe3, 0xdd, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x09, 0x80, 0x00, 0x44, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + tcp_socket.send(boost::asio::buffer(its_malicious_data)); + + // establish second tcp connection as client and send malicious data as well + boost::asio::ip::tcp::socket tcp_socket2(io_); + boost::asio::ip::tcp::socket::endpoint_type remote( + boost::asio::ip::address::from_string(std::string(remote_address)), + 40001); + tcp_socket2.open(remote.protocol()); + tcp_socket2.connect(remote); + std::uint8_t its_malicious_client_data[] = { + 0x33, 0x45, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x11, 0x3f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x24, 0x02, 0x00, 0x4e, 0xb3, 0xe4, 0x7a, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x45, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x38, 0x4f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x8a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x24, 0x02, 0x00, 0x4e, 0xb3, 0xe4, 0x7a, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x45, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x5f, 0x5f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x8b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x24, 0x02, 0x00, 0x4e, 0xb3, 0xe4, 0x7a, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x45, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x86, 0x6f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x24, 0x02, 0x00, 0x4e, 0xb3, 0xe4, 0x7a, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x45, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xad, 0x7f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x8d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x24, 0x02, 0x00, 0x4e, 0xb3, 0xe4, 0x7a, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x45, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xd4, 0x8f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x24, 0x02, 0x00, 0x4e, 0xb3, 0xe4, 0x7a, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x45, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xfb, 0x9f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x24, 0x02, 0x00, 0x4e, 0xb3, 0xe4, 0x7a, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x45, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x22, 0xaf, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x24, 0x02, 0x00, 0x4e, 0xb3, 0xe4, 0x7a, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x45, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, // payload missing + 0x33, 0x45, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x49, 0xbf, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x24, 0x02, 0x00, 0x4e, 0xb3, 0xe4, 0x7a, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x45, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x70, 0xcf, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x43, 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x6d, 0x80, 0x00, 0x45, 0x22, 0x80, 0x00, 0x45, 0x3b, 0x80, 0x00, 0x43, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x45, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x97, 0xdf, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x93, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x23, 0x99, 0x00, 0x4e, 0xb3, 0xe4, 0x4e, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x48, 0x00, 0x00, 0x45, 0x96, 0x00, 0x00, 0x45, 0x16, 0x00, 0x00, 0x45, 0x22, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x45, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x22, 0x91, 0x00, 0x4e, 0xb3, 0xe3, 0xd7, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x83, 0x40, 0x00, 0x44, 0x48, 0x00, 0x00, 0x45, 0x9c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x45, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0xe5, 0xff, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x21, 0x6c, 0x00, 0x4e, 0xb3, 0xe3, 0x55, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x00, 0x20, 0x00, 0x44, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x45, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x0d, 0x0f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x20, 0xa9, 0x00, 0x4e, 0xb3, 0xe3, 0x56, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x83, 0x40, 0x00, 0x45, 0x6d, 0x80, 0x00, 0x44, 0xfa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x45, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x34, 0x1f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x97, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x1f, 0xc6, 0x00, 0x4e, 0xb3, 0xe3, 0x87, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x96, 0x00, 0x00, 0x45, 0x83, 0x40, 0x00, 0x44, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x45, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x5b, 0x2f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x1e, 0xf1, 0x00, 0x4e, 0xb3, 0xe3, 0x5e, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x16, 0x00, 0x00, 0x45, 0x9c, 0x40, 0x00, 0x45, 0x22, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x45, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x82, 0x3f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x1d, 0xad, 0x00, 0x4e, 0xb3, 0xe3, 0xa8, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x48, 0x00, 0x00, 0x45, 0x16, 0x00, 0x00, 0x44, 0xaf, 0x00, 0x00, 0x45, 0x3b, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x45, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xa9, 0x4f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x1d, 0xec, 0x00, 0x4e, 0xb3, 0xe3, 0xd8, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0xa8, 0xc0, 0x00, 0x44, 0xaf, 0x00, 0x00, 0x45, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x45, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xd0, 0x5f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x1d, 0xf9, 0x00, 0x4e, 0xb3, 0xe3, 0xdd, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0xfa, 0x00, 0x00, 0x44, 0xfa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x45, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xf7, 0x6f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x9c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x1d, 0xf9, 0x00, 0x4e, 0xb3, 0xe3, 0xdd, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x19, 0x20, 0x00, 0x43, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x45, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x1e, 0x7f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x9d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x1d, 0xf9, 0x00, 0x4e, 0xb3, 0xe3, 0xdd, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x09, 0x80, 0x00, 0x44, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + tcp_socket2.send(boost::asio::buffer(its_malicious_client_data)); + + std::this_thread::sleep_for(std::chrono::milliseconds(1500)); + // call shutdown method + std::uint8_t shutdown_call[] = { + 0x33, 0x45, 0x14, 0x04, + 0x00, 0x00, 0x00, 0x08, + 0x22, 0x22, 0x00, 0x01, + 0x01, 0x00, 0x00, 0x00 }; + boost::asio::ip::udp::socket::endpoint_type target_service( + boost::asio::ip::address::from_string(std::string(remote_address)), + 30001); + udp_socket.send_to(boost::asio::buffer(shutdown_call), target_service); + } catch (const std::exception& _e) { + ADD_FAILURE() << "catched exception: " << _e.what(); + } + + }); + + send_thread.join(); + receive_thread.join(); + boost::system::error_code ec; + udp_socket.shutdown(boost::asio::socket_base::shutdown_both, ec); + tcp_socket.shutdown(boost::asio::socket_base::shutdown_both, ec); + udp_socket.close(ec); + tcp_socket.close(ec); + +} + +/* + * @test Send a message with an invalid protocol version to the test master + * two times as client and two time as service. Ensure that message with the + * WRONG_PROTOCOL_VERSION is sent back in both cases and that the client + * reestablishes the TCP connection after the service sent an message with an + * invalid protocol version back + */ +TEST_F(malicious_data, send_wrong_protocol_version) +{ + std::promise<void> remote_client_subscribed; + std::promise<void> offer_received; + + boost::asio::ip::tcp::socket tcp_socket(io_); + boost::asio::ip::udp::socket udp_socket(io_, + boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 30490)); + + std::thread sd_receive_thread([&](){ + std::atomic<bool> keep_receiving(true); + std::vector<std::uint8_t> receive_buffer(4096); + std::vector<vsomeip::event_t> its_received_events; + std::atomic<bool> service_offered(false); + std::atomic<bool> client_subscribed(false); + + // join the sd multicast group 224.0.24.1 + udp_socket.set_option(boost::asio::ip::multicast::join_group( + boost::asio::ip::address::from_string("224.0.24.1").to_v4())); + + while (keep_receiving) { + boost::system::error_code error; + std::size_t bytes_transferred = udp_socket.receive( + boost::asio::buffer(receive_buffer, receive_buffer.capacity()), 0, error); + if (error) { + keep_receiving = false; + ADD_FAILURE() << __func__ << " error: " << error.message(); + return; + } else { + vsomeip::deserializer its_deserializer(&receive_buffer[0], bytes_transferred, 0); + vsomeip::service_t its_service = VSOMEIP_BYTES_TO_WORD(receive_buffer[VSOMEIP_SERVICE_POS_MIN], + receive_buffer[VSOMEIP_SERVICE_POS_MAX]); + vsomeip::method_t its_method = VSOMEIP_BYTES_TO_WORD(receive_buffer[VSOMEIP_METHOD_POS_MIN], + receive_buffer[VSOMEIP_METHOD_POS_MAX]); + if (its_service == vsomeip::sd::service && its_method == vsomeip::sd::method) { + vsomeip::sd::message_impl sd_msg; + EXPECT_TRUE(sd_msg.deserialize(&its_deserializer)); + EXPECT_EQ(1u, sd_msg.get_entries().size()); + for (const auto& e : sd_msg.get_entries()) { + if (e->get_type() == vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP && !client_subscribed) { + EXPECT_TRUE(e->is_eventgroup_entry()); + EXPECT_EQ(vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP, e->get_type()); + EXPECT_EQ(1,e->get_num_options(1)); + EXPECT_EQ(std::uint32_t(0xFFFFFF), e->get_ttl()); + EXPECT_EQ(malicious_data_test::service.service_id, e->get_service()); + EXPECT_EQ(malicious_data_test::service.instance_id, e->get_instance()); + EXPECT_EQ(1u, sd_msg.get_options().size()); + if (e->get_type() == vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP) { + std::shared_ptr<vsomeip::sd::eventgroupentry_impl> its_casted_entry = + std::static_pointer_cast<vsomeip::sd::eventgroupentry_impl>(e); + EXPECT_EQ(1u, its_casted_entry->get_eventgroup()); + } + remote_client_subscribed.set_value(); + client_subscribed = true; + } else if (e->get_type() == vsomeip::sd::entry_type_e::OFFER_SERVICE && !service_offered) { + EXPECT_TRUE(e->is_service_entry()); + EXPECT_EQ(vsomeip::sd::entry_type_e::OFFER_SERVICE, e->get_type()); + EXPECT_EQ(2,e->get_num_options(1)); + EXPECT_EQ(std::uint32_t(0xFFFFFF), e->get_ttl()); + EXPECT_EQ(malicious_data_test::service.service_id + 1u, e->get_service()); + EXPECT_EQ(malicious_data_test::service.instance_id, e->get_instance()); + EXPECT_EQ(2u, sd_msg.get_options().size()); + if (e->get_type() == vsomeip::sd::entry_type_e::OFFER_SERVICE) { + std::shared_ptr<vsomeip::sd::serviceentry_impl> its_casted_entry = + std::static_pointer_cast<vsomeip::sd::serviceentry_impl>(e); + EXPECT_EQ(0u, its_casted_entry->get_minor_version()); + } + offer_received.set_value(); + service_offered = true; + } + } + if (service_offered && client_subscribed) { + keep_receiving = false; + } + } else { + ADD_FAILURE() << " received non-sd message"; + } + } + } + }); + + std::thread send_thread([&]() { + try { + std::promise<void> client_connected; + boost::asio::ip::tcp::socket::endpoint_type local( + boost::asio::ip::address::from_string(std::string(local_address)), + 40001); + boost::asio::ip::tcp::acceptor its_acceptor(io_); + boost::system::error_code ec; + its_acceptor.open(local.protocol(), ec); + boost::asio::detail::throw_error(ec, "acceptor open"); + its_acceptor.set_option(boost::asio::socket_base::reuse_address(true), ec); + boost::asio::detail::throw_error(ec, "acceptor set_option"); + its_acceptor.bind(local, ec); + boost::asio::detail::throw_error(ec, "acceptor bind"); + its_acceptor.listen(boost::asio::socket_base::max_connections, ec); + boost::asio::detail::throw_error(ec, "acceptor listen"); + its_acceptor.async_accept(tcp_socket, [&](boost::system::error_code _error) { + if (!_error) { + // Nagle algorithm off + tcp_socket.set_option(boost::asio::ip::tcp::no_delay(true)); + client_connected.set_value(); + } else { + ADD_FAILURE() << "accept_cbk: " << _error.message(); + } + }); + + + // offer the service + std::uint8_t its_offer_service_message[] = { + 0xff, 0xff, 0x81, 0x00, + 0x00, 0x00, 0x00, 0x30, // length + 0x00, 0x00, 0x00, 0x01, + 0x01, 0x01, 0x02, 0x00, + 0xc0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10, // length entries array + 0x01, 0x00, 0x00, 0x20, + 0x33, 0x44, 0x00, 0x01, // service / instance + 0x00, 0xff, 0xff, 0xff, // major / ttl + 0x00, 0x00, 0x00, 0x00, // minor + 0x00, 0x00, 0x00, 0x0c, // length options array + 0x00, 0x09, 0x04, 0x00, + 0xff, 0xff, 0xff, 0xff, // slave address + 0x00, 0x06, 0x9c, 0x41, + }; + boost::asio::ip::address its_local_address = + boost::asio::ip::address::from_string(std::string(local_address)); + std::memcpy(&its_offer_service_message[48], &its_local_address.to_v4().to_bytes()[0], 4); + + boost::asio::ip::udp::socket::endpoint_type target_sd( + boost::asio::ip::address::from_string(std::string(remote_address)), + 30490); + udp_socket.send_to(boost::asio::buffer(its_offer_service_message), target_sd); + + // wait until client established TCP connection + if (std::future_status::timeout == client_connected.get_future().wait_for(std::chrono::seconds(10))) { + ADD_FAILURE() << "Client didn't connect within time"; + } + + // wait until client subscribed + if (std::future_status::timeout == remote_client_subscribed.get_future().wait_for(std::chrono::seconds(10))) { + ADD_FAILURE() << "Client didn't subscribe within time"; + } + + // wait until a offer was received + if (std::future_status::timeout == offer_received.get_future().wait_for(std::chrono::seconds(10))) { + ADD_FAILURE() << "Didn't receive offer within time"; + } + + std::atomic<std::uint32_t> fin_as_service_received(0); + std::promise<void> client_reconnected1; + + std::thread tcp_receive_thread([&]() { + std::atomic<bool> keep_receiving(true); + std::vector<std::uint8_t> receive_buffer(4096); + + while (keep_receiving) { + boost::system::error_code error; + tcp_socket.receive( + boost::asio::buffer(receive_buffer, receive_buffer.capacity()), 0, error); + if (error == boost::asio::error::eof) { + EXPECT_EQ(boost::asio::error::eof, error); + fin_as_service_received++; + keep_receiving = false; + } else { + keep_receiving = false; + ADD_FAILURE() << __func__ << ":" << __LINE__ << " error: " << error.message(); + return; + } + } + }); + + boost::asio::ip::tcp::socket tcp_socket3(io_); + its_acceptor.async_accept(tcp_socket3, [&](boost::system::error_code _error) { + if (!_error) { + // Nagle algorithm off + tcp_socket3.set_option(boost::asio::ip::tcp::no_delay(true)); + client_reconnected1.set_value(); + } else { + ADD_FAILURE() << "accept_cbk2: " << _error.message(); + } + }); + // send malicious data as server (too long length and wrong protocol version) + std::uint8_t its_malicious_data[] = { + 0x33, 0x45, 0x00, 0x01, + 0x00, 0x00, 0x07, 0x7f, + 0xBB, 0xBB, 0xCA, 0xFE, + 0xAA, 0x00, 0x00, 0x00 // protocol version set to 0xAA + }; + tcp_socket.send(boost::asio::buffer(its_malicious_data)); + + // wait until client reestablished TCP connection + if (std::future_status::timeout == client_reconnected1.get_future().wait_for(std::chrono::seconds(10))) { + tcp_socket3.shutdown(boost::asio::socket_base::shutdown_both, ec); + tcp_socket3.close(ec); + ADD_FAILURE() << "Client didn't reconnect within time 1"; + } + + tcp_receive_thread.join(); + + EXPECT_EQ(1u, fin_as_service_received); + + std::thread tcp_receive_thread2([&]() { + std::atomic<bool> keep_receiving(true); + std::vector<std::uint8_t> receive_buffer(4096); + while (keep_receiving) { + boost::system::error_code error; + tcp_socket3.receive( + boost::asio::buffer(receive_buffer, receive_buffer.capacity()), 0, error); + if (error == boost::asio::error::eof) { + EXPECT_EQ(boost::asio::error::eof, error); + fin_as_service_received++; + // client must sent back error response before closing the connection + EXPECT_EQ(2u, fin_as_service_received); + if (fin_as_service_received == 2) { + keep_receiving = false; + } + } else { + keep_receiving = false; + return; + } + } + }); + + // send malicious data as server (wrong protocol version) + std::uint8_t its_malicious_data_correct_length[] = { + 0x33, 0x45, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x08, + 0xBB, 0xBB, 0xCA, 0xFE, + 0xAA, 0x00, 0x00, 0x00 // protocol version set to 0xAA + }; + tcp_socket3.send(boost::asio::buffer(its_malicious_data_correct_length)); + + tcp_socket3.shutdown(boost::asio::socket_base::shutdown_both, ec); + tcp_socket3.close(ec); + + + tcp_receive_thread2.join(); + EXPECT_EQ(2u, fin_as_service_received); + + // establish second tcp connection as client and send malicious data as well + std::atomic<std::uint32_t> error_response_as_client_received(0); + std::atomic<std::uint32_t> fin_as_client_received(0); + + boost::asio::ip::tcp::socket tcp_socket2(io_); + boost::asio::ip::tcp::socket::endpoint_type remote( + boost::asio::ip::address::from_string(std::string(remote_address)), + 40001); + tcp_socket2.open(remote.protocol()); + tcp_socket2.connect(remote); + + + std::thread tcp_service_receive_thread([&]() { + std::atomic<bool> keep_receiving(true); + std::vector<std::uint8_t> receive_buffer(4096); + while (keep_receiving) { + boost::system::error_code error; + std::size_t bytes_transferred = tcp_socket2.receive( + boost::asio::buffer(receive_buffer, receive_buffer.capacity()), 0, error); + if (!error) { + #if 0 + std::stringstream str; + for (size_t i = 0; i < bytes_transferred; i++) { + str << std::hex << std::setw(2) << std::setfill('0') << std::uint32_t(receive_buffer[i]) << " "; + } + std::cout << __func__ << " received: " << std::dec << bytes_transferred << " bytes: " << str.str() << std::endl; + #endif + vsomeip::deserializer its_deserializer(&receive_buffer[0], bytes_transferred, 0); + std::shared_ptr<vsomeip::message> its_message(its_deserializer.deserialize_message()); + EXPECT_EQ(0x3345, its_message->get_service()); + EXPECT_EQ(0x1, its_message->get_method()); + EXPECT_EQ(0xCCCC, its_message->get_client()); + EXPECT_EQ(0xDDDD, its_message->get_session()); + EXPECT_EQ(vsomeip::return_code_e::E_WRONG_PROTOCOL_VERSION, its_message->get_return_code()); + EXPECT_EQ(vsomeip::message_type_e::MT_ERROR, its_message->get_message_type()); + error_response_as_client_received++; + // service must sent back error response before closing the connection + EXPECT_EQ(error_response_as_client_received - 1u, fin_as_client_received); + } else { + EXPECT_EQ(boost::asio::error::eof, error); + fin_as_client_received++; + // service must sent back error response before closing the connection + EXPECT_EQ(error_response_as_client_received, fin_as_client_received); + if (fin_as_client_received == 1) { + keep_receiving = false; + } + } + } + }); + + // send malicious data as client (too long length and wrong protocol version) + std::uint8_t its_malicious_client_data[] = { + 0x33, 0x45, 0x00, 0x01, + 0x00, 0x00, 0x07, 0x7f, + 0xCC, 0xCC, 0xDD, 0xDD, + 0xAA, 0x00, 0x00, 0x00 // protocol version set to 0xAA + }; + tcp_socket2.send(boost::asio::buffer(its_malicious_client_data)); + tcp_service_receive_thread.join(); + EXPECT_EQ(1u, error_response_as_client_received); + EXPECT_EQ(1u, fin_as_client_received); + + tcp_socket2.shutdown(boost::asio::socket_base::shutdown_both, ec); + tcp_socket2.close(ec); + + // establish a tcp connection as client again and send wrong protocol + // version in message with a correct length field + boost::asio::ip::tcp::socket tcp_socket5(io_); + tcp_socket5.open(remote.protocol()); + tcp_socket5.connect(remote); + + std::thread tcp_service_receive_thread2([&]() { + std::atomic<bool> keep_receiving(true); + std::vector<std::uint8_t> receive_buffer(4096); + while (keep_receiving) { + boost::system::error_code error; + std::size_t bytes_transferred = tcp_socket5.receive( + boost::asio::buffer(receive_buffer, receive_buffer.capacity()), 0, error); + if (!error) { + vsomeip::deserializer its_deserializer(&receive_buffer[0], bytes_transferred, 0); + std::shared_ptr<vsomeip::message> its_message(its_deserializer.deserialize_message()); + EXPECT_EQ(0x3345, its_message->get_service()); + EXPECT_EQ(0x1, its_message->get_method()); + EXPECT_EQ(0xCCCC, its_message->get_client()); + EXPECT_EQ(0xDDDD, its_message->get_session()); + EXPECT_EQ(vsomeip::return_code_e::E_WRONG_PROTOCOL_VERSION, its_message->get_return_code()); + EXPECT_EQ(vsomeip::message_type_e::MT_ERROR, its_message->get_message_type()); + error_response_as_client_received++; + // service must sent back error response before closing the connection + EXPECT_EQ(error_response_as_client_received - 1u, fin_as_client_received); + if (error_response_as_client_received == 2) { + keep_receiving = false; + } + } + } + }); + + // send malicious data as client (wrong protocol version) + std::uint8_t its_malicious_client_data_correct_length[] = { + 0x33, 0x45, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x08, + 0xCC, 0xCC, 0xDD, 0xDD, + 0xAA, 0x00, 0x00, 0x00 // protocol version set to 0xAA + }; + tcp_socket5.send(boost::asio::buffer(its_malicious_client_data_correct_length)); + tcp_service_receive_thread2.join(); + EXPECT_EQ(2u, error_response_as_client_received); + EXPECT_EQ(1u, fin_as_client_received); + + tcp_socket5.shutdown(boost::asio::socket_base::shutdown_both, ec); + tcp_socket5.close(ec); + + // call shutdown method + std::uint8_t shutdown_call[] = { + 0x33, 0x45, 0x14, 0x04, + 0x00, 0x00, 0x00, 0x08, + 0x22, 0x22, 0x00, 0x01, + 0x01, 0x00, 0x00, 0x00 }; + boost::asio::ip::udp::socket::endpoint_type target_service( + boost::asio::ip::address::from_string(std::string(remote_address)), + 30001); + boost::asio::ip::udp::socket udp_socket2(io_, boost::asio::ip::udp::v4()); + udp_socket2.send_to(boost::asio::buffer(shutdown_call), target_service); + udp_socket2.shutdown(boost::asio::socket_base::shutdown_both, ec); + udp_socket2.close(ec); + } catch (const std::exception& _e) { + ADD_FAILURE() << "catched exception: " << _e.what(); + } + + }); + + send_thread.join(); + sd_receive_thread.join(); + boost::system::error_code ec; + udp_socket.shutdown(boost::asio::socket_base::shutdown_both, ec); + tcp_socket.shutdown(boost::asio::socket_base::shutdown_both, ec); + udp_socket.close(ec); + tcp_socket.close(ec); + +} + +/* + * @test Send a message with an invalid message type to the test master + * one time as client and one time as service. Ensure that the client + * reestablishes the TCP connection after the service sent an message with an + * invalid protocol version back + */ +TEST_F(malicious_data, send_wrong_message_type) +{ + std::promise<void> remote_client_subscribed; + std::promise<void> offer_received; + + boost::asio::ip::tcp::socket tcp_socket(io_); + boost::asio::ip::udp::socket udp_socket(io_, + boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 30490)); + + std::thread sd_receive_thread([&](){ + std::atomic<bool> keep_receiving(true); + std::vector<std::uint8_t> receive_buffer(4096); + std::vector<vsomeip::event_t> its_received_events; + std::atomic<bool> service_offered(false); + std::atomic<bool> client_subscribed(false); + + // join the sd multicast group 224.0.24.1 + udp_socket.set_option(boost::asio::ip::multicast::join_group( + boost::asio::ip::address::from_string("224.0.24.1").to_v4())); + + while (keep_receiving) { + boost::system::error_code error; + std::size_t bytes_transferred = udp_socket.receive( + boost::asio::buffer(receive_buffer, receive_buffer.capacity()), 0, error); + if (error) { + keep_receiving = false; + ADD_FAILURE() << __func__ << " error: " << error.message(); + return; + } else { + vsomeip::deserializer its_deserializer(&receive_buffer[0], bytes_transferred, 0); + vsomeip::service_t its_service = VSOMEIP_BYTES_TO_WORD(receive_buffer[VSOMEIP_SERVICE_POS_MIN], + receive_buffer[VSOMEIP_SERVICE_POS_MAX]); + vsomeip::method_t its_method = VSOMEIP_BYTES_TO_WORD(receive_buffer[VSOMEIP_METHOD_POS_MIN], + receive_buffer[VSOMEIP_METHOD_POS_MAX]); + if (its_service == vsomeip::sd::service && its_method == vsomeip::sd::method) { + vsomeip::sd::message_impl sd_msg; + EXPECT_TRUE(sd_msg.deserialize(&its_deserializer)); + EXPECT_EQ(1u, sd_msg.get_entries().size()); + for (const auto& e : sd_msg.get_entries()) { + if (e->get_type() == vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP && !client_subscribed) { + EXPECT_TRUE(e->is_eventgroup_entry()); + EXPECT_EQ(vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP, e->get_type()); + EXPECT_EQ(1,e->get_num_options(1)); + EXPECT_EQ(std::uint32_t(0xFFFFFF), e->get_ttl()); + EXPECT_EQ(malicious_data_test::service.service_id, e->get_service()); + EXPECT_EQ(malicious_data_test::service.instance_id, e->get_instance()); + EXPECT_EQ(1u, sd_msg.get_options().size()); + if (e->get_type() == vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP) { + std::shared_ptr<vsomeip::sd::eventgroupentry_impl> its_casted_entry = + std::static_pointer_cast<vsomeip::sd::eventgroupentry_impl>(e); + EXPECT_EQ(1u, its_casted_entry->get_eventgroup()); + } + remote_client_subscribed.set_value(); + client_subscribed = true; + } else if (e->get_type() == vsomeip::sd::entry_type_e::OFFER_SERVICE && !service_offered) { + EXPECT_TRUE(e->is_service_entry()); + EXPECT_EQ(vsomeip::sd::entry_type_e::OFFER_SERVICE, e->get_type()); + EXPECT_EQ(2,e->get_num_options(1)); + EXPECT_EQ(std::uint32_t(0xFFFFFF), e->get_ttl()); + EXPECT_EQ(malicious_data_test::service.service_id + 1u, e->get_service()); + EXPECT_EQ(malicious_data_test::service.instance_id, e->get_instance()); + EXPECT_EQ(2u, sd_msg.get_options().size()); + if (e->get_type() == vsomeip::sd::entry_type_e::OFFER_SERVICE) { + std::shared_ptr<vsomeip::sd::serviceentry_impl> its_casted_entry = + std::static_pointer_cast<vsomeip::sd::serviceentry_impl>(e); + EXPECT_EQ(0u, its_casted_entry->get_minor_version()); + } + offer_received.set_value(); + service_offered = true; + } + } + if (service_offered && client_subscribed) { + keep_receiving = false; + } + } else { + ADD_FAILURE() << " received non-sd message"; + } + } + } + }); + + std::thread send_thread([&]() { + try { + std::promise<void> client_connected; + boost::asio::ip::tcp::socket::endpoint_type local( + boost::asio::ip::address::from_string(std::string(local_address)), + 40001); + boost::asio::ip::tcp::acceptor its_acceptor(io_); + boost::system::error_code ec; + its_acceptor.open(local.protocol(), ec); + boost::asio::detail::throw_error(ec, "acceptor open"); + its_acceptor.set_option(boost::asio::socket_base::reuse_address(true), ec); + boost::asio::detail::throw_error(ec, "acceptor set_option"); + its_acceptor.bind(local, ec); + boost::asio::detail::throw_error(ec, "acceptor bind"); + its_acceptor.listen(boost::asio::socket_base::max_connections, ec); + boost::asio::detail::throw_error(ec, "acceptor listen"); + its_acceptor.async_accept(tcp_socket, [&](boost::system::error_code _error) { + if (!_error) { + // Nagle algorithm off + tcp_socket.set_option(boost::asio::ip::tcp::no_delay(true)); + client_connected.set_value(); + } else { + ADD_FAILURE() << "accept_cbk: " << _error.message(); + } + }); + + + // offer the service + std::uint8_t its_offer_service_message[] = { + 0xff, 0xff, 0x81, 0x00, + 0x00, 0x00, 0x00, 0x30, // length + 0x00, 0x00, 0x00, 0x01, + 0x01, 0x01, 0x02, 0x00, + 0xc0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10, // length entries array + 0x01, 0x00, 0x00, 0x20, + 0x33, 0x44, 0x00, 0x01, // service / instance + 0x00, 0xff, 0xff, 0xff, // major / ttl + 0x00, 0x00, 0x00, 0x00, // minor + 0x00, 0x00, 0x00, 0x0c, // length options array + 0x00, 0x09, 0x04, 0x00, + 0xff, 0xff, 0xff, 0xff, // slave address + 0x00, 0x06, 0x9c, 0x41, + }; + boost::asio::ip::address its_local_address = + boost::asio::ip::address::from_string(std::string(local_address)); + std::memcpy(&its_offer_service_message[48], &its_local_address.to_v4().to_bytes()[0], 4); + + boost::asio::ip::udp::socket::endpoint_type target_sd( + boost::asio::ip::address::from_string(std::string(remote_address)), + 30490); + udp_socket.send_to(boost::asio::buffer(its_offer_service_message), target_sd); + + // wait until client established TCP connection + if (std::future_status::timeout == client_connected.get_future().wait_for(std::chrono::seconds(10))) { + ADD_FAILURE() << "Client didn't connect within time"; + } + + // wait until client subscribed + if (std::future_status::timeout == remote_client_subscribed.get_future().wait_for(std::chrono::seconds(10))) { + ADD_FAILURE() << "Client didn't subscribe within time"; + } + + // wait until a offer was received + if (std::future_status::timeout == offer_received.get_future().wait_for(std::chrono::seconds(10))) { + ADD_FAILURE() << "Didn't receive offer within time"; + } + + std::atomic<bool> fin_as_service_received(false); + std::promise<void> client_reconnected; + + std::thread tcp_receive_thread([&]() { + std::atomic<bool> keep_receiving(true); + std::vector<std::uint8_t> receive_buffer(4096); + + while (keep_receiving) { + boost::system::error_code error; + tcp_socket.receive( + boost::asio::buffer(receive_buffer, receive_buffer.capacity()), 0, error); + if (!error) { + ADD_FAILURE() << __func__ << ":" << __LINE__ + << " received a non-error:" << error.message(); + } else if (error == boost::asio::error::eof) { + EXPECT_EQ(boost::asio::error::eof, error); + fin_as_service_received = true; + keep_receiving = false; + } else { + keep_receiving = false; + ADD_FAILURE() << __func__ << ":" << __LINE__ << " error: " << error.message(); + return; + } + } + }); + + boost::asio::ip::tcp::socket tcp_socket3(io_); + its_acceptor.async_accept(tcp_socket3, [&](boost::system::error_code _error) { + if (!_error) { + // Nagle algorithm off + tcp_socket.set_option(boost::asio::ip::tcp::no_delay(true)); + client_reconnected.set_value(); + } else { + ADD_FAILURE() << "accept_cbk2: " << _error.message(); + } + }); + // send malicious data as server (too long length and wrong message type) + std::uint8_t its_malicious_data[] = { + 0x33, 0x45, 0x00, 0x01, + 0x00, 0x00, 0x07, 0x7f, + 0xBB, 0xBB, 0xCA, 0xFE, + 0x01, 0x00, 0xAA, 0x00 // message type set to 0xAA + }; + tcp_socket.send(boost::asio::buffer(its_malicious_data)); + + // wait until client reestablished TCP connection + if (std::future_status::timeout == client_reconnected.get_future().wait_for(std::chrono::seconds(10))) { + tcp_socket3.shutdown(boost::asio::socket_base::shutdown_both, ec); + tcp_socket3.close(ec); + ADD_FAILURE() << "Client didn't reconnect within time"; + } else { + tcp_socket3.shutdown(boost::asio::socket_base::shutdown_both, ec); + tcp_socket3.close(ec); + } + + tcp_receive_thread.join(); + + EXPECT_TRUE(fin_as_service_received); + + + // establish second tcp connection as client and send malicious data as well + std::atomic<bool> fin_as_client_received(false); + + boost::asio::ip::tcp::socket tcp_socket2(io_); + boost::asio::ip::tcp::socket::endpoint_type remote( + boost::asio::ip::address::from_string(std::string(remote_address)), + 40001); + tcp_socket2.open(remote.protocol()); + tcp_socket2.connect(remote); + + + std::thread tcp_service_receive_thread([&]() { + std::atomic<bool> keep_receiving(true); + std::function<void()> receive; + std::vector<std::uint8_t> receive_buffer(4096); + + auto receive_cbk = [&](const boost::system::error_code& _error, + std::size_t bytes_transferred) { + (void)bytes_transferred; + if (!_error) { + ADD_FAILURE() << __func__ << ":" << __LINE__ + << " received a non-error:" << _error.message(); + } else { + EXPECT_EQ(boost::asio::error::eof, _error); + fin_as_client_received = true; + keep_receiving = false; + + } + }; + + receive = [&]() { + tcp_socket2.async_receive(boost::asio::buffer(receive_buffer, receive_buffer.capacity()), + receive_cbk); + }; + + while (keep_receiving) { + receive(); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + }); + + // send malicious data as client (too long length and wrong message type) + std::uint8_t its_malicious_client_data[] = { + 0x33, 0x45, 0x00, 0x01, + 0x00, 0x00, 0x07, 0x7f, + 0xCC, 0xCC, 0xDD, 0xDD, + 0x01, 0x00, 0xAA, 0x00 // protocol version set to 0xAA + }; + tcp_socket2.send(boost::asio::buffer(its_malicious_client_data)); + tcp_service_receive_thread.join(); + EXPECT_TRUE(fin_as_client_received); + + tcp_socket2.shutdown(boost::asio::socket_base::shutdown_both, ec); + tcp_socket2.close(ec); + + // call shutdown method + std::uint8_t shutdown_call[] = { + 0x33, 0x45, 0x14, 0x04, + 0x00, 0x00, 0x00, 0x08, + 0x22, 0x22, 0x00, 0x01, + 0x01, 0x00, 0x00, 0x00 }; + boost::asio::ip::udp::socket::endpoint_type target_service( + boost::asio::ip::address::from_string(std::string(remote_address)), + 30001); + boost::asio::ip::udp::socket udp_socket2(io_, boost::asio::ip::udp::v4()); + udp_socket2.send_to(boost::asio::buffer(shutdown_call), target_service); + udp_socket2.shutdown(boost::asio::socket_base::shutdown_both, ec); + udp_socket2.close(ec); + } catch (const std::exception& _e) { + ADD_FAILURE() << "catched exception: " << _e.what(); + } + + }); + + send_thread.join(); + sd_receive_thread.join(); + boost::system::error_code ec; + udp_socket.shutdown(boost::asio::socket_base::shutdown_both, ec); + tcp_socket.shutdown(boost::asio::socket_base::shutdown_both, ec); + udp_socket.close(ec); + tcp_socket.close(ec); + +} + +/* + * @test Send a message with an invalid return code to the test master + * one time as client and one time as service. Ensure that the client + * reestablishes the TCP connection after the service sent an message with an + * invalid protocol version back + */ +TEST_F(malicious_data, send_wrong_return_code) +{ + std::promise<void> remote_client_subscribed; + std::promise<void> offer_received; + + boost::asio::ip::tcp::socket tcp_socket(io_); + boost::asio::ip::udp::socket udp_socket(io_, + boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 30490)); + + std::thread sd_receive_thread([&](){ + std::atomic<bool> keep_receiving(true); + std::vector<std::uint8_t> receive_buffer(4096); + std::vector<vsomeip::event_t> its_received_events; + std::atomic<bool> service_offered(false); + std::atomic<bool> client_subscribed(false); + + // join the sd multicast group 224.0.24.1 + udp_socket.set_option(boost::asio::ip::multicast::join_group( + boost::asio::ip::address::from_string("224.0.24.1").to_v4())); + + while (keep_receiving) { + boost::system::error_code error; + std::size_t bytes_transferred = udp_socket.receive( + boost::asio::buffer(receive_buffer, receive_buffer.capacity()), 0, error); + if (error) { + keep_receiving = false; + ADD_FAILURE() << __func__ << " error: " << error.message(); + return; + } else { + vsomeip::deserializer its_deserializer(&receive_buffer[0], bytes_transferred, 0); + vsomeip::service_t its_service = VSOMEIP_BYTES_TO_WORD(receive_buffer[VSOMEIP_SERVICE_POS_MIN], + receive_buffer[VSOMEIP_SERVICE_POS_MAX]); + vsomeip::method_t its_method = VSOMEIP_BYTES_TO_WORD(receive_buffer[VSOMEIP_METHOD_POS_MIN], + receive_buffer[VSOMEIP_METHOD_POS_MAX]); + if (its_service == vsomeip::sd::service && its_method == vsomeip::sd::method) { + vsomeip::sd::message_impl sd_msg; + EXPECT_TRUE(sd_msg.deserialize(&its_deserializer)); + EXPECT_EQ(1u, sd_msg.get_entries().size()); + for (const auto& e : sd_msg.get_entries()) { + if (e->get_type() == vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP && !client_subscribed) { + EXPECT_TRUE(e->is_eventgroup_entry()); + EXPECT_EQ(vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP, e->get_type()); + EXPECT_EQ(1,e->get_num_options(1)); + EXPECT_EQ(std::uint32_t(0xFFFFFF), e->get_ttl()); + EXPECT_EQ(malicious_data_test::service.service_id, e->get_service()); + EXPECT_EQ(malicious_data_test::service.instance_id, e->get_instance()); + EXPECT_EQ(1u, sd_msg.get_options().size()); + if (e->get_type() == vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP) { + std::shared_ptr<vsomeip::sd::eventgroupentry_impl> its_casted_entry = + std::static_pointer_cast<vsomeip::sd::eventgroupentry_impl>(e); + EXPECT_EQ(1u, its_casted_entry->get_eventgroup()); + } + remote_client_subscribed.set_value(); + client_subscribed = true; + } else if (e->get_type() == vsomeip::sd::entry_type_e::OFFER_SERVICE && !service_offered) { + EXPECT_TRUE(e->is_service_entry()); + EXPECT_EQ(vsomeip::sd::entry_type_e::OFFER_SERVICE, e->get_type()); + EXPECT_EQ(2,e->get_num_options(1)); + EXPECT_EQ(std::uint32_t(0xFFFFFF), e->get_ttl()); + EXPECT_EQ(malicious_data_test::service.service_id + 1u, e->get_service()); + EXPECT_EQ(malicious_data_test::service.instance_id, e->get_instance()); + EXPECT_EQ(2u, sd_msg.get_options().size()); + if (e->get_type() == vsomeip::sd::entry_type_e::OFFER_SERVICE) { + std::shared_ptr<vsomeip::sd::serviceentry_impl> its_casted_entry = + std::static_pointer_cast<vsomeip::sd::serviceentry_impl>(e); + EXPECT_EQ(0u, its_casted_entry->get_minor_version()); + } + offer_received.set_value(); + service_offered = true; + } + } + if (service_offered && client_subscribed) { + keep_receiving = false; + } + } else { + ADD_FAILURE() << " received non-sd message"; + } + } + } + }); + + std::thread send_thread([&]() { + try { + std::promise<void> client_connected; + boost::asio::ip::tcp::socket::endpoint_type local( + boost::asio::ip::address::from_string(std::string(local_address)), + 40001); + boost::asio::ip::tcp::acceptor its_acceptor(io_); + boost::system::error_code ec; + its_acceptor.open(local.protocol(), ec); + boost::asio::detail::throw_error(ec, "acceptor open"); + its_acceptor.set_option(boost::asio::socket_base::reuse_address(true), ec); + boost::asio::detail::throw_error(ec, "acceptor set_option"); + its_acceptor.bind(local, ec); + boost::asio::detail::throw_error(ec, "acceptor bind"); + its_acceptor.listen(boost::asio::socket_base::max_connections, ec); + boost::asio::detail::throw_error(ec, "acceptor listen"); + its_acceptor.async_accept(tcp_socket, [&](boost::system::error_code _error) { + if (!_error) { + // Nagle algorithm off + tcp_socket.set_option(boost::asio::ip::tcp::no_delay(true)); + client_connected.set_value(); + } else { + ADD_FAILURE() << "accept_cbk: " << _error.message(); + } + }); + + + // offer the service + std::uint8_t its_offer_service_message[] = { + 0xff, 0xff, 0x81, 0x00, + 0x00, 0x00, 0x00, 0x30, // length + 0x00, 0x00, 0x00, 0x01, + 0x01, 0x01, 0x02, 0x00, + 0xc0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10, // length entries array + 0x01, 0x00, 0x00, 0x20, + 0x33, 0x44, 0x00, 0x01, // service / instance + 0x00, 0xff, 0xff, 0xff, // major / ttl + 0x00, 0x00, 0x00, 0x00, // minor + 0x00, 0x00, 0x00, 0x0c, // length options array + 0x00, 0x09, 0x04, 0x00, + 0xff, 0xff, 0xff, 0xff, // slave address + 0x00, 0x06, 0x9c, 0x41, + }; + boost::asio::ip::address its_local_address = + boost::asio::ip::address::from_string(std::string(local_address)); + std::memcpy(&its_offer_service_message[48], &its_local_address.to_v4().to_bytes()[0], 4); + + boost::asio::ip::udp::socket::endpoint_type target_sd( + boost::asio::ip::address::from_string(std::string(remote_address)), + 30490); + udp_socket.send_to(boost::asio::buffer(its_offer_service_message), target_sd); + + // wait until client established TCP connection + if (std::future_status::timeout == client_connected.get_future().wait_for(std::chrono::seconds(10))) { + ADD_FAILURE() << "Client didn't connect within time"; + } + + // wait until client subscribed + if (std::future_status::timeout == remote_client_subscribed.get_future().wait_for(std::chrono::seconds(10))) { + ADD_FAILURE() << "Client didn't subscribe within time"; + } + + // wait until a offer was received + if (std::future_status::timeout == offer_received.get_future().wait_for(std::chrono::seconds(10))) { + ADD_FAILURE() << "Didn't receive offer within time"; + } + + std::atomic<bool> fin_as_service_received(false); + std::promise<void> client_reconnected; + + std::thread tcp_receive_thread([&]() { + std::atomic<bool> keep_receiving(true); + std::vector<std::uint8_t> receive_buffer(4096); + + while (keep_receiving) { + boost::system::error_code error; + tcp_socket.receive( + boost::asio::buffer(receive_buffer, receive_buffer.capacity()), 0, error); + if (!error) { + ADD_FAILURE() << __func__ << ":" << __LINE__ + << " received a non-error:" << error.message(); + } else if (error == boost::asio::error::eof) { + EXPECT_EQ(boost::asio::error::eof, error); + fin_as_service_received = true; + keep_receiving = false; + } else { + keep_receiving = false; + ADD_FAILURE() << __func__ << ":" << __LINE__ << " error: " << error.message(); + return; + } + } + }); + + boost::asio::ip::tcp::socket tcp_socket3(io_); + its_acceptor.async_accept(tcp_socket3, [&](boost::system::error_code _error) { + if (!_error) { + // Nagle algorithm off + tcp_socket.set_option(boost::asio::ip::tcp::no_delay(true)); + client_reconnected.set_value(); + } else { + ADD_FAILURE() << "accept_cbk2: " << _error.message(); + } + }); + // send malicious data as server (too long length and wrong return code) + std::uint8_t its_malicious_data[] = { + 0x33, 0x45, 0x00, 0x01, + 0x00, 0x00, 0x07, 0x7f, + 0xBB, 0xBB, 0xCA, 0xFE, + 0x01, 0x00, 0x00, 0xAA // return code set to 0xAA + }; + tcp_socket.send(boost::asio::buffer(its_malicious_data)); + + // wait until client reestablished TCP connection + if (std::future_status::timeout == client_reconnected.get_future().wait_for(std::chrono::seconds(10))) { + tcp_socket3.shutdown(boost::asio::socket_base::shutdown_both, ec); + tcp_socket3.close(ec); + ADD_FAILURE() << "Client didn't reconnect within time"; + } else { + tcp_socket3.shutdown(boost::asio::socket_base::shutdown_both, ec); + tcp_socket3.close(ec); + } + + tcp_receive_thread.join(); + + EXPECT_TRUE(fin_as_service_received); + + + // establish second tcp connection as client and send malicious data as well + std::atomic<bool> fin_as_client_received(false); + + boost::asio::ip::tcp::socket tcp_socket2(io_); + boost::asio::ip::tcp::socket::endpoint_type remote( + boost::asio::ip::address::from_string(std::string(remote_address)), + 40001); + tcp_socket2.open(remote.protocol()); + tcp_socket2.connect(remote); + + + std::thread tcp_service_receive_thread([&]() { + std::atomic<bool> keep_receiving(true); + std::function<void()> receive; + std::vector<std::uint8_t> receive_buffer(4096); + + auto receive_cbk = [&](const boost::system::error_code& _error, + std::size_t bytes_transferred) { + (void)bytes_transferred; + if (!_error) { + ADD_FAILURE() << __func__ << ":" << __LINE__ + << " received a non-error:" << _error.message(); + } else { + EXPECT_EQ(boost::asio::error::eof, _error); + fin_as_client_received = true; + keep_receiving = false; + + } + }; + + receive = [&]() { + tcp_socket2.async_receive(boost::asio::buffer(receive_buffer, receive_buffer.capacity()), + receive_cbk); + }; + + while (keep_receiving) { + receive(); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + }); + + // send malicious data as client (too long length and wrong return code) + std::uint8_t its_malicious_client_data[] = { + 0x33, 0x45, 0x00, 0x01, + 0x00, 0x00, 0x07, 0x7f, + 0xCC, 0xCC, 0xDD, 0xDD, + 0x01, 0x00, 0x00, 0xAA // return version set to 0xAA + }; + tcp_socket2.send(boost::asio::buffer(its_malicious_client_data)); + tcp_service_receive_thread.join(); + EXPECT_TRUE(fin_as_client_received); + + tcp_socket2.shutdown(boost::asio::socket_base::shutdown_both, ec); + tcp_socket2.close(ec); + + // call shutdown method + std::uint8_t shutdown_call[] = { + 0x33, 0x45, 0x14, 0x04, + 0x00, 0x00, 0x00, 0x08, + 0x22, 0x22, 0x00, 0x01, + 0x01, 0x00, 0x00, 0x00 }; + boost::asio::ip::udp::socket::endpoint_type target_service( + boost::asio::ip::address::from_string(std::string(remote_address)), + 30001); + boost::asio::ip::udp::socket udp_socket2(io_, boost::asio::ip::udp::v4()); + udp_socket2.send_to(boost::asio::buffer(shutdown_call), target_service); + udp_socket2.shutdown(boost::asio::socket_base::shutdown_both, ec); + udp_socket2.close(ec); + } catch (const std::exception& _e) { + ADD_FAILURE() << "catched exception: " << _e.what(); + } + + }); + + send_thread.join(); + sd_receive_thread.join(); + boost::system::error_code ec; + udp_socket.shutdown(boost::asio::socket_base::shutdown_both, ec); + tcp_socket.shutdown(boost::asio::socket_base::shutdown_both, ec); + udp_socket.close(ec); + tcp_socket.close(ec); + +} + +/* + * @test Send a message with an invalid protocol version, invalid message type + * and invalid return code via UDP to the test master + * one time as client and one time as service. Ensure that message with the + * WRONG_PROTOCOL_VERSION is sent back in both cases + */ +TEST_F(malicious_data, wrong_header_fields_udp) +{ + std::promise<void> remote_client_subscribed; + std::promise<void> offer_received; + + boost::asio::ip::udp::socket udp_socket(io_, + boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 30490)); + boost::asio::ip::udp::socket udp_socket_service(io_, + boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 40001)); + + boost::asio::ip::udp::endpoint udp_client_info; + boost::asio::ip::udp::endpoint udp_service_info; + + + std::thread sd_receive_thread([&](){ + std::atomic<bool> keep_receiving(true); + std::vector<std::uint8_t> receive_buffer(4096); + std::vector<vsomeip::event_t> its_received_events; + std::atomic<bool> service_offered(false); + std::atomic<bool> client_subscribed(false); + + // join the sd multicast group 224.0.24.1 + udp_socket.set_option(boost::asio::ip::multicast::join_group( + boost::asio::ip::address::from_string("224.0.24.1").to_v4())); + + while (keep_receiving) { + boost::system::error_code error; + std::size_t bytes_transferred = udp_socket.receive( + boost::asio::buffer(receive_buffer, receive_buffer.capacity()), 0, error); + if (error) { + keep_receiving = false; + ADD_FAILURE() << __func__ << " error: " << error.message(); + return; + } else { + vsomeip::deserializer its_deserializer(&receive_buffer[0], bytes_transferred, 0); + vsomeip::service_t its_service = VSOMEIP_BYTES_TO_WORD(receive_buffer[VSOMEIP_SERVICE_POS_MIN], + receive_buffer[VSOMEIP_SERVICE_POS_MAX]); + vsomeip::method_t its_method = VSOMEIP_BYTES_TO_WORD(receive_buffer[VSOMEIP_METHOD_POS_MIN], + receive_buffer[VSOMEIP_METHOD_POS_MAX]); + if (its_service == vsomeip::sd::service && its_method == vsomeip::sd::method) { + vsomeip::sd::message_impl sd_msg; + EXPECT_TRUE(sd_msg.deserialize(&its_deserializer)); + EXPECT_EQ(1u, sd_msg.get_entries().size()); + for (const auto& e : sd_msg.get_entries()) { + if (e->get_type() == vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP && !client_subscribed) { + EXPECT_TRUE(e->is_eventgroup_entry()); + EXPECT_EQ(vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP, e->get_type()); + EXPECT_EQ(1,e->get_num_options(1)); + EXPECT_EQ(std::uint32_t(0xFFFFFF), e->get_ttl()); + EXPECT_EQ(malicious_data_test::service.service_id, e->get_service()); + EXPECT_EQ(malicious_data_test::service.instance_id, e->get_instance()); + EXPECT_EQ(1u, sd_msg.get_options().size()); + if (e->get_type() == vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP) { + std::shared_ptr<vsomeip::sd::eventgroupentry_impl> its_casted_entry = + std::static_pointer_cast<vsomeip::sd::eventgroupentry_impl>(e); + EXPECT_EQ(1u, its_casted_entry->get_eventgroup()); + } + std::shared_ptr<vsomeip::sd::option_impl> op = sd_msg.get_options().front(); + EXPECT_EQ(op->get_type(), vsomeip::sd::option_type_e::IP4_ENDPOINT); + EXPECT_EQ(op->get_length(), 9u); + if (op->get_type() == vsomeip::sd::option_type_e::IP4_ENDPOINT) { + std::shared_ptr<vsomeip::sd::ipv4_option_impl> ip_op + = std::static_pointer_cast<vsomeip::sd::ipv4_option_impl>(op); + EXPECT_EQ(vsomeip::sd::layer_four_protocol_e::UDP, ip_op->get_layer_four_protocol()); + udp_client_info = boost::asio::ip::udp::endpoint( + boost::asio::ip::address_v4(ip_op->get_address()), + ip_op->get_port()); + } + + remote_client_subscribed.set_value(); + client_subscribed = true; + } else if (e->get_type() == vsomeip::sd::entry_type_e::OFFER_SERVICE && !service_offered) { + EXPECT_TRUE(e->is_service_entry()); + EXPECT_EQ(vsomeip::sd::entry_type_e::OFFER_SERVICE, e->get_type()); + EXPECT_EQ(2,e->get_num_options(1)); + EXPECT_EQ(std::uint32_t(0xFFFFFF), e->get_ttl()); + EXPECT_EQ(malicious_data_test::service.service_id + 1u, e->get_service()); + EXPECT_EQ(malicious_data_test::service.instance_id, e->get_instance()); + EXPECT_EQ(2u, sd_msg.get_options().size()); + if (e->get_type() == vsomeip::sd::entry_type_e::OFFER_SERVICE) { + std::shared_ptr<vsomeip::sd::serviceentry_impl> its_casted_entry = + std::static_pointer_cast<vsomeip::sd::serviceentry_impl>(e); + EXPECT_EQ(0u, its_casted_entry->get_minor_version()); + } + for (const auto& op : sd_msg.get_options()) { + EXPECT_EQ(op->get_type(), vsomeip::sd::option_type_e::IP4_ENDPOINT); + EXPECT_EQ(op->get_length(), 9u); + if (op->get_type() == vsomeip::sd::option_type_e::IP4_ENDPOINT) { + std::shared_ptr<vsomeip::sd::ipv4_option_impl> ip_op + = std::static_pointer_cast<vsomeip::sd::ipv4_option_impl>(op); + if (ip_op->get_layer_four_protocol() == vsomeip::sd::layer_four_protocol_e::UDP) { + EXPECT_EQ(vsomeip::sd::layer_four_protocol_e::UDP, ip_op->get_layer_four_protocol()); + udp_service_info = boost::asio::ip::udp::endpoint( + boost::asio::ip::address_v4(ip_op->get_address()), + ip_op->get_port()); + } + } + } + offer_received.set_value(); + service_offered = true; + } + } + if (service_offered && client_subscribed) { + keep_receiving = false; + } + } else { + ADD_FAILURE() << " received non-sd message"; + } + } + } + }); + + std::thread send_thread([&]() { + try { + boost::system::error_code ec; + udp_socket_service.set_option(boost::asio::socket_base::reuse_address(true), ec); + boost::asio::detail::throw_error(ec, "udp_socket_service set_option"); + + // offer the service + std::uint8_t its_offer_service_message[] = { + 0xff, 0xff, 0x81, 0x00, + 0x00, 0x00, 0x00, 0x30, // length + 0x00, 0x00, 0x00, 0x01, + 0x01, 0x01, 0x02, 0x00, + 0xc0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10, // length entries array + 0x01, 0x00, 0x00, 0x20, + 0x33, 0x44, 0x00, 0x01, // service / instance + 0x00, 0xff, 0xff, 0xff, // major / ttl + 0x00, 0x00, 0x00, 0x00, // minor + 0x00, 0x00, 0x00, 0x0c, // length options array + 0x00, 0x09, 0x04, 0x00, + 0xff, 0xff, 0xff, 0xff, // slave address + 0x00, 0x11, 0x9c, 0x41, // offer via udp + }; + boost::asio::ip::address its_local_address = + boost::asio::ip::address::from_string(std::string(local_address)); + std::memcpy(&its_offer_service_message[48], &its_local_address.to_v4().to_bytes()[0], 4); + + boost::asio::ip::udp::socket::endpoint_type target_sd( + boost::asio::ip::address::from_string(std::string(remote_address)), + 30490); + udp_socket.send_to(boost::asio::buffer(its_offer_service_message), target_sd); + + // wait until client subscribed + if (std::future_status::timeout == remote_client_subscribed.get_future().wait_for(std::chrono::seconds(10))) { + ADD_FAILURE() << "Client didn't subscribe within time"; + } + + // wait until a offer was received + if (std::future_status::timeout == offer_received.get_future().wait_for(std::chrono::seconds(10))) { + ADD_FAILURE() << "Didn't receive offer within time"; + } + + // send malicious data as server (wrong protocol version) + std::uint8_t wrong_protocol_data[] = { + 0x33, 0x44, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x08, + 0xAA, 0xAA, 0xCA, 0xFE, + 0xAA, 0x00, 0x00, 0x00 // protocol version set to 0xAA + }; + udp_socket_service.send_to(boost::asio::buffer(wrong_protocol_data), udp_client_info); + + std::uint8_t wrong_message_type_data[] = { + 0x33, 0x44, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x08, + 0xBB, 0xBB, 0xCA, 0xFE, + 0x01, 0x00, 0xBB, 0x00 // message type set to 0xBB + }; + udp_socket_service.send_to(boost::asio::buffer(wrong_message_type_data), udp_client_info); + + std::uint8_t wrong_return_code_data[] = { + 0x33, 0x44, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x08, + 0xCC, 0xCC, 0xCA, 0xFE, + 0x01, 0x00, 0x00, 0xCC // return code set to 0xCC + }; + udp_socket_service.send_to(boost::asio::buffer(wrong_return_code_data), udp_client_info); + + std::uint8_t all_wrong_data[] = { + 0x33, 0x44, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x08, + 0xAA, 0xAA, 0xCA, 0xFE, + 0xAA, 0x00, 0xBB, 0xCC + }; + udp_socket_service.send_to(boost::asio::buffer(all_wrong_data), udp_client_info); + + udp_socket_service.shutdown(boost::asio::socket_base::shutdown_both, ec); + udp_socket_service.close(ec); + + // establish second UDP connection as client and send malicious data as well + std::atomic<bool> error_response_as_client_received(false); + + boost::asio::ip::udp::socket udp_socket_client(io_); + boost::asio::ip::udp::socket::endpoint_type remote( + boost::asio::ip::address::from_string(std::string(remote_address)), + 30001); + udp_socket_client.open(remote.protocol()); + udp_socket_client.connect(remote); + + + std::thread udp_client_receive_thread([&]() { + std::atomic<bool> keep_receiving(true); + std::function<void()> receive; + std::vector<std::uint8_t> receive_buffer(4096); + + auto receive_cbk = [&](const boost::system::error_code& _error, + std::size_t bytes_transferred) { + if (!_error) { + vsomeip::deserializer its_deserializer(&receive_buffer[0], bytes_transferred, 0); + std::shared_ptr<vsomeip::message> its_message(its_deserializer.deserialize_message()); + EXPECT_EQ(0x3345, its_message->get_service()); + EXPECT_EQ(0x1, its_message->get_method()); + EXPECT_EQ(0xCCCC, its_message->get_client()); + EXPECT_EQ(0xDDDD, its_message->get_session()); + EXPECT_EQ(vsomeip::return_code_e::E_WRONG_PROTOCOL_VERSION, its_message->get_return_code()); + EXPECT_EQ(vsomeip::message_type_e::MT_ERROR, its_message->get_message_type()); + error_response_as_client_received = true; + keep_receiving = false; + } else { + ADD_FAILURE() << __func__ << ":" << __LINE__ << " error: " << _error.message(); + return; + } + }; + + receive = [&]() { + udp_socket_client.async_receive(boost::asio::buffer(receive_buffer, receive_buffer.capacity()), + receive_cbk); + }; + + while (keep_receiving) { + receive(); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + }); + + // send malicious data as client (too long length and wrong protocol version) + std::uint8_t wrong_protocol_client_data[] = { + 0x33, 0x45, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x08, + 0xCC, 0xCC, 0xDD, 0xDD, + 0xAA, 0x00, 0x00, 0x00 // protocol version set to 0xAA + }; + udp_socket_client.send_to(boost::asio::buffer(wrong_protocol_client_data), udp_service_info); + + std::uint8_t wrong_message_type_client_data[] = { + 0x33, 0x45, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x08, + 0xCC, 0xCC, 0xDD, 0xDD, + 0x01, 0x00, 0xBB, 0x00 // message type set to 0xBB + }; + udp_socket_client.send_to(boost::asio::buffer(wrong_message_type_client_data), udp_service_info); + + std::uint8_t wrong_return_code_client_data[] = { + 0x33, 0x45, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x08, + 0xCC, 0xCC, 0xDD, 0xDD, + 0x01, 0x00, 0x00, 0xCC // return code set to 0xCC + }; + udp_socket_client.send_to(boost::asio::buffer(wrong_return_code_client_data), udp_service_info); + + std::uint8_t all_wrong_client_data[] = { + 0x33, 0x45, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x08, + 0xCC, 0xCC, 0xDD, 0xDD, + 0xAA, 0x00, 0xBB, 0xCC + }; + udp_socket_client.send_to(boost::asio::buffer(all_wrong_client_data), udp_service_info); + + + udp_client_receive_thread.join(); + EXPECT_TRUE(error_response_as_client_received); + + udp_socket_client.shutdown(boost::asio::socket_base::shutdown_both, ec); + udp_socket_client.close(ec); + + // call shutdown method + std::uint8_t shutdown_call[] = { + 0x33, 0x45, 0x14, 0x04, + 0x00, 0x00, 0x00, 0x08, + 0x22, 0x22, 0x00, 0x01, + 0x01, 0x00, 0x00, 0x00 }; + boost::asio::ip::udp::socket::endpoint_type target_service( + boost::asio::ip::address::from_string(std::string(remote_address)), + 30001); + boost::asio::ip::udp::socket udp_socket2(io_, boost::asio::ip::udp::v4()); + udp_socket2.send_to(boost::asio::buffer(shutdown_call), target_service); + udp_socket2.shutdown(boost::asio::socket_base::shutdown_both, ec); + udp_socket2.close(ec); + } catch (const std::exception& _e) { + ADD_FAILURE() << "catched exception: " << _e.what(); + } + + }); + + send_thread.join(); + sd_receive_thread.join(); + boost::system::error_code ec; + udp_socket.shutdown(boost::asio::socket_base::shutdown_both, ec); + udp_socket.close(ec); +} + +#if defined(__linux__) || defined(ANDROID) +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + if(argc < 3) { + std::cerr << "Please pass an target, local IP address and test mode to this binary like: " + << argv[0] << " 10.0.3.1 10.0.3.202 EVENTS" << std::endl; + exit(1); + } + remote_address = argv[1]; + local_address = argv[2]; + std::string its_testmode = argv[3]; + if (its_testmode == std::string("MALICIOUS_EVENTS")) { + ::testing::GTEST_FLAG(filter) = "*send_malicious_events"; + } else if (its_testmode == std::string("PROTOCOL_VERSION")) { + ::testing::GTEST_FLAG(filter) = "*send_wrong_protocol_version"; + } else if (its_testmode == std::string("MESSAGE_TYPE")) { + ::testing::GTEST_FLAG(filter) = "*send_wrong_message_type"; + } else if (its_testmode == std::string("RETURN_CODE")) { + ::testing::GTEST_FLAG(filter) = "*send_wrong_return_code"; + } else if (its_testmode == std::string("WRONG_HEADER_FIELDS_UDP")) { + ::testing::GTEST_FLAG(filter) = "*wrong_header_fields_udp"; + } + return RUN_ALL_TESTS(); +} +#endif |