Esempio n. 1
0
static void nh_dump_details(struct rtnl_nexthop *nh, struct nl_dump_params *dp)
{
	struct nl_cache *link_cache;
	char buf[128];

	link_cache = nl_cache_mngt_require("route/link");

	nl_dump(dp, "nexthop");

	if (nh->ce_mask & NH_ATTR_GATEWAY)
		nl_dump(dp, " via %s", nl_addr2str(nh->rtnh_gateway,
						   buf, sizeof(buf)));

	if(nh->ce_mask & NH_ATTR_IFINDEX) {
		if (link_cache) {
			nl_dump(dp, " dev %s",
				rtnl_link_i2name(link_cache,
						 nh->rtnh_ifindex,
						 buf, sizeof(buf)));
		} else
			nl_dump(dp, " dev %d", nh->rtnh_ifindex);
	}

	if (nh->ce_mask & NH_ATTR_WEIGHT)
		nl_dump(dp, " weight %u", nh->rtnh_weight);

	if (nh->ce_mask & NH_ATTR_REALMS)
		nl_dump(dp, " realm %04x:%04x",
			RTNL_REALM_FROM(nh->rtnh_realms),
			RTNL_REALM_TO(nh->rtnh_realms));

	if (nh->ce_mask & NH_ATTR_FLAGS)
		nl_dump(dp, " <%s>", rtnl_route_nh_flags2str(nh->rtnh_flags,
							buf, sizeof(buf)));
}
Esempio n. 2
0
static int neigh_dump_brief(struct nl_cache *c, struct nl_common *a, FILE *fd,
			    struct nl_dump_params *params)
{
	char dst[INET6_ADDRSTRLEN+5], lladdr[INET6_ADDRSTRLEN+5];
	struct rtnl_neigh *n = (struct rtnl_neigh *) a;
	char state[128], flags[64];

	dp_new_line(fd, params, 0);
	fprintf(fd, "%s dev %s lladdr %s ",
		nl_addr2str_r(&(n->n_dst), dst, sizeof(dst)),
		rtnl_link_i2name(nl_cache_lookup(RTNL_LINK), n->n_ifindex),
		nl_addr2str_r(&(n->n_lladdr), lladdr, sizeof(lladdr)));

	rtnl_neigh_state2str_r(n->n_state, state, sizeof(state));
	rtnl_neigh_flags2str_r(n->n_flags, flags, sizeof(flags));

	if (state[0])
		fprintf(fd, "<%s", state);
	if (flags[0])
		fprintf(fd, "%s%s", state[0] ? "," : "<", flags);
	if (state[0] || flags[0])
		fprintf(fd, ">");
	fprintf(fd, "\n");

	return 1;
}
Esempio n. 3
0
int match_nl_table_cmd_to_type(FILE *fp, bool print, int valid,
			      struct nlattr *tb[])
{
	unsigned int type, ifindex;
	int err;
	char iface[IFNAMSIZ];
	struct nl_sock *fd = NULL;

	if (!tb[NET_MAT_IDENTIFIER_TYPE]) {
		MAT_LOG(ERR,
			"Warning: received rule msg without identifier type!\n");
		return -EINVAL;
	}
	if (!tb[NET_MAT_IDENTIFIER]) {
		MAT_LOG(ERR,
			"Warning: received rule msg without identifier!\n");
		return -EINVAL;
	}

	if (valid > 0 && !tb[valid]) {
		MAT_LOG(ERR, "Warning: received cmd without valid attribute expected %i\n", valid);
		return -ENOMSG;
	}

	if (nla_len(tb[NET_MAT_IDENTIFIER_TYPE]) < (int)sizeof(type)) {
		MAT_LOG(ERR, "Warning: invalid identifier type len\n");
		return -EINVAL;
	}

	type = nla_get_u32(tb[NET_MAT_IDENTIFIER_TYPE]);

	switch (type) {
	case NET_MAT_IDENTIFIER_IFINDEX:
		fd = nl_socket_alloc();
		err = nl_connect(fd, NETLINK_ROUTE);
		if (err < 0) {
			MAT_LOG(ERR,"Warning: Unable to connect socket\n");
			break;
		}
		err = rtnl_link_alloc_cache(fd, AF_UNSPEC, &link_cache);
		if (err < 0) {
			MAT_LOG(ERR,"Warning: Unable to allocate cache\n");
			break;
		}
		ifindex = nla_get_u32(tb[NET_MAT_IDENTIFIER]);
		rtnl_link_i2name(link_cache, (int)ifindex, iface, IFNAMSIZ);
		if (ifindex)
			pfprintf(fp, print, "%s (%u):\n", iface, ifindex);
		break;
	default:
		MAT_LOG(ERR, "Warning: unknown interface identifier type %i\n", type);
		break;
	}

