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