mirror of
https://github.com/mfontanini/libtins
synced 2026-01-23 02:35:57 +01:00
Add IPv6 addresses to NetworkInterface::Info
This commit is contained in:
@@ -29,12 +29,14 @@
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <tins/network_interface.h>
|
||||
|
||||
using std::cout;
|
||||
using std::wcout;
|
||||
using std::endl;
|
||||
using std::string;
|
||||
using std::ostringstream;
|
||||
|
||||
using namespace Tins;
|
||||
|
||||
@@ -59,11 +61,27 @@ int main() {
|
||||
#endif // _WIN32
|
||||
cout << ": " << endl;
|
||||
|
||||
cout << " HW address: " << info.hw_addr << endl
|
||||
<< " IP address: " << info.ip_addr << endl
|
||||
<< " Netmask: " << info.netmask << endl
|
||||
<< " Broadcast: " << info.bcast_addr << endl
|
||||
<< " Iface index: " << iface.id() << endl
|
||||
<< " Status: " << "interface " << status << endl << endl;
|
||||
string ipv6_string;
|
||||
if (info.ipv6_addrs.empty()) {
|
||||
ipv6_string = "(none)";
|
||||
}
|
||||
else {
|
||||
ostringstream oss;
|
||||
for (size_t i = 0; i < info.ipv6_addrs.size(); ++i) {
|
||||
const NetworkInterface::IPv6AddressPrefix& prefix = info.ipv6_addrs[i];
|
||||
if (i > 0) {
|
||||
oss << ", ";
|
||||
}
|
||||
oss << prefix.address << "/" << prefix.prefix_length;
|
||||
}
|
||||
ipv6_string = oss.str();
|
||||
}
|
||||
cout << " HW address: " << info.hw_addr << endl
|
||||
<< " IP address: " << info.ip_addr << endl
|
||||
<< " IPv6 addresses: " << ipv6_string << endl
|
||||
<< " Netmask: " << info.netmask << endl
|
||||
<< " Broadcast: " << info.bcast_addr << endl
|
||||
<< " Iface index: " << iface.id() << endl
|
||||
<< " Status: " << "interface " << status << endl << endl;
|
||||
}
|
||||
}
|
||||
@@ -36,6 +36,7 @@
|
||||
#include "macros.h"
|
||||
#include "hw_address.h"
|
||||
#include "ip_address.h"
|
||||
#include "ipv6_address.h"
|
||||
|
||||
namespace Tins {
|
||||
|
||||
@@ -55,11 +56,20 @@ public:
|
||||
*/
|
||||
typedef HWAddress<6> address_type;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
struct IPv6AddressPrefix {
|
||||
IPv6Address address;
|
||||
uint32_t prefix_length;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Struct that holds an interface's addresses.
|
||||
*/
|
||||
struct Info {
|
||||
IPv4Address ip_addr, netmask, bcast_addr;
|
||||
std::vector<IPv6AddressPrefix> ipv6_addrs;
|
||||
address_type hw_addr;
|
||||
bool is_up;
|
||||
};
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
#include <net/if.h>
|
||||
#else
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <iphlpapi.h>
|
||||
#undef interface
|
||||
#endif
|
||||
@@ -75,37 +76,32 @@ struct InterfaceInfoCollector {
|
||||
using Tins::Endian::host_to_be;
|
||||
using Tins::IPv4Address;
|
||||
#if defined(BSD) || defined(__FreeBSD_kernel__)
|
||||
#define TINS_BROADCAST_ADDR(addr) (addr->ifa_dstaddr)
|
||||
const struct sockaddr_dl* addr_ptr = ((struct sockaddr_dl*)addr->ifa_addr);
|
||||
|
||||
if (addr->ifa_addr->sa_family == AF_LINK && addr_ptr->sdl_index == iface_id) {
|
||||
info->hw_addr = (const uint8_t*)LLADDR(addr_ptr);
|
||||
found_hw = true;
|
||||
}
|
||||
else if (addr->ifa_addr->sa_family == AF_INET && !std::strcmp(addr->ifa_name, iface_name)) {
|
||||
info->ip_addr = IPv4Address(((struct sockaddr_in *)addr->ifa_addr)->sin_addr.s_addr);
|
||||
info->netmask = IPv4Address(((struct sockaddr_in *)addr->ifa_netmask)->sin_addr.s_addr);
|
||||
if ((addr->ifa_flags & (IFF_BROADCAST | IFF_POINTOPOINT))) {
|
||||
info->bcast_addr = IPv4Address(((struct sockaddr_in *)addr->ifa_dstaddr)->sin_addr.s_addr);
|
||||
}
|
||||
else {
|
||||
info->bcast_addr = 0;
|
||||
}
|
||||
info->is_up = (addr->ifa_flags & IFF_UP);
|
||||
found_ip = true;
|
||||
}
|
||||
#else
|
||||
#define TINS_BROADCAST_ADDR(addr) (addr->ifa_broadaddr)
|
||||
const struct sockaddr_ll* addr_ptr = ((struct sockaddr_ll*)addr->ifa_addr);
|
||||
|
||||
if (addr->ifa_addr) {
|
||||
if (addr->ifa_addr->sa_family == AF_PACKET && addr_ptr->sll_ifindex == iface_id) {
|
||||
info->hw_addr = addr_ptr->sll_addr;
|
||||
found_hw = true;
|
||||
}
|
||||
else if (addr->ifa_addr->sa_family == AF_INET && !std::strcmp(addr->ifa_name, iface_name)) {
|
||||
if (!addr->ifa_addr) {
|
||||
return false;
|
||||
}
|
||||
if (addr->ifa_addr->sa_family == AF_PACKET && addr_ptr->sll_ifindex == iface_id) {
|
||||
info->hw_addr = addr_ptr->sll_addr;
|
||||
found_hw = true;
|
||||
}
|
||||
#endif
|
||||
else if (!std::strcmp(addr->ifa_name, iface_name)) {
|
||||
if (addr->ifa_addr->sa_family == AF_INET) {
|
||||
info->ip_addr = IPv4Address(((struct sockaddr_in *)addr->ifa_addr)->sin_addr.s_addr);
|
||||
info->netmask = IPv4Address(((struct sockaddr_in *)addr->ifa_netmask)->sin_addr.s_addr);
|
||||
if ((addr->ifa_flags & (IFF_BROADCAST | IFF_POINTOPOINT))) {
|
||||
info->bcast_addr = IPv4Address(((struct sockaddr_in *)addr->ifa_broadaddr)->sin_addr.s_addr);
|
||||
info->bcast_addr = IPv4Address(
|
||||
((struct sockaddr_in *)TINS_BROADCAST_ADDR(addr))->sin_addr.s_addr);
|
||||
}
|
||||
else {
|
||||
info->bcast_addr = 0;
|
||||
@@ -113,9 +109,29 @@ struct InterfaceInfoCollector {
|
||||
info->is_up = (addr->ifa_flags & IFF_UP);
|
||||
found_ip = true;
|
||||
}
|
||||
else if (addr->ifa_addr->sa_family == AF_INET6) {
|
||||
Tins::NetworkInterface::IPv6AddressPrefix prefix;
|
||||
prefix.address = ((struct sockaddr_in6 *)addr->ifa_addr)->sin6_addr.s6_addr;
|
||||
Tins::IPv6Address mask = ((struct sockaddr_in6 *)addr->ifa_netmask)->sin6_addr.s6_addr;
|
||||
prefix.prefix_length = 0;
|
||||
for (Tins::IPv6Address::iterator iter = mask.begin(); iter != mask.end(); ++iter) {
|
||||
if (*iter == 255) {
|
||||
prefix.prefix_length += 8;
|
||||
}
|
||||
else {
|
||||
uint8_t current_value = 128;
|
||||
while (*iter > 0) {
|
||||
prefix.prefix_length += 1;
|
||||
*iter &= ~current_value;
|
||||
current_value /= 2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
info->ipv6_addrs.push_back(prefix);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#undef TINS_BROADCAST_ADDR
|
||||
return found_ip && found_hw;
|
||||
}
|
||||
#else // _WIN32
|
||||
@@ -124,14 +140,25 @@ struct InterfaceInfoCollector {
|
||||
using Tins::Endian::host_to_be;
|
||||
if (iface_id == uint32_t(iface->IfIndex)) {
|
||||
copy(iface->PhysicalAddress, iface->PhysicalAddress + 6, info->hw_addr.begin());
|
||||
const IP_ADAPTER_UNICAST_ADDRESS* unicast = iface->FirstUnicastAddress;
|
||||
if (unicast) {
|
||||
info->ip_addr = IPv4Address(((const struct sockaddr_in *)unicast->Address.lpSockaddr)->sin_addr.s_addr);
|
||||
info->netmask = IPv4Address(host_to_be<uint32_t>(0xffffffff << (32 - unicast->OnLinkPrefixLength)));
|
||||
info->bcast_addr = IPv4Address((info->ip_addr & info->netmask) | ~info->netmask);
|
||||
info->is_up = (iface->Flags & IP_ADAPTER_IPV4_ENABLED) != 0;
|
||||
found_ip = true;
|
||||
found_hw = true;
|
||||
found_hw = true;
|
||||
IP_ADAPTER_UNICAST_ADDRESS* unicast = iface->FirstUnicastAddress;
|
||||
while (unicast) {
|
||||
int family = ((const struct sockaddr*)unicast->Address.lpSockaddr)->sa_family;
|
||||
if (family == AF_INET) {
|
||||
info->ip_addr = IPv4Address(((const struct sockaddr_in *)unicast->Address.lpSockaddr)->sin_addr.s_addr);
|
||||
info->netmask = IPv4Address(host_to_be<uint32_t>(0xffffffff << (32 - unicast->OnLinkPrefixLength)));
|
||||
info->bcast_addr = IPv4Address((info->ip_addr & info->netmask) | ~info->netmask);
|
||||
info->is_up = (iface->Flags & IP_ADAPTER_IPV4_ENABLED) != 0;
|
||||
found_ip = true;
|
||||
}
|
||||
else if (family == AF_INET6) {
|
||||
Tins::NetworkInterface::IPv6AddressPrefix prefix;
|
||||
prefix.address = ((const struct sockaddr_in6 *)unicast->Address.lpSockaddr)->sin6_addr.s6_addr;
|
||||
prefix.prefix_length = unicast->OnLinkPrefixLength;
|
||||
info->ipv6_addrs.push_back(prefix);
|
||||
found_ip = true;
|
||||
}
|
||||
unicast = unicast->Next;
|
||||
}
|
||||
}
|
||||
return found_ip && found_hw;
|
||||
|
||||
Reference in New Issue
Block a user