fprintf(stderr, _("Address deletion not supported on this system.\n")); #endif
fprintf(stderr, _("Address deletion not supported on this system.\n")); #endif }
int main(int argc, char **argv){    struct sockaddr sa;    struct sockaddr_in sin;    char host[128];    struct aftype *ap;    struct hwtype *hw;    struct ifreq ifr;    int goterr = 0, didnetmask = 0;    char **spp;    int fd;#if HAVE_AFINET6    extern struct aftype inet6_aftype;    struct sockaddr_in6 sa6;    struct in6_ifreq ifr6;    unsigned long prefix_len;    char *cp;#endif#if HAVE_AFINET    extern struct aftype inet_aftype;#endif#if I18N    bindtextdomain("net-tools", "/usr/share/locale");    textdomain("net-tools");#endif    /* Create a channel to the NET kernel. */    if ((skfd = sockets_open(0)) < 0) {	perror("socket");	exit(1);    }    /* Find any options. */    argc--;    argv++;    while (argc && *argv[0] == '-') {	if (!strcmp(*argv, "-a"))	    opt_a = 1;	else if (!strcmp(*argv, "-s"))	    ife_short = 1;	else if (!strcmp(*argv, "-v"))	    opt_v = 1;		else if (!strcmp(*argv, "-V") || !strcmp(*argv, "-version") ||	    !strcmp(*argv, "--version"))	    version();	else if (!strcmp(*argv, "-?") || !strcmp(*argv, "-h") ||	    !strcmp(*argv, "-help") || !strcmp(*argv, "--help"))	    usage();	else {	    fprintf(stderr, "ifconfig: unknown option %s\n", argv[0]);	    fprintf(stderr, "(Use --help for usage information.\n)");	    exit(1);	}	argv++;	argc--;    }    /* Do we have to show the current setup? */    if (argc == 0) {	int err = if_print((char *) NULL);	(void) close(skfd);	exit(err < 0);    }    /* No. Fetch the interface name. */    spp = argv;    safe_strncpy(ifr.ifr_name, *spp++, IFNAMSIZ);    if (*spp == (char *) NULL) {	int err = if_print(ifr.ifr_name);	(void) close(skfd);	exit(err < 0);    }    /* The next argument is either an address family name, or an option. */    if ((ap = get_aftype(*spp)) == NULL)	ap = get_aftype(DFLT_AF);    else {	/* XXX: should print the current setup if no args left, but only 	   for this family */	spp++;	addr_family = ap->af;    }    if (sockets_open(addr_family) < 0) {	perror("family socket");	exit(1);    }    /* Process the remaining arguments. */    while (*spp != (char *) NULL) {	if (!strcmp(*spp, "arp")) {	    goterr |= clr_flag(ifr.ifr_name, IFF_NOARP);	    spp++;	    continue;	}	if (!strcmp(*spp, "-arp")) {	    goterr |= set_flag(ifr.ifr_name, IFF_NOARP);	    spp++;	    continue;	}#ifdef IFF_PORTSEL	if (!strcmp(*spp, "media") || !strcmp(*spp, "port")) {	    if (*++spp == NULL)		usage();	    if (!strcasecmp(*spp, "auto")) {		goterr |= set_flag(ifr.ifr_name, IFF_AUTOMEDIA);	    } else {		int i, j, newport;		char *endp;		newport = strtol(*spp, &endp, 10);		if (*endp != 0) {		    newport = -1;		    for (i = 0; if_port_text[i][0] && newport == -1; i++) {			for (j = 0; if_port_text[i][j]; j++) {			    if (!strcasecmp(*spp, if_port_text[i][j])) {				newport = i;				break;			    }			}		    }		}		spp++;		if (newport == -1) {		    fprintf(stderr, _("Unknown media type.\n"));		    goterr = 1;		} else {		    if (ioctl(skfd, SIOCGIFMAP, &ifr) < 0) {			goterr = 1;			continue;		    }		    ifr.ifr_map.port = newport;		    if (ioctl(skfd, SIOCSIFMAP, &ifr) < 0) {			perror("SIOCSIFMAP");			goterr = 1;		    }		}	    }	    continue;	}#endif	if (!strcmp(*spp, "trailers")) {	    goterr |= clr_flag(ifr.ifr_name, IFF_NOTRAILERS);	    spp++;	    continue;	}	if (!strcmp(*spp, "-trailers")) {	    goterr |= set_flag(ifr.ifr_name, IFF_NOTRAILERS);	    spp++;	    continue;	}	if (!strcmp(*spp, "promisc")) {	    goterr |= set_flag(ifr.ifr_name, IFF_PROMISC);	    spp++;	    continue;	}	if (!strcmp(*spp, "-promisc")) {	    goterr |= clr_flag(ifr.ifr_name, IFF_PROMISC);	    spp++;	    continue;	}	if (!strcmp(*spp, "multicast")) {	    goterr |= set_flag(ifr.ifr_name, IFF_MULTICAST);	    spp++;	    continue;	}	if (!strcmp(*spp, "-multicast")) {	    goterr |= clr_flag(ifr.ifr_name, IFF_MULTICAST);	    spp++;	    continue;	}	if (!strcmp(*spp, "allmulti")) {	    goterr |= set_flag(ifr.ifr_name, IFF_ALLMULTI);	    spp++;	    continue;	}	if (!strcmp(*spp, "-allmulti")) {	    goterr |= clr_flag(ifr.ifr_name, IFF_ALLMULTI);	    spp++;	    continue;	}	if (!strcmp(*spp, "up")) {	    goterr |= set_flag(ifr.ifr_name, (IFF_UP | IFF_RUNNING));	    spp++;	    continue;	}	if (!strcmp(*spp, "down")) {	    goterr |= clr_flag(ifr.ifr_name, IFF_UP);	    spp++;	    continue;	}#ifdef HAVE_DYNAMIC	if (!strcmp(*spp, "dynamic")) {	    goterr |= set_flag(ifr.ifr_name, IFF_DYNAMIC);	    spp++;	    continue;	}	if (!strcmp(*spp, "-dynamic")) {	    goterr |= clr_flag(ifr.ifr_name, IFF_DYNAMIC);	    spp++;	    continue;	}#endif	if (!strcmp(*spp, "metric")) {	    if (*++spp == NULL)		usage();	    ifr.ifr_metric = atoi(*spp);	    if (ioctl(skfd, SIOCSIFMETRIC, &ifr) < 0) {		fprintf(stderr, "SIOCSIFMETRIC: %s\n", strerror(errno));		goterr = 1;	    }	    spp++;	    continue;	}	if (!strcmp(*spp, "mtu")) {	    if (*++spp == NULL)		usage();	    ifr.ifr_mtu = atoi(*spp);	    if (ioctl(skfd, SIOCSIFMTU, &ifr) < 0) {		fprintf(stderr, "SIOCSIFMTU: %s\n", strerror(errno));		goterr = 1;	    }	    spp++;	    continue;	}#ifdef SIOCSKEEPALIVE	if (!strcmp(*spp, "keepalive")) {	    if (*++spp == NULL)		usage();	    ifr.ifr_data = (caddr_t) atoi(*spp);	    if (ioctl(skfd, SIOCSKEEPALIVE, &ifr) < 0) {		fprintf(stderr, "SIOCSKEEPALIVE: %s\n", strerror(errno));		goterr = 1;	    }	    spp++;	    continue;	}#endif#ifdef SIOCSOUTFILL	if (!strcmp(*spp, "outfill")) {	    if (*++spp == NULL)		usage();	    ifr.ifr_data = (caddr_t) atoi(*spp);	    if (ioctl(skfd, SIOCSOUTFILL, &ifr) < 0) {		fprintf(stderr, "SIOCSOUTFILL: %s\n", strerror(errno));		goterr = 1;	    }	    spp++;	    continue;	}#endif	if (!strcmp(*spp, "-broadcast")) {	    goterr |= clr_flag(ifr.ifr_name, IFF_BROADCAST);	    spp++;	    continue;	}	if (!strcmp(*spp, "broadcast")) {	    if (*++spp != NULL) {		safe_strncpy(host, *spp, (sizeof host));		if (ap->input(0, host, &sa) < 0) {		    ap->herror(host);		    goterr = 1;		    spp++;		    continue;		}		memcpy((char *) &ifr.ifr_broadaddr, (char *) &sa,		       sizeof(struct sockaddr));		if (ioctl(ap->fd, SIOCSIFBRDADDR, &ifr) < 0) {		    fprintf(stderr, "SIOCSIFBRDADDR: %s\n",			    strerror(errno));		    goterr = 1;		}		spp++;	    }	    goterr |= set_flag(ifr.ifr_name, IFF_BROADCAST);	    continue;	}	if (!strcmp(*spp, "dstaddr")) {	    if (*++spp == NULL)		usage();	    safe_strncpy(host, *spp, (sizeof host));	    if (ap->input(0, host, &sa) < 0) {		ap->herror(host);		goterr = 1;		spp++;		continue;	    }	    memcpy((char *) &ifr.ifr_dstaddr, (char *) &sa,		   sizeof(struct sockaddr));	    if (ioctl(ap->fd, SIOCSIFDSTADDR, &ifr) < 0) {		fprintf(stderr, "SIOCSIFDSTADDR: %s\n",			strerror(errno));		goterr = 1;	    }	    spp++;	    continue;	}	if (!strcmp(*spp, "netmask")) {	    if (*++spp == NULL || didnetmask)		usage();	    safe_strncpy(host, *spp, (sizeof host));	    if (ap->input(0, host, &sa) < 0) {		ap->herror(host);		goterr = 1;		spp++;		continue;	    }	    didnetmask++;	    goterr = set_netmask(ap->fd, &ifr, &sa);	    spp++;	    continue;	}#ifdef HAVE_TXQUEUELEN	if (!strcmp(*spp, "txqueuelen")) {	    if (*++spp == NULL)		usage();	    ifr.ifr_qlen = strtoul(*spp, NULL, 0);	    if (ioctl(skfd, SIOCSIFTXQLEN, &ifr) < 0) {		fprintf(stderr, "SIOCSIFTXQLEN: %s\n", strerror(errno));		goterr = 1;	    }	    spp++;	    continue;	}#endif	if (!strcmp(*spp, "mem_start")) {	    if (*++spp == NULL)		usage();	    if (ioctl(skfd, SIOCGIFMAP, &ifr) < 0) {		goterr = 1;		continue;	    }	    ifr.ifr_map.mem_start = strtoul(*spp, NULL, 0);	    if (ioctl(skfd, SIOCSIFMAP, &ifr) < 0) {		fprintf(stderr, "SIOCSIFMAP: %s\n", strerror(errno));		goterr = 1;	    }	    spp++;	    continue;	}	if (!strcmp(*spp, "io_addr")) {	    if (*++spp == NULL)		usage();	    if (ioctl(skfd, SIOCGIFMAP, &ifr) < 0) {		goterr = 1;		continue;	    }	    ifr.ifr_map.base_addr = strtol(*spp, NULL, 0);	    if (ioctl(skfd, SIOCSIFMAP, &ifr) < 0) {		fprintf(stderr, "SIOCSIFMAP: %s\n", strerror(errno));		goterr = 1;	    }	    spp++;	    continue;	}	if (!strcmp(*spp, "irq")) {	    if (*++spp == NULL)		usage();	    if (ioctl(skfd, SIOCGIFMAP, &ifr) < 0) {		goterr = 1;		continue;	    }	    ifr.ifr_map.irq = atoi(*spp);	    if (ioctl(skfd, SIOCSIFMAP, &ifr) < 0) {		fprintf(stderr, "SIOCSIFMAP: %s\n", strerror(errno));		goterr = 1;	    }	    spp++;	    continue;	}	if (!strcmp(*spp, "-pointopoint")) {	    goterr |= clr_flag(ifr.ifr_name, IFF_POINTOPOINT);	    spp++;	    continue;	}	if (!strcmp(*spp, "pointopoint")) {	    if (*(spp + 1) != NULL) {		spp++;		safe_strncpy(host, *spp, (sizeof host));		if (ap->input(0, host, &sa)) {		    ap->herror(host);		    goterr = 1;		    spp++;		    continue;		}		memcpy((char *) &ifr.ifr_dstaddr, (char *) &sa,		       sizeof(struct sockaddr));		if (ioctl(ap->fd, SIOCSIFDSTADDR, &ifr) < 0) {		    fprintf(stderr, "SIOCSIFDSTADDR: %s\n",			    strerror(errno));		    goterr = 1;		}	    }	    goterr |= set_flag(ifr.ifr_name, IFF_POINTOPOINT);	    spp++;	    continue;	};	if (!strcmp(*spp, "hw")) {	    if (*++spp == NULL)		usage();	    if ((hw = get_hwtype(*spp)) == NULL)		usage();	    if (*++spp == NULL)		usage();	    safe_strncpy(host, *spp, (sizeof host));	    if (hw->input(host, &sa) < 0) {		fprintf(stderr, _("%s: invalid %s address.\n"), host, hw->name);		goterr = 1;		spp++;		continue;	    }	    memcpy((char *) &ifr.ifr_hwaddr, (char *) &sa,		   sizeof(struct sockaddr));	    if (ioctl(skfd, SIOCSIFHWADDR, &ifr) < 0) {		fprintf(stderr, "SIOCSIFHWADDR: %s\n",			strerror(errno));		goterr = 1;	    }	    spp++;	    continue;	}#if HAVE_AFINET || HAVE_AFINET6	if (!strcmp(*spp, "add")) {	    if (*++spp == NULL)		usage();#if HAVE_AFINET6	    if (strchr(*spp, ':')) {		/* INET6 */		if ((cp = strchr(*spp, '/'))) {		    prefix_len = atol(cp + 1);		    if ((prefix_len < 0) || (prefix_len > 128))			usage();		    *cp = 0;		} else {		    prefix_len = 0;		}		safe_strncpy(host, *spp, (sizeof host));		if (inet6_aftype.input(1, host, 				       (struct sockaddr *) &sa6) < 0) {		    inet6_aftype.herror(host);		    goterr = 1;		    spp++;		    continue;		}		memcpy((char *) &ifr6.ifr6_addr, (char *) &sa6.sin6_addr,		       sizeof(struct in6_addr));		fd = get_socket_for_af(AF_INET6);		if (fd < 0) {		    fprintf(stderr, 			    _("No support for INET6 on this system.\n"));		    goterr = 1;		    spp++;		    continue;		}		if (ioctl(fd, SIOGIFINDEX, &ifr) < 0) {		    perror("SIOGIFINDEX");		    goterr = 1;		    spp++;		    continue;		}		ifr6.ifr6_ifindex = ifr.ifr_ifindex;		ifr6.ifr6_prefixlen = prefix_len;		if (ioctl(fd, SIOCSIFADDR, &ifr6) < 0) {		    perror("SIOCSIFADDR");		    goterr = 1;		}		spp++;		continue;	    }#endif#ifdef HAVE_AFINET	    { /* ipv4 address a.b.c.d */		unsigned long ip, nm, bc;		safe_strncpy(host, *spp, (sizeof host));		if (inet_aftype.input(0, host, (struct sockaddr *)&sin) < 0) {		    ap->herror(host);		    goterr = 1;		    spp++;		    continue;		}		fd = get_socket_for_af(AF_INET);		if (fd < 0) {		    fprintf(stderr, 			    _("No support for INET on this system.\n"));		    goterr = 1;		    spp++;		    continue;		}		memcpy(&ip, &sin.sin_addr.s_addr, sizeof(unsigned long));				if (get_nmbc_parent(ifr.ifr_name, &nm, &bc) < 0) {			fprintf(stderr, _("Interface %s not initialized\n"),				ifr.ifr_name);			goterr = 1;			spp++;			continue;		}		set_ifstate(ifr.ifr_name, ip, nm, bc, 1);			    }	    spp++;	    continue;	}#else	fprintf(stderr, _("Bad address.\n"));#endif#endif#if HAVE_AFINET || HAVE_AFINET6	if (!strcmp(*spp, "del")) {	    if (*++spp == NULL)		usage();#ifdef SIOCDIFADDR#if HAVE_AFINET6	    if (strchr(*spp, ':')) {	/* INET6 */		if ((cp = strchr(*spp, '/'))) {		    prefix_len = atol(cp + 1);		    if ((prefix_len < 0) || (prefix_len > 128))			usage();		    *cp = 0;		} else {		    prefix_len = 0;		}		safe_strncpy(host, *spp, (sizeof host));		if (inet6_aftype.input(1, host, 				       (struct sockaddr *) &sa6) < 0) {		    inet6_aftype.herror(host);		    goterr = 1;		    spp++;		    continue;		}		memcpy((char *) &ifr6.ifr6_addr, (char *) &sa6.sin6_addr,		       sizeof(struct in6_addr));				fd = get_socket_for_af(AF_INET6);		if (fd < 0) {		    fprintf(stderr, 			    _("No support for INET6 on this system.\n"));		    goterr = 1;		    spp++;		    continue;		}		if (ioctl(fd, SIOGIFINDEX, &ifr) < 0) {		    perror("SIOGIFINDEX");		    goterr = 1;		    spp++;		    continue;		}		ifr6.ifr6_ifindex = ifr.ifr_ifindex;		ifr6.ifr6_prefixlen = prefix_len;		if (ioctl(fd, SIOCDIFADDR, &ifr6) < 0) {		    fprintf(stderr, "SIOCDIFADDR: %s\n",			    strerror(errno));		    goterr = 1;		}		spp++;		continue;	    }#endif#ifdef HAVE_AFINET	    {		/* ipv4 address a.b.c.d */		unsigned long ip, nm, bc;		safe_strncpy(host, *spp, (sizeof host));		if (inet_aftype.input(0, host, (struct sockaddr *)&sin) < 0) {		    ap->herror(host);		    goterr = 1;		    spp++;		    continue;		}		fd = get_socket_for_af(AF_INET);		if (fd < 0) {		    fprintf(stderr, _("No support for INET on this system.\n"));		    goterr = 1;		    spp++;		    continue;		}				memcpy(&ip, &sin.sin_addr.s_addr, sizeof(unsigned long));				if (get_nmbc_parent(ifr.ifr_name, &nm, &bc) < 0) {		    fprintf(stderr, _("Interface %s not initialized\n"),			    ifr.ifr_name);		    goterr = 1;		    spp++;		    continue;		}		set_ifstate(ifr.ifr_name, ip, nm, bc, 0);	    }	    spp++;	    continue;	}#else	fprintf(stderr, _("Bad address.\n"));#endif#else	fprintf(stderr, _("Address deletion not supported on this system.\n"));#endif#endif#if HAVE_AFINET6	if (!strcmp(*spp, "tunnel")) {	    if (*++spp == NULL)		usage();	    if ((cp = strchr(*spp, '/'))) {		prefix_len = atol(cp + 1);		if ((prefix_len < 0) || (prefix_len > 128))		    usage();		*cp = 0;	    } else {		prefix_len = 0;	    }	    safe_strncpy(host, *spp, (sizeof host));	    if (inet6_aftype.input(1, host, (struct sockaddr *) &sa6) < 0) {		inet6_aftype.herror(host);		goterr = 1;		spp++;		continue;	    }	    memcpy((char *) &ifr6.ifr6_addr, (char *) &sa6.sin6_addr,		   sizeof(struct in6_addr));	    fd = get_socket_for_af(AF_INET6);	    if (fd < 0) {		fprintf(stderr, _("No support for INET6 on this system.\n"));		goterr = 1;		spp++;		continue;	    }	    if (ioctl(fd, SIOGIFINDEX, &ifr) < 0) {		perror("SIOGIFINDEX");		goterr = 1;		spp++;		continue;	    }	    ifr6.ifr6_ifindex = ifr.ifr_ifindex;	    ifr6.ifr6_prefixlen = prefix_len;	    if (ioctl(fd, SIOCSIFDSTADDR, &ifr6) < 0) {		fprintf(stderr, "SIOCSIFDSTADDR: %s\n",			strerror(errno));		goterr = 1;	    }	    spp++;	    continue;	}#endif	/* If the next argument is a valid hostname, assume OK. */	safe_strncpy(host, *spp, (sizeof host));	/* 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)) {	    case -1:		usage();		break;	    case 1:		if (didnetmask)		    usage();		goterr = set_netmask(skfd, &ifr, &sa);		didnetmask++;		break;	    }	}	if (ap->input(0, host, &sa) < 0) {	    ap->herror(host);	    usage();	}	memcpy((char *) &ifr.ifr_addr, (char *) &sa, sizeof(struct sockaddr));	{	    int r = 0;		/* to shut gcc up */	    switch (ap->af) {#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;#endif#if HAVE_AFECONET	    case AF_ECONET:		fd = get_socket_for_af(AF_ECONET);		if (fd < 0) {		    fprintf(stderr, _("No support for ECONET on this system.\n"));		    exit(1);		}		r = ioctl(fd, SIOCSIFADDR, &ifr);		break;#endif	    default:		fprintf(stderr,		_("Don't know how to set addresses for family %d.\n"), ap->af);		exit(1);	    }	    if (r < 0) {		perror("SIOCSIFADDR");		goterr = 1;	    }	}       /*        * Don't do the set_flag() if the address is an alias with a - at the        * end, since it's deleted already! - Roman        *        * Should really use regex.h here, not sure though how well it'll go        * with the cross-platform support etc.         */        {            char *ptr;            short int found_colon = 0;            for (ptr = ifr.ifr_name; *ptr; ptr++ )                if (*ptr == ':') found_colon++;                            if (!(found_colon && *(ptr - 1) == '-'))                goterr |= set_flag(ifr.ifr_name, (IFF_UP | IFF_RUNNING));        }	spp++;    }    return (goterr);}