Esempio n. 1
0
/*
 * Dump IPSEC statistics structure.
 */
static void
ipsec_hist_new(const uint64_t *hist, size_t histmax,
    const struct val2str *name, const char *title, const char *cname)
{
	int first;
	size_t proto;
	const struct val2str *p;

	first = 1;
	for (proto = 0; proto < histmax; proto++) {
		if (hist[proto] <= 0)
			continue;
		if (first) {
			xo_open_list(cname);
			xo_emit("\t{T:/%s histogram}:\n", title);
			first = 0;
		}
		xo_open_instance(cname);
		for (p = name; p && p->str; p++) {
			if (p->val == (int)proto)
				break;
		}
		if (p && p->str) {
			xo_emit("\t\t{k:name}: {:count/%ju}\n", p->str,
			    (uintmax_t)hist[proto]);
		} else {
			xo_emit("\t\t#{k:name/%lu}: {:count/%ju}\n",
			    (unsigned long)proto, (uintmax_t)hist[proto]);
		}
		xo_close_instance(cname);
	}
	if (!first)
		xo_close_list(cname);
}
Esempio n. 2
0
void
printstream(const DISPLAY *dp)
{
	FTSENT *p;
	int chcnt;

	xo_open_list("entry");
	for (p = dp->list, chcnt = 0; p; p = p->fts_link) {
		if (p->fts_number == NO_PRINT)
			continue;
		/* XXX strlen does not take octal escapes into account. */
		if (strlen(p->fts_name) + chcnt +
		    (p->fts_link ? 2 : 0) >= (unsigned)termwidth) {
			xo_emit("\n");
			chcnt = 0;
		}
		xo_open_instance("file");
		chcnt += printaname(p, dp->s_inode, dp->s_block);
		xo_close_instance("file");
		if (p->fts_link) {
			xo_emit(", ");
			chcnt += 2;
		}
	}
	xo_close_list("entry");
	if (chcnt)
		xo_emit("\n");
}
Esempio n. 3
0
static void
p_rtentry_sysctl(const char *name, struct rt_msghdr *rtm)
{
	struct sockaddr *sa, *addr[RTAX_MAX];
	char buffer[128];
	char prettyname[128];
	int i, protrusion;

	xo_open_instance(name);
	sa = (struct sockaddr *)(rtm + 1);
	for (i = 0; i < RTAX_MAX; i++) {
		if (rtm->rtm_addrs & (1 << i)) {
			addr[i] = sa;
			sa = (struct sockaddr *)((char *)sa + SA_SIZE(sa));
		}
	}

	protrusion = p_sockaddr("destination", addr[RTAX_DST],
	    addr[RTAX_NETMASK],
	    rtm->rtm_flags, wid_dst);
	protrusion = p_sockaddr("gateway", addr[RTAX_GATEWAY], NULL, RTF_HOST,
	    wid_gw - protrusion);
	snprintf(buffer, sizeof(buffer), "{[:-%d}{:flags/%%s}{]:} ",
	    wid_flags - protrusion);
	p_flags(rtm->rtm_flags, buffer);
	if (Wflag) {
		xo_emit("{t:use/%*lu} ", wid_pksent, rtm->rtm_rmx.rmx_pksent);

		if (rtm->rtm_rmx.rmx_mtu != 0)
			xo_emit("{t:mtu/%*lu} ", wid_mtu, rtm->rtm_rmx.rmx_mtu);
		else
			xo_emit("{P:/%*s} ", wid_mtu, "");
	}

	memset(prettyname, 0, sizeof(prettyname));
	if (rtm->rtm_index < ifmap_size) {
		strlcpy(prettyname, ifmap[rtm->rtm_index].ifname,
		    sizeof(prettyname));
		if (*prettyname == '\0')
			strlcpy(prettyname, "---", sizeof(prettyname));
	}

	if (Wflag)
		xo_emit("{t:interface-name/%*s}", wid_if, prettyname);
	else
		xo_emit("{t:interface-name/%*.*s}", wid_if, wid_if,
		    prettyname);
	if (rtm->rtm_rmx.rmx_expire) {
		time_t expire_time;

		if ((expire_time = rtm->rtm_rmx.rmx_expire - uptime.tv_sec) > 0)
			xo_emit(" {:expire-time/%*d}", wid_expire,
			    (int)expire_time);
	}

	xo_emit("\n");
	xo_close_instance(name);
}
Esempio n. 4
0
void
printscol(const DISPLAY *dp)
{
	FTSENT *p;

	xo_open_list("entry");
	for (p = dp->list; p; p = p->fts_link) {
		if (IS_NOPRINT(p))
			continue;
		xo_open_instance("entry");
		(void)printaname(p, dp->s_inode, dp->s_block);
		xo_close_instance("entry");
		xo_emit("\n");
	}
	xo_close_list("entry");
}
Esempio n. 5
0
/*
 * Dump ICMP statistics.
 */
void
icmp_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
{
	struct icmpstat icmpstat;
	size_t len;
	int i, first;

	if (fetch_stats("net.inet.icmp.stats", off, &icmpstat,
	    sizeof(icmpstat), kread_counters) != 0)
		return;

	xo_open_container(name);
	xo_emit("{T:/%s}:\n", name);

#define	p(f, m) if (icmpstat.f || sflag <= 1) \
	xo_emit(m, icmpstat.f, plural(icmpstat.f))
#define	p1a(f, m) if (icmpstat.f || sflag <= 1) \
	xo_emit(m, icmpstat.f)
#define	p2(f, m) if (icmpstat.f || sflag <= 1) \
	xo_emit(m, icmpstat.f, plurales(icmpstat.f))

	p(icps_error, "\t{:icmp-calls/%lu} "
	    "{N:/call%s to icmp_error}\n");
	p(icps_oldicmp, "\t{:errors-not-from-message/%lu} "
	    "{N:/error%s not generated in response to an icmp message}\n");

	for (first = 1, i = 0; i < ICMP_MAXTYPE + 1; i++) {
		if (icmpstat.icps_outhist[i] != 0) {
			if (first) {
				xo_open_list("output-histogram");
				xo_emit("\tOutput histogram:\n");
				first = 0;
			}
			xo_open_instance("output-histogram");
			if (icmpnames[i] != NULL)
				xo_emit("\t\t{k:name/%s}: {:count/%lu}\n",
				    icmpnames[i], icmpstat.icps_outhist[i]);
			else
				xo_emit("\t\tunknown ICMP #{k:name/%d}: "
				    "{:count/%lu}\n",
				    i, icmpstat.icps_outhist[i]);
			xo_close_instance("output-histogram");
		}
	}
	if (!first)
		xo_close_list("output-histogram");

	p(icps_badcode, "\t{:dropped-bad-code/%lu} "
	    "{N:/message%s with bad code fields}\n");
	p(icps_tooshort, "\t{:dropped-too-short/%lu} "
	    "{N:/message%s less than the minimum length}\n");
	p(icps_checksum, "\t{:dropped-bad-checksum/%lu} "
	    "{N:/message%s with bad checksum}\n");
	p(icps_badlen, "\t{:dropped-bad-length/%lu} "
	    "{N:/message%s with bad length}\n");
	p1a(icps_bmcastecho, "\t{:dropped-multicast-echo/%lu} "
	    "{N:/multicast echo requests ignored}\n");
	p1a(icps_bmcasttstamp, "\t{:dropped-multicast-timestamp/%lu} "
	    "{N:/multicast timestamp requests ignored}\n");

	for (first = 1, i = 0; i < ICMP_MAXTYPE + 1; i++) {
		if (icmpstat.icps_inhist[i] != 0) {
			if (first) {
				xo_open_list("input-histogram");
				xo_emit("\tInput histogram:\n");
				first = 0;
			}
			xo_open_instance("input-histogram");
			if (icmpnames[i] != NULL)
				xo_emit("\t\t{k:name/%s}: {:count/%lu}\n",
					icmpnames[i],
					icmpstat.icps_inhist[i]);
			else
				xo_emit(
			"\t\tunknown ICMP #{k:name/%d}: {:count/%lu}\n",
					i, icmpstat.icps_inhist[i]);
			xo_close_instance("input-histogram");
		}
	}
	if (!first)
		xo_close_list("input-histogram");

	p(icps_reflect, "\t{:sent-packets/%lu} "
	    "{N:/message response%s generated}\n");
	p2(icps_badaddr, "\t{:discard-invalid-return-address/%lu} "
	    "{N:/invalid return address%s}\n");
	p(icps_noroute, "\t{:discard-no-route/%lu} "
	    "{N:/no return route%s}\n");
#undef p
#undef p1a
#undef p2
	if (live) {
		len = sizeof i;
		if (sysctlbyname("net.inet.icmp.maskrepl", &i, &len, NULL, 0) <
		    0)
			return;
		xo_emit("\tICMP address mask responses are "
		    "{q:icmp-address-responses/%sabled}\n", i ? "en" : "dis");
	}

	xo_close_container(name);
}
Esempio n. 6
0
int
main(int argc, char *argv[])
{
	int ch, errors, total;

	(void) setlocale(LC_CTYPE, "");

	argc = xo_parse_args(argc, argv);
	if (argc < 0)
		return (argc);

	while ((ch = getopt(argc, argv, "clmwL")) != -1)
		switch((char)ch) {
		case 'l':
			doline = 1;
			break;
		case 'w':
			doword = 1;
			break;
		case 'c':
			dochar = 1;
			domulti = 0;
			break;
		case 'L':
			dolongline = 1;
			break;
		case 'm':
			domulti = 1;
			dochar = 0;
			break;
		case '?':
		default:
			usage();
		}
	argv += optind;
	argc -= optind;

	(void)signal(SIGINFO, siginfo_handler);

	/* Wc's flags are on by default. */
	if (doline + doword + dochar + domulti + dolongline == 0)
		doline = doword = dochar = 1;

	stderr_handle = xo_create_to_file(stderr, XO_STYLE_TEXT, 0);
	xo_open_container("wc");
	xo_open_list("file");

	errors = 0;
	total = 0;
	if (!*argv) {
	 	xo_open_instance("file");
		if (cnt((char *)NULL) != 0)
			++errors;
	 	xo_close_instance("file");
	} else {
		do {
	 		xo_open_instance("file");
			if (cnt(*argv) != 0)
				++errors;
	 		xo_close_instance("file");
			++total;
		} while(*++argv);
	}

	xo_close_list("file");

	if (total > 1) {
		xo_open_container("total");
		show_cnt("total", tlinect, twordct, tcharct, tlongline);
		xo_close_container("total");
	}

	xo_close_container("wc");
	xo_finish();
	exit(errors == 0 ? 0 : 1);
}
Esempio n. 7
0
/*
 * Dump ICMP6 statistics.
 */
