int print_linkinfo(const struct sockaddr_nl *who,
		   struct nlmsghdr *n, void *arg)
{
	FILE *fp = (FILE*)arg;
	struct ifinfomsg *ifi = NLMSG_DATA(n);
	struct rtattr * tb[IFLA_MAX+1];
	int len = n->nlmsg_len;
	unsigned m_flag = 0;

	if (n->nlmsg_type != RTM_NEWLINK && n->nlmsg_type != RTM_DELLINK)
		return 0;

	len -= NLMSG_LENGTH(sizeof(*ifi));
	if (len < 0)
		return -1;

	if (filter.ifindex && ifi->ifi_index != filter.ifindex)
		return 0;
	if (filter.up && !(ifi->ifi_flags&IFF_UP))
		return 0;

	parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
	if (tb[IFLA_IFNAME] == NULL) {
		fprintf(stderr, "BUG: device with ifindex %d has nil ifname\n", ifi->ifi_index);
	}
	if (filter.label &&
	    (!filter.family || filter.family == AF_PACKET) &&
	    fnmatch(filter.label, RTA_DATA(tb[IFLA_IFNAME]), 0))
		return 0;

	if (n->nlmsg_type == RTM_DELLINK)
		fprintf(fp, "Deleted ");

	fprintf(fp, "%d: %s", ifi->ifi_index,
		tb[IFLA_IFNAME] ? (char*)RTA_DATA(tb[IFLA_IFNAME]) : "<nil>");

	if (tb[IFLA_LINK]) {
		SPRINT_BUF(b1);
		int iflink = *(int*)RTA_DATA(tb[IFLA_LINK]);
		if (iflink == 0)
			fprintf(fp, "@NONE: ");
		else {
			fprintf(fp, "@%s: ", ll_idx_n2a(iflink, b1));
			m_flag = ll_index_to_flags(iflink);
			m_flag = !(m_flag & IFF_UP);
		}
	} else {
		fprintf(fp, ": ");
	}
	print_link_flags(fp, ifi->ifi_flags, m_flag);

	if (tb[IFLA_MTU])
		fprintf(fp, "mtu %u ", *(int*)RTA_DATA(tb[IFLA_MTU]));
	if (tb[IFLA_QDISC])
		fprintf(fp, "qdisc %s ", (char*)RTA_DATA(tb[IFLA_QDISC]));
#ifdef IFLA_MASTER
	if (tb[IFLA_MASTER]) {
		SPRINT_BUF(b1);
		fprintf(fp, "master %s ", ll_idx_n2a(*(int*)RTA_DATA(tb[IFLA_MASTER]), b1));
	}
#endif
	if (tb[IFLA_OPERSTATE])
		print_operstate(fp, *(__u8 *)RTA_DATA(tb[IFLA_OPERSTATE]));
		
	if (filter.showqueue)
		print_queuelen(fp, (char*)RTA_DATA(tb[IFLA_IFNAME]));

	if (!filter.family || filter.family == AF_PACKET) {
		SPRINT_BUF(b1);
		fprintf(fp, "%s", _SL_);
		fprintf(fp, "    link/%s ", ll_type_n2a(ifi->ifi_type, b1, sizeof(b1)));

		if (tb[IFLA_ADDRESS]) {
			fprintf(fp, "%s", ll_addr_n2a(RTA_DATA(tb[IFLA_ADDRESS]),
						      RTA_PAYLOAD(tb[IFLA_ADDRESS]),
						      ifi->ifi_type,
						      b1, sizeof(b1)));
		}
		if (tb[IFLA_BROADCAST]) {
			if (ifi->ifi_flags&IFF_POINTOPOINT)
				fprintf(fp, " peer ");
			else
				fprintf(fp, " brd ");
			fprintf(fp, "%s", ll_addr_n2a(RTA_DATA(tb[IFLA_BROADCAST]),
						      RTA_PAYLOAD(tb[IFLA_BROADCAST]),
						      ifi->ifi_type,
						      b1, sizeof(b1)));
		}
	}

	if (do_link && tb[IFLA_LINKINFO] && show_details)
		print_linktype(fp, tb[IFLA_LINKINFO]);

	if (do_link && tb[IFLA_IFALIAS])
		fprintf(fp,"\n    alias %s", 
			(const char *) RTA_DATA(tb[IFLA_IFALIAS]));

