diff --git a/src/utils.cpp b/src/utils.cpp index 3be76ed..37efda5 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -172,16 +172,29 @@ IPv6Address resolve_domain6(const string& to_resolve) { HWAddress<6> resolve_hwaddr(const NetworkInterface& iface, IPv4Address ip, PacketSender& sender) { - IPv4Address my_ip; NetworkInterface::Info info(iface.addresses()); - EthernetII packet = ARP::make_arp_request(ip, info.ip_addr, info.hw_addr); - Internals::smart_ptr::type response(sender.send_recv(packet, iface)); - if (response.get()) { - const ARP* arp_resp = response->find_pdu(); - if (arp_resp) { - return arp_resp->sender_hw_addr(); + #ifdef _WIN32 + // On Windows, use SendARP + IPAddr source; + IPAddr dest; + ULONG hw_address[2]; + ULONG address_length = 6; + source = static_cast(info.ip_addr); + dest = static_cast(ip); + if (SendARP(dest, source, &hw_address, &address_length) == NO_ERROR && address_length == 6) { + return HWAddress<6>((const uint8_t*)hw_address); } - } + #else + // On other platforms, just do the ARP resolution ourselves + EthernetII packet = ARP::make_arp_request(ip, info.ip_addr, info.hw_addr); + Internals::smart_ptr::type response(sender.send_recv(packet, iface)); + if (response.get()) { + const ARP* arp_resp = response->find_pdu(); + if (arp_resp) { + return arp_resp->sender_hw_addr(); + } + } + #endif throw runtime_error("Could not resolve hardware address"); } diff --git a/tests/active_tests/src/utils_test.cpp b/tests/active_tests/src/utils_test.cpp index 77d3199..98e059c 100644 --- a/tests/active_tests/src/utils_test.cpp +++ b/tests/active_tests/src/utils_test.cpp @@ -29,6 +29,7 @@ #include #include +#include #include "utils_tests.h" #include "tins/ethernetII.h" #include "tins/arp.h" @@ -38,6 +39,7 @@ using std::cout; using std::endl; using std::string; using std::vector; +using std::numeric_limits; using std::ostringstream; using Tins::PDU; @@ -52,9 +54,11 @@ ResolveHWAddressTest::ResolveHWAddressTest(const PacketSenderPtr& packet_sender, : ActiveTest(packet_sender, configuration) { vector entries = Tins::Utils::route_entries(); string interface_name = configuration->interface().name(); + int current_metric = numeric_limits::max(); for (const auto& entry : entries) { - if (entry.interface == interface_name && entry.gateway != "0.0.0.0") { + if (entry.interface == interface_name && entry.gateway != "0.0.0.0" && entry.metric < current_metric) { target_address_ = entry.gateway; + current_metric = entry.metric; } } disable_on_platform(Configuration::WINDOWS); @@ -74,6 +78,7 @@ void ResolveHWAddressTest::execute_test() { resolved_address_ = Tins::Utils::resolve_hwaddr(configuration()->interface(), target_address_, *packet_sender()); + cout << log_prefix() << "address resolved to " << resolved_address_ << endl; auto local_ip_address = configuration()->interface().ipv4_address(); auto local_hw_address = configuration()->interface().hw_address(); auto packet = ARP::make_arp_request(target_address_, local_ip_address, local_hw_address);