void
icmp6_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
{
	struct icmp6stat icmp6stat, zerostat;
	int i, first;
	size_t len;

	len = sizeof icmp6stat;
	if (live) {
		memset(&icmp6stat, 0, len);
		if (zflag)
			memset(&zerostat, 0, len);
		if (sysctlbyname("net.inet6.icmp6.stats", &icmp6stat, &len,
		    zflag ? &zerostat : NULL, zflag ? len : 0) < 0) {
			if (errno != ENOENT)
				xo_warn("sysctl: net.inet6.icmp6.stats");
			return;
		}
	} else
		kread_counters(off, &icmp6stat, len);

	xo_emit("{T:/%s}:\n", name);
	xo_open_container(name);

#define	p(f, m) if (icmp6stat.f || sflag <= 1) \
	xo_emit(m, (uintmax_t)icmp6stat.f, plural(icmp6stat.f))
#define	p_5(f, m) if (icmp6stat.f || sflag <= 1) \
	xo_emit(m, (uintmax_t)icmp6stat.f)

	p(icp6s_error, "\t{:icmp6-calls/%ju} "
	    "{N:/call%s to icmp6_error}\n");
	p(icp6s_canterror, "\t{:errors-not-generated-from-message/%ju} "
	    "{N:/error%s not generated in response to an icmp6 message}\n");
	p(icp6s_toofreq, "\t{:errors-discarded-by-rate-limitation/%ju} "
	    "{N:/error%s not generated because of rate limitation}\n");
#define	NELEM (int)(sizeof(icmp6stat.icp6s_outhist)/sizeof(icmp6stat.icp6s_outhist[0]))
	for (first = 1, i = 0; i < NELEM; i++)
		if (icmp6stat.icp6s_outhist[i] != 0) {
			if (first) {
				xo_open_list("output-histogram");
				xo_emit("\t{T:Output histogram}:\n");
				first = 0;
			}
			xo_open_instance("output-histogram");
			xo_emit("\t\t{k:name/%s}: {:count/%ju}\n",
			    icmp6names[i],
			    (uintmax_t)icmp6stat.icp6s_outhist[i]);
			xo_close_instance("output-histogram");
		}
	if (!first)
		xo_close_list("output-histogram");
#undef NELEM

	p(icp6s_badcode, "\t{:dropped-bad-code/%ju} "
	    "{N:/message%s with bad code fields}\n");
	p(icp6s_tooshort, "\t{:dropped-too-short/%ju} "
	    "{N:/message%s < minimum length}\n");
	p(icp6s_checksum, "\t{:dropped-bad-checksum/%ju} "
	    "{N:/bad checksum%s}\n");
	p(icp6s_badlen, "\t{:dropped-bad-length/%ju} "
	    "{N:/message%s with bad length}\n");
#define	NELEM (int)(sizeof(icmp6stat.icp6s_inhist)/sizeof(icmp6stat.icp6s_inhist[0]))
	for (first = 1, i = 0; i < NELEM; i++)
		if (icmp6stat.icp6s_inhist[i] != 0) {
			if (first) {
				xo_open_list("input-histogram");
				xo_emit("\t{T:Input histogram}:\n");
				first = 0;
			}
			xo_open_instance("input-histogram");
			xo_emit("\t\t{k:name/%s}: {:count/%ju}\n",
			    icmp6names[i],
			    (uintmax_t)icmp6stat.icp6s_inhist[i]);
			xo_close_instance("input-histogram");
		}
	if (!first)
		xo_close_list("input-histogram");
#undef NELEM
	xo_emit("\t{T:Histogram of error messages to be generated}:\n");
	xo_open_container("errors");
	p_5(icp6s_odst_unreach_noroute, "\t\t{:no-route/%ju} "
	    "{N:/no route}\n");
	p_5(icp6s_odst_unreach_admin, "\t\t{:admin-prohibited/%ju} "
	    "{N:/administratively prohibited}\n");
	p_5(icp6s_odst_unreach_beyondscope, "\t\t{:beyond-scope/%ju} "
	    "{N:/beyond scope}\n");
	p_5(icp6s_odst_unreach_addr, "\t\t{:address-unreachable/%ju} "
	    "{N:/address unreachable}\n");
	p_5(icp6s_odst_unreach_noport, "\t\t{:port-unreachable/%ju} "
	    "{N:/port unreachable}\n");
	p_5(icp6s_opacket_too_big, "\t\t{:packet-too-big/%ju} "
	    "{N:/packet too big}\n");
	p_5(icp6s_otime_exceed_transit, "\t\t{:time-exceed-transmit/%ju} "
	    "{N:/time exceed transit}\n");
	p_5(icp6s_otime_exceed_reassembly, "\t\t{:time-exceed-reassembly/%ju} "
	    "{N:/time exceed reassembly}\n");
	p_5(icp6s_oparamprob_header, "\t\t{:bad-header/%ju} "
	    "{N:/erroneous header field}\n");
	p_5(icp6s_oparamprob_nextheader, "\t\t{:bad-next-header/%ju} "
	    "{N:/unrecognized next header}\n");
	p_5(icp6s_oparamprob_option, "\t\t{:bad-option/%ju} "
	    "{N:/unrecognized option}\n");
	p_5(icp6s_oredirect, "\t\t{:redirects/%ju} "
	    "{N:/redirect}\n");
	p_5(icp6s_ounknown, "\t\t{:unknown/%ju} {N:unknown}\n");

	p(icp6s_reflect, "\t{:reflect/%ju} "
	    "{N:/message response%s generated}\n");
	p(icp6s_nd_toomanyopt, "\t{:too-many-nd-options/%ju} "
	    "{N:/message%s with too many ND options}\n");
	p(icp6s_nd_badopt, "\t{:bad-nd-options/%ju} "
	    "{N:/message%s with bad ND options}\n");
	p(icp6s_badns, "\t{:bad-neighbor-solicitation/%ju} "
	    "{N:/bad neighbor solicitation message%s}\n");
	p(icp6s_badna, "\t{:bad-neighbor-advertisement/%ju} "
	    "{N:/bad neighbor advertisement message%s}\n");
	p(icp6s_badrs, "\t{:bad-router-solicitation/%ju} "
	    "{N:/bad router solicitation message%s}\n");
	p(icp6s_badra, "\t{:bad-router-advertisement/%ju} "
	    "{N:/bad router advertisement message%s}\n");
	p(icp6s_badredirect, "\t{:bad-redirect/%ju} "
	    "{N:/bad redirect message%s}\n");
	xo_close_container("errors");
	p(icp6s_pmtuchg, "\t{:path-mtu-changes/%ju} {N:/path MTU change%s}\n");
#undef p
#undef p_5
	xo_close_container(name);
}
Esempio n. 8
0
/*
 * Dump IPv6 per-interface statistics based on RFC 2465.
 */
void
ip6_ifstats(char *ifname)
{
	struct in6_ifreq ifr;
	int s;

#define	p(f, m) if (ifr.ifr_ifru.ifru_stat.f || sflag <= 1)	\
	xo_emit(m, (uintmax_t)ifr.ifr_ifru.ifru_stat.f,		\
	    plural(ifr.ifr_ifru.ifru_stat.f))

	if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
		xo_warn("Warning: socket(AF_INET6)");
		return;
	}

	strcpy(ifr.ifr_name, ifname);
	if (ioctl(s, SIOCGIFSTAT_IN6, (char *)&ifr) < 0) {
		if (errno != EPFNOSUPPORT)
			xo_warn("Warning: ioctl(SIOCGIFSTAT_IN6)");
		goto end;
	}

	xo_emit("{T:/ip6 on %s}:\n", ifr.ifr_name);

	xo_open_instance("ip6-interface-statistics");
	xo_emit("{ke:name/%s}", ifr.ifr_name);

	p(ifs6_in_receive, "\t{:received-packets/%ju} "
	    "{N:/total input datagram%s}\n");
	p(ifs6_in_hdrerr, "\t{:dropped-invalid-header/%ju} "
	    "{N:/datagram%s with invalid header received}\n");
	p(ifs6_in_toobig, "\t{:dropped-mtu-exceeded/%ju} "
	    "{N:/datagram%s exceeded MTU received}\n");
	p(ifs6_in_noroute, "\t{:dropped-no-route/%ju} "
	    "{N:/datagram%s with no route received}\n");
	p(ifs6_in_addrerr, "\t{:dropped-invalid-destination/%ju} "
	    "{N:/datagram%s with invalid dst received}\n");
	p(ifs6_in_protounknown, "\t{:dropped-unknown-protocol/%ju} "
	    "{N:/datagram%s with unknown proto received}\n");
	p(ifs6_in_truncated, "\t{:dropped-truncated/%ju} "
	    "{N:/truncated datagram%s received}\n");
	p(ifs6_in_discard, "\t{:dropped-discarded/%ju} "
	    "{N:/input datagram%s discarded}\n");
 	p(ifs6_in_deliver, "\t{:received-valid-packets/%ju} "
	    "{N:/datagram%s delivered to an upper layer protocol}\n");
	p(ifs6_out_forward, "\t{:sent-forwarded/%ju} "
	    "{N:/datagram%s forwarded to this interface}\n");
 	p(ifs6_out_request, "\t{:sent-packets/%ju} "
	    "{N:/datagram%s sent from an upper layer protocol}\n");
	p(ifs6_out_discard, "\t{:discard-packets/%ju} "
	    "{N:/total discarded output datagram%s}\n");
	p(ifs6_out_fragok, "\t{:discard-fragments/%ju} "
	    "{N:/output datagram%s fragmented}\n");
	p(ifs6_out_fragfail, "\t{:fragments-failed/%ju} "
	    "{N:/output datagram%s failed on fragment}\n");
	p(ifs6_out_fragcreat, "\t{:fragments-created/%ju} "
	    "{N:/output datagram%s succeeded on fragment}\n");
	p(ifs6_reass_reqd, "\t{:reassembly-required/%ju} "
	    "{N:/incoming datagram%s fragmented}\n");
	p(ifs6_reass_ok, "\t{:reassembled-packets/%ju} "
	    "{N:/datagram%s reassembled}\n");
	p(ifs6_reass_fail, "\t{:reassembly-failed/%ju} "
	    "{N:/datagram%s failed on reassembly}\n");
	p(ifs6_in_mcast, "\t{:received-multicast/%ju} "
	    "{N:/multicast datagram%s received}\n");
	p(ifs6_out_mcast, "\t{:sent-multicast/%ju} "
	    "{N:/multicast datagram%s sent}\n");

 end:
	xo_close_instance("ip6-interface-statistics");
 	close(s);

