Example #1
0
int arp_main(int argc ATTRIBUTE_UNUSED, char **argv)
{
	char *hw_type;
	char *protocol;

	/* Initialize variables... */
	ap = get_aftype(DFLT_AF);
	if (!ap)
		bb_error_msg_and_die("%s: %s not supported", DFLT_AF, "address family");

	getopt32(argv, "A:p:H:t:i:adnDsv", &protocol, &protocol,
				 &hw_type, &hw_type, &device);
	argv += optind;
	if (option_mask32 & ARP_OPT_A || option_mask32 & ARP_OPT_p) {
		ap = get_aftype(protocol);
		if (ap == NULL)
			bb_error_msg_and_die("%s: unknown %s", protocol, "address family");
	}
	if (option_mask32 & ARP_OPT_A || option_mask32 & ARP_OPT_p) {
		hw = get_hwtype(hw_type);
		if (hw == NULL)
			bb_error_msg_and_die("%s: unknown %s", hw_type, "hardware type");
		hw_set = 1;
	}
	//if (option_mask32 & ARP_OPT_i)... -i

	if (ap->af != AF_INET) {
		bb_error_msg_and_die("%s: kernel only supports 'inet'", ap->name);
	}

	/* If no hw type specified get default */
	if (!hw) {
		hw = get_hwtype(DFLT_HW);
		if (!hw)
			bb_error_msg_and_die("%s: %s not supported", DFLT_HW, "hardware type");
	}

	if (hw->alen <= 0) {
		bb_error_msg_and_die("%s: %s without ARP support",
							 hw->name, "hardware type");
	}
	sockfd = xsocket(AF_INET, SOCK_DGRAM, 0);

	/* Now see what we have to do here... */
	if (option_mask32 & (ARP_OPT_d|ARP_OPT_s)) {
		if (argv[0] == NULL)
			bb_error_msg_and_die("need host name");
		if (option_mask32 & ARP_OPT_s)
			return arp_set(argv);
		return arp_del(argv);
	}
	//if (option_mask32 & ARP_OPT_a) - default
	return arp_show(argv[0]);
}
Example #2
0
/* Print the contents of an ARP request block. */
static void arp_disp_2(char *name, int type, int arp_flags, char *hwa,
      char *mask, char *dev)
{
    static int title = 0;
    struct hwtype *xhw;
    char flags[10];

    xhw = get_hwntype(type);
    if (xhw == NULL)
        xhw = get_hwtype(DFLT_HW);

    if (title++ == 0) {
        printf("Address                  HWtype  HWaddress           Flags Mask            Iface\n");
    }
    /* Setup the flags. */
    flags[0] = '\0';
    if (arp_flags & ATF_COM)
        strcat(flags, "C");
    if (arp_flags & ATF_PERM)
        strcat(flags, "M");
    if (arp_flags & ATF_PUBL)
        strcat(flags, "P");
#ifdef HAVE_ATF_MAGIC
    if (arp_flags & ATF_MAGIC)
        strcat(flags, "A");
#endif
#ifdef HAVE_ATF_DONTPUB
    if (arp_flags & ATF_DONTPUB)
        strcat(flags, "!");
#endif
    if (arp_flags & ATF_USETRAILERS)
        strcat(flags, "T");

    if (!(arp_flags & ATF_NETMASK))
        mask = "";

    printf("%-23.23s  ", name);

    if (!(arp_flags & ATF_COM)) {
        if (arp_flags & ATF_PUBL)
            printf("%-8.8s%-20.20s", "*", "*");
        else
            printf("%-8.8s%-20.20s", "", "(incomplete)");
    } else {
        printf("%-8.8s%-20.20s", xhw->name, hwa);
    }

    printf("%-6.6s%-15.15s %s\n", flags, mask, dev);
}
Example #3
0
int activate_ld(const char *hwname, int fd)
{
    struct hwtype *hw;

    hw = get_hwtype(hwname);

    if (!hw) {
	fprintf(stderr, _("Hardware type `%s' not supported.\n"), hwname);
	return (E_NOSUPP);
    }
    if (!hw->activate) {
	fprintf(stderr, _("Cannot change line discipline to `%s'.\n"), hw->name);
	return (E_OPTERR);
    }
    return (hw->activate(fd));
}
Example #4
0
/* Print the contents of an ARP request block. */
static void
arp_disp(const char *name, char *ip, int type, int arp_flags,
		 char *hwa, char *mask, char *dev)
{
	const struct hwtype *xhw;

	xhw = get_hwntype(type);
	if (xhw == NULL)
		xhw = get_hwtype(DFLT_HW);

	printf("%s (%s) at ", name, ip);

	if (!(arp_flags & ATF_COM)) {
		if (arp_flags & ATF_PUBL)
			printf("* ");
		else
			printf("<incomplete> ");
	} else {
		printf("%s [%s] ", hwa, xhw->name);
	}

	if (arp_flags & ATF_NETMASK)
		printf("netmask %s ", mask);

	if (arp_flags & ATF_PERM)
		printf("PERM ");
	if (arp_flags & ATF_PUBL)
		printf("PUP ");
#ifdef HAVE_ATF_MAGIC
	if (arp_flags & ATF_MAGIC)
		printf("AUTO ");
#endif
#ifdef HAVE_ATF_DONTPUB
	if (arp_flags & ATF_DONTPUB)
		printf("DONTPUB ");
#endif
	if (arp_flags & ATF_USETRAILERS)
		printf("TRAIL ");

	printf("on %s\n", dev);
}
Example #5
0
int main(int argc, char **argv)
{
    struct sockaddr sa;
    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 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;

	if (!strcmp(*argv, "-v"))
	    opt_v = 1;

	if (!strcmp(*argv, "-V") || !strcmp(*argv, "-version") ||
	    !strcmp(*argv, "--version"))
	    version();

	if (!strcmp(*argv, "-?") || !strcmp(*argv, "-h") ||
	    !strcmp(*argv, "-help") || !strcmp(*argv, "--help"))
	    usage();

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

	/* setup the vlan if required */
	if (if_name_is_vlan(ifr.ifr_name)) {
		struct interface *i;
		if ((i = lookup_interface(ifr.ifr_name)) == NULL) {
			fprintf (stderr, "Couldn't lookup interfaces\n");
			exit(1);
		}
		if (do_if_fetch(i) < 0) {
			int err;
			printf("Creating new vlan\n");
			err = setup_vlan(ifr.ifr_name);
			if (err < 0) {
				fprintf(stderr, "Cannot init required vlan %s - %d\n",
					ifr.ifr_name, err);
				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_AFINET6
	if (!strcmp(*spp, "add")) {
	    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, SIOCSIFADDR, &ifr6) < 0) {
		perror("SIOCSIFADDR");
		goterr = 1;
	    }
	    spp++;
	    continue;
	}
	if (!strcmp(*spp, "del")) {
	    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;
#ifdef SIOCDIFADDR
	    if (ioctl(fd, SIOCDIFADDR, &ifr6) < 0) {
		fprintf(stderr, "SIOCDIFADDR: %s\n",
			strerror(errno));
		goterr = 1;
	    }
#else
	    fprintf(stderr, _("Address deletion not supported on this system.\n"));
#endif
	    spp++;
	    continue;
	}
	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);
}
Example #6
0
int main(int argc, char **argv)
{
    int i, lop, what;
    struct option longopts[] =
    {
	{"verbose", 0, 0, 'v'},
	{"version", 0, 0, 'V'},
	{"all", 0, 0, 'a'},
	{"delete", 0, 0, 'd'},
	{"file", 0, 0, 'f'},
	{"numeric", 0, 0, 'n'},
	{"set", 0, 0, 's'},
	{"protocol", 1, 0, 'A'},
	{"hw-type", 1, 0, 'H'},
	{"device", 1, 0, 'i'},
	{"help", 0, 0, 'h'},
	{"use-device", 0, 0, 'D'},
	{"symbolic", 0, 0, 'N'},
	{NULL, 0, 0, 0}
    };

#if I18N
    setlocale (LC_ALL, "");
    bindtextdomain("net-tools", "/usr/share/locale");
    textdomain("net-tools");
#endif

    /* Initialize variables... */
    if ((hw = get_hwtype(DFLT_HW)) == NULL) {
	fprintf(stderr, _("%s: hardware type not supported!\n"), DFLT_HW);
	return (-1);
    }
    if ((ap = get_aftype(DFLT_AF)) == NULL) {
	fprintf(stderr, _("%s: address family not supported!\n"), DFLT_AF);
	return (-1);
    }
    what = 0;

    /* Fetch the command-line arguments. */
    /* opterr = 0; */
    while ((i = getopt_long(argc, argv, "A:H:adfp:nsei:t:vh?DNV", longopts, &lop)) != EOF)
	switch (i) {
	case 'a':
	    what = 1;
	    opt_a = 1;
	    break;
	case 'f':
	    what = 2;
	    break;
	case 'd':
	    what = 3;
	    break;
	case 's':
	    what = 4;
	    break;


	case 'e':
	    opt_e = 1;
	    break;
	case 'n':
	    opt_n = FLAG_NUM;
	    break;
	case 'D':
	    opt_D = 1;
	    break;
	case 'N':
	    opt_N = FLAG_SYM;
	    fprintf(stderr, _("arp: -N not yet supported.\n"));
	    break;
	case 'v':
	    opt_v = 1;
	    break;

	case 'A':
	case 'p':
	    ap = get_aftype(optarg);
	    if (ap == NULL) {
		fprintf(stderr, _("arp: %s: unknown address family.\n"),
			optarg);
		exit(-1);
	    }
	    break;
	case 'H':
	case 't':
	    hw = get_hwtype(optarg);
	    if (hw == NULL) {
		fprintf(stderr, _("arp: %s: unknown hardware type.\n"),
			optarg);
		exit(-1);
	    }
	    hw_set = 1;
	    break;
	case 'i':
	    safe_strncpy(device, optarg, sizeof(device));
	    break;

	case 'V':
	    version();
	case '?':
	case 'h':
	default:
	    usage();
	}

    if (ap->af != AF_INET) {
	fprintf(stderr, _("arp: %s: kernel only supports 'inet'.\n"),
		ap->name);
	exit(-1);
    }

    /* If not hw type specified get default */
    if(hw_set==0)
	if ((hw = get_hwtype(DFLT_HW)) == NULL) {
	  fprintf(stderr, _("%s: hardware type not supported!\n"), DFLT_HW);
	  return (-1);
	}

    if (hw->alen <= 0) {
	fprintf(stderr, _("arp: %s: hardware type without ARP support.\n"),
		hw->name);
	exit(-1);
    }
    if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
	perror("socket");
	exit(-1);
    }
    /* Now see what we have to do here... */
    switch (what) {
    case 0:
	opt_e = 1;
	what = arp_show(argv[optind]);
	break;

    case 1:			/* show an ARP entry in the cache */
	what = arp_show(argv[optind]);
	break;

    case 2:			/* process an EtherFile */
	what = arp_file(argv[optind] ? argv[optind] : "/etc/ethers");
	break;

    case 3:			/* delete an ARP entry from the cache */
	what = arp_del(&argv[optind]);
	break;

    case 4:			/* set an ARP entry in the cache */
	what = arp_set(&argv[optind]);
	break;

    default:
	usage();
    }

    exit(what);
}
Example #7
0
int
main(int argc, char **argv)
{
  struct sockaddr sa;
  char host[128];
  struct aftype *ap;
  struct hwtype *hw;
  struct ifreq ifr;
  int goterr = 0;
  char **spp;

#if NLS
  setlocale (LC_MESSAGES, "");
  catfd = catopen ("nettools", MCLoadBySet);
#endif

  /* Create a channel to the NET kernel. */
  if ((skfd = sockets_open()) < 0) {
	perror("socket");
	NLS_CATCLOSE(catfd)
	exit(-1);
  }
  /* Find any options. */
  argc--; argv++;
  while (argc && *argv[0] == '-') {
	if (!strcmp(*argv, "-a")) opt_a = 1;
	
	if (!strcmp(*argv, "-v")) opt_v = 1;
	
	if (!strcmp(*argv, "-V") || !strcmp(*argv, "-version") || 
	    !strcmp(*argv, "--version")) version();
	    
	if (!strcmp(*argv, "-?") || !strcmp(*argv, "-h") || 
	    !strcmp(*argv, "-help") || !strcmp(*argv, "--help")) usage();

	argv++;
	argc--;
  }

  /* Do we have to show the current setup? */
  if (argc == 0) {
	if_print((char *)NULL);
	(void) close(skfd);
	NLS_CATCLOSE(catfd)
	exit(0);
  }

  /* No. Fetch the interface name. */
  spp = argv;
  strncpy(ifr.ifr_name, *spp++, IFNAMSIZ);
  if (*spp == (char *)NULL) {
	if_print(ifr.ifr_name);
	(void) close(skfd);
	NLS_CATCLOSE(catfd)
	exit(0);
  }

  /* The next argument is either an address family name, or an option. */
  if ((ap = get_aftype(*spp)) == NULL) {
	ap = get_aftype("inet");
  } else spp++;
  addr_family = ap->af;

  /* 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;
	}

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

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

	if (!strcmp(*spp, "-broadcast")) {
		goterr |= clr_flag(ifr.ifr_name, IFF_BROADCAST);
		spp++;
		continue;
	}

	if (!strcmp(*spp, "broadcast")) {
		if (*++spp != NULL ) {
			strcpy(host, *spp);
			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(skfd, 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();
		strcpy(host, *spp);
		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(skfd, SIOCSIFDSTADDR, &ifr) < 0) {
			fprintf(stderr, "SIOCSIFDSTADDR: %s\n",
						strerror(errno));
			goterr = 1;
		}
		spp++;
		continue;
	}

	if (!strcmp(*spp, "netmask")) {
		if (*++spp == NULL) usage();
		strcpy(host, *spp);
		if (ap->input(0, host, &sa) < 0) {
			ap->herror(host);
			goterr = 1;
			spp++;
			continue;
		}
		memcpy((char *) &ifr.ifr_netmask, (char *) &sa,
						sizeof(struct sockaddr));
		if (ioctl(skfd, SIOCSIFNETMASK, &ifr) < 0) {
			fprintf(stderr, "SIOCSIFNETMASK: %s\n",
						strerror(errno));
			goterr = 1;
		}
		spp++;
		continue;
	}

	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++;
			strcpy(host, *spp);
			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(skfd, 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();
		strcpy(host, *++spp);
		if (hw->input(host, &sa) < 0) {
			ap->herror(host);
			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 the next argument is a valid hostname, assume OK. */
	strcpy(host, *spp);
	if (ap->input(0, host, &sa) < 0) {
		ap->herror(host);
		usage();
	}

	memcpy((char *) &ifr.ifr_addr, (char *) &sa, sizeof(struct sockaddr));
	if (ioctl(skfd, SIOCSIFADDR, &ifr) < 0) {
		fprintf(stderr, "SIOCSIFADDR: %s\n", strerror(errno));
			goterr = 1;
	}
	goterr |= set_flag(ifr.ifr_name, (IFF_UP | IFF_RUNNING));
	spp++;
  }

  /* Close the socket. */
  (void) close(skfd);

  NLS_CATCLOSE(catfd)
  return(goterr);
}
Example #8
0
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, neednetmask=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
    setlocale (LC_ALL, "");
    bindtextdomain("net-tools", "/usr/share/locale");
    textdomain("net-tools");