	if (do_link && tb[IFLA_STATS64] && show_stats) {
		struct rtnl_link_stats64 slocal;
		struct rtnl_link_stats64 *s = RTA_DATA(tb[IFLA_STATS64]);
		if (((unsigned long)s) & (sizeof(unsigned long)-1)) {
			memcpy(&slocal, s, sizeof(slocal));
			s = &slocal;
		}
		fprintf(fp, "%s", _SL_);
		fprintf(fp, "    RX: bytes  packets  errors  dropped overrun mcast   %s%s",
			s->rx_compressed ? "compressed" : "", _SL_);
		fprintf(fp, "    %-10llu %-8llu %-7llu %-7llu %-7llu %-7llu",
			(unsigned long long)s->rx_bytes,
			(unsigned long long)s->rx_packets,
			(unsigned long long)s->rx_errors,
			(unsigned long long)s->rx_dropped,
			(unsigned long long)s->rx_over_errors,
			(unsigned long long)s->multicast);
		if (s->rx_compressed)
			fprintf(fp, " %-7llu",
				(unsigned long long)s->rx_compressed);
		if (show_stats > 1) {
			fprintf(fp, "%s", _SL_);
			fprintf(fp, "    RX errors: length  crc     frame   fifo    missed%s", _SL_);
			fprintf(fp, "               %-7llu  %-7llu %-7llu %-7llu %-7llu",
				(unsigned long long)s->rx_length_errors,
				(unsigned long long)s->rx_crc_errors,
				(unsigned long long)s->rx_frame_errors,
				(unsigned long long)s->rx_fifo_errors,
				(unsigned long long)s->rx_missed_errors);
		}
		fprintf(fp, "%s", _SL_);
		fprintf(fp, "    TX: bytes  packets  errors  dropped carrier collsns %s%s",
			s->tx_compressed ? "compressed" : "", _SL_);
		fprintf(fp, "    %-10llu %-8llu %-7llu %-7llu %-7llu %-7llu",
			(unsigned long long)s->tx_bytes,
			(unsigned long long)s->tx_packets,
			(unsigned long long)s->tx_errors,
			(unsigned long long)s->tx_dropped,
			(unsigned long long)s->tx_carrier_errors,
			(unsigned long long)s->collisions);
		if (s->tx_compressed)
			fprintf(fp, " %-7llu",
				(unsigned long long)s->tx_compressed);
		if (show_stats > 1) {
			fprintf(fp, "%s", _SL_);
			fprintf(fp, "    TX errors: aborted fifo    window  heartbeat%s", _SL_);
			fprintf(fp, "               %-7llu  %-7llu %-7llu %-7llu",
				(unsigned long long)s->tx_aborted_errors,
				(unsigned long long)s->tx_fifo_errors,
				(unsigned long long)s->tx_window_errors,
				(unsigned long long)s->tx_heartbeat_errors);
		}
	}
	if (do_link && !tb[IFLA_STATS64] && tb[IFLA_STATS] && show_stats) {
		struct rtnl_link_stats slocal;
		struct rtnl_link_stats *s = RTA_DATA(tb[IFLA_STATS]);
		if (((unsigned long)s) & (sizeof(unsigned long)-1)) {
			memcpy(&slocal, s, sizeof(slocal));
			s = &slocal;
		}
		fprintf(fp, "%s", _SL_);
		fprintf(fp, "    RX: bytes  packets  errors  dropped overrun mcast   %s%s",
			s->rx_compressed ? "compressed" : "", _SL_);
		fprintf(fp, "    %-10u %-8u %-7u %-7u %-7u %-7u",
			s->rx_bytes, s->rx_packets, s->rx_errors,
			s->rx_dropped, s->rx_over_errors,
			s->multicast
			);
		if (s->rx_compressed)
			fprintf(fp, " %-7u", s->rx_compressed);
		if (show_stats > 1) {
			fprintf(fp, "%s", _SL_);
			fprintf(fp, "    RX errors: length  crc     frame   fifo    missed%s", _SL_);
			fprintf(fp, "               %-7u  %-7u %-7u %-7u %-7u",
				s->rx_length_errors,
				s->rx_crc_errors,
				s->rx_frame_errors,
				s->rx_fifo_errors,
				s->rx_missed_errors
				);
		}
		fprintf(fp, "%s", _SL_);
		fprintf(fp, "    TX: bytes  packets  errors  dropped carrier collsns %s%s",
			s->tx_compressed ? "compressed" : "", _SL_);
		fprintf(fp, "    %-10u %-8u %-7u %-7u %-7u %-7u",
			s->tx_bytes, s->tx_packets, s->tx_errors,
			s->tx_dropped, s->tx_carrier_errors, s->collisions);
		if (s->tx_compressed)
			fprintf(fp, " %-7u", s->tx_compressed);
		if (show_stats > 1) {
			fprintf(fp, "%s", _SL_);
			fprintf(fp, "    TX errors: aborted fifo    window  heartbeat%s", _SL_);
			fprintf(fp, "               %-7u  %-7u %-7u %-7u",
				s->tx_aborted_errors,
				s->tx_fifo_errors,
				s->tx_window_errors,
				s->tx_heartbeat_errors
				);
		}
	}
	if (do_link && tb[IFLA_VFINFO_LIST] && tb[IFLA_NUM_VF]) {
		struct rtattr *i, *vflist = tb[IFLA_VFINFO_LIST];
		int rem = RTA_PAYLOAD(vflist);
		for (i = RTA_DATA(vflist); RTA_OK(i, rem); i = RTA_NEXT(i, rem))
			print_vfinfo(fp, i);
	}