#undef p
}
Esempio n. 9
0
static void
sctp_process_tcb(struct xsctp_tcb *xstcb,
    char *buf, const size_t buflen, size_t *offset, int *indent)
{
	int i, xl_total = 0, xr_total = 0, x_max;
	struct xsctp_raddr *xraddr;
	struct xsctp_laddr *xladdr;
	struct xladdr_entry *prev_xl = NULL, *xl = NULL, *xl_tmp;
	struct xraddr_entry *prev_xr = NULL, *xr = NULL, *xr_tmp;

	LIST_INIT(&xladdr_head);
	LIST_INIT(&xraddr_head);

	/*
	 * Make `struct xladdr_list' list and `struct xraddr_list' list
	 * to handle the address flexibly.
	 */
	while (*offset < buflen) {
		xladdr = (struct xsctp_laddr *)(buf + *offset);
		*offset += sizeof(struct xsctp_laddr);
		if (xladdr->last == 1)
			break;

		prev_xl = xl;
		xl = malloc(sizeof(struct xladdr_entry));
		if (xl == NULL) {
			xo_warnx("malloc %lu bytes",
			    (u_long)sizeof(struct xladdr_entry));
			goto out;
		}
		xl->xladdr = xladdr;
		if (prev_xl == NULL)
			LIST_INSERT_HEAD(&xladdr_head, xl, xladdr_entries);
		else
			LIST_INSERT_AFTER(prev_xl, xl, xladdr_entries);
		xl_total++;
	}

	while (*offset < buflen) {
		xraddr = (struct xsctp_raddr *)(buf + *offset);
		*offset += sizeof(struct xsctp_raddr);
		if (xraddr->last == 1)
			break;

		prev_xr = xr;
		xr = malloc(sizeof(struct xraddr_entry));
		if (xr == NULL) {
			xo_warnx("malloc %lu bytes",
			    (u_long)sizeof(struct xraddr_entry));
			goto out;
		}
		xr->xraddr = xraddr;
		if (prev_xr == NULL)
			LIST_INSERT_HEAD(&xraddr_head, xr, xraddr_entries);
		else
			LIST_INSERT_AFTER(prev_xr, xr, xraddr_entries);
		xr_total++;
	}

	/*
	 * Let's print the address infos.
	 */
	xo_open_list("address");
	xl = LIST_FIRST(&xladdr_head);
	xr = LIST_FIRST(&xraddr_head);
	x_max = MAX(xl_total, xr_total);
	for (i = 0; i < x_max; i++) {
		xo_open_instance("address");

		if (((*indent == 0) && i > 0) || *indent > 0)
			xo_emit("{P:/%-12s} ", " ");

		if (xl != NULL) {
			sctp_print_address("local", &(xl->xladdr->address),
			    htons(xstcb->local_port), numeric_port);
		} else {
			if (Wflag) {
				xo_emit("{P:/%-45s} ", " ");
			} else {
				xo_emit("{P:/%-22s} ", " ");
			}
		}

		if (xr != NULL && !Lflag) {
			sctp_print_address("remote", &(xr->xraddr->address),
			    htons(xstcb->remote_port), numeric_port);
		}

		if (xl != NULL)
			xl = LIST_NEXT(xl, xladdr_entries);
		if (xr != NULL)
			xr = LIST_NEXT(xr, xraddr_entries);

		if (i == 0 && !Lflag)
			sctp_statesprint(xstcb->state);

		if (i < x_max)
			xo_emit("\n");
		xo_close_instance("address");
	}

out:
	/*
	 * Free the list which be used to handle the address.
	 */
	xl = LIST_FIRST(&xladdr_head);
	while (xl != NULL) {
		xl_tmp = LIST_NEXT(xl, xladdr_entries);
		free(xl);
		xl = xl_tmp;
	}

	xr = LIST_FIRST(&xraddr_head);
	while (xr != NULL) {
		xr_tmp = LIST_NEXT(xr, xraddr_entries);
		free(xr);
		xr = xr_tmp;
	}
}
Esempio n. 10
0
static void
p_rtable_sysctl(int fibnum, int af)
{
	size_t needed;
	int mib[7];
	char *buf, *next, *lim;
	struct rt_msghdr *rtm;
	struct sockaddr *sa;
	int fam = AF_UNSPEC, ifindex = 0, size;
	int need_table_close = false;

	struct ifaddrs *ifap, *ifa;
	struct sockaddr_dl *sdl;

	/*
	 * Retrieve interface list at first
	 * since we need #ifindex -> if_xname match
	 */
	if (getifaddrs(&ifap) != 0)
		err(EX_OSERR, "getifaddrs");

	for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
		
		if (ifa->ifa_addr->sa_family != AF_LINK)
			continue;

		sdl = (struct sockaddr_dl *)ifa->ifa_addr;
		ifindex = sdl->sdl_index;

		if (ifindex >= ifmap_size) {
			size = roundup(ifindex + 1, 32) *
			    sizeof(struct ifmap_entry);
			if ((ifmap = realloc(ifmap, size)) == NULL)
				errx(2, "realloc(%d) failed", size);
			memset(&ifmap[ifmap_size], 0,
			    size - ifmap_size *
			    sizeof(struct ifmap_entry));

			ifmap_size = roundup(ifindex + 1, 32);
		}

		if (*ifmap[ifindex].ifname != '\0')
			continue;

		strlcpy(ifmap[ifindex].ifname, ifa->ifa_name, IFNAMSIZ);
	}

	freeifaddrs(ifap);

	mib[0] = CTL_NET;
	mib[1] = PF_ROUTE;
	mib[2] = 0;
	mib[3] = af;
	mib[4] = NET_RT_DUMP;
	mib[5] = 0;
	mib[6] = fibnum;
	if (sysctl(mib, nitems(mib), NULL, &needed, NULL, 0) < 0)
		err(EX_OSERR, "sysctl: net.route.0.%d.dump.%d estimate", af,
		    fibnum);
	if ((buf = malloc(needed)) == NULL)
		errx(2, "malloc(%lu)", (unsigned long)needed);
	if (sysctl(mib, nitems(mib), buf, &needed, NULL, 0) < 0)
		err(1, "sysctl: net.route.0.%d.dump.%d", af, fibnum);
	lim  = buf + needed;
	xo_open_container("route-table");
	xo_open_list("rt-family");
	for (next = buf; next < lim; next += rtm->rtm_msglen) {
		rtm = (struct rt_msghdr *)next;
		if (rtm->rtm_version != RTM_VERSION)
			continue;
		/*
		 * Peek inside header to determine AF
		 */
		sa = (struct sockaddr *)(rtm + 1);
		/* Only print family first time. */
		if (fam != sa->sa_family) {
			if (need_table_close) {
				xo_close_list("rt-entry");
				xo_close_instance("rt-family");
			}
			need_table_close = true;

			fam = sa->sa_family;
			wid_dst = WID_DST_DEFAULT(fam);
			wid_gw = WID_GW_DEFAULT(fam);
			wid_flags = 6;
			wid_pksent = 8;
			wid_mtu = 6;
			wid_if = WID_IF_DEFAULT(fam);
			wid_expire = 6;
			xo_open_instance("rt-family");
			pr_family(fam);
			xo_open_list("rt-entry");

			pr_rthdr(fam);
		}
		p_rtentry_sysctl("rt-entry", rtm);
	}
	if (need_table_close) {
		xo_close_list("rt-entry");
		xo_close_instance("rt-family");
	}
	xo_close_list("rt-family");
	xo_close_container("route-table");
	free(buf);
}
Esempio n. 11
0
int
main(int argc, char *argv[])
{
	struct kinfo_proc *kp;
	struct kinfo_proc *dkp;
	struct stat *stp;
	time_t touched;
	int ch, i, nentries, nusers, wcmd, longidle, longattime;
	const char *memf, *nlistf, *p, *save_p;
	char *x_suffix;
	char buf[MAXHOSTNAMELEN], errbuf[_POSIX2_LINE_MAX];
	char fn[MAXHOSTNAMELEN];
	char *dot;

	(void)setlocale(LC_ALL, "");
	use_ampm = (*nl_langinfo(T_FMT_AMPM) != '\0');
	use_comma = (*nl_langinfo(RADIXCHAR) != ',');

	argc = xo_parse_args(argc, argv);
	if (argc < 0)
		exit(1);

	/* Are we w(1) or uptime(1)? */
	if (strcmp(basename(argv[0]), "uptime") == 0) {
		wcmd = 0;
		p = "";
	} else {
		wcmd = 1;
		p = "dhiflM:N:nsuw";
	}

	memf = _PATH_DEVNULL;
	nlistf = NULL;
	while ((ch = getopt(argc, argv, p)) != -1)
		switch (ch) {
		case 'd':
			dflag = 1;
			break;
		case 'h':
			header = 0;
			break;
		case 'i':
			sortidle = 1;
			break;
		case 'M':
			header = 0;
			memf = optarg;
			break;
		case 'N':
			nlistf = optarg;
			break;
		case 'n':
			nflag = 1;
			break;
		case 'f': case 'l': case 's': case 'u': case 'w':
			warnx("[-flsuw] no longer supported");
			/* FALLTHROUGH */
		case '?':
		default:
			usage(wcmd);
		}
	argc -= optind;
	argv += optind;

	if (!(_res.options & RES_INIT))
		res_init();
	_res.retrans = 2;	/* resolver timeout to 2 seconds per try */
	_res.retry = 1;		/* only try once.. */

	if ((kd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, errbuf)) == NULL)
		errx(1, "%s", errbuf);

	(void)time(&now);

	if (*argv)
		sel_users = argv;

	setutxent();
	for (nusers = 0; (utmp = getutxent()) != NULL;) {
		if (utmp->ut_type != USER_PROCESS)
			continue;
		if (!(stp = ttystat(utmp->ut_line)))
			continue;	/* corrupted record */
		++nusers;
		if (wcmd == 0)
			continue;
		if (sel_users) {
			int usermatch;
			char **user;

			usermatch = 0;
			for (user = sel_users; !usermatch && *user; user++)
				if (!strcmp(utmp->ut_user, *user))
					usermatch = 1;
			if (!usermatch)
				continue;
		}
		if ((ep = calloc(1, sizeof(struct entry))) == NULL)
			errx(1, "calloc");
		*nextp = ep;
		nextp = &ep->next;
		memmove(&ep->utmp, utmp, sizeof *utmp);
		ep->tdev = stp->st_rdev;
		/*
		 * If this is the console device, attempt to ascertain
		 * the true console device dev_t.
		 */
		if (ep->tdev == 0) {
			size_t size;

			size = sizeof(dev_t);
			(void)sysctlbyname("machdep.consdev", &ep->tdev, &size, NULL, 0);
		}
		touched = stp->st_atime;
		if (touched < ep->utmp.ut_tv.tv_sec) {
			/* tty untouched since before login */
			touched = ep->utmp.ut_tv.tv_sec;
		}
		if ((ep->idle = now - touched) < 0)
			ep->idle = 0;
	}
	endutxent();

	xo_open_container("uptime-information");

	if (header || wcmd == 0) {
		pr_header(&now, nusers);
		if (wcmd == 0) {
			xo_close_container("uptime-information");
			xo_finish();

			(void)kvm_close(kd);
			exit(0);
		}

#define HEADER_USER		"USER"
#define HEADER_TTY		"TTY"
#define HEADER_FROM		"FROM"
#define HEADER_LOGIN_IDLE	"LOGIN@  IDLE "
#define HEADER_WHAT		"WHAT\n"
#define WUSED  (W_DISPUSERSIZE + W_DISPLINESIZE + W_DISPHOSTSIZE + \
		sizeof(HEADER_LOGIN_IDLE) + 3)	/* header width incl. spaces */ 
		xo_emit("{T:/%-*.*s} {T:/%-*.*s} {T:/%-*.*s}  {T:/%s}", 
				W_DISPUSERSIZE, W_DISPUSERSIZE, HEADER_USER,
				W_DISPLINESIZE, W_DISPLINESIZE, HEADER_TTY,
				W_DISPHOSTSIZE, W_DISPHOSTSIZE, HEADER_FROM,
				HEADER_LOGIN_IDLE HEADER_WHAT);
	}

	if ((kp = kvm_getprocs(kd, KERN_PROC_ALL, 0, &nentries)) == NULL)
		err(1, "%s", kvm_geterr(kd));
	for (i = 0; i < nentries; i++, kp++) {
		if (kp->ki_stat == SIDL || kp->ki_stat == SZOMB ||
		    kp->ki_tdev == NODEV)
			continue;
		for (ep = ehead; ep != NULL; ep = ep->next) {
			if (ep->tdev == kp->ki_tdev) {
				/*
				 * proc is associated with this terminal
				 */
				if (ep->kp == NULL && kp->ki_pgid == kp->ki_tpgid) {
					/*
					 * Proc is 'most interesting'
					 */
					if (proc_compare(ep->kp, kp))
						ep->kp = kp;
				}
				/*
				 * Proc debug option info; add to debug
				 * list using kinfo_proc ki_spare[0]
				 * as next pointer; ptr to ptr avoids the
				 * ptr = long assumption.
				 */
				dkp = ep->dkp;
				ep->dkp = kp;
				debugproc(kp) = dkp;
			}
		}
	}
	if ((ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == -1 &&
	     ioctl(STDERR_FILENO, TIOCGWINSZ, &ws) == -1 &&
	     ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) == -1) || ws.ws_col == 0)
	       ttywidth = 79;
        else
	       ttywidth = ws.ws_col - 1;
	argwidth = ttywidth - WUSED;
	if (argwidth < 4)
		argwidth = 8;
	for (ep = ehead; ep != NULL; ep = ep->next) {
		if (ep->kp == NULL) {
			ep->args = strdup("-");
			continue;
		}
		ep->args = fmt_argv(kvm_getargv(kd, ep->kp, argwidth),
		    ep->kp->ki_comm, NULL, MAXCOMLEN);
		if (ep->args == NULL)
			err(1, NULL);
	}
	/* sort by idle time */
	if (sortidle && ehead != NULL) {
		struct entry *from, *save;

		from = ehead;
		ehead = NULL;
		while (from != NULL) {
			for (nextp = &ehead;
			    (*nextp) && from->idle >= (*nextp)->idle;
			    nextp = &(*nextp)->next)
				continue;
			save = from;
			from = from->next;
			save->next = *nextp;
			*nextp = save;
		}
	}

	xo_open_container("user-table");
	xo_open_list("user-entry");

	for (ep = ehead; ep != NULL; ep = ep->next) {
		struct addrinfo hints, *res;
		struct sockaddr_storage ss;
		struct sockaddr *sa = (struct sockaddr *)&ss;
		struct sockaddr_in *lsin = (struct sockaddr_in *)&ss;
		struct sockaddr_in6 *lsin6 = (struct sockaddr_in6 *)&ss;
		time_t t;
		int isaddr;

		xo_open_instance("user-entry");

		save_p = p = *ep->utmp.ut_host ? ep->utmp.ut_host : "-";
		if ((x_suffix = strrchr(p, ':')) != NULL) {
			if ((dot = strchr(x_suffix, '.')) != NULL &&
			    strchr(dot+1, '.') == NULL)
				*x_suffix++ = '\0';
			else
				x_suffix = NULL;
		}

		isaddr = 0;
		memset(&ss, '\0', sizeof(ss));
		if (inet_pton(AF_INET6, p, &lsin6->sin6_addr) == 1) {
			lsin6->sin6_len = sizeof(*lsin6);
			lsin6->sin6_family = AF_INET6;
			isaddr = 1;
		} else if (inet_pton(AF_INET, p, &lsin->sin_addr) == 1) {
			lsin->sin_len = sizeof(*lsin);
			lsin->sin_family = AF_INET;
			isaddr = 1;
		}
		if (!nflag) {
			/* Attempt to change an IP address into a name */
			if (isaddr && realhostname_sa(fn, sizeof(fn), sa,
			    sa->sa_len) == HOSTNAME_FOUND)
				p = fn;
		} else if (!isaddr) {
			/*
			 * If a host has only one A/AAAA RR, change a
			 * name into an IP address
			 */
			memset(&hints, 0, sizeof(hints));
			hints.ai_flags = AI_PASSIVE;
			hints.ai_family = AF_UNSPEC;
			hints.ai_socktype = SOCK_STREAM;
			if (getaddrinfo(p, NULL, &hints, &res) == 0) {
				if (res->ai_next == NULL &&
				    getnameinfo(res->ai_addr, res->ai_addrlen,
					fn, sizeof(fn), NULL, 0,
					NI_NUMERICHOST) == 0)
					p = fn;
				freeaddrinfo(res);
			}
		}

		if (x_suffix) {
			(void)snprintf(buf, sizeof(buf), "%s:%s", p, x_suffix);
			p = buf;
		}
		if (dflag) {
		        xo_open_container("process-table");
		        xo_open_list("process-entry");

			for (dkp = ep->dkp; dkp != NULL; dkp = debugproc(dkp)) {
				const char *ptr;

				ptr = fmt_argv(kvm_getargv(kd, dkp, argwidth),
				    dkp->ki_comm, NULL, MAXCOMLEN);
				if (ptr == NULL)
					ptr = "-";
				xo_open_instance("process-entry");
				xo_emit("\t\t{:process-id/%-9d/%d} {:command/%s}\n",
				    dkp->ki_pid, ptr);
				xo_close_instance("process-entry");
			}
		        xo_close_list("process-entry");
		        xo_close_container("process-table");
		}
		xo_emit("{:user/%-*.*s/%@**@s} {:tty/%-*.*s/%@**@s} ",
			W_DISPUSERSIZE, W_DISPUSERSIZE, ep->utmp.ut_user,
			W_DISPLINESIZE, W_DISPLINESIZE,
			*ep->utmp.ut_line ?
			(strncmp(ep->utmp.ut_line, "tty", 3) &&
			 strncmp(ep->utmp.ut_line, "cua", 3) ?
			 ep->utmp.ut_line : ep->utmp.ut_line + 3) : "-");

		if (save_p && save_p != p)
		    xo_attr("address", "%s", save_p);
		xo_emit("{:from/%-*.*s/%@**@s} ",
		    W_DISPHOSTSIZE, W_DISPHOSTSIZE, *p ? p : "-");
		t = ep->utmp.ut_tv.tv_sec;
		longattime = pr_attime(&t, &now);
		longidle = pr_idle(ep->idle);
		xo_emit("{:command/%.*s/%@*@s}\n",
		    argwidth - longidle - longattime,
		    ep->args);

		xo_close_instance("user-entry");
	}

	xo_close_list("user-entry");
	xo_close_container("user-table");
	xo_close_container("uptime-information");
	xo_finish();

	(void)kvm_close(kd);
	exit(0);
}
Esempio n. 12
0
int
main (int argc, char **argv)
{
    static char base_grocery[] = "GRO";
    static char base_hardware[] = "HRD";
    struct item {
	const char *i_title;
	int i_sold;
	int i_instock;
	int i_onorder;
	const char *i_sku_base;
	int i_sku_num;
    };
    struct item list[] = {
	{ "gum", 1412, 54, 10, base_grocery, 415 },
	{ "rope", 85, 4, 2, base_hardware, 212 },
	{ "ladder", 0, 2, 1, base_hardware, 517 },
	{ "bolt", 4123, 144, 42, base_hardware, 632 },
	{ "water", 17, 14, 2, base_grocery, 2331 },
	{ NULL, 0, 0, 0, NULL, 0 }
    };
    struct item list2[] = {
	{ "fish", 1321, 45, 1, base_grocery, 533 },
	{ NULL, 0, 0, 0, NULL, 0 }
    };
    struct item *ip;
    xo_info_t info[] = {
	{ "in-stock", "number", "Number of items in stock" },
	{ "name", "string", "Name of the item" },
	{ "on-order", "number", "Number of items on order" },
	{ "sku", "string", "Stock Keeping Unit" },
	{ "sold", "number", "Number of items sold" },
	{ NULL, NULL, NULL },
    };
    int info_count = (sizeof(info) / sizeof(info[0])) - 1;
    
    argc = xo_parse_args(argc, argv);
    if (argc < 0)
	return 1;

    for (argc = 1; argv[argc]; argc++) {
	if (strcmp(argv[argc], "xml") == 0)
	    xo_set_style(NULL, XO_STYLE_XML);
	else if (strcmp(argv[argc], "json") == 0)
	    xo_set_style(NULL, XO_STYLE_JSON);
	else if (strcmp(argv[argc], "text") == 0)
	    xo_set_style(NULL, XO_STYLE_TEXT);
	else if (strcmp(argv[argc], "html") == 0)
	    xo_set_style(NULL, XO_STYLE_HTML);
	else if (strcmp(argv[argc], "pretty") == 0)
	    xo_set_flags(NULL, XOF_PRETTY);
	else if (strcmp(argv[argc], "xpath") == 0)
	    xo_set_flags(NULL, XOF_XPATH);
	else if (strcmp(argv[argc], "info") == 0)
	    xo_set_flags(NULL, XOF_INFO);
        else if (strcmp(argv[argc], "error") == 0) {
            close(-1);
            xo_err(1, "error detected");
        }
    }

    xo_set_info(NULL, info, info_count);
    xo_set_flags(NULL, XOF_KEYS);

    xo_open_container_h(NULL, "top");

    xo_attr("test", "value");
    xo_open_container("data");
    xo_open_list("item");
    xo_attr("test2", "value2");

    xo_emit("{T:Item/%-10s}{T:Total Sold/%12s}{T:In Stock/%12s}"
	    "{T:On Order/%12s}{T:SKU/%5s}\n");

    for (ip = list; ip->i_title; ip++) {
	xo_open_instance("item");
	xo_attr("test3", "value3");

	xo_emit("{keq:sku/%s-%u/%s-000-%u}"
		"{k:name/%-10s/%s}{n:sold/%12u/%u}{:in-stock/%12u/%u}"
		"{:on-order/%12u/%u}{qkd:sku/%5s-000-%u/%s-000-%u}\n",
		ip->i_sku_base, ip->i_sku_num,
		ip->i_title, ip->i_sold, ip->i_instock, ip->i_onorder,
		ip->i_sku_base, ip->i_sku_num);

	xo_close_instance("item");
    }

    xo_close_list("item");
    xo_close_container("data");

    xo_emit("\n\n");

    xo_open_container("data");
    xo_open_list("item");

    for (ip = list; ip->i_title; ip++) {
	xo_open_instance("item");

	xo_emit("{keq:sku/%s-%u/%s-000-%u}", ip->i_sku_base, ip->i_sku_num);
	xo_emit("{L:Item} '{k:name/%s}':\n", ip->i_title);
	xo_emit("{P:   }{L:Total sold}: {n:sold/%u%s}\n",
		ip->i_sold, ip->i_sold ? ".0" : "");
	xo_emit("{P:   }{Lcw:In stock}{:in-stock/%u}\n", ip->i_instock);
	xo_emit("{P:   }{Lcw:On order}{:on-order/%u}\n", ip->i_onorder);
	xo_emit("{P:   }{L:SKU}: {qkd:sku/%s-000-%u}\n",
		ip->i_sku_base, ip->i_sku_num);

	xo_close_instance("item");
    }

    xo_close_list("item");
    xo_close_container("data");

    xo_open_container("data");
    xo_open_list("item");

    for (ip = list2; ip->i_title; ip++) {
	xo_open_instance("item");

	xo_emit("{keq:sku/%s-%u/%s-000-%u}", ip->i_sku_base, ip->i_sku_num);
	xo_emit("{L:Item} '{k:name/%s}':\n", ip->i_title);
	xo_emit("{P:   }{L:Total sold}: {n:sold/%u%s}\n",
		ip->i_sold, ip->i_sold ? ".0" : "");
	xo_emit("{P:   }{Lcw:In stock}{:in-stock/%u}\n", ip->i_instock);
	xo_emit("{P:   }{Lcw:On order}{:on-order/%u}\n", ip->i_onorder);
	xo_emit("{P:   }{L:SKU}: {qkd:sku/%s-000-%u}\n",
		ip->i_sku_base, ip->i_sku_num);

	xo_close_instance("item");
    }

    xo_close_list("item");
    xo_close_container("data");

    xo_open_container("data");
    xo_open_list("item");

    for (ip = list; ip->i_title; ip++) {
	xo_attr("test4", "value4");
	xo_emit("{Lwc:Item}{l:item}\n", ip->i_title);
    }

    xo_close_list("item");
    xo_close_container("data");

    xo_emit("X{P:}X", "epic fail");
    xo_emit("X{T:}X", "epic fail");
    xo_emit("X{N:}X", "epic fail");
    xo_emit("X{L:}X\n", "epic fail");

    xo_emit("X{P:        }X{Lwc:Cost}{:cost/%u}\n", 425);
    xo_emit("X{P:/%30s}X{Lwc:Cost}{:cost/%u}\n", "", 455);

    xo_close_container_h(NULL, "top");

    xo_finish();

    return 0;
}
Esempio n. 13
0
/*
 * Traverse() walks the logical directory structure specified by the argv list
 * in the order specified by the mastercmp() comparison function.  During the
 * traversal it passes linked lists of structures to display() which represent
 * a superset (may be exact set) of the files to be displayed.
 */
