static void print_encap_mpls(FILE *fp, struct rtattr *encap)
{
	struct rtattr *tb[MPLS_IPTUNNEL_MAX+1];

	parse_rtattr_nested(tb, MPLS_IPTUNNEL_MAX, encap);

	if (tb[MPLS_IPTUNNEL_DST])
		fprintf(fp, " %s ",
		        format_host_rta(AF_MPLS, tb[MPLS_IPTUNNEL_DST]));
}
示例#2
0
int print_addrlabel(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
{
	FILE *fp = (FILE *)arg;
	struct ifaddrlblmsg *ifal = NLMSG_DATA(n);
	int len = n->nlmsg_len;
	struct rtattr *tb[IFAL_MAX+1];

	if (n->nlmsg_type != RTM_NEWADDRLABEL && n->nlmsg_type != RTM_DELADDRLABEL)
		return 0;

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

	parse_rtattr(tb, IFAL_MAX, IFAL_RTA(ifal), len);

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

	if (tb[IFAL_ADDRESS]) {
		fprintf(fp, "prefix %s/%u ",
			format_host_rta(ifal->ifal_family,
		                        tb[IFAL_ADDRESS]),
			ifal->ifal_prefixlen);
	}

	if (ifal->ifal_index)
		fprintf(fp, "dev %s ", ll_index_to_name(ifal->ifal_index));

	if (tb[IFAL_LABEL] && RTA_PAYLOAD(tb[IFAL_LABEL]) == sizeof(uint32_t)) {
		uint32_t label;

		memcpy(&label, RTA_DATA(tb[IFAL_LABEL]), sizeof(label));
		fprintf(fp, "label %u ", label);
	}

	fprintf(fp, "\n");
	fflush(fp);
	return 0;
}
示例#3
0
int print_neigh(struct nlmsghdr *n, void *arg)
{
	FILE *fp = (FILE *)arg;
	struct ndmsg *r = NLMSG_DATA(n);
	int len = n->nlmsg_len;
	struct rtattr *tb[NDA_MAX+1];
	static int logit = 1;
	__u8 protocol = 0;

	if (n->nlmsg_type != RTM_NEWNEIGH && n->nlmsg_type != RTM_DELNEIGH &&
	    n->nlmsg_type != RTM_GETNEIGH) {
		fprintf(stderr, "Not RTM_NEWNEIGH: %08x %08x %08x\n",
			n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags);

		return 0;
	}
	len -= NLMSG_LENGTH(sizeof(*r));
	if (len < 0) {
		fprintf(stderr, "BUG: wrong nlmsg len %d\n", len);
		return -1;
	}

	if (filter.flushb && n->nlmsg_type != RTM_NEWNEIGH)
		return 0;

	if (filter.family && filter.family != r->ndm_family)
		return 0;
	if (filter.index && filter.index != r->ndm_ifindex)
		return 0;
	if (!(filter.state&r->ndm_state) &&
	    !(r->ndm_flags & NTF_PROXY) &&
	    !(r->ndm_flags & NTF_EXT_LEARNED) &&
	    (r->ndm_state || !(filter.state&0x100)) &&
	    (r->ndm_family != AF_DECnet))
		return 0;

	if (filter.master && !(n->nlmsg_flags & NLM_F_DUMP_FILTERED)) {
		if (logit) {
			logit = 0;
			fprintf(fp,
				"\nWARNING: Kernel does not support filtering by master device\n\n");
		}
	}

	parse_rtattr(tb, NDA_MAX, NDA_RTA(r), n->nlmsg_len - NLMSG_LENGTH(sizeof(*r)));

	if (inet_addr_match_rta(&filter.pfx, tb[NDA_DST]))
		return 0;

	if (tb[NDA_PROTOCOL])
		protocol = rta_getattr_u8(tb[NDA_PROTOCOL]);

	if (filter.protocol && filter.protocol != protocol)
		return 0;

	if (filter.unused_only && tb[NDA_CACHEINFO]) {
		struct nda_cacheinfo *ci = RTA_DATA(tb[NDA_CACHEINFO]);

		if (ci->ndm_refcnt)
			return 0;
	}

	if (filter.flushb) {
		struct nlmsghdr *fn;

		if (NLMSG_ALIGN(filter.flushp) + n->nlmsg_len > filter.flushe) {
			if (flush_update())
				return -1;
		}
		fn = (struct nlmsghdr *)(filter.flushb + NLMSG_ALIGN(filter.flushp));
		memcpy(fn, n, n->nlmsg_len);
		fn->nlmsg_type = RTM_DELNEIGH;
		fn->nlmsg_flags = NLM_F_REQUEST;
		fn->nlmsg_seq = ++rth.seq;
		filter.flushp = (((char *)fn) + n->nlmsg_len) - filter.flushb;
		filter.flushed++;
		if (show_stats < 2)
			return 0;
	}

	open_json_object(NULL);
	if (n->nlmsg_type == RTM_DELNEIGH)
		print_bool(PRINT_ANY, "deleted", "Deleted ", true);
	else if (n->nlmsg_type == RTM_GETNEIGH)
		print_null(PRINT_ANY, "miss", "%s ", "miss");

	if (tb[NDA_DST]) {
		const char *dst;
		int family = r->ndm_family;

		if (family == AF_BRIDGE) {
			if (RTA_PAYLOAD(tb[NDA_DST]) == sizeof(struct in6_addr))
				family = AF_INET6;
			else
				family = AF_INET;
		}

		dst = format_host_rta(family, tb[NDA_DST]);
		print_color_string(PRINT_ANY,
				   ifa_family_color(family),
				   "dst", "%s ", dst);
	}

	if (!filter.index && r->ndm_ifindex) {
		if (!is_json_context())
			fprintf(fp, "dev ");

		print_color_string(PRINT_ANY, COLOR_IFNAME,
				   "dev", "%s ",
				   ll_index_to_name(r->ndm_ifindex));
	}

	if (tb[NDA_LLADDR]) {
		const char *lladdr;
		SPRINT_BUF(b1);

		lladdr = ll_addr_n2a(RTA_DATA(tb[NDA_LLADDR]),
				     RTA_PAYLOAD(tb[NDA_LLADDR]),
				     ll_index_to_type(r->ndm_ifindex),
				     b1, sizeof(b1));

		if (!is_json_context())
			fprintf(fp, "lladdr ");

		print_color_string(PRINT_ANY, COLOR_MAC,
				   "lladdr", "%s", lladdr);
	}

	if (r->ndm_flags & NTF_ROUTER)
		print_null(PRINT_ANY, "router", " %s", "router");

	if (r->ndm_flags & NTF_PROXY)
		print_null(PRINT_ANY, "proxy", " %s", "proxy");

	if (r->ndm_flags & NTF_EXT_LEARNED)
		print_null(PRINT_ANY, "extern_learn", " %s ", "extern_learn");

	if (show_stats) {
		if (tb[NDA_CACHEINFO])
			print_cacheinfo(RTA_DATA(tb[NDA_CACHEINFO]));

		if (tb[NDA_PROBES])
			print_uint(PRINT_ANY, "probes", " probes %u",
				   rta_getattr_u32(tb[NDA_PROBES]));
	}

	if (r->ndm_state)
		print_neigh_state(r->ndm_state);

	if (protocol) {
		SPRINT_BUF(b1);

		print_string(PRINT_ANY, "protocol", " proto %s ",
			     rtnl_rtprot_n2a(protocol, b1, sizeof(b1)));
	}

	print_string(PRINT_FP, NULL, "\n", "");
	close_json_object();
	fflush(stdout);

	return 0;
}