diff --git a/include/utils.h b/include/utils.h index 8dfecd0..c6c2bac 100644 --- a/include/utils.h +++ b/include/utils.h @@ -40,6 +40,14 @@ namespace Tins { * conversions, interface listing, etc. */ namespace Utils { + /** + * \brief Struct that represents an interface's information. + */ + struct InterfaceInfo { + uint32_t ip_addr, netmask, bcast_addr; + uint8_t hw_addr[6]; + }; + /** \brief Convert a dotted-ip-notation string to an integer. * * \param ip A dotted ip notation string @@ -121,8 +129,23 @@ namespace Tins { * If the lookup fails, false will be returned, true otherwise. * \param iface The interface from which to extract the ip address. * \param ip The ip address found will be returned in this param. + * + * \return bool indicating wether the operation was successfull. */ bool interface_ip(const std::string &iface, uint32_t &ip); + + /** + * \brief Lookup the ip/hw/netmask/broadcast address of the + * given interface. + * + * If the lookup fails, false will be returned, true otherwise. + * \param iface The interface from which to extract the ip address. + * \param info The InterfaceInfo in which the information will + * be stored. + * + * \return bool indicating wether the operation was successfull. + */ + bool interface_info(const std::string &iface, InterfaceInfo &info); /** * \brief Lookup the hardware address of the given interface. @@ -131,6 +154,8 @@ namespace Tins { * \param iface The interface from which to extract the hardware address. * \param buffer The hw address will be stored in this buffer. It must * be at least 6 bytes long. + * + * \return bool indicating wether the operation was successfull. */ bool interface_hwaddr(const std::string &iface, uint8_t *buffer); @@ -140,6 +165,8 @@ namespace Tins { * If the lookup fails, false will be returned, true otherwise. * \param iface The interface from which to extract the identifier. * \param id The interface id will be returned in this parameter. + * + * \return bool indicating wether the operation was successfull. */ bool interface_id(const std::string &iface, uint32_t &id); diff --git a/src/utils.cpp b/src/utils.cpp index 866823a..9870101 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -49,6 +49,7 @@ struct InterfaceCollector { } }; +/** \cond */ struct IPv4Collector { uint32_t ip; bool found; @@ -64,6 +65,7 @@ struct IPv4Collector { } }; +/** \cond */ struct HWAddressCollector { uint8_t *result; bool found; @@ -79,6 +81,30 @@ struct HWAddressCollector { } }; +/** \cond */ +struct InterfaceInfoCollector { + Tins::Utils::InterfaceInfo *info; + const char *iface; + bool found; + + InterfaceInfoCollector(Tins::Utils::InterfaceInfo *res, const char *interface) : + info(res), iface(interface), found(false) { } + + void 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)) { + info->ip_addr = ((struct sockaddr_in *)addr->ifa_addr)->sin_addr.s_addr; + info->netmask = ((struct sockaddr_in *)addr->ifa_netmask)->sin_addr.s_addr; + if((addr->ifa_flags & (IFF_BROADCAST | IFF_POINTOPOINT))) + info->bcast_addr = ((struct sockaddr_in *)addr->ifa_ifu.ifu_broadaddr)->sin_addr.s_addr; + else + info->bcast_addr = 0; + found = true; + } + } +}; + bool from_hex(const string &str, uint32_t &result) { unsigned i(0); result = 0; @@ -284,6 +310,15 @@ bool Tins::Utils::interface_hwaddr(const string &iface, uint8_t *buffer) { return collector.found; } +bool Tins::Utils::interface_info(const string &iface, InterfaceInfo &info) { + InterfaceInfoCollector collector(&info, iface.c_str()); + generic_iface_loop(collector); + info.ip_addr = net_to_host_l(info.ip_addr); + info.netmask = net_to_host_l(info.netmask); + info.bcast_addr = net_to_host_l(info.bcast_addr); + return collector.found; +} + bool Tins::Utils::interface_id(const string &iface, uint32_t &id) { id = if_nametoindex(iface.c_str()); return (((int32_t)id) != -1);