static void
traverse(int argc, char *argv[], int options)
{
	FTS *ftsp;
	FTSENT *p, *chp;
	int ch_options;
	int first = 1;

	if ((ftsp =
	    fts_open(argv, options, f_nosort ? NULL : mastercmp)) == NULL)
		xo_err(1, "fts_open");

	/*
	 * We ignore errors from fts_children here since they will be
	 * replicated and signalled on the next call to fts_read() below.
	 */
	chp = fts_children(ftsp, 0);
	if (chp != NULL)
		display(NULL, chp, options);
	if (f_listdir)
		return;

	/*
	 * If not recursing down this tree and don't need stat info, just get
	 * the names.
	 */
	ch_options = !f_recursive && !f_label &&
	    options & FTS_NOSTAT ? FTS_NAMEONLY : 0;

	while ((p = fts_read(ftsp)) != NULL)
		switch (p->fts_info) {
		case FTS_DC:
			xo_warnx("%s: directory causes a cycle", p->fts_name);
			break;
		case FTS_DNR:
		case FTS_ERR:
			xo_warnx("%s: %s", p->fts_path, strerror(p->fts_errno));
			rval = 1;
			break;
		case FTS_D:
			if (p->fts_level != FTS_ROOTLEVEL &&
			    p->fts_name[0] == '.' && !f_listdot)
				break;

			if (first) {
				first = 0;
				xo_open_list("directory");
			}
			xo_open_instance("directory");

			/*
			 * If already output something, put out a newline as
			 * a separator.  If multiple arguments, precede each
			 * directory with its name.
			 */
			if (output) {
				xo_emit("\n");
				(void)printname("path", p->fts_path);
				xo_emit(":\n");
			} else if (argc > 1) {
				(void)printname("path", p->fts_path);
				xo_emit(":\n");
				output = 1;
			}
			chp = fts_children(ftsp, ch_options);
			display(p, chp, options);

			xo_close_instance("directory");
			if (!f_recursive && chp != NULL)
				(void)fts_set(ftsp, p, FTS_SKIP);
			break;
		default:
			break;
		}
	if (!first)
		xo_close_list("directory");
	if (errno)
		xo_err(1, "fts_read");
}
Esempio n. 14
0
void
bpf_stats(char *ifname)
{
	struct xbpf_d *d, *bd, zerostat;
	char *pname, flagbuf[12];
	size_t size;

	if (zflag) {
		bzero(&zerostat, sizeof(zerostat));
		if (sysctlbyname("net.bpf.stats", NULL, NULL,
		    &zerostat, sizeof(zerostat)) < 0)
			xo_warn("failed to zero bpf counters");
		return;
	}
	if (sysctlbyname("net.bpf.stats", NULL, &size,
	    NULL, 0) < 0) {
		xo_warn("net.bpf.stats");
		return;
	}
	if (size == 0)
		return;
	bd = malloc(size);
	if (bd == NULL) {
		xo_warn("malloc failed");
		return;
	}
	if (sysctlbyname("net.bpf.stats", bd, &size,
	    NULL, 0) < 0) {
		xo_warn("net.bpf.stats");
		free(bd);
		return;
	}
	xo_emit("{T:/%5s} {T:/%6s} {T:/%7s} {T:/%9s} {T:/%9s} {T:/%9s} "
	    "{T:/%5s} {T:/%5s} {T:/%s}\n",
	    "Pid", "Netif", "Flags", "Recv", "Drop", "Match",
	    "Sblen", "Hblen", "Command");
	xo_open_container("bpf-statistics");
	xo_open_list("bpf-entry");
	for (d = &bd[0]; d < &bd[size / sizeof(*d)]; d++) {
		if (d->bd_structsize != sizeof(*d)) {
			xo_warnx("bpf_stats_extended: version mismatch");
			return;
		}
		if (ifname && strcmp(ifname, d->bd_ifname) != 0)
			continue;
		xo_open_instance("bpf-entry");
		pname = bpf_pidname(d->bd_pid);
		xo_emit("{k:pid/%5d} {k:interface-name/%6s} ",
		    d->bd_pid, d->bd_ifname);
		bpf_flags(d, flagbuf);
		xo_emit("{d:flags/%7s} {:received-packets/%9ju} "
		    "{:dropped-packets/%9ju} {:filter-packets/%9ju} "
		    "{:store-buffer-length/%5d} {:hold-buffer-length/%5d} "
		    "{:process/%s}\n",
		    flagbuf, (uintmax_t)d->bd_rcount, (uintmax_t)d->bd_dcount,
		    (uintmax_t)d->bd_fcount, d->bd_slen, d->bd_hlen, pname);
		free(pname);
		xo_close_instance("bpf-entry");
	}
	xo_close_list("bpf-entry");
	xo_close_container("bpf-statistics");
	free(bd);
}
Esempio n. 15
0
static void
sctp_process_inpcb(struct xsctp_inpcb *xinpcb,
    char *buf, const size_t buflen, size_t *offset)
{
	int indent = 0, xladdr_total = 0, is_listening = 0;
	static int first = 1;
	const char *tname, *pname;
	struct xsctp_tcb *xstcb;
	struct xsctp_laddr *xladdr;
	size_t offset_laddr;
	int process_closed;

	if (xinpcb->maxqlen > 0)
		is_listening = 1;

	if (first) {
		if (!Lflag) {
			xo_emit("Active SCTP associations");
			if (aflag)
				xo_emit(" (including servers)");
		} else
			xo_emit("Current listen queue sizes (qlen/maxqlen)");
		xo_emit("\n");
		if (Lflag)
			xo_emit("{T:/%-6.6s} {T:/%-5.5s} {T:/%-8.8s} "
			    "{T:/%-22.22s}\n",
			    "Proto", "Type", "Listen", "Local Address");
		else
			if (Wflag)
				xo_emit("{T:/%-6.6s} {T:/%-5.5s} {T:/%-45.45s} "
				    "{T:/%-45.45s} {T:/%s}\n",
				    "Proto", "Type",
				    "Local Address", "Foreign Address",
				    "(state)");
			else
				xo_emit("{T:/%-6.6s} {T:/%-5.5s} {T:/%-22.22s} "
				    "{T:/%-22.22s} {T:/%s}\n",
				    "Proto", "Type",
				    "Local Address", "Foreign Address",
				    "(state)");
		first = 0;
	}
	xladdr = (struct xsctp_laddr *)(buf + *offset);
	if (Lflag && !is_listening) {
		sctp_skip_xinpcb_ifneed(buf, buflen, offset);
		return;
	}

	if (xinpcb->flags & SCTP_PCB_FLAGS_BOUND_V6) {
		/* Can't distinguish between sctp46 and sctp6 */
		pname = "sctp46";
	} else {
		pname = "sctp4";
	}

	if (xinpcb->flags & SCTP_PCB_FLAGS_TCPTYPE)
		tname = "1to1";
	else if (xinpcb->flags & SCTP_PCB_FLAGS_UDPTYPE)
		tname = "1toN";
	else
		tname = "????";

	if (Lflag) {
		char buf1[22];

		snprintf(buf1, sizeof buf1, "%u/%u", 
		    xinpcb->qlen, xinpcb->maxqlen);
		xo_emit("{:protocol/%-6.6s/%s} {:type/%-5.5s/%s} ",
		    pname, tname);
		xo_emit("{d:queues/%-8.8s}{e:queue-len/%hu}"
		    "{e:max-queue-len/%hu} ",
		    buf1, xinpcb->qlen, xinpcb->maxqlen);
	}

	offset_laddr = *offset;
	process_closed = 0;

	xo_open_list("local-address");
retry:
	while (*offset < buflen) {
		xladdr = (struct xsctp_laddr *)(buf + *offset);
		*offset += sizeof(struct xsctp_laddr);
		if (xladdr->last) {
			if (aflag && !Lflag && (xladdr_total == 0) && process_closed) {
				xo_open_instance("local-address");

				xo_emit("{:protocol/%-6.6s/%s} "
				    "{:type/%-5.5s/%s} ", pname, tname);
				if (Wflag) {
					xo_emit("{P:/%-91.91s/%s} "
					    "{:state/CLOSED}", " ");
				} else {
					xo_emit("{P:/%-45.45s/%s} "
					    "{:state/CLOSED}", " ");
				}
				xo_close_instance("local-address");
			}
			if (process_closed || is_listening) {
				xo_emit("\n");
			}
			break;
		}

		if (!Lflag && !is_listening && !process_closed)
			continue;

		xo_open_instance("local-address");

		if (xladdr_total == 0) {
			xo_emit("{:protocol/%-6.6s/%s} {:type/%-5.5s/%s} ",
			    pname, tname);
		} else {
			xo_emit("\n");
			xo_emit(Lflag ? "{P:/%-21.21s} " : "{P:/%-12.12s} ",
			    " ");
		}
		sctp_print_address("local", &(xladdr->address),
		    htons(xinpcb->local_port), numeric_port);
		if (aflag && !Lflag && xladdr_total == 0) {
			if (Wflag) {
				if (process_closed) {
					xo_emit("{P:/%-45.45s} "
					    "{:state/CLOSED}", " ");
				} else {
					xo_emit("{P:/%-45.45s} "
					    "{:state:LISTEN}", " ");
				}
			} else {
				if (process_closed) {
					xo_emit("{P:/%-22.22s} "
					    "{:state/CLOSED}", " ");
				} else {
					xo_emit("{P:/%-22.22s} "
					    "{:state/LISTEN}", " ");
				}
			}
		}
		xladdr_total++;
		xo_close_instance("local-address");
	}

	xstcb = (struct xsctp_tcb *)(buf + *offset);
	*offset += sizeof(struct xsctp_tcb);
	if (aflag && (xladdr_total == 0) && xstcb->last && !process_closed) {
		process_closed = 1;
		*offset = offset_laddr;
		goto retry;
	}
	while (xstcb->last == 0 && *offset < buflen) {
		xo_emit("{:protocol/%-6.6s/%s} {:type/%-5.5s/%s} ",
		    pname, tname);
		sctp_process_tcb(xstcb, buf, buflen, offset, &indent);
		indent++;
		xstcb = (struct xsctp_tcb *)(buf + *offset);
		*offset += sizeof(struct xsctp_tcb);
	}

	xo_close_list("local-address");
}
Esempio n. 16
0
/*
 * Print a summary of connections related to an Internet
 * protocol.  For TCP, also give state of connection.
 * Listening processes (aflag) are suppressed unless the
 * -a (all) flag is specified.
 */
