From 3d7c8b5684849969aced6fe467c79aeee40a7c1a Mon Sep 17 00:00:00 2001 From: Teddy Reed Date: Fri, 3 Oct 2014 18:00:15 -0700 Subject: [PATCH] [vtable] Unify routes table for OSX/Linux --- osquery/tables/networking/darwin/routes.cpp | 24 ++++++++++----- osquery/tables/networking/linux/routes.cpp | 22 ++++++++++++-- osquery/tables/networking/utils.cpp | 30 +++++++++++++++++++ osquery/tables/networking/utils.h | 3 +- osquery/tables/specs/linux/routes.table | 10 ------- .../tables/specs/{darwin => x}/routes.table | 7 +++-- 6 files changed, 73 insertions(+), 23 deletions(-) delete mode 100644 osquery/tables/specs/linux/routes.table rename osquery/tables/specs/{darwin => x}/routes.table (65%) diff --git a/osquery/tables/networking/darwin/routes.cpp b/osquery/tables/networking/darwin/routes.cpp index 0371ea45..61d03730 100644 --- a/osquery/tables/networking/darwin/routes.cpp +++ b/osquery/tables/networking/darwin/routes.cpp @@ -12,6 +12,7 @@ #include #include +#include #include #include @@ -38,8 +39,7 @@ const std::vector kRouteTypes = { std::make_pair(RTF_STATIC, "static"), std::make_pair(RTF_BLACKHOLE, "blackhole"), std::make_pair(RTF_ROUTER, "router"), - std::make_pair(RTF_PROXY, "proxy"), -}; + std::make_pair(RTF_PROXY, "proxy"), }; InterfaceMap genInterfaceMap() { InterfaceMap ifmap; @@ -55,9 +55,9 @@ InterfaceMap genInterfaceMap() { InterfaceMap::iterator it = ifmap.begin(); for (if_addr = if_addrs; if_addr != NULL; if_addr = if_addr->ifa_next) { if (if_addr->ifa_addr != NULL && if_addr->ifa_addr->sa_family == AF_LINK) { + std::string route_type = std::string(if_addr->ifa_name); sdl = (struct sockaddr_dl *)if_addr->ifa_addr; - ifmap.insert( - it, std::make_pair(sdl->sdl_index, std::string(if_addr->ifa_name))); + ifmap.insert(it, std::make_pair(sdl->sdl_index, route_type)); } } @@ -104,8 +104,8 @@ void genRouteTableType(RouteType type, InterfaceMap ifmap, QueryData &results) { Row r; r["type"] = type.second; + r["flags"] = boost::lexical_cast(route->rtm_flags); - r["use"] = boost::lexical_cast(route->rtm_use); r["mtu"] = boost::lexical_cast(route->rtm_rmx.rmx_mtu); if ((route->rtm_addrs & RTA_DST) == RTA_DST) { @@ -119,12 +119,22 @@ void genRouteTableType(RouteType type, InterfaceMap ifmap, QueryData &results) { } if (kDefaultRoute.compare(r["destination"]) == 0) { - r["netmask"] = kDefaultRoute; + r["netmask"] = "0"; } else if ((route->rtm_addrs & RTA_NETMASK) == RTA_NETMASK) { sa_table[RTAX_NETMASK]->sa_family = sa_table[RTAX_DST]->sa_family; - r["netmask"] = canonical_ip_address(sa_table[RTAX_NETMASK]); + r["netmask"] = boost::lexical_cast( + netmaskFromIP(sa_table[RTAX_NETMASK])); + } else { + if (sa_table[RTA_DST]->sa_family == AF_INET6) { + r["netmask"] = "128"; + } else { + r["netmask"] = "32"; + } } + // Fields not supported by OSX routes: + r["source"] = ""; + r["metric"] = "0"; results.push_back(r); } diff --git a/osquery/tables/networking/linux/routes.cpp b/osquery/tables/networking/linux/routes.cpp index aa7a4146..a2b8992d 100644 --- a/osquery/tables/networking/linux/routes.cpp +++ b/osquery/tables/networking/linux/routes.cpp @@ -85,6 +85,7 @@ void genNetlinkRoutes(const struct nlmsghdr* netlink_msg, QueryData& results) { // Iterate over each route in the netlink message has_destination = false; + r["metric"] = "0"; while (RTA_OK(attr, attr_size)) { switch (attr->rta_type) { case RTA_OIF: @@ -121,9 +122,26 @@ void genNetlinkRoutes(const struct nlmsghdr* netlink_msg, QueryData& results) { } } - // This is the cidr-formatted mask - r["genmask"] = boost::lexical_cast(mask); + // Route type determination + if (message->rtm_type == RTN_UNICAST) { + r["type"] = "gateway"; + } else if (message->rtm_type == RTN_LOCAL) { + r["type"] = "local"; + } else if (message->rtm_type == RTN_BROADCAST) { + r["type"] = "broadcast"; + } else if (message->rtm_type == RTN_ANYCAST) { + r["type"] = "anycast"; + } else { + r["type"] = "other"; + } + r["flags"] = boost::lexical_cast(message->rtm_flags); + + // This is the cidr-formatted mask + r["netmask"] = boost::lexical_cast(mask); + + // Fields not supported by Linux routes: + r["mtu"] = "0"; results.push_back(r); } diff --git a/osquery/tables/networking/utils.cpp b/osquery/tables/networking/utils.cpp index ba640e5a..be1a09b6 100644 --- a/osquery/tables/networking/utils.cpp +++ b/osquery/tables/networking/utils.cpp @@ -37,6 +37,36 @@ std::string canonical_ip_address(const struct sockaddr *in) { return address; } +inline short addBits(unsigned char byte) { + short bits = 0; + for (int i = 7; i >= 0; --i) { + if ((byte & (1 << i)) == 0) { + break; + } + bits++; + } + return bits; +} + +int netmaskFromIP(const struct sockaddr *in) { + int mask = 0; + + if (in->sa_family == AF_INET6) { + struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)in; + for (size_t i = 0; i < 16; i++) { + mask += addBits(in6->sin6_addr.s6_addr[i]); + } + } else { + struct sockaddr_in *in4 = (struct sockaddr_in *)in; + char *address = reinterpret_cast(&in4->sin_addr.s_addr); + for (size_t i = 0; i < 4; i++) { + mask += addBits(address[i]); + } + } + + return mask; +} + std::string canonical_mac_address(const struct ifaddrs *addr) { std::stringstream mac; diff --git a/osquery/tables/networking/utils.h b/osquery/tables/networking/utils.h index 5e9bc77c..cf59128b 100644 --- a/osquery/tables/networking/utils.h +++ b/osquery/tables/networking/utils.h @@ -8,5 +8,6 @@ #include // Return a string representation for an IPv4/IPv6 struct. -std::string canonical_ip_address(const struct sockaddr *); +std::string canonical_ip_address(const struct sockaddr *in); std::string canonical_mac_address(const struct ifaddrs *addr); +int netmaskFromIP(const struct sockaddr *in); \ No newline at end of file diff --git a/osquery/tables/specs/linux/routes.table b/osquery/tables/specs/linux/routes.table deleted file mode 100644 index f6d53b60..00000000 --- a/osquery/tables/specs/linux/routes.table +++ /dev/null @@ -1,10 +0,0 @@ -table_name("routes") -schema([ - Column(name="destination", type="std::string"), - Column(name="genmask", type="std::string"), - Column(name="gateway", type="std::string"), - Column(name="source", type="std::string"), - Column(name="interface", type="std::string"), - Column(name="metric", type="std::string"), -]) -implementation("routes@genRoutes") diff --git a/osquery/tables/specs/darwin/routes.table b/osquery/tables/specs/x/routes.table similarity index 65% rename from osquery/tables/specs/darwin/routes.table rename to osquery/tables/specs/x/routes.table index 79ae6bd6..636cee3a 100644 --- a/osquery/tables/specs/darwin/routes.table +++ b/osquery/tables/specs/x/routes.table @@ -3,10 +3,11 @@ schema([ Column(name="destination", type="std::string"), Column(name="netmask", type="std::string"), Column(name="gateway", type="std::string"), + Column(name="source", type="std::string"), Column(name="flags", type="int"), - Column(name="use", type="int"), Column(name="interface", type="std::string"), - Column(name="mtu", type="int"), + Column(name="mtu", type="int"), + Column(name="metric", type="int"), Column(name="type", type="std::string"), ]) -implementation("routes@genRoutes") +implementation("networking/routes@genRoutes")