| 1 | // Copyright (C) Microsoft Corporation. All rights reserved. |
| 2 | #include <iostream> |
| 3 | #include "Route.h" |
| 4 | #include "Utils.h" |
| 5 | |
| 6 | Route::Route(int routeFamily, const std::optional<Address>& routeNextHop, int routeInterface, bool isRouteDefault, const std::optional<Address>& routeDestination, int routeMetric) : |
| 7 | family(routeFamily), via(routeNextHop), dev(routeInterface), defaultRoute(isRouteDefault), to(routeDestination), metric(routeMetric) |
| 8 | { |
| 9 | // For onlink routes, ensure the via field is empty |
| 10 | if (via.has_value() && ((family == AF_INET && via->Addr() == "0.0.0.0") || (family == AF_INET6 && via->Addr() == "::"))) |
| 11 | { |
| 12 | via.reset(); |
| 13 | } |
| 14 | } |
| 15 | |
| 16 | std::ostream& operator<<(std::ostream& out, const Route& route) |
| 17 | { |
| 18 | if (route.defaultRoute) |
| 19 | { |
| 20 | out << "default "; |
| 21 | } |
| 22 | |
| 23 | if (route.to.has_value()) |
| 24 | { |
| 25 | out << route.to.value() << " "; |
| 26 | } |
| 27 | |
| 28 | if (route.via.has_value()) |
| 29 | { |
| 30 | out << " via " << route.via.value() << " "; |
| 31 | } |
| 32 | |
| 33 | return out << "dev " << route.dev << " metric " << route.metric; |
| 34 | } |
| 35 | |
| 36 | bool Route::IsOnlink() const |
| 37 | { |
| 38 | return !via.has_value(); |
| 39 | } |
| 40 | |
| 41 | bool Route::IsMulticast() const |
| 42 | { |
| 43 | if (!to.has_value()) |
| 44 | { |
| 45 | return false; |
| 46 | } |
| 47 | |
| 48 | if (family == AF_INET) |
| 49 | { |
| 50 | in_addr address = {}; |
| 51 | Syscall(::inet_pton, to->Family(), to->Addr().c_str(), &address); |
| 52 | return IN_MULTICAST(ntohl(address.s_addr)); |
| 53 | } |
| 54 | |
| 55 | in6_addr address = {}; |
| 56 | Syscall(::inet_pton, to->Family(), to->Addr().c_str(), &address); |
| 57 | return IN6_IS_ADDR_MULTICAST(&address); |
| 58 | } |