[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#312554: libc6: if_nameindex(3) returns broken list of network interfaces



Package: libc6
Version: 2.3.2.ds1-22
Severity: normal


if_nameindex(3) returns only a subset of all network interfaces, and
lists some of them multiple times. This contradicts the man page
if_nameindex(3posix) and the libc6.info docs which state

   NAME
       if_nameindex - return all network interface names and indexes

and

   -- Function: struct if_nameindex * if_nameindex (void)
        This function returns an array of `if_nameindex'
        structures, one for every interface that is present.

respectively.

The returned list

  - does not contain "all network interface names" like the man page says.
    It only includes those which have an IPv4 address configured on them.

  - does not contain "one [structure] for every interface present" like
    the libc6 info page says.
    It contains one if_nameindex structure for every IPv4 address
    configured on the interface.

According to empirical studies, the list returned by if_nameindex(3)
is determined according to this logic:

     return_list = []
     for interface in list_of_all_interfaces:
        if is_up(interface):
            for ipv4_addr in addr_list(interface, AF_INET):
                return_list.append(interface)
     return return_list
 
However, the if_nameindex documentation suggests that the list
should be created using this logic:
 
     return_list = []
     for interface in list_of_all_interfaces:
        if is_up(interface):
            return_list.append(interface)
     return return_list

I used this short test program:

#include <stdio.h>
#include <net/if.h>

int main(int argc, char *argv[])
{
	int i;
	struct if_nameindex *ifs = if_nameindex();
	if (ifs == NULL) {
		perror("could not run if_nameindex");
		return 1;
	}
	for (i=0; (i>=0) && 
		(ifs[i].if_index != 0) && (ifs[i].if_name != NULL);
		i++)
	{
		printf("%3d  %3d  %s\n", i, ifs[i].if_index, ifs[i].if_name);
	}
	if_freenameindex(ifs);
}

In my case, this program prints

  0    1  lo
  1    1  lo
  2   12  eth0
  3   12  eth0
  4   12  eth0

while I have an additional interface dummy0 which is up, but has no IPv4
addresses configured. The complete output of "ip addr" is as follows:

1: lo: <LOOPBACK,UP> mtu 16436 qdisc noqueue 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
    inet 169.254.185.103/16 scope link lo
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
12: eth0: <BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast qlen 1000
    link/ether aa::bb:cc:dd:ee brd ff:ff:ff:ff:ff:ff
    inet 169.254.28.139/16 scope link eth0
    inet 192.168.1.2/24 brd 192.168.1.255 scope global eth0
    inet 192.168.1.1/24 scope global eth0
    inet6 2001:6f8:abcd:abcd::1007/64 scope global 
       valid_lft forever preferred_lft forever
    [ ... another 10 inet6 addrs deleted ... ]
13: dummy0: <BROADCAST,NOARP,UP> mtu 1500 qdisc noqueue 
    link/ether 56:b4:4e:e7:91:3a brd ff:ff:ff:ff:ff:ff
    inet6 2001:6f8:abcd:abce::1007/128 scope global 
       valid_lft forever preferred_lft forever
    [ ... another 10 inet6 addrs deleted ... ]

This behaviour plainly contradicts the documentation.

I suggest as solutions to either:

  a) simplify the logic behind if_nameindex(3) such that it lists all
     interfaces in state "up" regardless of any addresses possibly
     configured on them
  b) change the info documentation to actually describe the current
     behaviour of "List all interfaces with IPv4 addresses configured
     as many times as the number of IPv4 addresses on the interface.
     This violates the POSIX definition of if_nameindex." :-)

The described erroneous behaviour also occurs with the stock Debian
kernel from kernel-image-2.6.8-2-686 2.6.8-16, so this is not an
issue specific to a certain version of the Linux kernel.

-- System Information:
Debian Release: 3.1
  APT prefers unstable
  APT policy: (700, 'unstable'), (100, 'experimental')
Architecture: i386 (i686)
Kernel: Linux 2.6.11.10-swsusp2-ndim-2
Locale: LANG=C, LC_CTYPE=de_DE.UTF-8 (charmap=UTF-8)

Versions of packages libc6 depends on:
ii  libdb1-compat                 2.1.3-7    The Berkeley database routines [gl

-- no debconf information



Reply to: