source: trunk/minix/commands/simple/pr_routes.c@ 9

Last change on this file since 9 was 9, checked in by Mattia Monga, 13 years ago

Minix 3.1.2a

File size: 5.7 KB
Line 
1/*
2vmd/cmd/simple/pr_routes.c
3*/
4
5#define _POSIX_C_SOURCE 2
6
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>
16
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>
24
25#define N_IF 64 /* More than enough? */
26
27char *prog_name;
28int all_devices;
29char *ifname;
30ipaddr_t iftab[N_IF];
31
32static void print_header(void);
33static void print_route(nwio_route_t *route);
34static void fill_iftab(void);
35static char *get_ifname(ipaddr_t addr);
36static void fatal(char *fmt, ...);
37static void usage(void);
38
39int main(int argc, char *argv[])
40{
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;
51
52 prog_name= argv[0];
53
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)
59 {
60 switch(c)
61 {
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);
88 }
89 }
90 if (optind != argc)
91 usage();
92
93 ip_device= I_arg;
94 all_devices= a_flag;
95
96 if (i_flag)
97 ioctl_cmd= NWIOGIPIROUTE;
98 else
99 ioctl_cmd= NWIOGIPOROUTE;
100
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;
106
107 ip_fd= open(ip_device, O_RDONLY);
108 if (ip_fd == -1)
109 {
110 fprintf(stderr, "%s: unable to open %s: %s\n", prog_name,
111 ip_device, strerror(errno));
112 exit(1);
113 }
114
115 if (!all_devices && ifname)
116 {
117 cp= strrchr(ip_device, '/');
118 if (cp)
119 ifname= cp+1;
120 }
121 else
122 {
123 ifname= NULL;
124 fill_iftab();
125 }
126
127 result= ioctl(ip_fd, NWIOGIPCONF, &ip_conf);
128 if (result == -1)
129 {
130 fprintf(stderr, "%s: unable to NWIOIPGCONF: %s\n",
131 prog_name, strerror(errno));
132 exit(1);
133 }
134
135 route.nwr_ent_no= 0;
136 result= ioctl(ip_fd, ioctl_cmd, &route);
137 if (result == -1)
138 {
139 fprintf(stderr, "%s: unable to NWIOGIPxROUTE: %s\n",
140 prog_name, strerror(errno));
141 exit(1);
142 }
143 print_header();
144 nr_routes= route.nwr_ent_count;
145 for (i= 0; i<nr_routes; i++)
146 {
147 route.nwr_ent_no= i;
148 result= ioctl(ip_fd, ioctl_cmd, &route);
149 if (result == -1)
150 {
151 fprintf(stderr, "%s: unable to NWIOGIPxROUTE: %s\n",
152 prog_name, strerror(errno));
153 exit(1);
154 }
155 if (all_devices || route.nwr_ifaddr == ip_conf.nwic_ipaddr)
156 print_route(&route);
157 }
158 exit(0);
159}
160
161int ent_width= 5;
162int if_width= 4;
163int dest_width= 18;
164int gateway_width= 15;
165int dist_width= 4;
166int pref_width= 5;
167int mtu_width= 4;
168
169static void print_header(void)
170{
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");
180}
181
182static char *cidr2a(ipaddr_t addr, ipaddr_t mask)
183{
184 ipaddr_t testmask= 0xFFFFFFFF;
185 int n;
186 static char result[sizeof("255.255.255.255/255.255.255.255")];
187
188 for (n= 32; n >= 0; n--)
189 {
190 if (mask == htonl(testmask))
191 break;
192 testmask= (testmask << 1) & 0xFFFFFFFF;
193 }
194
195 sprintf(result, "%s/%-2d", inet_ntoa(addr), n);
196 if (n == -1)
197 strcpy(strchr(result, '/')+1, inet_ntoa(mask));
198 return result;
199}
200
201static void print_route(nwio_route_t *route)
202{
203 if (!(route->nwr_flags & NWRF_INUSE))
204 return;
205
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");
219}
220
221static void fill_iftab(void)
222{
223 int i, j, r, fd;
224 nwio_ipconf_t ip_conf;
225 char dev_name[12]; /* /dev/ipXXXX */
226
227 for (i= 0; i<N_IF; i++)
228 {
229 iftab[i]= 0;
230
231 sprintf(dev_name, "/dev/ip%d", i);
232 fd= open(dev_name, O_RDWR);
233 if (fd == -1)
234 {
235 if (errno == EACCES || errno == ENOENT || errno == ENXIO)
236 continue;
237 fatal("unable to open '%s': %s",
238 dev_name, strerror(errno));
239 }
240 fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK);
241 r= ioctl(fd, NWIOGIPCONF, &ip_conf);
242 if (r == -1 && errno == EAGAIN)
243 {
244 /* interface is down */
245 close(fd);
246 continue;
247 }
248 if (r == -1)
249 {
250 fatal("NWIOGIPCONF failed on %s: %s",
251 dev_name, strerror(errno));
252 }
253
254 iftab[i]= ip_conf.nwic_ipaddr;
255 close(fd);
256
257 for (j= 0; j<i; j++)
258 {
259 if (iftab[j] == iftab[i])
260 {
261 fatal("duplicate address in ip%d and ip%d: %s",
262 i, j, inet_ntoa(iftab[i]));
263 }
264 }
265
266 }
267}
268
269static char *get_ifname(ipaddr_t addr)
270{
271 static char name[7]; /* ipXXXX */
272
273 int i;
274
275 for (i= 0; i<N_IF; i++)
276 {
277 if (iftab[i] != addr)
278 continue;
279 sprintf(name, "ip%d", i);
280 return name;
281 }
282
283 return inet_ntoa(addr);
284}
285
286static void fatal(char *fmt, ...)
287{
288 va_list ap;
289
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);
296}
297
298static void usage(void)
299{
300 fprintf(stderr, "Usage: %s [-i|-o] [ -a ] [ -I <ip-device> ]\n",
301 prog_name);
302 exit(1);
303}
304
305/*
306 * $PchId: pr_routes.c,v 1.8 2002/04/11 10:58:58 philip Exp $
307 */
Note: See TracBrowser for help on using the repository browser.