Status genRoute(const struct rt_msghdr *route, const AddressMap &addr_map, Row &r) { r["flags"] = INTEGER(route->rtm_flags); r["mtu"] = INTEGER(route->rtm_rmx.rmx_mtu); if ((route->rtm_addrs & RTA_DST) == RTA_DST) { r["destination"] = ipAsString(addr_map[RTAX_DST]); } if ((route->rtm_addrs & RTA_GATEWAY) == RTA_GATEWAY) { r["gateway"] = ipAsString(addr_map[RTAX_GATEWAY]); } if (r["destination"] == kDefaultRoute) { r["netmask"] = "0"; } else if ((route->rtm_addrs & RTA_NETMASK) == RTA_NETMASK) { addr_map[RTAX_NETMASK]->sa_family = addr_map[RTAX_DST]->sa_family; r["netmask"] = INTEGER(netmaskFromIP(addr_map[RTAX_NETMASK])); } else { if (addr_map[RTAX_DST]->sa_family == AF_INET6) { r["netmask"] = "128"; } else { r["netmask"] = "32"; } } // Fields not supported by OSX routes: r["source"] = ""; r["metric"] = "0"; return Status(0, "OK"); }
void genAddressesFromAddr(const struct ifaddrs *addr, QueryData &results) { std::string dest_address; Row r; r["interface"] = std::string(addr->ifa_name); // Address and mask will appear every time. if (addr->ifa_addr != nullptr) { r["address"] = ipAsString(static_cast<struct sockaddr *>(addr->ifa_addr)); } if (addr->ifa_netmask != nullptr) { r["mask"] = ipAsString(static_cast<struct sockaddr *>(addr->ifa_netmask)); } // The destination address is used for either a broadcast or PtP address. if (addr->ifa_dstaddr != nullptr) { dest_address = ipAsString(static_cast<struct sockaddr *>(addr->ifa_dstaddr)); if ((addr->ifa_flags & IFF_BROADCAST) == IFF_BROADCAST) { r["broadcast"] = dest_address; } else { r["point_to_point"] = dest_address; } } results.push_back(r); }
Status genArp(const struct rt_msghdr *route, const AddressMap &addr_map, Row &r) { if (addr_map[RTAX_DST]->sa_family != AF_INET) { return Status(1, "Not in ARP cache"); } // The cache will always know the address. r["address"] = ipAsString(addr_map[RTAX_DST]); auto sdl = (struct sockaddr_dl *)addr_map[RTA_DST]; if (sdl->sdl_alen > 0) { r["mac"] = macAsString(LLADDR(sdl)); } else { r["mac"] = "incomplete"; } // Note: also possible to detect published. if (route->rtm_rmx.rmx_expire == 0) { r["permanent"] = "1"; } else { r["permanent"] = "0"; } return Status(0, "OK"); }
std::string ipAsString(const struct in_addr* in) { struct sockaddr_in addr; addr.sin_addr = *in; addr.sin_family = AF_INET; addr.sin_port = 0; #ifdef __MAC__ addr.sin_len = sizeof(sockaddr_in); #endif return ipAsString(reinterpret_cast<struct sockaddr*>(&addr)); }