get rthashsize from kernel
[unix-history] / usr / src / usr.bin / netstat / route.c
CommitLineData
3537c4ea 1#ifndef lint
f508555e 2static char sccsid[] = "@(#)route.c 4.9 84/10/31";
3537c4ea
SL
3#endif
4
5#include <sys/types.h>
6#include <sys/socket.h>
7#include <sys/mbuf.h>
44906619 8
3537c4ea 9#include <net/if.h>
3537c4ea 10#include <net/route.h>
44906619
SL
11#include <netinet/in.h>
12
3537c4ea
SL
13#include <netdb.h>
14
15extern int kmem;
16extern int nflag;
17extern char *routename();
18
19/*
20 * Definitions for showing gateway flags.
21 */
22struct bits {
23 short b_mask;
24 char b_val;
25} bits[] = {
26 { RTF_UP, 'U' },
27 { RTF_GATEWAY, 'G' },
28 { RTF_HOST, 'H' },
29 { 0 }
30};
31
32/*
33 * Print routing tables.
34 */
f508555e
MK
35routepr(hostaddr, netaddr, hashsizeaddr)
36 off_t hostaddr, netaddr, hashsizeaddr;
3537c4ea
SL
37{
38 struct mbuf mb;
39 register struct rtentry *rt;
40 register struct mbuf *m;
41 register struct bits *p;
3537c4ea 42 char name[16], *flags;
f508555e 43 struct mbuf **routehash;
3537c4ea 44 struct ifnet ifnet;
f508555e
MK
45 int hashsize;
46 int i, doinghost = 1;
3537c4ea
SL
47
48 if (hostaddr == 0) {
49 printf("rthost: symbol not in namelist\n");
50 return;
51 }
52 if (netaddr == 0) {
53 printf("rtnet: symbol not in namelist\n");
54 return;
55 }
f508555e
MK
56 if (hashsizeaddr == 0) {
57 printf("rthashsize: symbol not in namelist\n");
58 return;
59 }
60 klseek(kmem, hashsizeaddr, 0);
61 read(kmem, &hashsize, sizeof (hashsize));
62 routehash = (struct mbuf **)malloc( hashsize*sizeof (struct mbuf *) );
3537c4ea 63 klseek(kmem, hostaddr, 0);
f508555e 64 read(kmem, routehash, hashsize*sizeof (struct mbuf *));
3537c4ea
SL
65 printf("Routing tables\n");
66 printf("%-15.15s %-15.15s %-8.8s %-6.6s %-10.10s %s\n",
67 "Destination", "Gateway",
68 "Flags", "Refcnt", "Use", "Interface");
69again:
f508555e 70 for (i = 0; i < hashsize; i++) {
3537c4ea
SL
71 if (routehash[i] == 0)
72 continue;
73 m = routehash[i];
74 while (m) {
75 struct sockaddr_in *sin;
76
77 klseek(kmem, m, 0);
78 read(kmem, &mb, sizeof (mb));
79 rt = mtod(&mb, struct rtentry *);
80 sin = (struct sockaddr_in *)&rt->rt_dst;
bbd2d21e
SL
81 printf("%-15.15s ",
82 sin->sin_addr.s_addr ?
83 routename(sin->sin_addr) : "default");
3537c4ea
SL
84 sin = (struct sockaddr_in *)&rt->rt_gateway;
85 printf("%-15.15s ", routename(sin->sin_addr));
86 for (flags = name, p = bits; p->b_mask; p++)
87 if (p->b_mask & rt->rt_flags)
88 *flags++ = p->b_val;
89 *flags = '\0';
90 printf("%-8.8s %-6d %-10d ", name,
91 rt->rt_refcnt, rt->rt_use);
92 if (rt->rt_ifp == 0) {
93 putchar('\n');
94 m = mb.m_next;
95 continue;
96 }
97 klseek(kmem, rt->rt_ifp, 0);
98 read(kmem, &ifnet, sizeof (ifnet));
99 klseek(kmem, (int)ifnet.if_name, 0);
100 read(kmem, name, 16);
101 printf("%s%d\n", name, ifnet.if_unit);
102 m = mb.m_next;
103 }
104 }
105 if (doinghost) {
106 klseek(kmem, netaddr, 0);
f508555e 107 read(kmem, routehash, hashsize*sizeof (struct mbuf *));
3537c4ea
SL
108 doinghost = 0;
109 goto again;
110 }
f508555e 111 free(routehash);
3537c4ea
SL
112}
113
114char *
115routename(in)
116 struct in_addr in;
117{
118 char *cp = 0;
119 static char line[50];
40f48772
MK
120 struct hostent *hp;
121 struct netent *np;
122 int lna, net, subnet;
3537c4ea 123
444a708d 124 net = inet_netof(in);
40f48772 125 subnet = inet_subnetof(in);
444a708d 126 lna = inet_lnaof(in);
3537c4ea
SL
127 if (!nflag) {
128 if (lna == INADDR_ANY) {
40f48772 129 np = getnetbyaddr(net, AF_INET);
3537c4ea
SL
130 if (np)
131 cp = np->n_name;
40f48772
MK
132 } else if ((subnet != net) && ((lna & 0xff) == 0) &&
133 (np = getnetbyaddr(subnet, AF_INET))) {
134 struct in_addr subnaddr, inet_makeaddr();
135 subnaddr = inet_makeaddr(subnet, INADDR_ANY);
136 if (bcmp(&in, &subnaddr, sizeof(in)) == 0)
137 cp = np->n_name;
f6d7bbb7
MK
138 else
139 goto host;
3537c4ea 140 } else {
f6d7bbb7 141host:
3394f0b5
SL
142 hp = gethostbyaddr(&in, sizeof (struct in_addr),
143 AF_INET);
3537c4ea
SL
144 if (hp)
145 cp = hp->h_name;
146 }
147 }
148 if (cp)
149 strcpy(line, cp);
150 else {
151 u_char *ucp = (u_char *)&in;
152 if (lna == INADDR_ANY)
153 sprintf(line, "%u.%u.%u", ucp[0], ucp[1], ucp[2]);
154 else
155 sprintf(line, "%u.%u.%u.%u", ucp[0], ucp[1],
156 ucp[2], ucp[3]);
157 }
158 return (line);
159}
bbd2d21e
SL
160/*
161 * Print routing statistics
162 */
163rt_stats(off)
164 off_t off;
165{
166 struct rtstat rtstat;
167
168 if (off == 0) {
169 printf("rtstat: symbol not in namelist\n");
170 return;
171 }
172 klseek(kmem, off, 0);
173 read(kmem, (char *)&rtstat, sizeof (rtstat));
174 printf("routing:\n");
175 printf("\t%d bad routing redirect%s\n",
176 rtstat.rts_badredirect, plural(rtstat.rts_badredirect));
177 printf("\t%d dynamically created route%s\n",
178 rtstat.rts_dynamic, plural(rtstat.rts_dynamic));
179 printf("\t%d new gateway%s due to redirects\n",
180 rtstat.rts_newgateway, plural(rtstat.rts_newgateway));
181 printf("\t%d destination%s found unreachable\n",
182 rtstat.rts_unreach, plural(rtstat.rts_unreach));
183 printf("\t%d use%s of a wildcard route\n",
184 rtstat.rts_wildcard, plural(rtstat.rts_wildcard));
185}
40f48772
MK
186
187/*
188 * Return the possible subnetwork number from an internet address.
189 * If the address is of the form of a subnet address (most significant
190 * bit of the host part is set), believe the subnet exists.
191 * Otherwise, return the network number.
192 * SHOULD FIND OUT WHETHER THIS IS A LOCAL NETWORK BEFORE LOOKING
193 * INSIDE OF THE HOST PART. We can only believe this if we have other
194 * information (e.g., we can find a name for this number).
195 */
196inet_subnetof(in)
197 struct in_addr in;
198{
199 register u_long i = ntohl(in.s_addr);
200
201 if (IN_CLASSA(i)) {
202 if (IN_SUBNETA(i))
203 return ((i & IN_CLASSA_SUBNET) >> IN_CLASSA_SUBNSHIFT);
204 else
205 return ((i & IN_CLASSA_NET) >> IN_CLASSA_NSHIFT);
206 } else if (IN_CLASSB(i)) {
207 if (IN_SUBNETB(i))
208 return ((i & IN_CLASSB_SUBNET) >> IN_CLASSB_SUBNSHIFT);
209 else
210 return ((i & IN_CLASSB_NET) >> IN_CLASSB_NSHIFT);
211 } else
212 return ((i & IN_CLASSC_NET) >> IN_CLASSC_NSHIFT);
213}