154720Ssklower /*
254720Ssklower * Copyright (c) 1989 Stephen Deering
362145Sbostic * Copyright (c) 1992, 1993
462145Sbostic * The Regents of the University of California. All rights reserved.
554720Ssklower *
654720Ssklower * This code is derived from software contributed to Berkeley by
754720Ssklower * Stephen Deering of Stanford University.
854720Ssklower *
954720Ssklower * %sccs.include.redist.c%
1054720Ssklower *
11*69047Sbostic * @(#)mroute.c 8.2 (Berkeley) 04/28/95
1254720Ssklower */
1354720Ssklower
1454720Ssklower /*
1554720Ssklower * Print DVMRP multicast routing structures and statistics.
1654720Ssklower *
1754720Ssklower * MROUTING 1.0
1854720Ssklower */
1954720Ssklower
2054720Ssklower #include <sys/param.h>
2154720Ssklower #include <sys/socket.h>
2254720Ssklower #include <sys/socketvar.h>
2354720Ssklower #include <sys/protosw.h>
2454720Ssklower
2554720Ssklower #include <netinet/in.h>
2654720Ssklower #include <netinet/igmp.h>
2754720Ssklower #define KERNEL 1
2854720Ssklower #include <netinet/ip_mroute.h>
2954720Ssklower #undef KERNEL
3054720Ssklower
3154720Ssklower #include <stdio.h>
3254720Ssklower #include <stdlib.h>
3354720Ssklower #include "netstat.h"
3454720Ssklower
3554720Ssklower void
mroutepr(mrpaddr,mrtaddr,vifaddr)3654720Ssklower mroutepr(mrpaddr, mrtaddr, vifaddr)
3754761Ssklower u_long mrpaddr, mrtaddr, vifaddr;
3854720Ssklower {
3954720Ssklower u_int mrtproto;
4054720Ssklower struct mrt *mrttable[MRTHASHSIZ];
4154720Ssklower struct vif viftable[MAXVIFS];
4254720Ssklower register struct mrt *mrt;
4354720Ssklower struct mrt smrt;
4454720Ssklower register struct vif *v;
4554720Ssklower register vifi_t vifi;
4654720Ssklower register struct in_addr *grp;
4754720Ssklower register int i, n;
4854720Ssklower register int banner_printed;
4954720Ssklower register int saved_nflag;
5054720Ssklower
5154720Ssklower if (mrpaddr == 0) {
5254720Ssklower printf("ip_mrtproto: symbol not in namelist\n");
5354720Ssklower return;
5454720Ssklower }
5554720Ssklower
5654761Ssklower kread(mrpaddr, (char *)&mrtproto, sizeof(mrtproto));
5754720Ssklower switch (mrtproto) {
5854720Ssklower
5954720Ssklower case 0:
6054720Ssklower printf("no multicast routing compiled into this system\n");
6154720Ssklower return;
6254720Ssklower
6354720Ssklower case IGMP_DVMRP:
6454720Ssklower break;
6554720Ssklower
6654720Ssklower default:
6754720Ssklower printf("multicast routing protocol %u, unknown\n", mrtproto);
6854720Ssklower return;
6954720Ssklower }
7054720Ssklower
7154720Ssklower if (mrtaddr == 0) {
7254720Ssklower printf("mrttable: symbol not in namelist\n");
7354720Ssklower return;
7454720Ssklower }
7554720Ssklower if (vifaddr == 0) {
7654720Ssklower printf("viftable: symbol not in namelist\n");
7754720Ssklower return;
7854720Ssklower }
7954720Ssklower
8054720Ssklower saved_nflag = nflag;
8154720Ssklower nflag = 1;
8254720Ssklower
8354761Ssklower kread(vifaddr, (char *)&viftable, sizeof(viftable));
8454720Ssklower banner_printed = 0;
8554720Ssklower for (vifi = 0, v = viftable; vifi < MAXVIFS; ++vifi, ++v) {
8654720Ssklower if (v->v_lcl_addr.s_addr == 0)
8754720Ssklower continue;
8854720Ssklower
8954720Ssklower if (!banner_printed) {
9054720Ssklower printf("\nVirtual Interface Table\n%s%s",
9154720Ssklower " Vif Threshold Local-Address ",
9254720Ssklower "Remote-Address Groups\n");
9354720Ssklower banner_printed = 1;
9454720Ssklower }
9554720Ssklower
9654720Ssklower printf(" %2u %3u %-15.15s",
9754720Ssklower vifi, v->v_threshold, routename(v->v_lcl_addr.s_addr));
9854720Ssklower printf(" %-15.15s\n", (v->v_flags & VIFF_TUNNEL) ?
9954720Ssklower routename(v->v_rmt_addr.s_addr) : "");
10054720Ssklower
10154720Ssklower n = v->v_lcl_grps_n;
10254720Ssklower grp = (struct in_addr *)malloc(n * sizeof(*grp));
10354720Ssklower if (grp == NULL) {
10454720Ssklower printf("v_lcl_grps_n: malloc failed\n");
10554720Ssklower return;
10654720Ssklower }
10754761Ssklower kread((u_long)v->v_lcl_grps, (caddr_t)grp, n * sizeof(*grp));
10854720Ssklower for (i = 0; i < n; ++i)
10954720Ssklower printf("%51s %-15.15s\n",
11054720Ssklower "", routename((grp++)->s_addr));
11154720Ssklower free(grp);
11254720Ssklower }
11354720Ssklower if (!banner_printed)
11454720Ssklower printf("\nVirtual Interface Table is empty\n");
11554720Ssklower
11654761Ssklower kread(mrtaddr, (char *)&mrttable, sizeof(mrttable));
11754720Ssklower banner_printed = 0;
11854720Ssklower for (i = 0; i < MRTHASHSIZ; ++i) {
11954720Ssklower for (mrt = mrttable[i]; mrt != NULL; mrt = mrt->mrt_next) {
12054720Ssklower if (!banner_printed) {
12154720Ssklower printf("\nMulticast Routing Table\n%s",
12254720Ssklower " Hash Origin-Subnet In-Vif Out-Vifs\n");
12354720Ssklower banner_printed = 1;
12454720Ssklower }
12554720Ssklower
12654761Ssklower kread((u_long)mrt, (char *)&smrt, sizeof(*mrt));
12754720Ssklower mrt = &smrt;
12854720Ssklower printf(" %3u %-15.15s %2u ",
12954720Ssklower i, netname(mrt->mrt_origin.s_addr,
13054720Ssklower ntohl(mrt->mrt_originmask.s_addr)),
13154720Ssklower mrt->mrt_parent);
13254720Ssklower for (vifi = 0; vifi < MAXVIFS; ++vifi)
13354720Ssklower if (VIFM_ISSET(vifi, mrt->mrt_children))
13454720Ssklower printf(" %u%c",
13554720Ssklower vifi,
13654720Ssklower VIFM_ISSET(vifi, mrt->mrt_leaves) ?
13754720Ssklower '*' : ' ');
13854720Ssklower printf("\n");
13954720Ssklower }
14054720Ssklower }
14154720Ssklower if (!banner_printed)
14254720Ssklower printf("\nMulticast Routing Table is empty\n");
14354720Ssklower
14454720Ssklower printf("\n");
14554720Ssklower nflag = saved_nflag;
14654720Ssklower }
14754720Ssklower
14854720Ssklower
14954720Ssklower void
mrt_stats(mrpaddr,mstaddr)15054720Ssklower mrt_stats(mrpaddr, mstaddr)
15154761Ssklower u_long mrpaddr, mstaddr;
15254720Ssklower {
15354720Ssklower u_int mrtproto;
15454720Ssklower struct mrtstat mrtstat;
15554720Ssklower
15654720Ssklower if(mrpaddr == 0) {
15754720Ssklower printf("ip_mrtproto: symbol not in namelist\n");
15854720Ssklower return;
15954720Ssklower }
16054720Ssklower
16154761Ssklower kread(mrpaddr, (char *)&mrtproto, sizeof(mrtproto));
16254720Ssklower switch (mrtproto) {
16354720Ssklower case 0:
16454720Ssklower printf("no multicast routing compiled into this system\n");
16554720Ssklower return;
16654720Ssklower
16754720Ssklower case IGMP_DVMRP:
16854720Ssklower break;
16954720Ssklower
17054720Ssklower default:
17154720Ssklower printf("multicast routing protocol %u, unknown\n", mrtproto);
17254720Ssklower return;
17354720Ssklower }
17454720Ssklower
17554720Ssklower if (mstaddr == 0) {
17654720Ssklower printf("mrtstat: symbol not in namelist\n");
17754720Ssklower return;
17854720Ssklower }
17954720Ssklower
18054761Ssklower kread(mstaddr, (char *)&mrtstat, sizeof(mrtstat));
18154720Ssklower printf("multicast routing:\n");
18254720Ssklower printf(" %10u multicast route lookup%s\n",
18354720Ssklower mrtstat.mrts_mrt_lookups, plural(mrtstat.mrts_mrt_lookups));
18454720Ssklower printf(" %10u multicast route cache miss%s\n",
18554720Ssklower mrtstat.mrts_mrt_misses, plurales(mrtstat.mrts_mrt_misses));
18654720Ssklower printf(" %10u group address lookup%s\n",
18754720Ssklower mrtstat.mrts_grp_lookups, plural(mrtstat.mrts_grp_lookups));
18854720Ssklower printf(" %10u group address cache miss%s\n",
18954720Ssklower mrtstat.mrts_grp_misses, plurales(mrtstat.mrts_grp_misses));
19054720Ssklower printf(" %10u datagram%s with no route for origin\n",
19154720Ssklower mrtstat.mrts_no_route, plural(mrtstat.mrts_no_route));
19254720Ssklower printf(" %10u datagram%s with malformed tunnel options\n",
19354720Ssklower mrtstat.mrts_bad_tunnel, plural(mrtstat.mrts_bad_tunnel));
19454720Ssklower printf(" %10u datagram%s with no room for tunnel options\n",
19554720Ssklower mrtstat.mrts_cant_tunnel, plural(mrtstat.mrts_cant_tunnel));
196*69047Sbostic printf(" %10u datagram%s arrived on the wrong interface\n",
197*69047Sbostic mrtstat.mrts_wrong_if, plural(mrtstat.mrts_wrong_if));
19854720Ssklower }
199