mroute.c revision 1.7 1 /*
2 * Copyright (c) 1989 Stephen Deering
3 * Copyright (c) 1992, 1993
4 * The Regents of the University of California. All rights reserved.
5 *
6 * This code is derived from software contributed to Berkeley by
7 * Stephen Deering of Stanford University.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed by the University of
20 * California, Berkeley and its contributors.
21 * 4. Neither the name of the University nor the names of its contributors
22 * may be used to endorse or promote products derived from this software
23 * without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * SUCH DAMAGE.
36 *
37 * from: @(#)mroute.c 8.1 (Berkeley) 6/6/93
38 * $Id: mroute.c,v 1.7 1995/06/12 03:03:13 mycroft Exp $
39 */
40
41 /*
42 * Print DVMRP multicast routing structures and statistics.
43 *
44 * MROUTING 1.0
45 */
46
47 #include <sys/param.h>
48 #include <sys/socket.h>
49 #include <sys/socketvar.h>
50 #include <sys/protosw.h>
51
52 #include <net/if.h>
53 #include <net/route.h>
54 #include <netinet/in.h>
55 #include <netinet/igmp.h>
56 #define _KERNEL
57 #include <netinet/ip_mroute.h>
58 #undef _KERNEL
59
60 #include <stdio.h>
61 #include <stdlib.h>
62 #include "netstat.h"
63
64 char *
65 pktscale(n)
66 u_long n;
67 {
68 static char buf[8];
69 char t;
70
71 if (n < 1024)
72 t = ' ';
73 else if (n < 1024 * 1024) {
74 t = 'k';
75 n /= 1024;
76 } else {
77 t = 'm';
78 n /= 1048576;
79 }
80
81 sprintf(buf, "%u%c", n, t);
82 return (buf);
83 }
84
85 void
86 mroutepr(mrpaddr, mfchashtbladdr, mfchashaddr, vifaddr)
87 u_long mrpaddr, mfchashtbladdr, mfchashaddr, vifaddr;
88 {
89 u_int mrtproto;
90 LIST_HEAD(, mfc) *mfchashtbl;
91 u_long mfchash;
92 struct vif viftable[MAXVIFS];
93 struct mfc *mfcp, mfc;
94 register struct vif *v;
95 register vifi_t vifi;
96 struct in_addr *grp;
97 int i;
98 int banner_printed;
99 int saved_nflag;
100 int numvifs;
101 int nmfc; /* No. of cache entries */
102
103 if (mrpaddr == 0) {
104 printf("ip_mrtproto: symbol not in namelist\n");
105 return;
106 }
107
108 kread(mrpaddr, (char *)&mrtproto, sizeof(mrtproto));
109 switch (mrtproto) {
110 case 0:
111 printf("no multicast routing compiled into this system\n");
112 return;
113
114 case IGMP_DVMRP:
115 break;
116
117 default:
118 printf("multicast routing protocol %u, unknown\n", mrtproto);
119 return;
120 }
121
122 if (mfchashtbladdr == 0) {
123 printf("mfchashtbl: symbol not in namelist\n");
124 return;
125 }
126 if (mfchashaddr == 0) {
127 printf("mfchash: symbol not in namelist\n");
128 return;
129 }
130 if (vifaddr == 0) {
131 printf("viftable: symbol not in namelist\n");
132 return;
133 }
134
135 saved_nflag = nflag;
136 nflag = 1;
137
138 kread(vifaddr, (char *)&viftable, sizeof(viftable));
139 banner_printed = 0;
140 numvifs = 0;
141
142 for (vifi = 0, v = viftable; vifi < MAXVIFS; ++vifi, ++v) {
143 if (v->v_lcl_addr.s_addr == 0)
144 continue;
145 numvifs = vifi;
146
147 if (!banner_printed) {
148 printf("\nVirtual Interface Table\n %s%s",
149 "Vif Thresh Limit Local-Address ",
150 "Remote-Address Pkt_in Pkt_out\n");
151 banner_printed = 1;
152 }
153
154 printf(" %3u %3u %5u %-15.15s",
155 vifi, v->v_threshold, v->v_rate_limit,
156 routename(v->v_lcl_addr.s_addr));
157 printf(" %-15.15s %6u %7u\n", (v->v_flags & VIFF_TUNNEL) ?
158 routename(v->v_rmt_addr.s_addr) : "",
159 v->v_pkt_in, v->v_pkt_out);
160 }
161 if (!banner_printed)
162 printf("\nVirtual Interface Table is empty\n");
163
164 kread(mfchashtbladdr, (char *)&mfchashtbl, sizeof(mfchashtbl));
165 kread(mfchashaddr, (char *)&mfchash, sizeof(mfchash));
166 banner_printed = 0;
167 nmfc = 0;
168
169 for (i = 0; i <= mfchash; ++i) {
170 kread((u_long)&mfchashtbl[i], (char *)&mfcp, sizeof(mfcp));
171
172 for (; mfcp != 0; mfcp = mfc.mfc_hash.le_next) {
173 if (!banner_printed) {
174 printf("\nMulticast Forwarding Cache\n %s%s",
175 "Hash Origin Mcastgroup ",
176 "Traffic In-Vif Out-Vifs/Forw-ttl\n");
177 banner_printed = 1;
178 }
179
180 kread((u_long)mfcp, (char *)&mfc, sizeof(mfc));
181 printf(" %3u %-15.15s",
182 i, routename(mfc.mfc_origin.s_addr));
183 printf(" %-15.15s %7s %3u ",
184 routename(mfc.mfc_mcastgrp.s_addr),
185 pktscale(mfc.mfc_pkt_cnt), mfc.mfc_parent);
186 for (vifi = 0; vifi <= numvifs; ++vifi)
187 if (mfc.mfc_ttls[vifi])
188 printf(" %u/%u", vifi, mfc.mfc_ttls[vifi]);
189
190 printf("\n");
191 nmfc++;
192 }
193 }
194 if (!banner_printed)
195 printf("\nMulticast Forwarding Cache is empty\n");
196 else
197 printf("\nTotal no. of entries in cache: %d\n", nmfc);
198
199 printf("\n");
200 nflag = saved_nflag;
201 }
202
203
204 void
205 mrt_stats(mrpaddr, mstaddr)
206 u_long mrpaddr, mstaddr;
207 {
208 u_int mrtproto;
209 struct mrtstat mrtstat;
210
211 if (mrpaddr == 0) {
212 printf("ip_mrtproto: symbol not in namelist\n");
213 return;
214 }
215
216 kread(mrpaddr, (char *)&mrtproto, sizeof(mrtproto));
217 switch (mrtproto) {
218 case 0:
219 printf("no multicast routing compiled into this system\n");
220 return;
221
222 case IGMP_DVMRP:
223 break;
224
225 default:
226 printf("multicast routing protocol %u, unknown\n", mrtproto);
227 return;
228 }
229
230 if (mstaddr == 0) {
231 printf("mrtstat: symbol not in namelist\n");
232 return;
233 }
234
235 kread(mstaddr, (char *)&mrtstat, sizeof(mrtstat));
236 printf("multicast routing:\n");
237 printf(" %10u datagram%s with no route for origin\n",
238 mrtstat.mrts_no_route, plural(mrtstat.mrts_no_route));
239 printf(" %10u upcall%s made to mrouted\n",
240 mrtstat.mrts_upcalls, plural(mrtstat.mrts_upcalls));
241 printf(" %10u datagram%s with malformed tunnel options\n",
242 mrtstat.mrts_bad_tunnel, plural(mrtstat.mrts_bad_tunnel));
243 printf(" %10u datagram%s with no room for tunnel options\n",
244 mrtstat.mrts_cant_tunnel, plural(mrtstat.mrts_cant_tunnel));
245 printf(" %10u datagram%s arrived on wrong interface\n",
246 mrtstat.mrts_wrong_if, plural(mrtstat.mrts_wrong_if));
247 printf(" %10u datagram%s dropped due to upcall Q overflow\n",
248 mrtstat.mrts_upq_ovflw, plural(mrtstat.mrts_upq_ovflw));
249 printf(" %10u datagram%s dropped due to upcall socket overflow\n",
250 mrtstat.mrts_upq_sockfull, plural(mrtstat.mrts_upq_sockfull));
251 printf(" %10u datagram%s cleaned up by the cache\n",
252 mrtstat.mrts_cache_cleanups, plural(mrtstat.mrts_cache_cleanups));
253 printf(" %10u datagram%s dropped selectively by ratelimiter\n",
254 mrtstat.mrts_drop_sel, plural(mrtstat.mrts_drop_sel));
255 printf(" %10u datagram%s dropped - bucket Q overflow\n",
256 mrtstat.mrts_q_overflow, plural(mrtstat.mrts_q_overflow));
257 printf(" %10u datagram%s dropped - larger than bkt size\n",
258 mrtstat.mrts_pkt2large, plural(mrtstat.mrts_pkt2large));
259 }
260