int goterr = 0;
int goterr = 0, didnetmask = 0;
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 HAVE_AFINET6  extern struct aftype inet6_aftype;  struct sockaddr_in6 sa6;  struct in6_ifreq ifr6;  unsigned long prefix_len;  char *cp;#endif  #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;    }#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;    }    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;    }#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++;	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();      if (*++spp == NULL) usage();      strcpy(host, *spp);      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;      }      strcpy(host, *spp);      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));            if (ioctl(inet6_sock, SIOGIFINDEX, &ifr) < 0) {	perror("SIOGIFINDEX");	goterr = 1;	spp++;	continue;      }      ifr6.ifr6_ifindex = ifr.ifr_ifindex;      ifr6.ifr6_prefixlen = prefix_len;      if (ioctl(inet6_sock, SIOCSIFADDR, &ifr6) < 0) {	fprintf(stderr, "SIOCSIFADDR: %s\n",		strerror(errno));	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;      }      strcpy(host, *spp);      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));            if (ioctl(inet6_sock, SIOGIFINDEX, &ifr) < 0) {	perror("SIOGIFINDEX");	goterr = 1;	spp++;	continue;      }      ifr6.ifr6_ifindex = ifr.ifr_ifindex;      ifr6.ifr6_prefixlen = prefix_len;#ifdef SIOCDIFADDR      if (ioctl(inet6_sock, 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;      }      strcpy(host, *spp);      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));            if (ioctl(inet6_sock, SIOGIFINDEX, &ifr) < 0) {	perror("SIOGIFINDEX");	goterr = 1;	spp++;	continue;      }            ifr6.ifr6_ifindex = ifr.ifr_ifindex;      ifr6.ifr6_prefixlen = prefix_len;            if (ioctl(inet6_sock, 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. */    strcpy(host, *spp);    if (ap->input(0, host, &sa) < 0) {      ap->herror(host);      usage();    }    memcpy((char *) &ifr.ifr_addr, (char *) &sa, sizeof(struct sockaddr));    {      int r;      switch (ap->af) {#if HAVE_AFINET      case AF_INET:	r = ioctl(inet_sock, SIOCSIFADDR, &ifr);	break;#endif#if HAVE_AFECONET      case AF_ECONET:	r = ioctl(ec_sock, SIOCSIFADDR, &ifr);	break;#endif      default:	printf("Don't know how to set addresses for this family.\n");	exit(1);      }      if (r < 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);}