	if (fd) {
                nl_close(fd);
                nl_socket_free(fd);
        }
	return 0;
}
char *
nm_netlink_index_to_iface (int idx)
{
	NMNetlinkMonitor *self;
	NMNetlinkMonitorPrivate *priv;
	char *buf = NULL;

	g_return_val_if_fail (idx >= 0, NULL);

	self = nm_netlink_monitor_get ();
	priv = NM_NETLINK_MONITOR_GET_PRIVATE (self);

	buf = g_malloc0 (MAX_IFACE_LEN);
	g_assert (buf);

	nl_cache_refill (priv->nlh_sync, priv->link_cache);
	if (!rtnl_link_i2name (priv->link_cache, idx, buf, MAX_IFACE_LEN - 1)) {
		nm_log_warn (LOGD_HW, "(%d) failed to find interface name for index", idx);
		g_free (buf);
		buf = NULL;
	}

	g_object_unref (self);
	return buf;
}
Esempio n. 5
0
static void nh_dump_line(struct rtnl_nexthop *nh, struct nl_dump_params *dp)
{
	struct nl_cache *link_cache;
	char buf[128];

	link_cache = nl_cache_mngt_require("route/link");

	nl_dump(dp, "via");

	if (nh->ce_mask & NH_ATTR_GATEWAY)
		nl_dump(dp, " %s", nl_addr2str(nh->rtnh_gateway,
						   buf, sizeof(buf)));

	if(nh->ce_mask & NH_ATTR_IFINDEX) {
		if (link_cache) {
			nl_dump(dp, " dev %s",
				rtnl_link_i2name(link_cache,
						 nh->rtnh_ifindex,
						 buf, sizeof(buf)));
		} else
			nl_dump(dp, " dev %d", nh->rtnh_ifindex);
	}

	nl_dump(dp, " ");
}
Esempio n. 6
0
static int route_dump_brief(struct nl_cache *c, struct nl_common *a, FILE *fd,
			    struct nl_dump_params *params)
{
	struct rtnl_route *r = (struct rtnl_route *) a;

	dp_new_line(fd, params, 0);

	if (r->rt_mask & ROUTE_HAS_DST) {
		char dst[INET6_ADDRSTRLEN+5];
		fprintf(fd, "%s ", nl_addr2str_r(&r->rt_dst, dst, sizeof(dst)));
	} else if (r->rt_dst_len)
		fprintf(fd, "0/%u ", r->rt_dst_len);
	else
		fprintf(fd, "default ");

	if (r->rt_mask & ROUTE_HAS_GATEWAY) {
		char via[INET6_ADDRSTRLEN+5];
		fprintf(fd, "via %s ", nl_addr2str_r(&r->rt_gateway, via, sizeof(via)));
	}

	if (r->rt_mask & ROUTE_HAS_OIF) {
		const char *dev = rtnl_link_i2name(nl_cache_lookup(RTNL_LINK), r->rt_oif);
		fprintf(fd, "dev %s ", dev);
	}

	if (r->rt_table != RT_TABLE_MAIN)
		fprintf(fd, "table %u ", r->rt_table);

	if (r->rt_mask & ROUTE_HAS_FLAGS && r->rt_flags) {
		int flags = r->rt_flags;

		fprintf(fd, "<");
		
#define PRINT_FLAG(f) if (flags & RTNH_F_##f) { \
		flags &= ~RTNH_F_##f; fprintf(fd, #f "%s", flags ? "," : ""); }
		PRINT_FLAG(DEAD);
		PRINT_FLAG(ONLINK);
		PRINT_FLAG(PERVASIVE);
#undef PRINT_FLAG

#define PRINT_FLAG(f) if (flags & RTM_F_##f) { \
		flags &= ~RTM_F_##f; fprintf(fd, #f "%s", flags ? "," : ""); }
		PRINT_FLAG(NOTIFY);
		PRINT_FLAG(CLONED);
		PRINT_FLAG(EQUALIZE);
		PRINT_FLAG(PREFIX);
#undef PRINT_FLAG

		fprintf(fd, ">");
	}

	fprintf(fd, "\n");

	return 1;
}
Esempio n. 7
0
void tca_dump_line(struct rtnl_tc *g, const char *type,
		   struct nl_dump_params *p)
{
	char handle[32], parent[32];
	struct nl_cache *link_cache;
	
	link_cache = nl_cache_mngt_require("route/link");

	nl_dump_line(p, "%s %s ", type, g->tc_kind);

	if (link_cache) {
		char buf[32];
		nl_dump(p, "dev %s ",
			rtnl_link_i2name(link_cache, g->tc_ifindex,
					 buf, sizeof(buf)));
	} else
		nl_dump(p, "dev %u ", g->tc_ifindex);
	
