Improve the process for GNU tools
[minix3.git] / minix / commands / pr_routes / pr_routes.c
blob864c16e3ca71ddebfcf691067756fbc3e4800d21
1 /*
2 vmd/cmd/simple/pr_routes.c
3 */
5 #include <sys/types.h>
6 #include <sys/ioctl.h>
7 #include <errno.h>
8 #include <fcntl.h>
9 #include <stdarg.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <unistd.h>
15 #include <net/netlib.h>
16 #include <net/hton.h>
17 #include <net/gen/in.h>
18 #include <net/gen/ip_io.h>
19 #include <net/gen/route.h>
20 #include <netdb.h>
21 #include <net/gen/inet.h>
22 #include <arpa/inet.h>
24 #define N_IF 64 /* More than enough? */
26 char *prog_name;
27 int all_devices;
28 char *ifname;
29 ipaddr_t iftab[N_IF];
31 static void print_header(void);
32 static void print_route(nwio_route_t *route);
33 static void fill_iftab(void);
34 static char *get_ifname(ipaddr_t addr);
35 static void fatal(char *fmt, ...);
36 static void usage(void);
38 int main(int argc, char *argv[])
40 int nr_routes, i;
41 nwio_route_t route;
42 nwio_ipconf_t ip_conf;
43 unsigned long ioctl_cmd;
44 int ip_fd;
45 int result;
46 int c;
47 char *ip_device, *cp;
48 int a_flag, i_flag, o_flag;
49 char *I_arg;
51 prog_name= argv[0];
53 a_flag= 0;
54 i_flag= 0;
55 o_flag= 0;
56 I_arg= NULL;
57 while ((c =getopt(argc, argv, "?aI:io")) != -1)
59 switch(c)
61 case '?':
62 usage();
63 case 'a':
64 if (a_flag)
65 usage();
66 a_flag= 1;
67 break;
68 case 'I':
69 if (I_arg)
70 usage();
71 I_arg= optarg;
72 break;
73 case 'i':
74 if (i_flag || o_flag)
75 usage();
76 i_flag= 1;
77 break;
78 case 'o':
79 if (i_flag || o_flag)
80 usage();
81 o_flag= 1;
82 break;
83 default:
84 fprintf(stderr, "%s: getopt failed: '%c'\n",
85 prog_name, c);
86 exit(1);
89 if (optind != argc)
90 usage();
92 ip_device= I_arg;
93 all_devices= a_flag;
95 if (i_flag)
96 ioctl_cmd= NWIOGIPIROUTE;
97 else
98 ioctl_cmd= NWIOGIPOROUTE;
100 if (ip_device == NULL)
101 ip_device= getenv("IP_DEVICE");
102 ifname= ip_device;
103 if (ip_device == NULL)
104 ip_device= IP_DEVICE;
106 ip_fd= open(ip_device, O_RDONLY);
107 if (ip_fd == -1)
109 fprintf(stderr, "%s: unable to open %s: %s\n", prog_name,
110 ip_device, strerror(errno));
111 exit(1);
114 if (!all_devices && ifname)
116 cp= strrchr(ip_device, '/');
117 if (cp)
118 ifname= cp+1;
120 else
122 ifname= NULL;
123 fill_iftab();
126 result= ioctl(ip_fd, NWIOGIPCONF, &ip_conf);
127 if (result == -1)
129 fprintf(stderr, "%s: unable to NWIOIPGCONF: %s\n",
130 prog_name, strerror(errno));
131 exit(1);
134 route.nwr_ent_no= 0;
135 result= ioctl(ip_fd, ioctl_cmd, &route);
136 if (result == -1)
138 fprintf(stderr, "%s: unable to NWIOGIPxROUTE: %s\n",
139 prog_name, strerror(errno));
140 exit(1);
142 print_header();
143 nr_routes= route.nwr_ent_count;
144 for (i= 0; i<nr_routes; i++)
146 route.nwr_ent_no= i;
147 result= ioctl(ip_fd, ioctl_cmd, &route);
148 if (result == -1)
150 fprintf(stderr, "%s: unable to NWIOGIPxROUTE: %s\n",
151 prog_name, strerror(errno));
152 exit(1);
154 if (all_devices || route.nwr_ifaddr == ip_conf.nwic_ipaddr)
155 print_route(&route);
157 exit(0);
160 int ent_width= 5;
161 int if_width= 4;
162 int dest_width= 18;
163 int gateway_width= 15;
164 int dist_width= 4;
165 int pref_width= 5;
166 int mtu_width= 4;
168 static void print_header(void)
170 printf("%*s ", ent_width, "ent #");
171 printf("%*s ", if_width, "if");
172 printf("%*s ", dest_width, "dest");
173 printf("%*s ", gateway_width, "gateway");
174 printf("%*s ", dist_width, "dist");
175 printf("%*s ", pref_width, "pref");
176 printf("%*s ", mtu_width, "mtu");
177 printf("%s", "flags");
178 printf("\n");
181 static char *cidr2a(ipaddr_t addr, ipaddr_t mask)
183 ipaddr_t testmask= 0xFFFFFFFF;
184 int n;
185 static char result[sizeof("255.255.255.255/255.255.255.255")];
187 for (n= 32; n >= 0; n--)
189 if (mask == htonl(testmask))
190 break;
191 testmask= (testmask << 1) & 0xFFFFFFFF;
194 sprintf(result, "%s/%-2d", inet_ntoa(*(struct in_addr *)&addr), n);
195 if (n == -1)
196 strcpy(strchr(result, '/')+1,
197 inet_ntoa(*(struct in_addr *)&mask));
198 return result;
201 static void print_route(nwio_route_t *route)
203 if (!(route->nwr_flags & NWRF_INUSE))
204 return;
206 printf("%*lu ", ent_width, (unsigned long) route->nwr_ent_no);
207 printf("%*s ", if_width,
208 ifname ? ifname : get_ifname(route->nwr_ifaddr));
209 printf("%*s ", dest_width, cidr2a(route->nwr_dest, route->nwr_netmask));
210 printf("%*s ", gateway_width,
211 inet_ntoa(*(struct in_addr *)&route->nwr_gateway));
212 printf("%*lu ", dist_width, (unsigned long) route->nwr_dist);
213 printf("%*ld ", pref_width, (long) route->nwr_pref);
214 printf("%*lu", mtu_width, (long) route->nwr_mtu);
215 if (route->nwr_flags & NWRF_STATIC)
216 printf(" static");
217 if (route->nwr_flags & NWRF_UNREACHABLE)
218 printf(" dead");
219 printf("\n");
222 static void fill_iftab(void)
224 int i, j, r, fd;
225 nwio_ipconf_t ip_conf;
226 char dev_name[12]; /* /dev/ipXXXX */
228 for (i= 0; i<N_IF; i++)
230 iftab[i]= 0;
232 sprintf(dev_name, "/dev/ip%d", i);
233 fd= open(dev_name, O_RDWR);
234 if (fd == -1)
236 if (errno == EACCES || errno == ENOENT || errno == ENXIO)
237 continue;
238 fatal("unable to open '%s': %s",
239 dev_name, strerror(errno));
241 fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK);
242 r= ioctl(fd, NWIOGIPCONF, &ip_conf);
243 if (r == -1 && errno == EAGAIN)
245 /* interface is down */
246 close(fd);
247 continue;
249 if (r == -1)
251 fatal("NWIOGIPCONF failed on %s: %s",
252 dev_name, strerror(errno));
255 iftab[i]= ip_conf.nwic_ipaddr;
256 close(fd);
258 for (j= 0; j<i; j++)
260 if (iftab[j] == iftab[i])
262 fatal("duplicate address in ip%d and ip%d: %s",
263 i, j,
264 inet_ntoa(*(struct in_addr *)&iftab[i]));
271 static char *get_ifname(ipaddr_t addr)
273 static char name[7]; /* ipXXXX */
275 int i;
277 for (i= 0; i<N_IF; i++)
279 if (iftab[i] != addr)
280 continue;
281 sprintf(name, "ip%d", i);
282 return name;
285 return inet_ntoa(*(struct in_addr *)&addr);
288 static void fatal(char *fmt, ...)
290 va_list ap;
292 va_start(ap, fmt);
293 fprintf(stderr, "%s: ", prog_name);
294 vfprintf(stderr, fmt, ap);
295 fprintf(stderr, "\n");
296 va_end(ap);
297 exit(1);
300 static void usage(void)
302 fprintf(stderr, "Usage: %s [-i|-o] [ -a ] [ -I <ip-device> ]\n",
303 prog_name);
304 exit(1);
308 * $PchId: pr_routes.c,v 1.8 2002/04/11 10:58:58 philip Exp $