Based on Dustin's report of manually using ifconfig (probably the simplest scenario that can cause -ENOBUFS), I've looked at the source-code for ifconfig in the net-tools package.
Would it be possible for one or more of you to single-step through a simple ifconfig scenario using gdb to pin-point which code-path is issuing the error?
There are only two instances of perror("SIOCSIFADDR") - one is in the IPv6 code-path which should only get triggered when a colon is found in the address string. This should get you started:
# set IFACE here to the one having problems
IFACE=eth0
# debug
gdb --args ifconfig $IFACE 10.0.0.1
At this point the gdb command prompt appears, and gdb commands are active. Use "help" to learn more.
(gdb) break 997
Breakpoint 1 at 0x4047b4: file ifconfig.c, line 997.
(gdb) run
Starting program: /home/all/SourceCode/net-tools-1.60/ifconfig wlan0 10.254.251.51
Breakpoint 1, main (argc=2, argv=0x7fff13b3f1f0) at ifconfig.c:998
998 fd = get_socket_for_af(AF_INET);
(gdb) display r
1: r = 0
(gdb) next
999 if (fd < 0) {
1: r = 0
(gdb) next
1003 r = ioctl(fd, SIOCSIFADDR, &ifr);
1: r = 0
(gdb) next
1021 if (r < 0) {
1: r = 0
(gdb)
At this point, if "r" is less than 0 there has been an IOCTL error. The value of -ENOBUFS is -105 and comes from the kernel:
include/asm-generic/errno.h:78:#define ENOBUFS 105 /* No buffer space available */
Assuming it is this code-path the code-fragment is:
#if HAVE_AFINET
case AF_INET:
fd = get_socket_for_af(AF_INET);
if (fd < 0) {
fprintf(stderr, _("No support for INET on this system.\n"));
exit(1);
}
r = ioctl(fd, SIOCSIFADDR, &ifr);
break;
If it is, this will confirm my earlier report that the error comes from the kernel's IOCTL handler net/ipv4/devinit.c::devinet_ioctl()
Quit gdb with:
(gdb) quit
# back to shell and regular user log-in privileges
exit
Based on Dustin's report of manually using ifconfig (probably the simplest scenario that can cause -ENOBUFS), I've looked at the source-code for ifconfig in the net-tools package.
Would it be possible for one or more of you to single-step through a simple ifconfig scenario using gdb to pin-point which code-path is issuing the error?
There are only two instances of perror( "SIOCSIFADDR" ) - one is in the IPv6 code-path which should only get triggered when a colon is found in the address string. This should get you started:
apt-get source net-tools
cd net-tools-1.60
# copy the build configuration files
cp debian/config.h config.h
cp debian/config.make config.make
# enable debug symbols, disable optimisations
sed -i '/^COPTS/ s/# -g/ -g #/' -e '/^COPTS/ s/-O2//' Makefile
# build
make ifconfig
# switch to root
sudo -s
# set IFACE here to the one having problems
IFACE=eth0
# debug
gdb --args ifconfig $IFACE 10.0.0.1
At this point the gdb command prompt appears, and gdb commands are active. Use "help" to learn more.
(gdb) break 997 SourceCode/ net-tools- 1.60/ifconfig wlan0 10.254.251.51
Breakpoint 1 at 0x4047b4: file ifconfig.c, line 997.
(gdb) run
Starting program: /home/all/
Breakpoint 1, main (argc=2, argv=0x7fff13b3 f1f0) at ifconfig.c:998 for_af( AF_INET) ;
998 fd = get_socket_
(gdb) display r
1: r = 0
(gdb) next
999 if (fd < 0) {
1: r = 0
(gdb) next
1003 r = ioctl(fd, SIOCSIFADDR, &ifr);
1: r = 0
(gdb) next
1021 if (r < 0) {
1: r = 0
(gdb)
At this point, if "r" is less than 0 there has been an IOCTL error. The value of -ENOBUFS is -105 and comes from the kernel:
include/ asm-generic/ errno.h: 78:#define ENOBUFS 105 /* No buffer space available */
Assuming it is this code-path the code-fragment is:
#if HAVE_AFINET for_af( AF_INET) ; stderr, _("No support for INET on this system.\n"));
case AF_INET:
fd = get_socket_
if (fd < 0) {
fprintf(
exit(1);
}
r = ioctl(fd, SIOCSIFADDR, &ifr);
break;
If it is, this will confirm my earlier report that the error comes from the kernel's IOCTL handler net/ipv4/ devinit. c::devinet_ ioctl()
Quit gdb with:
(gdb) quit
# back to shell and regular user log-in privileges
exit