new subnets, interface addressing
[unix-history] / usr / src / usr.bin / netstat / route.c
CommitLineData
3537c4ea 1#ifndef lint
cab3a575 2static char sccsid[] = "@(#)route.c 4.10 85/06/03";
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;
cab3a575 17extern char *routename(), *netname();
3537c4ea
SL
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 81 printf("%-15.15s ",
cab3a575
MK
82 (sin->sin_addr.s_addr == 0) ? "default" :
83 (rt->rt_flags & RTF_HOST) ?
84 routename(sin->sin_addr) : netname(sin->sin_addr, 0));
3537c4ea
SL
85 sin = (struct sockaddr_in *)&rt->rt_gateway;
86 printf("%-15.15s ", routename(sin->sin_addr));
87 for (flags = name, p = bits; p->b_mask; p++)
88 if (p->b_mask & rt->rt_flags)
89 *flags++ = p->b_val;
90 *flags = '\0';
91 printf("%-8.8s %-6d %-10d ", name,
92 rt->rt_refcnt, rt->rt_use);
93 if (rt->rt_ifp == 0) {
94 putchar('\n');
95 m = mb.m_next;
96 continue;
97 }
98 klseek(kmem, rt->rt_ifp, 0);
99 read(kmem, &ifnet, sizeof (ifnet));
100 klseek(kmem, (int)ifnet.if_name, 0);
101 read(kmem, name, 16);
102 printf("%s%d\n", name, ifnet.if_unit);
103 m = mb.m_next;
104 }
105 }
106 if (doinghost) {
107 klseek(kmem, netaddr, 0);
f508555e 108 read(kmem, routehash, hashsize*sizeof (struct mbuf *));
3537c4ea
SL
109 doinghost = 0;
110 goto again;
111 }
f508555e 112 free(routehash);
3537c4ea
SL
113}
114
115char *
116routename(in)
117 struct in_addr in;
118{
119 char *cp = 0;
120 static char line[50];
40f48772 121 struct hostent *hp;
3537c4ea 122
3537c4ea 123 if (!nflag) {
cab3a575
MK
124 hp = gethostbyaddr(&in, sizeof (struct in_addr),
125 AF_INET);
126 if (hp)
127 cp = hp->h_name;
3537c4ea
SL
128 }
129 if (cp)
130 strcpy(line, cp);
131 else {
cab3a575
MK
132#define C(x) ((x) & 0xff)
133 in.s_addr = ntohl(in.s_addr);
134 sprintf(line, "%u.%u.%u.%u", C(in.s_addr >> 24),
135 C(in.s_addr >> 16), C(in.s_addr >> 8), C(in.s_addr));
136 }
137 return (line);
138}
139
140/*
141 * Return the name of the network whose address is given.
142 * The address is assumed to be that of a net or subnet, not a host.
143 */
144char *
145netname(in, mask)
146 struct in_addr in;
147 u_long mask;
148{
149 char *cp = 0;
150 static char line[50];
151 struct netent *np = 0;
152 u_long net;
153 register i;
154
155 in.s_addr = ntohl(in.s_addr);
156 if (!nflag && in.s_addr) {
157 if (mask) {
158 net = in.s_addr & mask;
159 while ((mask & 1) == 0)
160 mask >>= 1, net >>= 1;
161 np = getnetbyaddr(net, AF_INET);
162 }
163 if (np == 0) {
164 /*
165 * Try for subnet addresses.
166 */
167 for (i = 0; ((0xf<<i) & in.s_addr) == 0; i += 4)
168 ;
169 for ( ; i; i -= 4)
170 if (np = getnetbyaddr((unsigned)in.s_addr >> i,
171 AF_INET))
172 break;
173 }
174 if (np)
175 cp = np->n_name;
3537c4ea 176 }
cab3a575
MK
177 if (cp)
178 strcpy(line, cp);
179 else if ((in.s_addr & 0xffffff) == 0)
180 sprintf(line, "%u", C(in.s_addr >> 24));
181 else if ((in.s_addr & 0xffff) == 0)
182 sprintf(line, "%u.%u", C(in.s_addr >> 24) , C(in.s_addr >> 16));
183 else if ((in.s_addr & 0xff) == 0)
184 sprintf(line, "%u.%u.%u", C(in.s_addr >> 24),
185 C(in.s_addr >> 16), C(in.s_addr >> 8));
186 else
187 sprintf(line, "%u.%u.%u.%u", C(in.s_addr >> 24),
188 C(in.s_addr >> 16), C(in.s_addr >> 8), C(in.s_addr));
3537c4ea
SL
189 return (line);
190}
bbd2d21e
SL
191/*
192 * Print routing statistics
193 */
194rt_stats(off)
195 off_t off;
196{
197 struct rtstat rtstat;
198
199 if (off == 0) {
200 printf("rtstat: symbol not in namelist\n");
201 return;
202 }
203 klseek(kmem, off, 0);
204 read(kmem, (char *)&rtstat, sizeof (rtstat));
205 printf("routing:\n");
206 printf("\t%d bad routing redirect%s\n",
207 rtstat.rts_badredirect, plural(rtstat.rts_badredirect));
208 printf("\t%d dynamically created route%s\n",
209 rtstat.rts_dynamic, plural(rtstat.rts_dynamic));
210 printf("\t%d new gateway%s due to redirects\n",
211 rtstat.rts_newgateway, plural(rtstat.rts_newgateway));
212 printf("\t%d destination%s found unreachable\n",
213 rtstat.rts_unreach, plural(rtstat.rts_unreach));
214 printf("\t%d use%s of a wildcard route\n",
215 rtstat.rts_wildcard, plural(rtstat.rts_wildcard));
216}