Hello
I have a problem with retreiving network interface list using IOCTLs. I have 4 interfaces:
$ ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast state DOWN qlen 1000
link/ether 00:1d:ba:39:f2:8d brd ff:ff:ff:ff:ff:ff
3: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000
link/ether 00:21:5c:0d:ad:15 brd ff:ff:ff:ff:ff:ff
inet 192.168.2.5/24 brd 192.168.2.255 scope global wlan0
inet6 fe80::221:5cff:fe0d:ad15/64 scope link
valid_lft forever preferred_lft forever
4: pan0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN
link/ether ae:97:70:65:ed:95 brd ff:ff:ff:ff:ff:ff
But in my program just the lo interface is found. Why can't I get all interfaces?
Here's the code:
struct interface {
char ifname[MAXINTFNAME_LEN];
uint8_t addr[MACADDR_LEN];
int if_index;
struct sockaddr_in if_broadaddr;
};
int get_interface_info(struct interface* interf)
{
struct ifreq ifr;
struct ifreq *ifr_arr;
struct ifconf ifc;
int found = 0;
char buf[1024] = {'\0'};
int s = 0, ret = 0, i = 0;
if (!interf || interf->ifname==NULL)
return -1;
memset(&ifr, 0, sizeof ifr);
memset(&ifc, 0, sizeof ifc);
s = socket(AF_INET, SOCK_DGRAM, 0);
if (s==-1) {
return -1;
}
ifc.ifc_len = sizeof(buf);
ifc.ifc_buf = buf;
ioctl(s, SIOCGIFCONF, &ifc);
ifr_arr = ifc.ifc_req;
for (i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; ifr_arr++) {
if (!strcmp(ifr_arr->ifr_name, interf->ifname)) {
strcpy(ifr.ifr_name, interf->ifname);
if (0 == (ret=ioctl(s, SIOCGIFFLAGS, &ifr))) {
if (0 == (ret=ioctl(s, SIOCGIFHWADDR, &ifr))) {
memcpy(interf->addr, ifr.ifr_hwaddr.sa_data, MACADDR_LEN);
if (0 ==(ret=ioctl(s, SIOCGIFINDEX, &ifr))) {
interf->if_index = ifr.ifr_ifindex;
}
if (0 == (ret=ioctl(s, SIOCGIFBRDADDR, &ifr))) {
memset(&(interf->if_broadaddr), 0x0, sizeof(interf->if_broadaddr));
memcpy(&(interf->if_broadaddr), (struct sockaddr_in*)(&(ifr.ifr_ifru.ifru_broadaddr)), sizeof(ifr.ifr_ifru.ifru_broadaddr));
}
}
}
found = 1;
break;
}
}
close(s);
if (!found)
return -2;
return ret;
}
My system is Linux 2.6.31