version 1.23, 2015/01/16 06:40:10 |
version 1.24, 2015/02/09 12:25:03 |
|
|
|
|
#include <sys/types.h> |
#include <sys/types.h> |
#include <sys/socket.h> |
#include <sys/socket.h> |
#include <sys/socketvar.h> |
|
#include <sys/protosw.h> |
|
#include <sys/sysctl.h> |
#include <sys/sysctl.h> |
|
|
#include <net/if.h> |
|
#include <net/route.h> |
|
#include <netinet/in.h> |
#include <netinet/in.h> |
#include <netinet/igmp.h> |
#include <netinet/igmp.h> |
#define _KERNEL |
|
#include <netinet/ip_mroute.h> |
#include <netinet/ip_mroute.h> |
#undef _KERNEL |
|
|
|
#include <err.h> |
#include <err.h> |
#include <errno.h> |
#include <errno.h> |
#include <limits.h> |
#include <limits.h> |
#include <stdio.h> |
#include <stdio.h> |
#include <stdlib.h> |
#include <stdlib.h> |
|
#include <util.h> |
#include "netstat.h" |
#include "netstat.h" |
|
|
static char * |
|
pktscale(u_long n) |
|
{ |
|
static char buf[8]; |
|
char t; |
|
|
|
if (n < 1024) |
|
t = ' '; |
|
else if (n < 1024 * 1024) { |
|
t = 'k'; |
|
n /= 1024; |
|
} else { |
|
t = 'm'; |
|
n /= 1048576; |
|
} |
|
|
|
snprintf(buf, sizeof buf, "%lu%c", n, t); |
|
return (buf); |
|
} |
|
|
|
void |
void |
mroutepr(u_long mfchashtbladdr, u_long mfchashaddr, u_long vifaddr) |
mroutepr(void) |
{ |
{ |
u_int mrtproto; |
u_int mrtproto; |
LIST_HEAD(, mfc) *mfchashtbl; |
struct vifinfo *v; |
u_long mfchash; |
struct mfcinfo *m; |
struct vif viftable[MAXVIFS], *v; |
size_t needed, numvifs, nummfcs, vifi, mfci; |
struct mfc *mfcp, mfc; |
char *buf = NULL; |
vifi_t vifi; |
char fmtbuf[FMT_SCALED_STRSIZE]; |
|
vifi_t maxvif = 0; |
int mib[] = { CTL_NET, PF_INET, IPPROTO_IP, IPCTL_MRTPROTO }; |
int mib[] = { CTL_NET, PF_INET, IPPROTO_IP, IPCTL_MRTPROTO }; |
size_t len = sizeof(int); |
size_t len = sizeof(int); |
int i, banner_printed = 0, saved_nflag, numvifs = 0; |
int banner_printed = 0, saved_nflag; |
int nmfc; /* No. of cache entries */ |
|
|
|
if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), |
if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), |
&mrtproto, &len, NULL, 0) == -1) { |
&mrtproto, &len, NULL, 0) == -1) { |
|
|
return; |
return; |
} |
} |
|
|
if (mfchashtbladdr == 0) { |
|
printf("mfchashtbl: symbol not in namelist\n"); |
|
return; |
|
} |
|
if (mfchashaddr == 0) { |
|
printf("mfchash: symbol not in namelist\n"); |
|
return; |
|
} |
|
if (vifaddr == 0) { |
|
printf("viftable: symbol not in namelist\n"); |
|
return; |
|
} |
|
|
|
saved_nflag = nflag; |
saved_nflag = nflag; |
nflag = 1; |
nflag = 1; |
|
|
kread(vifaddr, &viftable, sizeof(viftable)); |
mib[3] = IPCTL_MRTVIF; |
|
needed = get_sysctl(mib, sizeof(mib) / sizeof(mib[0]), &buf); |
|
numvifs = needed / sizeof(*v); |
|
v = (struct vifinfo *)buf; |
|
if (numvifs) |
|
maxvif = v[numvifs - 1].v_vifi; |
|
|
for (vifi = 0, v = viftable; vifi < MAXVIFS; ++vifi, ++v) { |
for (vifi = 0; vifi < numvifs; ++vifi, ++v) { |
if (v->v_lcl_addr.s_addr == 0) |
|
continue; |
|
numvifs = vifi; |
|
|
|
if (!banner_printed) { |
if (!banner_printed) { |
printf("\nVirtual Interface Table\n %s%s", |
printf("\nVirtual Interface Table\n %s%s", |
"Vif Thresh Limit Local-Address ", |
"Vif Thresh Limit Local-Address ", |
|
|
} |
} |
|
|
printf(" %3u %3u %-15.15s", |
printf(" %3u %3u %-15.15s", |
vifi, v->v_threshold, |
v->v_vifi, v->v_threshold, |
routename4(v->v_lcl_addr.s_addr)); |
routename4(v->v_lcl_addr.s_addr)); |
printf(" %-15.15s %6lu %7lu\n", (v->v_flags & VIFF_TUNNEL) ? |
printf(" %-15.15s %6lu %7lu\n", (v->v_flags & VIFF_TUNNEL) ? |
routename4(v->v_rmt_addr.s_addr) : "", |
routename4(v->v_rmt_addr.s_addr) : "", |
|
|
if (!banner_printed) |
if (!banner_printed) |
printf("Virtual Interface Table is empty\n"); |
printf("Virtual Interface Table is empty\n"); |
|
|
kread(mfchashtbladdr, &mfchashtbl, sizeof(mfchashtbl)); |
|
kread(mfchashaddr, &mfchash, sizeof(mfchash)); |
|
banner_printed = 0; |
banner_printed = 0; |
nmfc = 0; |
|
|
|
if (mfchashtbl != 0) |
mib[3] = IPCTL_MRTMFC; |
for (i = 0; i <= mfchash; ++i) { |
needed = get_sysctl(mib, sizeof(mib) / sizeof(mib[0]), &buf); |
kread((u_long)&mfchashtbl[i], &mfcp, sizeof(mfcp)); |
nummfcs = needed / sizeof(*m); |
|
m = (struct mfcinfo *)buf; |
|
|
for (; mfcp != 0; mfcp = LIST_NEXT(&mfc, mfc_hash)) { |
for (mfci = 0; mfci < nummfcs; ++mfci, ++m) { |
if (!banner_printed) { |
if (!banner_printed) { |
printf("\nMulticast Forwarding Cache\n %s%s", |
printf("\nMulticast Forwarding Cache\n %s%s", |
"Hash Origin Mcastgroup ", |
"Hash Origin Mcastgroup ", |
"Traffic In-Vif Out-Vifs/Forw-ttl\n"); |
"Traffic In-Vif Out-Vifs/Forw-ttl\n"); |
banner_printed = 1; |
banner_printed = 1; |
} |
} |
|
|
kread((u_long)mfcp, &mfc, sizeof(mfc)); |
printf(" %3zu %-15.15s", |
printf(" %3u %-15.15s", |
mfci, routename4(m->mfc_origin.s_addr)); |
i, routename4(mfc.mfc_origin.s_addr)); |
fmt_scaled(m->mfc_pkt_cnt, fmtbuf); |
printf(" %-15.15s %7s %3u ", |
printf(" %-15.15s %7s %3u ", |
routename4(mfc.mfc_mcastgrp.s_addr), |
routename4(m->mfc_mcastgrp.s_addr), |
pktscale(mfc.mfc_pkt_cnt), mfc.mfc_parent); |
buf, m->mfc_parent); |
for (vifi = 0; vifi <= numvifs; ++vifi) |
for (vifi = 0; vifi <= maxvif; ++vifi) |
if (mfc.mfc_ttls[vifi]) |
if (m->mfc_ttls[vifi]) |
printf(" %u/%u", vifi, |
printf(" %zu/%u", vifi, m->mfc_ttls[vifi]); |
mfc.mfc_ttls[vifi]); |
|
|
|
printf("\n"); |
printf("\n"); |
|
} |
nmfc++; |
|
} |
|
} |
|
if (!banner_printed) |
if (!banner_printed) |
printf("Multicast Forwarding Cache is empty\n"); |
printf("Multicast Forwarding Cache is empty\n"); |
else |
else |
printf("\nTotal no. of entries in cache: %d\n", nmfc); |
printf("\nTotal no. of entries in cache: %zu\n", nummfcs); |
|
|
printf("\n"); |
printf("\n"); |
nflag = saved_nflag; |
nflag = saved_nflag; |