Bug 125263 - KInfoCenter Network Interfaces doesn't show all active interfaces
Summary: KInfoCenter Network Interfaces doesn't show all active interfaces
Status: RESOLVED FIXED
Alias: None
Product: kcontrol
Classification: Miscellaneous
Component: kcminfo (show other bugs)
Version: unspecified
Platform: unspecified Linux
: NOR normal
Target Milestone: ---
Assignee: Helge Deller
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-04-10 01:53 UTC by David Liontooth
Modified: 2006-05-26 22:27 UTC (History)
0 users

See Also:
Latest Commit:
Version Fixed In:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description David Liontooth 2006-04-10 01:53:27 UTC
Version:            (using KDE 3.5.2, Debian Package 4:3.5.2-2 (testing/unstable))
Compiler:          Target: x86_64-linux-gnu
OS:                Linux (x86_64) release 2.6.16

In KInfoCenter's menu item Network Interfaces, on three different machines, I see only lo (and on one machine VMware's vmnet1).

Previous bugs, Bug 50405 and Bug 12257, report a similar problem and the issue may have been partially resolved, but clearly not fully. 

Two of these machines have fixed ip addresses and one has dhcp. The two with fixed addresses each have two live NICs, neither of which show up.

Dave
Comment 1 David Liontooth 2006-04-10 02:01:41 UTC
Perhaps this is amd64-specific? On an i386 machine running the same Debian sid, eth0 shows up. The configuration files (/etc/network/interfaces) are identical aside from one digit in the address:

auto eth0
iface eth0 inet static
        address 128.xx.xxx.xx
        netmask 255.255.255.192
        broadcast 128.xx.xxx.255
        gateway 128.xx.xxx.1

# route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
128.xx.xxx.xx    *          255.255.255.192     U     0      0        0 eth0
default         xxx-r000.xxxnet 0.0.0.0         UG    0      0        0 eth0

Dave
Comment 2 Helge Deller 2006-04-11 22:02:19 UTC
Can you send the output of /sbin/ifconfig of both machines (the working and non-working ones). And, do you have IPv6 enabled (I assume not, since in your route above there is only IPv4) ?
Comment 3 David Liontooth 2006-04-12 03:42:06 UTC
Correct, this is all IPv4. Here's an example from a 64-bit (amd64) that kinfocenter does not display correctly:

th0      Link encap:Ethernet  HWaddr 00:14:85:XX:E0:A4
          inet addr:128.xx.xxx.xxx  Bcast:128.xx.xxx.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:4448624 errors:0 dropped:0 overruns:0 frame:0
          TX packets:3180440 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:1034528306 (986.6 MiB)  TX bytes:4148680254 (3.8 GiB)
          Interrupt:19 Memory:fb000000-0

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:536599 errors:0 dropped:0 overruns:0 frame:0
          TX packets:536599 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:643279034 (613.4 MiB)  TX bytes:643279034 (613.4 MiB)

Here's an example from an i686 machine that kinfocenter displays correctly:

eth0      Link encap:Ethernet  HWaddr 00:0A:xx:1A:43:3D
          inet addr:128.xx.xxx.xx  Bcast:128.xx.xxx.255  Mask:255.255.255.192
          IPX/Ethernet 802.3 addr:00EFF225:000A5E1A433D
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:112704579 errors:0 dropped:0 overruns:0 frame:0
          TX packets:69987989 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:1232641013 (1.1 GiB)  TX bytes:2617804941 (2.4 GiB)
          Interrupt:11 Memory:faffc000-0

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:77856 errors:0 dropped:0 overruns:0 frame:0
          TX packets:77856 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:408294818 (389.3 MiB)  TX bytes:408294818 (389.3 MiB)

This doesn't appear to be very informative, as ifconfig looks normal in both cases. Strace -f kinfocenter is a bit more informative. The one where kinfocenter doesn't display eth0:

[pid 16339] socket(PF_INET, SOCK_DGRAM, IPPROTO_IP) = 15
[pid 16339] ioctl(15, SIOCGIFCONF, {80, {{"lo", {AF_INET, inet_addr("127.0.0.1")}}, {"eth0", {AF_INET, inet_addr("128.xx.xxx.xx")}}}}) = 0
[pid 16339] ioctl(15, SIOCGIFFLAGS, {ifr_name="lo", ifr_flags=IFF_UP|IFF_LOOPBACK|IFF_RUNNING}) = 0
[pid 16339] ioctl(15, SIOCGIFNETMASK, {ifr_name="lo", ifr_netmask={AF_INET, inet_addr("255.0.0.0")}}) = 0
[pid 16339] ioctl(15, SIOCGIFHWADDR, {ifr_name="lo", ifr_hwaddr=00:00:00:00:00:00}) = 0
[pid 16339] write(4, "F\0\5\0\341\3\340\2B\1\340\2\0\0\0\0Z\0!\0008\0\7\0\17"..., 944) = 944
[pid 16339] ioctl(4, FIONREAD, [0])     = 0

