diff --git a/include/network_interface.h b/include/network_interface.h index 7ed5ba1..625f7f3 100644 --- a/include/network_interface.h +++ b/include/network_interface.h @@ -31,6 +31,7 @@ #define TINS_NETWORK_INTERFACE_H #include +#include #include #include "hw_address.h" #include "ip_address.h" @@ -66,6 +67,16 @@ public: */ static NetworkInterface default_interface(); + /** + * Returns all available network interfaces. + */ + static std::vector all(); + + /** + * Returns a network interface for the given index. + */ + static NetworkInterface from_index(id_type identifier); + /** * Default constructor. */ diff --git a/include/utils.h b/include/utils.h index 9e70a06..ad751bd 100644 --- a/include/utils.h +++ b/include/utils.h @@ -36,6 +36,7 @@ #include #include #undef interface + #include "network_interface.h" #endif #include "macros.h" #if defined(BSD) || defined(__FreeBSD_kernel__) @@ -389,9 +390,8 @@ void Tins::Utils::route_entries(ForwardIterator output) { for (DWORD i = 0; i < table->dwNumEntries; i++) { MIB_IPFORWARDROW *row = &table->table[i]; if(row->dwForwardType == MIB_IPROUTE_TYPE_INDIRECT) { - if_indextoname(row->dwForwardIfIndex, iface_name); RouteEntry entry; - entry.interface = iface_name; + entry.interface = NetworkInterface::from_index(row->dwForwardIfIndex).name(); entry.destination = IPv4Address(row->dwForwardDest); entry.mask = IPv4Address(row->dwForwardMask); entry.gateway = IPv4Address(row->dwForwardNextHop); diff --git a/src/network_interface.cpp b/src/network_interface.cpp index 5e34620..af0388d 100644 --- a/src/network_interface.cpp +++ b/src/network_interface.cpp @@ -49,6 +49,10 @@ #include "utils.h" #include "endianness.h" +using std::string; +using std::vector; +using std::set; + /** \cond */ struct InterfaceInfoCollector { typedef Tins::NetworkInterface::Info info_type; @@ -123,11 +127,26 @@ namespace Tins { NetworkInterface NetworkInterface::default_interface() { return NetworkInterface(IPv4Address(uint32_t(0))); } + +vector NetworkInterface::all() { + const set interfaces = Utils::network_interfaces(); + vector output; + for(set::const_iterator it = interfaces.begin(); it != interfaces.end(); ++it) { + output.push_back(*it); + } + return output; +} NetworkInterface::NetworkInterface() : iface_id(0) { } +NetworkInterface NetworkInterface::from_index(id_type identifier) { + NetworkInterface iface; + iface.iface_id = identifier; + return iface; +} + NetworkInterface::NetworkInterface(const char *name) { iface_id = name ? resolve_index(name) : 0; } @@ -177,7 +196,7 @@ std::string NetworkInterface::name() const { PIP_ADAPTER_ADDRESSES iface = (IP_ADAPTER_ADDRESSES *)&buffer[0]; while (iface) { if (iface->IfIndex == iface_id) { - return std::string("\\Device\\NPF_") + iface->AdapterName; + return iface->AdapterName; } iface = iface->Next; } @@ -197,10 +216,26 @@ NetworkInterface::Info NetworkInterface::addresses() const { } NetworkInterface::id_type NetworkInterface::resolve_index(const char *name) { + #ifndef WIN32 id_type id = if_nametoindex(name); if(!id) throw std::runtime_error("Invalid interface"); return id; + #else // Win32 + ULONG size; + ::GetAdaptersAddresses(AF_INET, 0, 0, 0, &size); + std::vector buffer(size); + if (::GetAdaptersAddresses(AF_INET, 0, 0, (IP_ADAPTER_ADDRESSES *)&buffer[0], &size) == ERROR_SUCCESS) { + PIP_ADAPTER_ADDRESSES iface = (IP_ADAPTER_ADDRESSES *)&buffer[0]; + while (iface) { + if (strcmp(iface->AdapterName, name) == 0) { + return iface->IfIndex; + } + iface = iface->Next; + } + } + throw std::runtime_error("Invalid interface"); + #endif // Win32 } } diff --git a/src/sniffer.cpp b/src/sniffer.cpp index 704e728..8cac7cd 100644 --- a/src/sniffer.cpp +++ b/src/sniffer.cpp @@ -27,6 +27,12 @@ * */ +#ifdef WIN32 + #define TINS_PREFIX_INTERFACE(x) ("\\Device\\NPF_" + x) +#else // WIN32 + #define TINS_PREFIX_INTERFACE(x) (x) +#endif // WIN32 + #include #include #include "sniffer.h" @@ -217,7 +223,7 @@ void BaseSniffer::set_timeout(int ms) { Sniffer::Sniffer(const string &device, const SnifferConfiguration& configuration) { char error[PCAP_ERRBUF_SIZE]; - pcap_t* phandle = pcap_create(device.c_str(), error); + pcap_t* phandle = pcap_create(TINS_PREFIX_INTERFACE(device).c_str(), error); if (!phandle) { throw runtime_error(error); } @@ -225,7 +231,7 @@ Sniffer::Sniffer(const string &device, const SnifferConfiguration& configuration // Set the netmask if we are able to find it. bpf_u_int32 ip, if_mask; - if (pcap_lookupnet(device.c_str(), &ip, &if_mask, error) == 0) { + if (pcap_lookupnet(TINS_PREFIX_INTERFACE(device).c_str(), &ip, &if_mask, error) == 0) { set_if_mask(if_mask); } @@ -251,7 +257,7 @@ Sniffer::Sniffer(const std::string &device, unsigned max_packet_size, bool promi configuration.set_rfmon(rfmon); char error[PCAP_ERRBUF_SIZE]; - pcap_t* phandle = pcap_create(device.c_str(), error); + pcap_t* phandle = pcap_create(TINS_PREFIX_INTERFACE(device).c_str(), error); if (!phandle) { throw runtime_error(error); } @@ -259,7 +265,7 @@ Sniffer::Sniffer(const std::string &device, unsigned max_packet_size, bool promi // Set the netmask if we are able to find it. bpf_u_int32 ip, if_mask; - if (pcap_lookupnet(device.c_str(), &ip, &if_mask, error) == 0) { + if (pcap_lookupnet(TINS_PREFIX_INTERFACE(device).c_str(), &ip, &if_mask, error) == 0) { set_if_mask(if_mask); } @@ -284,7 +290,7 @@ Sniffer::Sniffer(const std::string &device, promisc_type promisc, const std::str configuration.set_rfmon(rfmon); char error[PCAP_ERRBUF_SIZE]; - pcap_t* phandle = pcap_create(device.c_str(), error); + pcap_t* phandle = pcap_create(TINS_PREFIX_INTERFACE(device).c_str(), error); if (!phandle) { throw runtime_error(error); } @@ -292,7 +298,7 @@ Sniffer::Sniffer(const std::string &device, promisc_type promisc, const std::str // Set the netmask if we are able to find it. bpf_u_int32 ip, if_mask; - if (pcap_lookupnet(device.c_str(), &ip, &if_mask, error) == 0) { + if (pcap_lookupnet(TINS_PREFIX_INTERFACE(device).c_str(), &ip, &if_mask, error) == 0) { set_if_mask(if_mask); } diff --git a/src/utils.cpp b/src/utils.cpp index 7dc1814..8b8ff66 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -63,7 +63,7 @@ struct InterfaceCollector { #ifdef WIN32 bool operator() (PIP_ADAPTER_ADDRESSES addr) { - ifaces.insert(string("\\Device\\NPF_") + addr->AdapterName); + ifaces.insert(addr->AdapterName); return false; } #else