void
protopr(u_long off, const char *name, int af1, int proto)
{
	static int first = 1;
	int istcp;
	char *buf;
	const char *vchar;
	struct xtcpcb *tp;
	struct xinpcb *inp;
	struct xinpgen *xig, *oxig;
	struct xsocket *so;

	istcp = 0;
	switch (proto) {
	case IPPROTO_TCP:
#ifdef INET6
		if (strncmp(name, "sdp", 3) != 0) {
			if (tcp_done != 0)
				return;
			else
				tcp_done = 1;
		} else {
			if (sdp_done != 0)
				return;
			else
				sdp_done = 1;
		}
#endif
		istcp = 1;
		break;
	case IPPROTO_UDP:
#ifdef INET6
		if (udp_done != 0)
			return;
		else
			udp_done = 1;
#endif
		break;
	}

	if (!pcblist_sysctl(proto, name, &buf))
		return;

	oxig = xig = (struct xinpgen *)buf;
	for (xig = (struct xinpgen *)((char *)xig + xig->xig_len);
	    xig->xig_len > sizeof(struct xinpgen);
	    xig = (struct xinpgen *)((char *)xig + xig->xig_len)) {
		if (istcp) {
			tp = (struct xtcpcb *)xig;
			inp = &tp->xt_inp;
		} else {
			inp = (struct xinpcb *)xig;
		}
		so = &inp->xi_socket;

		/* Ignore sockets for protocols other than the desired one. */
		if (so->xso_protocol != proto)
			continue;

		/* Ignore PCBs which were freed during copyout. */
		if (inp->inp_gencnt > oxig->xig_gen)
			continue;

		if ((af1 == AF_INET && (inp->inp_vflag & INP_IPV4) == 0)
#ifdef INET6
		    || (af1 == AF_INET6 && (inp->inp_vflag & INP_IPV6) == 0)
#endif /* INET6 */
		    || (af1 == AF_UNSPEC && ((inp->inp_vflag & INP_IPV4) == 0
#ifdef INET6
					  && (inp->inp_vflag & INP_IPV6) == 0
#endif /* INET6 */
			))
		    )
			continue;
		if (!aflag &&
		    (
		     (istcp && tp->t_state == TCPS_LISTEN)
		     || (af1 == AF_INET &&
		      inet_lnaof(inp->inp_laddr) == INADDR_ANY)
#ifdef INET6
		     || (af1 == AF_INET6 &&
			 IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr))
#endif /* INET6 */
		     || (af1 == AF_UNSPEC &&
			 (((inp->inp_vflag & INP_IPV4) != 0 &&
			   inet_lnaof(inp->inp_laddr) == INADDR_ANY)
#ifdef INET6
			  || ((inp->inp_vflag & INP_IPV6) != 0 &&
			      IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr))
#endif
			  ))
		     ))
			continue;

		if (first) {
			if (!Lflag) {
				xo_emit("Active Internet connections");
				if (aflag)
					xo_emit(" (including servers)");
			} else
				xo_emit(
	"Current listen queue sizes (qlen/incqlen/maxqlen)");
			xo_emit("\n");
			if (Aflag)
				xo_emit("{T:/%-*s} ", 2 * (int)sizeof(void *),
				    "Tcpcb");
			if (Lflag)
				xo_emit((Aflag && !Wflag) ?
				    "{T:/%-5.5s} {T:/%-32.32s} {T:/%-18.18s}" :
				    ((!Wflag || af1 == AF_INET) ?
				    "{T:/%-5.5s} {T:/%-32.32s} {T:/%-22.22s}" :
				    "{T:/%-5.5s} {T:/%-32.32s} {T:/%-45.45s}"),
				    "Proto", "Listen", "Local Address");
			else if (Tflag)
				xo_emit((Aflag && !Wflag) ?
    "{T:/%-5.5s} {T:/%-6.6s} {T:/%-6.6s} {T:/%-6.6s} {T:/%-18.18s} {T:/%s}" :
				    ((!Wflag || af1 == AF_INET) ?
    "{T:/%-5.5s} {T:/%-6.6s} {T:/%-6.6s} {T:/%-6.6s} {T:/%-22.22s} {T:/%s}" :
    "{T:/%-5.5s} {T:/%-6.6s} {T:/%-6.6s} {T:/%-6.6s} {T:/%-45.45s} {T:/%s}"),
				    "Proto", "Rexmit", "OOORcv", "0-win",
				    "Local Address", "Foreign Address");
			else {
				xo_emit((Aflag && !Wflag) ?
    "{T:/%-5.5s} {T:/%-6.6s} {T:/%-6.6s} {T:/%-18.18s} {T:/%-18.18s}" :
				    ((!Wflag || af1 == AF_INET) ?
    "{T:/%-5.5s} {T:/%-6.6s} {T:/%-6.6s} {T:/%-22.22s} {T:/%-22.22s}" :
    "{T:/%-5.5s} {T:/%-6.6s} {T:/%-6.6s} {T:/%-45.45s} {T:/%-45.45s}"),
				    "Proto", "Recv-Q", "Send-Q",
				    "Local Address", "Foreign Address");
				if (!xflag && !Rflag)
					xo_emit(" (state)");
			}
			if (xflag) {
				xo_emit(" {T:/%-6.6s} {T:/%-6.6s} {T:/%-6.6s} "
				    "{T:/%-6.6s} {T:/%-6.6s} {T:/%-6.6s} "
				    "{T:/%-6.6s} {T:/%-6.6s} {T:/%-6.6s} "
				    "{T:/%-6.6s} {T:/%-6.6s} {T:/%-6.6s}",
				    "R-MBUF", "S-MBUF", "R-CLUS", "S-CLUS",
				    "R-HIWA", "S-HIWA", "R-LOWA", "S-LOWA",
				    "R-BCNT", "S-BCNT", "R-BMAX", "S-BMAX");
				xo_emit(" {T:/%7.7s} {T:/%7.7s} {T:/%7.7s} "
				    "{T:/%7.7s} {T:/%7.7s} {T:/%7.7s}",
				    "rexmt", "persist", "keep", "2msl",
				    "delack", "rcvtime");
			} else if (Rflag) {
				xo_emit("  {T:/%8.8s} {T:/%5.5s}",
				    "flowid", "ftype");
			}
			xo_emit("\n");
			first = 0;
		}
		if (Lflag && so->so_qlimit == 0)
			continue;
		xo_open_instance("socket");
		if (Aflag) {
			if (istcp)
				xo_emit("{q:address/%*lx} ",
				    2 * (int)sizeof(void *),
				    (u_long)inp->inp_ppcb);
			else
				xo_emit("{q:address/%*lx} ",
				    2 * (int)sizeof(void *),
				    (u_long)so->so_pcb);
		}
