CBL-Mariner/SPECS/net-tools/CVS-20081002-ifconfig.c_syn...

380 lines
12 KiB
Diff

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);
}