home *** CD-ROM | disk | FTP | other *** search
/ PC-Online 1996 May / PCOnline_05_1996.bin / linux / source / n / tcpip / netkit-a.06 / netkit-a / NetKit-A-0.06 / net-tools-1.1.38 / ifconfig.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-17  |  15.7 KB  |  663 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.   printf(" MTU:%d  Metric:%d\n", ptr->mtu, ptr->metric?ptr->metric:1);
  126.  
  127.  
  128.   /* If needed, display the interface statistics. */
  129.   printf("          ");
  130.   printf("RX packets:%u errors:%u dropped:%u %s:%u\n",
  131.         ptr->stats.rx_packets, ptr->stats.rx_errors,
  132.         ptr->stats.rx_dropped, dispname, ptr->stats.rx_fifo_errors);
  133.   printf("          ");
  134.   printf("TX packets:%u errors:%u dropped:%u %s:%u\n",
  135.         ptr->stats.tx_packets, ptr->stats.tx_errors,
  136.         ptr->stats.tx_dropped, dispname, ptr->stats.tx_fifo_errors);
  137.  
  138.   if(hf<255)
  139.   {
  140.       printf("          Interrupt:%d Base address:0x%x ", ptr->map.irq,ptr->map.base_addr);
  141.       if(ptr->map.mem_start)
  142.       {
  143.           printf("Memory:%lx-%lx ",
  144.               ptr->map.mem_start,ptr->map.mem_end);
  145.       }
  146.       if(ptr->map.dma)
  147.           printf("DMA chan:%x ",ptr->map.dma);
  148.       printf("\n");
  149.   }
  150.   printf("\n");
  151. }
  152.  
  153.  
  154. static void if_getstats(char *ifname, struct interface *ife)
  155. {
  156.   FILE *f=fopen("/proc/net/dev","r");
  157.   char buf[256];
  158.   char *bp;
  159.   if(f==NULL)
  160.       return;
  161.   while(fgets(buf,255,f))
  162.   {
  163.       bp=buf;
  164.       while(*bp&&isspace(*bp))
  165.           bp++;
  166.       if(strncmp(bp,ifname,strlen(ifname))==0 && bp[strlen(ifname)]==':')
  167.       {
  168.          bp=strchr(bp,':');
  169.          bp++;
  170.          sscanf(bp,"%d %d %d %d %d %d %d %d %d %d %d",
  171.              &ife->stats.rx_packets,
  172.              &ife->stats.rx_errors,
  173.              &ife->stats.rx_dropped,
  174.              &ife->stats.rx_fifo_errors,
  175.              &ife->stats.rx_frame_errors,
  176.              
  177.              &ife->stats.tx_packets,
  178.              &ife->stats.tx_errors,
  179.              &ife->stats.tx_dropped,
  180.              &ife->stats.tx_fifo_errors,
  181.              &ife->stats.collisions,
  182.              
  183.              &ife->stats.tx_carrier_errors
  184.          );
  185.          fclose(f);
  186.          return;
  187.       }
  188.   }
  189.   fclose(f);
  190. }
  191.  
  192. /* Fetch the inteface configuration from the kernel. */
  193. static int
  194. if_fetch(char *ifname, struct interface *ife)
  195. {
  196.   struct ifreq ifr;
  197.  
  198.   memset((char *) ife, 0, sizeof(struct interface));
  199.   strcpy(ife->name, ifname);
  200.  
  201.   strcpy(ifr.ifr_name, ifname);
  202.   if (ioctl(skfd, SIOCGIFFLAGS, &ifr) < 0) return(-1);
  203.   ife->flags = ifr.ifr_flags;
  204.  
  205.   strcpy(ifr.ifr_name, ifname);
  206.   if (ioctl(skfd, SIOCGIFADDR, &ifr) < 0) {
  207.     memset(&ife->addr, 0, sizeof(struct sockaddr));
  208.   } else ife->addr = ifr.ifr_addr;
  209.  
  210.   strcpy(ifr.ifr_name, ifname);
  211.   
  212.   if (ioctl(skfd, SIOCGIFHWADDR, &ifr) < 0) {
  213.     memset(ife->hwaddr, 0, 32);
  214.   } else memcpy(ife->hwaddr,ifr.ifr_hwaddr.sa_data,8);
  215.  
  216.   ife->type=ifr.ifr_hwaddr.sa_family;
  217.  
  218.   strcpy(ifr.ifr_name, ifname);
  219.   if (ioctl(skfd, SIOCGIFMETRIC, &ifr) < 0) {
  220.     ife->metric = 0;
  221.   } else ife->metric = ifr.ifr_metric;
  222.  
  223.   strcpy(ifr.ifr_name, ifname);
  224.   if (ioctl(skfd, SIOCGIFMTU, &ifr) < 0) {
  225.     ife->mtu = 0;
  226.   } else ife->mtu = ifr.ifr_mtu;
  227.  
  228.   strcpy(ifr.ifr_name, ifname);
  229.   if (ioctl(skfd, SIOCGIFMAP, &ifr) < 0) {
  230.     memset(&ife->map, 0, sizeof(struct ifmap));
  231.   } else memcpy(&ife->map,&ifr.ifr_map,sizeof(struct ifmap));
  232.  
  233.   strcpy(ifr.ifr_name, ifname);
  234.   if (ioctl(skfd, SIOCGIFDSTADDR, &ifr) < 0) {
  235.     memset(&ife->dstaddr, 0, sizeof(struct sockaddr));
  236.   } else ife->dstaddr = ifr.ifr_dstaddr;
  237.  
  238.   strcpy(ifr.ifr_name, ifname);
  239.   if (ioctl(skfd, SIOCGIFBRDADDR, &ifr) < 0) {
  240.     memset(&ife->broadaddr, 0, sizeof(struct sockaddr));
  241.   } else ife->broadaddr = ifr.ifr_broadaddr;
  242.  
  243.   strcpy(ifr.ifr_name, ifname);
  244.   if (ioctl(skfd, SIOCGIFNETMASK, &ifr) < 0) {
  245.     memset(&ife->netmask, 0, sizeof(struct sockaddr));
  246.   } else ife->netmask = ifr.ifr_netmask;
  247.   
  248.   strcpy(ifr.ifr_name, ifname);
  249.   if (ioctl(skfd, SIOCGIFMAP, &ifr) < 0) {
  250.       memset(&ife->map, 0, sizeof(struct ifmap));
  251.   }
  252.   else ife->map = ifr.ifr_map;
  253.   
  254.   if_getstats(ifname,ife);
  255.   return(0);
  256. }
  257.  
  258.  
  259. static void
  260. if_print(char *ifname)
  261. {
  262.   char buff[1024];
  263.   struct interface ife;
  264.   struct ifconf ifc;
  265.   struct ifreq *ifr;
  266.   int i;
  267.  
  268.   if (ifname == (char *)NULL) {
  269.     ifc.ifc_len = sizeof(buff);
  270.     ifc.ifc_buf = buff;
  271.     if (ioctl(skfd, SIOCGIFCONF, &ifc) < 0) {
  272.         fprintf(stderr, "SIOCGIFCONF: %s\n", strerror(errno));
  273.         return;
  274.     }
  275.  
  276.     ifr = ifc.ifc_req;
  277.     for (i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; ifr++) {
  278.         if (if_fetch(ifr->ifr_name, &ife) < 0) {
  279.             fprintf(stderr, "%s: unknown interface.\n",
  280.                             ifr->ifr_name);
  281.             continue;
  282.         }
  283.  
  284.         if (((ife.flags & IFF_UP) == 0) && !opt_a) continue;
  285.         ife_print(&ife);
  286.     }
  287.   } else {
  288.     if (if_fetch(ifname, &ife) < 0)
  289.         fprintf(stderr, "%s: unknown interface.\n", ifname);
  290.       else ife_print(&ife);
  291.   }
  292. }
  293.  
  294.  
  295. /* Set a certain interface flag. */
  296. static int
  297. set_flag(char *ifname, short flag)
  298. {
  299.   struct ifreq ifr;
  300.  
  301.   strcpy(ifr.ifr_name, ifname);
  302.   if (ioctl(skfd, SIOCGIFFLAGS, &ifr) < 0) return(-1);
  303.   ifr.ifr_flags |= flag;
  304.   if (ioctl(skfd, SIOCSIFFLAGS, &ifr) < 0) {
  305.     fprintf(stderr, "SIOCSIFFLAGS: %s\n", strerror(errno));
  306.     return(-1);
  307.   }
  308.   return(0);
  309. }
  310.  
  311.  
  312. /* Clear a certain interface flag. */
  313. static int
  314. clr_flag(char *ifname, short flag)
  315. {
  316.   struct ifreq ifr;
  317.  
  318.   strcpy(ifr.ifr_name, ifname);
  319.   if (ioctl(skfd, SIOCGIFFLAGS, &ifr) < 0) return(-1);
  320.   ifr.ifr_flags &= ~flag;
  321.   if (ioctl(skfd, SIOCSIFFLAGS, &ifr) < 0) {
  322.     fprintf(stderr, "SIOCSIFFLAGS: %s\n", strerror(errno));
  323.     return(-1);
  324.   }
  325.   return(0);
  326. }
  327.  
  328.  
  329. static void
  330. usage(void)
  331. {
  332.   fprintf(stderr, "Usage: ifconfig [-a] [-i] [-v] interface\n");
  333.   fprintf(stderr, "                [inet address]\n");
  334.   fprintf(stderr, "                [ax25] [hw] address]\n");
  335.   fprintf(stderr, "                [metric NN] [mtu NN]\n");
  336.   fprintf(stderr, "                [trailers] [-trailers]\n");
  337.   fprintf(stderr, "                [arp] [-arp]\n");
  338.   fprintf(stderr, "                [netmask aa.bb.cc.dd]\n");
  339.   fprintf(stderr, "                [dstaddr aa.bb.cc.dd]\n");
  340.   fprintf(stderr, "                [mem_start NN] [io_addr NN] [irq NN]\n");
  341.   fprintf(stderr, "                [[-] broadcast [aa.bb.cc.dd]]\n");
  342.   fprintf(stderr, "                [[-]pointopoint [aa.bb.cc.dd]]\n");
  343.   fprintf(stderr, "                [up] [down] ...\n");
  344.   exit(1);
  345. }
  346.  
  347.  
  348. int
  349. main(int argc, char **argv)
  350. {
  351.   struct sockaddr sa;
  352.   char host[128];
  353.   struct aftype *ap;
  354.   struct hwtype *hw;
  355.   struct ifreq ifr;
  356.   int goterr = 0;
  357.   char **spp;
  358.  
  359.   /* Create a channel to the NET kernel. */
  360.   if ((skfd = socket(AF_INET, SOCK_DGRAM,0)) < 0) {
  361.     perror("socket");
  362.     exit(-1);
  363.   }
  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, "allmulti")) {
  435.         goterr |= set_flag(ifr.ifr_name, IFF_ALLMULTI);
  436.         spp++;
  437.         continue;
  438.     }
  439.  
  440.     if (!strcmp(*spp, "-allmulti")) {
  441.         goterr |= clr_flag(ifr.ifr_name, IFF_ALLMULTI);
  442.         spp++;
  443.         continue;
  444.     }
  445.  
  446.     if (!strcmp(*spp, "up")) {
  447.         goterr |= set_flag(ifr.ifr_name, (IFF_UP | IFF_RUNNING));
  448.         spp++;
  449.         continue;
  450.     }
  451.  
  452.     if (!strcmp(*spp, "down")) {
  453.         goterr |= clr_flag(ifr.ifr_name, IFF_UP);
  454.         spp++;
  455.         continue;
  456.     }
  457.  
  458.     if (!strcmp(*spp, "metric")) {
  459.         if (*++spp == NULL) usage();
  460.         ifr.ifr_metric = atoi(*spp);
  461.         if (ioctl(skfd, SIOCSIFMETRIC, &ifr) < 0) {
  462.             fprintf(stderr, "SIOCSIFMETRIC: %s\n", strerror(errno));
  463.             goterr = 1;
  464.         }
  465.         spp++;
  466.         continue;
  467.     }
  468.  
  469.     if (!strcmp(*spp, "mtu")) {
  470.         if (*++spp == NULL) usage();
  471.         ifr.ifr_mtu = atoi(*spp);
  472.         if (ioctl(skfd, SIOCSIFMTU, &ifr) < 0) {
  473.             fprintf(stderr, "SIOCSIFMTU: %s\n", strerror(errno));
  474.             goterr = 1;
  475.         }
  476.         spp++;
  477.         continue;
  478.     }
  479.  
  480.     if (!strcmp(*spp, "-broadcast")) {
  481.         goterr |= clr_flag(ifr.ifr_name, IFF_BROADCAST);
  482.         spp++;
  483.         continue;
  484.     }
  485.  
  486.     if (!strcmp(*spp, "broadcast")) {
  487.         if (*++spp != NULL ) {
  488.             strcpy(host, *spp);
  489.             if (ap->input(host, &sa) < 0) {
  490.                 ap->herror(host);
  491.                 goterr = 1;
  492.                 spp++;
  493.                 continue;
  494.             }
  495.             memcpy((char *) &ifr.ifr_broadaddr, (char *) &sa,
  496.                         sizeof(struct sockaddr));
  497.             if (ioctl(skfd, SIOCSIFBRDADDR, &ifr) < 0) {
  498.                 fprintf(stderr, "SIOCSIFBRDADDR: %s\n",
  499.                             strerror(errno));
  500.                 goterr = 1;
  501.             }
  502.             spp++;
  503.         }
  504.         goterr |= set_flag(ifr.ifr_name, IFF_BROADCAST);
  505.         continue;
  506.     }
  507.  
  508.     if (!strcmp(*spp, "dstaddr")) {
  509.         if (*++spp == NULL) usage();
  510.         strcpy(host, *spp);
  511.         if (ap->input(host, &sa) < 0) {
  512.             ap->herror(host);
  513.             goterr = 1;
  514.             spp++;
  515.             continue;
  516.         }
  517.         memcpy((char *) &ifr.ifr_dstaddr, (char *) &sa,
  518.                         sizeof(struct sockaddr));
  519.         if (ioctl(skfd, SIOCSIFDSTADDR, &ifr) < 0) {
  520.             fprintf(stderr, "SIOCSIFDSTADDR: %s\n",
  521.                         strerror(errno));
  522.             goterr = 1;
  523.         }
  524.         spp++;
  525.         continue;
  526.     }
  527.  
  528.     if (!strcmp(*spp, "netmask")) {
  529.         if (*++spp == NULL) usage();
  530.         strcpy(host, *spp);
  531.         if (ap->input(host, &sa) < 0) {
  532.             ap->herror(host);
  533.             goterr = 1;
  534.             spp++;
  535.             continue;
  536.         }
  537.         memcpy((char *) &ifr.ifr_netmask, (char *) &sa,
  538.                         sizeof(struct sockaddr));
  539.         if (ioctl(skfd, SIOCSIFNETMASK, &ifr) < 0) {
  540.             fprintf(stderr, "SIOCSIFNETMASK: %s\n",
  541.                         strerror(errno));
  542.             goterr = 1;
  543.         }
  544.         spp++;
  545.         continue;
  546.     }
  547.  
  548.     if (!strcmp(*spp, "mem_start")) {
  549.         if (*++spp == NULL) usage();
  550.         if (ioctl(skfd, SIOCGIFMAP, &ifr) < 0) {
  551.             goterr = 1;
  552.             continue;
  553.         }
  554.         ifr.ifr_map.mem_start = strtoul(*spp, NULL, 0);
  555.         if (ioctl(skfd, SIOCSIFMAP, &ifr) < 0) {
  556.             fprintf(stderr, "SIOCSIFMAP: %s\n", strerror(errno));
  557.             goterr = 1;
  558.         }
  559.         spp++;
  560.         continue;
  561.     }
  562.  
  563.     if (!strcmp(*spp, "io_addr")) {
  564.         if (*++spp == NULL) usage();
  565.         if (ioctl(skfd, SIOCGIFMAP, &ifr) < 0) {
  566.             goterr = 1;
  567.             continue;
  568.         }
  569.         ifr.ifr_map.base_addr = strtol(*spp, NULL, 0);
  570.         if (ioctl(skfd, SIOCSIFMAP, &ifr) < 0) {
  571.             fprintf(stderr, "SIOCSIFMAP: %s\n", strerror(errno));
  572.             goterr = 1;
  573.         }
  574.         spp++;
  575.         continue;
  576.     }
  577.  
  578.     if (!strcmp(*spp, "irq")) {
  579.         if (*++spp == NULL) usage();
  580.         if (ioctl(skfd, SIOCGIFMAP, &ifr) < 0) {
  581.             goterr = 1;
  582.             continue;
  583.         }
  584.         ifr.ifr_map.irq = atoi(*spp);
  585.         if (ioctl(skfd, SIOCSIFMAP, &ifr) < 0) {
  586.             fprintf(stderr, "SIOCSIFMAP: %s\n", strerror(errno));
  587.             goterr = 1;
  588.         }
  589.         spp++;
  590.         continue;
  591.     }
  592.  
  593.     if (!strcmp(*spp, "-pointopoint")) {
  594.         goterr |= clr_flag(ifr.ifr_name, IFF_POINTOPOINT);
  595.         spp++;
  596.         continue;
  597.     }
  598.  
  599.     if (!strcmp(*spp, "pointopoint")) {
  600.         if (*++spp != NULL) {
  601.             strcpy(host, *spp);
  602.             if (ap->input(host, &sa)) {
  603.                 ap->herror(host);
  604.                 goterr = 1;
  605.                 spp++;
  606.                 continue;
  607.             };
  608.             memcpy((char *) &ifr.ifr_dstaddr, (char *) &sa,
  609.                         sizeof(struct sockaddr));
  610.             if (ioctl(skfd, SIOCSIFDSTADDR, &ifr) < 0) {
  611.                 fprintf(stderr, "SIOCSIFDSTADDR: %s\n",
  612.                             strerror(errno));
  613.                 goterr = 1;
  614.             }
  615.         }
  616.         goterr |= set_flag(ifr.ifr_name, IFF_POINTOPOINT);
  617.         spp++;
  618.         continue;
  619.     };
  620.  
  621.     if (!strcmp(*spp, "hw")) {
  622.         if (*++spp == NULL) usage();
  623.         if ((hw = get_hwtype(*spp)) == NULL) usage();
  624.         strcpy(host, *++spp);
  625.         if (hw->input(host, &sa) < 0) {
  626.             ap->herror(host);
  627.             goterr = 1;
  628.             spp++;
  629.             continue;
  630.         }
  631.         memcpy((char *) &ifr.ifr_hwaddr, (char *) &sa,
  632.                         sizeof(struct sockaddr));
  633.         if (ioctl(skfd, SIOCSIFHWADDR, &ifr) < 0) {
  634.             fprintf(stderr, "SIOCSIFHWADDR: %s\n",
  635.                         strerror(errno));
  636.             goterr = 1;
  637.         }
  638.         spp++;
  639.         continue;
  640.     }
  641.  
  642.     /* If the next argument is a valid hostname, assume OK. */
  643.     strcpy(host, *spp);
  644.     if (ap->input(host, &sa) < 0) {
  645.         ap->herror(host);
  646.         usage();
  647.     }
  648.  
  649.     memcpy((char *) &ifr.ifr_addr, (char *) &sa, sizeof(struct sockaddr));
  650.     if (ioctl(skfd, SIOCSIFADDR, &ifr) < 0) {
  651.         fprintf(stderr, "SIOCSIFADDR: %s\n", strerror(errno));
  652.             goterr = 1;
  653.     }
  654.     goterr |= set_flag(ifr.ifr_name, (IFF_UP | IFF_RUNNING));
  655.     spp++;
  656.   }
  657.  
  658.   /* Close the socket. */
  659.   (void) close(skfd);
  660.  
  661.   return(goterr);
  662. }
  663.