#ifdef INET6
		if ((inp->inp_vflag & INP_IPV6) != 0)
			vchar = ((inp->inp_vflag & INP_IPV4) != 0) ?
			    "46" : "6";
		else
#endif
		vchar = ((inp->inp_vflag & INP_IPV4) != 0) ?
		    "4" : "";
		if (istcp && (tp->t_flags & TF_TOE) != 0)
			xo_emit("{:protocol/%-3.3s%-2.2s/%s%s} ", "toe", vchar);
		else
			xo_emit("{:protocol/%-3.3s%-2.2s/%s%s} ", name, vchar);
		if (Lflag) {
			char buf1[33];

			snprintf(buf1, sizeof buf1, "%u/%u/%u", so->so_qlen,
			    so->so_incqlen, so->so_qlimit);
			xo_emit("{:listen-queue-sizes/%-32.32s} ", buf1);
		} else if (Tflag) {
			if (istcp)
				xo_emit("{:sent-retransmit-packets/%6u} "
				    "{:received-out-of-order-packets/%6u} "
				    "{:sent-zero-window/%6u} ",
				    tp->t_sndrexmitpack, tp->t_rcvoopack,
				    tp->t_sndzerowin);
			else
				xo_emit("{P:/%21s}", "");
		} else {
			xo_emit("{:receive-bytes-waiting/%6u} "
			    "{:send-bytes-waiting/%6u} ",
			    so->so_rcv.sb_cc, so->so_snd.sb_cc);
		}
		if (numeric_port) {
			if (inp->inp_vflag & INP_IPV4) {
				inetprint("local", &inp->inp_laddr,
				    (int)inp->inp_lport, name, 1, af1);
				if (!Lflag)
					inetprint("remote", &inp->inp_faddr,
					    (int)inp->inp_fport, name, 1, af1);
			}
#ifdef INET6
			else if (inp->inp_vflag & INP_IPV6) {
				inet6print("local", &inp->in6p_laddr,
				    (int)inp->inp_lport, name, 1);
				if (!Lflag)
					inet6print("remote", &inp->in6p_faddr,
					    (int)inp->inp_fport, name, 1);
			} /* else nothing printed now */
#endif /* INET6 */
		} else if (inp->inp_flags & INP_ANONPORT) {
			if (inp->inp_vflag & INP_IPV4) {
				inetprint("local", &inp->inp_laddr,
				    (int)inp->inp_lport, name, 1, af1);
				if (!Lflag)
					inetprint("remote", &inp->inp_faddr,
					    (int)inp->inp_fport, name, 0, af1);
			}
#ifdef INET6
			else if (inp->inp_vflag & INP_IPV6) {
				inet6print("local", &inp->in6p_laddr,
				    (int)inp->inp_lport, name, 1);
				if (!Lflag)
					inet6print("remote", &inp->in6p_faddr,
					    (int)inp->inp_fport, name, 0);
			} /* else nothing printed now */
#endif /* INET6 */
		} else {
			if (inp->inp_vflag & INP_IPV4) {
				inetprint("local", &inp->inp_laddr,
				    (int)inp->inp_lport, name, 0, af1);
				if (!Lflag)
					inetprint("remote", &inp->inp_faddr,
					    (int)inp->inp_fport, name,
					    inp->inp_lport != inp->inp_fport,
					    af1);
			}
#ifdef INET6
			else if (inp->inp_vflag & INP_IPV6) {
				inet6print("local", &inp->in6p_laddr,
				    (int)inp->inp_lport, name, 0);
				if (!Lflag)
					inet6print("remote", &inp->in6p_faddr,
					    (int)inp->inp_fport, name,
					    inp->inp_lport != inp->inp_fport);
			} /* else nothing printed now */
#endif /* INET6 */
		}
		if (xflag) {
			xo_emit("{:receive-mbufs/%6u} {:send-mbufs/%6u} "
			    "{:receive-clusters/%6u} {:send-clusters/%6u} "
			    "{:receive-high-water/%6u} {:send-high-water/%6u} "
			    "{:receive-low-water/%6u} {:send-low-water/%6u} "
			    "{:receive-mbuf-bytes/%6u} {:send-mbuf-bytes/%6u} "
			    "{:receive-mbuf-bytes-max/%6u} "
			    "{:send-mbuf-bytes-max/%6u}",
			    so->so_rcv.sb_mcnt, so->so_snd.sb_mcnt,
			    so->so_rcv.sb_ccnt, so->so_snd.sb_ccnt,
			    so->so_rcv.sb_hiwat, so->so_snd.sb_hiwat,
			    so->so_rcv.sb_lowat, so->so_snd.sb_lowat,
			    so->so_rcv.sb_mbcnt, so->so_snd.sb_mbcnt,
			    so->so_rcv.sb_mbmax, so->so_snd.sb_mbmax);
			if (istcp)
				xo_emit(" {:retransmit-timer/%4d.%02d} "
				    "{:persist-timer/%4d.%02d} "
				    "{:keepalive-timer/%4d.%02d} "
				    "{:msl2-timer/%4d.%02d} "
				    "{:delay-ack-timer/%4d.%02d} "
				    "{:inactivity-timer/%4d.%02d}",
				    tp->tt_rexmt / 1000,
				    (tp->tt_rexmt % 1000) / 10,
				    tp->tt_persist / 1000,
				    (tp->tt_persist % 1000) / 10,
				    tp->tt_keep / 1000,
				    (tp->tt_keep % 1000) / 10,
				    tp->tt_2msl / 1000,
				    (tp->tt_2msl % 1000) / 10,
				    tp->tt_delack / 1000,
				    (tp->tt_delack % 1000) / 10,
				    tp->t_rcvtime / 1000,
				    (tp->t_rcvtime % 1000) / 10);
		}
		if (istcp && !Lflag && !xflag && !Tflag && !Rflag) {
			if (tp->t_state < 0 || tp->t_state >= TCP_NSTATES)
				xo_emit("{:tcp-state/%d}", tp->t_state);
			else {
				xo_emit("{:tcp-state/%s}",
				    tcpstates[tp->t_state]);
#if defined(TF_NEEDSYN) && defined(TF_NEEDFIN)
				/* Show T/TCP `hidden state' */
				if (tp->t_flags & (TF_NEEDSYN|TF_NEEDFIN))
					xo_emit("{:need-syn-or-fin/*}");
#endif /* defined(TF_NEEDSYN) && defined(TF_NEEDFIN) */
			}
		}
		if (Rflag) {
			/* XXX: is this right Alfred */
			xo_emit(" {:flow-id/%08x} {:flow-type/%5d}",
			    inp->inp_flowid,
			    inp->inp_flowtype);
		}
		xo_emit("\n");
		xo_close_instance("socket");
	}
	if (xig != oxig && xig->xig_gen != oxig->xig_gen) {
		if (oxig->xig_count > xig->xig_count) {
			xo_emit("Some {d:lost/%s} sockets may have been "
			    "deleted.\n", name);
		} else if (oxig->xig_count < xig->xig_count) {
			xo_emit("Some {d:created/%s} sockets may have been "
			    "created.\n", name);
		} else {
			xo_emit("Some {d:changed/%s} sockets may have been "
			    "created or deleted.\n", name);
		}
	}
	free(buf);
}
Esempio n. 17
0
void
mroute6pr()
{
	struct mf6c *mf6ctable[MF6CTBLSIZ], *mfcp;
	struct mif6_sctl mif6table[MAXMIFS];
	struct mf6c mfc;
	struct rtdetq rte, *rtep;
	struct mif6_sctl *mifp;
	mifi_t mifi;
	int i;
	int banner_printed;
	int saved_numeric_addr;
	mifi_t maxmif = 0;
	long int waitings;
	size_t len;

	if (live == 0)
		return;

	len = sizeof(mif6table);
	if (sysctlbyname("net.inet6.ip6.mif6table", mif6table, &len, NULL, 0) <
	    0) {
		xo_warn("sysctl: net.inet6.ip6.mif6table");
		return;
	}

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

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

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

		maxmif = mifi;
		if (!banner_printed) {
			xo_open_list("multicast-interface");
			xo_emit("\n{T:IPv6 Multicast Interface Table}\n"
			    "{T: Mif   Rate   PhyIF   Pkts-In   Pkts-Out}\n");
			banner_printed = 1;
		}

		xo_open_instance("multicast-interface");
		xo_emit("  {:mif/%2u}   {:rate-limit/%4d}",
		    mifi, mifp->m6_rate_limit);
		xo_emit("   {:ifname/%5s}", (mifp->m6_flags & MIFF_REGISTER) ?
		    "reg0" : if_indextoname(mifp->m6_ifp, ifname));

		xo_emit(" {:received-packets/%9ju}  {:sent-packets/%9ju}\n",
		    (uintmax_t)mifp->m6_pkt_in,
		    (uintmax_t)mifp->m6_pkt_out);
		xo_close_instance("multicast-interface");
	}
	if (banner_printed)
		xo_open_list("multicast-interface");
	else
		xo_emit("\n{T:IPv6 Multicast Interface Table is empty}\n");

	len = sizeof(mf6ctable);
	if (sysctlbyname("net.inet6.ip6.mf6ctable", mf6ctable, &len, NULL, 0) <
	    0) {
		xo_warn("sysctl: net.inet6.ip6.mf6ctable");
		return;
	}

	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) {
				xo_open_list("multicast-forwarding-cache");
				xo_emit("\n"
				    "{T:IPv6 Multicast Forwarding Cache}\n");
				xo_emit(" {T:%-*.*s} {T:%-*.*s} {T:%s}",
				    WID_ORG, WID_ORG, "Origin",
				    WID_GRP, WID_GRP, "Group",
				    "  Packets Waits In-Mif  Out-Mifs\n");
				banner_printed = 1;
			}

			xo_open_instance("multicast-forwarding-cache");

			xo_emit(" {:origin/%-*.*s}", WID_ORG, WID_ORG,
			    routename(sin6tosa(&mfc.mf6c_origin),
			    numeric_addr));
			xo_emit(" {:group/%-*.*s}", WID_GRP, WID_GRP,
			    routename(sin6tosa(&mfc.mf6c_mcastgrp),
			    numeric_addr));
			xo_emit(" {:total-packets/%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;
			}
			xo_emit("   {:waitings/%3ld}", waitings);

			if (mfc.mf6c_parent == MF6C_INCOMPLETE_PARENT)
				xo_emit(" ---   ");
			else
				xo_emit("  {:parent/%3d}   ", mfc.mf6c_parent);
			xo_open_list("mif");
			for (mifi = 0; mifi <= maxmif; mifi++) {
				if (IF_ISSET(mifi, &mfc.mf6c_ifset))
					xo_emit(" {l:%u}", mifi);
			}
			xo_close_list("mif");
			xo_emit("\n");

			mfcp = mfc.mf6c_next;
			xo_close_instance("multicast-forwarding-cache");
		}
	}
	if (banner_printed)
		xo_close_list("multicast-forwarding-cache");
	else
		xo_emit("\n{T:IPv6 Multicast Forwarding Table is empty}\n");

	xo_emit("\n");
	numeric_addr = saved_numeric_addr;
}
Esempio n. 18
0
/*
 * Dump ICMPv6 per-interface statistics based on RFC 2466.
 */
