static void print_vfinfo(FILE *fp, struct rtattr *vfinfo)
{
	struct ifla_vf_mac *vf_mac;
	struct ifla_vf_vlan *vf_vlan;
	struct ifla_vf_tx_rate *vf_tx_rate;
	struct rtattr *vf[IFLA_VF_MAX+1];
	SPRINT_BUF(b1);

	if (vfinfo->rta_type != IFLA_VF_INFO) {
		fprintf(stderr, "BUG: rta type is %d\n", vfinfo->rta_type);
		return;
	}

	parse_rtattr_nested(vf, IFLA_VF_MAX, vfinfo);

	vf_mac = RTA_DATA(vf[IFLA_VF_MAC]);
	vf_vlan = RTA_DATA(vf[IFLA_VF_VLAN]);
	vf_tx_rate = RTA_DATA(vf[IFLA_VF_TX_RATE]);

	fprintf(fp, "\n    vf %d MAC %s", vf_mac->vf,
		ll_addr_n2a((unsigned char *)&vf_mac->mac,
		ETH_ALEN, 0, b1, sizeof(b1)));
	if (vf_vlan->vlan)
		fprintf(fp, ", vlan %d", vf_vlan->vlan);
	if (vf_vlan->qos)
		fprintf(fp, ", qos %d", vf_vlan->qos);
	if (vf_tx_rate->rate)
		fprintf(fp, ", tx rate %d (Mbps)", vf_tx_rate->rate);
}
Esempio n. 2
0
static void print_maddr(FILE *fp, struct ma_info *list)
{
	fprintf(fp, "\t");

	if (list->addr.family == AF_PACKET) {
		SPRINT_BUF(b1);
		fprintf(fp, "link  %s", ll_addr_n2a((unsigned char*)list->addr.data,
						    list->addr.bytelen, 0,
						    b1, sizeof(b1)));
	} else {
		char abuf[256];
		switch(list->addr.family) {
		case AF_INET:
			fprintf(fp, "inet  ");
			break;
		case AF_INET6:
			fprintf(fp, "inet6 ");
			break;
		default:
			fprintf(fp, "family %d ", list->addr.family);
			break;
		}
		fprintf(fp, "%s", 
			format_host(list->addr.family,
				    -1,
				    list->addr.data,
				    abuf, sizeof(abuf)));
	}
	if (list->users != 1)
		fprintf(fp, " users %d", list->users);
	if (list->features)
		fprintf(fp, " %s", list->features);
	fprintf(fp, "\n");
}
static void bond_slave_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
{
	SPRINT_BUF(b1);
	if (!tb)
		return;

	if (tb[IFLA_BOND_SLAVE_STATE])
		print_slave_state(f, tb[IFLA_BOND_SLAVE_STATE]);

	if (tb[IFLA_BOND_SLAVE_MII_STATUS])
		print_slave_mii_status(f, tb[IFLA_BOND_SLAVE_MII_STATUS]);

	if (tb[IFLA_BOND_SLAVE_LINK_FAILURE_COUNT])
		fprintf(f, "link_failure_count %d ",
			rta_getattr_u32(tb[IFLA_BOND_SLAVE_LINK_FAILURE_COUNT]));

	if (tb[IFLA_BOND_SLAVE_PERM_HWADDR])
		fprintf(f, "perm_hwaddr %s ",
			ll_addr_n2a(RTA_DATA(tb[IFLA_BOND_SLAVE_PERM_HWADDR]),
				    RTA_PAYLOAD(tb[IFLA_BOND_SLAVE_PERM_HWADDR]),
				    0, b1, sizeof(b1)));

	if (tb[IFLA_BOND_SLAVE_QUEUE_ID])
		fprintf(f, "queue_id %d ",
			rta_getattr_u16(tb[IFLA_BOND_SLAVE_QUEUE_ID]));

	if (tb[IFLA_BOND_SLAVE_AD_AGGREGATOR_ID])
		fprintf(f, "ad_aggregator_id %d ",
			rta_getattr_u16(tb[IFLA_BOND_SLAVE_AD_AGGREGATOR_ID]));
}
Esempio n. 4
0
static void hsr_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
{
	SPRINT_BUF(b1);

	if (!tb)
		return;

	if (tb[IFLA_HSR_SLAVE1] &&
	    RTA_PAYLOAD(tb[IFLA_HSR_SLAVE1]) < sizeof(__u32))
		return;
	if (tb[IFLA_HSR_SLAVE2] &&
	    RTA_PAYLOAD(tb[IFLA_HSR_SLAVE2]) < sizeof(__u32))
		return;
	if (tb[IFLA_HSR_SEQ_NR] &&
	    RTA_PAYLOAD(tb[IFLA_HSR_SEQ_NR]) < sizeof(__u16))
		return;
	if (tb[IFLA_HSR_SUPERVISION_ADDR] &&
	    RTA_PAYLOAD(tb[IFLA_HSR_SUPERVISION_ADDR]) < ETH_ALEN)
		return;

	if (tb[IFLA_HSR_SLAVE1])
		print_string(PRINT_ANY,
			     "slave1",
			     "slave1 %s ",
			     ll_index_to_name(rta_getattr_u32(tb[IFLA_HSR_SLAVE1])));
	else
		print_null(PRINT_ANY, "slave1", "slave1 %s ", "<none>");

	if (tb[IFLA_HSR_SLAVE2])
		print_string(PRINT_ANY,
			     "slave2",
			     "slave2 %s ",
			     ll_index_to_name(rta_getattr_u32(tb[IFLA_HSR_SLAVE2])));
	else
		print_null(PRINT_ANY, "slave2", "slave2 %s ", "<none>");

	if (tb[IFLA_HSR_SEQ_NR])
		print_int(PRINT_ANY,
			  "seq_nr",
			  "sequence %d ",
			  rta_getattr_u16(tb[IFLA_HSR_SEQ_NR]));

	if (tb[IFLA_HSR_SUPERVISION_ADDR])
		print_string(PRINT_ANY,
			     "supervision_addr",
			     "supervision %s ",
			     ll_addr_n2a(RTA_DATA(tb[IFLA_HSR_SUPERVISION_ADDR]),
					 RTA_PAYLOAD(tb[IFLA_HSR_SUPERVISION_ADDR]),
					 ARPHRD_VOID,
					 b1, sizeof(b1)));
}
Esempio n. 5
0
static void print_vfinfo(FILE *fp, struct rtattr *vfinfo)
{
	struct ifla_vf_mac *vf_mac;
	struct ifla_vf_vlan *vf_vlan;
	struct ifla_vf_tx_rate *vf_tx_rate;
	struct ifla_vf_spoofchk *vf_spoofchk;
	struct rtattr *vf[IFLA_VF_MAX+1];
	struct rtattr *tmp;
	SPRINT_BUF(b1);

	if (vfinfo->rta_type != IFLA_VF_INFO) {
		fprintf(stderr, "BUG: rta type is %d\n", vfinfo->rta_type);
		return;
	}

	parse_rtattr_nested(vf, IFLA_VF_MAX, vfinfo);

	vf_mac = RTA_DATA(vf[IFLA_VF_MAC]);
	vf_vlan = RTA_DATA(vf[IFLA_VF_VLAN]);
	vf_tx_rate = RTA_DATA(vf[IFLA_VF_TX_RATE]);

	/* Check if the spoof checking vf info type is supported by
	 * this kernel.
	 */
	tmp = (struct rtattr *)((char *)vf[IFLA_VF_TX_RATE] +
			vf[IFLA_VF_TX_RATE]->rta_len);

	if (tmp->rta_type != IFLA_VF_SPOOFCHK)
		vf_spoofchk = NULL;
	else
		vf_spoofchk = RTA_DATA(vf[IFLA_VF_SPOOFCHK]);

	fprintf(fp, "\n    vf %d MAC %s", vf_mac->vf,
		ll_addr_n2a((unsigned char *)&vf_mac->mac,
		ETH_ALEN, 0, b1, sizeof(b1)));
	if (vf_vlan->vlan)
		fprintf(fp, ", vlan %d", vf_vlan->vlan);
	if (vf_vlan->qos)
		fprintf(fp, ", qos %d", vf_vlan->qos);
	if (vf_tx_rate->rate)
		fprintf(fp, ", tx rate %d (Mbps)", vf_tx_rate->rate);
	if (vf_spoofchk && vf_spoofchk->setting != -1) {
		if (vf_spoofchk->setting)
			fprintf(fp, ", spoof checking on");
		else
			fprintf(fp, ", spoof checking off");
	}
}
Esempio n. 6
0
File: utils.c Progetto: dtaht/tc-adv
const char *rt_addr_n2a_r(int af, int len,
			  const void *addr, char *buf, int buflen)
{
	switch (af) {
	case AF_INET:
	case AF_INET6:
		return inet_ntop(af, addr, buf, buflen);
	case AF_MPLS:
		return mpls_ntop(af, addr, buf, buflen);
	case AF_IPX:
		return ipx_ntop(af, addr, buf, buflen);
	case AF_DECnet:
	{
		struct dn_naddr dna = { 2, { 0, 0, } };

		memcpy(dna.a_addr, addr, 2);
		return dnet_ntop(af, &dna, buf, buflen);
	}
	case AF_PACKET:
		return ll_addr_n2a(addr, len, ARPHRD_VOID, buf, buflen);
	case AF_BRIDGE:
	{
		const union {
			struct sockaddr sa;
			struct sockaddr_in sin;
			struct sockaddr_in6 sin6;
		} *sa = addr;

		switch (sa->sa.sa_family) {
		case AF_INET:
			return inet_ntop(AF_INET, &sa->sin.sin_addr,
					 buf, buflen);
		case AF_INET6:
			return inet_ntop(AF_INET6, &sa->sin6.sin6_addr,
					 buf, buflen);
		}

		/* fallthrough */
	}
	default:
		return "???";
	}
}
Esempio n. 7
0
const char *rt_addr_n2a(int af, int len, const void *addr, char *buf, int buflen)
{
	switch (af) {
	case AF_INET:
	case AF_INET6:
		return inet_ntop(af, addr, buf, buflen);
	case AF_MPLS:
		return mpls_ntop(af, addr, buf, buflen);
	case AF_IPX:
		return ipx_ntop(af, addr, buf, buflen);
	case AF_DECnet:
	{
		struct dn_naddr dna = { 2, { 0, 0, }};
		memcpy(dna.a_addr, addr, 2);
		return dnet_ntop(af, &dna, buf, buflen);
	}
	case AF_PACKET:
		return ll_addr_n2a(addr, len, ARPHRD_VOID, buf, buflen);
	default:
		return "???";
	}
}
Esempio n. 8
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;
}
Esempio n. 9
0
int print_neigh(const struct sockaddr_nl *who, 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];
	char abuf[256];

	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_state || !(filter.state&0x100)) &&
             (r->ndm_family != AF_DECnet))
		return 0;

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

	if (tb[NDA_DST]) {
		if (filter.pfx.family) {
			inet_prefix dst;
			memset(&dst, 0, sizeof(dst));
			dst.family = r->ndm_family;
			memcpy(&dst.data, RTA_DATA(tb[NDA_DST]), RTA_PAYLOAD(tb[NDA_DST]));
			if (inet_addr_match(&dst, &filter.pfx, filter.pfx.bitlen))
				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;
	}

	if (n->nlmsg_type == RTM_DELNEIGH)
		fprintf(fp, "delete ");
	else if (n->nlmsg_type == RTM_GETNEIGH)
		fprintf(fp, "miss ");
	if (tb[NDA_DST]) {
		fprintf(fp, "%s ",
			format_host(r->ndm_family,
				    RTA_PAYLOAD(tb[NDA_DST]),
				    RTA_DATA(tb[NDA_DST]),
				    abuf, sizeof(abuf)));
	}
	if (!filter.index && r->ndm_ifindex)
		fprintf(fp, "dev %s ", ll_index_to_name(r->ndm_ifindex));
	if (tb[NDA_LLADDR]) {
		SPRINT_BUF(b1);
		fprintf(fp, "lladdr %s", ll_addr_n2a(RTA_DATA(tb[NDA_LLADDR]),
					      RTA_PAYLOAD(tb[NDA_LLADDR]),
					      ll_index_to_type(r->ndm_ifindex),
					      b1, sizeof(b1)));
	}
	if (r->ndm_flags & NTF_ROUTER) {
		fprintf(fp, " router");
	}
	if (r->ndm_flags & NTF_PROXY) {
		fprintf(fp, " proxy");
	}
	if (tb[NDA_CACHEINFO] && show_stats) {
		struct nda_cacheinfo *ci = RTA_DATA(tb[NDA_CACHEINFO]);
		int hz = get_user_hz();

		if (ci->ndm_refcnt)
			printf(" ref %d", ci->ndm_refcnt);
		fprintf(fp, " used %d/%d/%d", ci->ndm_used/hz,
		       ci->ndm_confirmed/hz, ci->ndm_updated/hz);
	}

	if (tb[NDA_PROBES] && show_stats) {
		__u32 p = rta_getattr_u32(tb[NDA_PROBES]);
		fprintf(fp, " probes %u", p);
	}

	if (r->ndm_state) {
		int nud = r->ndm_state;
		fprintf(fp, " ");

#define PRINT_FLAG(f) if (nud & NUD_##f) { \
	nud &= ~NUD_##f; fprintf(fp, #f "%s", nud ? "," : ""); }
		PRINT_FLAG(INCOMPLETE);
		PRINT_FLAG(REACHABLE);
		PRINT_FLAG(STALE);
		PRINT_FLAG(DELAY);
		PRINT_FLAG(PROBE);
		PRINT_FLAG(FAILED);
		PRINT_FLAG(NOARP);
		PRINT_FLAG(PERMANENT);
#undef PRINT_FLAG
	}
	fprintf(fp, "\n");

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

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

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

    parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
    if (tb[IFLA_IFNAME] == NULL) {
        fprintf(stderr, "BUG: nil ifname\n");
        return -1;
    }
    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]) {
        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]) {
        fprintf(fp, "master %s ", ll_idx_n2a(*(int*)RTA_DATA(tb[IFLA_MASTER]), b1));
    }
