Example #1
0
void
mrt6_stats()
{
	struct mrt6stat mrtstat;
	u_long mstaddr;
	size_t len = sizeof mrtstat;

	kresolve_list(mrl);
	mstaddr = mrl[N_MRT6STAT].n_value;

	if (mstaddr == 0) {
		fprintf(stderr, "No IPv6 MROUTING kernel support.\n");
		return;
	}

	if (live) {
		if (sysctlbyname("net.inet6.ip6.mrt6stat", &mrtstat, &len,
		    NULL, 0) < 0) {
			warn("sysctl: net.inet6.ip6.mrt6stat");
			return;
		}
	} else
		kread(mstaddr, (char *)&mrtstat, sizeof(mrtstat));

	printf("IPv6 multicast forwarding:\n");

#define	p(f, m) if (mrtstat.f || sflag <= 1) \
	printf(m, (uintmax_t)mrtstat.f, plural(mrtstat.f))
#define	p2(f, m) if (mrtstat.f || sflag <= 1) \
	printf(m, (uintmax_t)mrtstat.f, plurales(mrtstat.f))

	p(mrt6s_mfc_lookups, "\t%ju multicast forwarding cache lookup%s\n");
	p2(mrt6s_mfc_misses, "\t%ju multicast forwarding cache miss%s\n");
	p(mrt6s_upcalls, "\t%ju upcall%s to multicast routing daemon\n");
	p(mrt6s_upq_ovflw, "\t%ju upcall queue overflow%s\n");
	p(mrt6s_upq_sockfull,
	    "\t%ju upcall%s dropped due to full socket buffer\n");
	p(mrt6s_cache_cleanups, "\t%ju cache cleanup%s\n");
	p(mrt6s_no_route, "\t%ju datagram%s with no route for origin\n");
	p(mrt6s_bad_tunnel, "\t%ju datagram%s arrived with bad tunneling\n");
	p(mrt6s_cant_tunnel, "\t%ju datagram%s could not be tunneled\n");
	p(mrt6s_wrong_if, "\t%ju datagram%s arrived on wrong interface\n");
	p(mrt6s_drop_sel, "\t%ju datagram%s selectively dropped\n");
	p(mrt6s_q_overflow,
	    "\t%ju datagram%s dropped due to queue overflow\n");
	p(mrt6s_pkt2large, "\t%ju datagram%s dropped for being too large\n");

#undef	p2
#undef	p
}
Example #2
0
int
main(int argc, char *argv[])
{
	struct protox *tp = NULL;  /* for printing cblocks & stats */
	int ch;
	int fib = -1;
	char *endptr;

	af = AF_UNSPEC;

	while ((ch = getopt(argc, argv, "46AaBbdF:f:ghI:iLlM:mN:np:Qq:RrSTsuWw:xz"))
	    != -1)
		switch(ch) {
		case '4':
#ifdef INET
			af = AF_INET;
#else
			errx(1, "IPv4 support is not compiled in");
#endif
			break;
		case '6':
#ifdef INET6
			af = AF_INET6;
#else
			errx(1, "IPv6 support is not compiled in");
#endif
			break;
		case 'A':
			Aflag = 1;
			break;
		case 'a':
			aflag = 1;
			break;
		case 'B':
			Bflag = 1;
			break;
		case 'b':
			bflag = 1;
			break;
		case 'd':
			dflag = 1;
			break;
		case 'F':
			fib = strtol(optarg, &endptr, 0);
			if (*endptr != '\0' ||
			    (fib == 0 && (errno == EINVAL || errno == ERANGE)))
				errx(1, "%s: invalid fib", optarg);
			break;
		case 'f':
			if (strcmp(optarg, "inet") == 0)
				af = AF_INET;
#ifdef INET6
			else if (strcmp(optarg, "inet6") == 0)
				af = AF_INET6;
#endif
#ifdef IPSEC
			else if (strcmp(optarg, "pfkey") == 0)
				af = PF_KEY;
#endif
			else if (strcmp(optarg, "unix") == 0)
				af = AF_UNIX;
#ifdef NETGRAPH
			else if (strcmp(optarg, "ng") == 0
			    || strcmp(optarg, "netgraph") == 0)
				af = AF_NETGRAPH;
#endif
			else if (strcmp(optarg, "link") == 0)
				af = AF_LINK;
			else {
				errx(1, "%s: unknown address family", optarg);
			}
			break;
		case 'g':
			gflag = 1;
			break;
		case 'h':
			hflag = 1;
			break;
		case 'I': {
			char *cp;

			iflag = 1;
			for (cp = interface = optarg; isalpha(*cp); cp++)
				continue;
			unit = atoi(cp);
			break;
		}
		case 'i':
			iflag = 1;
			break;
		case 'L':
			Lflag = 1;
			break;
		case 'M':
			memf = optarg;
			break;
		case 'm':
			mflag = 1;
			break;
		case 'N':
			nlistf = optarg;
			break;
		case 'n':
			numeric_addr = numeric_port = 1;
			break;
		case 'p':
			if ((tp = name2protox(optarg)) == NULL) {
				errx(1,
				     "%s: unknown or uninstrumented protocol",
				     optarg);
			}
			pflag = 1;
			break;
		case 'Q':
			Qflag = 1;
			break;
		case 'q':
			noutputs = atoi(optarg);
			if (noutputs != 0)
				noutputs++;
			break;
		case 'r':
			rflag = 1;
			break;
		case 'R':
			Rflag = 1;
			break;
		case 's':
			++sflag;
			break;
		case 'S':
			numeric_addr = 1;
			break;
		case 'u':
			af = AF_UNIX;
			break;
		case 'W':
		case 'l':
			Wflag = 1;
			break;
		case 'w':
			interval = atoi(optarg);
			iflag = 1;
			break;
		case 'T':
			Tflag = 1;
			break;
		case 'x':
			xflag = 1;
			break;
		case 'z':
			zflag = 1;
			break;
		case '?':
		default:
			usage();
		}
	argv += optind;
	argc -= optind;

#define	BACKWARD_COMPATIBILITY
#ifdef	BACKWARD_COMPATIBILITY
	if (*argv) {
		if (isdigit(**argv)) {
			interval = atoi(*argv);
			if (interval <= 0)
				usage();
			++argv;
			iflag = 1;
		}
		if (*argv) {
			nlistf = *argv;
			if (*++argv)
				memf = *argv;
		}
	}
#endif

	/*
	 * Discard setgid privileges if not the running kernel so that bad
	 * guys can't print interesting stuff from kernel memory.
	 */
	live = (nlistf == NULL && memf == NULL);
	if (!live)
		setgid(getgid());

	if (xflag && Tflag) 
		errx(1, "-x and -T are incompatible, pick one.");

	if (Bflag) {
		if (!live)
			usage();
		bpf_stats(interface);
		exit(0);
	}
	if (mflag) {
		if (!live) {
			if (kread(0, NULL, 0) == 0)
				mbpr(kvmd, nl[N_SFSTAT].n_value);
		} else
			mbpr(NULL, 0);
		exit(0);
	}
	if (Qflag) {
		if (!live) {
			if (kread(0, NULL, 0) == 0)
				netisr_stats(kvmd);
		} else
			netisr_stats(NULL);
		exit(0);
	}
#if 0
	/*
	 * Keep file descriptors open to avoid overhead
	 * of open/close on each call to get* routines.
	 */
	sethostent(1);
	setnetent(1);
#else
	/*
	 * This does not make sense any more with DNS being default over
	 * the files.  Doing a setXXXXent(1) causes a tcp connection to be
	 * used for the queries, which is slower.
	 */
#endif
	if (iflag && !sflag) {
		intpr(interval, NULL, af);
		exit(0);
	}
	if (rflag) {
		if (sflag) {
			rt_stats();
			flowtable_stats();
		} else
			routepr(fib, af);
		exit(0);
	}

	if (gflag) {
		if (sflag) {
			if (af == AF_INET || af == AF_UNSPEC)
				mrt_stats();
#ifdef INET6
			if (af == AF_INET6 || af == AF_UNSPEC)
				mrt6_stats();
#endif
		} else {
			if (af == AF_INET || af == AF_UNSPEC)
				mroutepr();
#ifdef INET6
			if (af == AF_INET6 || af == AF_UNSPEC)
				mroute6pr();
#endif
		}
		exit(0);
	}

	/* Load all necessary kvm symbols */
	kresolve_list(nl);

	if (tp) {
		printproto(tp, tp->pr_name);
		exit(0);
	}
	if (af == AF_INET || af == AF_UNSPEC)
		for (tp = protox; tp->pr_name; tp++)
			printproto(tp, tp->pr_name);
#ifdef INET6
	if (af == AF_INET6 || af == AF_UNSPEC)
		for (tp = ip6protox; tp->pr_name; tp++)
			printproto(tp, tp->pr_name);
#endif /*INET6*/
#ifdef IPSEC
	if (af == PF_KEY || af == AF_UNSPEC)
		for (tp = pfkeyprotox; tp->pr_name; tp++)
			printproto(tp, tp->pr_name);
#endif /*IPSEC*/
#ifdef NETGRAPH
	if (af == AF_NETGRAPH || af == AF_UNSPEC)
		for (tp = netgraphprotox; tp->pr_name; tp++)
			printproto(tp, tp->pr_name);
#endif /* NETGRAPH */
	if ((af == AF_UNIX || af == AF_UNSPEC) && !sflag)
		unixpr(nl[N_UNP_COUNT].n_value, nl[N_UNP_GENCNT].n_value,
		    nl[N_UNP_DHEAD].n_value, nl[N_UNP_SHEAD].n_value,
		    nl[N_UNP_SPHEAD].n_value);
	exit(0);
}
Example #3
0
void
mroute6pr()
{
	struct mf6c *mf6ctable[MF6CTBLSIZ], *mfcp;
	struct mif6 mif6table[MAXMIFS];
	struct mf6c mfc;
	struct rtdetq rte, *rtep;
	struct mif6 *mifp;
	u_long mfcaddr, mifaddr;
	mifi_t mifi;
	int i;
	int banner_printed;
	int saved_numeric_addr;
	mifi_t maxmif = 0;
	long int waitings;
	size_t len;

	kresolve_list(mrl);
	mfcaddr = mrl[N_MF6CTABLE].n_value;
	mifaddr = mrl[N_MIF6TABLE].n_value;

	if (mfcaddr == 0 || mifaddr == 0) {
		fprintf(stderr, "No IPv6 MROUTING kernel support.\n");
		return;
	}

	len = sizeof(mif6table);
	if (live) {
		if (sysctlbyname("net.inet6.ip6.mif6table", mif6table, &len,
		    NULL, 0) < 0) {
			warn("sysctl: net.inet6.ip6.mif6table");
			return;
		}
	} else
		kread(mifaddr, (char *)mif6table, sizeof(mif6table));

	saved_numeric_addr = numeric_addr;
	numeric_addr = 1;
	banner_printed = 0;

	for (mifi = 0, mifp = mif6table; mifi < MAXMIFS; ++mifi, ++mifp) {
		struct ifnet ifnet;
		char ifname[IFNAMSIZ];

		if (mifp->m6_ifp == NULL)
			continue;

		/* XXX KVM */
		kread((u_long)mifp->m6_ifp, (char *)&ifnet, sizeof(ifnet));

		maxmif = mifi;
		if (!banner_printed) {
			printf("\nIPv6 Multicast Interface Table\n"
			       " Mif   Rate   PhyIF   "
			       "Pkts-In   Pkts-Out\n");
			banner_printed = 1;
		}

		printf("  %2u   %4d",
		       mifi, mifp->m6_rate_limit);
		printf("   %5s", (mifp->m6_flags & MIFF_REGISTER) ?
		       "reg0" : if_indextoname(ifnet.if_index, ifname));

		printf(" %9ju  %9ju\n", (uintmax_t)mifp->m6_pkt_in,
		    (uintmax_t)mifp->m6_pkt_out);
	}
	if (!banner_printed)
		printf("\nIPv6 Multicast Interface Table is empty\n");

	len = sizeof(mf6ctable);
	if (live) {
		if (sysctlbyname("net.inet6.ip6.mf6ctable", mf6ctable, &len,
		    NULL, 0) < 0) {
			warn("sysctl: net.inet6.ip6.mf6ctable");
			return;
		}
	} else
		kread(mfcaddr, (char *)mf6ctable, sizeof(mf6ctable));

	banner_printed = 0;

	for (i = 0; i < MF6CTBLSIZ; ++i) {
		mfcp = mf6ctable[i];
		while(mfcp) {
			kread((u_long)mfcp, (char *)&mfc, sizeof(mfc));
			if (!banner_printed) {
				printf ("\nIPv6 Multicast Forwarding Cache\n");
				printf(" %-*.*s %-*.*s %s",
				       WID_ORG, WID_ORG, "Origin",
				       WID_GRP, WID_GRP, "Group",
				       "  Packets Waits In-Mif  Out-Mifs\n");
				banner_printed = 1;
			}

			printf(" %-*.*s", WID_ORG, WID_ORG,
			       routename6(&mfc.mf6c_origin));
			printf(" %-*.*s", WID_GRP, WID_GRP,
			       routename6(&mfc.mf6c_mcastgrp));
			printf(" %9ju", (uintmax_t)mfc.mf6c_pkt_cnt);

			for (waitings = 0, rtep = mfc.mf6c_stall; rtep; ) {
				waitings++;
				/* XXX KVM */
				kread((u_long)rtep, (char *)&rte, sizeof(rte));
				rtep = rte.next;
			}
			printf("   %3ld", waitings);

			if (mfc.mf6c_parent == MF6C_INCOMPLETE_PARENT)
				printf(" ---   ");
			else
				printf("  %3d   ", mfc.mf6c_parent);
			for (mifi = 0; mifi <= maxmif; mifi++) {
				if (IF_ISSET(mifi, &mfc.mf6c_ifset))
					printf(" %u", mifi);
			}
			printf("\n");

			mfcp = mfc.mf6c_next;
		}
	}
	if (!banner_printed)
		printf("\nIPv6 Multicast Forwarding Table is empty\n");

	printf("\n");
	numeric_addr = saved_numeric_addr;
}