154720Ssklower /* 254720Ssklower * Copyright (c) 1989 Stephen Deering 354720Ssklower * Copyright (c) 1992 Regents of the University of California. 454720Ssklower * 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*54761Ssklower * @(#)mroute.c 7.2 (Berkeley) 07/07/92 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 3654720Ssklower mroutepr(mrpaddr, mrtaddr, vifaddr) 37*54761Ssklower 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 56*54761Ssklower 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 83*54761Ssklower 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 } 107*54761Ssklower 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 116*54761Ssklower 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 126*54761Ssklower 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 15054720Ssklower mrt_stats(mrpaddr, mstaddr) 151*54761Ssklower 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 161*54761Ssklower 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 180*54761Ssklower 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)); 19654720Ssklower } 197