#endif
    print_queuelen((char*)RTA_DATA(tb[IFLA_IFNAME]));

    {
        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 (tb[IFLA_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
                   );
        }
    }
    fprintf(fp, "\n");
    fflush(fp);
    return 0;
}
Esempio n. 11
0
File: fdb.c Progetto: SamB/iproute2
int print_fdb(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
{
	FILE *fp = arg;
	struct ndmsg *r = NLMSG_DATA(n);
	int len = n->nlmsg_len;
	struct rtattr * tb[NDA_MAX+1];

	if (n->nlmsg_type != RTM_NEWNEIGH && n->nlmsg_type != RTM_DELNEIGH) {
		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 (r->ndm_family != AF_BRIDGE)
		return 0;

	if (filter_index && filter_index != r->ndm_ifindex)
		return 0;

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

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

	if (tb[NDA_LLADDR]) {
		SPRINT_BUF(b1);
		fprintf(fp, "%s ",
			ll_addr_n2a(RTA_DATA(tb[NDA_LLADDR]),
				    RTA_PAYLOAD(tb[NDA_LLADDR]),
				    ll_index_to_type(r->ndm_ifindex),
				    b1, sizeof(b1)));
	}

	if (!filter_index && r->ndm_ifindex)
		fprintf(fp, "dev %s ", ll_index_to_name(r->ndm_ifindex));

	if (tb[NDA_DST]) {
		SPRINT_BUF(abuf);
		fprintf(fp, "dst %s ",
			format_host(AF_INET,
				    RTA_PAYLOAD(tb[NDA_DST]),
				    RTA_DATA(tb[NDA_DST]),
				    abuf, sizeof(abuf)));
	}

	if (show_stats && tb[NDA_CACHEINFO]) {
		struct nda_cacheinfo *ci = RTA_DATA(tb[NDA_CACHEINFO]);
		int hz = get_user_hz();

		fprintf(fp, " used %d/%d", ci->ndm_used/hz,
		       ci->ndm_updated/hz);
	}
	if (r->ndm_flags & NTF_SELF)
		fprintf(fp, "self ");
	if (r->ndm_flags & NTF_MASTER)
		fprintf(fp, "master ");

	fprintf(fp, "%s\n", state_n2a(r->ndm_state));
	return 0;
}
Esempio n. 12
0
static void bond_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
{
	unsigned ifindex;

	if (!tb)
		return;

	if (tb[IFLA_BOND_MODE]) {
		const char *mode = get_name(mode_tbl,
			rta_getattr_u8(tb[IFLA_BOND_MODE]));
		fprintf(f, "mode %s ", mode);
	}

	if (tb[IFLA_BOND_ACTIVE_SLAVE] &&
	    (ifindex = rta_getattr_u32(tb[IFLA_BOND_ACTIVE_SLAVE]))) {
		char buf[IFNAMSIZ];
		const char *n = if_indextoname(ifindex, buf);

		if (n)
			fprintf(f, "active_slave %s ", n);
		else
			fprintf(f, "active_slave %u ", ifindex);
	}

	if (tb[IFLA_BOND_MIIMON])
		fprintf(f, "miimon %u ", rta_getattr_u32(tb[IFLA_BOND_MIIMON]));

	if (tb[IFLA_BOND_UPDELAY])
		fprintf(f, "updelay %u ", rta_getattr_u32(tb[IFLA_BOND_UPDELAY]));

	if (tb[IFLA_BOND_DOWNDELAY])
		fprintf(f, "downdelay %u ",
			rta_getattr_u32(tb[IFLA_BOND_DOWNDELAY]));

	if (tb[IFLA_BOND_USE_CARRIER])
		fprintf(f, "use_carrier %u ",
			rta_getattr_u8(tb[IFLA_BOND_USE_CARRIER]));

	if (tb[IFLA_BOND_ARP_INTERVAL])
		fprintf(f, "arp_interval %u ",
			rta_getattr_u32(tb[IFLA_BOND_ARP_INTERVAL]));

	if (tb[IFLA_BOND_ARP_IP_TARGET]) {
		struct rtattr *iptb[BOND_MAX_ARP_TARGETS + 1];
		char buf[INET_ADDRSTRLEN];
		int i;

		parse_rtattr_nested(iptb, BOND_MAX_ARP_TARGETS,
			tb[IFLA_BOND_ARP_IP_TARGET]);

		if (iptb[0])
			fprintf(f, "arp_ip_target ");

		for (i = 0; i < BOND_MAX_ARP_TARGETS; i++) {
			if (iptb[i])
				fprintf(f, "%s",
					rt_addr_n2a(AF_INET,
						    RTA_PAYLOAD(iptb[i]),
						    RTA_DATA(iptb[i]),
						    buf,
						    INET_ADDRSTRLEN));
			if (i < BOND_MAX_ARP_TARGETS-1 && iptb[i+1])
				fprintf(f, ",");
		}

		if (iptb[0])
			fprintf(f, " ");
	}

	if (tb[IFLA_BOND_ARP_VALIDATE]) {
		const char *arp_validate = get_name(arp_validate_tbl,
			rta_getattr_u32(tb[IFLA_BOND_ARP_VALIDATE]));
		fprintf(f, "arp_validate %s ", arp_validate);
	}

	if (tb[IFLA_BOND_ARP_ALL_TARGETS]) {
		const char *arp_all_targets = get_name(arp_all_targets_tbl,
			rta_getattr_u32(tb[IFLA_BOND_ARP_ALL_TARGETS]));
		fprintf(f, "arp_all_targets %s ", arp_all_targets);
	}

	if (tb[IFLA_BOND_PRIMARY] &&
	    (ifindex = rta_getattr_u32(tb[IFLA_BOND_PRIMARY]))) {
		char buf[IFNAMSIZ];
		const char *n = if_indextoname(ifindex, buf);

		if (n)
			fprintf(f, "primary %s ", n);
		else
			fprintf(f, "primary %u ", ifindex);
	}

	if (tb[IFLA_BOND_PRIMARY_RESELECT]) {
		const char *primary_reselect = get_name(primary_reselect_tbl,
			rta_getattr_u8(tb[IFLA_BOND_PRIMARY_RESELECT]));
		fprintf(f, "primary_reselect %s ", primary_reselect);
	}

	if (tb[IFLA_BOND_FAIL_OVER_MAC]) {
		const char *fail_over_mac = get_name(fail_over_mac_tbl,
			rta_getattr_u8(tb[IFLA_BOND_FAIL_OVER_MAC]));
		fprintf(f, "fail_over_mac %s ", fail_over_mac);
	}

	if (tb[IFLA_BOND_XMIT_HASH_POLICY]) {
		const char *xmit_hash_policy = get_name(xmit_hash_policy_tbl,
			rta_getattr_u8(tb[IFLA_BOND_XMIT_HASH_POLICY]));
		fprintf(f, "xmit_hash_policy %s ", xmit_hash_policy);
	}

	if (tb[IFLA_BOND_RESEND_IGMP])
		fprintf(f, "resend_igmp %u ",
			rta_getattr_u32(tb[IFLA_BOND_RESEND_IGMP]));

	if (tb[IFLA_BOND_NUM_PEER_NOTIF])
		fprintf(f, "num_grat_arp %u ",
			rta_getattr_u8(tb[IFLA_BOND_NUM_PEER_NOTIF]));

	if (tb[IFLA_BOND_ALL_SLAVES_ACTIVE])
		fprintf(f, "all_slaves_active %u ",
			rta_getattr_u8(tb[IFLA_BOND_ALL_SLAVES_ACTIVE]));

	if (tb[IFLA_BOND_MIN_LINKS])
		fprintf(f, "min_links %u ",
			rta_getattr_u32(tb[IFLA_BOND_MIN_LINKS]));

	if (tb[IFLA_BOND_LP_INTERVAL])
		fprintf(f, "lp_interval %u ",
			rta_getattr_u32(tb[IFLA_BOND_LP_INTERVAL]));

	if (tb[IFLA_BOND_PACKETS_PER_SLAVE])
		fprintf(f, "packets_per_slave %u ",
			rta_getattr_u32(tb[IFLA_BOND_PACKETS_PER_SLAVE]));

	if (tb[IFLA_BOND_AD_LACP_RATE]) {
		const char *lacp_rate = get_name(lacp_rate_tbl,
			rta_getattr_u8(tb[IFLA_BOND_AD_LACP_RATE]));
		fprintf(f, "lacp_rate %s ", lacp_rate);
	}

	if (tb[IFLA_BOND_AD_SELECT]) {
		const char *ad_select = get_name(ad_select_tbl,
			rta_getattr_u8(tb[IFLA_BOND_AD_SELECT]));
		fprintf(f, "ad_select %s ", ad_select);
	}

	if (tb[IFLA_BOND_AD_INFO]) {
		struct rtattr *adtb[IFLA_BOND_AD_INFO_MAX + 1];

		parse_rtattr_nested(adtb, IFLA_BOND_AD_INFO_MAX,
			tb[IFLA_BOND_AD_INFO]);

		if (adtb[IFLA_BOND_AD_INFO_AGGREGATOR])
			fprintf(f, "ad_aggregator %d ",
			  rta_getattr_u16(adtb[IFLA_BOND_AD_INFO_AGGREGATOR]));

		if (adtb[IFLA_BOND_AD_INFO_NUM_PORTS])
			fprintf(f, "ad_num_ports %d ",
			  rta_getattr_u16(adtb[IFLA_BOND_AD_INFO_NUM_PORTS]));

		if (adtb[IFLA_BOND_AD_INFO_ACTOR_KEY])
			fprintf(f, "ad_actor_key %d ",
			  rta_getattr_u16(adtb[IFLA_BOND_AD_INFO_ACTOR_KEY]));

		if (adtb[IFLA_BOND_AD_INFO_PARTNER_KEY])
			fprintf(f, "ad_partner_key %d ",
			  rta_getattr_u16(adtb[IFLA_BOND_AD_INFO_PARTNER_KEY]));

		if (adtb[IFLA_BOND_AD_INFO_PARTNER_MAC]) {
			unsigned char *p =
				RTA_DATA(adtb[IFLA_BOND_AD_INFO_PARTNER_MAC]);
			SPRINT_BUF(b);
			fprintf(f, "ad_partner_mac %s ",
				ll_addr_n2a(p, ETH_ALEN, 0, b, sizeof(b)));
		}
	}

	if (tb[IFLA_BOND_AD_ACTOR_SYS_PRIO]) {
		fprintf(f, "ad_actor_sys_prio %u ",
			rta_getattr_u16(tb[IFLA_BOND_AD_ACTOR_SYS_PRIO]));
	}

	if (tb[IFLA_BOND_AD_USER_PORT_KEY]) {
		fprintf(f, "ad_user_port_key %u ",
			rta_getattr_u16(tb[IFLA_BOND_AD_USER_PORT_KEY]));
	}

	if (tb[IFLA_BOND_AD_ACTOR_SYSTEM]) {
		/* We assume the l2 address is an Ethernet MAC address */
		SPRINT_BUF(b1);
		fprintf(f, "ad_actor_system %s ",
			ll_addr_n2a(RTA_DATA(tb[IFLA_BOND_AD_ACTOR_SYSTEM]),
				    RTA_PAYLOAD(tb[IFLA_BOND_AD_ACTOR_SYSTEM]),
				    1 /*ARPHDR_ETHER*/, b1, sizeof(b1)));
	}

	if (tb[IFLA_BOND_TLB_DYNAMIC_LB]) {
		fprintf(f, "tlb_dynamic_lb %u ",
			rta_getattr_u8(tb[IFLA_BOND_TLB_DYNAMIC_LB]));
	}
}
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. 14
0
static int print_ife(struct action_util *au, FILE *f, struct rtattr *arg)
{
	struct tc_ife *p = NULL;
	struct rtattr *tb[TCA_IFE_MAX + 1];
	__u16 ife_type = 0;
	__u32 mmark = 0;
	__u16 mtcindex = 0;
	__u32 mprio = 0;
	int has_optional = 0;
	SPRINT_BUF(b2);

	if (arg == NULL)
		return -1;

	parse_rtattr_nested(tb, TCA_IFE_MAX, arg);

	if (tb[TCA_IFE_PARMS] == NULL) {
		fprintf(f, "[NULL ife parameters]");
		return -1;
	}
	p = RTA_DATA(tb[TCA_IFE_PARMS]);

	fprintf(f, "ife %s ", p->flags & IFE_ENCODE ? "encode" : "decode");
	print_action_control(f, "action ", p->action, " ");

	if (tb[TCA_IFE_TYPE]) {
		ife_type = rta_getattr_u16(tb[TCA_IFE_TYPE]);
		has_optional = 1;
		fprintf(f, "type 0x%X ", ife_type);
	}

	if (has_optional)
		fprintf(f, "\n\t ");

	if (tb[TCA_IFE_METALST]) {
		struct rtattr *metalist[IFE_META_MAX + 1];
		int len = 0;

		parse_rtattr_nested(metalist, IFE_META_MAX,
				    tb[TCA_IFE_METALST]);

		if (metalist[IFE_META_SKBMARK]) {
			len = RTA_PAYLOAD(metalist[IFE_META_SKBMARK]);
			if (len) {
				mmark = rta_getattr_u32(metalist[IFE_META_SKBMARK]);
				fprintf(f, "use mark %u ", mmark);
			} else
				fprintf(f, "allow mark ");
		}

		if (metalist[IFE_META_TCINDEX]) {
			len = RTA_PAYLOAD(metalist[IFE_META_TCINDEX]);
			if (len) {
				mtcindex =
					rta_getattr_u16(metalist[IFE_META_TCINDEX]);
				fprintf(f, "use tcindex %d ", mtcindex);
			} else
				fprintf(f, "allow tcindex ");
		}

		if (metalist[IFE_META_PRIO]) {
			len = RTA_PAYLOAD(metalist[IFE_META_PRIO]);
			if (len) {
				mprio = rta_getattr_u32(metalist[IFE_META_PRIO]);
				fprintf(f, "use prio %u ", mprio);
			} else
				fprintf(f, "allow prio ");
		}

	}

	if (tb[TCA_IFE_DMAC]) {
		has_optional = 1;
		fprintf(f, "dst %s ",
			ll_addr_n2a(RTA_DATA(tb[TCA_IFE_DMAC]),
				    RTA_PAYLOAD(tb[TCA_IFE_DMAC]), 0, b2,
				    sizeof(b2)));

	}

	if (tb[TCA_IFE_SMAC]) {
		has_optional = 1;
		fprintf(f, "src %s ",
			ll_addr_n2a(RTA_DATA(tb[TCA_IFE_SMAC]),
				    RTA_PAYLOAD(tb[TCA_IFE_SMAC]), 0, b2,
				    sizeof(b2)));
	}

	fprintf(f, "\n\t index %u ref %d bind %d", p->index, p->refcnt,
		p->bindcnt);
	if (show_stats) {
		if (tb[TCA_IFE_TM]) {
			struct tcf_t *tm = RTA_DATA(tb[TCA_IFE_TM]);

			print_tm(f, tm);
		}
	}

	fprintf(f, "\n");

	return 0;
}
Esempio n. 15
0
static void bridge_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
{
	if (!tb)
		return;

	if (tb[IFLA_BR_FORWARD_DELAY])
		print_uint(PRINT_ANY,
			   "forward_delay",
			   "forward_delay %u ",
			   rta_getattr_u32(tb[IFLA_BR_FORWARD_DELAY]));

	if (tb[IFLA_BR_HELLO_TIME])
		print_uint(PRINT_ANY,
			   "hello_time",
			   "hello_time %u ",
			   rta_getattr_u32(tb[IFLA_BR_HELLO_TIME]));

	if (tb[IFLA_BR_MAX_AGE])
		print_uint(PRINT_ANY,
			   "max_age",
			   "max_age %u ",
			   rta_getattr_u32(tb[IFLA_BR_MAX_AGE]));

	if (tb[IFLA_BR_AGEING_TIME])
		print_uint(PRINT_ANY,
			   "ageing_time",
			   "ageing_time %u ",
			   rta_getattr_u32(tb[IFLA_BR_AGEING_TIME]));

	if (tb[IFLA_BR_STP_STATE])
		print_uint(PRINT_ANY,
			   "stp_state",
			   "stp_state %u ",
			   rta_getattr_u32(tb[IFLA_BR_STP_STATE]));

	if (tb[IFLA_BR_PRIORITY])
		print_uint(PRINT_ANY,
			   "priority",
			   "priority %u ",
			   rta_getattr_u16(tb[IFLA_BR_PRIORITY]));

	if (tb[IFLA_BR_VLAN_FILTERING])
		print_uint(PRINT_ANY,
			   "vlan_filtering",
			   "vlan_filtering %u ",
			   rta_getattr_u8(tb[IFLA_BR_VLAN_FILTERING]));

	if (tb[IFLA_BR_VLAN_PROTOCOL]) {
		SPRINT_BUF(b1);

		print_string(PRINT_ANY,
			     "vlan_protocol",
			     "vlan_protocol %s ",
			     ll_proto_n2a(rta_getattr_u16(tb[IFLA_BR_VLAN_PROTOCOL]),
					  b1, sizeof(b1)));
	}

	if (tb[IFLA_BR_BRIDGE_ID]) {
		char bridge_id[32];

		br_dump_bridge_id(RTA_DATA(tb[IFLA_BR_BRIDGE_ID]), bridge_id,
				  sizeof(bridge_id));
		print_string(PRINT_ANY,
			     "bridge_id",
			     "bridge_id %s ",
			     bridge_id);
	}

	if (tb[IFLA_BR_ROOT_ID]) {
		char root_id[32];

		br_dump_bridge_id(RTA_DATA(tb[IFLA_BR_BRIDGE_ID]), root_id,
				  sizeof(root_id));
		print_string(PRINT_ANY,
			     "root_id",
			     "designated_root %s ",
			     root_id);
	}

	if (tb[IFLA_BR_ROOT_PORT])
		print_uint(PRINT_ANY,
			   "root_port",
			   "root_port %u ",
			   rta_getattr_u16(tb[IFLA_BR_ROOT_PORT]));

	if (tb[IFLA_BR_ROOT_PATH_COST])
		print_uint(PRINT_ANY,
			   "root_path_cost",
			   "root_path_cost %u ",
			   rta_getattr_u32(tb[IFLA_BR_ROOT_PATH_COST]));

	if (tb[IFLA_BR_TOPOLOGY_CHANGE])
		print_uint(PRINT_ANY,
			   "topology_change",
			   "topology_change %u ",
			   rta_getattr_u8(tb[IFLA_BR_TOPOLOGY_CHANGE]));

	if (tb[IFLA_BR_TOPOLOGY_CHANGE_DETECTED])
		print_uint(PRINT_ANY,
			   "topology_change_detected",
			   "topology_change_detected %u ",
			   rta_getattr_u8(tb[IFLA_BR_TOPOLOGY_CHANGE_DETECTED]));

	if (tb[IFLA_BR_HELLO_TIMER])
		_bridge_print_timer(f, "hello_timer", tb[IFLA_BR_HELLO_TIMER]);

	if (tb[IFLA_BR_TCN_TIMER])
		_bridge_print_timer(f, "tcn_timer", tb[IFLA_BR_TCN_TIMER]);

	if (tb[IFLA_BR_TOPOLOGY_CHANGE_TIMER])
		_bridge_print_timer(f, "topology_change_timer",
				    tb[IFLA_BR_TOPOLOGY_CHANGE_TIMER]);

	if (tb[IFLA_BR_GC_TIMER])
		_bridge_print_timer(f, "gc_timer", tb[IFLA_BR_GC_TIMER]);

	if (tb[IFLA_BR_VLAN_DEFAULT_PVID])
		print_uint(PRINT_ANY,
			   "vlan_default_pvid",
			   "vlan_default_pvid %u ",
			   rta_getattr_u16(tb[IFLA_BR_VLAN_DEFAULT_PVID]));

	if (tb[IFLA_BR_VLAN_STATS_ENABLED])
		print_uint(PRINT_ANY,
			   "vlan_stats_enabled",
			   "vlan_stats_enabled %u ",
			   rta_getattr_u8(tb[IFLA_BR_VLAN_STATS_ENABLED]));

	if (tb[IFLA_BR_GROUP_FWD_MASK])
		print_0xhex(PRINT_ANY,
			    "group_fwd_mask",
			    "group_fwd_mask %#llx ",
			    rta_getattr_u16(tb[IFLA_BR_GROUP_FWD_MASK]));

	if (tb[IFLA_BR_GROUP_ADDR]) {
		SPRINT_BUF(mac);

		print_string(PRINT_ANY,
			     "group_addr",
			     "group_address %s ",
			     ll_addr_n2a(RTA_DATA(tb[IFLA_BR_GROUP_ADDR]),
					 RTA_PAYLOAD(tb[IFLA_BR_GROUP_ADDR]),
					 1 /*ARPHDR_ETHER*/, mac, sizeof(mac)));
	}

	if (tb[IFLA_BR_MCAST_SNOOPING])
		print_uint(PRINT_ANY,
			   "mcast_snooping",
			   "mcast_snooping %u ",
			   rta_getattr_u8(tb[IFLA_BR_MCAST_SNOOPING]));

	if (tb[IFLA_BR_MCAST_ROUTER])
		print_uint(PRINT_ANY,
			   "mcast_router",
			   "mcast_router %u ",
			   rta_getattr_u8(tb[IFLA_BR_MCAST_ROUTER]));

	if (tb[IFLA_BR_MCAST_QUERY_USE_IFADDR])
		print_uint(PRINT_ANY,
			   "mcast_query_use_ifaddr",
			   "mcast_query_use_ifaddr %u ",
			   rta_getattr_u8(tb[IFLA_BR_MCAST_QUERY_USE_IFADDR]));

	if (tb[IFLA_BR_MCAST_QUERIER])
		print_uint(PRINT_ANY,
			   "mcast_querier",
			   "mcast_querier %u ",
			   rta_getattr_u8(tb[IFLA_BR_MCAST_QUERIER]));

	if (tb[IFLA_BR_MCAST_HASH_ELASTICITY])
		print_uint(PRINT_ANY,
			   "mcast_hash_elasticity",
			   "mcast_hash_elasticity %u ",
			   rta_getattr_u32(tb[IFLA_BR_MCAST_HASH_ELASTICITY]));

	if (tb[IFLA_BR_MCAST_HASH_MAX])
		print_uint(PRINT_ANY,
			   "mcast_hash_max",
			   "mcast_hash_max %u ",
			   rta_getattr_u32(tb[IFLA_BR_MCAST_HASH_MAX]));

	if (tb[IFLA_BR_MCAST_LAST_MEMBER_CNT])
		print_uint(PRINT_ANY,
			   "mcast_last_member_cnt",
			   "mcast_last_member_count %u ",
			   rta_getattr_u32(tb[IFLA_BR_MCAST_LAST_MEMBER_CNT]));

	if (tb[IFLA_BR_MCAST_STARTUP_QUERY_CNT])
		print_uint(PRINT_ANY,
			   "mcast_startup_query_cnt",
			   "mcast_startup_query_count %u ",
			   rta_getattr_u32(tb[IFLA_BR_MCAST_STARTUP_QUERY_CNT]));

	if (tb[IFLA_BR_MCAST_LAST_MEMBER_INTVL])
		print_lluint(PRINT_ANY,
			     "mcast_last_member_intvl",
			     "mcast_last_member_interval %llu ",
			     rta_getattr_u64(tb[IFLA_BR_MCAST_LAST_MEMBER_INTVL]));

	if (tb[IFLA_BR_MCAST_MEMBERSHIP_INTVL])
		print_lluint(PRINT_ANY,
			     "mcast_membership_intvl",
			     "mcast_membership_interval %llu ",
			     rta_getattr_u64(tb[IFLA_BR_MCAST_MEMBERSHIP_INTVL]));

	if (tb[IFLA_BR_MCAST_QUERIER_INTVL])
		print_lluint(PRINT_ANY,
			     "mcast_querier_intvl",
			     "mcast_querier_interval %llu ",
			     rta_getattr_u64(tb[IFLA_BR_MCAST_QUERIER_INTVL]));

	if (tb[IFLA_BR_MCAST_QUERY_INTVL])
		print_lluint(PRINT_ANY,
			     "mcast_query_intvl",
			     "mcast_query_interval %llu ",
			     rta_getattr_u64(tb[IFLA_BR_MCAST_QUERY_INTVL]));

	if (tb[IFLA_BR_MCAST_QUERY_RESPONSE_INTVL])
		print_lluint(PRINT_ANY,
			     "mcast_query_response_intvl",
			     "mcast_query_response_interval %llu ",
			     rta_getattr_u64(tb[IFLA_BR_MCAST_QUERY_RESPONSE_INTVL]));

	if (tb[IFLA_BR_MCAST_STARTUP_QUERY_INTVL])
		print_lluint(PRINT_ANY,
			     "mcast_startup_query_intvl",
			     "mcast_startup_query_interval %llu ",
			     rta_getattr_u64(tb[IFLA_BR_MCAST_STARTUP_QUERY_INTVL]));

	if (tb[IFLA_BR_MCAST_STATS_ENABLED])
		print_uint(PRINT_ANY,
			   "mcast_stats_enabled",
			   "mcast_stats_enabled %u ",
			   rta_getattr_u8(tb[IFLA_BR_MCAST_STATS_ENABLED]));

	if (tb[IFLA_BR_MCAST_IGMP_VERSION])
		print_uint(PRINT_ANY,
			   "mcast_igmp_version",
			   "mcast_igmp_version %u ",
			   rta_getattr_u8(tb[IFLA_BR_MCAST_IGMP_VERSION]));

	if (tb[IFLA_BR_MCAST_MLD_VERSION])
		print_uint(PRINT_ANY,
			   "mcast_mld_version",
			   "mcast_mld_version %u ",
			   rta_getattr_u8(tb[IFLA_BR_MCAST_MLD_VERSION]));

	if (tb[IFLA_BR_NF_CALL_IPTABLES])
		print_uint(PRINT_ANY,
			   "nf_call_iptables",
			   "nf_call_iptables %u ",
			   rta_getattr_u8(tb[IFLA_BR_NF_CALL_IPTABLES]));

	if (tb[IFLA_BR_NF_CALL_IP6TABLES])
		print_uint(PRINT_ANY,
			   "nf_call_ip6tables",
			   "nf_call_ip6tables %u ",
			   rta_getattr_u8(tb[IFLA_BR_NF_CALL_IP6TABLES]));

	if (tb[IFLA_BR_NF_CALL_ARPTABLES])
		print_uint(PRINT_ANY,
			   "nf_call_arptables",
			   "nf_call_arptables %u ",
			   rta_getattr_u8(tb[IFLA_BR_NF_CALL_ARPTABLES]));
}
Esempio n. 16
0
static void read_dev_mcast(struct ma_info **result_p)
{
	char buf[256];
	FILE *fp = fopen("/proc/net/dev_mcast", "r");

	if (!fp)
		return;

	while (fgets(buf, sizeof(buf), fp)) {
		char hexa[256];
		struct ma_info m = { .addr.family = AF_PACKET };
		int len;
		int st;

		sscanf(buf, "%d%s%d%d%s", &m.index, m.name, &m.users, &st,
		       hexa);
		if (filter.dev && strcmp(filter.dev, m.name))
			continue;

		len = parse_hex(hexa, (unsigned char *)&m.addr.data, sizeof(m.addr.data));
		if (len >= 0) {
			struct ma_info *ma = malloc(sizeof(m));

			memcpy(ma, &m, sizeof(m));
			ma->addr.bytelen = len;
			ma->addr.bitlen = len<<3;
			if (st)
				ma->features = "static";
			maddr_ins(result_p, ma);
		}
	}
	fclose(fp);
}

static void read_igmp(struct ma_info **result_p)
{
	struct ma_info m = {
		.addr.family = AF_INET,
		.addr.bitlen = 32,
		.addr.bytelen = 4,
	};
	char buf[256];
	FILE *fp = fopen("/proc/net/igmp", "r");

	if (!fp)
		return;
	if (!fgets(buf, sizeof(buf), fp)) {
		fclose(fp);
		return;
	}

	while (fgets(buf, sizeof(buf), fp)) {
		struct ma_info *ma;
		size_t len;

		if (buf[0] != '\t') {
			sscanf(buf, "%d%s", &m.index, m.name);
			len = strlen(m.name);
			if (m.name[len - 1] == ':')
				len--;
			continue;
		}

		if (filter.dev && strncmp(filter.dev, m.name, len))
			continue;

		sscanf(buf, "%08x%d", (__u32 *)&m.addr.data, &m.users);

		ma = malloc(sizeof(m));
		memcpy(ma, &m, sizeof(m));
		maddr_ins(result_p, ma);
	}
	fclose(fp);
}


static void read_igmp6(struct ma_info **result_p)
{
	char buf[256];
	FILE *fp = fopen("/proc/net/igmp6", "r");

	if (!fp)
		return;

	while (fgets(buf, sizeof(buf), fp)) {
		char hexa[256];
		struct ma_info m = { .addr.family = AF_INET6 };
		int len;

		sscanf(buf, "%d%s%s%d", &m.index, m.name, hexa, &m.users);

		if (filter.dev && strcmp(filter.dev, m.name))
			continue;

		len = parse_hex(hexa, (unsigned char *)&m.addr.data, sizeof(m.addr.data));
		if (len >= 0) {
			struct ma_info *ma = malloc(sizeof(m));

			memcpy(ma, &m, sizeof(m));

			ma->addr.bytelen = len;
			ma->addr.bitlen = len<<3;
			maddr_ins(result_p, ma);
		}
	}
	fclose(fp);
}

static void print_maddr(FILE *fp, struct ma_info *list)
{
	fprintf(fp, "\t");

	if (list->addr.family == AF_PACKET) {
		SPRINT_BUF(b1);
		fprintf(fp, "link  %s", ll_addr_n2a((unsigned char *)list->addr.data,
						    list->addr.bytelen, 0,
						    b1, sizeof(b1)));
	} else {
		switch (list->addr.family) {
		case AF_INET:
			fprintf(fp, "inet  ");
			break;
		case AF_INET6:
			fprintf(fp, "inet6 ");
			break;
		default:
			fprintf(fp, "family %d ", list->addr.family);
			break;
		}
		fprintf(fp, "%s",
			format_host(list->addr.family,
				    -1, list->addr.data));
	}
	if (list->users != 1)
		fprintf(fp, " users %d", list->users);
	if (list->features)
		fprintf(fp, " %s", list->features);
	fprintf(fp, "\n");
}

static void print_mlist(FILE *fp, struct ma_info *list)
{
	int cur_index = 0;

	for (; list; list = list->next) {
		if (oneline) {
			cur_index = list->index;
			fprintf(fp, "%d:\t%s%s", cur_index, list->name, _SL_);
		} else if (cur_index != list->index) {
			cur_index = list->index;
			fprintf(fp, "%d:\t%s\n", cur_index, list->name);
		}
		print_maddr(fp, list);
	}
}
Esempio n. 17
0
int main(int argc, char **argv)
{
	int opt;
	int do_list = 0;
	char *do_load = NULL;

	while ((opt = getopt(argc, argv, "h?b:lf:a:n:p:kR:B:")) != EOF) {
		switch (opt) {
	        case 'b':
			dbname = optarg;
			break;
		case 'f':
			if (do_load) {
				fprintf(stderr, "Duplicate option -f\n");
				usage();
			}
			do_load = optarg;
			break;
		case 'l':
			do_list = 1;
			break;
		case 'a':
			active_probing = atoi(optarg);
			break;
		case 'n':
			negative_timeout = atoi(optarg);
			break;
		case 'k':
			no_kernel_broadcasts = 1;
			break;
		case 'p':
			if ((poll_timeout = 1000 * strtod(optarg, NULL)) < 100) {
				fprintf(stderr,"Invalid poll timeout\n");
				exit(-1);
			}
			break;
		case 'R':
			if ((broadcast_rate = atoi(optarg)) <= 0 ||
			    (broadcast_rate = 1000/broadcast_rate) <= 0) {
				fprintf(stderr, "Invalid ARP rate\n");
				exit(-1);
			}
			break;
		case 'B':
			if ((broadcast_burst = atoi(optarg)) <= 0 ||
			    (broadcast_burst = 1000*broadcast_burst) <= 0) {
				fprintf(stderr, "Invalid ARP burst\n");
				exit(-1);
			}
			break;
		case 'h':
		case '?':
		default:
			usage();
		}
	}
	argc -= optind;
	argv += optind;

	if (argc > 0) {
		ifnum = argc;
		ifnames = argv;
		ifvec = malloc(argc*sizeof(int));
		if (!ifvec) {
			perror("malloc");
			exit(-1);
		}
	}

	if ((udp_sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
		perror("socket");
		exit(-1);
	}

        if (ifnum) {
		int i;
		struct ifreq ifr;
		memset(&ifr, 0, sizeof(ifr));
		for (i=0; i<ifnum; i++) {
			strncpy(ifr.ifr_name, ifnames[i], IFNAMSIZ);
			if (ioctl(udp_sock, SIOCGIFINDEX, &ifr)) {
				perror("ioctl(SIOCGIFINDEX)");
				exit(-1);;
			}
			ifvec[i] = ifr.ifr_ifindex;
		}
	}

	dbase = dbopen(dbname, O_CREAT|O_RDWR, 0644, DB_HASH, NULL);
	if (dbase == NULL) {
		perror("db_open");
		exit(-1);
	}

	if (do_load) {
		char buf[128];
		FILE *fp;
		struct dbkey k;
		DBT dbkey, dbdat;

		dbkey.data = &k;
		dbkey.size = sizeof(k);

		if (strcmp(do_load, "-") == 0 || strcmp(do_load, "--") == 0) {
			fp = stdin;
		} else if ((fp = fopen(do_load, "r")) == NULL) {
			perror("fopen");
			goto do_abort;
		}

		buf[sizeof(buf)-1] = 0;
		while (fgets(buf, sizeof(buf)-1, fp)) {
			__u8 b1[6];
			char ipbuf[128];
			char macbuf[128];

			if (buf[0] == '#')
				continue;

			if (sscanf(buf, "%u%s%s", &k.iface, ipbuf, macbuf) != 3) {
				fprintf(stderr, "Wrong format of input file \"%s\"\n", do_load);
				goto do_abort;
			}
			if (strncmp(macbuf, "FAILED:", 7) == 0)
				continue;
			if (!inet_aton(ipbuf, (struct in_addr*)&k.addr)) {
				fprintf(stderr, "Invalid IP address: \"%s\"\n", ipbuf);
				goto do_abort;
			}

			if (ll_addr_a2n((char *) b1, 6, macbuf) != 6)
				goto do_abort;
			dbdat.size = 6;

			if (dbase->put(dbase, &dbkey, &dbdat, 0)) {
				perror("hash->put");
				goto do_abort;
			}
		}
		dbase->sync(dbase, 0);
		if (fp != stdin)
			fclose(fp);
	}

	if (do_list) {
		DBT dbkey, dbdat;
		printf("%-8s %-15s %s\n", "#Ifindex", "IP", "MAC");
		while (dbase->seq(dbase, &dbkey, &dbdat, R_NEXT) == 0) {
			struct dbkey *key = dbkey.data;
			if (handle_if(key->iface)) {
				if (!IS_NEG(dbdat.data)) {
					char b1[18];
					printf("%-8d %-15s %s\n",
					       key->iface,
					       inet_ntoa(*(struct in_addr*)&key->addr),
					       ll_addr_n2a(dbdat.data, 6, ARPHRD_ETHER, b1, 18));
				} else {
					printf("%-8d %-15s FAILED: %dsec ago\n",
					       key->iface,
					       inet_ntoa(*(struct in_addr*)&key->addr),
					       NEG_AGE(dbdat.data));
				}
			}
		}
	}

	if (do_load || do_list)
		goto out;

	pset[0].fd = socket(PF_PACKET, SOCK_DGRAM, 0);
	if (pset[0].fd < 0) {
		perror("socket");
		exit(-1);
	}

	if (1) {
		struct sockaddr_ll sll;
		memset(&sll, 0, sizeof(sll));
		sll.sll_family = AF_PACKET;
		sll.sll_protocol = htons(ETH_P_ARP);
		sll.sll_ifindex = (ifnum == 1 ? ifvec[0] : 0);
		if (bind(pset[0].fd, (struct sockaddr*)&sll, sizeof(sll)) < 0) {
			perror("bind");
			goto do_abort;
		}
	}

	if (rtnl_open(&rth, RTMGRP_NEIGH) < 0) {
		perror("rtnl_open");
		goto do_abort;
	}
	pset[1].fd = rth.fd;

	load_initial_table();

	if (daemon(0, 0)) {
		perror("arpd: daemon");
		goto do_abort;
	}

	openlog("arpd", LOG_PID | LOG_CONS, LOG_DAEMON);
	catch_signal(SIGINT, sig_exit);
	catch_signal(SIGTERM, sig_exit);
	catch_signal(SIGHUP, sig_sync);
	catch_signal(SIGUSR1, sig_stats);

#define EVENTS (POLLIN|POLLPRI|POLLERR|POLLHUP)
	pset[0].events = EVENTS;
	pset[0].revents = 0;
	pset[1].events = EVENTS;
	pset[1].revents = 0;

	sigsetjmp(env, 1);

	for (;;) {
		in_poll = 1;

		if (do_exit)
			break;
		if (do_sync) {
			in_poll = 0;
			dbase->sync(dbase, 0);
			do_sync = 0;
			in_poll = 1;
		}
		if (do_stats)
			send_stats();
		if (poll(pset, 2, poll_timeout) > 0) {
			in_poll = 0;
			if (pset[0].revents&EVENTS)
				get_arp_pkt();
			if (pset[1].revents&EVENTS)
				get_kern_msg();
		} else {
			do_sync = 1;
		}
	}

	undo_sysctl_adjustments();
out:
	dbase->close(dbase);
	exit(0);

do_abort:
	dbase->close(dbase);
	exit(-1);
}
Esempio n. 18
0
static void bridge_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
{
	if (!tb)
		return;

	if (tb[IFLA_BR_FORWARD_DELAY])
		fprintf(f, "forward_delay %u ",
			rta_getattr_u32(tb[IFLA_BR_FORWARD_DELAY]));

	if (tb[IFLA_BR_HELLO_TIME])
		fprintf(f, "hello_time %u ",
			rta_getattr_u32(tb[IFLA_BR_HELLO_TIME]));

	if (tb[IFLA_BR_MAX_AGE])
		fprintf(f, "max_age %u ",
			rta_getattr_u32(tb[IFLA_BR_MAX_AGE]));

	if (tb[IFLA_BR_AGEING_TIME])
		fprintf(f, "ageing_time %u ",
			rta_getattr_u32(tb[IFLA_BR_AGEING_TIME]));

	if (tb[IFLA_BR_STP_STATE])
		fprintf(f, "stp_state %u ",
			rta_getattr_u32(tb[IFLA_BR_STP_STATE]));

	if (tb[IFLA_BR_PRIORITY])
		fprintf(f, "priority %u ",
			rta_getattr_u16(tb[IFLA_BR_PRIORITY]));

	if (tb[IFLA_BR_VLAN_FILTERING])
		fprintf(f, "vlan_filtering %u ",
			rta_getattr_u8(tb[IFLA_BR_VLAN_FILTERING]));

	if (tb[IFLA_BR_VLAN_PROTOCOL]) {
		SPRINT_BUF(b1);

		fprintf(f, "vlan_protocol %s ",
			ll_proto_n2a(rta_getattr_u16(tb[IFLA_BR_VLAN_PROTOCOL]),
				     b1, sizeof(b1)));
	}

	if (tb[IFLA_BR_BRIDGE_ID]) {
		char bridge_id[32];

		br_dump_bridge_id(RTA_DATA(tb[IFLA_BR_BRIDGE_ID]), bridge_id,
				  sizeof(bridge_id));
		fprintf(f, "bridge_id %s ", bridge_id);
	}

	if (tb[IFLA_BR_ROOT_ID]) {
		char root_id[32];

		br_dump_bridge_id(RTA_DATA(tb[IFLA_BR_BRIDGE_ID]), root_id,
				  sizeof(root_id));
		fprintf(f, "designated_root %s ", root_id);
	}

	if (tb[IFLA_BR_ROOT_PORT])
		fprintf(f, "root_port %u ",
			rta_getattr_u16(tb[IFLA_BR_ROOT_PORT]));

	if (tb[IFLA_BR_ROOT_PATH_COST])
		fprintf(f, "root_path_cost %u ",
			rta_getattr_u32(tb[IFLA_BR_ROOT_PATH_COST]));

	if (tb[IFLA_BR_TOPOLOGY_CHANGE])
		fprintf(f, "topology_change %u ",
			rta_getattr_u8(tb[IFLA_BR_TOPOLOGY_CHANGE]));

	if (tb[IFLA_BR_TOPOLOGY_CHANGE_DETECTED])
		fprintf(f, "topology_change_detected %u ",
			rta_getattr_u8(tb[IFLA_BR_TOPOLOGY_CHANGE_DETECTED]));

	if (tb[IFLA_BR_HELLO_TIMER]) {
		struct timeval tv;

		__jiffies_to_tv(&tv, rta_getattr_u64(tb[IFLA_BR_HELLO_TIMER]));
		fprintf(f, "hello_timer %4i.%.2i ", (int)tv.tv_sec,
			(int)tv.tv_usec/10000);
	}

	if (tb[IFLA_BR_TCN_TIMER]) {
		struct timeval tv;

		__jiffies_to_tv(&tv, rta_getattr_u64(tb[IFLA_BR_TCN_TIMER]));
		fprintf(f, "tcn_timer %4i.%.2i ", (int)tv.tv_sec,
			(int)tv.tv_usec/10000);
	}

	if (tb[IFLA_BR_TOPOLOGY_CHANGE_TIMER]) {
		unsigned long jiffies;
		struct timeval tv;

		jiffies = rta_getattr_u64(tb[IFLA_BR_TOPOLOGY_CHANGE_TIMER]);
		__jiffies_to_tv(&tv, jiffies);
		fprintf(f, "topology_change_timer %4i.%.2i ", (int)tv.tv_sec,
			(int)tv.tv_usec/10000);
	}

	if (tb[IFLA_BR_GC_TIMER]) {
		struct timeval tv;

		__jiffies_to_tv(&tv, rta_getattr_u64(tb[IFLA_BR_GC_TIMER]));
		fprintf(f, "gc_timer %4i.%.2i ", (int)tv.tv_sec,
			(int)tv.tv_usec/10000);
	}

	if (tb[IFLA_BR_VLAN_DEFAULT_PVID])
		fprintf(f, "vlan_default_pvid %u ",
			rta_getattr_u16(tb[IFLA_BR_VLAN_DEFAULT_PVID]));

	if (tb[IFLA_BR_GROUP_FWD_MASK])
		fprintf(f, "group_fwd_mask %#x ",
			rta_getattr_u16(tb[IFLA_BR_GROUP_FWD_MASK]));

	if (tb[IFLA_BR_GROUP_ADDR]) {
		SPRINT_BUF(mac);

		fprintf(f, "group_address %s ",
			ll_addr_n2a(RTA_DATA(tb[IFLA_BR_GROUP_ADDR]),
				    RTA_PAYLOAD(tb[IFLA_BR_GROUP_ADDR]),
				    1 /*ARPHDR_ETHER*/, mac, sizeof(mac)));
	}

	if (tb[IFLA_BR_MCAST_SNOOPING])
		fprintf(f, "mcast_snooping %u ",
			rta_getattr_u8(tb[IFLA_BR_MCAST_SNOOPING]));

	if (tb[IFLA_BR_MCAST_ROUTER])
		fprintf(f, "mcast_router %u ",
			rta_getattr_u8(tb[IFLA_BR_MCAST_ROUTER]));

	if (tb[IFLA_BR_MCAST_QUERY_USE_IFADDR])
		fprintf(f, "mcast_query_use_ifaddr %u ",
			rta_getattr_u8(tb[IFLA_BR_MCAST_QUERY_USE_IFADDR]));

	if (tb[IFLA_BR_MCAST_QUERIER])
		fprintf(f, "mcast_querier %u ",
			rta_getattr_u8(tb[IFLA_BR_MCAST_QUERIER]));

	if (tb[IFLA_BR_MCAST_HASH_ELASTICITY])
		fprintf(f, "mcast_hash_elasticity %u ",
			rta_getattr_u32(tb[IFLA_BR_MCAST_HASH_ELASTICITY]));

	if (tb[IFLA_BR_MCAST_HASH_MAX])
		fprintf(f, "mcast_hash_max %u ",
			rta_getattr_u32(tb[IFLA_BR_MCAST_HASH_MAX]));

	if (tb[IFLA_BR_MCAST_LAST_MEMBER_CNT])
		fprintf(f, "mcast_last_member_count %u ",
			rta_getattr_u32(tb[IFLA_BR_MCAST_LAST_MEMBER_CNT]));

	if (tb[IFLA_BR_MCAST_STARTUP_QUERY_CNT])
		fprintf(f, "mcast_startup_query_count %u ",
			rta_getattr_u32(tb[IFLA_BR_MCAST_STARTUP_QUERY_CNT]));

	if (tb[IFLA_BR_MCAST_LAST_MEMBER_INTVL])
		fprintf(f, "mcast_last_member_interval %llu ",
			rta_getattr_u64(tb[IFLA_BR_MCAST_LAST_MEMBER_INTVL]));

	if (tb[IFLA_BR_MCAST_MEMBERSHIP_INTVL])
		fprintf(f, "mcast_membership_interval %llu ",
			rta_getattr_u64(tb[IFLA_BR_MCAST_MEMBERSHIP_INTVL]));

	if (tb[IFLA_BR_MCAST_QUERIER_INTVL])
		fprintf(f, "mcast_querier_interval %llu ",
			rta_getattr_u64(tb[IFLA_BR_MCAST_QUERIER_INTVL]));

	if (tb[IFLA_BR_MCAST_QUERY_INTVL])
		fprintf(f, "mcast_query_interval %llu ",
			rta_getattr_u64(tb[IFLA_BR_MCAST_QUERY_INTVL]));

	if (tb[IFLA_BR_MCAST_QUERY_RESPONSE_INTVL])
		fprintf(f, "mcast_query_response_interval %llu ",
			rta_getattr_u64(tb[IFLA_BR_MCAST_QUERY_RESPONSE_INTVL]));

	if (tb[IFLA_BR_MCAST_STARTUP_QUERY_INTVL])
		fprintf(f, "mcast_startup_query_interval %llu ",
			rta_getattr_u64(tb[IFLA_BR_MCAST_STARTUP_QUERY_INTVL]));

	if (tb[IFLA_BR_NF_CALL_IPTABLES])
		fprintf(f, "nf_call_iptables %u ",
			rta_getattr_u8(tb[IFLA_BR_NF_CALL_IPTABLES]));

	if (tb[IFLA_BR_NF_CALL_IP6TABLES])
		fprintf(f, "nf_call_ip6tables %u ",
			rta_getattr_u8(tb[IFLA_BR_NF_CALL_IP6TABLES]));

	if (tb[IFLA_BR_NF_CALL_ARPTABLES])
		fprintf(f, "nf_call_arptables %u ",
			rta_getattr_u8(tb[IFLA_BR_NF_CALL_ARPTABLES]));
}
Esempio n. 19
0
json_t* make_interface_file() {
	json_t *interfaces_json = json_object();
	json_t *ifTable_json = json_object();
	json_t *ifEntry_array = json_array();

	struct rtnl_handle rth = { .fd = -1 };

	if (rtnl_open(&rth, 0) < 0) {
		exit(1);
	}

	if (rtnl_wilddump_request(&rth, AF_PACKET, RTM_GETLINK) < 0) {
		perror("Cannot send dump request");
		exit(1);
	}

	struct nlmsg_list *linfo = NULL;

	if (rtnl_dump_filter(&rth, store_nlmsg, &linfo, NULL, NULL) < 0) {
		fprintf(stderr, "Dump terminated\n");
		exit(1);
	}

	struct nlmsg_list *l, *n;

	for (l = linfo; l; l = n) {
		n = l->next;
		struct nlmsghdr *nlhdr = &(l->h);
		struct ifinfomsg *ifimsg = NLMSG_DATA(nlhdr);

		// Process Data of Netlink Message as ifinfomsg
		if (ifimsg->ifi_family != AF_UNSPEC && ifimsg->ifi_family != AF_INET6) {
			printf("error family: %d\n", ifimsg->ifi_family);
			continue;
		}

		// Add Each Parameter to json file
		json_t *interface_json = json_object();
		json_t *linux_json = json_object();

		json_object_set_new(interface_json, "ifIndex", json_integer(ifimsg->ifi_index));
		json_object_set_new(linux_json, "ifi_type", json_integer(ifimsg->ifi_type));
		json_object_set_new(linux_json, "ifi_flags", json_integer(ifimsg->ifi_flags));

		// Analyze rtattr Message
		int len = nlhdr->nlmsg_len - NLMSG_LENGTH(sizeof(*ifimsg));;

		struct rtattr *tb[IFLA_MAX+1];
		parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifimsg), len);


		if (tb[IFLA_IFNAME]) {
			// printf("\n%s\n", (char *)RTA_DATA(tb[IFLA_IFNAME]));
			json_object_set_new(interface_json, "ifDscr", json_string((char *)RTA_DATA(tb[IFLA_IFNAME])));
		}

		if (tb[IFLA_MTU]) {
			// printf("%d\n", *(int *)RTA_DATA(tb[IFLA_MTU]));
			json_object_set_new(interface_json, "ifMtu", json_integer(*(int *)RTA_DATA(tb[IFLA_MTU])));
		}

		static const char *oper_states[] = {
			"UNKNOWN", "NOTPRESENT", "DOWN", "LOWERLAYERDOWN",
			"TESTING", "DORMANT",	 "UP"
		};

		if (tb[IFLA_OPERSTATE]) {
			__u8 state = *(__u8 *)RTA_DATA(tb[IFLA_OPERSTATE]);
			if (state >= sizeof(oper_states)/sizeof(oper_states[0])){
				fprintf(stderr, "state %#x ", state);
			}
			else{
				// printf("state %s ", oper_states[state]);
				json_object_set_new(interface_json, "ifOperStatus", json_string(oper_states[state]));
			}
		}

		if (tb[IFLA_ADDRESS]) {
			char abuf[64];
			json_object_set_new(interface_json, "ifPhysAddress", json_string(ll_addr_n2a(RTA_DATA(tb[IFLA_ADDRESS]), RTA_PAYLOAD(tb[IFLA_ADDRESS]), ifimsg->ifi_type, abuf, sizeof(abuf))));
		}

		json_object_set_new(interface_json, "linux", linux_json);
		json_array_append(ifEntry_array, interface_json);
	}

	json_object_set_new(ifTable_json, "ifEntry", ifEntry_array);
	json_object_set_new(interfaces_json, "ifTable", ifTable_json);

	free(l);

	rtnl_close(&rth);

	return interfaces_json;
}
Esempio n. 20
0
static int print_linkinfo(struct sockaddr_nl ATTRIBUTE_UNUSED *who,
		const struct nlmsghdr *n, void ATTRIBUTE_UNUSED *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;

	memset(tb, 0, sizeof(tb));
	parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
	if (tb[IFLA_IFNAME] == NULL) {
		bb_error_msg("nil ifname");
		return -1;
	}
	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 (filter.showqueue)
		print_queuelen((char*)RTA_DATA(tb[IFLA_IFNAME]));

	if (!filter.family || filter.family == AF_PACKET) {
		SPRINT_BUF(b1);
		fprintf(fp, "%c    link/%s ", _SL_, 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)));
		}
	}
	fputc('\n', fp);
	fflush(fp);
	return 0;
}
Esempio n. 21
0
int print_neigh(struct sockaddr_nl *who, 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];
	char abuf[256];

	if (n->nlmsg_type != RTM_NEWNEIGH && n->nlmsg_type != RTM_DELNEIGH) {
		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_state || !(filter.state&0x100)) &&
             (r->ndm_family != AF_DECnet))
		return 0;

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

	if (tb[NDA_DST]) {
		if (filter.pfx.family) {
			inet_prefix dst;
			memset(&dst, 0, sizeof(dst));
			dst.family = r->ndm_family;
			memcpy(&dst.data, RTA_DATA(tb[NDA_DST]), RTA_PAYLOAD(tb[NDA_DST]));
			if (inet_addr_match(&dst, &filter.pfx, filter.pfx.bitlen))
				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 = ++filter.rth->seq;
		filter.flushp = (((char*)fn) + n->nlmsg_len) - filter.flushb;
		filter.flushed++;
		if (show_stats < 2)
			return 0;
	}

	if (tb[NDA_DST]) {
		fprintf(fp, "%s ", 
			format_host(r->ndm_family,
				    RTA_PAYLOAD(tb[NDA_DST]),
				    RTA_DATA(tb[NDA_DST]),
				    abuf, sizeof(abuf)));
	}
	if (!filter.index && r->ndm_ifindex)
		fprintf(fp, "dev %s ", ll_index_to_name(r->ndm_ifindex));
	if (tb[NDA_LLADDR]) {
		SPRINT_BUF(b1);
		fprintf(fp, "lladdr %s", ll_addr_n2a(RTA_DATA(tb[NDA_LLADDR]),
					      RTA_PAYLOAD(tb[NDA_LLADDR]),
					      ll_index_to_type(r->ndm_ifindex),
					      b1, sizeof(b1)));
	}
	if (r->ndm_flags & NTF_ROUTER) {
		fprintf(fp, " router");
	}
	if (tb[NDA_CACHEINFO] && show_stats) {
		static int hz;
		struct nda_cacheinfo *ci = RTA_DATA(tb[NDA_CACHEINFO]);
		if (!hz)
			hz = get_hz();
		if (ci->ndm_refcnt)
			printf(" ref %d", ci->ndm_refcnt);
		fprintf(fp, " used %d/%d/%d", ci->ndm_used/hz,
		       ci->ndm_confirmed/hz, ci->ndm_updated/hz);
	}

	if (r->ndm_state) {
		SPRINT_BUF(b1);
		fprintf(fp, " nud %s", nud_state_n2a(r->ndm_state, b1, sizeof(b1)));
	}
	fprintf(fp, "\n");

	fflush(fp);
	return 0;
}
Esempio n. 22
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. 23
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;
}