network-info-0.1: cbits/network-linux.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#include <ifaddrs.h>
#include <netdb.h>
#include <netpacket/packet.h>
#include "network.h"
#include "common.h"
void maccopy(unsigned char *dst, struct sockaddr *addr)
{
/* TODO check that sll_halen is equal to 6 (MAC_SIZE) */
memcpy(dst, ((struct sockaddr_ll *)addr)->sll_addr, MAC_SIZE);
}
struct network_interface *add_interface(struct network_interface *ns, const wchar_t *name, int max_ns)
{
int i;
for (i = 0; i < max_ns; i++) {
if (wcsempty(ns[i].name)) {
wszcopy(ns[i].name, name, NAME_SIZE);
return &ns[i];
} else if (wcscmp(ns[i].name, name) == 0) {
return &ns[i];
}
}
return NULL;
}
int count_interfaces(struct network_interface *ns, int max_ns)
{
int i;
for (i = 0; i < max_ns; i++) {
if (wcsempty(ns[i].name)) {
break;
}
}
return i;
}
int c_get_network_interfaces(struct network_interface *ns, int max_ns)
{
struct network_interface *n;
struct ifaddrs *ifaddr, *ifa;
struct sockaddr *addr;
wchar_t name[NAME_SIZE];
int family, error;
error = getifaddrs(&ifaddr);
if (error != 0) {
perror("getifaddrs");
return 0;
}
memset(ns, 0, sizeof(struct network_interface) * max_ns);
for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
mbswszcopy(name, ifa->ifa_name, NAME_SIZE);
addr = ifa->ifa_addr;
family = addr->sa_family;
n = add_interface(ns, name, max_ns);
if (family == AF_INET) {
ipv4copy(&n->ip_address, addr);
} else if (family == AF_INET6) {
ipv6copy(&n->ip6_address, addr);
} else if (family == AF_PACKET) {
maccopy(n->mac_address, addr);
}
}
freeifaddrs(ifaddr);
return count_interfaces(ns, max_ns);
}