custom message type for VM_INFO
[minix3.git] / commands / pr_routes / pr_routes.c
blob1e24e3fd7244519a67a3e2056f5cde10d48177a6
1 /*
2 vmd/cmd/simple/pr_routes.c
3 */
5 #define _POSIX_C_SOURCE 2
7 #include <sys/types.h>
8 #include <sys/ioctl.h>
9 #include <errno.h>
10 #include <fcntl.h>
11 #include <stdarg.h>
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <unistd.h>
17 #include <net/netlib.h>
18 #include <net/hton.h>
19 #include <net/gen/in.h>
20 #include <net/gen/ip_io.h>
21 #include <net/gen/route.h>
22 #include <net/gen/netdb.h>
23 #include <net/gen/inet.h>
25 #define N_IF 64 /* More than enough? */
27 char *prog_name;
28 int all_devices;
29 char *ifname;
30 ipaddr_t iftab[N_IF];
32 static void print_header(void);
33 static void print_route(nwio_route_t *route);
34 static void fill_iftab(void);
35 static char *get_ifname(ipaddr_t addr);
36 static void fatal(char *fmt, ...);
37 static void usage(void);
39 int main(int argc, char *argv[])
41 int nr_routes, i;
42 nwio_route_t route;
43 nwio_ipconf_t ip_conf;
44 unsigned long ioctl_cmd;
45 int ip_fd;
46 int result;
47 int c;
48 char *ip_device, *cp;
49 int a_flag, i_flag, o_flag;
50 char *I_arg;
52 prog_name= argv[0];
54 a_flag= 0;
55 i_flag= 0;
56 o_flag= 0;
57 I_arg= NULL;
58 while ((c =getopt(argc, argv, "?aI:io")) != -1)
60 switch(c)
62 case '?':
63 usage();
64 case 'a':
65 if (a_flag)
66 usage();
67 a_flag= 1;
68 break;
69 case 'I':
70 if (I_arg)
71 usage();
72 I_arg= optarg;
73 break;
74 case 'i':
75 if (i_flag || o_flag)
76 usage();
77 i_flag= 1;
78 break;
79 case 'o':
80 if (i_flag || o_flag)
81 usage();
82 o_flag= 1;
83 break;
84 default:
85 fprintf(stderr, "%s: getopt failed: '%c'\n",
86 prog_name, c);
87 exit(1);
90 if (optind != argc)
91 usage();
93 ip_device= I_arg;
94 all_devices= a_flag;
96 if (i_flag)
97 ioctl_cmd= NWIOGIPIROUTE;
98 else
99 ioctl_cmd= NWIOGIPOROUTE;
101 if (ip_device == NULL)
102 ip_device= getenv("IP_DEVICE");
103 ifname= ip_device;
104 if (ip_device == NULL)
105 ip_device= IP_DEVICE;
107 ip_fd= open(ip_device, O_RDONLY);
108 if (ip_fd == -1)
110 fprintf(stderr, "%s: unable to open %s: %s\n", prog_name,
111 ip_device, strerror(errno));
112 exit(1);
115 if (!all_devices && ifname)
117 cp= strrchr(ip_device, '/');
118 if (cp)
119 ifname= cp+1;
121 else
123 ifname= NULL;
124 fill_iftab();
127 result= ioctl(ip_fd, NWIOGIPCONF, &ip_conf);
128 if (result == -1)
130 fprintf(stderr, "%s: unable to NWIOIPGCONF: %s\n",
131 prog_name, strerror(errno));
132 exit(1);
135 route.nwr_ent_no= 0;
136 result= ioctl(ip_fd, ioctl_cmd, &route);
137 if (result == -1)
139 fprintf(stderr, "%s: unable to NWIOGIPxROUTE: %s\n",
140 prog_name, strerror(errno));
141 exit(1);
143 print_header();
144 nr_routes= route.nwr_ent_count;
145 for (i= 0; i<nr_routes; i++)
147 route.nwr_ent_no= i;
148 result= ioctl(ip_fd, ioctl_cmd, &route);
149 if (result == -1)
151 fprintf(stderr, "%s: unable to NWIOGIPxROUTE: %s\n",
152 prog_name, strerror(errno));
153 exit(1);
155 if (all_devices || route.nwr_ifaddr == ip_conf.nwic_ipaddr)
156 print_route(&route);
158 exit(0);
161 int ent_width= 5;
162 int if_width= 4;
163 int dest_width= 18;
164 int gateway_width= 15;
165 int dist_width= 4;
166 int pref_width= 5;
167 int mtu_width= 4;
169 static void print_header(void)
171 printf("%*s ", ent_width, "ent #");
172 printf("%*s ", if_width, "if");
173 printf("%*s ", dest_width, "dest");
174 printf("%*s ", gateway_width, "gateway");
175 printf("%*s ", dist_width, "dist");
176 printf("%*s ", pref_width, "pref");
177 printf("%*s ", mtu_width, "mtu");
178 printf("%s", "flags");
179 printf("\n");
182 static char *cidr2a(ipaddr_t addr, ipaddr_t mask)
184 ipaddr_t testmask= 0xFFFFFFFF;
185 int n;
186 static char result[sizeof("255.255.255.255/255.255.255.255")];
188 for (n= 32; n >= 0; n--)
190 if (mask == htonl(testmask))
191 break;
192 testmask= (testmask << 1) & 0xFFFFFFFF;
195 sprintf(result, "%s/%-2d", inet_ntoa(addr), n);
196 if (n == -1)
197 strcpy(strchr(result, '/')+1, inet_ntoa(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, inet_ntoa(route->nwr_gateway));
211 printf("%*lu ", dist_width, (unsigned long) route->nwr_dist);
212 printf("%*ld ", pref_width, (long) route->nwr_pref);
213 printf("%*lu", mtu_width, (long) route->nwr_mtu);
214 if (route->nwr_flags & NWRF_STATIC)
215 printf(" static");
216 if (route->nwr_flags & NWRF_UNREACHABLE)
217 printf(" dead");
218 printf("\n");
221 static void fill_iftab(void)
223 int i, j, r, fd;
224 nwio_ipconf_t ip_conf;
225 char dev_name[12]; /* /dev/ipXXXX */
227 for (i= 0; i<N_IF; i++)
229 iftab[i]= 0;
231 sprintf(dev_name, "/dev/ip%d", i);
232 fd= open(dev_name, O_RDWR);
233 if (fd == -1)
235 if (errno == EACCES || errno == ENOENT || errno == ENXIO)
236 continue;
237 fatal("unable to open '%s': %s",
238 dev_name, strerror(errno));
240 fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK);
241 r= ioctl(fd, NWIOGIPCONF, &ip_conf);
242 if (r == -1 && errno == EAGAIN)
244 /* interface is down */
245 close(fd);
246 continue;
248 if (r == -1)
250 fatal("NWIOGIPCONF failed on %s: %s",
251 dev_name, strerror(errno));
254 iftab[i]= ip_conf.nwic_ipaddr;
255 close(fd);
257 for (j= 0; j<i; j++)
259 if (iftab[j] == iftab[i])
261 fatal("duplicate address in ip%d and ip%d: %s",
262 i, j, inet_ntoa(iftab[i]));
269 static char *get_ifname(ipaddr_t addr)
271 static char name[7]; /* ipXXXX */
273 int i;
275 for (i= 0; i<N_IF; i++)
277 if (iftab[i] != addr)
278 continue;
279 sprintf(name, "ip%d", i);
280 return name;
283 return inet_ntoa(addr);
286 static void fatal(char *fmt, ...)
288 va_list ap;
290 va_start(ap, fmt);
291 fprintf(stderr, "%s: ", prog_name);
292 vfprintf(stderr, fmt, ap);
293 fprintf(stderr, "\n");
294 va_end(ap);
295 exit(1);
298 static void usage(void)
300 fprintf(stderr, "Usage: %s [-i|-o] [ -a ] [ -I <ip-device> ]\n",
301 prog_name);
302 exit(1);
306 * $PchId: pr_routes.c,v 1.8 2002/04/11 10:58:58 philip Exp $