Sync with upstream CVS, complete log: Revision 1.58 - Thu Oct 2 23:31:04 2008 UTC by ecki Avoid segfault of ifconfig(8) on missing /proc/net/dev (Debian Bug #222209 Pierre Lombard, Tollef Fog Heen) Revision 1.57 - Tue Dec 10 00:56:41 2002 UTC by ecki - change columns of netstat -i/ifconfig -s to avoid run-into (Stefan Illner) - prevent segfault on protocol families without host error member - use /128 as default prefix if not specified instead of /0 Revision 1.56 - Fri Jul 5 17:36:02 2002 UTC by ecki Jack Bloch noticed that the hw comamnd of ifconfig returns a confusing -EBUSY if interface is up (on lkml). Revision 1.55 - Wed Jul 3 23:40:47 2002 UTC by ecki there is no such thing as -i option for ifconfig removed variable, fixed usage, added options to english man page Revision 1.54 - Thu Nov 1 03:00:13 2001 UTC by ecki delay the setting of netmask derived from /mask after setting address (Debian Bug #116573 reported by Brian Warner) Revision 1.53 - Thu Nov 1 01:54:49 2001 UTC by ecki minor fix to return E_USAGE on -V instead of exit(0); Revision 1.52 - Thu Nov 1 01:48:31 2001 UTC by ecki failed to set error flag if netmask setting reported an error (Debian Bug #117837 reported by Sam Clegg) Revision 1.51 - Fri Jun 29 03:48:51 2001 UTC by ecki this will check after clearing a flag, that it is indeed cleared. it will also be a bit more verbose and precise on errors. See Debian Bug #102474 Index: net-tools/ifconfig.c =================================================================== --- net-tools.orig/ifconfig.c +++ net-tools/ifconfig.c @@ -3,7 +3,7 @@ * that either displays or sets the characteristics of * one or more of the system's networking interfaces. * - * Version: $Id: ifconfig.c,v 1.50 2001/04/13 18:25:18 pb Exp $ + * Version: $Id: ifconfig.c,v 1.58 2008/10/02 23:31:04 ecki Exp $ * * Author: Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org> * and others. Copyright 1993 MicroWalt Corporation @@ -88,7 +88,6 @@ struct in6_ifreq { char *Release = RELEASE, *Version = "ifconfig 1.42 (2001-04-13)"; int opt_a = 0; /* show all interfaces */ -int opt_i = 0; /* show the statistics */ int opt_v = 0; /* debugging output flag */ int addr_family = 0; /* currently selected AF */ @@ -105,7 +104,7 @@ static int if_print(char *ifname) int res; if (ife_short) - printf(_("Iface MTU Met RX-OK RX-ERR RX-DRP RX-OVR TX-OK TX-ERR TX-DRP TX-OVR Flg\n")); + printf(_("Iface MTU Met RX-OK RX-ERR RX-DRP RX-OVR TX-OK TX-ERR TX-DRP TX-OVR Flg\n")); if (!ifname) { res = for_all_interfaces(do_if_print, &opt_a); @@ -113,6 +112,9 @@ static int if_print(char *ifname) struct interface *ife; ife = lookup_interface(ifname); + if (!ife) { + return -1; + } res = do_if_fetch(ife); if (res >= 0) ife_print(ife); @@ -127,7 +129,7 @@ static int set_flag(char *ifname, short safe_strncpy(ifr.ifr_name, ifname, IFNAMSIZ); if (ioctl(skfd, SIOCGIFFLAGS, &ifr) < 0) { - fprintf(stderr, _("%s: unknown interface: %s\n"), + fprintf(stderr, _("%s: ERROR while getting interface flags: %s\n"), ifname, strerror(errno)); return (-1); } @@ -159,7 +161,7 @@ static int clr_flag(char *ifname, short safe_strncpy(ifr.ifr_name, ifname, IFNAMSIZ); if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) { - fprintf(stderr, _("%s: unknown interface: %s\n"), + fprintf(stderr, _("%s: ERROR while getting interface flags: %s\n"), ifname, strerror(errno)); return -1; } @@ -172,9 +174,35 @@ static int clr_flag(char *ifname, short return (0); } +/** test is a specified flag is set */ +static int test_flag(char *ifname, short flags) +{ + struct ifreq ifr; + int fd; + + if (strchr(ifname, ':')) { + /* This is a v4 alias interface. Downing it via a socket for + another AF may have bad consequences. */ + fd = get_socket_for_af(AF_INET); + if (fd < 0) { + fprintf(stderr, _("No support for INET on this system.\n")); + return -1; + } + } else + fd = skfd; + + safe_strncpy(ifr.ifr_name, ifname, IFNAMSIZ); + if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) { + fprintf(stderr, _("%s: ERROR while testing interface flags: %s\n"), + ifname, strerror(errno)); + return -1; + } + return (ifr.ifr_flags & flags); +} + static void usage(void) { - fprintf(stderr, _("Usage:\n ifconfig [-a] [-i] [-v] [-s] <interface> [[<AF>] <address>]\n")); + fprintf(stderr, _("Usage:\n ifconfig [-a] [-v] [-s] <interface> [[<AF>] <address>]\n")); #if HAVE_AFINET fprintf(stderr, _(" [add <address>[/<prefixlen>]]\n")); fprintf(stderr, _(" [del <address>[/<prefixlen>]]\n")); @@ -208,7 +236,7 @@ static void usage(void) static void version(void) { fprintf(stderr, "%s\n%s\n", Release, Version); - exit(0); + exit(E_USAGE); } static int set_netmask(int skfd, struct ifreq *ifr, struct sockaddr *sa) @@ -222,18 +250,19 @@ static int set_netmask(int skfd, struct strerror(errno)); err = 1; } - return 0; + return err; } int main(int argc, char **argv) { struct sockaddr sa; + struct sockaddr samask; struct sockaddr_in sin; char host[128]; struct aftype *ap; struct hwtype *hw; struct ifreq ifr; - int goterr = 0, didnetmask = 0; + int goterr = 0, didnetmask = 0, neednetmask=0; char **spp; int fd; #if HAVE_AFINET6 @@ -388,6 +417,8 @@ int main(int argc, char **argv) } if (!strcmp(*spp, "-promisc")) { goterr |= clr_flag(ifr.ifr_name, IFF_PROMISC); + if (test_flag(ifr.ifr_name, IFF_PROMISC) > 0) + fprintf(stderr, _("Warning: Interface %s still in promisc mode... maybe other application is running?\n"), ifr.ifr_name); spp++; continue; } @@ -398,6 +429,8 @@ int main(int argc, char **argv) } if (!strcmp(*spp, "-multicast")) { goterr |= clr_flag(ifr.ifr_name, IFF_MULTICAST); + if (test_flag(ifr.ifr_name, IFF_MULTICAST) > 0) + fprintf(stderr, _("Warning: Interface %s still in MULTICAST mode.\n"), ifr.ifr_name); spp++; continue; } @@ -408,6 +441,8 @@ int main(int argc, char **argv) } if (!strcmp(*spp, "-allmulti")) { goterr |= clr_flag(ifr.ifr_name, IFF_ALLMULTI); + if (test_flag(ifr.ifr_name, IFF_MULTICAST) > 0) + fprintf(stderr, _("Warning: Interface %s still in ALLMULTI mode.\n"), ifr.ifr_name); spp++; continue; } @@ -430,6 +465,8 @@ int main(int argc, char **argv) if (!strcmp(*spp, "-dynamic")) { goterr |= clr_flag(ifr.ifr_name, IFF_DYNAMIC); spp++; + if (test_flag(ifr.ifr_name, IFF_MULTICAST) > 0) + fprintf(stderr, _("Warning: Interface %s still in DYNAMIC mode.\n"), ifr.ifr_name); continue; } #endif @@ -486,6 +523,8 @@ int main(int argc, char **argv) if (!strcmp(*spp, "-broadcast")) { goterr |= clr_flag(ifr.ifr_name, IFF_BROADCAST); + if (test_flag(ifr.ifr_name, IFF_MULTICAST) > 0) + fprintf(stderr, _("Warning: Interface %s still in BROADCAST mode.\n"), ifr.ifr_name); spp++; continue; } @@ -493,7 +532,10 @@ int main(int argc, char **argv) if (*++spp != NULL) { safe_strncpy(host, *spp, (sizeof host)); if (ap->input(0, host, &sa) < 0) { - ap->herror(host); + if (ap->herror) + ap->herror(host); + else + fprintf(stderr, _("ifconfig: Error resolving '%s' for broadcast\n"), host); goterr = 1; spp++; continue; @@ -515,7 +557,10 @@ int main(int argc, char **argv) usage(); safe_strncpy(host, *spp, (sizeof host)); if (ap->input(0, host, &sa) < 0) { - ap->herror(host); + if (ap->herror) + ap->herror(host); + else + fprintf(stderr, _("ifconfig: Error resolving '%s' for dstaddr\n"), host); goterr = 1; spp++; continue; @@ -535,13 +580,16 @@ int main(int argc, char **argv) usage(); safe_strncpy(host, *spp, (sizeof host)); if (ap->input(0, host, &sa) < 0) { - ap->herror(host); + if (ap->herror) + ap->herror(host); + else + fprintf(stderr, _("ifconfig: Error resolving '%s' for netmask\n"), host); goterr = 1; spp++; continue; } didnetmask++; - goterr = set_netmask(ap->fd, &ifr, &sa); + goterr |= set_netmask(ap->fd, &ifr, &sa); spp++; continue; } @@ -613,6 +661,8 @@ int main(int argc, char **argv) if (!strcmp(*spp, "-pointopoint")) { goterr |= clr_flag(ifr.ifr_name, IFF_POINTOPOINT); spp++; + if (test_flag(ifr.ifr_name, IFF_MULTICAST) > 0) + fprintf(stderr, _("Warning: Interface %s still in POINTOPOINT mode.\n"), ifr.ifr_name); continue; } if (!strcmp(*spp, "pointopoint")) { @@ -620,7 +670,10 @@ int main(int argc, char **argv) spp++; safe_strncpy(host, *spp, (sizeof host)); if (ap->input(0, host, &sa)) { - ap->herror(host); + if (ap->herror) + ap->herror(host); + else + fprintf(stderr, _("ifconfig: Error resolving '%s' for pointopoint\n"), host); goterr = 1; spp++; continue; @@ -661,8 +714,12 @@ int main(int argc, char **argv) memcpy((char *) &ifr.ifr_hwaddr, (char *) &sa, sizeof(struct sockaddr)); if (ioctl(skfd, SIOCSIFHWADDR, &ifr) < 0) { - fprintf(stderr, "SIOCSIFHWADDR: %s\n", - strerror(errno)); + if (errno == EBUSY) + fprintf(stderr, "SIOCSIFHWADDR: %s - you may need to down the interface\n", + strerror(errno)); + else + fprintf(stderr, "SIOCSIFHWADDR: %s\n", + strerror(errno)); goterr = 1; } spp++; @@ -681,12 +738,15 @@ int main(int argc, char **argv) usage(); *cp = 0; } else { - prefix_len = 0; + prefix_len = 128; } safe_strncpy(host, *spp, (sizeof host)); if (inet6_aftype.input(1, host, (struct sockaddr *) &sa6) < 0) { - inet6_aftype.herror(host); + if (inet6_aftype.herror) + inet6_aftype.herror(host); + else + fprintf(stderr, _("ifconfig: Error resolving '%s' for add\n"), host); goterr = 1; spp++; continue; @@ -771,7 +831,7 @@ int main(int argc, char **argv) usage(); *cp = 0; } else { - prefix_len = 0; + prefix_len = 128; } safe_strncpy(host, *spp, (sizeof host)); if (inet6_aftype.input(1, host, @@ -800,6 +860,8 @@ int main(int argc, char **argv) } ifr6.ifr6_ifindex = ifr.ifr_ifindex; ifr6.ifr6_prefixlen = prefix_len; + if (opt_v) + fprintf(stderr, "now deleting: ioctl(SIOCDIFADDR,{ifindex=%d,prefixlen=%ld})\n",ifr.ifr_ifindex,prefix_len); if (ioctl(fd, SIOCDIFADDR, &ifr6) < 0) { fprintf(stderr, "SIOCDIFADDR: %s\n", strerror(errno)); @@ -859,7 +921,7 @@ int main(int argc, char **argv) usage(); *cp = 0; } else { - prefix_len = 0; + prefix_len = 128; } safe_strncpy(host, *spp, (sizeof host)); if (inet6_aftype.input(1, host, (struct sockaddr *) &sa6) < 0) { @@ -903,7 +965,7 @@ int main(int argc, char **argv) /* FIXME: sa is too small for INET6 addresses, inet6 should use that too, broadcast is unexpected */ if (ap->getmask) { - switch (ap->getmask(host, &sa, NULL)) { + switch (ap->getmask(host, &samask, NULL)) { case -1: usage(); break; @@ -911,8 +973,8 @@ int main(int argc, char **argv) if (didnetmask) usage(); - goterr = set_netmask(skfd, &ifr, &sa); - didnetmask++; + // remeber to set the netmask from samask later + neednetmask = 1; break; } } @@ -921,9 +983,11 @@ int main(int argc, char **argv) exit(1); } if (ap->input(0, host, &sa) < 0) { - ap->herror(host); - fprintf(stderr, _("ifconfig: `--help' gives usage information.\n")); - exit(1); + if (ap->herror) + ap->herror(host); + else + fprintf(stderr,_("ifconfig: error resolving '%s' to set address for af=%s\n"), host, ap->name); fprintf(stderr, + _("ifconfig: `--help' gives usage information.\n")); exit(1); } memcpy((char *) &ifr.ifr_addr, (char *) &sa, sizeof(struct sockaddr)); { @@ -980,6 +1044,14 @@ int main(int argc, char **argv) spp++; } + if (neednetmask) { + goterr |= set_netmask(skfd, &ifr, &samask); + didnetmask++; + } + + if (opt_v && goterr) + fprintf(stderr, _("WARNING: at least one error occured. (%d)\n"), goterr); + return (goterr); }