This strace shows that "eth0" and the correct IP address is read by kinfocenter, but not pursued for some reason.

The working one shows a similar beginning, but eth0 is here pursued:

[pid  7510] socket(PF_INET, SOCK_DGRAM, IPPROTO_IP) = 15
[pid  7510] ioctl(15, SIOCGIFCONF, {64, {{"lo", {AF_INET, inet_addr("127.0.0.1")}}, {"eth0", {AF_INET, inet_addr("128.xx.xxx.xx")}}}}) = 0
[pid  7510] ioctl(15, SIOCGIFFLAGS, {ifr_name="lo", ifr_flags=IFF_UP|IFF_LOOPBACK|IFF_RUNNING}) = 0
[pid  7510] ioctl(15, SIOCGIFNETMASK, {ifr_name="lo", ifr_netmask={AF_INET, inet_addr("255.0.0.0")}}) = 0
[pid  7510] ioctl(15, SIOCGIFHWADDR, {ifr_name="lo", ifr_hwaddr=00:00:00:00:00:00}) = 0
[pid  7510] ioctl(15, SIOCGIFFLAGS, {ifr_name="eth0", ifr_flags=IFF_UP|IFF_BROADCAST|IFF_RUNNING|IFF_MULTICAST}) = 0
[pid  7510] ioctl(15, SIOCGIFNETMASK, {ifr_name="eth0", ifr_netmask={AF_INET, inet_addr("255.255.255.192")}}) = 0
[pid  7510] ioctl(15, SIOCGIFHWADDR, {ifr_name="eth0", ifr_hwaddr=00:0a:5e:xx:43:3d}) = 0

Let me know if there's anything I can add.

Dave

Comment 4 Helge Deller 2006-04-12 19:03:10 UTC
Are you able to compile this module yourself ?
I'm pretty sure, that the problem is somehow in 
kdebase/kcontrol/nics/nic.cpp (around line 169):

   for (char* ptr = buf; ptr < buf + ifc.ifc_len; )
   {
      struct ifreq *ifr =(struct ifreq *) ptr;
      int len = sizeof(struct sockaddr);
#ifdef  HAVE_STRUCT_SOCKADDR_SA_LEN
      if (ifr->ifr_addr.sa_len > len)
         len = ifr->ifr_addr.sa_len;            /* length > 16 */
#endif
      ptr += sizeof(ifr->ifr_name) + len;       /* for next one in buffer */

The question is, why the loop exits (ptr < buf + ifc.ifc_len) and if the calculation of the next nic is correct (inside the #ifdef ... #endif clause).
You might just comment out or delete the #ifdef ... #endif part and try.
I'm not sure why it doesn't work on AMD64.
Furthermore, is HAVE_STRUCT_SOCKADDR_SA_LEN #defined in your top level config.h file or not. It's not on my ia32 box, but maybe it's on your AMD64 which is why this part is executed...

Helge
Comment 5 Daniel Eklöf 2006-05-26 15:38:07 UTC
I have the same problem on my amd64 box. HAVE_STRUCT_SOCKADDR_SA_LEN is not defined.

Some points of interrest:

1. sizeof(ifr->ifr_name) == 16
2. sizeof(struct sockaddr) == 16
3. sizeof(*ifr) == 40

Thus, the way things work right now, ptr is increased with 32 bytes in each iteration, when we should be adding 40. Changing

 ptr += sizeof(ifr->ifr_name) + len;       /* for next one in buffer */ 

to

 ptr += sizeof(*ifr);

works; all interfaces with an IPv4 address is detected and displayed.

I'm not sure why the code does it the way it currently does. Perhaps the change I'm suggesting will break on other platforms?
Comment 6 Helge Deller 2006-05-26 22:27:31 UTC
SVN commit 545108 by deller:

fix (hopefully) nic information on AMD64 and others.
Patch analysis and suggestion by Daniel Eklöf.
BUG: 125263
(can someone who is working on HEAD please forward-port it ?)


 M  +4 -2      nic.cpp  


--- branches/KDE/3.5/kdebase/kcontrol/nics/nic.cpp #545107:545108
@@ -164,12 +164,14 @@
    for (char* ptr = buf; ptr < buf + ifc.ifc_len; )
    {
       struct ifreq *ifr =(struct ifreq *) ptr;
+#ifdef	HAVE_STRUCT_SOCKADDR_SA_LEN
       int len = sizeof(struct sockaddr);
-#ifdef	HAVE_STRUCT_SOCKADDR_SA_LEN
       if (ifr->ifr_addr.sa_len > len)
          len = ifr->ifr_addr.sa_len;		/* length > 16 */
+      ptr += sizeof(ifr->ifr_name) + len;	/* for next one in buffer */
+#else
+      ptr += sizeof(*ifr);			/* for next one in buffer */
 #endif
-      ptr += sizeof(ifr->ifr_name) + len;	/* for next one in buffer */
 
       int flags;
       struct sockaddr_in *sinptr;