#endif

    /* 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: option `%s' not recognised.\n"), 
		    argv[0]);
	    fprintf(stderr, _("ifconfig: `--help' gives usage information.\n"));
	    exit(1);
	}

	argv++;
	argc--;
    }

    /* Create a channel to the NET kernel. */
    if ((skfd = sockets_open(0)) < 0) {
	perror("socket");
	exit(1);
    }

    /* 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)
	spp++; /* it was a AF name */
    else 
	ap = get_aftype(DFLT_AF);
	
    if (ap) {
	addr_family = ap->af;
	skfd = ap->fd;
    }

    /* 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) {
			perror("port: SIOCGIFMAP"); 
			goterr = 1;
			continue;
		    }
		    ifr.ifr_map.port = newport;
		    if (ioctl(skfd, SIOCSIFMAP, &ifr) < 0) {
			perror("port: 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);
	    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;
	}
	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);
	    if (test_flag(ifr.ifr_name, IFF_MULTICAST) > 0)
	    	fprintf(stderr, _("Warning: Interface %s still in MULTICAST mode.\n"), ifr.ifr_name);
	    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);
	    if (test_flag(ifr.ifr_name, IFF_MULTICAST) > 0)
	    	fprintf(stderr, _("Warning: Interface %s still in ALLMULTI mode.\n"), ifr.ifr_name);
	    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++;
	    if (test_flag(ifr.ifr_name, IFF_MULTICAST) > 0)
	    	fprintf(stderr, _("Warning: Interface %s still in DYNAMIC mode.\n"), ifr.ifr_name);
	    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);
	    if (test_flag(ifr.ifr_name, IFF_MULTICAST) > 0)
	    	fprintf(stderr, _("Warning: Interface %s still in BROADCAST mode.\n"), ifr.ifr_name);
	    spp++;
	    continue;
	}
	if (!strcmp(*spp, "broadcast")) {
	    if (*++spp != NULL) {
		safe_strncpy(host, *spp, (sizeof host));
		if (ap->input(0, host, &sa) < 0) {
		    if (ap->herror)
		    	ap->herror(host);
		    else
		    	fprintf(stderr, _("ifconfig: Error resolving '%s' for broadcast\n"), 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) {
		    if (ap->herror)
		    	ap->herror(host);
		    else
		    	fprintf(stderr, _("ifconfig: Error resolving '%s' for dstaddr\n"), 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) {
		    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);
	    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) {
		fprintf(stderr, "mem_start: SIOCGIFMAP: %s\n", strerror(errno)); 
		spp++; 
		goterr = 1;
		continue;
	    }
	    ifr.ifr_map.mem_start = strtoul(*spp, NULL, 0);
	    if (ioctl(skfd, SIOCSIFMAP, &ifr) < 0) {
		fprintf(stderr, "mem_start: SIOCSIFMAP: %s\n", strerror(errno));
		goterr = 1;
	    }
	    spp++;
	    continue;
	}
	if (!strcmp(*spp, "io_addr")) {
	    if (*++spp == NULL)
		usage();
	    if (ioctl(skfd, SIOCGIFMAP, &ifr) < 0) {
		fprintf(stderr, "io_addr: SIOCGIFMAP: %s\n", strerror(errno)); 
		spp++; 
		goterr = 1;
		continue;
	    }
	    ifr.ifr_map.base_addr = strtol(*spp, NULL, 0);
	    if (ioctl(skfd, SIOCSIFMAP, &ifr) < 0) {
		fprintf(stderr, "io_addr: SIOCSIFMAP: %s\n", strerror(errno));
		goterr = 1;
	    }
	    spp++;
	    continue;
	}
	if (!strcmp(*spp, "irq")) {
	    if (*++spp == NULL)
		usage();
	    if (ioctl(skfd, SIOCGIFMAP, &ifr) < 0) {
		fprintf(stderr, "irq: SIOCGIFMAP: %s\n", strerror(errno)); 
		goterr = 1;
		spp++; 
		continue;
	    }
	    ifr.ifr_map.irq = atoi(*spp);
	    if (ioctl(skfd, SIOCSIFMAP, &ifr) < 0) {
		fprintf(stderr, "irq: SIOCSIFMAP: %s\n", strerror(errno));
		goterr = 1;
	    }
	    spp++;
	    continue;
	}
	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")) {
	    if (*(spp + 1) != NULL) {
		spp++;
		safe_strncpy(host, *spp, (sizeof host));
		if (ap->input(0, host, &sa)) {
		    if (ap->herror)
		    	ap->herror(host);
		    else
		    	fprintf(stderr, _("ifconfig: Error resolving '%s' for pointopoint\n"), 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 (hw->input == NULL) {
	    	fprintf(stderr, _("hw address type `%s' has no handler to set address. failed.\n"), *spp);
	    	spp+=2;
	    	goterr = 1;
	    	continue;
	    }
	    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) {
		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++;
	    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 = 128;
		}
		safe_strncpy(host, *spp, (sizeof host));
		if (inet6_aftype.input(1, host, 
				       (struct sockaddr *) &sa6) < 0) {
		    if (inet6_aftype.herror)
		    	inet6_aftype.herror(host);
		    else
		    	fprintf(stderr, _("ifconfig: Error resolving '%s' for add\n"), 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 = 128;
		}
		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 (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));
		    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 = 128;
	    }
	    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, &samask, NULL)) {
	    case -1:
		usage();
		break;
	    case 1:
		if (didnetmask)
		    usage();

		// remeber to set the netmask from samask later
		neednetmask = 1;
		break;
	    }
	}
	if (ap->input == NULL) {
	   fprintf(stderr, _("ifconfig: Cannot set address for this protocol family.\n"));
	   exit(1);
	}
	if (ap->input(0, host, &sa) < 0) {
	    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));
	{
	    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++;
    }

    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);
}
Example #9
0
int arp_main(int argc, char **argv)
{
   int what, i;

   /* Initialize variables... */
   if ((hw = get_hwtype(DFLT_HW)) == NULL) {
      bb_error_msg("%s: hardware type not supported!\n", DFLT_HW);
      return -1;
   }
   if ((ap = get_aftype(DFLT_AF)) == NULL) {
      bb_error_msg("%s: address family not supported!\n", DFLT_AF);
      return -1;
   }
   what = 0;

   /* Fetch the command-line arguments. */
   while ((i = getopt(argc, argv, "A:H:adfp:nsei:t:vh?DNV")) != EOF)
      switch (i) {
         case 'a':
            what = 1;
            opt_a = 1;
            break;
         case 'f':
            what = 2;
            break;
         case 'd':
            what = 3;
            break;
         case 's':
            what = 4;
            break;
         case 'e':
            opt_e = 1;
            break;
         case 'n':
            opt_n = 1;
            break;
         case 'D':
            opt_D = 1;
            break;
         case 'v':
            opt_v = 1;
            break;
         case 'A':
         case 'p':
            ap = get_aftype(optarg);
            if (ap == NULL) {
               bb_error_msg("%s: unknown address family.\n", optarg);
               exit(-1);
            }
            break;
         case 'H':
         case 't':
            hw = get_hwtype(optarg);
            if (hw == NULL) {
               bb_error_msg("%s: unknown hardware type.\n", optarg);
               exit(-1);
            }
            hw_set = 1;
            break;
         case 'i':
            safe_strncpy(device, optarg, sizeof(device));
            break;
         case '?':
         case 'h':
         default:
            bb_show_usage();
      }

   if (ap->af != AF_INET) {
      bb_error_msg("%s: kernel only supports 'inet'.\n", ap->name);
      exit(-1);
   }

   /* If not hw type specified get default */
   if (hw_set==0) {
      if ((hw = get_hwtype(DFLT_HW)) == NULL) {
         bb_error_msg("%s: hardware type not supported!\n", DFLT_HW);
         return (-1);
      }
   }

   if (hw->alen <= 0) {
      bb_error_msg("%s: hardware type without ARP support.\n", hw->name);
      exit(-1);
   }
   if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
      perror("socket");
      return -1;
   }
   /* Now see what we have to do here... */
   switch (what) {
      case 0:
         opt_e = 1;
         what = arp_show(argv[optind]);
         break;

      case 1:                     /* show an ARP entry in the cache */
         what = arp_show(argv[optind]);
         break;

      case 2:                     /* process an EtherFile */
         what = arp_file(argv[optind] ? argv[optind] : "/etc/ethers");
         break;

      case 3:                     /* delete an ARP entry from the cache */
         what = arp_del(&argv[optind]);
         break;

      case 4:                     /* set an ARP entry in the cache */
         what = arp_set(&argv[optind]);
         break;

      default:
         bb_show_usage();
   }

   return what;
}
Example #10
0
int arp_main(int argc, char **argv)
{
    char *hw_type;
    char *protocol;

    unsigned int ulRet = 0;

    /* Initialize variables... */
    ap = get_aftype(DFLT_AF);
    if (!ap)
        bb_error_msg_and_die("%s: %s not supported", DFLT_AF, "address family");

    getopt32(argv, "A:c:H:t:i:adnDsv", &protocol, &protocol,
             &hw_type, &hw_type, &device);
    argv += optind;

    /*start of atp add code for arp send mac by ourself by c00126165 2008-7-15*/

    ulRet = atp_arp_send_packet_main(protocol,(char *)device);

    if (ulRet == 1)
    {
        return 0;
    }
    /*end of atp add code for arp send mac by ourself by c00126165 2008-7-15*/

    if (option_mask32 & ARP_OPT_A || option_mask32 & ARP_OPT_p) {
        ap = get_aftype(protocol);
        if (ap == NULL)
            bb_error_msg_and_die("%s: unknown %s", protocol, "address family");
    }
    if (option_mask32 & ARP_OPT_A || option_mask32 & ARP_OPT_p) {
        hw = get_hwtype(hw_type);
        if (hw == NULL)
            bb_error_msg_and_die("%s: unknown %s", hw_type, "hardware type");
        hw_set = 1;
    }
    //if (option_mask32 & ARP_OPT_i)... -i

    if (ap->af != AF_INET) {
        bb_error_msg_and_die("%s: kernel only supports 'inet'", ap->name);
    }

    /* If no hw type specified get default */
    if (!hw) {
        hw = get_hwtype(DFLT_HW);
        if (!hw)
            bb_error_msg_and_die("%s: %s not supported", DFLT_HW, "hardware type");
    }

    if (hw->alen <= 0) {
        bb_error_msg_and_die("%s: %s without ARP support",
                             hw->name, "hardware type");
    }
    sockfd = xsocket(AF_INET, SOCK_DGRAM, 0);

    /* Now see what we have to do here... */
    if (option_mask32 & (ARP_OPT_d|ARP_OPT_s)) {
        if (argv[0] == NULL)
            bb_error_msg_and_die("need host name");
        if (option_mask32 & ARP_OPT_s)
            return arp_set(argv);
        return arp_del(argv);
    }
    //if (option_mask32 & ARP_OPT_a) - default
    return arp_show(argv[0]);
}
Example #11
0
int main(int argc, char **argv)
{
    int result = 0, mode = 0, c, nargs = 0, verbose = 0;
    char *args[3];
    struct hostent *hp;
    int fd;

#if I18N
    setlocale (LC_ALL, "");
    bindtextdomain("net-tools", "/usr/share/locale");
    textdomain("net-tools");
#endif

    /* Get a default hardware type.  */
    hardware = get_hwtype(DFLT_HW);

    do {
	c = getopt_long(argc, argv, "-ht:aHdsVvf", longopts, NULL);
	switch (c) {
	case EOF:
	    break;
	case 'h':
	    usage();
	case 'V':
	    fprintf(stderr, version_string);
	    exit(E_VERSION);
	    break;
	case 'v':
	    verbose++;
	    break;
	case 'a':
	case 's':
	case 'd':
	    if (mode) {
		fprintf(stderr, _("%s: illegal option mix.\n"), argv[0]);
		usage();
	    } else {
		mode = (c == 'a' ? MODE_DISPLAY : (c == 'd' ? MODE_DELETE : MODE_SET));
	    }
	    break;
	case 'f':
	    mode = MODE_ETHERS;
	    break;
        case 'H':
	case 't':
	    if (optarg) {
		hardware = get_hwtype(optarg);
	    } else {
		usage();
	    }
	    break;
	case 1:
	    if (nargs == 2) {
		usage();
		exit(1);
	    } else {
		args[nargs++] = optarg;
	    }
	    break;
	default:
	    usage();
	}
    } while (c != EOF);

    if (hardware == NULL) {
	fprintf(stderr, _("rarp: %s: unknown hardware type.\n"), optarg);
	exit(1);
    }
    switch (mode) {
    case 0:
	usage();

    case MODE_DISPLAY:
	if (nargs != (mode - 1)) {
	    usage();
	}
	result = display_cache();
	break;

    case MODE_DELETE:
    case MODE_SET:
	if (nargs != (mode - 1)) {
	    usage();
	}
	if ((hp = gethostbyname(args[0])) == NULL) {
	    fprintf(stderr, _("rarp: %s: unknown host\n"), args[0]);
	    exit(1);
	}
	if (fd = socket(PF_INET, SOCK_DGRAM, 0), fd < 0) {
	    perror("socket");
	    exit(1);
	}
	result = (mode == MODE_DELETE) ? rarp_delete(fd, hp) : rarp_set(fd, hp, args[1]);
	close(fd);
	break;

    case MODE_ETHERS:
	if (nargs != 0 && nargs != 1)
	    usage();
	if (fd = socket(PF_INET, SOCK_DGRAM, 0), fd < 0) {
	    perror("socket");
	    exit(1);
	}
	result = rarp_file(fd, nargs ? args[0] : _PATH_ETHERS);
	close(fd);

    }
    exit(result);
}