home *** CD-ROM | disk | FTP | other *** search
/ PC-Online 1996 May / PCOnline_05_1996.bin / linux / source / n / tcpip / net-tool.000 / net-tool / net-tools / ifconfig.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-28  |  16.0 KB  |  675 lines

  1. /*
  2.  * ifconfig    This file contains an implementation of the command
  3.  *        that either displays or sets the characteristics of
  4.  *        one or more of the system's networking interfaces.
  5.  *
  6.  * Usage:    ifconfig [-a] [-i] [-v] interface
  7.  *            [inet address]
  8.  *            [ax25] [hw] address]
  9.  *            [metric NN] [mtu NN]
  10.  *            [trailers] [-trailers]
  11.  *            [arp] [-arp]
  12.  *            [netmask aa.bb.cc.dd]
  13.  *            [dstaddr aa.bb.cc.dd]
  14.  *            [mem_start NN] [io_addr NN] [irq NN]
  15.  *            [[-] broadcast [aa.bb.cc.dd]]
  16.  *            [[-]pointopoint [aa.bb.cc.dd]]
  17.  *            [up] [down] ...
  18.  *
  19.  * Version:    @(#)ifconfig.c    2.30    10/07/93
  20.  *
  21.  * Author:    Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
  22.  *        Copyright 1993 MicroWalt Corporation
  23.  *
  24.  *        This program is free software; you can redistribute it
  25.  *        and/or  modify it under  the terms of  the GNU General
  26.  *        Public  License as  published  by  the  Free  Software
  27.  *        Foundation;  either  version 2 of the License, or  (at
  28.  *        your option) any later version.
  29.  */
  30. #include <sys/types.h>
  31. #include <sys/socket.h>
  32. #include <sys/ioctl.h>
  33. #include <linux/if.h>
  34. #include <linux/if_arp.h>
  35. #include <linux/if_ether.h>
  36. #include <stdio.h>
  37. #include <errno.h>
  38. #include <fcntl.h>
  39. #include <ctype.h>
  40. #include <stdlib.h>
  41. #include <string.h>
  42. #include <unistd.h>
  43. #include "support.h"
  44. #include "pathnames.h"
  45. #include "version.h"
  46.  
  47.  
  48. struct interface {
  49.   char            name[IFNAMSIZ];        /* interface name    */
  50.   short            type;            /* if type        */
  51.   short            flags;            /* various flags    */
  52.   int            metric;            /* routing metric    */
  53.   int            mtu;            /* MTU value        */
  54.   struct ifmap        map;            /* hardware setup    */
  55.   struct sockaddr    addr;            /* IP address        */
  56.   struct sockaddr    dstaddr;        /* P-P IP address    */
  57.   struct sockaddr    broadaddr;        /* IP broadcast address    */
  58.   struct sockaddr    netmask;        /* IP network mask    */
  59.   char            hwaddr[32];        /* HW address        */
  60.   struct enet_statistics stats;            /* statistics        */
  61. };
  62.  
  63.   
  64. char *Release = RELEASE,
  65.      *Version = "@(#) ifconfig 2.30 (10/07/93)";
  66.  
  67.  
  68. int opt_a = 0;                /* show all interfaces        */
  69. int opt_i = 0;                /* show the statistics        */
  70. int opt_v = 0;                /* debugging output flag    */
  71. int skfd = -1;                /* AF_INET raw socket desc.    */
  72. int addr_family = 0;            /* currently selected AF    */
  73.  
  74.  
  75. static void
  76. ife_print(struct interface *ptr)
  77. {
  78.   struct aftype *ap;
  79.   struct hwtype *hw;
  80.   int hf;
  81.   char *dispname="overruns";
  82.   
  83.   ap = get_afntype(ptr->addr.sa_family);
  84.   if (ap == NULL) ap = get_afntype(0);
  85.  
  86.   hf=ptr->type;
  87.  
  88.   if(strncmp(ptr->name,"lo",2)==0)
  89.       hf=255;
  90.       
  91.   if(hf==ARPHRD_CSLIP || hf==ARPHRD_CSLIP6)
  92.   {
  93.       /* Overrun got reused: BAD - fix later */
  94.       dispname="compressed";
  95.   }
  96.       
  97.   hw = get_hwntype(hf);
  98.   if (hw == NULL) hw = get_hwntype(0);
  99.  
  100.   printf("%-8.8s  Link encap:%s  ", ptr->name, hw->title);
  101.   if (hw->sprint != NULL) {
  102.     printf("HWaddr %s", hw->print(ptr->hwaddr));
  103.   }
  104.   printf("\n          %s addr:%s", ap->name, ap->sprint(&ptr->addr, 1));
  105.   if (ptr->flags & IFF_POINTOPOINT) {
  106.     printf("  P-t-P:%s  ", ap->sprint(&ptr->dstaddr, 1));
  107.   } else {
  108.     printf("  Bcast:%s  ", ap->sprint(&ptr->broadaddr, 1));
  109.   }
  110.   printf("Mask:%s\n", ap->sprint(&ptr->netmask, 1));
  111.   printf("          ");
  112.   if (ptr->flags == 0) printf("[NO FLAGS] ");
  113.   if (ptr->flags & IFF_UP) printf("UP ");
  114.   if (ptr->flags & IFF_BROADCAST) printf("BROADCAST ");
  115.   if (ptr->flags & IFF_DEBUG) printf("DEBUG ");
  116.   if (ptr->flags & IFF_LOOPBACK) printf("LOOPBACK ");
  117.   if (ptr->flags & IFF_POINTOPOINT) printf("POINTOPOINT ");
  118.   if (ptr->flags & IFF_NOTRAILERS) printf("NOTRAILERS ");
  119.   if (ptr->flags & IFF_RUNNING) printf("RUNNING ");
  120.   if (ptr->flags & IFF_NOARP) printf("NOARP ");
  121.   if (ptr->flags & IFF_PROMISC) printf("PROMISC ");
  122.   if (ptr->flags & IFF_ALLMULTI) printf("ALLMULTI ");
  123.   if (ptr->flags & IFF_SLAVE) printf("SLAVE ");
  124.   if (ptr->flags & IFF_MASTER) printf("MASTER ");
  125.   if (ptr->flags & IFF_MULTICAST) printf("MULTICAST ");
  126.   printf(" MTU:%d  Metric:%d\n", ptr->mtu, ptr->metric?ptr->metric:1);
  127.  
  128.  
  129.   /* If needed, display the interface statistics. */
  130.   printf("          ");
  131.   printf("RX packets:%u errors:%u dropped:%u %s:%u\n",
  132.         ptr->stats.rx_packets, ptr->stats.rx_errors,
  133.         ptr->stats.rx_dropped, dispname, ptr->stats.rx_fifo_errors);
  134.   printf("          ");
  135.   printf("TX packets:%u errors:%u dropped:%u %s:%u\n",
  136.         ptr->stats.tx_packets, ptr->stats.tx_errors,
  137.         ptr->stats.tx_dropped, dispname, ptr->stats.tx_fifo_errors);
  138.  
  139.   if(hf<255)
  140.   {
  141.       printf("          Interrupt:%d Base address:0x%x ", ptr->map.irq,ptr->map.base_addr);
  142.       if(ptr->map.mem_start)
  143.       {
  144.           printf("Memory:%lx-%lx ",
  145.               ptr->map.mem_start,ptr->map.mem_end);
  146.       }
  147.       if(ptr->map.dma)
  148.           printf("DMA chan:%x ",ptr->map.dma);
  149.       printf("\n");
  150.   }
  151.   printf("\n");
  152. }
  153.  
  154.  
  155. static void if_getstats(char *ifname, struct interface *ife)
  156. {
  157.   FILE *f=fopen("/proc/net/dev","r");
  158.   char buf[256];
  159.   char *bp;
  160.   if(f==NULL)
  161.       return;
  162.   while(fgets(buf,255,f))
  163.   {
  164.       bp=buf;
  165.       while(*bp&&isspace(*bp))
  166.           bp++;
  167.       if(strncmp(bp,ifname,strlen(ifname))==0 && bp[strlen(ifname)]==':')
  168.       {
  169.          bp=strchr(bp,':');
  170.          bp++;
  171.          sscanf(bp,"%d %d %d %d %d %d %d %d %d %d %d",
  172.              &ife->stats.rx_packets,
  173.              &ife->stats.rx_errors,
  174.              &ife->stats.rx_dropped,
  175.              &ife->stats.rx_fifo_errors,
  176.              &ife->stats.rx_frame_errors,
  177.              
  178.              &ife->stats.tx_packets,
  179.              &ife->stats.tx_errors,
  180.              &ife->stats.tx_dropped,
  181.              &ife->stats.tx_fifo_errors,
  182.              &ife->stats.collisions,
  183.              
  184.              &ife->stats.tx_carrier_errors
  185.          );
  186.          fclose(f);
  187.          return;
  188.       }
  189.   }
  190.   fclose(f);
  191. }
  192.  
  193. /* Fetch the inteface configuration from the kernel. */
  194. static int
  195. if_fetch(char *ifname, struct interface *ife)
  196. {
  197.   struct ifreq ifr;
  198.  
  199.   memset((char *) ife, 0, sizeof(struct interface));
  200.   strcpy(ife->name, ifname);
  201.  
  202.   strcpy(ifr.ifr_name, ifname);
  203.   if (ioctl(skfd, SIOCGIFFLAGS, &ifr) < 0) return(-1);
  204.   ife->flags = ifr.ifr_flags;
  205.  
  206.   strcpy(ifr.ifr_name, ifname);
  207.   if (ioctl(skfd, SIOCGIFADDR, &ifr) < 0) {
  208.     memset(&ife->addr, 0, sizeof(struct sockaddr));
  209.   } else ife->addr = ifr.ifr_addr;
  210.  
  211.   strcpy(ifr.ifr_name, ifname);
  212.   
  213.   if (ioctl(skfd, SIOCGIFHWADDR, &ifr) < 0) {
  214.     memset(ife->hwaddr, 0, 32);
  215.   } else memcpy(ife->hwaddr,ifr.ifr_hwaddr.sa_data,8);
  216.  
  217.   ife->type=ifr.ifr_hwaddr.sa_family;
  218.  
  219.   strcpy(ifr.ifr_name, ifname);
  220.   if (ioctl(skfd, SIOCGIFMETRIC, &ifr) < 0) {
  221.     ife->metric = 0;
  222.   } else ife->metric = ifr.ifr_metric;
  223.  
  224.   strcpy(ifr.ifr_name, ifname);
  225.   if (ioctl(skfd, SIOCGIFMTU, &ifr) < 0) {
  226.     ife->mtu = 0;
  227.   } else ife->mtu = ifr.ifr_mtu;
  228.  
  229.   strcpy(ifr.ifr_name, ifname);
  230.   if (ioctl(skfd, SIOCGIFMAP, &ifr) < 0) {
  231.     memset(&ife->map, 0, sizeof(struct ifmap));
  232.   } else memcpy(&ife->map,&ifr.ifr_map,sizeof(struct ifmap));
  233.  
  234.   strcpy(ifr.ifr_name, ifname);
  235.   if (ioctl(skfd, SIOCGIFDSTADDR, &ifr) < 0) {
  236.     memset(&ife->dstaddr, 0, sizeof(struct sockaddr));
  237.   } else ife->dstaddr = ifr.ifr_dstaddr;
  238.  
  239.   strcpy(ifr.ifr_name, ifname);
  240.   if (ioctl(skfd, SIOCGIFBRDADDR, &ifr) < 0) {
  241.     memset(&ife->broadaddr, 0, sizeof(struct sockaddr));
  242.   } else ife->broadaddr = ifr.ifr_broadaddr;
  243.  
  244.   strcpy(ifr.ifr_name, ifname);
  245.   if (ioctl(skfd, SIOCGIFNETMASK, &ifr) < 0) {
  246.     memset(&ife->netmask, 0, sizeof(struct sockaddr));
  247.   } else ife->netmask = ifr.ifr_netmask;
  248.   
  249.   strcpy(ifr.ifr_name, ifname);
  250.   if (ioctl(skfd, SIOCGIFMAP, &ifr) < 0) {
  251.       memset(&ife->map, 0, sizeof(struct ifmap));
  252.   }
  253.   else ife->map = ifr.ifr_map;
  254.   
  255.   if_getstats(ifname,ife);
  256.   return(0);
  257. }
  258.  
  259.  
  260. static void
  261. if_print(char *ifname)
  262. {
  263.   char buff[1024];
  264.   struct interface ife;
  265.   struct ifconf ifc;
  266.   struct ifreq *ifr;
  267.   int i;
  268.  
  269.   if (ifname == (char *)NULL) {
  270.     ifc.ifc_len = sizeof(buff);
  271.     ifc.ifc_buf = buff;
  272.     if (ioctl(skfd, SIOCGIFCONF, &ifc) < 0) {
  273.         fprintf(stderr, "SIOCGIFCONF: %s\n", strerror(errno));
  274.         return;
  275.     }
  276.  
  277.     ifr = ifc.ifc_req;
  278.     for (i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; ifr++) {
  279.         if (if_fetch(ifr->ifr_name, &ife) < 0) {
  280.             fprintf(stderr, "%s: unknown interface.\n",
  281.                             ifr->ifr_name);
  282.             continue;
  283.         }
  284.  
  285.         if (((ife.flags & IFF_UP) == 0) && !opt_a) continue;
  286.         ife_print(&ife);
  287.     }
  288.   } else {
  289.     if (if_fetch(ifname, &ife) < 0)
  290.         fprintf(stderr, "%s: unknown interface.\n", ifname);
  291.       else ife_print(&ife);
  292.   }
  293. }
  294.  
  295.  
  296. /* Set a certain interface flag. */
  297. static int
  298. set_flag(char *ifname, short flag)
  299. {
  300.   struct ifreq ifr;
  301.  
  302.   strcpy(ifr.ifr_name, ifname);
  303.   if (ioctl(skfd, SIOCGIFFLAGS, &ifr) < 0) return(-1);
  304.   ifr.ifr_flags |= flag;
  305.   if (ioctl(skfd, SIOCSIFFLAGS, &ifr) < 0) {
  306.     fprintf(stderr, "SIOCSIFFLAGS: %s\n", strerror(errno));
  307.     return(-1);
  308.   }
  309.   return(0);
  310. }
  311.  
  312.  
  313. /* Clear a certain interface flag. */
  314. static int
  315. clr_flag(char *ifname, short flag)
  316. {
  317.   struct ifreq ifr;
  318.  
  319.   strcpy(ifr.ifr_name, ifname);
  320.   if (ioctl(skfd, SIOCGIFFLAGS, &ifr) < 0) return(-1);
  321.   ifr.ifr_flags &= ~flag;
  322.   if (ioctl(skfd, SIOCSIFFLAGS, &ifr) < 0) {
  323.     fprintf(stderr, "SIOCSIFFLAGS: %s\n", strerror(errno));
  324.     return(-1);
  325.   }
  326.   return(0);
  327. }
  328.  
  329.  
  330. static void
  331. usage(void)
  332. {
  333.   fprintf(stderr, "Usage: ifconfig [-a] [-i] [-v] interface\n");
  334.   fprintf(stderr, "                [inet address]\n");
  335.   fprintf(stderr, "                [ax25] [hw] address]\n");
  336.   fprintf(stderr, "                [metric NN] [mtu NN]\n");
  337.   fprintf(stderr, "                [trailers] [-trailers]\n");
  338.   fprintf(stderr, "                [arp] [-arp]\n");
  339.   fprintf(stderr, "                [netmask aa.bb.cc.dd]\n");
  340.   fprintf(stderr, "                [dstaddr aa.bb.cc.dd]\n");
  341.   fprintf(stderr, "                [mem_start NN] [io_addr NN] [irq NN]\n");
  342.   fprintf(stderr, "                [[-] broadcast [aa.bb.cc.dd]]\n");
  343.   fprintf(stderr, "                [[-]pointopoint [aa.bb.cc.dd]]\n");
  344.   fprintf(stderr, "                [up] [down] ...\n");
  345.   exit(1);
  346. }
  347.  
  348.  
  349. int
  350. main(int argc, char **argv)
  351. {
  352.   struct sockaddr sa;
  353.   char host[128];
  354.   struct aftype *ap;
  355.   struct hwtype *hw;
  356.   struct ifreq ifr;
  357.   int goterr = 0;
  358.   char **spp;
  359.  
  360.   /* Create a channel to the NET kernel. */
  361.   if ((skfd = socket(AF_INET, SOCK_DGRAM,0)) < 0) {
  362.     perror("socket");
  363.     exit(-1);
  364.   }
  365.   /* Find any options. */
  366.   argc--; argv++;
  367.   while (argc && *argv[0] == '-') {
  368.     if (!strcmp(*argv, "-a")) opt_a = 1;
  369.     if (!strcmp(*argv, "-v")) opt_v = 1;
  370.     argv++;
  371.     argc--;
  372.   }
  373.  
  374.   /* Do we have to show the current setup? */
  375.   if (argc == 0) {
  376.     if_print((char *)NULL);
  377.     (void) close(skfd);
  378.     exit(0);
  379.   }
  380.  
  381.   /* No. Fetch the interface name. */
  382.   spp = argv;
  383.   strncpy(ifr.ifr_name, *spp++, IFNAMSIZ);
  384.   if (*spp == (char *)NULL) {
  385.     if_print(ifr.ifr_name);
  386.     (void) close(skfd);
  387.     exit(0);
  388.   }
  389.  
  390.   /* The next argument is either an address family name, or an option. */
  391.   if ((ap = get_aftype(*spp)) == NULL) {
  392.     ap = get_aftype("inet");
  393.   } else spp++;
  394.   addr_family = ap->af;
  395.  
  396.   /* Process the remaining arguments. */
  397.   while (*spp != (char *)NULL) {
  398.     if (!strcmp(*spp, "arp")) {
  399.         goterr |= clr_flag(ifr.ifr_name, IFF_NOARP);
  400.         spp++;
  401.         continue;
  402.     }
  403.  
  404.     if (!strcmp(*spp, "-arp")) {
  405.         goterr |= set_flag(ifr.ifr_name, IFF_NOARP);
  406.         spp++;
  407.         continue;
  408.     }
  409.  
  410.     if (!strcmp(*spp, "trailers")) {
  411.         goterr |= clr_flag(ifr.ifr_name, IFF_NOTRAILERS);
  412.         spp++;
  413.         continue;
  414.     }
  415.  
  416.     if (!strcmp(*spp, "-trailers")) {
  417.         goterr |= set_flag(ifr.ifr_name, IFF_NOTRAILERS);
  418.         spp++;
  419.         continue;
  420.     }
  421.  
  422.     if (!strcmp(*spp, "promisc")) {
  423.         goterr |= set_flag(ifr.ifr_name, IFF_PROMISC);
  424.         spp++;
  425.         continue;
  426.     }
  427.  
  428.     if (!strcmp(*spp, "-promisc")) {
  429.         goterr |= clr_flag(ifr.ifr_name, IFF_PROMISC);
  430.         spp++;
  431.         continue;
  432.     }
  433.  
  434.     if (!strcmp(*spp, "multicast")) {
  435.         goterr |= set_flag(ifr.ifr_name, IFF_MULTICAST);
  436.         spp++;
  437.         continue;
  438.     }
  439.  
  440.     if (!strcmp(*spp, "-multicast")) {
  441.         goterr |= clr_flag(ifr.ifr_name, IFF_MULTICAST);
  442.         spp++;
  443.         continue;
  444.     }
  445.  
  446.     if (!strcmp(*spp, "allmulti")) {
  447.         goterr |= set_flag(ifr.ifr_name, IFF_ALLMULTI);
  448.         spp++;
  449.         continue;
  450.     }
  451.  
  452.     if (!strcmp(*spp, "-allmulti")) {
  453.         goterr |= clr_flag(ifr.ifr_name, IFF_ALLMULTI);
  454.         spp++;
  455.         continue;
  456.     }
  457.  
  458.     if (!strcmp(*spp, "up")) {
  459.         goterr |= set_flag(ifr.ifr_name, (IFF_UP | IFF_RUNNING));
  460.         spp++;
  461.         continue;
  462.     }
  463.  
  464.     if (!strcmp(*spp, "down")) {
  465.         goterr |= clr_flag(ifr.ifr_name, IFF_UP);
  466.         spp++;
  467.         continue;
  468.     }
  469.  
  470.     if (!strcmp(*spp, "metric")) {
  471.         if (*++spp == NULL) usage();
  472.         ifr.ifr_metric = atoi(*spp);
  473.         if (ioctl(skfd, SIOCSIFMETRIC, &ifr) < 0) {
  474.             fprintf(stderr, "SIOCSIFMETRIC: %s\n", strerror(errno));
  475.             goterr = 1;
  476.         }
  477.         spp++;
  478.         continue;
  479.     }
  480.  
  481.     if (!strcmp(*spp, "mtu")) {
  482.         if (*++spp == NULL) usage();
  483.         ifr.ifr_mtu = atoi(*spp);
  484.         if (ioctl(skfd, SIOCSIFMTU, &ifr) < 0) {
  485.             fprintf(stderr, "SIOCSIFMTU: %s\n", strerror(errno));
  486.             goterr = 1;
  487.         }
  488.         spp++;
  489.         continue;
  490.     }
  491.  
  492.     if (!strcmp(*spp, "-broadcast")) {
  493.         goterr |= clr_flag(ifr.ifr_name, IFF_BROADCAST);
  494.         spp++;
  495.         continue;
  496.     }
  497.  
  498.     if (!strcmp(*spp, "broadcast")) {
  499.         if (*++spp != NULL ) {
  500.             strcpy(host, *spp);
  501.             if (ap->input(host, &sa) < 0) {
  502.                 ap->herror(host);
  503.                 goterr = 1;
  504.                 spp++;
  505.                 continue;
  506.             }
  507.             memcpy((char *) &ifr.ifr_broadaddr, (char *) &sa,
  508.                         sizeof(struct sockaddr));
  509.             if (ioctl(skfd, SIOCSIFBRDADDR, &ifr) < 0) {
  510.                 fprintf(stderr, "SIOCSIFBRDADDR: %s\n",
  511.                             strerror(errno));
  512.                 goterr = 1;
  513.             }
  514.             spp++;
  515.         }
  516.         goterr |= set_flag(ifr.ifr_name, IFF_BROADCAST);
  517.         continue;
  518.     }
  519.  
  520.     if (!strcmp(*spp, "dstaddr")) {
  521.         if (*++spp == NULL) usage();
  522.         strcpy(host, *spp);
  523.         if (ap->input(host, &sa) < 0) {
  524.             ap->herror(host);
  525.             goterr = 1;
  526.             spp++;
  527.             continue;
  528.         }
  529.         memcpy((char *) &ifr.ifr_dstaddr, (char *) &sa,
  530.                         sizeof(struct sockaddr));
  531.         if (ioctl(skfd, SIOCSIFDSTADDR, &ifr) < 0) {
  532.             fprintf(stderr, "SIOCSIFDSTADDR: %s\n",
  533.                         strerror(errno));
  534.             goterr = 1;
  535.         }
  536.         spp++;
  537.         continue;
  538.     }
  539.  
  540.     if (!strcmp(*spp, "netmask")) {
  541.         if (*++spp == NULL) usage();
  542.         strcpy(host, *spp);
  543.         if (ap->input(host, &sa) < 0) {
  544.             ap->herror(host);
  545.             goterr = 1;
  546.             spp++;
  547.             continue;
  548.         }
  549.         memcpy((char *) &ifr.ifr_netmask, (char *) &sa,
  550.                         sizeof(struct sockaddr));
  551.         if (ioctl(skfd, SIOCSIFNETMASK, &ifr) < 0) {
  552.             fprintf(stderr, "SIOCSIFNETMASK: %s\n",
  553.                         strerror(errno));
  554.             goterr = 1;
  555.         }
  556.         spp++;
  557.         continue;
  558.     }
  559.  
  560.     if (!strcmp(*spp, "mem_start")) {
  561.         if (*++spp == NULL) usage();
  562.         if (ioctl(skfd, SIOCGIFMAP, &ifr) < 0) {
  563.             goterr = 1;
  564.             continue;
  565.         }
  566.         ifr.ifr_map.mem_start = strtoul(*spp, NULL, 0);
  567.         if (ioctl(skfd, SIOCSIFMAP, &ifr) < 0) {
  568.             fprintf(stderr, "SIOCSIFMAP: %s\n", strerror(errno));
  569.             goterr = 1;
  570.         }
  571.         spp++;
  572.         continue;
  573.     }
  574.  
  575.     if (!strcmp(*spp, "io_addr")) {
  576.         if (*++spp == NULL) usage();
  577.         if (ioctl(skfd, SIOCGIFMAP, &ifr) < 0) {
  578.             goterr = 1;
  579.             continue;
  580.         }
  581.         ifr.ifr_map.base_addr = strtol(*spp, NULL, 0);
  582.         if (ioctl(skfd, SIOCSIFMAP, &ifr) < 0) {
  583.             fprintf(stderr, "SIOCSIFMAP: %s\n", strerror(errno));
  584.             goterr = 1;
  585.         }
  586.         spp++;
  587.         continue;
  588.     }
  589.  
  590.     if (!strcmp(*spp, "irq")) {
  591.         if (*++spp == NULL) usage();
  592.         if (ioctl(skfd, SIOCGIFMAP, &ifr) < 0) {
  593.             goterr = 1;
  594.             continue;
  595.         }
  596.         ifr.ifr_map.irq = atoi(*spp);
  597.         if (ioctl(skfd, SIOCSIFMAP, &ifr) < 0) {
  598.             fprintf(stderr, "SIOCSIFMAP: %s\n", strerror(errno));
  599.             goterr = 1;
  600.         }
  601.         spp++;
  602.         continue;
  603.     }
  604.  
  605.     if (!strcmp(*spp, "-pointopoint")) {
  606.         goterr |= clr_flag(ifr.ifr_name, IFF_POINTOPOINT);
  607.         spp++;
  608.         continue;
  609.     }
  610.  
  611.     if (!strcmp(*spp, "pointopoint")) {
  612.         if (*++spp != NULL) {
  613.             strcpy(host, *spp);
  614.             if (ap->input(host, &sa)) {
  615.                 ap->herror(host);
  616.                 goterr = 1;
  617.                 spp++;
  618.                 continue;
  619.             };
  620.             memcpy((char *) &ifr.ifr_dstaddr, (char *) &sa,
  621.                         sizeof(struct sockaddr));
  622.             if (ioctl(skfd, SIOCSIFDSTADDR, &ifr) < 0) {
  623.                 fprintf(stderr, "SIOCSIFDSTADDR: %s\n",
  624.                             strerror(errno));
  625.                 goterr = 1;
  626.             }
  627.         }
  628.         goterr |= set_flag(ifr.ifr_name, IFF_POINTOPOINT);
  629.         spp++;
  630.         continue;
  631.     };
  632.  
  633.     if (!strcmp(*spp, "hw")) {
  634.         if (*++spp == NULL) usage();
  635.         if ((hw = get_hwtype(*spp)) == NULL) usage();
  636.         strcpy(host, *++spp);
  637.         if (hw->input(host, &sa) < 0) {
  638.             ap->herror(host);
  639.             goterr = 1;
  640.             spp++;
  641.             continue;
  642.         }
  643.         memcpy((char *) &ifr.ifr_hwaddr, (char *) &sa,
  644.                         sizeof(struct sockaddr));
  645.         if (ioctl(skfd, SIOCSIFHWADDR, &ifr) < 0) {
  646.             fprintf(stderr, "SIOCSIFHWADDR: %s\n",
  647.                         strerror(errno));
  648.             goterr = 1;
  649.         }
  650.         spp++;
  651.         continue;
  652.     }
  653.  
  654.     /* If the next argument is a valid hostname, assume OK. */
  655.     strcpy(host, *spp);
  656.     if (ap->input(host, &sa) < 0) {
  657.         ap->herror(host);
  658.         usage();
  659.     }
  660.  
  661.     memcpy((char *) &ifr.ifr_addr, (char *) &sa, sizeof(struct sockaddr));
  662.     if (ioctl(skfd, SIOCSIFADDR, &ifr) < 0) {
  663.         fprintf(stderr, "SIOCSIFADDR: %s\n", strerror(errno));
  664.             goterr = 1;
  665.     }
  666.     goterr |= set_flag(ifr.ifr_name, (IFF_UP | IFF_RUNNING));
  667.     spp++;
  668.   }
  669.  
  670.   /* Close the socket. */
  671.   (void) close(skfd);
  672.  
  673.   return(goterr);
  674. }
  675.