I think there is no way to enumerate each network interface on my system and their assigned IP address using just sockets. Is this correct?
I mean, in Linux this cou
Here's a good start:
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <ifaddrs.h>
#include <stdio.h>
void
print_sockaddr(struct sockaddr* addr,const char *name)
{
char addrbuf[128] ;
addrbuf[0] = 0;
if(addr->sa_family == AF_UNSPEC)
return;
switch(addr->sa_family) {
case AF_INET:
inet_ntop(addr->sa_family,&((struct sockaddr_in*)addr)->sin_addr,addrbuf,sizeof(addrbuf));
break;
case AF_INET6:
inet_ntop(addr->sa_family,&((struct sockaddr_in6*)addr)->sin6_addr,addrbuf,sizeof(addrbuf));
break;
default:
sprintf(addrbuf,"Unknown (%d)",(int)addr->sa_family);
break;
}
printf("%-16s %s\n",name,addrbuf);
}
void
print_ifaddr(struct ifaddrs *addr)
{
char addrbuf[128] ;
addrbuf[0] = 0;
printf("%-16s %s\n","Name",addr->ifa_name);
if(addr->ifa_addr != NULL)
print_sockaddr(addr->ifa_addr,"Address");
if(addr->ifa_netmask != NULL)
print_sockaddr(addr->ifa_netmask,"Netmask");
if(addr->ifa_broadaddr != NULL)
print_sockaddr(addr->ifa_broadaddr,"Broadcast addr.");
if(addr->ifa_dstaddr != NULL)
print_sockaddr(addr->ifa_dstaddr,"Peer addr.");
puts("");
}
int main(int argc,char *argv[])
{
struct ifaddrs *addrs,*tmp;
if(getifaddrs(&addrs) != 0) {
perror("getifaddrs");
return 1;
}
for(tmp = addrs; tmp ; tmp = tmp->ifa_next) {
print_ifaddr(tmp);
}
freeifaddrs(addrs);
return 0;
}
On Linux, that information is accessed through NETLINK sockets. See the manual pages for libnetlink(3), netlink(7) and rtnetlink(7).
A somewhat more portable way of doing this is via ioctl()'s. SIOCGIFCONF is the one you want. See the manual page for netdevice(7). This one works on some other *nixes.
Use gethostname()
to retreive the machine's local DNS name, and then pass that name to gethostbyname()
to get its local IP addresses.
If the OS supports IPv6, then look at the getaddrinfo()
function instead of gethostbyname()
.
Take a look at the ioctl()
function. If I recall correctly, you can use it to obtain information on any interface, as well as obtaining the available interfaces.
I don't remember the correct invocation though. As with fcntl()
, it takes a request argument plus variable parameters that determine its behaviour.