void
icmp6_ifstats(char *ifname)
{
	struct in6_ifreq ifr;
	int s;

#define	p(f, m) if (ifr.ifr_ifru.ifru_icmp6stat.f || sflag <= 1)	\
	xo_emit(m, (uintmax_t)ifr.ifr_ifru.ifru_icmp6stat.f,		\
	    plural(ifr.ifr_ifru.ifru_icmp6stat.f))
#define	p2(f, m) if (ifr.ifr_ifru.ifru_icmp6stat.f || sflag <= 1)	\
	xo_emit(m, (uintmax_t)ifr.ifr_ifru.ifru_icmp6stat.f,		\
	    pluralies(ifr.ifr_ifru.ifru_icmp6stat.f))

	if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
		xo_warn("Warning: socket(AF_INET6)");
		return;
	}

	strcpy(ifr.ifr_name, ifname);
	if (ioctl(s, SIOCGIFSTAT_ICMP6, (char *)&ifr) < 0) {
		if (errno != EPFNOSUPPORT)
			xo_warn("Warning: ioctl(SIOCGIFSTAT_ICMP6)");
		goto end;
	}

	xo_emit("{T:/icmp6 on %s}:\n", ifr.ifr_name);

	xo_open_instance("icmp6-interface-statistics");
	xo_emit("{ke:name/%s}", ifr.ifr_name);
	p(ifs6_in_msg, "\t{:received-packets/%ju} "
	    "{N:/total input message%s}\n");
	p(ifs6_in_error, "\t{:received-errors/%ju} "
	    "{N:/total input error message%s}\n");
	p(ifs6_in_dstunreach, "\t{:received-destination-unreachable/%ju} "
	    "{N:/input destination unreachable error%s}\n");
	p(ifs6_in_adminprohib, "\t{:received-admin-prohibited/%ju} "
	    "{N:/input administratively prohibited error%s}\n");
	p(ifs6_in_timeexceed, "\t{:received-time-exceeded/%ju} "
	    "{N:/input time exceeded error%s}\n");
	p(ifs6_in_paramprob, "\t{:received-bad-parameter/%ju} "
	    "{N:/input parameter problem error%s}\n");
	p(ifs6_in_pkttoobig, "\t{:received-packet-too-big/%ju} "
	    "{N:/input packet too big error%s}\n");
	p(ifs6_in_echo, "\t{:received-echo-requests/%ju} "
	    "{N:/input echo request%s}\n");
	p2(ifs6_in_echoreply, "\t{:received-echo-replies/%ju} "
	    "{N:/input echo repl%s}\n");
	p(ifs6_in_routersolicit, "\t{:received-router-solicitation/%ju} "
	    "{N:/input router solicitation%s}\n");
	p(ifs6_in_routeradvert, "\t{:received-router-advertisement/%ju} "
	    "{N:/input router advertisement%s}\n");
	p(ifs6_in_neighborsolicit, "\t{:received-neighbor-solicitation/%ju} "
	    "{N:/input neighbor solicitation%s}\n");
	p(ifs6_in_neighboradvert, "\t{:received-neighbor-advertisement/%ju} "
	    "{N:/input neighbor advertisement%s}\n");
	p(ifs6_in_redirect, "\t{received-redirects/%ju} "
	    "{N:/input redirect%s}\n");
	p2(ifs6_in_mldquery, "\t{:received-mld-queries/%ju} "
	    "{N:/input MLD quer%s}\n");
	p(ifs6_in_mldreport, "\t{:received-mld-reports/%ju} "
	    "{N:/input MLD report%s}\n");
	p(ifs6_in_mlddone, "\t{:received-mld-done/%ju} "
	    "{N:/input MLD done%s}\n");

	p(ifs6_out_msg, "\t{:sent-packets/%ju} "
	    "{N:/total output message%s}\n");
	p(ifs6_out_error, "\t{:sent-errors/%ju} "
	    "{N:/total output error message%s}\n");
	p(ifs6_out_dstunreach, "\t{:sent-destination-unreachable/%ju} "
	    "{N:/output destination unreachable error%s}\n");
	p(ifs6_out_adminprohib, "\t{:sent-admin-prohibited/%ju} "
	    "{N:/output administratively prohibited error%s}\n");
	p(ifs6_out_timeexceed, "\t{:sent-time-exceeded/%ju} "
	    "{N:/output time exceeded error%s}\n");
	p(ifs6_out_paramprob, "\t{:sent-bad-parameter/%ju} "
	    "{N:/output parameter problem error%s}\n");
	p(ifs6_out_pkttoobig, "\t{:sent-packet-too-big/%ju} "
	    "{N:/output packet too big error%s}\n");
	p(ifs6_out_echo, "\t{:sent-echo-requests/%ju} "
	    "{N:/output echo request%s}\n");
	p2(ifs6_out_echoreply, "\t{:sent-echo-replies/%ju} "
	    "{N:/output echo repl%s}\n");
	p(ifs6_out_routersolicit, "\t{:sent-router-solicitation/%ju} "
	    "{N:/output router solicitation%s}\n");
	p(ifs6_out_routeradvert, "\t{:sent-router-advertisement/%ju} "
	    "{N:/output router advertisement%s}\n");
	p(ifs6_out_neighborsolicit, "\t{:sent-neighbor-solicitation/%ju} "
	    "{N:/output neighbor solicitation%s}\n");
	p(ifs6_out_neighboradvert, "\t{:sent-neighbor-advertisement/%ju} "
	    "{N:/output neighbor advertisement%s}\n");
	p(ifs6_out_redirect, "\t{:sent-redirects/%ju} "
	    "{N:/output redirect%s}\n");
	p2(ifs6_out_mldquery, "\t{:sent-mld-queries/%ju} "
	    "{N:/output MLD quer%s}\n");
	p(ifs6_out_mldreport, "\t{:sent-mld-reports/%ju} "
	    "{N:/output MLD report%s}\n");
	p(ifs6_out_mlddone, "\t{:sent-mld-dones/%ju} "
	    "{N:/output MLD done%s}\n");

end:
	xo_close_instance("icmp6-interface-statistics");
	close(s);
#undef p
}
Esempio n. 19
0
void
printlong(const DISPLAY *dp)
{
	struct stat *sp;
	FTSENT *p;
	NAMES *np;
	char buf[20];
#ifdef COLORLS
	int color_printed = 0;
#endif

	if ((dp->list == NULL || dp->list->fts_level != FTS_ROOTLEVEL) &&
	    (f_longform || f_size)) {
		xo_emit("{L:total} {:total-blocks/%lu}\n",
			howmany(dp->btotal, blocksize));
	}

	xo_open_list("entry");
	for (p = dp->list; p; p = p->fts_link) {
		char *name, *type;
		if (IS_NOPRINT(p))
			continue;
		xo_open_instance("entry");
		sp = p->fts_statp;
		name = getname(p->fts_name);
		if (name)
		    xo_emit("{ke:name/%hs}", name);
		if (f_inode)
			xo_emit("{t:inode/%*ju} ",
			    dp->s_inode, (uintmax_t)sp->st_ino);
		if (f_size)
			xo_emit("{t:blocks/%*jd} ",
			    dp->s_block, howmany(sp->st_blocks, blocksize));
		strmode(sp->st_mode, buf);
		aclmode(buf, p);
		np = p->fts_pointer;
		xo_attr("value", "%03o", (int) sp->st_mode & ALLPERMS);
		if (f_numericonly) {
			xo_emit("{t:mode/%s}{e:mode_octal/%03o} {t:links/%*u} {td:user/%-*s}{e:user/%ju}  {td:group/%-*s}{e:group/%ju}  ",
				buf, (int) sp->st_mode & ALLPERMS, dp->s_nlink, sp->st_nlink,
				dp->s_user, np->user, sp->st_uid, dp->s_group, np->group, sp->st_gid);
		} else {
			xo_emit("{t:mode/%s}{e:mode_octal/%03o} {t:links/%*u} {t:user/%-*s}  {t:group/%-*s}  ",
				buf, (int) sp->st_mode & ALLPERMS, dp->s_nlink, sp->st_nlink,
				dp->s_user, np->user, dp->s_group, np->group);
		}
		if (S_ISBLK(sp->st_mode))
			asprintf(&type, "block");
		if (S_ISCHR(sp->st_mode))
			asprintf(&type, "character");
		if (S_ISDIR(sp->st_mode))
			asprintf(&type, "directory");
		if (S_ISFIFO(sp->st_mode))
			asprintf(&type, "fifo");
		if (S_ISLNK(sp->st_mode))
			asprintf(&type, "symlink");
		if (S_ISREG(sp->st_mode))
			asprintf(&type, "regular");
		if (S_ISSOCK(sp->st_mode))
			asprintf(&type, "socket");
		if (S_ISWHT(sp->st_mode))
			asprintf(&type, "whiteout");
		xo_emit("{e:type/%s}", type);
		free(type);
		if (f_flags)
			xo_emit("{:flags/%-*s} ", dp->s_flags, np->flags);
		if (f_label)
			xo_emit("{t:label/%-*s} ", dp->s_label, np->label);
		if (S_ISCHR(sp->st_mode) || S_ISBLK(sp->st_mode))
			printdev(dp->s_size, sp->st_rdev);
		else
			printsize("size", dp->s_size, sp->st_size);
		if (f_accesstime)
			printtime("access-time", sp->st_atime);
		else if (f_birthtime)
			printtime("birth-time", sp->st_birthtime);
		else if (f_statustime)
			printtime("change-time", sp->st_ctime);
		else
			printtime("modify-time", sp->st_mtime);
#ifdef COLORLS
		if (f_color)
			color_printed = colortype(sp->st_mode);
#endif

		if (name) {
		    xo_emit("{dk:name/%hs}", name);
		    free(name);
		}
		
#ifdef COLORLS
		if (f_color && color_printed)
			endcolor(0);
#endif
		if (f_type)
			(void)printtype(sp->st_mode);
		if (S_ISLNK(sp->st_mode))
			printlink(p);
		xo_close_instance("entry");
		xo_emit("\n");
	}
	xo_close_list("entry");
}
Esempio n. 20
0
/*
 * Dump IP6 statistics structure.
 */