	nl_dump(p, "id %s parent %s",
		rtnl_tc_handle2str(g->tc_handle, handle, sizeof(handle)),
		rtnl_tc_handle2str(g->tc_parent, parent, sizeof(parent)));
}
Esempio n. 8
0
static int addr_dump_brief(struct nl_object *obj, struct nl_dump_params *p)
{
	struct rtnl_addr *addr = (struct rtnl_addr *) obj;
	struct nl_cache *link_cache;
	char buf[128];

	link_cache = nl_cache_mngt_require("route/link");

	if (addr->a_mask & ADDR_ATTR_LOCAL)
		dp_dump(p, "%s",
			nl_addr2str(addr->a_local, buf, sizeof(buf)));
	else
		dp_dump(p, "none");

	if (addr->a_mask & ADDR_ATTR_PEER)
		dp_dump(p, " peer %s",
			nl_addr2str(addr->a_peer, buf, sizeof(buf)));

	dp_dump(p, " %s ", nl_af2str(addr->a_family, buf, sizeof(buf)));

	if (link_cache)
		dp_dump(p, "dev %s ",
			rtnl_link_i2name(link_cache, addr->a_ifindex,
					 buf, sizeof(buf)));
	else
		dp_dump(p, "dev %d ", addr->a_ifindex);

	dp_dump(p, "scope %s",
		rtnl_scope2str(addr->a_scope, buf, sizeof(buf)));

	rtnl_addr_flags2str(addr->a_flags, buf, sizeof(buf));
	if (buf[0])
		dp_dump(p, " <%s>", buf);

	dp_dump(p, "\n");

	return 1;
}
int main(int argc, char *argv[])
{
	struct nl_sock *sock;
	struct nl_cache *link_cache;
	char name[IFNAMSIZ];
	uint32_t ifindex;

	if (argc < 2)
		print_usage();

	sock = nl_cli_alloc_socket();
	nl_cli_connect(sock, NETLINK_ROUTE);
	link_cache = nl_cli_link_alloc_cache(sock);

	ifindex = nl_cli_parse_u32(argv[1]);

	if (!rtnl_link_i2name(link_cache, ifindex, name, sizeof(name)))
		nl_cli_fatal(ENOENT, "Interface index %d does not exist",
			     ifindex);

	printf("%s\n", name);

	return 0;
}
Esempio n. 10
0
static void nh_dump_env(struct rtnl_nexthop *nh, struct nl_dump_params *dp)
{
	struct nl_cache *link_cache;
	char buf[128];

	link_cache = nl_cache_mngt_require("route/link");

	if (nh->ce_mask & NH_ATTR_GATEWAY)
		nl_dump_line(dp, "ROUTE_NH%d_VIA=%s\n", dp->dp_ivar,
			nl_addr2str(nh->rtnh_gateway, buf, sizeof(buf)));

	if(nh->ce_mask & NH_ATTR_IFINDEX) {
		if (link_cache) {
			nl_dump_line(dp, "ROUTE_NH%d_DEV=%s\n", dp->dp_ivar,
					rtnl_link_i2name(link_cache,
						 nh->rtnh_ifindex,
						 buf, sizeof(buf)));
		} else
			nl_dump_line(dp, "ROUTE_NH%d_DEV=%d\n", dp->dp_ivar,
					nh->rtnh_ifindex);
	}

	if (nh->ce_mask & NH_ATTR_WEIGHT)
		nl_dump_line(dp, "ROUTE_NH%d_WEIGHT=%u\n", dp->dp_ivar,
				nh->rtnh_weight);

	if (nh->ce_mask & NH_ATTR_REALMS)
		nl_dump_line(dp, "ROUTE_NH%d_REALM=%04x:%04x\n", dp->dp_ivar,
			RTNL_REALM_FROM(nh->rtnh_realms),
			RTNL_REALM_TO(nh->rtnh_realms));

	if (nh->ce_mask & NH_ATTR_FLAGS)
		nl_dump_line(dp, "ROUTE_NH%d_FLAGS=<%s>\n", dp->dp_ivar,
			rtnl_route_nh_flags2str(nh->rtnh_flags,
							buf, sizeof(buf)));
}
Esempio n. 11
0
CAMLprim value
ocaml_get_routing_table(value unit) {
    CAMLparam1(unit);
    CAMLlocal3( ret, tmp, entry );

    struct nl_sock *fd;
    struct nl_cache *res, *links;
    struct rtnl_route *it;
    uint32 i_ip, netmask = 0, mask_len, gw;
    int i;
    struct nl_addr *ip;
    char device_name[IFNAMSIZ];
    struct rtnl_nexthop *to;
    fd = nl_socket_alloc();
    if (!fd) {
        fprintf(stderr, "error nl_socket_alloc\n");
        exit(1);
    }

    if(nl_connect(fd, NETLINK_ROUTE) < 0) {
        fprintf(stderr, "error nl_connect\n");
        exit(1);
    }

    ret = Val_emptylist;

    if(rtnl_route_alloc_cache(fd, AF_UNSPEC, 0, &res) < 0) {
        fprintf(stderr, "error rtnl_route_alloc_cache");
        exit(1);
    }

    if(rtnl_link_alloc_cache (fd, AF_UNSPEC, &links) < 0) {
        fprintf(stderr, "error rtnl_link_alloc_cache");
        exit(1);
    }

    it = (struct rtnl_route *)nl_cache_get_first(res);
    for(; it != NULL; it = (struct rtnl_route *)
                           nl_cache_get_next((struct nl_object *)it) ) {
        if(rtnl_route_get_family (it) == AF_INET) {
            ip = rtnl_route_get_dst(it);
            i_ip = ntohl(*(int *)nl_addr_get_binary_addr(ip));
            mask_len = nl_addr_get_prefixlen(ip);
            for(i = 0; i < 32; i++)
                netmask = (netmask << 1) + (i< mask_len?1:0);
            to = rtnl_route_nexthop_n(it, 0);
            rtnl_link_i2name(links, rtnl_route_nh_get_ifindex(to),
                             device_name, IFNAMSIZ);
            if ( rtnl_route_nh_get_gateway (to) != NULL)
                gw = ntohl(*(int *)nl_addr_get_binary_addr(
                               rtnl_route_nh_get_gateway (to)));
            else
                gw = 0;
            /*printf("src ip:%x mask:%x gw:%x dev:%s\n", i_ip, netmask, */
            /*gw, device_name);*/

            entry = caml_alloc(7,0);
            Store_field(entry, 0, Val_int(i_ip & 0xFFFF));
            Store_field(entry, 1, Val_int(i_ip >> 16));
            Store_field(entry, 2, Val_int(netmask & 0xFFFF));
            Store_field(entry, 3, Val_int(netmask >> 16));
            Store_field(entry, 4, Val_int(gw & 0xFFFF));
            Store_field(entry, 5, Val_int(gw >> 16));
            Store_field(entry, 6, caml_copy_string(device_name));

            // store in list
            tmp =  caml_alloc(2, 0);
            Store_field( tmp, 0, entry);  // head
            Store_field( tmp, 1, ret);  // tail
            ret = tmp;
        }
    }
Esempio n. 12
0
static int addr_dump_xml(struct nl_object *obj, struct nl_dump_params *p)
{
	struct rtnl_addr *addr = (struct rtnl_addr *) obj;
	struct nl_cache *link_cache;
	char buf[128];
	int line = 0;

	dp_dump_line(p, line++, "<address>\n");
	dp_dump_line(p, line++, "  <family>%s</family>\n",
		     nl_af2str(addr->a_family, buf, sizeof(buf)));

	if (addr->a_mask & ADDR_ATTR_LOCAL)
		dp_dump_line(p, line++, "  <local>%s</local>\n",
			     nl_addr2str(addr->a_local, buf, sizeof(buf)));

	if (addr->a_mask & ADDR_ATTR_PEER)
		dp_dump_line(p, line++, "  <peer>%s</peer>\n",
			     nl_addr2str(addr->a_peer, buf, sizeof(buf)));

	if (addr->a_mask & ADDR_ATTR_BROADCAST)
		dp_dump_line(p, line++, "  <broadcast>%s</broadcast>\n",
			     nl_addr2str(addr->a_bcast, buf, sizeof(buf)));

	if (addr->a_mask & ADDR_ATTR_ANYCAST)
		dp_dump_line(p, line++, "  <anycast>%s</anycast>\n",
			     nl_addr2str(addr->a_anycast, buf, sizeof(buf)));

	if (addr->a_mask & ADDR_ATTR_MULTICAST)
		dp_dump_line(p, line++, "  <multicast>%s</multicast>\n",
			     nl_addr2str(addr->a_multicast, buf,
					   sizeof(buf)));

	if (addr->a_mask & ADDR_ATTR_PREFIXLEN)
		dp_dump_line(p, line++, "  <prefixlen>%u</prefixlen>\n",
			     addr->a_prefixlen);
	link_cache = nl_cache_mngt_require("route/link");

	if (link_cache)
		dp_dump_line(p, line++, "  <device>%s</device>\n",
			     rtnl_link_i2name(link_cache, addr->a_ifindex,
			     		      buf, sizeof(buf)));
	else
		dp_dump_line(p, line++, "  <device>%u</device>\n",
			     addr->a_ifindex);

	if (addr->a_mask & ADDR_ATTR_SCOPE)
		dp_dump_line(p, line++, "  <scope>%s</scope>\n",
			     rtnl_scope2str(addr->a_scope, buf, sizeof(buf)));

	if (addr->a_mask & ADDR_ATTR_LABEL)
		dp_dump_line(p, line++, "  <label>%s</label>\n", addr->a_label);

	rtnl_addr_flags2str(addr->a_flags, buf, sizeof(buf));
	if (buf[0])
		dp_dump_line(p, line++, "  <flags>%s</flags>\n", buf);

	if (addr->a_mask & ADDR_ATTR_CACHEINFO) {
		struct rtnl_addr_cacheinfo *ci = &addr->a_cacheinfo;

		dp_dump_line(p, line++, "  <cacheinfo>\n");

		dp_dump_line(p, line++, "    <valid>%s</valid>\n",
			     ci->aci_valid == 0xFFFFFFFFU ? "forever" :
			     nl_msec2str(ci->aci_valid * 1000,
					   buf, sizeof(buf)));

		dp_dump_line(p, line++, "    <prefered>%s</prefered>\n",
			     ci->aci_prefered == 0xFFFFFFFFU ? "forever" :
			     nl_msec2str(ci->aci_prefered * 1000,
					 buf, sizeof(buf)));

		dp_dump_line(p, line++, "    <created>%s</created>\n",
			     nl_msec2str(addr->a_cacheinfo.aci_cstamp * 10,
					 buf, sizeof(buf)));

		dp_dump_line(p, line++, "    <last-update>%s</last-update>\n",
			     nl_msec2str(addr->a_cacheinfo.aci_tstamp * 10,
					 buf, sizeof(buf)));

		dp_dump_line(p, line++, "  </cacheinfo>\n");
	}

	dp_dump_line(p, line++, "</address>\n");

	return line;
}
Esempio n. 13
0
static int netlink_msg_handler(struct nl_msg *msg, void *arg)
{
	struct nlmsghdr *hdr;
	struct tcmsg *tcm;
	struct nlattr *attrs[TCA_MAX+1];
	struct nlattr *stat_attrs[TCA_STATS_MAX+1];
	struct qdisc_handler *h;
	char qdisc[IFNAMSIZ] = {0};
	int qdisc_l = 0;
	char ifname[IFNAMSIZ] = {0};
	int ifname_l = 0;
	struct timeval current_time = {0};
	double time;

	char *ret = NULL;

	struct gnet_stats_basic *sb;
	struct gnet_stats_queue *q;

	struct options *opt = arg;

	struct recordset rset = {0};

	hdr = nlmsg_hdr(msg);
	tcm = nlmsg_data(hdr);
	if(!has_iface(opt, tcm->tcm_ifindex))
		return NL_SKIP;

	if((ret = rtnl_link_i2name(opt->cache, tcm->tcm_ifindex, ifname, IFNAMSIZ)) == NULL)
		return NL_SKIP;

	// No length checking in netlink library.
	if((ifname_l = 1 + strnlen(ifname, IFNAMSIZ)) >= IFNAMSIZ) {
		ifname[IFNAMSIZ-1] = '\0';
		ifname_l = IFNAMSIZ;
	}

	gettimeofday(&current_time, NULL);
	time = (double)current_time.tv_usec / 1000000 + (double) current_time.tv_sec;
	add_record_double(&rset, "time", sizeof("time"), time);
	add_record_str(&rset, "iface", sizeof("iface"), ifname, ifname_l);

	nlmsg_parse(hdr, sizeof(*tcm), attrs, TCA_MAX, tca_policy);

	if(attrs[TCA_KIND]) {
		qdisc_l = nla_len(attrs[TCA_KIND]);
		memcpy(qdisc, nla_get_string(attrs[TCA_KIND]), qdisc_l);
		add_record_str(&rset, "qdisc", sizeof("qdisc"), qdisc, qdisc_l);
	}

	add_record_hex(&rset, "handle", sizeof("handle"), tcm->tcm_handle >> 16);

	if(attrs[TCA_STATS2]) {
		nla_parse_nested(stat_attrs, TCA_STATS_MAX, attrs[TCA_STATS2], tca_stats_policy);
		if(stat_attrs[TCA_STATS_BASIC]) {
			sb = nla_data(stat_attrs[TCA_STATS_BASIC]);
			add_record_uint(&rset, "bytes", sizeof("bytes"), sb->bytes);
			add_record_uint(&rset, "packets", sizeof("packets"), sb->packets);
		}

		if(stat_attrs[TCA_STATS_QUEUE]) {
			q = nla_data(stat_attrs[TCA_STATS_QUEUE]);
			add_record_uint(&rset, "drops", sizeof("drops"), q->drops);
			add_record_uint(&rset, "qlen", sizeof("qlen"), q->qlen);
			add_record_uint(&rset, "backlog", sizeof("backlog"), q->backlog);
			add_record_uint(&rset, "overlimits", sizeof("overlimits"), q->overlimits);
			add_record_uint(&rset, "requeues", sizeof("requeues"), q->requeues);
		}
		if(stat_attrs[TCA_STATS_APP]) {
			h = find_qdisc_handler(qdisc);
			if(h)
				h->parse_stats(stat_attrs[TCA_STATS_APP], &rset);
		}
	}
	opt->formatter->format(opt->formatter, &rset);
	clear_records(&rset);
	if(!opt->run_length || current_time.tv_sec < opt->start_time.tv_sec + opt->run_length)
		return NL_OK;
	else
		return NL_STOP;
}
Esempio n. 14
0
static void route_proc_cb(struct nl_object *c, void *arg)
{
        struct ip_lookup_res *res = (struct ip_lookup_res*) arg;
	struct rtnl_route *route = (struct rtnl_route *) c;
	struct nl_cache *link_cache;
        struct nl_addr *addr;
        struct rtnl_nexthop *nh;
        int prefix_len;
        int oif;
	char buf[64];

	link_cache = nl_cache_mngt_require("route/link");

        addr = rtnl_route_get_dst(route);
        if (addr) {
		printf("%s", nl_addr2str(addr, buf, sizeof(buf)));
                res->dstaddr = *(uint32_t *) nl_addr_get_binary_addr(addr);
        }

        prefix_len = rtnl_route_get_dst_len(route);
        if (prefix_len)
                printf("/%d ", prefix_len);
        else
                printf("default ");

        addr = rtnl_route_get_src(route);
        if (addr) 
		printf("src %s ", nl_addr2str(addr, buf, sizeof(buf)));

        addr = rtnl_route_get_pref_src(route);
        if (addr)
		printf("preferred src %s ", nl_addr2str(addr, buf, sizeof(buf)));

        addr = rtnl_route_get_gateway(route);
        if (addr) { 
		printf("via %s ", nl_addr2str(addr, buf, sizeof(buf)));
                res->nh_addr = *(uint32_t*) nl_addr_get_binary_addr(addr);
        }
        else {
                res->nh_addr = 0;
        }

        oif = rtnl_route_get_oif(route);
        res->oif = oif;
        if (oif != RTNL_LINK_NOT_FOUND && link_cache) {
	        printf("dev %s ", rtnl_link_i2name(link_cache, oif,
						 buf, sizeof(buf)));
                rtnl_link_i2name(link_cache, oif, res->oifname, sizeof(res->oifname));
        }
        
        /* Declaration of rtnl_route_nh_get_gateway() is missing from 
         * include/netlink/route/nexthop.h, there is no way to inspect
         * each nexthop for gateway information, will just use gateway 
         * info stored in rtnl_route struct. The probem is only present
         * libnl 1 */
        /*
        nl_list_for_each_entry(nh, rtnl_route_get_nexthops(route), rtnh_list) {

        }
        */
                
        printf("\n");

}
Esempio n. 15
0
static void handle_class(struct nl_object *obj, void *arg)
{
	struct rtnl_tc *tc = (struct rtnl_tc *) obj;
	struct element *e;
	struct rdata *rdata = arg;
	struct rdata ndata = {
		.level = rdata->level + 1,
	};

	if (!(e = handle_tc_obj(tc, "class", rdata)))
		return;

	ndata.parent = e;

	if (!strcmp(rtnl_tc_get_kind(tc), "htb"))
		element_set_txmax(e, rtnl_htb_get_rate((struct rtnl_class *) tc));

	find_classes(rtnl_tc_get_handle(tc), &ndata);
	find_qdiscs(rtnl_tc_get_handle(tc), &ndata);
}

static void find_qdiscs(uint32_t parent, struct rdata *rdata)
{
	struct rtnl_qdisc *filter;

	if (!(filter = rtnl_qdisc_alloc()))
		return;

	rtnl_tc_set_parent((struct rtnl_tc *) filter, parent);

	nl_cache_foreach_filter(qdisc_cache, OBJ_CAST(filter),
				handle_qdisc, rdata);

	rtnl_qdisc_put(filter);
}

static void find_cls(int ifindex, uint32_t parent, struct rdata *rdata)
{
	struct nl_cache *cls_cache;

	if (rtnl_cls_alloc_cache(sock, ifindex, parent, &cls_cache) < 0)
		return;

	nl_cache_foreach(cls_cache, handle_cls, rdata);

	nl_cache_free(cls_cache);
}

static void find_classes(uint32_t parent, struct rdata *rdata)
{
	struct rtnl_class *filter;

	if (!(filter = rtnl_class_alloc()))
		return;

	rtnl_tc_set_parent((struct rtnl_tc *) filter, parent);

	nl_cache_foreach_filter(class_cache, OBJ_CAST(filter),
				handle_class, rdata);

	rtnl_class_put(filter);
}

static void handle_qdisc(struct nl_object *obj, void *arg)
{
	struct rtnl_tc *tc = (struct rtnl_tc *) obj;
	struct element *e;
	struct rdata *rdata = arg;
	struct rdata ndata = {
		.level = rdata->level + 1,
	};

	if (!(e = handle_tc_obj(tc, "qdisc", rdata)))
		return;

	ndata.parent = e;

	find_cls(rtnl_tc_get_ifindex(tc), rtnl_tc_get_handle(tc), &ndata);

	if (rtnl_tc_get_parent(tc) == TC_H_ROOT) {
		find_cls(rtnl_tc_get_ifindex(tc), TC_H_ROOT, &ndata);
		find_classes(TC_H_ROOT, &ndata);
	}

	find_classes(rtnl_tc_get_handle(tc), &ndata);
}

static void handle_tc(struct element *e, struct rtnl_link *link)
{
	struct rtnl_qdisc *qdisc;
	int ifindex = rtnl_link_get_ifindex(link);
	struct rdata rdata = {
		.level = 1,
		.parent = e,
	};

	if (rtnl_class_alloc_cache(sock, ifindex, &class_cache) < 0)
		return;

	qdisc = rtnl_qdisc_get_by_parent(qdisc_cache, ifindex, TC_H_ROOT);
	if (qdisc) {
		handle_qdisc(OBJ_CAST(qdisc), &rdata);
		rtnl_qdisc_put(qdisc);
	}

	qdisc = rtnl_qdisc_get_by_parent(qdisc_cache, ifindex, 0);
	if (qdisc) {
		handle_qdisc(OBJ_CAST(qdisc), &rdata);
		rtnl_qdisc_put(qdisc);
	}

	qdisc = rtnl_qdisc_get_by_parent(qdisc_cache, ifindex, TC_H_INGRESS);
	if (qdisc) {
		handle_qdisc(OBJ_CAST(qdisc), &rdata);
		rtnl_qdisc_put(qdisc);
	}

	nl_cache_free(class_cache);
}

static void update_link_infos(struct element *e, struct rtnl_link *link)
{
	char buf[64];

	snprintf(buf, sizeof(buf), "%u", rtnl_link_get_mtu(link));
	element_update_info(e, "MTU", buf);

	rtnl_link_flags2str(rtnl_link_get_flags(link), buf, sizeof(buf));
	element_update_info(e, "Flags", buf);

	rtnl_link_operstate2str(rtnl_link_get_operstate(link),
				buf, sizeof(buf));
	element_update_info(e, "Operstate", buf);

	snprintf(buf, sizeof(buf), "%u", rtnl_link_get_ifindex(link));
	element_update_info(e, "IfIndex", buf);

	nl_addr2str(rtnl_link_get_addr(link), buf, sizeof(buf));
	element_update_info(e, "Address", buf);

	nl_addr2str(rtnl_link_get_broadcast(link), buf, sizeof(buf));
	element_update_info(e, "Broadcast", buf);

	rtnl_link_mode2str(rtnl_link_get_linkmode(link),
			   buf, sizeof(buf));
	element_update_info(e, "Mode", buf);

	snprintf(buf, sizeof(buf), "%u", rtnl_link_get_txqlen(link));
	element_update_info(e, "TXQlen", buf);

	nl_af2str(rtnl_link_get_family(link), buf, sizeof(buf));
	element_update_info(e, "Family", buf);

	element_update_info(e, "Alias",
		rtnl_link_get_ifalias(link) ? : "");

	element_update_info(e, "Qdisc",
		rtnl_link_get_qdisc(link) ? : "");

	if (rtnl_link_get_link(link)) {
		snprintf(buf, sizeof(buf), "%u", rtnl_link_get_link(link));
		element_update_info(e, "SlaveOfIndex", buf);
	}
}

static void do_link(struct nl_object *obj, void *arg)
{
	struct rtnl_link *link = (struct rtnl_link *) obj;
	struct element *e, *e_parent = NULL;
	int i, master_ifindex;

	if (!cfg_show_all && !(rtnl_link_get_flags(link) & IFF_UP)) {
		/* FIXME: delete element */
		return;
	}

	/* Check if the interface is a slave of another interface */
	if ((master_ifindex = rtnl_link_get_link(link))) {
		char parent[IFNAMSIZ+1];

		rtnl_link_i2name(link_cache, master_ifindex,
				 parent, sizeof(parent));

		e_parent = element_lookup(grp, parent, master_ifindex, NULL, 0);
	}

	if (!(e = element_lookup(grp, rtnl_link_get_name(link),
				 rtnl_link_get_ifindex(link), e_parent, ELEMENT_CREAT)))
		return;

	if (e->e_flags & ELEMENT_FLAG_CREATED) {
		if (e->e_parent)
			e->e_level = e->e_parent->e_level + 1;

		if (element_set_key_attr(e, "bytes", "packets") ||
		    element_set_usage_attr(e, "bytes"))
			BUG();

		/* FIXME: Update link infos every 1s or so */
		update_link_infos(e, link);

		e->e_flags &= ~ELEMENT_FLAG_CREATED;
	}

	for (i = 0; i < ARRAY_SIZE(link_attrs); i++) {
		struct attr_map *m = &link_attrs[i];
		uint64_t c_rx = 0, c_tx = 0;
		int flags = 0;

		if (m->rxid >= 0) {
			c_rx = rtnl_link_get_stat(link, m->rxid);
			flags |= UPDATE_FLAG_RX;
		}

		if (m->txid >= 0) {
			c_tx = rtnl_link_get_stat(link, m->txid);
			flags |= UPDATE_FLAG_TX;
		}

		attr_update(e, m->attrid, c_rx, c_tx, flags);
	}

	if (!c_notc)
		handle_tc(e, link);

	element_notify_update(e, NULL);
	element_lifesign(e, 1);
}

static void netlink_read(void)
{
	int err;

	if ((err = nl_cache_resync(sock, link_cache, NULL, NULL)) < 0) {
		fprintf(stderr, "Unable to resync link cache: %s\n", nl_geterror(err));
		goto disable;
	}

	if ((err = nl_cache_resync(sock, qdisc_cache, NULL, NULL)) < 0) {
		fprintf(stderr, "Unable to resync qdisc cache: %s\n", nl_geterror(err));
		goto disable;
	}

	nl_cache_foreach(link_cache, do_link, NULL);

	return;

disable:
	netlink_ops.m_flags &= ~BMON_MODULE_ENABLED;
}

static void netlink_shutdown(void)
{
	nl_cache_free(link_cache);
	nl_cache_free(qdisc_cache);
	nl_socket_free(sock);
}
Esempio n. 16
0
static void env_dump(struct nl_object *obj, void *arg)
{
	struct nl_dump_params *p = arg;
	struct rtnl_addr *addr = (struct rtnl_addr *) obj;
	struct nl_cache *link_cache;
	struct nl_addr *a;
	static int index = 0;
	char buf[128], pfx[32], *s;

	snprintf(pfx, sizeof(pfx), "ADDR%d", index++);

	nl_dump_line(p, "%s_FAMILY=%s\n", pfx,
		     nl_af2str(rtnl_addr_get_family(addr), buf, sizeof(buf)));

	nl_dump_line(p, "%s_LOCAL=%s\n", pfx,
		     nl_addr2str(rtnl_addr_get_local(addr), buf, sizeof(buf)));

	nl_dump_line(p, "%s_IFINDEX=%u\n", pfx, rtnl_addr_get_ifindex(addr));
	link_cache = nl_cache_mngt_require_safe("route/link");
	if (link_cache)
		nl_dump_line(p, "%s_IFNAME=%s\n", pfx,
			     rtnl_link_i2name(link_cache,
			     		      rtnl_addr_get_ifindex(addr),
			     		      buf, sizeof(buf)));

	if ((a = rtnl_addr_get_peer(addr)))
		nl_dump_line(p, "%s_PEER=%s\n", pfx,
			     nl_addr2str(a, buf, sizeof(buf)));

	if ((a = rtnl_addr_get_broadcast(addr)))
		nl_dump_line(p, "%s_BROADCAST=%s\n", pfx,
			     nl_addr2str(a, buf, sizeof(buf)));

	nl_dump_line(p, "%s_SCOPE=%s\n", pfx,
		     rtnl_scope2str(rtnl_addr_get_scope(addr),
				    buf, sizeof(buf)));

	if ((s = rtnl_addr_get_label(addr)))
		nl_dump_line(p, "%s_LABEL=%s\n", pfx, s);

	rtnl_addr_flags2str(rtnl_addr_get_flags(addr), buf, sizeof(buf));
	if (buf[0])
		nl_dump_line(p, "%s_FLAGS=%s\n", pfx, buf);

	nl_dump_line(p, "%s_CACHEINFO_VALID=%u\n", pfx,
		     rtnl_addr_get_valid_lifetime(addr));

	if (link_cache)
		nl_cache_put(link_cache);

#if 0
	if (addr->ce_mask & ADDR_ATTR_CACHEINFO) {
		struct rtnl_addr_cacheinfo *ci = &addr->a_cacheinfo;

		nl_dump_line(p, "ADDR_CACHEINFO_PREFERRED=%u\n",
			     ci->aci_prefered);

		nl_dump_line(p, "ADDR_CACHEINFO_CREATED=%u\n", ci->aci_cstamp);
		nl_dump_line(p, "ADDR_CACHEINFO_LASTUPDATE=%u\n",
			     ci->aci_tstamp);
	}
#endif
}
Esempio n. 17
0
	const std::string NetLinkManager::getInterface(const int ifindex) const
	{
		char buf[256];
		rtnl_link_i2name(_link_cache, ifindex, (char*)&buf, sizeof buf);
		return std::string((char*)&buf);
	}
static int addr_dump_env(struct nl_object *obj, struct nl_dump_params *p)
{
	struct rtnl_addr *addr = (struct rtnl_addr *) obj;
	struct nl_cache *link_cache;
	char buf[128];
	int line = 0;

	dp_dump_line(p, line++, "ADDR_FAMILY=%s\n",
		     nl_af2str(addr->a_family, buf, sizeof(buf)));

	if (addr->ce_mask & ADDR_ATTR_LOCAL)
		dp_dump_line(p, line++, "ADDR_LOCAL=%s\n",
			     nl_addr2str(addr->a_local, buf, sizeof(buf)));

	if (addr->ce_mask & ADDR_ATTR_PEER)
		dp_dump_line(p, line++, "ADDR_PEER=%s\n",
			     nl_addr2str(addr->a_peer, buf, sizeof(buf)));

	if (addr->ce_mask & ADDR_ATTR_BROADCAST)
		dp_dump_line(p, line++, "ADDR_BROADCAST=%s\n",
			     nl_addr2str(addr->a_bcast, buf, sizeof(buf)));

	if (addr->ce_mask & ADDR_ATTR_ANYCAST)
		dp_dump_line(p, line++, "ADDR_ANYCAST=%s\n",
			     nl_addr2str(addr->a_anycast, buf, sizeof(buf)));

	if (addr->ce_mask & ADDR_ATTR_MULTICAST)
		dp_dump_line(p, line++, "ADDR_MULTICAST=%s\n",
			     nl_addr2str(addr->a_multicast, buf,
					   sizeof(buf)));

	if (addr->ce_mask & ADDR_ATTR_PREFIXLEN)
		dp_dump_line(p, line++, "ADDR_PREFIXLEN=%u\n",
			     addr->a_prefixlen);
	link_cache = nl_cache_mngt_require("route/link");

	dp_dump_line(p, line++, "ADDR_IFINDEX=%u\n", addr->a_ifindex);
	if (link_cache)
		dp_dump_line(p, line++, "ADDR_IFNAME=%s\n",
			     rtnl_link_i2name(link_cache, addr->a_ifindex,
			     		      buf, sizeof(buf)));

	if (addr->ce_mask & ADDR_ATTR_SCOPE)
		dp_dump_line(p, line++, "ADDR_SCOPE=%s\n",
			     rtnl_scope2str(addr->a_scope, buf, sizeof(buf)));

	if (addr->ce_mask & ADDR_ATTR_LABEL)
		dp_dump_line(p, line++, "ADDR_LABEL=%s\n", addr->a_label);

	rtnl_addr_flags2str(addr->a_flags, buf, sizeof(buf));
	if (buf[0])
		dp_dump_line(p, line++, "ADDR_FLAGS=%s\n", buf);

	if (addr->ce_mask & ADDR_ATTR_CACHEINFO) {
		struct rtnl_addr_cacheinfo *ci = &addr->a_cacheinfo;

		dp_dump_line(p, line++, "ADDR_CACHEINFO_VALID=%s\n",
			     ci->aci_valid == 0xFFFFFFFFU ? "forever" :
			     nl_msec2str(ci->aci_valid * 1000,
					   buf, sizeof(buf)));

		dp_dump_line(p, line++, "ADDR_CACHEINFO_PREFERED=%s\n",
			     ci->aci_prefered == 0xFFFFFFFFU ? "forever" :
			     nl_msec2str(ci->aci_prefered * 1000,
					 buf, sizeof(buf)));

		dp_dump_line(p, line++, "ADDR_CACHEINFO_CREATED=%s\n",
			     nl_msec2str(addr->a_cacheinfo.aci_cstamp * 10,
					 buf, sizeof(buf)));

		dp_dump_line(p, line++, "ADDR_CACHEINFO_LASTUPDATE=%s\n",
			     nl_msec2str(addr->a_cacheinfo.aci_tstamp * 10,
					 buf, sizeof(buf)));
	}

	return line;
}