Commit | Line | Data |
---|---|---|
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 |
8 | static 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 | ||
23 | extern int kmem; | |
24 | extern int nflag; | |
f1fbb01b | 25 | extern char *routename(), *netname(), *ns_print(); |
3537c4ea SL |
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 | { 0 } | |
38 | }; | |
39 | ||
40 | /* | |
41 | * Print routing tables. | |
42 | */ | |
f508555e MK |
43 | routepr(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"); | |
77 | again: | |
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 | ||
139 | char * | |
140 | routename(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 | */ | |
168 | char * | |
169 | netname(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 | */ | |
218 | rt_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 |
241 | short ns_bh[] = {-1,-1,-1}; |
242 | ||
243 | char * | |
244 | ns_print(sns) | |
245 | struct 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 | } | |
270 | char * | |
271 | ns_phost(sns) | |
272 | struct 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 | } |