void
ip6_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
{
	struct ip6stat ip6stat, zerostat;
	int first, i;
	size_t len;

	len = sizeof ip6stat;
	if (live) {
		memset(&ip6stat, 0, len);
		if (zflag)
			memset(&zerostat, 0, len);
		if (sysctlbyname("net.inet6.ip6.stats", &ip6stat, &len,
		    zflag ? &zerostat : NULL, zflag ? len : 0) < 0) {
			if (errno != ENOENT)
				xo_warn("sysctl: net.inet6.ip6.stats");
			return;
		}
	} else
		kread_counters(off, &ip6stat, len);
	xo_open_container(name);
	xo_emit("{T:/%s}:\n", name);

#define	p(f, m) if (ip6stat.f || sflag <= 1) \
	xo_emit(m, (uintmax_t)ip6stat.f, plural(ip6stat.f))
#define	p1a(f, m) if (ip6stat.f || sflag <= 1) \
	xo_emit(m, (uintmax_t)ip6stat.f)

	p(ip6s_total, "\t{:received-packets/%ju} "
	    "{N:/total packet%s received}\n");
	p1a(ip6s_toosmall, "\t{:dropped-below-minimum-size/%ju} "
	    "{N:/with size smaller than minimum}\n");
	p1a(ip6s_tooshort, "\t{:dropped-short-packets/%ju} "
	    "{N:/with data size < data length}\n");
	p1a(ip6s_badoptions, "\t{:dropped-bad-options/%ju} "
	    "{N:/with bad options}\n");
	p1a(ip6s_badvers, "\t{:dropped-bad-version/%ju} "
	    "{N:/with incorrect version number}\n");
	p(ip6s_fragments, "\t{:received-fragments/%ju} "
	    "{N:/fragment%s received}\n");
	p(ip6s_fragdropped, "\t{:dropped-fragment/%ju} "
	    "{N:/fragment%s dropped (dup or out of space)}\n");
	p(ip6s_fragtimeout, "\t{:dropped-fragment-after-timeout/%ju} "
	    "{N:/fragment%s dropped after timeout}\n");
	p(ip6s_fragoverflow, "\t{:dropped-fragments-overflow/%ju} "
	    "{N:/fragment%s that exceeded limit}\n");
	p(ip6s_reassembled, "\t{:reassembled-packets/%ju} "
	    "{N:/packet%s reassembled ok}\n");
	p(ip6s_delivered, "\t{:received-local-packets/%ju} "
	    "{N:/packet%s for this host}\n");
	p(ip6s_forward, "\t{:forwarded-packets/%ju} "
	    "{N:/packet%s forwarded}\n");
	p(ip6s_cantforward, "\t{:packets-not-forwardable/%ju} "
	    "{N:/packet%s not forwardable}\n");
	p(ip6s_redirectsent, "\t{:sent-redirects/%ju} "
	    "{N:/redirect%s sent}\n");
	p(ip6s_localout, "\t{:sent-packets/%ju} "
	    "{N:/packet%s sent from this host}\n");
	p(ip6s_rawout, "\t{:send-packets-fabricated-header/%ju} "
	    "{N:/packet%s sent with fabricated ip header}\n");
	p(ip6s_odropped, "\t{:discard-no-mbufs/%ju} "
	    "{N:/output packet%s dropped due to no bufs, etc.}\n");
	p(ip6s_noroute, "\t{:discard-no-route/%ju} "
	    "{N:/output packet%s discarded due to no route}\n");
	p(ip6s_fragmented, "\t{:sent-fragments/%ju} "
	    "{N:/output datagram%s fragmented}\n");
	p(ip6s_ofragments, "\t{:fragments-created/%ju} "
	    "{N:/fragment%s created}\n");
	p(ip6s_cantfrag, "\t{:discard-cannot-fragment/%ju} "
	    "{N:/datagram%s that can't be fragmented}\n");
	p(ip6s_badscope, "\t{:discard-scope-violations/%ju} "
	    "{N:/packet%s that violated scope rules}\n");
	p(ip6s_notmember, "\t{:multicast-no-join-packets/%ju} "
	    "{N:/multicast packet%s which we don't join}\n");
	for (first = 1, i = 0; i < IP6S_HDRCNT; i++)
		if (ip6stat.ip6s_nxthist[i] != 0) {
			if (first) {
				xo_emit("\t{T:Input histogram}:\n");
				xo_open_list("input-histogram");
				first = 0;
			}
			xo_open_instance("input-histogram");
			xo_emit("\t\t{k:name/%s}: {:count/%ju}\n", ip6nh[i],
			    (uintmax_t)ip6stat.ip6s_nxthist[i]);
			xo_close_instance("input-histogram");
		}
	if (!first)
		xo_close_list("input-histogram");

	xo_open_container("mbuf-statistics");
	xo_emit("\t{T:Mbuf statistics}:\n");
	xo_emit("\t\t{:one-mbuf/%ju} {N:/one mbuf}\n",
	    (uintmax_t)ip6stat.ip6s_m1);
	for (first = 1, i = 0; i < IP6S_M2MMAX; i++) {
		char ifbuf[IFNAMSIZ];
		if (ip6stat.ip6s_m2m[i] != 0) {
			if (first) {
				xo_emit("\t\t{N:two or more mbuf}:\n");
				xo_open_list("mbuf-data");
				first = 0;
			}
			xo_open_instance("mbuf-data");
			xo_emit("\t\t\t{k:name/%s}= {:count/%ju}\n",
			    if_indextoname(i, ifbuf),
			    (uintmax_t)ip6stat.ip6s_m2m[i]);
			xo_close_instance("mbuf-data");
		}
	}
	if (!first)
		xo_close_list("mbuf-data");
	xo_emit("\t\t{:one-extra-mbuf/%ju} {N:one ext mbuf}\n",
	    (uintmax_t)ip6stat.ip6s_mext1);
	xo_emit("\t\t{:two-or-more-extra-mbufs/%ju} "
	    "{N:/two or more ext mbuf}\n", (uintmax_t)ip6stat.ip6s_mext2m);
	xo_close_container("mbuf-statistics");

	p(ip6s_exthdrtoolong, "\t{:dropped-header-too-long/%ju} "
	    "{N:/packet%s whose headers are not contiguous}\n");
	p(ip6s_nogif, "\t{:discard-tunnel-no-gif/%ju} "
	    "{N:/tunneling packet%s that can't find gif}\n");
	p(ip6s_toomanyhdr, "\t{:dropped-too-many-headers/%ju} "
	    "{N:/packet%s discarded because of too many headers}\n");

	/* for debugging source address selection */
#define	PRINT_SCOPESTAT(s,i) do {\
		switch(i) { /* XXX hardcoding in each case */\
		case 1:\
			p(s, "\t\t{ke:name/interface-locals}{:count/%ju} " \
			  "{N:/interface-local%s}\n");	\
			break;\
		case 2:\
			p(s,"\t\t{ke:name/link-locals}{:count/%ju} " \
			"{N:/link-local%s}\n"); \
			break;\
		case 5:\
			p(s,"\t\t{ke:name/site-locals}{:count/%ju} " \
			  "{N:/site-local%s}\n");\
			break;\
		case 14:\
			p(s,"\t\t{ke:name/globals}{:count/%ju} " \
			  "{N:/global%s}\n");\
			break;\
		default:\
			xo_emit("\t\t{qke:name/%x}{:count/%ju} " \
				"addresses scope=%x\n",\
				i, (uintmax_t)ip6stat.s, i);	   \
		}\
	} while (0);

	xo_open_container("source-address-selection");
	p(ip6s_sources_none, "\t{:address-selection-failures/%ju} "
	    "{N:/failure%s of source address selection}\n");

	for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) {
		if (ip6stat.ip6s_sources_sameif[i]) {
			if (first) {
				xo_open_list("outgoing-interface");
				xo_emit("\tsource addresses on an outgoing "
				    "I/F\n");
				first = 0;
			}
			xo_open_instance("outgoing-interface");
			PRINT_SCOPESTAT(ip6s_sources_sameif[i], i);
			xo_close_instance("outgoing-interface");
		}
	}
	if (!first)
		xo_close_list("outgoing-interface");

	for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) {
		if (ip6stat.ip6s_sources_otherif[i]) {
			if (first) {
				xo_open_list("non-outgoing-interface");
				xo_emit("\tsource addresses on a non-outgoing "
				    "I/F\n");
				first = 0;
			}
			xo_open_instance("non-outgoing-interface");
			PRINT_SCOPESTAT(ip6s_sources_otherif[i], i);
			xo_close_instance("non-outgoing-interface");
		}
	}
	if (!first)
		xo_close_list("non-outgoing-interface");

	for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) {
		if (ip6stat.ip6s_sources_samescope[i]) {
			if (first) {
				xo_open_list("same-source");
				xo_emit("\tsource addresses of same scope\n");
				first = 0;
			}
			xo_open_instance("same-source");
			PRINT_SCOPESTAT(ip6s_sources_samescope[i], i);
			xo_close_instance("same-source");
		}
	}
	if (!first)
		xo_close_list("same-source");

	for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) {
		if (ip6stat.ip6s_sources_otherscope[i]) {
			if (first) {
				xo_open_list("different-scope");
				xo_emit("\tsource addresses of a different "
				    "scope\n");
				first = 0;
			}
			xo_open_instance("different-scope");
			PRINT_SCOPESTAT(ip6s_sources_otherscope[i], i);
			xo_close_instance("different-scope");
		}
	}
	if (!first)
		xo_close_list("different-scope");

	for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) {
		if (ip6stat.ip6s_sources_deprecated[i]) {
			if (first) {
				xo_open_list("deprecated-source");
				xo_emit("\tdeprecated source addresses\n");
				first = 0;
			}
			xo_open_instance("deprecated-source");
			PRINT_SCOPESTAT(ip6s_sources_deprecated[i], i);
			xo_close_instance("deprecated-source");
		}
	}
	if (!first)
		xo_close_list("deprecated-source");

	for (first = 1, i = 0; i < IP6S_RULESMAX; i++) {
		if (ip6stat.ip6s_sources_rule[i]) {
			if (first) {
				xo_open_list("rules-applied");
				xo_emit("\t{T:Source addresses selection "
				    "rule applied}:\n");
				first = 0;
			}
			xo_open_instance("rules-applied");
			xo_emit("\t\t{ke:name/%s}{:count/%ju} {d:name/%s}\n",
			    srcrule_str[i],
			    (uintmax_t)ip6stat.ip6s_sources_rule[i],
			    srcrule_str[i]);
			xo_close_instance("rules-applied");
		}
	}
	if (!first)
		xo_close_list("rules-applied");

	xo_close_container("source-address-selection");

#undef p
#undef p1a
	xo_close_container(name);
}
Esempio n. 21
0
void
printcol(const DISPLAY *dp)
{
	static FTSENT **array;
	static int lastentries = -1;
	FTSENT *p;
	FTSENT **narray;
	int base;
	int chcnt;
	int cnt;
	int col;
	int colwidth;
	int endcol;
	int num;
	int numcols;
	int numrows;
	int row;
	int tabwidth;

	if (f_notabs)
		tabwidth = 1;
	else
		tabwidth = 8;

	/*
	 * Have to do random access in the linked list -- build a table
	 * of pointers.
	 */
	if (dp->entries > lastentries) {
		if ((narray =
		    realloc(array, dp->entries * sizeof(FTSENT *))) == NULL) {
			printscol(dp);
			return;
		}
		lastentries = dp->entries;
		array = narray;
	}
	for (p = dp->list, num = 0; p; p = p->fts_link)
		if (p->fts_number != NO_PRINT)
			array[num++] = p;

	colwidth = dp->maxlen;
	if (f_inode)
		colwidth += dp->s_inode + 1;
	if (f_size)
		colwidth += dp->s_block + 1;
	if (f_type)
		colwidth += 1;

	colwidth = (colwidth + tabwidth) & ~(tabwidth - 1);
	if (termwidth < 2 * colwidth) {
		printscol(dp);
		return;
	}
	numcols = termwidth / colwidth;
	numrows = num / numcols;
	if (num % numcols)
		++numrows;

	if ((dp->list == NULL || dp->list->fts_level != FTS_ROOTLEVEL) &&
	    (f_longform || f_size)) {
		xo_emit("{L:total} {:total-blocks/%lu}\n",
			howmany(dp->btotal, blocksize));
	}

	xo_open_list("entry");
	base = 0;
	for (row = 0; row < numrows; ++row) {
		endcol = colwidth;
		if (!f_sortacross)
			base = row;
		for (col = 0, chcnt = 0; col < numcols; ++col) {
			xo_open_instance("entry");
			chcnt += printaname(array[base], dp->s_inode,
			    dp->s_block);
			xo_close_instance("entry");
			if (f_sortacross)
				base++;
			else
				base += numrows;
			if (base >= num)
				break;
			while ((cnt = ((chcnt + tabwidth) & ~(tabwidth - 1)))
			    <= endcol) {
				if (f_sortacross && col + 1 >= numcols)
					break;
				xo_emit(f_notabs ? " " : "\t");
				chcnt = cnt;
			}
			endcol += colwidth;
		}
		xo_emit("\n");
	}
	xo_close_list("entry");
}
Esempio n. 22
0
int
main (int argc, char **argv)
{
    struct employee {
	const char *e_first;
	const char *e_nic;
	const char *e_last;
	unsigned e_dept;
	unsigned e_percent;
    } employees[] = {
	{ "Jim", "რეგტ", "გთხოვთ ახ", 431, 90 },
	{ "Terry", "<one", "Οὐχὶ ταὐτὰ παρίσταταί μοι Jones", 660, 90 },
	{ "Leslie", "Les", "Patterson", 341,60 },
	{ "Ashley", "Ash", "Meter & Smith", 1440, 40 },
	{ "0123456789", "0123456789", "012345678901234567890", 1440, 40 },
	{ "ახლა", "გაიარო", "საერთაშორისო", 123, 90 },
	{ "෴ණ්ණ෴෴ණ්ණ෴", "Mick",
	  "෴ණ්ණ෴෴ණ්ණ෴෴ණ්ණ෴෴෴", 110, 20 },
	{ NULL, NULL }
    }, *ep = employees;
    int rc;

    argc = xo_parse_args(argc, argv);
    if (argc < 0)
	return 1;

    xo_set_info(NULL, info, info_count);
    xo_set_flags(NULL, XOF_COLUMNS);

    xo_open_container("employees");

    xo_emit("Οὐχὶ ταὐτὰ παρίσταταί μοι {:v1/%s}, {:v2/%s}\n",
	    "γιγνώσκειν", "ὦ ἄνδρες ᾿Αθηναῖοι");

    rc = xo_emit("გთხოვთ {:v1/%s} {:v2/%s}\n",
	    "ახლავე გაიაროთ რეგისტრაცია",
	    "Unicode-ის მეათე საერთაშორისო");
    xo_emit("{Twc:Width}{:width/%d}\n", rc);

    /* Okay, Sinhala is uber cool ... */
    rc = xo_emit("[{:sinhala}]\n", "෴ණ්ණ෴");
    xo_emit("{Twc:Width}{:width/%d}\n", rc);
    rc = xo_emit("[{:sinhala}]\n", "෴");
    xo_emit("{Twc:Width}{:width/%d}\n", rc);
    rc = xo_emit("[{:sinhala/%-4..4s/%s}]\n", "෴ණ්ණ෴෴ණ්ණ෴");
    xo_emit("[{:not-sinhala/%-4..4s/%s}]\n", "123456");
    rc = xo_emit("[{:tag/%s}]\n", "ර්‍ඝ");
    xo_emit("{Twc:Width}{:width/%d}\n", rc);

    xo_open_list("employee");

    xo_emit("{T:First Name/%-25s}{T:Last Name/%-14s}"
	    "{T:/%-12s}{T:Time (%)}\n", "Department");
    for ( ; ep->e_first; ep++) {
	xo_open_instance("employee");
	xo_emit("{[:-25}{:first-name/%s} ({:nic-name/\"%s\"}){]:}"
		"{:last-name/%-14..14s/%s}"
		"{:department/%8u/%u}{:percent-time/%8u/%u}\n",
		ep->e_first, ep->e_nic, ep->e_last, ep->e_dept, ep->e_percent);
	if (ep->e_percent > 50) {
	    xo_attr("full-time", "%s", "honest & for true");
	    xo_emit("{e:benefits/%s}", "full");
	}
	xo_close_instance("employee");
    }

    xo_close_list("employee");
    xo_close_container("employees");

    xo_finish();

    return 0;
}