|
|
1.1 root 1: /*
2: * Copyright (c) 1983, 1988 Regents of the University of California.
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms are permitted
6: * provided that the above copyright notice and this paragraph are
7: * duplicated in all such forms and that any documentation,
8: * advertising materials, and other materials related to such
9: * distribution and use acknowledge that the software was developed
10: * by the University of California, Berkeley. The name of the
11: * University may not be used to endorse or promote products derived
12: * from this software without specific prior written permission.
13: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15: * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16: */
17:
18: #ifndef lint
19: static char sccsid[] = "@(#)route.c 5.14 (Berkeley) 6/29/88";
20: #endif /* not lint */
21:
22: #include <stdio.h>
23: #include <strings.h>
24:
25: #include <sys/param.h>
26: #include <sys/socket.h>
27: #include <sys/mbuf.h>
28:
29: #include <net/if.h>
30: #include <net/route.h>
31: #include <netinet/in.h>
32:
33: #include <netns/ns.h>
34:
35: #include <netdb.h>
36:
37: extern int kmem;
38: extern int nflag;
39: extern char *routename(), *netname(), *ns_print(), *plural();
40: extern char *malloc();
41:
42: /*
43: * Definitions for showing gateway flags.
44: */
45: struct bits {
46: short b_mask;
47: char b_val;
48: } bits[] = {
49: { RTF_UP, 'U' },
50: { RTF_GATEWAY, 'G' },
51: { RTF_HOST, 'H' },
52: { RTF_DYNAMIC, 'D' },
53: { RTF_MODIFIED, 'M' },
54: { 0 }
55: };
56:
57: /*
58: * Print routing tables.
59: */
60: routepr(hostaddr, netaddr, hashsizeaddr)
61: off_t hostaddr, netaddr, hashsizeaddr;
62: {
63: struct mbuf mb;
64: register struct rtentry *rt;
65: register struct mbuf *m;
66: register struct bits *p;
67: char name[16], *flags;
68: struct mbuf **routehash;
69: struct ifnet ifnet;
70: int hashsize;
71: int i, doinghost = 1;
72:
73: if (hostaddr == 0) {
74: printf("rthost: symbol not in namelist\n");
75: return;
76: }
77: if (netaddr == 0) {
78: printf("rtnet: symbol not in namelist\n");
79: return;
80: }
81: if (hashsizeaddr == 0) {
82: printf("rthashsize: symbol not in namelist\n");
83: return;
84: }
85: klseek(kmem, hashsizeaddr, 0);
86: read(kmem, (char *)&hashsize, sizeof (hashsize));
87: routehash = (struct mbuf **)malloc( hashsize*sizeof (struct mbuf *) );
88: klseek(kmem, hostaddr, 0);
89: read(kmem, (char *)routehash, hashsize*sizeof (struct mbuf *));
90: printf("Routing tables\n");
91: printf("%-16.16s %-18.18s %-6.6s %6.6s%8.8s %s\n",
92: "Destination", "Gateway",
93: "Flags", "Refs", "Use", "Interface");
94: again:
95: for (i = 0; i < hashsize; i++) {
96: if (routehash[i] == 0)
97: continue;
98: m = routehash[i];
99: while (m) {
100: struct sockaddr_in *sin;
101:
102: klseek(kmem, (off_t)m, 0);
103: read(kmem, (char *)&mb, sizeof (mb));
104: rt = mtod(&mb, struct rtentry *);
105: if ((unsigned)rt < (unsigned)&mb ||
106: (unsigned)rt >= (unsigned)(&mb + 1)) {
107: printf("???\n");
108: return;
109: }
110:
111: switch(rt->rt_dst.sa_family) {
112: case AF_INET:
113: sin = (struct sockaddr_in *)&rt->rt_dst;
114: printf("%-16.16s ",
115: (sin->sin_addr.s_addr == 0) ? "default" :
116: (rt->rt_flags & RTF_HOST) ?
117: routename(sin->sin_addr) :
118: netname(sin->sin_addr, 0L));
119: sin = (struct sockaddr_in *)&rt->rt_gateway;
120: printf("%-18.18s ", routename(sin->sin_addr));
121: break;
122: case AF_NS:
123: printf("%-16s ",
124: ns_print((struct sockaddr_ns *)&rt->rt_dst));
125: printf("%-18s ",
126: ns_print((struct sockaddr_ns *)&rt->rt_gateway));
127: break;
128: default:
129: {
130: u_short *s = (u_short *)rt->rt_dst.sa_data;
131: printf("(%d)%x %x %x %x %x %x %x ",
132: rt->rt_dst.sa_family,
133: s[0], s[1], s[2], s[3], s[4], s[5], s[6]);
134: s = (u_short *)rt->rt_gateway.sa_data;
135: printf("(%d)%x %x %x %x %x %x %x ",
136: rt->rt_gateway.sa_family,
137: s[0], s[1], s[2], s[3], s[4], s[5], s[6]);
138: }
139: }
140: for (flags = name, p = bits; p->b_mask; p++)
141: if (p->b_mask & rt->rt_flags)
142: *flags++ = p->b_val;
143: *flags = '\0';
144: printf("%-6.6s %6d %8d ", name,
145: rt->rt_refcnt, rt->rt_use);
146: if (rt->rt_ifp == 0) {
147: putchar('\n');
148: m = mb.m_next;
149: continue;
150: }
151: klseek(kmem, (off_t)rt->rt_ifp, 0);
152: read(kmem, (char *)&ifnet, sizeof (ifnet));
153: klseek(kmem, (off_t)ifnet.if_name, 0);
154: read(kmem, name, 16);
155: printf(" %.15s%d\n", name, ifnet.if_unit);
156: m = mb.m_next;
157: }
158: }
159: if (doinghost) {
160: klseek(kmem, netaddr, 0);
161: read(kmem, (char *)routehash, hashsize*sizeof (struct mbuf *));
162: doinghost = 0;
163: goto again;
164: }
165: free((char *)routehash);
166: }
167:
168: char *
169: routename(in)
170: struct in_addr in;
171: {
172: register char *cp;
173: static char line[MAXHOSTNAMELEN + 1];
174: struct hostent *hp;
175: static char domain[MAXHOSTNAMELEN + 1];
176: static int first = 1;
177: char *index();
178:
179: if (first) {
180: first = 0;
181: if (gethostname(domain, MAXHOSTNAMELEN) == 0 &&
182: (cp = index(domain, '.')))
183: (void) strcpy(domain, cp + 1);
184: else
185: domain[0] = 0;
186: }
187: cp = 0;
188: if (!nflag) {
189: hp = gethostbyaddr((char *)&in, sizeof (struct in_addr),
190: AF_INET);
191: if (hp) {
192: if ((cp = index(hp->h_name, '.')) &&
193: !strcmp(cp + 1, domain))
194: *cp = 0;
195: cp = hp->h_name;
196: }
197: }
198: if (cp)
199: strncpy(line, cp, sizeof(line) - 1);
200: else {
201: #define C(x) ((x) & 0xff)
202: in.s_addr = ntohl(in.s_addr);
203: sprintf(line, "%u.%u.%u.%u", C(in.s_addr >> 24),
204: C(in.s_addr >> 16), C(in.s_addr >> 8), C(in.s_addr));
205: }
206: return (line);
207: }
208:
209: /*
210: * Return the name of the network whose address is given.
211: * The address is assumed to be that of a net or subnet, not a host.
212: */
213: char *
214: netname(in, mask)
215: struct in_addr in;
216: u_long mask;
217: {
218: char *cp = 0;
219: static char line[MAXHOSTNAMELEN + 1];
220: struct netent *np = 0;
221: u_long net;
222: register i;
223: int subnetshift;
224:
225: i = ntohl(in.s_addr);
226: if (!nflag && i) {
227: if (mask == 0) {
228: if (IN_CLASSA(i)) {
229: mask = IN_CLASSA_NET;
230: subnetshift = 8;
231: } else if (IN_CLASSB(i)) {
232: mask = IN_CLASSB_NET;
233: subnetshift = 8;
234: } else {
235: mask = IN_CLASSC_NET;
236: subnetshift = 4;
237: }
238: /*
239: * If there are more bits than the standard mask
240: * would suggest, subnets must be in use.
241: * Guess at the subnet mask, assuming reasonable
242: * width subnet fields.
243: */
244: while (i &~ mask)
245: mask = (long)mask >> subnetshift;
246: }
247: net = i & mask;
248: while ((mask & 1) == 0)
249: mask >>= 1, net >>= 1;
250: np = getnetbyaddr(net, AF_INET);
251: if (np)
252: cp = np->n_name;
253: }
254: if (cp)
255: strncpy(line, cp, sizeof(line) - 1);
256: else if ((i & 0xffffff) == 0)
257: sprintf(line, "%u", C(i >> 24));
258: else if ((i & 0xffff) == 0)
259: sprintf(line, "%u.%u", C(i >> 24) , C(i >> 16));
260: else if ((i & 0xff) == 0)
261: sprintf(line, "%u.%u.%u", C(i >> 24), C(i >> 16), C(i >> 8));
262: else
263: sprintf(line, "%u.%u.%u.%u", C(i >> 24),
264: C(i >> 16), C(i >> 8), C(i));
265: return (line);
266: }
267:
268: /*
269: * Print routing statistics
270: */
271: rt_stats(off)
272: off_t off;
273: {
274: struct rtstat rtstat;
275:
276: if (off == 0) {
277: printf("rtstat: symbol not in namelist\n");
278: return;
279: }
280: klseek(kmem, off, 0);
281: read(kmem, (char *)&rtstat, sizeof (rtstat));
282: printf("routing:\n");
283: printf("\t%u bad routing redirect%s\n",
284: rtstat.rts_badredirect, plural(rtstat.rts_badredirect));
285: printf("\t%u dynamically created route%s\n",
286: rtstat.rts_dynamic, plural(rtstat.rts_dynamic));
287: printf("\t%u new gateway%s due to redirects\n",
288: rtstat.rts_newgateway, plural(rtstat.rts_newgateway));
289: printf("\t%u destination%s found unreachable\n",
290: rtstat.rts_unreach, plural(rtstat.rts_unreach));
291: printf("\t%u use%s of a wildcard route\n",
292: rtstat.rts_wildcard, plural(rtstat.rts_wildcard));
293: }
294: short ns_nullh[] = {0,0,0};
295: short ns_bh[] = {-1,-1,-1};
296:
297: char *
298: ns_print(sns)
299: struct sockaddr_ns *sns;
300: {
301: struct ns_addr work;
302: union { union ns_net net_e; u_long long_e; } net;
303: u_short port;
304: static char mybuf[50], cport[10], chost[25];
305: char *host = "";
306: register char *p; register u_char *q;
307:
308: work = sns->sns_addr;
309: port = ntohs(work.x_port);
310: work.x_port = 0;
311: net.net_e = work.x_net;
312: if (ns_nullhost(work) && net.long_e == 0) {
313: if (port ) {
314: sprintf(mybuf, "*.%xH", port);
315: upHex(mybuf);
316: } else
317: sprintf(mybuf, "*.*");
318: return (mybuf);
319: }
320:
321: if (bcmp(ns_bh, work.x_host.c_host, 6) == 0) {
322: host = "any";
323: } else if (bcmp(ns_nullh, work.x_host.c_host, 6) == 0) {
324: host = "*";
325: } else {
326: q = work.x_host.c_host;
327: sprintf(chost, "%02x%02x%02x%02x%02x%02xH",
328: q[0], q[1], q[2], q[3], q[4], q[5]);
329: for (p = chost; *p == '0' && p < chost + 12; p++);
330: host = p;
331: }
332: if (port)
333: sprintf(cport, ".%xH", htons(port));
334: else
335: *cport = 0;
336:
337: sprintf(mybuf,"%xH.%s%s", ntohl(net.long_e), host, cport);
338: upHex(mybuf);
339: return(mybuf);
340: }
341:
342: char *
343: ns_phost(sns)
344: struct sockaddr_ns *sns;
345: {
346: struct sockaddr_ns work;
347: static union ns_net ns_zeronet;
348: char *p;
349:
350: work = *sns;
351: work.sns_addr.x_port = 0;
352: work.sns_addr.x_net = ns_zeronet;
353:
354: p = ns_print(&work);
355: if (strncmp("0H.", p, 3) == 0) p += 3;
356: return(p);
357: }
358: upHex(p0)
359: char *p0;
360: {
361: register char *p = p0;
362: for (; *p; p++) switch (*p) {
363:
364: case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
365: *p += ('A' - 'a');
366: }
367: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.