Radix cross Linux

The main Radix cross Linux repository contains the build scripts of packages, which have the most complete and common functionality for desktop machines

452 Commits   2 Branches   1 Tag
     5         kx /*
     5         kx  * ifconfig   This file contains an implementation of the command
     5         kx  *              that either displays or sets the characteristics of
     5         kx  *              one or more of the system's networking interfaces.
     5         kx  *
     5         kx  * Version:     $Id: ifconfig.c,v 1.59 2011-01-01 03:22:31 ecki Exp $
     5         kx  *
     5         kx  * Author:      Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
     5         kx  *              and others.  Copyright 1993 MicroWalt Corporation
     5         kx  *
     5         kx  *              This program is free software; you can redistribute it
     5         kx  *              and/or  modify it under  the terms of  the GNU General
     5         kx  *              Public  License as  published  by  the  Free  Software
     5         kx  *              Foundation;  either  version 2 of the License, or  (at
     5         kx  *              your option) any later version.
     5         kx  *
     5         kx  * Patched to support 'add' and 'del' keywords for INET(4) addresses
     5         kx  * by Mrs. Brisby <mrs.brisby@nimh.org>
     5         kx  *
     5         kx  * {1.34} - 19980630 - Arnaldo Carvalho de Melo <acme@conectiva.com.br>
     5         kx  *                     - gettext instead of catgets for i18n
     5         kx  *          10/1998  - Andi Kleen. Use interface list primitives.
     5         kx  *	    20001008 - Bernd Eckenfels, Patch from RH for setting mtu
     5         kx  *			(default AF was wrong)
     5         kx  *          20010404 - Arnaldo Carvalho de Melo, use setlocale
     5         kx  */
     5         kx 
     5         kx #define DFLT_AF "inet"
     5         kx 
     5         kx #include "config.h"
     5         kx 
     5         kx #include <features.h>
     5         kx #include <sys/types.h>
     5         kx #include <sys/socket.h>
     5         kx #include <sys/ioctl.h>
     5         kx #include <netinet/in.h>
     5         kx #include <net/if.h>
     5         kx #include <net/if_arp.h>
     5         kx #include <stdio.h>
     5         kx #include <errno.h>
     5         kx #include <fcntl.h>
     5         kx #include <ctype.h>
     5         kx #include <stdlib.h>
     5         kx #include <string.h>
     5         kx #include <unistd.h>
     5         kx #include <netdb.h>
     5         kx 
     5         kx /* Ugh.  But libc5 doesn't provide POSIX types.  */
     5         kx #include <asm/types.h>
     5         kx 
     5         kx 
     5         kx #if HAVE_HWSLIP
     5         kx #include <linux/if_slip.h>
     5         kx #endif
     5         kx 
     5         kx #if HAVE_AFINET6
     5         kx 
     5         kx #ifndef _LINUX_IN6_H
     5         kx /*
     5         kx  *    This is in linux/include/net/ipv6.h.
     5         kx  */
     5         kx 
     5         kx struct in6_ifreq {
     5         kx     struct in6_addr ifr6_addr;
     5         kx     __u32 ifr6_prefixlen;
     5         kx     unsigned int ifr6_ifindex;
     5         kx };
     5         kx 
     5         kx #endif
     5         kx 
     5         kx #endif				/* HAVE_AFINET6 */
     5         kx 
     5         kx #if HAVE_AFIPX
     5         kx #if (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1)
     5         kx #include <netipx/ipx.h>
     5         kx #else
     5         kx #include "ipx.h"
     5         kx #endif
     5         kx #endif
     5         kx #include "net-support.h"
     5         kx #include "pathnames.h"
     5         kx #include "version.h"
     5         kx #include "../intl.h"
     5         kx #include "interface.h"
     5         kx #include "sockets.h"
     5         kx #include "util.h"
     5         kx 
     5         kx static char *Release = RELEASE;
     5         kx 
     5         kx int opt_a = 0;			/* show all interfaces          */
     5         kx int opt_v = 0;			/* debugging output flag        */
     5         kx 
     5         kx int addr_family = 0;		/* currently selected AF        */
     5         kx 
     5         kx /* for ipv4 add/del modes */
     5         kx static int get_nmbc_parent(char *parent, in_addr_t *nm, in_addr_t *bc);
     5         kx static int set_ifstate(char *parent, in_addr_t ip, in_addr_t nm, in_addr_t bc,
     5         kx 		       int flag);
     5         kx 
     5         kx static int if_print(char *ifname)
     5         kx {
     5         kx     int res;
     5         kx 
     5         kx     if (ife_short)
     5         kx 	printf(_("Iface      MTU    RX-OK RX-ERR RX-DRP RX-OVR    TX-OK TX-ERR TX-DRP TX-OVR Flg\n"));
     5         kx 
     5         kx     if (!ifname) {
     5         kx 	res = for_all_interfaces(do_if_print, &opt_a);
     5         kx     } else {
     5         kx 	struct interface *ife;
     5         kx 
     5         kx 	ife = lookup_interface(ifname);
     5         kx 	if (!ife) {
     5         kx 		return -1;
     5         kx 	}
     5         kx 	res = do_if_fetch(ife);
     5         kx 	if (res >= 0)
     5         kx 	    ife_print(ife);
     5         kx     }
     5         kx     return res;
     5         kx }
     5         kx 
     5         kx /* Set a certain interface flag. */
     5         kx static int set_flag(char *ifname, short flag)
     5         kx {
     5         kx     struct ifreq ifr;
     5         kx 
     5         kx     safe_strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
     5         kx     if (ioctl(skfd, SIOCGIFFLAGS, &ifr) < 0) {
     5         kx 	fprintf(stderr, _("%s: ERROR while getting interface flags: %s\n"),
     5         kx 		ifname,	strerror(errno));
     5         kx 	return (-1);
     5         kx     }
     5         kx     safe_strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
     5         kx     ifr.ifr_flags |= flag;
     5         kx     if (ioctl(skfd, SIOCSIFFLAGS, &ifr) < 0) {
     5         kx 	perror("SIOCSIFFLAGS");
     5         kx 	return -1;
     5         kx     }
     5         kx     return (0);
     5         kx }
     5         kx 
     5         kx /* Clear a certain interface flag. */
     5         kx static int clr_flag(char *ifname, short flag)
     5         kx {
     5         kx     struct ifreq ifr;
     5         kx     int fd;
     5         kx 
     5         kx     if (strchr(ifname, ':')) {
     5         kx         /* This is a v4 alias interface.  Downing it via a socket for
     5         kx 	   another AF may have bad consequences. */
     5         kx         fd = get_socket_for_af(AF_INET);
     5         kx 	if (fd < 0) {
     5         kx 	    fprintf(stderr, _("No support for INET on this system.\n"));
     5         kx 	    return -1;
     5         kx 	}
     5         kx     } else
     5         kx         fd = skfd;
     5         kx 
     5         kx     safe_strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
     5         kx     if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) {
     5         kx 	fprintf(stderr, _("%s: ERROR while getting interface flags: %s\n"),
     5         kx 		ifname, strerror(errno));
     5         kx 	return -1;
     5         kx     }
     5         kx     safe_strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
     5         kx     ifr.ifr_flags &= ~flag;
     5         kx     if (ioctl(fd, SIOCSIFFLAGS, &ifr) < 0) {
     5         kx 	perror("SIOCSIFFLAGS");
     5         kx 	return -1;
     5         kx     }
     5         kx     return (0);
     5         kx }
     5         kx 
     5         kx /** test is a specified flag is set */
     5         kx static int test_flag(char *ifname, short flags)
     5         kx {
     5         kx     struct ifreq ifr;
     5         kx     int fd;
     5         kx 
     5         kx     if (strchr(ifname, ':')) {
     5         kx         /* This is a v4 alias interface.  Downing it via a socket for
     5         kx 	   another AF may have bad consequences. */
     5         kx         fd = get_socket_for_af(AF_INET);
     5         kx 	if (fd < 0) {
     5         kx 	    fprintf(stderr, _("No support for INET on this system.\n"));
     5         kx 	    return -1;
     5         kx 	}
     5         kx     } else
     5         kx         fd = skfd;
     5         kx 
     5         kx     safe_strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
     5         kx     if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) {
     5         kx 	fprintf(stderr, _("%s: ERROR while testing interface flags: %s\n"),
     5         kx 		ifname, strerror(errno));
     5         kx 	return -1;
     5         kx     }
     5         kx     return (ifr.ifr_flags & flags);
     5         kx }
     5         kx 
     5         kx static void usage(int rc)
     5         kx {
     5         kx     FILE *fp = rc ? stderr : stdout;
     5         kx     fprintf(fp, _("Usage:\n  ifconfig [-a] [-v] [-s] <interface> [[<AF>] <address>]\n"));
     5         kx #if HAVE_AFINET
     5         kx     fprintf(fp, _("  [add <address>[/<prefixlen>]]\n"));
     5         kx     fprintf(fp, _("  [del <address>[/<prefixlen>]]\n"));
     5         kx     fprintf(fp, _("  [[-]broadcast [<address>]]  [[-]pointopoint [<address>]]\n"));
     5         kx     fprintf(fp, _("  [netmask <address>]  [dstaddr <address>]  [tunnel <address>]\n"));
     5         kx #endif
     5         kx #ifdef SIOCSKEEPALIVE
     5         kx     fprintf(fp, _("  [outfill <NN>] [keepalive <NN>]\n"));
     5         kx #endif
     5         kx     fprintf(fp, _("  [hw <HW> <address>]  [mtu <NN>]\n"));
     5         kx     fprintf(fp, _("  [[-]trailers]  [[-]arp]  [[-]allmulti]\n"));
     5         kx     fprintf(fp, _("  [multicast]  [[-]promisc]\n"));
     5         kx     fprintf(fp, _("  [mem_start <NN>]  [io_addr <NN>]  [irq <NN>]  [media <type>]\n"));
     5         kx #ifdef HAVE_TXQUEUELEN
     5         kx     fprintf(fp, _("  [txqueuelen <NN>]\n"));
     5         kx #endif
     5         kx #ifdef SIOCSIFNAME
     5         kx     fprintf(fp, _("  [name <newname>]\n"));
     5         kx #endif
     5         kx #ifdef HAVE_DYNAMIC
     5         kx     fprintf(fp, _("  [[-]dynamic]\n"));
     5         kx #endif
     5         kx     fprintf(fp, _("  [up|down] ...\n\n"));
     5         kx 
     5         kx     fprintf(fp, _("  <HW>=Hardware Type.\n"));
     5         kx     fprintf(fp, _("  List of possible hardware types:\n"));
     5         kx     print_hwlist(0); /* 1 = ARPable */
     5         kx     fprintf(fp, _("  <AF>=Address family. Default: %s\n"), DFLT_AF);
     5         kx     fprintf(fp, _("  List of possible address families:\n"));
     5         kx     print_aflist(0); /* 1 = routeable */
     5         kx     exit(rc);
     5         kx }
     5         kx 
     5         kx static void version(void)
     5         kx {
     5         kx     printf("%s\n", Release);
     5         kx     exit(E_VERSION);
     5         kx }
     5         kx 
     5         kx static int set_netmask(int skfd, struct ifreq *ifr, struct sockaddr *sa)
     5         kx {
     5         kx     int err = 0;
     5         kx 
     5         kx     memcpy(&ifr->ifr_netmask, sa, sizeof(struct sockaddr));
     5         kx     if (ioctl(skfd, SIOCSIFNETMASK, ifr) < 0) {
     5         kx 	fprintf(stderr, "SIOCSIFNETMASK: %s\n",
     5         kx 		strerror(errno));
     5         kx 	err = 1;
     5         kx     }
     5         kx     return err;
     5         kx }
     5         kx 
     5         kx int main(int argc, char **argv)
     5         kx {
     5         kx     struct sockaddr_storage _sa, _samask;
     5         kx     struct sockaddr *sa = (struct sockaddr *)&_sa;
     5         kx     struct sockaddr *samask = (struct sockaddr *)&_samask;
     5         kx     struct sockaddr_in *sin = (struct sockaddr_in *)&_sa;
     5         kx     char host[128];
     5         kx     const struct aftype *ap;
     5         kx     const struct hwtype *hw;
     5         kx     struct ifreq ifr;
     5         kx     int goterr = 0, didnetmask = 0, neednetmask=0;
     5         kx     char **spp;
     5         kx     int fd;
     5         kx #if HAVE_AFINET6
     5         kx     extern struct aftype inet6_aftype;
     5         kx     struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&_sa;
     5         kx     struct in6_ifreq ifr6;
     5         kx     unsigned long prefix_len;
     5         kx     char *cp;
     5         kx #endif
     5         kx #if HAVE_AFINET
     5         kx     extern struct aftype inet_aftype;
     5         kx #endif
     5         kx 
     5         kx #if I18N
     5         kx     setlocale(LC_ALL, "");
     5         kx     bindtextdomain("net-tools", "/usr/share/locale");
     5         kx     textdomain("net-tools");
     5         kx #endif
     5         kx 
     5         kx     /* Find any options. */
     5         kx     argc--;
     5         kx     argv++;
     5         kx     while (argc && *argv[0] == '-') {
     5         kx 	if (!strcmp(*argv, "-a"))
     5         kx 	    opt_a = 1;
     5         kx 
     5         kx 	else if (!strcmp(*argv, "-s"))
     5         kx 	    ife_short = 1;
     5         kx 
     5         kx 	else if (!strcmp(*argv, "-v"))
     5         kx 	    opt_v = 1;
     5         kx 
     5         kx 	else if (!strcmp(*argv, "-V") || !strcmp(*argv, "-version") ||
     5         kx 	    !strcmp(*argv, "--version"))
     5         kx 	    version();
     5         kx 
     5         kx 	else if (!strcmp(*argv, "-?") || !strcmp(*argv, "-h") ||
     5         kx 	    !strcmp(*argv, "-help") || !strcmp(*argv, "--help"))
     5         kx 	    usage(E_USAGE);
     5         kx 
     5         kx 	else {
     5         kx 	    fprintf(stderr, _("ifconfig: option `%s' not recognised.\n"),
     5         kx 		    argv[0]);
     5         kx 	    fprintf(stderr, _("ifconfig: `--help' gives usage information.\n"));
     5         kx 	    exit(1);
     5         kx 	}
     5         kx 
     5         kx 	argv++;
     5         kx 	argc--;
     5         kx     }
     5         kx 
     5         kx     /* Create a channel to the NET kernel. */
     5         kx     if ((skfd = sockets_open(0)) < 0) {
     5         kx 	perror("socket");
     5         kx 	exit(1);
     5         kx     }
     5         kx 
     5         kx     /* Do we have to show the current setup? */
     5         kx     if (argc == 0) {
     5         kx 	int err = if_print((char *) NULL);
     5         kx 	(void) close(skfd);
     5         kx 	exit(err < 0);
     5         kx     }
     5         kx     /* No. Fetch the interface name. */
     5         kx     spp = argv;
     5         kx     safe_strncpy(ifr.ifr_name, *spp++, IFNAMSIZ);
     5         kx     if (*spp == (char *) NULL) {
     5         kx 	int err = if_print(ifr.ifr_name);
     5         kx 	(void) close(skfd);
     5         kx 	exit(err < 0);
     5         kx     }
     5         kx 
     5         kx     /* The next argument is either an address family name, or an option. */
     5         kx     if ((ap = get_aftype(*spp)) != NULL)
     5         kx 	spp++; /* it was a AF name */
     5         kx     else
     5         kx 	ap = get_aftype(DFLT_AF);
     5         kx 
     5         kx     if (ap) {
     5         kx 	addr_family = ap->af;
     5         kx 	skfd = ap->fd;
     5         kx     }
     5         kx 
     5         kx     /* Process the remaining arguments. */
     5         kx     while (*spp != (char *) NULL) {
     5         kx 	if (!strcmp(*spp, "arp")) {
     5         kx 	    goterr |= clr_flag(ifr.ifr_name, IFF_NOARP);
     5         kx 	    spp++;
     5         kx 	    continue;
     5         kx 	}
     5         kx 	if (!strcmp(*spp, "-arp")) {
     5         kx 	    goterr |= set_flag(ifr.ifr_name, IFF_NOARP);
     5         kx 	    spp++;
     5         kx 	    continue;
     5         kx 	}
     5         kx #ifdef IFF_PORTSEL
     5         kx 	if (!strcmp(*spp, "media") || !strcmp(*spp, "port")) {
     5         kx 	    if (*++spp == NULL)
     5         kx 		usage(E_OPTERR);
     5         kx 	    if (!strcasecmp(*spp, "auto")) {
     5         kx 		goterr |= set_flag(ifr.ifr_name, IFF_AUTOMEDIA);
     5         kx 	    } else {
     5         kx 		int i, j, newport;
     5         kx 		char *endp;
     5         kx 		newport = strtol(*spp, &endp, 10);
     5         kx 		if (*endp != 0) {
     5         kx 		    newport = -1;
     5         kx 		    for (i = 0; if_port_text[i][0] && newport == -1; i++) {
     5         kx 			for (j = 0; if_port_text[i][j]; j++) {
     5         kx 			    if (!strcasecmp(*spp, if_port_text[i][j])) {
     5         kx 				newport = i;
     5         kx 				break;
     5         kx 			    }
     5         kx 			}
     5         kx 		    }
     5         kx 		}
     5         kx 		spp++;
     5         kx 		if (newport == -1) {
     5         kx 		    fprintf(stderr, _("Unknown media type.\n"));
     5         kx 		    goterr = 1;
     5         kx 		} else {
     5         kx 		    if (ioctl(skfd, SIOCGIFMAP, &ifr) < 0) {
     5         kx 			perror("port: SIOCGIFMAP");
     5         kx 			goterr = 1;
     5         kx 			continue;
     5         kx 		    }
     5         kx 		    ifr.ifr_map.port = newport;
     5         kx 		    if (ioctl(skfd, SIOCSIFMAP, &ifr) < 0) {
     5         kx 			perror("port: SIOCSIFMAP");
     5         kx 			goterr = 1;
     5         kx 		    }
     5         kx 		}
     5         kx 	    }
     5         kx 	    continue;
     5         kx 	}
     5         kx #endif
     5         kx 
     5         kx 	if (!strcmp(*spp, "trailers")) {
     5         kx 	    goterr |= clr_flag(ifr.ifr_name, IFF_NOTRAILERS);
     5         kx 	    spp++;
     5         kx 	    continue;
     5         kx 	}
     5         kx 	if (!strcmp(*spp, "-trailers")) {
     5         kx 	    goterr |= set_flag(ifr.ifr_name, IFF_NOTRAILERS);
     5         kx 	    spp++;
     5         kx 	    continue;
     5         kx 	}
     5         kx 	if (!strcmp(*spp, "promisc")) {
     5         kx 	    goterr |= set_flag(ifr.ifr_name, IFF_PROMISC);
     5         kx 	    spp++;
     5         kx 	    continue;
     5         kx 	}
     5         kx 	if (!strcmp(*spp, "-promisc")) {
     5         kx 	    goterr |= clr_flag(ifr.ifr_name, IFF_PROMISC);
     5         kx 	    if (test_flag(ifr.ifr_name, IFF_PROMISC) > 0)
     5         kx 	    	fprintf(stderr, _("Warning: Interface %s still in promisc mode... maybe other application is running?\n"), ifr.ifr_name);
     5         kx 	    spp++;
     5         kx 	    continue;
     5         kx 	}
     5         kx 	if (!strcmp(*spp, "multicast")) {
     5         kx 	    goterr |= set_flag(ifr.ifr_name, IFF_MULTICAST);
     5         kx 	    spp++;
     5         kx 	    continue;
     5         kx 	}
     5         kx 	if (!strcmp(*spp, "-multicast")) {
     5         kx 	    goterr |= clr_flag(ifr.ifr_name, IFF_MULTICAST);
     5         kx 	    if (test_flag(ifr.ifr_name, IFF_MULTICAST) > 0)
     5         kx 	    	fprintf(stderr, _("Warning: Interface %s still in MULTICAST mode.\n"), ifr.ifr_name);
     5         kx 	    spp++;
     5         kx 	    continue;
     5         kx 	}
     5         kx 	if (!strcmp(*spp, "allmulti")) {
     5         kx 	    goterr |= set_flag(ifr.ifr_name, IFF_ALLMULTI);
     5         kx 	    spp++;
     5         kx 	    continue;
     5         kx 	}
     5         kx 	if (!strcmp(*spp, "-allmulti")) {
     5         kx 	    goterr |= clr_flag(ifr.ifr_name, IFF_ALLMULTI);
     5         kx 	    if (test_flag(ifr.ifr_name, IFF_ALLMULTI) > 0)
     5         kx 	    	fprintf(stderr, _("Warning: Interface %s still in ALLMULTI mode.\n"), ifr.ifr_name);
     5         kx 	    spp++;
     5         kx 	    continue;
     5         kx 	}
     5         kx 	if (!strcmp(*spp, "up")) {
     5         kx 	    goterr |= set_flag(ifr.ifr_name, (IFF_UP | IFF_RUNNING));
     5         kx 	    spp++;
     5         kx 	    continue;
     5         kx 	}
     5         kx 	if (!strcmp(*spp, "down")) {
     5         kx 	    goterr |= clr_flag(ifr.ifr_name, IFF_UP);
     5         kx 	    spp++;
     5         kx 	    continue;
     5         kx 	}
     5         kx #ifdef HAVE_DYNAMIC
     5         kx 	if (!strcmp(*spp, "dynamic")) {
     5         kx 	    goterr |= set_flag(ifr.ifr_name, IFF_DYNAMIC);
     5         kx 	    spp++;
     5         kx 	    continue;
     5         kx 	}
     5         kx 	if (!strcmp(*spp, "-dynamic")) {
     5         kx 	    goterr |= clr_flag(ifr.ifr_name, IFF_DYNAMIC);
     5         kx 	    spp++;
     5         kx 	    if (test_flag(ifr.ifr_name, IFF_DYNAMIC) > 0)
     5         kx 	    	fprintf(stderr, _("Warning: Interface %s still in DYNAMIC mode.\n"), ifr.ifr_name);
     5         kx 	    continue;
     5         kx 	}
     5         kx #endif
     5         kx 
     5         kx 	if (!strcmp(*spp, "mtu")) {
     5         kx 	    if (*++spp == NULL)
     5         kx 		usage(E_OPTERR);
     5         kx 	    ifr.ifr_mtu = atoi(*spp);
     5         kx 	    if (ioctl(skfd, SIOCSIFMTU, &ifr) < 0) {
     5         kx 		fprintf(stderr, "SIOCSIFMTU: %s\n", strerror(errno));
     5         kx 		goterr = 1;
     5         kx 	    }
     5         kx 	    spp++;
     5         kx 	    continue;
     5         kx 	}
     5         kx #ifdef SIOCSKEEPALIVE
     5         kx 	if (!strcmp(*spp, "keepalive")) {
     5         kx 	    if (*++spp == NULL)
     5         kx 		usage(E_OPTERR);
     5         kx 	    ifr.ifr_data = (caddr_t) (uintptr_t) atoi(*spp);
     5         kx 	    if (ioctl(skfd, SIOCSKEEPALIVE, &ifr) < 0) {
     5         kx 		fprintf(stderr, "SIOCSKEEPALIVE: %s\n", strerror(errno));
     5         kx 		goterr = 1;
     5         kx 	    }
     5         kx 	    spp++;
     5         kx 	    continue;
     5         kx 	}
     5         kx #endif
     5         kx 
     5         kx #ifdef SIOCSOUTFILL
     5         kx 	if (!strcmp(*spp, "outfill")) {
     5         kx 	    if (*++spp == NULL)
     5         kx 		usage(E_OPTERR);
     5         kx 	    ifr.ifr_data = (caddr_t) (uintptr_t) atoi(*spp);
     5         kx 	    if (ioctl(skfd, SIOCSOUTFILL, &ifr) < 0) {
     5         kx 		fprintf(stderr, "SIOCSOUTFILL: %s\n", strerror(errno));
     5         kx 		goterr = 1;
     5         kx 	    }
     5         kx 	    spp++;
     5         kx 	    continue;
     5         kx 	}
     5         kx #endif
     5         kx 
     5         kx 	if (!strcmp(*spp, "-broadcast")) {
     5         kx 	    goterr |= clr_flag(ifr.ifr_name, IFF_BROADCAST);
     5         kx 	    if (test_flag(ifr.ifr_name, IFF_BROADCAST) > 0)
     5         kx 	    	fprintf(stderr, _("Warning: Interface %s still in BROADCAST mode.\n"), ifr.ifr_name);
     5         kx 	    spp++;
     5         kx 	    continue;
     5         kx 	}
     5         kx 	if (!strcmp(*spp, "broadcast")) {
     5         kx 	    if (*++spp != NULL) {
     5         kx 		safe_strncpy(host, *spp, (sizeof host));
     5         kx 		if (ap->input(0, host, &_sa) < 0) {
     5         kx 		    if (ap->herror)
     5         kx 		    	ap->herror(host);
     5         kx 		    else
     5         kx 		    	fprintf(stderr, _("ifconfig: Error resolving '%s' for broadcast\n"), host);
     5         kx 		    goterr = 1;
     5         kx 		    spp++;
     5         kx 		    continue;
     5         kx 		}
     5         kx 		memcpy(&ifr.ifr_broadaddr, sa, sizeof(struct sockaddr));
     5         kx 		if (ioctl(ap->fd, SIOCSIFBRDADDR, &ifr) < 0) {
     5         kx 		    fprintf(stderr, "SIOCSIFBRDADDR: %s\n",
     5         kx 			    strerror(errno));
     5         kx 		    goterr = 1;
     5         kx 		}
     5         kx 		spp++;
     5         kx 	    }
     5         kx 	    goterr |= set_flag(ifr.ifr_name, IFF_BROADCAST);
     5         kx 	    continue;
     5         kx 	}
     5         kx 	if (!strcmp(*spp, "dstaddr")) {
     5         kx 	    if (*++spp == NULL)
     5         kx 		usage(E_OPTERR);
     5         kx 	    safe_strncpy(host, *spp, (sizeof host));
     5         kx 	    if (ap->input(0, host, &_sa) < 0) {
     5         kx 		    if (ap->herror)
     5         kx 		    	ap->herror(host);
     5         kx 		    else
     5         kx 		    	fprintf(stderr, _("ifconfig: Error resolving '%s' for dstaddr\n"), host);
     5         kx 		goterr = 1;
     5         kx 		spp++;
     5         kx 		continue;
     5         kx 	    }
     5         kx 	    memcpy(&ifr.ifr_dstaddr, sa, sizeof(struct sockaddr));
     5         kx 	    if (ioctl(ap->fd, SIOCSIFDSTADDR, &ifr) < 0) {
     5         kx 		fprintf(stderr, "SIOCSIFDSTADDR: %s\n",
     5         kx 			strerror(errno));
     5         kx 		goterr = 1;
     5         kx 	    }
     5         kx 	    spp++;
     5         kx 	    continue;
     5         kx 	}
     5         kx 	if (!strcmp(*spp, "netmask")) {
     5         kx 	    if (*++spp == NULL || didnetmask)
     5         kx 		usage(E_OPTERR);
     5         kx 	    safe_strncpy(host, *spp, (sizeof host));
     5         kx 	    if (ap->input(0, host, &_sa) < 0) {
     5         kx 		    if (ap->herror)
     5         kx 		    	ap->herror(host);
     5         kx 		    else
     5         kx 		    	fprintf(stderr, _("ifconfig: Error resolving '%s' for netmask\n"), host);
     5         kx 		goterr = 1;
     5         kx 		spp++;
     5         kx 		continue;
     5         kx 	    }
     5         kx 	    didnetmask++;
     5         kx 	    goterr |= set_netmask(ap->fd, &ifr, sa);
     5         kx 	    spp++;
     5         kx 	    continue;
     5         kx 	}
     5         kx #ifdef HAVE_TXQUEUELEN
     5         kx 	if (!strcmp(*spp, "txqueuelen")) {
     5         kx 	    if (*++spp == NULL)
     5         kx 		usage(E_OPTERR);
     5         kx 	    ifr.ifr_qlen = strtoul(*spp, NULL, 0);
     5         kx 	    if (ioctl(skfd, SIOCSIFTXQLEN, &ifr) < 0) {
     5         kx 		fprintf(stderr, "SIOCSIFTXQLEN: %s\n", strerror(errno));
     5         kx 		goterr = 1;
     5         kx 	    }
     5         kx 	    spp++;
     5         kx 	    continue;
     5         kx 	}
     5         kx #endif
     5         kx 
     5         kx #ifdef SIOCSIFNAME
     5         kx 	if (!strcmp(*spp, "name")) {
     5         kx 	    if (*++spp == NULL)
     5         kx 		usage(E_OPTERR);
     5         kx 	    safe_strncpy(ifr.ifr_newname, *spp, IFNAMSIZ);
     5         kx 	    if (ioctl(skfd, SIOCSIFNAME, &ifr) < 0) {
     5         kx 		fprintf(stderr, "SIOCSIFNAME: %s\n", strerror(errno));
     5         kx 		goterr = 1;
     5         kx 	    }
     5         kx 	    spp++;
     5         kx 	    continue;
     5         kx 	}
     5         kx #endif
     5         kx 
     5         kx 	if (!strcmp(*spp, "mem_start")) {
     5         kx 	    if (*++spp == NULL)
     5         kx 		usage(E_OPTERR);
     5         kx 	    if (ioctl(skfd, SIOCGIFMAP, &ifr) < 0) {
     5         kx 		fprintf(stderr, "mem_start: SIOCGIFMAP: %s\n", strerror(errno));
     5         kx 		spp++;
     5         kx 		goterr = 1;
     5         kx 		continue;
     5         kx 	    }
     5         kx 	    ifr.ifr_map.mem_start = strtoul(*spp, NULL, 0);
     5         kx 	    if (ioctl(skfd, SIOCSIFMAP, &ifr) < 0) {
     5         kx 		fprintf(stderr, "mem_start: SIOCSIFMAP: %s\n", strerror(errno));
     5         kx 		goterr = 1;
     5         kx 	    }
     5         kx 	    spp++;
     5         kx 	    continue;
     5         kx 	}
     5         kx 	if (!strcmp(*spp, "io_addr")) {
     5         kx 	    if (*++spp == NULL)
     5         kx 		usage(E_OPTERR);
     5         kx 	    if (ioctl(skfd, SIOCGIFMAP, &ifr) < 0) {
     5         kx 		fprintf(stderr, "io_addr: SIOCGIFMAP: %s\n", strerror(errno));
     5         kx 		spp++;
     5         kx 		goterr = 1;
     5         kx 		continue;
     5         kx 	    }
     5         kx 	    ifr.ifr_map.base_addr = strtol(*spp, NULL, 0);
     5         kx 	    if (ioctl(skfd, SIOCSIFMAP, &ifr) < 0) {
     5         kx 		fprintf(stderr, "io_addr: SIOCSIFMAP: %s\n", strerror(errno));
     5         kx 		goterr = 1;
     5         kx 	    }
     5         kx 	    spp++;
     5         kx 	    continue;
     5         kx 	}
     5         kx 	if (!strcmp(*spp, "irq")) {
     5         kx 	    if (*++spp == NULL)
     5         kx 		usage(E_OPTERR);
     5         kx 	    if (ioctl(skfd, SIOCGIFMAP, &ifr) < 0) {
     5         kx 		fprintf(stderr, "irq: SIOCGIFMAP: %s\n", strerror(errno));
     5         kx 		goterr = 1;
     5         kx 		spp++;
     5         kx 		continue;
     5         kx 	    }
     5         kx 	    ifr.ifr_map.irq = atoi(*spp);
     5         kx 	    if (ioctl(skfd, SIOCSIFMAP, &ifr) < 0) {
     5         kx 		fprintf(stderr, "irq: SIOCSIFMAP: %s\n", strerror(errno));
     5         kx 		goterr = 1;
     5         kx 	    }
     5         kx 	    spp++;
     5         kx 	    continue;
     5         kx 	}
     5         kx 	if (!strcmp(*spp, "-pointopoint") || !strcmp(*spp, "-pointtopoint")) {
     5         kx 	    goterr |= clr_flag(ifr.ifr_name, IFF_POINTOPOINT);
     5         kx 	    spp++;
     5         kx 	    if (test_flag(ifr.ifr_name, IFF_POINTOPOINT) > 0)
     5         kx 	    	fprintf(stderr, _("Warning: Interface %s still in POINTOPOINT mode.\n"), ifr.ifr_name);
     5         kx 	    continue;
     5         kx 	}
     5         kx 	if (!strcmp(*spp, "pointopoint") || !strcmp(*spp, "pointtopoint")) {
     5         kx 	    if (*(spp + 1) != NULL) {
     5         kx 		spp++;
     5         kx 		safe_strncpy(host, *spp, (sizeof host));
     5         kx 		if (ap->input(0, host, &_sa)) {
     5         kx 		    if (ap->herror)
     5         kx 		    	ap->herror(host);
     5         kx 		    else
     5         kx 		    	fprintf(stderr, _("ifconfig: Error resolving '%s' for pointopoint\n"), host);
     5         kx 		    goterr = 1;
     5         kx 		    spp++;
     5         kx 		    continue;
     5         kx 		}
     5         kx 		memcpy(&ifr.ifr_dstaddr, sa, sizeof(struct sockaddr));
     5         kx 		if (ioctl(ap->fd, SIOCSIFDSTADDR, &ifr) < 0) {
     5         kx 		    fprintf(stderr, "SIOCSIFDSTADDR: %s\n",
     5         kx 			    strerror(errno));
     5         kx 		    goterr = 1;
     5         kx 		}
     5         kx 	    }
     5         kx 	    goterr |= set_flag(ifr.ifr_name, IFF_POINTOPOINT);
     5         kx 	    spp++;
     5         kx 	    continue;
     5         kx 	};
     5         kx 
     5         kx 	if (!strcmp(*spp, "hw")) {
     5         kx 	    if (*++spp == NULL)
     5         kx 		usage(E_OPTERR);
     5         kx 	    if ((hw = get_hwtype(*spp)) == NULL)
     5         kx 		usage(E_OPTERR);
     5         kx 	    if (hw->input == NULL) {
     5         kx 	    	fprintf(stderr, _("hw address type `%s' has no handler to set address. failed.\n"), *spp);
     5         kx 	    	spp+=2;
     5         kx 	    	goterr = 1;
     5         kx 	    	continue;
     5         kx 	    }
     5         kx 	    if (*++spp == NULL)
     5         kx 		usage(E_OPTERR);
     5         kx 	    safe_strncpy(host, *spp, (sizeof host));
     5         kx 	    if (hw->input(host, &_sa) < 0) {
     5         kx 		fprintf(stderr, _("%s: invalid %s address.\n"), host, hw->name);
     5         kx 		goterr = 1;
     5         kx 		spp++;
     5         kx 		continue;
     5         kx 	    }
     5         kx 	    memcpy(&ifr.ifr_hwaddr, sa, sizeof(struct sockaddr));
     5         kx 	    if (ioctl(skfd, SIOCSIFHWADDR, &ifr) < 0) {
     5         kx 		if (errno == EBUSY)
     5         kx 			fprintf(stderr, "SIOCSIFHWADDR: %s - you may need to down the interface\n",
     5         kx 				strerror(errno));
     5         kx 		else
     5         kx 			fprintf(stderr, "SIOCSIFHWADDR: %s\n",
     5         kx 				strerror(errno));
     5         kx 		goterr = 1;
     5         kx 	    }
     5         kx 	    spp++;
     5         kx 	    continue;
     5         kx 	}
     5         kx #if HAVE_AFINET || HAVE_AFINET6
     5         kx 	if (!strcmp(*spp, "add")) {
     5         kx 	    if (*++spp == NULL)
     5         kx 		usage(E_OPTERR);
     5         kx #if HAVE_AFINET6
     5         kx 	    if (strchr(*spp, ':')) {
     5         kx 		/* INET6 */
     5         kx 		if ((cp = strchr(*spp, '/'))) {
     5         kx 		    prefix_len = atol(cp + 1);
     5         kx 		    if ((prefix_len < 0) || (prefix_len > 128))
     5         kx 			usage(E_OPTERR);
     5         kx 		    *cp = 0;
     5         kx 		} else {
     5         kx 		    prefix_len = 128;
     5         kx 		}
     5         kx 		safe_strncpy(host, *spp, (sizeof host));
     5         kx 		if (inet6_aftype.input(1, host, &_sa) < 0) {
     5         kx 		    if (inet6_aftype.herror)
     5         kx 		    	inet6_aftype.herror(host);
     5         kx 		    else
     5         kx 		    	fprintf(stderr, _("ifconfig: Error resolving '%s' for add\n"), host);
     5         kx 		    goterr = 1;
     5         kx 		    spp++;
     5         kx 		    continue;
     5         kx 		}
     5         kx 		memcpy(&ifr6.ifr6_addr, &sin6->sin6_addr, sizeof(struct in6_addr));
     5         kx 
     5         kx 		fd = get_socket_for_af(AF_INET6);
     5         kx 		if (fd < 0) {
     5         kx 		    fprintf(stderr,
     5         kx 			    _("No support for INET6 on this system.\n"));
     5         kx 		    goterr = 1;
     5         kx 		    spp++;
     5         kx 		    continue;
     5         kx 		}
     5         kx 		if (ioctl(fd, SIOGIFINDEX, &ifr) < 0) {
     5         kx 		    perror("SIOGIFINDEX");
     5         kx 		    goterr = 1;
     5         kx 		    spp++;
     5         kx 		    continue;
     5         kx 		}
     5         kx 		ifr6.ifr6_ifindex = ifr.ifr_ifindex;
     5         kx 		ifr6.ifr6_prefixlen = prefix_len;
     5         kx 		if (ioctl(fd, SIOCSIFADDR, &ifr6) < 0) {
     5         kx 		    perror("SIOCSIFADDR");
     5         kx 		    goterr = 1;
     5         kx 		}
     5         kx 		spp++;
     5         kx 		continue;
     5         kx 	    }
     5         kx #endif
     5         kx #if HAVE_AFINET
     5         kx 	    { /* ipv4 address a.b.c.d */
     5         kx 		in_addr_t ip, nm = (in_addr_t)0, bc = (in_addr_t)0;
     5         kx 		safe_strncpy(host, *spp, (sizeof host));
     5         kx 		if (inet_aftype.input(0, host, &_sa) < 0) {
     5         kx 		    ap->herror(host);
     5         kx 		    goterr = 1;
     5         kx 		    spp++;
     5         kx 		    continue;
     5         kx 		}
     5         kx 		fd = get_socket_for_af(AF_INET);
     5         kx 		if (fd < 0) {
     5         kx 		    fprintf(stderr,
     5         kx 			    _("No support for INET on this system.\n"));
     5         kx 		    goterr = 1;
     5         kx 		    spp++;
     5         kx 		    continue;
     5         kx 		}
     5         kx 
     5         kx 		memcpy(&ip, &sin->sin_addr.s_addr, sizeof(ip));
     5         kx 
     5         kx 		if (get_nmbc_parent(ifr.ifr_name, &nm, &bc) < 0) {
     5         kx 			fprintf(stderr, _("Interface %s not initialized\n"),
     5         kx 				ifr.ifr_name);
     5         kx 			goterr = 1;
     5         kx 			spp++;
     5         kx 			continue;
     5         kx 		}
     5         kx 		set_ifstate(ifr.ifr_name, ip, nm, bc, 1);
     5         kx 
     5         kx 	    }
     5         kx 	    spp++;
     5         kx 	    continue;
     5         kx #else
     5         kx 	    fprintf(stderr, _("Bad address.\n"));
     5         kx #endif
     5         kx 	}
     5         kx #endif
     5         kx 
     5         kx #if HAVE_AFINET || HAVE_AFINET6
     5         kx 	if (!strcmp(*spp, "del")) {
     5         kx 	    if (*++spp == NULL)
     5         kx 		usage(E_OPTERR);
     5         kx 
     5         kx #ifdef SIOCDIFADDR
     5         kx #if HAVE_AFINET6
     5         kx 	    if (strchr(*spp, ':')) {	/* INET6 */
     5         kx 		if ((cp = strchr(*spp, '/'))) {
     5         kx 		    prefix_len = atol(cp + 1);
     5         kx 		    if ((prefix_len < 0) || (prefix_len > 128))
     5         kx 			usage(E_OPTERR);
     5         kx 		    *cp = 0;
     5         kx 		} else {
     5         kx 		    prefix_len = 128;
     5         kx 		}
     5         kx 		safe_strncpy(host, *spp, (sizeof host));
     5         kx 		if (inet6_aftype.input(1, host, &_sa) < 0) {
     5         kx 		    inet6_aftype.herror(host);
     5         kx 		    goterr = 1;
     5         kx 		    spp++;
     5         kx 		    continue;
     5         kx 		}
     5         kx 		memcpy(&ifr6.ifr6_addr, &sin6->sin6_addr,
     5         kx 		       sizeof(struct in6_addr));
     5         kx 
     5         kx 		fd = get_socket_for_af(AF_INET6);
     5         kx 		if (fd < 0) {
     5         kx 		    fprintf(stderr,
     5         kx 			    _("No support for INET6 on this system.\n"));
     5         kx 		    goterr = 1;
     5         kx 		    spp++;
     5         kx 		    continue;
     5         kx 		}
     5         kx 		if (ioctl(fd, SIOGIFINDEX, &ifr) < 0) {
     5         kx 		    perror("SIOGIFINDEX");
     5         kx 		    goterr = 1;
     5         kx 		    spp++;
     5         kx 		    continue;
     5         kx 		}
     5         kx 		ifr6.ifr6_ifindex = ifr.ifr_ifindex;
     5         kx 		ifr6.ifr6_prefixlen = prefix_len;
     5         kx 		if (opt_v)
     5         kx 			fprintf(stderr, "now deleting: ioctl(SIOCDIFADDR,{ifindex=%d,prefixlen=%ld})\n",ifr.ifr_ifindex,prefix_len);
     5         kx 		if (ioctl(fd, SIOCDIFADDR, &ifr6) < 0) {
     5         kx 		    fprintf(stderr, "SIOCDIFADDR: %s\n",
     5         kx 			    strerror(errno));
     5         kx 		    goterr = 1;
     5         kx 		}
     5         kx 		spp++;
     5         kx 		continue;
     5         kx 	    }
     5         kx #endif
     5         kx #if HAVE_AFINET
     5         kx 	    {
     5         kx 		/* ipv4 address a.b.c.d */
     5         kx 		in_addr_t ip, nm = (in_addr_t)0, bc = (in_addr_t)0;
     5         kx 		safe_strncpy(host, *spp, (sizeof host));
     5         kx 		if (inet_aftype.input(0, host, &_sa) < 0) {
     5         kx 		    ap->herror(host);
     5         kx 		    goterr = 1;
     5         kx 		    spp++;
     5         kx 		    continue;
     5         kx 		}
     5         kx 		fd = get_socket_for_af(AF_INET);
     5         kx 		if (fd < 0) {
     5         kx 		    fprintf(stderr, _("No support for INET on this system.\n"));
     5         kx 		    goterr = 1;
     5         kx 		    spp++;
     5         kx 		    continue;
     5         kx 		}
     5         kx 
     5         kx 		/* Clear "ip" in case sizeof(unsigned long) > sizeof(sin.sin_addr.s_addr) */
     5         kx 		ip = 0;
     5         kx 		memcpy(&ip, &sin->sin_addr.s_addr, sizeof(ip));
     5         kx 
     5         kx 		if (get_nmbc_parent(ifr.ifr_name, &nm, &bc) < 0) {
     5         kx 		    fprintf(stderr, _("Interface %s not initialized\n"),
     5         kx 			    ifr.ifr_name);
     5         kx 		    goterr = 1;
     5         kx 		    spp++;
     5         kx 		    continue;
     5         kx 		}
     5         kx 		set_ifstate(ifr.ifr_name, ip, nm, bc, 0);
     5         kx 	    }
     5         kx 	    spp++;
     5         kx 	    continue;
     5         kx #else
     5         kx 	    fprintf(stderr, _("Bad address.\n"));
     5         kx #endif
     5         kx #else
     5         kx 	    fprintf(stderr, _("Address deletion not supported on this system.\n"));
     5         kx #endif
     5         kx 	}
     5         kx #endif
     5         kx #if HAVE_AFINET6
     5         kx 	if (!strcmp(*spp, "tunnel")) {
     5         kx 	    if (*++spp == NULL)
     5         kx 		usage(E_OPTERR);
     5         kx 	    if ((cp = strchr(*spp, '/'))) {
     5         kx 		prefix_len = atol(cp + 1);
     5         kx 		if ((prefix_len < 0) || (prefix_len > 128))
     5         kx 		    usage(E_OPTERR);
     5         kx 		*cp = 0;
     5         kx 	    } else {
     5         kx 		prefix_len = 128;
     5         kx 	    }
     5         kx 	    safe_strncpy(host, *spp, (sizeof host));
     5         kx 	    if (inet6_aftype.input(1, host, &_sa) < 0) {
     5         kx 		inet6_aftype.herror(host);
     5         kx 		goterr = 1;
     5         kx 		spp++;
     5         kx 		continue;
     5         kx 	    }
     5         kx 	    memcpy(&ifr6.ifr6_addr, &sin6->sin6_addr, sizeof(struct in6_addr));
     5         kx 
     5         kx 	    fd = get_socket_for_af(AF_INET6);
     5         kx 	    if (fd < 0) {
     5         kx 		fprintf(stderr, _("No support for INET6 on this system.\n"));
     5         kx 		goterr = 1;
     5         kx 		spp++;
     5         kx 		continue;
     5         kx 	    }
     5         kx 	    if (ioctl(fd, SIOGIFINDEX, &ifr) < 0) {
     5         kx 		perror("SIOGIFINDEX");
     5         kx 		goterr = 1;
     5         kx 		spp++;
     5         kx 		continue;
     5         kx 	    }
     5         kx 	    ifr6.ifr6_ifindex = ifr.ifr_ifindex;
     5         kx 	    ifr6.ifr6_prefixlen = prefix_len;
     5         kx 
     5         kx 	    if (ioctl(fd, SIOCSIFDSTADDR, &ifr6) < 0) {
     5         kx 		fprintf(stderr, "SIOCSIFDSTADDR: %s\n",
     5         kx 			strerror(errno));
     5         kx 		goterr = 1;
     5         kx 	    }
     5         kx 	    spp++;
     5         kx 	    continue;
     5         kx 	}
     5         kx #endif
     5         kx 
     5         kx 	/* If the next argument is a valid hostname, assume OK. */
     5         kx 	safe_strncpy(host, *spp, (sizeof host));
     5         kx 
     5         kx 	/* FIXME: sa is too small for INET6 addresses, inet6 should use that too,
     5         kx 	   broadcast is unexpected */
     5         kx 	if (ap->getmask) {
     5         kx 	    switch (ap->getmask(host, &_samask, NULL)) {
     5         kx 	    case -1:
     5         kx 		usage(E_OPTERR);
     5         kx 		break;
     5         kx 	    case 1:
     5         kx 		if (didnetmask)
     5         kx 		    usage(E_OPTERR);
     5         kx 
     5         kx 		// remeber to set the netmask from samask later
     5         kx 		neednetmask = 1;
     5         kx 		break;
     5         kx 	    }
     5         kx 	}
     5         kx 	if (ap->input == NULL) {
     5         kx 	   fprintf(stderr, _("ifconfig: Cannot set address for this protocol family.\n"));
     5         kx 	   exit(1);
     5         kx 	}
     5         kx 	if (ap->input(0, host, &_sa) < 0) {
     5         kx 	    if (ap->herror) {
     5         kx 	    	ap->herror(host);
     5         kx 	    } else {
     5         kx 	    	fprintf(stderr,_("ifconfig: error resolving '%s' to set address for af=%s\n"), host, ap->name);
     5         kx 	    	fprintf(stderr, _("ifconfig: `--help' gives usage information.\n"));
     5         kx 	    	exit(1);
     5         kx 	    }
     5         kx 	}
     5         kx 	memcpy(&ifr.ifr_addr, sa, sizeof(struct sockaddr));
     5         kx 	{
     5         kx 	    int r = 0;		/* to shut gcc up */
     5         kx 	    switch (ap->af) {
     5         kx #if HAVE_AFINET
     5         kx 	    case AF_INET:
     5         kx 		fd = get_socket_for_af(AF_INET);
     5         kx 		if (fd < 0) {
     5         kx 		    fprintf(stderr, _("No support for INET on this system.\n"));
     5         kx 		    exit(1);
     5         kx 		}
     5         kx 		r = ioctl(fd, SIOCSIFADDR, &ifr);
     5         kx 		break;
     5         kx #endif
     5         kx #if HAVE_AFECONET
     5         kx 	    case AF_ECONET:
     5         kx 		fd = get_socket_for_af(AF_ECONET);
     5         kx 		if (fd < 0) {
     5         kx 		    fprintf(stderr, _("No support for ECONET on this system.\n"));
     5         kx 		    exit(1);
     5         kx 		}
     5         kx 		r = ioctl(fd, SIOCSIFADDR, &ifr);
     5         kx 		break;
     5         kx #endif
     5         kx 	    default:
     5         kx 		fprintf(stderr,
     5         kx 		_("Don't know how to set addresses for family %d.\n"), ap->af);
     5         kx 		exit(1);
     5         kx 	    }
     5         kx 	    if (r < 0) {
     5         kx 		perror("SIOCSIFADDR");
     5         kx 		goterr = 1;
     5         kx 	    }
     5         kx 	}
     5         kx 
     5         kx        /*
     5         kx         * Don't do the set_flag() if the address is an alias with a - at the
     5         kx         * end, since it's deleted already! - Roman
     5         kx         * Same goes if they used address 0.0.0.0 as the kernel uses this to
     5         kx         * destroy aliases.
     5         kx         *
     5         kx         * Should really use regex.h here, not sure though how well it'll go
     5         kx         * with the cross-platform support etc.
     5         kx         */
     5         kx         {
     5         kx             char *ptr;
     5         kx             short int found_colon = 0;
     5         kx             short int bring_up = 1;
     5         kx             for (ptr = ifr.ifr_name; *ptr; ptr++ )
     5         kx                 if (*ptr == ':') found_colon++;
     5         kx 
     5         kx             if (found_colon) {
     5         kx                 if (ptr[-1] == '-')
     5         kx                     bring_up = 0;
     5         kx                 else if (ap->af == AF_INET && sin->sin_addr.s_addr == 0)
     5         kx                     bring_up = 0;
     5         kx             }
     5         kx 
     5         kx             if (bring_up)
     5         kx                 goterr |= set_flag(ifr.ifr_name, (IFF_UP | IFF_RUNNING));
     5         kx         }
     5         kx 
     5         kx 	spp++;
     5         kx     }
     5         kx 
     5         kx     if (neednetmask) {
     5         kx 	goterr |= set_netmask(skfd, &ifr, samask);
     5         kx 	didnetmask++;
     5         kx     }
     5         kx 
     5         kx     if (opt_v && goterr)
     5         kx     	fprintf(stderr, _("WARNING: at least one error occured. (%d)\n"), goterr);
     5         kx 
     5         kx     return (goterr);
     5         kx }
     5         kx 
     5         kx struct ifcmd {
     5         kx     int flag;
     5         kx     unsigned long addr;
     5         kx     char *base;
     5         kx     int baselen;
     5         kx };
     5         kx 
     5         kx static unsigned char searcher[256];
     5         kx 
     5         kx static int set_ip_using(const char *name, int c, unsigned long ip)
     5         kx {
     5         kx     struct ifreq ifr;
     5         kx     struct sockaddr_in sin;
     5         kx 
     5         kx     safe_strncpy(ifr.ifr_name, name, IFNAMSIZ);
     5         kx     memset(&sin, 0, sizeof(struct sockaddr));
     5         kx     sin.sin_family = AF_INET;
     5         kx     sin.sin_addr.s_addr = ip;
     5         kx     memcpy(&ifr.ifr_addr, &sin, sizeof(struct sockaddr));
     5         kx     if (ioctl(skfd, c, &ifr) < 0)
     5         kx 	return -1;
     5         kx     return 0;
     5         kx }
     5         kx 
     5         kx static int do_ifcmd(struct interface *x, struct ifcmd *ptr)
     5         kx {
     5         kx     char *z, *e;
     5         kx     struct sockaddr_in *sin;
     5         kx     int i;
     5         kx 
     5         kx     if (do_if_fetch(x) < 0)
     5         kx 	return 0;
     5         kx     if (strncmp(x->name, ptr->base, ptr->baselen) != 0)
     5         kx 	return 0; /* skip */
     5         kx     z = strchr(x->name, ':');
     5         kx     if (!z || !*z)
     5         kx 	return 0;
     5         kx     z++;
     5         kx     for (e = z; *e; e++)
     5         kx 	if (*e == '-') /* deleted */
     5         kx 	    return 0;
     5         kx     i = atoi(z);
     5         kx     if (i < 0 || i > 255)
     5         kx 	abort();
     5         kx     searcher[i] = 1;
     5         kx 
     5         kx     /* copy */
     5         kx     sin = (struct sockaddr_in *)&x->dstaddr_sas;
     5         kx     if (sin->sin_addr.s_addr != ptr->addr) {
     5         kx 	return 0;
     5         kx     }
     5         kx 
     5         kx     if (ptr->flag) {
     5         kx 	/* turn UP */
     5         kx 	if (set_flag(x->name, IFF_UP | IFF_RUNNING) == -1)
     5         kx 	    return -1;
     5         kx     } else {
     5         kx 	/* turn DOWN */
     5         kx 	if (clr_flag(x->name, IFF_UP) == -1)
     5         kx 	    return -1;
     5         kx     }
     5         kx 
     5         kx     return 1; /* all done! */
     5         kx }
     5         kx 
     5         kx 
     5         kx static int get_nmbc_parent(char *parent,
     5         kx 			   in_addr_t *nm, in_addr_t *bc)
     5         kx {
     5         kx     struct interface *i;
     5         kx     struct sockaddr_in *sin;
     5         kx 
     5         kx     i = lookup_interface(parent);
     5         kx     if (!i)
     5         kx 	return -1;
     5         kx     if (do_if_fetch(i) < 0)
     5         kx 	return 0;
     5         kx     sin = (struct sockaddr_in *)&i->netmask_sas;
     5         kx     memcpy(nm, &sin->sin_addr.s_addr, sizeof(*nm));
     5         kx     sin = (struct sockaddr_in *)&i->broadaddr_sas;
     5         kx     memcpy(bc, &sin->sin_addr.s_addr, sizeof(*bc));
     5         kx     return 0;
     5         kx }
     5         kx 
     5         kx static int set_ifstate(char *parent, in_addr_t ip, in_addr_t nm, in_addr_t bc,
     5         kx 		       int flag)
     5         kx {
     5         kx     char buf[IFNAMSIZ];
     5         kx     struct ifcmd pt;
     5         kx     int i;
     5         kx 
     5         kx     pt.base = parent;
     5         kx     pt.baselen = strlen(parent);
     5         kx     pt.addr = ip;
     5         kx     pt.flag = flag;
     5         kx     memset(searcher, 0, sizeof(searcher));
     5         kx     i = for_all_interfaces((int (*)(struct interface *,void *))do_ifcmd,
     5         kx 			   &pt);
     5         kx     if (i == -1)
     5         kx 	return -1;
     5         kx     if (i == 1)
     5         kx 	return 0;
     5         kx 
     5         kx     /* add a new interface */
     5         kx     for (i = 0; i < 256; i++)
     5         kx 	if (searcher[i] == 0)
     5         kx 	    break;
     5         kx 
     5         kx     if (i == 256)
     5         kx 	return -1; /* FAILURE!!! out of ip addresses */
     5         kx 
     5         kx     if (snprintf(buf, IFNAMSIZ, "%s:%d", parent, i) > IFNAMSIZ)
     5         kx 	return -1;
     5         kx     if (set_ip_using(buf, SIOCSIFADDR, ip) == -1)
     5         kx 	return -1;
     5         kx     if (set_ip_using(buf, SIOCSIFNETMASK, nm) == -1)
     5         kx 	return -1;
     5         kx     if (set_ip_using(buf, SIOCSIFBRDADDR, bc) == -1)
     5         kx 	return -1;
     5         kx     if (set_flag(buf, IFF_BROADCAST) == -1)
     5         kx 	return -1;
     5         kx     return 0;
     5         kx }