I would like to write a piece of code which checks, for each network device (e.g. eth0, lo, master devices) some statistics and configuration data about that device.
I could find the statistics data (and most of the configuration data) in /sys/class/net/..., however, I couldn't find any C/C++ API or any entry in procfs/sysfs listing the inet addr, netmask and gateway.
Some alternatives I checked:
Also, since this code is intended for a product in my workplace, where every external library is inspected thoroughly (meaning it will take me forever to add any external library) I prefer solutions which rely on Linux native API and not external libraries.
Thanks!
There sure is using a struct of ifreq and ioctl() calls you can grab all interface information:
Man page is here Ifreq manpage
/* local interface info */
typedef struct{
char *iface;
struct ether_addr hwa;
struct in_addr ipa;
struct in_addr bcast;
struct in_addr nmask;
u_short mtu;
} ifcfg_t;
/*
* Grabs local network interface information and stores in a ifcfg_t
* defined in network.h, returns 0 on success -1 on failure
*/
int get_local_info(int rsock, ifcfg_t *ifcfg)
{
struct ifreq ifr;
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, ifcfg->iface, IF_NAMESIZE);
if((ioctl(rsock, SIOCGIFHWADDR, &ifr)) == -1){
perror("ioctl():");
return -1;
}
memcpy(&(ifcfg->hwa), &ifr.ifr_hwaddr.sa_data, 6);
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, ifcfg->iface, IF_NAMESIZE);
if((ioctl(rsock, SIOCGIFADDR, &ifr)) == -1){
perror("ioctl():");
return -1;
}
memcpy(&ifcfg->ipa, &(*(struct sockaddr_in *)&ifr.ifr_addr).sin_addr, 4);
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, ifcfg->iface, IF_NAMESIZE);
if((ioctl(rsock, SIOCGIFBRDADDR, &ifr)) == -1){
perror("ioctl():");
return -1;
}
memcpy(&ifcfg->bcast, &(*(struct sockaddr_in *)&ifr.ifr_broadaddr).sin_addr, 4);
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, ifcfg->iface, IF_NAMESIZE);
if((ioctl(rsock, SIOCGIFNETMASK, &ifr)) == -1){
perror("ioctl():");
return -1;
}
memcpy(&ifcfg->nmask.s_addr, &(*(struct sockaddr_in *)&ifr.ifr_netmask).sin_addr, 4);
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, ifcfg->iface, IF_NAMESIZE);
if((ioctl(rsock, SIOCGIFMTU, &ifr)) == -1){
perror("ioctl():");
return -1;
}
ifcfg->mtu = ifr.ifr_mtu;
return 0;
}
Quick edit, this function requires that the interface has been assigned before it is called, like so:
strcpy(if_cfg->iface, iface)
Ensuring you have allocated the memory first, then call like so
if((get_local_info(sock, if_cfg)) != 0){
printf("Unable to get network device info\n");
return -1;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With