Manual Pages
getifaddrs, freeifaddrs – get interface addresses
packet – packet interface on device level
NETLINK
Generic NETLINK HowTo
Netlink Sockets in C using the 3.X linux kernel
Tutorials & Blogs
Code Snippet: getifaddrs
Get the IP address of the machine
How to get MAC address of your machine using a C program?
How to get local IP and MAC address C [duplicate]
MAC address with getifaddrs (wrong answer!!)
Code Stippet
lldpd/src/daemon/interfaces-linux.c
Get network interface’s MAC address and IP address
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/param.h>
#include <netinet/in.h>
#include <net/ethernet.h>
#include <net/if.h>
#include <linux/if_link.h>
#include <linux/if_vlan.h>
#include <linux/sockios.h>
#include <ifaddrs.h>
bool
netif_init(netif_t *netif, const char *name)
{
bool result = true;
int sockfd;
struct ifaddrs *ifas;
struct ifaddrs *ifa;
struct ifreq ifr;
struct rtnl_link_stats *stats;
struct vlan_ioctl_args ifv;
/* string copy name */
strncpy(netif->name, name, NETIF_NAME_SIZE);
/* create socket (required for ioctl) */
if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
LOG_ERRNO(LOG_NETWORK_INTERFACE, LOG_ERROR, errno, ("socket failed"));
return false;
}
/* get interface addresses */
if (getifaddrs(&ifas) != 0) {
return false;
}
for (ifa = ifas; ifa != NULL; ifa = ifa->ifa_next) {
if ((ifa->ifa_addr) == NULL) continue;
if ((ifa->ifa_flags & IFF_UP) == 0) continue;
/* network interface name matches */
if (strcmp(name, ifa->ifa_name) == 0) {
switch (ifa->ifa_addr->sa_family) {
case AF_INET: netif_add_ipv4_address(netif, IPV4_ADDRESS(&(INADDR(ifa->ifa_addr)->sin_addr)),
IPV4_ADDRESS(&(INADDR(ifa->ifa_netmask)->sin_addr)),
IPV4_ADDRESS(&(INADDR(ifa->ifa_broadaddr)->sin_addr)),
NULL);
break;
case AF_INET6: netif_add_ipv6_address(netif, IPV6_ADDRESS(&(INADDR6(ifa->ifa_addr)->sin6_addr)),
IPV6_ADDRESS(&(INADDR6(ifa->ifa_netmask)->sin6_addr)),
IPV6_STATE_VALID);
break;
case AF_PACKET: stats = ifa->ifa_data;
LOG_PRINTLN(LOG_NETWORK_INTERFACE, LOG_DEBUG, ("tx packet: %" PRIu32 " rx packet: %" PRIu32 " tx bytes: %" PRIu32 " rx bytes: %" PRIu32,
stats->tx_packets, stats->rx_packets, stats->tx_bytes, stats->rx_bytes));
bzero((char *) &ifr, sizeof(ifr));
strncpy(ifr.ifr_name, netif->name, NETIF_NAME_SIZE);
if (ioctl(sockfd, SIOCGIFHWADDR, &ifr) != -1) {
netif_add_mac_address(netif, MAC_ADDRESS(LLADDR(LADDR(ifr.ifr_hwaddr.sa_data))));
bzero((char *) &ifv, sizeof(ifv));
ifv.cmd = GET_VLAN_VID_CMD;
strncpy(ifv.device1, netif->name, sizeof(ifv.device1));
if (ioctl(sockfd, SIOCGIFVLAN, &ifv) != -1) {
netif_add_vid(netif, ifv.u.VID);
}
} else {
LOG_PRINTLN(LOG_NETWORK_INTERFACE, LOG_ERROR, ("couldn't get MAC address"));
result = false;
goto netif_init_exit;
}
break;
default: continue;
}
}
}
netif_init_exit:
freeifaddrs(ifas);
return result;
}
$ grep -r vlan_ioctl /usr/include
/usr/include/linux/if_vlan.h:/* Passed in vlan_ioctl_args structure to determine behaviour. */
/usr/include/linux/if_vlan.h:enum vlan_ioctl_cmds {
/usr/include/linux/if_vlan.h:struct vlan_ioctl_args {
/usr/include/linux/if_vlan.h: int cmd; /* Should be one of the vlan_ioctl_cmds enum above. */
