00001
00002
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
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];
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
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];
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
00307