pr_routes.c

Go to the documentation of this file.
00001 /*
00002 vmd/cmd/simple/pr_routes.c
00003 */
00004 
00005 #define _POSIX_C_SOURCE 2
00006 
00007 #include <sys/types.h>
00008 #include <sys/ioctl.h>
00009 #include <errno.h>
00010 #include <fcntl.h>
00011 #include <stdarg.h>
00012 #include <stdio.h>
00013 #include <stdlib.h>
00014 #include <string.h>
00015 #include <unistd.h>
00016 
00017 #include <net/netlib.h>
00018 #include <net/hton.h>
00019 #include <net/gen/in.h>
00020 #include <net/gen/ip_io.h>
00021 #include <net/gen/route.h>
00022 #include <net/gen/netdb.h>
00023 #include <net/gen/inet.h>
00024 
00025 #define N_IF    64      /* More than enough? */
00026 
00027 char *prog_name;
00028 int all_devices;
00029 char *ifname;
00030 ipaddr_t iftab[N_IF];
00031 
00032 static void print_header(void);
00033 static void print_route(nwio_route_t *route);
00034 static void fill_iftab(void);
00035 static char *get_ifname(ipaddr_t addr);
00036 static void fatal(char *fmt, ...);
00037 static void usage(void);
00038 
00039 int main(int argc, char *argv[])
00040 {
00041         int nr_routes, i;
00042         nwio_route_t route;
00043         nwio_ipconf_t ip_conf;
00044         unsigned long ioctl_cmd;
00045         int ip_fd;
00046         int result;
00047         int c;
00048         char *ip_device, *cp;
00049         int a_flag, i_flag, o_flag;
00050         char *I_arg;
00051 
00052         prog_name= argv[0];
00053 
00054         a_flag= 0;
00055         i_flag= 0;
00056         o_flag= 0;
00057         I_arg= NULL;
00058         while ((c =getopt(argc, argv, "?aI:io")) != -1)
00059         {
00060                 switch(c)
00061                 {
00062                 case '?':
00063                         usage();
00064                 case 'a':
00065                         if (a_flag)
00066                                 usage();
00067                         a_flag= 1;
00068                         break;
00069                 case 'I':
00070                         if (I_arg)
00071                                 usage();
00072                         I_arg= optarg;
00073                         break;
00074                 case 'i':
00075                         if (i_flag || o_flag)
00076                                 usage();
00077                         i_flag= 1;
00078                         break;
00079                 case 'o':
00080                         if (i_flag || o_flag)
00081                                 usage();
00082                         o_flag= 1;
00083                         break;
00084                 default:
00085                         fprintf(stderr, "%s: getopt failed: '%c'\n",
00086                                 prog_name, c);
00087                         exit(1);
00088                 }
00089         }
00090         if (optind != argc)
00091                 usage();
00092 
00093         ip_device= I_arg;
00094         all_devices= a_flag;
00095 
00096         if (i_flag)
00097                 ioctl_cmd= NWIOGIPIROUTE;
00098         else
00099                 ioctl_cmd= NWIOGIPOROUTE;
00100 
00101         if (ip_device == NULL)
00102                 ip_device= getenv("IP_DEVICE");
00103         ifname= ip_device;
00104         if (ip_device == NULL)
00105                 ip_device= IP_DEVICE;
00106                 
00107         ip_fd= open(ip_device, O_RDONLY);
00108         if (ip_fd == -1)
00109         {
00110                 fprintf(stderr, "%s: unable to open %s: %s\n", prog_name,
00111                         ip_device, strerror(errno));
00112                 exit(1);
00113         }
00114 
00115         if (!all_devices && ifname)
00116         {
00117                 cp= strrchr(ip_device, '/');
00118                 if (cp)
00119                         ifname= cp+1;
00120         }
00121         else
00122         {
00123                 ifname= NULL;
00124                 fill_iftab();
00125         }
00126 
00127         result= ioctl(ip_fd, NWIOGIPCONF, &ip_conf);
00128         if (result == -1)
00129         {
00130                 fprintf(stderr, "%s: unable to NWIOIPGCONF: %s\n",
00131                         prog_name, strerror(errno));
00132                 exit(1);
00133         }
00134 
00135         route.nwr_ent_no= 0;
00136         result= ioctl(ip_fd, ioctl_cmd, &route);
00137         if (result == -1)
00138         {
00139                 fprintf(stderr, "%s: unable to NWIOGIPxROUTE: %s\n",
00140                         prog_name, strerror(errno));
00141                 exit(1);
00142         }
00143         print_header();
00144         nr_routes= route.nwr_ent_count;
00145         for (i= 0; i<nr_routes; i++)
00146         {
00147                 route.nwr_ent_no= i;
00148                 result= ioctl(ip_fd, ioctl_cmd, &route);
00149                 if (result == -1)
00150                 {
00151                         fprintf(stderr, "%s: unable to NWIOGIPxROUTE: %s\n",
00152                                 prog_name, strerror(errno));
00153                         exit(1);
00154                 }
00155                 if (all_devices || route.nwr_ifaddr == ip_conf.nwic_ipaddr)
00156                         print_route(&route);
00157         }
00158         exit(0);
00159 }
00160 
00161 int ent_width= 5;
00162 int if_width= 4;
00163 int dest_width= 18;
00164 int gateway_width= 15;
00165 int dist_width= 4;
00166 int pref_width= 5;
00167 int mtu_width= 4;
00168 
00169 static void print_header(void)
00170 {
00171         printf("%*s ", ent_width, "ent #");
00172         printf("%*s ", if_width, "if");
00173         printf("%*s ", dest_width, "dest");
00174         printf("%*s ", gateway_width, "gateway");
00175         printf("%*s ", dist_width, "dist");
00176         printf("%*s ", pref_width, "pref");
00177         printf("%*s ", mtu_width, "mtu");
00178         printf("%s", "flags");
00179         printf("\n");
00180 }
00181 
00182 static char *cidr2a(ipaddr_t addr, ipaddr_t mask)
00183 {
00184         ipaddr_t testmask= 0xFFFFFFFF;
00185         int n;
00186         static char result[sizeof("255.255.255.255/255.255.255.255")];
00187 
00188         for (n= 32; n >= 0; n--)
00189         {
00190                 if (mask == htonl(testmask))
00191                         break;
00192                 testmask= (testmask << 1) & 0xFFFFFFFF;
00193         }
00194 
00195         sprintf(result, "%s/%-2d", inet_ntoa(addr), n);
00196         if (n == -1)
00197                 strcpy(strchr(result, '/')+1, inet_ntoa(mask));
00198         return result;
00199 }
00200 
00201 static void print_route(nwio_route_t *route)
00202 {
00203         if (!(route->nwr_flags & NWRF_INUSE))
00204                 return;
00205 
00206         printf("%*lu ", ent_width, (unsigned long) route->nwr_ent_no);
00207         printf("%*s ", if_width,
00208                 ifname ?  ifname : get_ifname(route->nwr_ifaddr));
00209         printf("%*s ", dest_width, cidr2a(route->nwr_dest, route->nwr_netmask));
00210         printf("%*s ", gateway_width, inet_ntoa(route->nwr_gateway));
00211         printf("%*lu ", dist_width, (unsigned long) route->nwr_dist);
00212         printf("%*ld ", pref_width, (long) route->nwr_pref);
00213         printf("%*lu", mtu_width, (long) route->nwr_mtu);
00214         if (route->nwr_flags & NWRF_STATIC)
00215                 printf(" static");
00216         if (route->nwr_flags & NWRF_UNREACHABLE)
00217                 printf(" dead");
00218         printf("\n");
00219 }
00220 
00221 static void fill_iftab(void)
00222 {
00223         int i, j, r, fd;
00224         nwio_ipconf_t ip_conf;
00225         char dev_name[12];      /* /dev/ipXXXX */
00226 
00227         for (i= 0; i<N_IF; i++)
00228         {
00229                 iftab[i]= 0;
00230 
00231                 sprintf(dev_name, "/dev/ip%d", i);
00232                 fd= open(dev_name, O_RDWR);
00233                 if (fd == -1)
00234                 {
00235                         if (errno == EACCES || errno == ENOENT || errno == ENXIO)
00236                                 continue;
00237                         fatal("unable to open '%s': %s",
00238                                 dev_name, strerror(errno));
00239                 }
00240                 fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK);
00241                 r= ioctl(fd, NWIOGIPCONF, &ip_conf);
00242                 if (r == -1 && errno == EAGAIN)
00243                 {
00244                         /* interface is down */
00245                         close(fd);
00246                         continue;
00247                 }
00248                 if (r == -1)
00249                 {
00250                         fatal("NWIOGIPCONF failed on %s: %s",
00251                                 dev_name, strerror(errno));
00252                 }
00253 
00254                 iftab[i]= ip_conf.nwic_ipaddr;
00255                 close(fd);
00256 
00257                 for (j= 0; j<i; j++)
00258                 {
00259                         if (iftab[j] == iftab[i])
00260                         {
00261                                 fatal("duplicate address in ip%d and ip%d: %s",
00262                                         i, j, inet_ntoa(iftab[i]));
00263                         }
00264                 }
00265 
00266         }
00267 }
00268 
00269 static char *get_ifname(ipaddr_t addr)
00270 {
00271         static char name[7];    /* ipXXXX */
00272 
00273         int i;
00274 
00275         for (i= 0; i<N_IF; i++)
00276         {
00277                 if (iftab[i] != addr)
00278                         continue;
00279                 sprintf(name, "ip%d", i);
00280                 return name;
00281         }
00282 
00283         return inet_ntoa(addr);
00284 }
00285 
00286 static void fatal(char *fmt, ...)
00287 {
00288         va_list ap;
00289 
00290         va_start(ap, fmt);
00291         fprintf(stderr, "%s: ", prog_name);
00292         vfprintf(stderr, fmt, ap);
00293         fprintf(stderr, "\n");
00294         va_end(ap);
00295         exit(1);
00296 }
00297 
00298 static void usage(void)
00299 {
00300         fprintf(stderr, "Usage: %s [-i|-o] [ -a ] [ -I <ip-device> ]\n",
00301                 prog_name);
00302         exit(1);
00303 }
00304 
00305 /*
00306  * $PchId: pr_routes.c,v 1.8 2002/04/11 10:58:58 philip Exp $
00307  */

Generated on Fri Apr 14 22:57:10 2006 for minix by  doxygen 1.4.6