From dd1d1c3c49a9b5c6e46cad0bb5918d45f655f184 Mon Sep 17 00:00:00 2001 From: Matias Fontanini Date: Wed, 8 Aug 2012 23:43:08 -0300 Subject: [PATCH] Added NetworkInterface class. Needs testing. --- include/network_interface.h | 55 ++++++++++++++++++++++++++++ include/utils.h | 9 +++-- src/network_interface.cpp | 71 +++++++++++++++++++++++++++++++++++++ src/utils.cpp | 12 ++++--- 4 files changed, 140 insertions(+), 7 deletions(-) create mode 100644 include/network_interface.h create mode 100644 src/network_interface.cpp diff --git a/include/network_interface.h b/include/network_interface.h new file mode 100644 index 0000000..2a6e89c --- /dev/null +++ b/include/network_interface.h @@ -0,0 +1,55 @@ +/* + * libtins is a net packet wrapper library for crafting and + * interpreting sniffed packets. + * + * Copyright (C) 2011 Nasel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef TINS_NETWORK_INTERFACE_H +#define TINS_NETWORK_INTERFACE_H + +#include +#include +#include "hwaddress.h" + +namespace Tins { +class NetworkInterface { +public: + typedef uint32_t id_type; + typedef HWAddress<6> address_type; + + NetworkInterface(const std::string &name); + NetworkInterface(id_type id); + + id_type id() const { + return iface_id; + } + + address_type address(); + + bool operator==(const NetworkInterface &rhs) const { + return iface_id == rhs.iface_id; + } + + bool operator!=(const NetworkInterface &rhs) const { + return !(*this == rhs); + } +private: + id_type iface_id; +}; +} +#endif // TINS_NETWORK_INTERFACE_H diff --git a/include/utils.h b/include/utils.h index b687f63..963570a 100644 --- a/include/utils.h +++ b/include/utils.h @@ -285,12 +285,15 @@ namespace Tins { * the object to collect data from them. * \param functor An instance of an class which implements operator(struct ifaddrs*). */ - template void generic_iface_loop(T &functor) { + template + void generic_iface_loop(Functor &functor) { struct ifaddrs *ifaddrs = 0; struct ifaddrs *if_it = 0; getifaddrs(&ifaddrs); - for(if_it = ifaddrs; if_it; if_it = if_it->ifa_next) - functor(if_it); + for(if_it = ifaddrs; if_it; if_it = if_it->ifa_next) { + if(!functor(if_it)) + break; + } if(ifaddrs) freeifaddrs(ifaddrs); } diff --git a/src/network_interface.cpp b/src/network_interface.cpp new file mode 100644 index 0000000..de43429 --- /dev/null +++ b/src/network_interface.cpp @@ -0,0 +1,71 @@ +/* + * libtins is a net packet wrapper library for crafting and + * interpreting sniffed packets. + * + * Copyright (C) 2011 Nasel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#ifndef WIN32 + #include + #include +#endif +#include "network_interface.h" +#include "utils.h" + +/** \cond */ +template +struct HWAddressCollector { + Address *result; + int iface_id; + bool found; + + HWAddressCollector(Tins::HWAddress<6> *res, int id) + : result(res), iface_id(id), found(false){ } + + bool operator() (struct ifaddrs *addr) { + const struct sockaddr_ll* addr_ptr = ((struct sockaddr_ll*)addr->ifa_addr); + if(!found && addr->ifa_addr->sa_family == AF_PACKET && addr_ptr->sll_ifindex == iface_id) { + *result = addr_ptr->sll_addr; + found = true; + } + return found; + } +}; + +namespace Tins { +NetworkInterface::NetworkInterface(const std::string &name) { + iface_id = if_nametoindex(name.c_str()); + if(!iface_id) + throw std::runtime_error("Invalid interface error"); +} + +NetworkInterface::NetworkInterface(id_type id) +: iface_id(id) { + +} + +NetworkInterface::address_type NetworkInterface::address() { + address_type addr; + ::HWAddressCollector collector(&addr, iface_id); + Utils::generic_iface_loop(collector); + if(!collector.found) + throw std::runtime_error("Error looking up interface address"); + return addr; +} +} + diff --git a/src/utils.cpp b/src/utils.cpp index 99a21c7..ea2a846 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -43,8 +43,9 @@ using namespace std; struct InterfaceCollector { set ifaces; - void operator() (struct ifaddrs *addr) { + bool operator() (struct ifaddrs *addr) { ifaces.insert(addr->ifa_name); + return true; } }; @@ -56,11 +57,12 @@ struct IPv4Collector { IPv4Collector(const char *interface) : ip(0), found(false), iface(interface) { } - void operator() (struct ifaddrs *addr) { + bool operator() (struct ifaddrs *addr) { if(!found && addr->ifa_addr->sa_family == AF_INET && !strcmp(addr->ifa_name, iface)) { ip = ((struct sockaddr_in *)addr->ifa_addr)->sin_addr.s_addr; found = true; } + return found; } }; @@ -73,11 +75,12 @@ struct HWAddressCollector { HWAddressCollector(Tins::HWAddress<6> *res, const char *interface) : result(res), found(false), iface(interface) { } - void operator() (struct ifaddrs *addr) { + bool operator() (struct ifaddrs *addr) { if(!found && addr->ifa_addr->sa_family == AF_PACKET && !strcmp(addr->ifa_name, iface)) { *result = ((struct sockaddr_ll*)addr->ifa_addr)->sll_addr; found = true; } + return found; } }; @@ -90,7 +93,7 @@ struct InterfaceInfoCollector { InterfaceInfoCollector(Tins::Utils::InterfaceInfo *res, const char *interface) : info(res), iface(interface), found(false) { } - void operator() (struct ifaddrs *addr) { + bool operator() (struct ifaddrs *addr) { if(addr->ifa_addr->sa_family == AF_PACKET && !strcmp(addr->ifa_name, iface)) memcpy(info->hw_addr, ((struct sockaddr_ll*)addr->ifa_addr)->sll_addr, sizeof(info->hw_addr)); else if(addr->ifa_addr->sa_family == AF_INET && !strcmp(addr->ifa_name, iface)) { @@ -102,6 +105,7 @@ struct InterfaceInfoCollector { info->bcast_addr = 0; found = true; } + return found; } };