#include #include #include #include #include "icmpv6.h" #include "ethernetII.h" #include "ip.h" #include "tcp.h" #include "utils.h" #include "rawpdu.h" #include "hw_address.h" using namespace Tins; class ICMPv6Test : public testing::Test { public: static const uint8_t expected_packet[]; static const uint8_t expected_packet1[]; static const uint8_t expected_packet2[]; static const uint8_t packet_with_extensions[]; static const uint8_t packet_with_extensions_and_length[]; static const uint8_t mld2_icmpv6_layer[]; static const uint8_t mlqm_icmpv6_layer[]; void test_equals(const ICMPv6& icmp1, const ICMPv6& icmp2); }; const uint8_t ICMPv6Test::expected_packet[] = { 136, 0, 220, 21, 192, 0, 0, 0, 63, 254, 5, 7, 0, 0, 0, 1, 2, 96, 151, 255, 254, 7, 105, 234 }; const uint8_t ICMPv6Test::expected_packet1[] = { 134, 0, 70, 37, 64, 0, 7, 8, 0, 0, 117, 48, 0, 0, 3, 232, 1, 1, 0, 96, 151, 7, 105, 234, 5, 1, 0, 0, 0, 0, 5, 220, 3, 4, 64, 192, 0, 54, 238, 128, 0, 54, 238, 128, 0, 0, 0, 0, 63, 254, 5, 7, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 }; const uint8_t ICMPv6Test::expected_packet2[] = { 0, 96, 151, 7, 105, 234, 0, 0, 134, 5, 128, 218, 134, 221, 96, 0, 0, 0, 0, 32, 58, 255, 254, 128, 0, 0, 0, 0, 0, 0, 2, 0, 134, 255 , 254, 5, 128, 218, 254, 128, 0, 0, 0, 0, 0, 0, 2, 96, 151, 255, 254, 7, 105, 234, 135, 0, 0, 0, 0, 0, 0, 0, 254, 128, 0, 0, 0 , 0, 0, 0, 2, 96, 151, 255, 254, 7, 105, 234, 1, 1, 0, 0, 134, 5, 128, 218 }; const uint8_t ICMPv6Test::packet_with_extensions[] = { 3, 0, 139, 66, 0, 0, 0, 0, 96, 0, 0, 0, 0, 38, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 12, 0, 99, 0, 38, 45, 93, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 197, 95, 0, 8, 1, 1, 24, 150, 1, 1 }; const uint8_t ICMPv6Test::packet_with_extensions_and_length[] = { 3, 0, 139, 66, 16, 0, 0, 0, 96, 0, 0, 0, 0, 38, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 12, 0, 99, 0, 38, 45, 93, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 197, 95, 0, 8, 1, 1, 24, 150, 1, 1 }; const uint8_t ICMPv6Test::mld2_icmpv6_layer[] = { 143, 0, 0, 0, 0, 0, 0, 1, 1, 2, 0, 8, 255, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 255, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 255, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 255, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 255, 0, 0, 9, 222, 173, 190, 239, 190, 173, 254, 237 }; // Multicast Listener Query Message const uint8_t ICMPv6Test::mlqm_icmpv6_layer[] = { 130, 0, 0, 0, 0, 0, 0, 0, 255, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 255, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 255, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 255, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 255, 0, 0, 9 }; TEST_F(ICMPv6Test, Constructor) { ICMPv6 icmp; EXPECT_EQ(icmp.type(), ICMPv6::ECHO_REQUEST); EXPECT_EQ(icmp.code(), 0); EXPECT_EQ(icmp.checksum(), 0); EXPECT_EQ(icmp.identifier(), 0); EXPECT_EQ(icmp.sequence(), 0); EXPECT_EQ(icmp.override(), 0); EXPECT_EQ(icmp.solicited(), 0); EXPECT_EQ(icmp.router(), 0); EXPECT_EQ(icmp.hop_limit(), 0); EXPECT_EQ(icmp.router_pref(), 0); EXPECT_EQ(icmp.home_agent(), 0); EXPECT_EQ(icmp.other(), 0); EXPECT_EQ(icmp.managed(), 0); EXPECT_EQ(icmp.router_lifetime(), 0); } TEST_F(ICMPv6Test, ConstructorFromBuffer) { ICMPv6 icmp(expected_packet, sizeof(expected_packet)); EXPECT_EQ(icmp.type(), ICMPv6::NEIGHBOUR_ADVERT); EXPECT_EQ(icmp.code(), 0); EXPECT_EQ(icmp.checksum(), 0xdc15); EXPECT_EQ(icmp.solicited(), 1); EXPECT_EQ(icmp.router(), 1); EXPECT_EQ(icmp.override(), 0); EXPECT_EQ(icmp.target_addr(), "3ffe:507:0:1:260:97ff:fe07:69ea"); } TEST_F(ICMPv6Test, ConstructorFromBuffer2) { ICMPv6 icmp(expected_packet1, sizeof(expected_packet1)); EXPECT_EQ(icmp.type(), ICMPv6::ROUTER_ADVERT); EXPECT_EQ(icmp.code(), 0); EXPECT_EQ(icmp.checksum(), 0x4625); EXPECT_EQ(icmp.managed(), 0); EXPECT_EQ(icmp.home_agent(), 0); EXPECT_EQ(icmp.other(), 0); EXPECT_EQ(icmp.router_pref(), 0); EXPECT_EQ(icmp.router_lifetime(), 1800); EXPECT_EQ(icmp.reachable_time(), 30000U); EXPECT_EQ(icmp.retransmit_timer(), 1000U); const ICMPv6::option* opt = icmp.search_option(ICMPv6::SOURCE_ADDRESS); ASSERT_TRUE(opt != NULL); EXPECT_EQ(opt->data_size(), 6U); EXPECT_EQ(HWAddress<6>(opt->data_ptr()), "00:60:97:07:69:ea"); opt = icmp.search_option(ICMPv6::MTU); ASSERT_TRUE(opt != NULL); EXPECT_EQ(opt->data_size(), 6U); opt = icmp.search_option(ICMPv6::PREFIX_INFO); ASSERT_TRUE(opt != NULL); EXPECT_EQ(opt->data_size(), 30U); } TEST_F(ICMPv6Test, ConstructorFromBuffer_MLD2_Layer) { ICMPv6 icmp(mld2_icmpv6_layer, sizeof(mld2_icmpv6_layer)); ICMPv6::multicast_address_records_list records = icmp.multicast_address_records(); ASSERT_EQ(1UL, records.size()); ICMPv6::multicast_address_record r = *records.begin(); EXPECT_EQ(1, r.type); std::vector aux_data; aux_data.push_back(0xde); aux_data.push_back(0xad); aux_data.push_back(0xbe); aux_data.push_back(0xef); aux_data.push_back(0xbe); aux_data.push_back(0xad); aux_data.push_back(0xfe); aux_data.push_back(0xed); EXPECT_EQ(aux_data, r.aux_data); std::vector sources; sources.push_back("::"); sources.push_back("ff02::1"); sources.push_back("::"); sources.push_back("ff02::1"); sources.push_back("ff02::1"); sources.push_back("ff02::2"); sources.push_back("::1"); sources.push_back("ff02::1:ff00:9"); EXPECT_EQ(sources, r.sources); PDU::serialization_type buffer = icmp.serialize(); EXPECT_EQ( PDU::serialization_type( mld2_icmpv6_layer, mld2_icmpv6_layer + sizeof(mld2_icmpv6_layer) ), buffer ); } TEST_F(ICMPv6Test, ConstructorFromBuffer_MLQM_Layer) { ICMPv6 icmp(mlqm_icmpv6_layer, sizeof(mlqm_icmpv6_layer)); ICMPv6::sources_list sources; sources.push_back("::"); sources.push_back("ff02::1"); sources.push_back("::"); sources.push_back("ff02::1"); sources.push_back("ff02::1"); sources.push_back("ff02::2"); sources.push_back("::1"); sources.push_back("ff02::1:ff00:9"); EXPECT_EQ(sources, icmp.sources()); EXPECT_EQ(0, icmp.supress()); EXPECT_EQ(0, icmp.qrv()); EXPECT_EQ(0, icmp.qqic()); EXPECT_EQ(0, icmp.maximum_response_code()); EXPECT_EQ(IPv6Address("ff02::1"), icmp.multicast_addr()); PDU::serialization_type buffer = icmp.serialize(); EXPECT_EQ( PDU::serialization_type( mlqm_icmpv6_layer, mlqm_icmpv6_layer + sizeof(mlqm_icmpv6_layer) ), buffer ); } TEST_F(ICMPv6Test, Type) { ICMPv6 icmp; icmp.type(ICMPv6::MLD2_REPORT); EXPECT_EQ(icmp.type(), ICMPv6::MLD2_REPORT); } TEST_F(ICMPv6Test, Code) { ICMPv6 icmp; icmp.code(0x7a); EXPECT_EQ(icmp.code(), 0x7a); } TEST_F(ICMPv6Test, Checksum) { ICMPv6 icmp; icmp.checksum(0x827f); EXPECT_EQ(icmp.checksum(), 0x827f); } TEST_F(ICMPv6Test, Identifier) { ICMPv6 icmp; icmp.identifier(0x827f); EXPECT_EQ(icmp.identifier(), 0x827f); } TEST_F(ICMPv6Test, Sequence) { ICMPv6 icmp; icmp.sequence(0x827f); EXPECT_EQ(icmp.sequence(), 0x827f); } TEST_F(ICMPv6Test, Override) { ICMPv6 icmp; icmp.override(1); EXPECT_EQ(icmp.override(), 1); icmp.override(0); EXPECT_EQ(icmp.override(), 0); } TEST_F(ICMPv6Test, Solicited) { ICMPv6 icmp; icmp.solicited(1); EXPECT_EQ(icmp.solicited(), 1); icmp.solicited(0); EXPECT_EQ(icmp.solicited(), 0); } TEST_F(ICMPv6Test, Router) { ICMPv6 icmp; icmp.router(1); EXPECT_EQ(icmp.router(), 1); icmp.router(0); EXPECT_EQ(icmp.router(), 0); } TEST_F(ICMPv6Test, RouterPref) { ICMPv6 icmp; icmp.router_pref(1); EXPECT_EQ(icmp.router_pref(), 1); icmp.router_pref(0); EXPECT_EQ(icmp.router_pref(), 0); } TEST_F(ICMPv6Test, HomeAgent) { ICMPv6 icmp; icmp.home_agent(1); EXPECT_EQ(icmp.home_agent(), 1); icmp.home_agent(0); EXPECT_EQ(icmp.home_agent(), 0); } TEST_F(ICMPv6Test, Other) { ICMPv6 icmp; icmp.other(1); EXPECT_EQ(icmp.other(), 1); icmp.other(0); EXPECT_EQ(icmp.other(), 0); } TEST_F(ICMPv6Test, Managed) { ICMPv6 icmp; icmp.managed(1); EXPECT_EQ(icmp.managed(), 1); icmp.managed(0); EXPECT_EQ(icmp.managed(), 0); } TEST_F(ICMPv6Test, RTLifetime) { ICMPv6 icmp; icmp.router_lifetime(0x827f); EXPECT_EQ(icmp.router_lifetime(), 0x827f); } TEST_F(ICMPv6Test, SourceLinkLayerAddress) { ICMPv6 icmp; icmp.source_link_layer_addr("09:fe:da:fe:22:33"); EXPECT_EQ(icmp.source_link_layer_addr(), "09:fe:da:fe:22:33"); } TEST_F(ICMPv6Test, TargetLinkLayerAddress) { ICMPv6 icmp; icmp.target_link_layer_addr("09:fe:da:fe:22:33"); EXPECT_EQ(icmp.target_link_layer_addr(), "09:fe:da:fe:22:33"); } TEST_F(ICMPv6Test, PrefixInformation) { ICMPv6 icmp; ICMPv6::prefix_info_type result, info(0x8, 1, 0, 0x92038fad, 0x918273fa, "827d:adae::1"); icmp.prefix_info(info); result = icmp.prefix_info(); EXPECT_EQ(result.prefix_len, info.prefix_len); EXPECT_EQ(result.A, info.A); EXPECT_EQ(result.L, info.L); EXPECT_EQ(result.valid_lifetime, info.valid_lifetime); EXPECT_EQ(result.preferred_lifetime, info.preferred_lifetime); EXPECT_EQ(IPv6Address(info.prefix), IPv6Address(result.prefix)); EXPECT_EQ(IPv6Address(result.prefix), "827d:adae::1"); } TEST_F(ICMPv6Test, RedirectHeader) { ICMPv6 icmp; EthernetII eth = EthernetII() / IP("8.8.8.8", "192.168.0.100") / TCP(22, 26); PDU::serialization_type buffer = eth.serialize(); icmp.redirect_header(buffer); EXPECT_EQ(buffer, icmp.redirect_header()); } TEST_F(ICMPv6Test, MTU) { ICMPv6 icmp; ICMPv6::mtu_type data(0x1234, 0x9a8df7); icmp.mtu(data); EXPECT_EQ(data, icmp.mtu()); } TEST_F(ICMPv6Test, ShortcutLimit) { ICMPv6 icmp; ICMPv6::shortcut_limit_type slimit(123); slimit.reserved1 = 0x7f; slimit.reserved2 = 0x12345678; icmp.shortcut_limit(slimit); ICMPv6::shortcut_limit_type sl = icmp.shortcut_limit(); EXPECT_EQ(123, sl.limit); EXPECT_EQ(0x7f, sl.reserved1); EXPECT_EQ(0x12345678U, sl.reserved2); } TEST_F(ICMPv6Test, NewAdvertisementInterval) { ICMPv6 icmp; ICMPv6::new_advert_interval_type adv(0x9a8df7); adv.reserved = 0x1234; icmp.new_advert_interval(adv); ICMPv6::new_advert_interval_type data = icmp.new_advert_interval(); EXPECT_EQ(0x9a8df7U, data.interval); EXPECT_EQ(0x1234, data.reserved); } TEST_F(ICMPv6Test, NewHomeAgentInformation) { ICMPv6 icmp; ICMPv6::new_ha_info_type data; data.push_back(0xfeed); data.push_back(0x92fa); data.push_back(0xaab3); icmp.new_home_agent_info(data); EXPECT_EQ(icmp.new_home_agent_info(), data); } TEST_F(ICMPv6Test, SourceAddressList) { ICMPv6 icmp; ICMPv6::addr_list_type data; data.addresses.push_back("827d:adae::1"); data.addresses.push_back("2929:1234:fefe::2"); icmp.source_addr_list(data); EXPECT_EQ(icmp.source_addr_list().addresses, data.addresses); } TEST_F(ICMPv6Test, TargetAddressList) { ICMPv6 icmp; ICMPv6::addr_list_type data; data.addresses.push_back("827d:adae::1"); data.addresses.push_back("2929:1234:fefe::2"); icmp.target_addr_list(data); EXPECT_EQ(icmp.target_addr_list().addresses, data.addresses); } TEST_F(ICMPv6Test, RSASignature) { ICMPv6 icmp; ICMPv6::rsa_sign_type data, result; // can i haz std::iota? const uint8_t arr[16] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; std::copy(arr, arr + sizeof(arr), data.key_hash); data.signature.push_back(12); data.signature.push_back(15); data.signature.push_back(221); icmp.rsa_signature(data); result = icmp.rsa_signature(); EXPECT_TRUE(std::equal(data.key_hash, data.key_hash + sizeof(data.key_hash), result.key_hash)); // There might be some padding(in this case, there is). ASSERT_LE(data.signature.size(), result.signature.size()); EXPECT_TRUE(std::equal(data.signature.begin(), data.signature.end(), result.signature.begin())); } TEST_F(ICMPv6Test, Timestamp) { ICMPv6 icmp; ICMPv6::timestamp_type ts(0x2837d6aaa231ULL); icmp.timestamp(ts); EXPECT_EQ(ts.timestamp, icmp.timestamp().timestamp); } TEST_F(ICMPv6Test, Nonce) { ICMPv6 icmp; ICMPv6::nonce_type data; data.push_back(22); data.push_back(211); data.push_back(67); icmp.nonce(data); EXPECT_EQ(icmp.nonce(), data); } TEST_F(ICMPv6Test, IPPrefix) { ICMPv6 icmp; ICMPv6::ip_prefix_type data(67, 198, "ff00:0928:ddfa::"), output; icmp.ip_prefix(data); output = icmp.ip_prefix(); EXPECT_EQ(output.option_code, data.option_code); EXPECT_EQ(output.prefix_len, data.prefix_len); EXPECT_EQ(output.address, data.address); } TEST_F(ICMPv6Test, LinkLayerAddress) { ICMPv6 icmp; ICMPv6::lladdr_type data(67), output; data.address.push_back(87); data.address.push_back(22); data.address.push_back(185); icmp.link_layer_addr(data); output = icmp.link_layer_addr(); EXPECT_EQ(output.option_code, data.option_code); ASSERT_LE(data.address.size(), output.address.size()); EXPECT_TRUE(std::equal(data.address.begin(), data.address.end(), output.address.begin())); } TEST_F(ICMPv6Test, NAACK) { ICMPv6 icmp; ICMPv6::naack_type data(0x92, 0xb3), result; icmp.naack(data); result = icmp.naack(); EXPECT_EQ(result.code, data.code); EXPECT_EQ(result.status, data.status); } TEST_F(ICMPv6Test, MAP) { ICMPv6 icmp; ICMPv6::map_type data(0x9, 0xb, 1, 0x9283719, "f029:adde::1"), output; icmp.map(data); output = icmp.map(); EXPECT_EQ(output.dist, data.dist); EXPECT_EQ(output.pref, data.pref); EXPECT_EQ(output.r, data.r); EXPECT_EQ(output.valid_lifetime, data.valid_lifetime); EXPECT_EQ(output.address, data.address); } TEST_F(ICMPv6Test, RouteInfo) { ICMPv6 icmp; ICMPv6::route_info_type data(0x92, 2, 0xf23a8823), output; data.prefix.push_back(98); data.prefix.push_back(52); data.prefix.push_back(44); icmp.route_info(data); output = icmp.route_info(); EXPECT_EQ(output.prefix_len, data.prefix_len); EXPECT_EQ(output.pref, data.pref); EXPECT_EQ(output.route_lifetime, data.route_lifetime); ASSERT_LE(data.prefix.size(), output.prefix.size()); EXPECT_TRUE(std::equal(data.prefix.begin(), data.prefix.end(), output.prefix.begin())); } TEST_F(ICMPv6Test, RecursiveDNSServer) { ICMPv6 icmp; ICMPv6::recursive_dns_type data(0x9283712), output; data.servers.push_back("827d:adae::1"); data.servers.push_back("2929:1234:fefe::2"); icmp.recursive_dns_servers(data); output = icmp.recursive_dns_servers(); EXPECT_EQ(output.lifetime, data.lifetime); EXPECT_EQ(output.servers, data.servers); } TEST_F(ICMPv6Test, HandoverKeyRequest) { ICMPv6 icmp; ICMPv6::handover_key_req_type data(2), output; data.key.push_back(98); data.key.push_back(52); data.key.push_back(44); icmp.handover_key_request(data); output = icmp.handover_key_request(); EXPECT_EQ(output.AT, data.AT); EXPECT_EQ(data.key, output.key); } TEST_F(ICMPv6Test, HandoverKeyReply) { ICMPv6 icmp; ICMPv6::handover_key_reply_type data(0x9283, 2), output; data.key.push_back(98); data.key.push_back(52); data.key.push_back(44); icmp.handover_key_reply(data); output = icmp.handover_key_reply(); EXPECT_EQ(output.AT, data.AT); EXPECT_EQ(output.lifetime, data.lifetime); EXPECT_EQ(data.key, output.key); } TEST_F(ICMPv6Test, HandoverAssistInfo) { ICMPv6 icmp; ICMPv6::handover_assist_info_type data(0x92), output; data.hai.push_back(98); data.hai.push_back(52); data.hai.push_back(44); icmp.handover_assist_info(data); output = icmp.handover_assist_info(); EXPECT_EQ(output.option_code, data.option_code); EXPECT_EQ(data.hai, output.hai); } TEST_F(ICMPv6Test, MobileNodeIdentifier) { ICMPv6 icmp; ICMPv6::mobile_node_id_type data(0x92), output; data.mn.push_back(98); data.mn.push_back(52); data.mn.push_back(44); icmp.mobile_node_identifier(data); output = icmp.mobile_node_identifier(); EXPECT_EQ(output.option_code, data.option_code); EXPECT_EQ(data.mn, output.mn); } TEST_F(ICMPv6Test, DNSSearchList) { ICMPv6 icmp; ICMPv6::dns_search_list_type data(0x9283fd1), output; data.domains.push_back("libtins.sourceforge.net"); data.domains.push_back("www.example.com"); icmp.dns_search_list(data); output = icmp.dns_search_list(); EXPECT_EQ(output.lifetime, data.lifetime); EXPECT_EQ(data.domains, output.domains); } TEST_F(ICMPv6Test, MLD2Fields) { ICMPv6 icmp; ICMPv6::multicast_address_records_list records; ICMPv6::multicast_address_record r; r.type = 1; r.aux_data.push_back(0xde); r.aux_data.push_back(0xad); r.aux_data.push_back(0xbe); r.aux_data.push_back(0xef); r.aux_data.push_back(0xbe); r.aux_data.push_back(0xad); r.aux_data.push_back(0xfe); r.aux_data.push_back(0xed); r.sources.push_back("::"); r.sources.push_back("ff02::1"); r.sources.push_back("::"); r.sources.push_back("ff02::1"); r.sources.push_back("ff02::1"); r.sources.push_back("ff02::2"); r.sources.push_back("::1"); r.sources.push_back("ff02::1:ff00:9"); records.push_back(r); icmp.multicast_address_records(records); ICMPv6::multicast_address_records_list stored_records; stored_records = icmp.multicast_address_records(); ASSERT_EQ(1, stored_records.size()); ICMPv6::multicast_address_record r2 = *stored_records.begin(); EXPECT_EQ(r.type, r2.type); EXPECT_EQ(r.sources, r2.sources); EXPECT_EQ(r.aux_data, r2.aux_data); } TEST_F(ICMPv6Test, MLQMFields) { ICMPv6 icmp; ICMPv6::sources_list sources; sources.push_back("::"); sources.push_back("ff02::1"); icmp.sources(sources); icmp.qrv(3); icmp.maximum_response_code(0x928a); icmp.supress(1); icmp.qqic(0xa8); icmp.multicast_addr("feed::beef"); EXPECT_EQ(sources, icmp.sources()); EXPECT_EQ(1, icmp.supress()); EXPECT_EQ(3, icmp.qrv()); EXPECT_EQ(0xa8, icmp.qqic()); EXPECT_EQ(0x928a, icmp.maximum_response_code()); EXPECT_EQ(IPv6Address("feed::beef"), icmp.multicast_addr()); } TEST_F(ICMPv6Test, SpoofedOptions) { ICMPv6 pdu; uint8_t a[] = { 1,2,3,4,5,6 }; pdu.add_option( ICMPv6::option(ICMPv6::NAACK, 250, a, a + sizeof(a)) ); pdu.add_option( ICMPv6::option(ICMPv6::NAACK, 250, a, a + sizeof(a)) ); pdu.add_option( ICMPv6::option(ICMPv6::NAACK, 250, a, a + sizeof(a)) ); // probably we'd expect it to crash if it's not working, valgrind plx EXPECT_EQ(3U, pdu.options().size()); EXPECT_EQ(pdu.serialize().size(), pdu.size()); } TEST_F(ICMPv6Test, ChecksumCalculation) { EthernetII eth(expected_packet2, sizeof(expected_packet2)); EthernetII::serialization_type serialized = eth.serialize(); const ICMPv6& icmp = eth.rfind_pdu(); EXPECT_EQ(0x68bd, icmp.checksum()); } TEST_F(ICMPv6Test, RemoveOption) { ICMPv6 icmp; PDU::serialization_type old_buffer = icmp.serialize(); ICMPv6::recursive_dns_type data(0x9283712); data.servers.push_back("827d:adae::1"); data.servers.push_back("2929:1234:fefe::2"); icmp.recursive_dns_servers(data); icmp.timestamp(0x2837d6aaa231ULL); EXPECT_TRUE(icmp.remove_option(ICMPv6::TIMESTAMP)); EXPECT_TRUE(icmp.remove_option(ICMPv6::RECURSIVE_DNS_SERV)); PDU::serialization_type new_buffer = icmp.serialize(); EXPECT_EQ(old_buffer, new_buffer); } TEST_F(ICMPv6Test, ExtensionsParsingWithoutALengthField) { const uint8_t encapsulated[] = { 96, 0, 0, 0, 0, 38, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 12, 0, 99, 0, 38, 45, 93, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; const uint8_t ext[] = { 0, 8, 1, 1, 24, 150, 1, 1 }; ICMPv6 icmp(packet_with_extensions, sizeof(packet_with_extensions)); ICMPExtensionsStructure extensions = icmp.extensions(); ASSERT_EQ(1, extensions.extensions().size()); EXPECT_EQ( ICMPExtension::payload_type(ext, ext + sizeof(ext)), extensions.extensions().begin()->serialize() ); const RawPDU* raw = icmp.find_pdu(); ASSERT_TRUE(raw != 0); EXPECT_EQ(sizeof(encapsulated), raw->payload().size()); EXPECT_EQ( RawPDU::payload_type(encapsulated, encapsulated + sizeof(encapsulated)), raw->payload() ); } TEST_F(ICMPv6Test, ExtensionsParsingWithALengthField) { const uint8_t encapsulated[] = { 96, 0, 0, 0, 0, 38, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 12, 0, 99, 0, 38, 45, 93, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; const uint8_t ext[] = { 0, 8, 1, 1, 24, 150, 1, 1 }; ICMPv6 icmp(packet_with_extensions_and_length, sizeof(packet_with_extensions_and_length)); ICMPExtensionsStructure extensions = icmp.extensions(); ASSERT_EQ(1, extensions.extensions().size()); EXPECT_EQ( ICMPExtension::payload_type(ext, ext + sizeof(ext)), extensions.extensions().begin()->serialize() ); const RawPDU* raw = icmp.find_pdu(); ASSERT_TRUE(raw != 0); EXPECT_EQ( RawPDU::payload_type(encapsulated, encapsulated + sizeof(encapsulated)), raw->payload() ); }