	fprintf(fp, "\n");
	fflush(fp);
	return 0;
}
Esempio n. 2
0
int print_linkinfo(const struct sockaddr_nl *who,
		   struct nlmsghdr *n, void *arg)
{
	FILE *fp = (FILE*)arg;
	struct ifinfomsg *ifi = NLMSG_DATA(n);
	struct rtattr * tb[IFLA_MAX+1];
	int len = n->nlmsg_len;
	unsigned m_flag = 0;

	if (n->nlmsg_type != RTM_NEWLINK && n->nlmsg_type != RTM_DELLINK)
		return 0;

	len -= NLMSG_LENGTH(sizeof(*ifi));
	if (len < 0)
		return -1;

	if (filter.ifindex && ifi->ifi_index != filter.ifindex)
		return 0;
	if (filter.up && !(ifi->ifi_flags&IFF_UP))
		return 0;

	parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
	if (tb[IFLA_IFNAME] == NULL) {
		fprintf(stderr, "BUG: device with ifindex %d has nil ifname\n", ifi->ifi_index);
	}
	if (filter.label &&
	    (!filter.family || filter.family == AF_PACKET) &&
	    fnmatch(filter.label, RTA_DATA(tb[IFLA_IFNAME]), 0))
		return 0;

	if (tb[IFLA_GROUP]) {
		int group = *(int*)RTA_DATA(tb[IFLA_GROUP]);
		if (filter.group != -1 && group != filter.group)
			return -1;
	}

	if (tb[IFLA_MASTER]) {
		int master = *(int*)RTA_DATA(tb[IFLA_MASTER]);
		if (filter.master > 0 && master != filter.master)
			return -1;
	}
	else if (filter.master > 0)
		return -1;

	if (filter.kind) {
		if (tb[IFLA_LINKINFO]) {
			char *kind = parse_link_kind(tb[IFLA_LINKINFO]);

			if (strcmp(kind, filter.kind))
				return -1;
		} else {
			return -1;
		}
	}

	if (n->nlmsg_type == RTM_DELLINK)
		fprintf(fp, "Deleted ");

	fprintf(fp, "%d: ", ifi->ifi_index);
	color_fprintf(fp, COLOR_IFNAME, "%s",
		tb[IFLA_IFNAME] ? rta_getattr_str(tb[IFLA_IFNAME]) : "<nil>");

	if (tb[IFLA_LINK]) {
		SPRINT_BUF(b1);
		int iflink = *(int*)RTA_DATA(tb[IFLA_LINK]);
		if (iflink == 0)
			fprintf(fp, "@NONE: ");
		else {
			if (tb[IFLA_LINK_NETNSID])
				fprintf(fp, "@if%d: ", iflink);
			else {
				fprintf(fp, "@%s: ", ll_idx_n2a(iflink, b1));
				m_flag = ll_index_to_flags(iflink);
				m_flag = !(m_flag & IFF_UP);
			}
		}
	} else {
		fprintf(fp, ": ");
	}
	print_link_flags(fp, ifi->ifi_flags, m_flag);

	if (tb[IFLA_MTU])
		fprintf(fp, "mtu %u ", *(int*)RTA_DATA(tb[IFLA_MTU]));
	if (tb[IFLA_QDISC])
		fprintf(fp, "qdisc %s ", rta_getattr_str(tb[IFLA_QDISC]));
	if (tb[IFLA_MASTER]) {
		SPRINT_BUF(b1);
		fprintf(fp, "master %s ", ll_idx_n2a(*(int*)RTA_DATA(tb[IFLA_MASTER]), b1));
	}

