print xns interfaces and route reasonably
[unix-history] / usr / src / usr.bin / netstat / route.c
CommitLineData
5ff67f98
DF
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
3537c4ea 7#ifndef lint
f1fbb01b
KS
8static char sccsid[] = "@(#)route.c 5.2 85/06/15";
9#endif
3537c4ea
SL
10
11#include <sys/types.h>
12#include <sys/socket.h>
13#include <sys/mbuf.h>
44906619 14
3537c4ea 15#include <net/if.h>
3537c4ea 16#include <net/route.h>
44906619
SL
17#include <netinet/in.h>
18
f1fbb01b
KS
19#include <netns/ns.h>
20
3537c4ea
SL
21#include <netdb.h>
22
23extern int kmem;
24extern int nflag;
f1fbb01b 25extern char *routename(), *netname(), *ns_print();
3537c4ea
SL
26
27/*
28 * Definitions for showing gateway flags.
29 */
30struct bits {
31 short b_mask;
32 char b_val;
33} bits[] = {
34 { RTF_UP, 'U' },
35 { RTF_GATEWAY, 'G' },
36 { RTF_HOST, 'H' },
37 { 0 }
38};
39
40/*
41 * Print routing tables.
42 */
f508555e
MK
43routepr(hostaddr, netaddr, hashsizeaddr)
44 off_t hostaddr, netaddr, hashsizeaddr;
3537c4ea
SL
45{
46 struct mbuf mb;
47 register struct rtentry *rt;
48 register struct mbuf *m;
49 register struct bits *p;
3537c4ea 50 char name[16], *flags;
f508555e 51 struct mbuf **routehash;
3537c4ea 52 struct ifnet ifnet;
f508555e
MK
53 int hashsize;
54 int i, doinghost = 1;
3537c4ea
SL
55
56 if (hostaddr == 0) {
57 printf("rthost: symbol not in namelist\n");
58 return;
59 }
60 if (netaddr == 0) {
61 printf("rtnet: symbol not in namelist\n");
62 return;
63 }
f508555e
MK
64 if (hashsizeaddr == 0) {
65 printf("rthashsize: symbol not in namelist\n");
66 return;
67 }
68 klseek(kmem, hashsizeaddr, 0);
69 read(kmem, &hashsize, sizeof (hashsize));
70 routehash = (struct mbuf **)malloc( hashsize*sizeof (struct mbuf *) );
3537c4ea 71 klseek(kmem, hostaddr, 0);
f508555e 72 read(kmem, routehash, hashsize*sizeof (struct mbuf *));
3537c4ea
SL
73 printf("Routing tables\n");
74 printf("%-15.15s %-15.15s %-8.8s %-6.6s %-10.10s %s\n",
75 "Destination", "Gateway",
76 "Flags", "Refcnt", "Use", "Interface");
77again:
f508555e 78 for (i = 0; i < hashsize; i++) {
3537c4ea
SL
79 if (routehash[i] == 0)
80 continue;
81 m = routehash[i];
82 while (m) {
83 struct sockaddr_in *sin;
f1fbb01b
KS
84 struct sockaddr_ns *sns;
85 long *l = (long *)&rt->rt_dst;
3537c4ea
SL
86
87 klseek(kmem, m, 0);
88 read(kmem, &mb, sizeof (mb));
89 rt = mtod(&mb, struct rtentry *);
f1fbb01b
KS
90 switch(rt->rt_dst.sa_family) {
91 case AF_INET:
3537c4ea 92 sin = (struct sockaddr_in *)&rt->rt_dst;
bbd2d21e 93 printf("%-15.15s ",
cab3a575
MK
94 (sin->sin_addr.s_addr == 0) ? "default" :
95 (rt->rt_flags & RTF_HOST) ?
96 routename(sin->sin_addr) : netname(sin->sin_addr, 0));
3537c4ea
SL
97 sin = (struct sockaddr_in *)&rt->rt_gateway;
98 printf("%-15.15s ", routename(sin->sin_addr));
f1fbb01b
KS
99 break;
100 case AF_NS:
101 printf("%-15s ",
102 ns_print((struct sockaddr_ns *)&rt->rt_dst));
103 printf("%-15s ",
104 ns_print((struct sockaddr_ns *)&rt->rt_gateway));
105 break;
106 default:
107 printf("%8.8x %8.8x %8.8x %8.8x",*l, l[1], l[2], l[3]);
108 l = (long *)&rt->rt_gateway;
109 printf("%8.8x %8.8x %8.8x %8.8x",*l, l[1], l[2], l[3]);
110 }
3537c4ea
SL
111 for (flags = name, p = bits; p->b_mask; p++)
112 if (p->b_mask & rt->rt_flags)
113 *flags++ = p->b_val;
114 *flags = '\0';
115 printf("%-8.8s %-6d %-10d ", name,
116 rt->rt_refcnt, rt->rt_use);
117 if (rt->rt_ifp == 0) {
118 putchar('\n');
119 m = mb.m_next;
120 continue;
121 }
122 klseek(kmem, rt->rt_ifp, 0);
123 read(kmem, &ifnet, sizeof (ifnet));
124 klseek(kmem, (int)ifnet.if_name, 0);
125 read(kmem, name, 16);
126 printf("%s%d\n", name, ifnet.if_unit);
127 m = mb.m_next;
128 }
129 }
130 if (doinghost) {
131 klseek(kmem, netaddr, 0);
f508555e 132 read(kmem, routehash, hashsize*sizeof (struct mbuf *));
3537c4ea
SL
133 doinghost = 0;
134 goto again;
135 }
f508555e 136 free(routehash);
3537c4ea
SL
137}
138
139char *
140routename(in)
141 struct in_addr in;
142{
143 char *cp = 0;
144 static char line[50];
40f48772 145 struct hostent *hp;
3537c4ea 146
3537c4ea 147 if (!nflag) {
cab3a575
MK
148 hp = gethostbyaddr(&in, sizeof (struct in_addr),
149 AF_INET);
150 if (hp)
151 cp = hp->h_name;
3537c4ea
SL
152 }
153 if (cp)
154 strcpy(line, cp);
155 else {
cab3a575
MK
156#define C(x) ((x) & 0xff)
157 in.s_addr = ntohl(in.s_addr);
158 sprintf(line, "%u.%u.%u.%u", C(in.s_addr >> 24),
159 C(in.s_addr >> 16), C(in.s_addr >> 8), C(in.s_addr));
160 }
161 return (line);
162}
163
164/*
165 * Return the name of the network whose address is given.
166 * The address is assumed to be that of a net or subnet, not a host.
167 */
168char *
169netname(in, mask)
170 struct in_addr in;
171 u_long mask;
172{
173 char *cp = 0;
174 static char line[50];
175 struct netent *np = 0;
176 u_long net;
177 register i;
178
179 in.s_addr = ntohl(in.s_addr);
180 if (!nflag && in.s_addr) {
181 if (mask) {
182 net = in.s_addr & mask;
183 while ((mask & 1) == 0)
184 mask >>= 1, net >>= 1;
185 np = getnetbyaddr(net, AF_INET);
186 }
187 if (np == 0) {
188 /*
189 * Try for subnet addresses.
190 */
191 for (i = 0; ((0xf<<i) & in.s_addr) == 0; i += 4)
192 ;
193 for ( ; i; i -= 4)
194 if (np = getnetbyaddr((unsigned)in.s_addr >> i,
195 AF_INET))
196 break;
197 }
198 if (np)
199 cp = np->n_name;
3537c4ea 200 }
cab3a575
MK
201 if (cp)
202 strcpy(line, cp);
203 else if ((in.s_addr & 0xffffff) == 0)
204 sprintf(line, "%u", C(in.s_addr >> 24));
205 else if ((in.s_addr & 0xffff) == 0)
206 sprintf(line, "%u.%u", C(in.s_addr >> 24) , C(in.s_addr >> 16));
207 else if ((in.s_addr & 0xff) == 0)
208 sprintf(line, "%u.%u.%u", C(in.s_addr >> 24),
209 C(in.s_addr >> 16), C(in.s_addr >> 8));
210 else
211 sprintf(line, "%u.%u.%u.%u", C(in.s_addr >> 24),
212 C(in.s_addr >> 16), C(in.s_addr >> 8), C(in.s_addr));
3537c4ea
SL
213 return (line);
214}
bbd2d21e
SL
215/*
216 * Print routing statistics
217 */
218rt_stats(off)
219 off_t off;
220{
221 struct rtstat rtstat;
222
223 if (off == 0) {
224 printf("rtstat: symbol not in namelist\n");
225 return;
226 }
227 klseek(kmem, off, 0);
228 read(kmem, (char *)&rtstat, sizeof (rtstat));
229 printf("routing:\n");
230 printf("\t%d bad routing redirect%s\n",
231 rtstat.rts_badredirect, plural(rtstat.rts_badredirect));
232 printf("\t%d dynamically created route%s\n",
233 rtstat.rts_dynamic, plural(rtstat.rts_dynamic));
234 printf("\t%d new gateway%s due to redirects\n",
235 rtstat.rts_newgateway, plural(rtstat.rts_newgateway));
236 printf("\t%d destination%s found unreachable\n",
237 rtstat.rts_unreach, plural(rtstat.rts_unreach));
238 printf("\t%d use%s of a wildcard route\n",
239 rtstat.rts_wildcard, plural(rtstat.rts_wildcard));
240}
f1fbb01b
KS
241short ns_bh[] = {-1,-1,-1};
242
243char *
244ns_print(sns)
245struct sockaddr_ns *sns;
246{
247 register struct ns_addr *dna = &sns->sns_addr;
248 long net = ntohl(ns_netof(*dna));
249 static char mybuf[50];
250 register char *p = mybuf;
251 short port = dna->x_port;
252
253 sprintf(p,"%ld:", net);
254
255 while(*p)p++; /* find end of string */
256
257 if (strncmp(ns_bh,dna->x_host.c_host,6)==0)
258 sprintf(p,"any");
259 else
260 sprintf(p,"%x.%x.%x.%x.%x.%x",
261 dna->x_host.c_host[0], dna->x_host.c_host[1],
262 dna->x_host.c_host[2], dna->x_host.c_host[3],
263 dna->x_host.c_host[4], dna->x_host.c_host[5]);
264 if (port) {
265 while(*p)p++; /* find end of string */
266 printf(":%d",port);
267 }
268 return(mybuf);
269}
270char *
271ns_phost(sns)
272struct sockaddr_ns *sns;
273{
274 register struct ns_addr *dna = &sns->sns_addr;
275 long net = ntohl(ns_netof(*dna));
276 static char mybuf[50];
277 register char *p = mybuf;
278 if (strncmp(ns_bh,dna->x_host.c_host,6)==0)
279 sprintf(p,"any");
280 else
281 sprintf(p,"%x,%x,%x",
282 dna->x_host.s_host[0], dna->x_host.s_host[1],
283 dna->x_host.s_host[2]);
284 return(mybuf);
285}