From e4c0d74883205d54a8fbe83c086267123de70db7 Mon Sep 17 00:00:00 2001 From: Matias Fontanini Date: Thu, 7 Jun 2012 11:45:51 -0300 Subject: [PATCH] Added Utils::route_entries to retrieve routing table entries. --- include/utils.h | 52 ++++++++++++++++++++++++++++++++++++++++++++++--- src/utils.cpp | 52 +++++++++++++++---------------------------------- 2 files changed, 65 insertions(+), 39 deletions(-) diff --git a/include/utils.h b/include/utils.h index d1425ad..b51cb76 100644 --- a/include/utils.h +++ b/include/utils.h @@ -29,6 +29,7 @@ #endif #include #include +#include #include #include "packetsender.h" #include "ipaddress.h" @@ -49,6 +50,14 @@ namespace Tins { uint8_t hw_addr[6]; }; + /** + * \brief Struct that represents an entry in /proc/net/route + */ + struct RouteEntry { + std::string interface; + IPv4Address destination, gateway, mask; + }; + /** \brief Convert a dotted-ip-notation string to an integer. * * \param ip A dotted ip notation string @@ -193,7 +202,16 @@ namespace Tins { * * \return bool indicating wether the lookup was successfull. */ - bool gateway_from_ip(IPv4Address ip, IPv4Address &gw_addr) ; + bool gateway_from_ip(IPv4Address ip, IPv4Address &gw_addr); + + + /** + * \brief Retrieves entries int the routing table. + * + * \brief output ForwardIterator in which entries will be stored. + */ + template + void route_entries(ForwardIterator output); /** \brief Convert 16 bit integer into network byte order. @@ -275,7 +293,35 @@ namespace Tins { if(ifaddrs) freeifaddrs(ifaddrs); } - }; -}; + + namespace Internals { + void skip_line(std::istream &input); + bool from_hex(const std::string &str, uint32_t &result); + } + } +} + +template +void Tins::Utils::route_entries(ForwardIterator output) { + using namespace Utils::Internals; + std::ifstream input("/proc/net/route"); + std::string destination, mask, gw; + uint32_t dummy; + skip_line(input); + RouteEntry entry; + while(input >> entry.interface >> destination >> gw) { + for(unsigned i(0); i < 5; ++i) + input >> mask; + from_hex(destination, dummy); + entry.destination = net_to_host_l(dummy); + from_hex(mask, dummy); + entry.mask = net_to_host_l(dummy); + from_hex(gw, dummy); + entry.gateway = net_to_host_l(dummy); + skip_line(input); + *output = entry; + ++output; + } +} #endif diff --git a/src/utils.cpp b/src/utils.cpp index 140ee6c..e22bc4d 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -21,7 +21,6 @@ #include #include -#include #include #include #include @@ -105,7 +104,7 @@ struct InterfaceInfoCollector { } }; -bool from_hex(const string &str, uint32_t &result) { +bool Tins::Utils::Internals::from_hex(const string &str, uint32_t &result) { unsigned i(0); result = 0; while(i < str.size()) { @@ -122,7 +121,7 @@ bool from_hex(const string &str, uint32_t &result) { return true; } -void skip_line(istream &input) { +void Tins::Utils::Internals::skip_line(istream &input) { int c = 0; while(c != '\n' && input) c = input.get(); @@ -248,46 +247,27 @@ bool Tins::Utils::resolve_hwaddr(const string &iface, IPv4Address ip, string Tins::Utils::interface_from_ip(IPv4Address ip) { if(ip == 0x7f000001) return "lo"; - ifstream input("/proc/net/route"); - bool match(false); - string iface; - string destination, mask; - uint32_t destination_int, mask_int, ip_int = ip; - skip_line(input); - while(!match) { - input >> iface >> destination; - for(unsigned i(0); i < 6; ++i) - input >> mask; - from_hex(destination, destination_int); - from_hex(mask, mask_int); - if((ip_int & mask_int) == destination_int) - return iface; - skip_line(input); + std::vector entries; + uint32_t ip_int = ip; + route_entries(std::back_inserter(entries)); + for(std::vector::const_iterator it(entries.begin()); it != entries.end(); ++it) { + std::cout << std::hex << ip_int << " " << (uint32_t)it->mask << " " << (uint32_t)it->destination << "\n"; + if((ip_int & it->mask) == it->destination) + return it->interface; } return ""; } bool Tins::Utils::gateway_from_ip(IPv4Address ip, IPv4Address &gw_addr) { - ifstream input("/proc/net/route"); - bool match(false); - string iface; - string destination, mask, gw; - uint32_t destination_int, mask_int; - ip = Utils::net_to_host_l(ip); - skip_line(input); - while(!match) { - input >> iface >> destination >> gw; - for(unsigned i(0); i < 5; ++i) - input >> mask; - from_hex(destination, destination_int); - from_hex(mask, mask_int); - if((ip & mask_int) == destination_int) { - uint32_t tmp_ip; - from_hex(gw, tmp_ip); - gw_addr = net_to_host_l(tmp_ip); + std::vector entries; + uint32_t ip_int = ip; + route_entries(std::back_inserter(entries)); + for(std::vector::const_iterator it(entries.begin()); it != entries.end(); ++it) { + std::cout << std::hex << ip_int << " " << (uint32_t)it->mask << " " << (uint32_t)it->destination << "\n"; + if((ip_int & it->mask) == it->destination) { + gw_addr = it->gateway; return true; } - skip_line(input); } return false; }