	if (tb[IFLA_PHYS_PORT_ID]) {
		SPRINT_BUF(b1);
		fprintf(fp, "portid %s ",
			hexstring_n2a(RTA_DATA(tb[IFLA_PHYS_PORT_ID]),
				      RTA_PAYLOAD(tb[IFLA_PHYS_PORT_ID]),
				      b1, sizeof(b1)));
	}

	if (tb[IFLA_OPERSTATE])
		print_operstate(fp, rta_getattr_u8(tb[IFLA_OPERSTATE]));

	if (do_link && tb[IFLA_LINKMODE])
		print_linkmode(fp, tb[IFLA_LINKMODE]);

	if (tb[IFLA_GROUP]) {
		SPRINT_BUF(b1);
		int group = *(int*)RTA_DATA(tb[IFLA_GROUP]);
		fprintf(fp, "group %s ", rtnl_group_n2a(group, b1, sizeof(b1)));
	}

	if (filter.showqueue)
		print_queuelen(fp, tb);

	if (!filter.family || filter.family == AF_PACKET || show_details) {
		SPRINT_BUF(b1);
		fprintf(fp, "%s", _SL_);
		fprintf(fp, "    link/%s ", ll_type_n2a(ifi->ifi_type, b1, sizeof(b1)));

		if (tb[IFLA_ADDRESS]) {
			color_fprintf(fp, COLOR_MAC, "%s",
					ll_addr_n2a(RTA_DATA(tb[IFLA_ADDRESS]),
						RTA_PAYLOAD(tb[IFLA_ADDRESS]),
						ifi->ifi_type,
						b1, sizeof(b1)));
		}
		if (tb[IFLA_BROADCAST]) {
			if (ifi->ifi_flags&IFF_POINTOPOINT)
				fprintf(fp, " peer ");
			else
				fprintf(fp, " brd ");
			fprintf(fp, "%s", ll_addr_n2a(RTA_DATA(tb[IFLA_BROADCAST]),
						      RTA_PAYLOAD(tb[IFLA_BROADCAST]),
						      ifi->ifi_type,
						      b1, sizeof(b1)));
		}
	}

	if (tb[IFLA_LINK_NETNSID]) {
		int id = *(int*)RTA_DATA(tb[IFLA_LINK_NETNSID]);

		if (id >= 0)
			fprintf(fp, " link-netnsid %d", id);
		else
			fprintf(fp, " link-netnsid unknown");
	}

	if (tb[IFLA_PROMISCUITY] && show_details)
		fprintf(fp, " promiscuity %u ",
			*(int*)RTA_DATA(tb[IFLA_PROMISCUITY]));

	if (tb[IFLA_LINKINFO] && show_details)
		print_linktype(fp, tb[IFLA_LINKINFO]);

	if (do_link && tb[IFLA_AF_SPEC] && show_details)
		print_af_spec(fp, tb[IFLA_AF_SPEC]);

	if ((do_link || show_details) && tb[IFLA_IFALIAS]) {
		fprintf(fp, "%s    alias %s", _SL_,
			rta_getattr_str(tb[IFLA_IFALIAS]));
	}

	if (do_link && show_stats) {
		fprintf(fp, "%s", _SL_);
		__print_link_stats(fp, tb);
	}

	if ((do_link || show_details) && tb[IFLA_VFINFO_LIST] && tb[IFLA_NUM_VF]) {
		struct rtattr *i, *vflist = tb[IFLA_VFINFO_LIST];
		int rem = RTA_PAYLOAD(vflist);
		for (i = RTA_DATA(vflist); RTA_OK(i, rem); i = RTA_NEXT(i, rem))
			print_vfinfo(fp, i);
	}

	fprintf(fp, "\n");
	fflush(fp);
	return 1;
}
Esempio n. 3
0
int print_linkinfo(const struct sockaddr_nl *who,
		   struct nlmsghdr *n, void *arg)
{
	FILE *fp = (FILE*)arg;
	struct ifinfomsg *ifi = NLMSG_DATA(n);
	struct rtattr * tb[IFLA_MAX+1];
	int len = n->nlmsg_len;
	unsigned m_flag = 0;

	if (n->nlmsg_type != RTM_NEWLINK && n->nlmsg_type != RTM_DELLINK)
		return 0;

	len -= NLMSG_LENGTH(sizeof(*ifi));
	if (len < 0)
		return -1;

	if (filter.ifindex && ifi->ifi_index != filter.ifindex)
		return 0;
	if (filter.up && !(ifi->ifi_flags&IFF_UP))
		return 0;

	parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
	if (tb[IFLA_IFNAME] == NULL) {
		fprintf(stderr, "BUG: device with ifindex %d has nil ifname\n", ifi->ifi_index);
	}
	if (filter.label &&
	    (!filter.family || filter.family == AF_PACKET) &&
	    fnmatch(filter.label, RTA_DATA(tb[IFLA_IFNAME]), 0))
		return 0;

	if (tb[IFLA_GROUP]) {
		int group = *(int*)RTA_DATA(tb[IFLA_GROUP]);
		if (group != filter.group)
			return -1;
	}

	if (n->nlmsg_type == RTM_DELLINK)
		fprintf(fp, "Deleted ");

	fprintf(fp, "%d: %s", ifi->ifi_index,
		tb[IFLA_IFNAME] ? rta_getattr_str(tb[IFLA_IFNAME]) : "<nil>");

	if (tb[IFLA_LINK]) {
		SPRINT_BUF(b1);
		int iflink = *(int*)RTA_DATA(tb[IFLA_LINK]);
		if (iflink == 0)
			fprintf(fp, "@NONE: ");
		else {
			fprintf(fp, "@%s: ", ll_idx_n2a(iflink, b1));
			m_flag = ll_index_to_flags(iflink);
			m_flag = !(m_flag & IFF_UP);
		}
	} else {
		fprintf(fp, ": ");
	}
	print_link_flags(fp, ifi->ifi_flags, m_flag);

	if (tb[IFLA_MTU])
		fprintf(fp, "mtu %u ", *(int*)RTA_DATA(tb[IFLA_MTU]));
	if (tb[IFLA_QDISC])
		fprintf(fp, "qdisc %s ", rta_getattr_str(tb[IFLA_QDISC]));
	if (tb[IFLA_MASTER]) {
		SPRINT_BUF(b1);
		fprintf(fp, "master %s ", ll_idx_n2a(*(int*)RTA_DATA(tb[IFLA_MASTER]), b1));
	}

	if (tb[IFLA_OPERSTATE])
		print_operstate(fp, rta_getattr_u8(tb[IFLA_OPERSTATE]));

	if (do_link && tb[IFLA_LINKMODE])
		print_linkmode(fp, tb[IFLA_LINKMODE]);

	if (filter.showqueue)
		print_queuelen(fp, tb);

	if (!filter.family || filter.family == AF_PACKET) {
		SPRINT_BUF(b1);
		fprintf(fp, "%s", _SL_);
		fprintf(fp, "    link/%s ", ll_type_n2a(ifi->ifi_type, b1, sizeof(b1)));

		if (tb[IFLA_ADDRESS]) {
			fprintf(fp, "%s", ll_addr_n2a(RTA_DATA(tb[IFLA_ADDRESS]),
						      RTA_PAYLOAD(tb[IFLA_ADDRESS]),
						      ifi->ifi_type,
						      b1, sizeof(b1)));
		}
		if (tb[IFLA_BROADCAST]) {
			if (ifi->ifi_flags&IFF_POINTOPOINT)
				fprintf(fp, " peer ");
			else
				fprintf(fp, " brd ");
			fprintf(fp, "%s", ll_addr_n2a(RTA_DATA(tb[IFLA_BROADCAST]),
						      RTA_PAYLOAD(tb[IFLA_BROADCAST]),
						      ifi->ifi_type,
						      b1, sizeof(b1)));
		}
	}

	if (do_link && tb[IFLA_LINKINFO] && show_details)
		print_linktype(fp, tb[IFLA_LINKINFO]);

	if (do_link && tb[IFLA_IFALIAS])
		fprintf(fp,"\n    alias %s", 
			rta_getattr_str(tb[IFLA_IFALIAS]));

	if (do_link && show_stats) {
		if (tb[IFLA_STATS64])
			print_link_stats64(fp, RTA_DATA(tb[IFLA_STATS64]));
		else if (tb[IFLA_STATS])
			print_link_stats(fp, RTA_DATA(tb[IFLA_STATS]));
	}

	if (do_link && tb[IFLA_VFINFO_LIST] && tb[IFLA_NUM_VF]) {
		struct rtattr *i, *vflist = tb[IFLA_VFINFO_LIST];
		int rem = RTA_PAYLOAD(vflist);
		for (i = RTA_DATA(vflist); RTA_OK(i, rem); i = RTA_NEXT(i, rem))
			print_vfinfo(fp, i);
	}

	fprintf(fp, "\n");
	fflush(fp);
	return 0;
}