Пример #1
0
bool devEthernet::hasLink() {
	if ( ! _netlinkSocket ) {
		MOD_ERROR("hasLink() called on uninitialized netlink socket.");
		return false;
	}

	nl_cache* cache;
	if ( rtnl_link_alloc_cache (_netlinkSocket, AF_UNSPEC, &cache) ) {
		MOD_ERROR("hasLink() rtnl_link_alloc_cache error: %s",
			nl_geterror(errno));
		return false;
	}

	rtnl_link* link = rtnl_link_get(cache, index());
	if ( ! link ) {
		MOD_ERROR("hasLink() rtnl_link_get error: %s", nl_geterror(errno));
			nl_cache_free(cache);
		return false;
	}

	// First, check that interface is able to send
	uint8_t operState = rtnl_link_get_operstate(link);

	#ifdef DEFINE_DEBUG
	char buf[100];
	rtnl_link_operstate2str (operState, buf, 100);
	MOD_DEBUG("operState is 0x%x (%s).", operState, buf);
	#endif

	bool ret = false;

	// Next make sure there's a carrier
	#ifndef IFF_LOWER_UP
	const int IFF_LOWER_UP = 0x10000;
	#endif

	#ifndef IFF_DORMANT
	const int IFF_DORMANT = 0x20000;
	#endif

	if ( operState == OperUp) {
		unsigned int flags = rtnl_link_get_flags (link);
		ret = ( ((flags & IFF_LOWER_UP) == IFF_LOWER_UP) && ((flags & IFF_DORMANT) != IFF_DORMANT) );
	}

	rtnl_link_put(link);
	nl_cache_free(cache);

	return ret;
}
int main(int argc, char *argv[])
{
	struct nl_handle *nlh;
	struct nl_cache *link_cache;
	int err = 1;

	if (nltool_init(argc, argv) < 0)
		return -1;

	if (argc < 3 || !strcmp(argv[1], "-h"))
		print_usage();

	nlh = nltool_alloc_handle();
	if (!nlh)
		return -1;

	if (nltool_connect(nlh, NETLINK_ROUTE) < 0)
		goto errout;

	link_cache = nltool_alloc_link_cache(nlh);
	if (!link_cache)
		goto errout_close;

	gargv = &argv[2];
	gargc = argc - 2;

	if (!strcasecmp(argv[1], "all"))
		nl_cache_foreach(link_cache, dump_stats, NULL);
	else {
		int ifindex = strtoul(argv[1], NULL, 0);
		struct rtnl_link *link = rtnl_link_get(link_cache, ifindex);

		if (!link) {
			fprintf(stderr, "Could not find ifindex %d\n", ifindex);
			goto errout_link_cache;
		}

		dump_stats((struct nl_object *) link, NULL);
		rtnl_link_put(link);
	}

	err = 0;
errout_link_cache:
	nl_cache_free(link_cache);
errout_close:
	nl_close(nlh);
errout:
	nl_handle_destroy(nlh);
	return err;
}
Пример #3
0
static int
netlink3_reset_interface_parameters(const interface_t* ifp)
{
	struct nl_sock *sk;
	struct nl_cache *cache;
	struct rtnl_link *link = NULL;
	struct rtnl_link *new_state = NULL;
	int res = 0;

	if (!(sk = nl_socket_alloc())) {
		log_message(LOG_INFO, "Unable to open netlink socket");
		return -1;
	}

	if (nl_connect(sk, NETLINK_ROUTE) < 0)
		goto err;
	if (rtnl_link_alloc_cache(sk, AF_UNSPEC, &cache))
		goto err;
	if (!(link = rtnl_link_get(cache, ifp->ifindex)))
		goto err;
	if (!(new_state = rtnl_link_alloc()))
		goto err;
	if (rtnl_link_inet_set_conf(new_state, IPV4_DEVCONF_ARP_IGNORE, ifp->reset_arp_ignore_value) ||
	    rtnl_link_inet_set_conf(new_state, IPV4_DEVCONF_ARPFILTER, ifp->reset_arp_filter_value) ||
	    rtnl_link_change(sk, link, new_state, 0))
		goto err;

	rtnl_link_put(link);
	link = NULL;

	rtnl_link_put(new_state);
	new_state = NULL;

	goto exit;
err:
	res = -1;

	if (link)
		rtnl_link_put(link);
	if (new_state)
		rtnl_link_put(new_state);

exit:
	nl_socket_free(sk);

	return res;
}
Пример #4
0
/* Given an interface's MAC address, return the name (e.g., eth0) in human
 * readable format.  Return NULL for no match
 */
char *iface_mac2device(char *mac) {
    struct nl_handle *handle = NULL;
    struct nl_cache *cache = NULL;
    struct rtnl_link *link = NULL;
    struct nl_addr *mac_as_nl_addr = NULL;
    char *retval = NULL;
    int i, n;

    if (mac == NULL) {
        return NULL;
    }

    if ((mac_as_nl_addr = nl_addr_parse(mac, AF_LLC)) == NULL) {
        return NULL;
    }

    if ((cache = _iface_get_link_cache(&handle)) == NULL) {
        return NULL;
    }

    n = nl_cache_nitems(cache);
    for (i = 0; i <= n; i++) {
        struct nl_addr *addr;

        if ((link = rtnl_link_get(cache, i)) == NULL) {
            continue;
        }

        addr = rtnl_link_get_addr(link);

        if (!nl_addr_cmp(mac_as_nl_addr, addr)) {
            retval = strdup(rtnl_link_get_name(link));
            rtnl_link_put(link);
            break;
        }

        rtnl_link_put(link);
    }

    nl_close(handle);
    nl_handle_destroy(handle);

    return retval;
}
struct rtnl_link *
nm_netlink_index_to_rtnl_link (int idx)
{
	NMNetlinkMonitor *self;
	NMNetlinkMonitorPrivate *priv;
	struct rtnl_link *ret = NULL;

	if (idx <= 0)
		return NULL;

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

	nl_cache_refill (priv->nlh_sync, priv->link_cache);
	ret = rtnl_link_get (priv->link_cache, idx);
	g_object_unref (self);

	return ret;
}
Пример #6
0
// Returns the netlink link object associated with a given link by its
// interface index. Returns None if the link is not found.
inline Result<Netlink<struct rtnl_link>> get(int index)
{
  Try<Netlink<struct nl_sock>> socket = routing::socket();
  if (socket.isError()) {
    return Error(socket.error());
  }

  // Dump all the netlink link objects from kernel. Note that the flag
  // AF_UNSPEC means all available families.
  struct nl_cache* c = NULL;
  int error = rtnl_link_alloc_cache(socket.get().get(), AF_UNSPEC, &c);
  if (error != 0) {
    return Error(nl_geterror(error));
  }

  Netlink<struct nl_cache> cache(c);
  struct rtnl_link* l = rtnl_link_get(cache.get(), index);
  if (l == NULL) {
    return None();
  }

  return Netlink<struct rtnl_link>(l);
}
Пример #7
0
static int
netlink3_set_interface_parameters(const interface_t *ifp, interface_t *base_ifp)
{
	struct nl_sock *sk;
	struct nl_cache *cache;
	struct rtnl_link *link = NULL;
	struct rtnl_link *new_state = NULL;
	int res = 0;

	if (!(sk = nl_socket_alloc())) {
		log_message(LOG_INFO, "Unable to open netlink socket");
		return -1;
	}

	if (nl_connect(sk, NETLINK_ROUTE) < 0)
		goto err;
	if (rtnl_link_alloc_cache(sk, AF_UNSPEC, &cache))
		goto err;
	if (!(link = rtnl_link_get(cache, ifp->ifindex)))
		goto err;

	// Allocate a new link
	if (!(new_state = rtnl_link_alloc()))
		goto err;

	if (rtnl_link_inet_set_conf(new_state, IPV4_DEVCONF_ARP_IGNORE, 1) ||
	    rtnl_link_inet_set_conf(new_state, IPV4_DEVCONF_ACCEPT_LOCAL, 1) ||
	    rtnl_link_inet_set_conf(new_state, IPV4_DEVCONF_RP_FILTER, 0) ||
	    rtnl_link_inet_set_conf(new_state, IPV4_DEVCONF_PROMOTE_SECONDARIES, 1) ||
	    rtnl_link_change (sk, link, new_state, 0))
		goto err;

	rtnl_link_put(new_state);
	new_state = NULL;

	rtnl_link_put(link);
	link = NULL;

	/* Set arp_ignore and arp_filter on base interface if needed */
	if (base_ifp->reset_arp_config)
		(base_ifp->reset_arp_config)++;
	else {
		if (!(link = rtnl_link_get(cache, base_ifp->ifindex)))
			goto err;
		if (rtnl_link_inet_get_conf(link, IPV4_DEVCONF_ARP_IGNORE, &base_ifp->reset_arp_ignore_value) < 0)
			goto err;
		if (rtnl_link_inet_get_conf(link, IPV4_DEVCONF_ARPFILTER, &base_ifp->reset_arp_filter_value) < 0)
			goto err;

		if (base_ifp->reset_arp_ignore_value != 1 ||
		    base_ifp->reset_arp_filter_value != 1 ) {
			/* The underlying interface mustn't reply for our address(es) */
			if (!(new_state = rtnl_link_alloc()))
				goto err;

			if (rtnl_link_inet_set_conf(new_state, IPV4_DEVCONF_ARP_IGNORE, 1) ||
			    rtnl_link_inet_set_conf(new_state, IPV4_DEVCONF_ARPFILTER, 1) ||
			    rtnl_link_change(sk, link, new_state, 0))
				goto err;

			rtnl_link_put(new_state);
			new_state = NULL;

			rtnl_link_put(link);
			link = NULL;

			base_ifp->reset_arp_config = 1;
		}
	}

	goto exit;
err:
	res = -1;

	if (link)
		rtnl_link_put(link);
	if (new_state)
		rtnl_link_put(new_state);

exit:
	nl_socket_free(sk);

	return res;
}
Пример #8
0
Файл: tc.c Проект: acooks/libnl
int rtnl_tc_msg_parse(struct nlmsghdr *n, struct rtnl_tc *tc)
{
	struct nl_cache *link_cache;
	struct rtnl_tc_ops *ops;
	struct nlattr *tb[TCA_MAX + 1];
	char kind[TCKINDSIZ];
	struct tcmsg *tm;
	int err;

	tc->ce_msgtype = n->nlmsg_type;

	err = nlmsg_parse(n, sizeof(*tm), tb, TCA_MAX, tc_policy);
	if (err < 0)
		return err;

	if (tb[TCA_KIND] == NULL)
		return -NLE_MISSING_ATTR;

	nla_strlcpy(kind, tb[TCA_KIND], sizeof(kind));
	rtnl_tc_set_kind(tc, kind);

	tm = nlmsg_data(n);
	tc->tc_family  = tm->tcm_family;
	tc->tc_ifindex = tm->tcm_ifindex;
	tc->tc_handle  = tm->tcm_handle;
	tc->tc_parent  = tm->tcm_parent;
	tc->tc_info    = tm->tcm_info;

	tc->ce_mask |= (TCA_ATTR_FAMILY | TCA_ATTR_IFINDEX | TCA_ATTR_HANDLE|
		        TCA_ATTR_PARENT | TCA_ATTR_INFO);

	if (tb[TCA_OPTIONS]) {
		tc->tc_opts = nl_data_alloc_attr(tb[TCA_OPTIONS]);
		if (!tc->tc_opts)
			return -NLE_NOMEM;
		tc->ce_mask |= TCA_ATTR_OPTS;
	}

	if (tb[TCA_STATS2]) {
		struct nlattr *tbs[TCA_STATS_MAX + 1];

		err = nla_parse_nested(tbs, TCA_STATS_MAX, tb[TCA_STATS2],
				       tc_stats2_policy);
		if (err < 0)
			return err;

		if (tbs[TCA_STATS_BASIC]) {
			struct gnet_stats_basic *bs;
			
			bs = nla_data(tbs[TCA_STATS_BASIC]);
			tc->tc_stats[RTNL_TC_BYTES]	= bs->bytes;
			tc->tc_stats[RTNL_TC_PACKETS]	= bs->packets;
		}

		if (tbs[TCA_STATS_RATE_EST]) {
			struct gnet_stats_rate_est *re;

			re = nla_data(tbs[TCA_STATS_RATE_EST]);
			tc->tc_stats[RTNL_TC_RATE_BPS]	= re->bps;
			tc->tc_stats[RTNL_TC_RATE_PPS]	= re->pps;
		}
		
		if (tbs[TCA_STATS_QUEUE]) {
			struct gnet_stats_queue *q;

			q = nla_data(tbs[TCA_STATS_QUEUE]);
			tc->tc_stats[RTNL_TC_QLEN]	= q->qlen;
			tc->tc_stats[RTNL_TC_BACKLOG]	= q->backlog;
			tc->tc_stats[RTNL_TC_DROPS]	= q->drops;
			tc->tc_stats[RTNL_TC_REQUEUES]	= q->requeues;
			tc->tc_stats[RTNL_TC_OVERLIMITS]	= q->overlimits;
		}

		tc->ce_mask |= TCA_ATTR_STATS;
		
		if (tbs[TCA_STATS_APP]) {
			tc->tc_xstats = nl_data_alloc_attr(tbs[TCA_STATS_APP]);
			if (tc->tc_xstats == NULL)
				return -NLE_NOMEM;
			tc->ce_mask |= TCA_ATTR_XSTATS;
		} else
			goto compat_xstats;
	} else {
		if (tb[TCA_STATS]) {
			struct tc_stats *st = nla_data(tb[TCA_STATS]);

			tc->tc_stats[RTNL_TC_BYTES]	= st->bytes;
			tc->tc_stats[RTNL_TC_PACKETS]	= st->packets;
			tc->tc_stats[RTNL_TC_RATE_BPS]	= st->bps;
			tc->tc_stats[RTNL_TC_RATE_PPS]	= st->pps;
			tc->tc_stats[RTNL_TC_QLEN]	= st->qlen;
			tc->tc_stats[RTNL_TC_BACKLOG]	= st->backlog;
			tc->tc_stats[RTNL_TC_DROPS]	= st->drops;
			tc->tc_stats[RTNL_TC_OVERLIMITS]= st->overlimits;

			tc->ce_mask |= TCA_ATTR_STATS;
		}

compat_xstats:
		if (tb[TCA_XSTATS]) {
			tc->tc_xstats = nl_data_alloc_attr(tb[TCA_XSTATS]);
			if (tc->tc_xstats == NULL)
				return -NLE_NOMEM;
			tc->ce_mask |= TCA_ATTR_XSTATS;
		}
	}

	ops = rtnl_tc_get_ops(tc);
	if (ops && ops->to_msg_parser) {
		void *data = rtnl_tc_data(tc);

		if (!data)
			return -NLE_NOMEM;

		err = ops->to_msg_parser(tc, data);
		if (err < 0)
			return err;
	}

	if ((link_cache = __nl_cache_mngt_require("route/link"))) {
		struct rtnl_link *link;

		if ((link = rtnl_link_get(link_cache, tc->tc_ifindex))) {
			rtnl_tc_set_link(tc, link);

			/* rtnl_tc_set_link incs refcnt */
			rtnl_link_put(link);
		}
	}

	return 0;
}
Пример #9
0
int main(int argc, char *argv[])
{
	struct nl_sock *nl_sock;
	struct nl_cache *link_cache;
	int ifindex;
	int ret = 0;
	int err = 0;

	if (argc < 2)
	{
		printf("%s ip gw on/off tip\n", argv[0]);
		return -1;
	}

//link
	if (err = rtnl_route_read_table_names(ROUTE_TABLE)) {
		printf("failed to read %s. err = %s\n", ROUTE_TABLE, nl_geterror(err));
		return -1;;
	}

	nl_sock = nl_socket_alloc();
	if (NULL == nl_sock) {
		printf("failed to alloc netlink handler.\n");
		return -1;
	}

	if (err = nl_connect(nl_sock, NETLINK_ROUTE)) {
		printf("failed to connect NETLINK_ROUTE. err = %s\n", nl_geterror(err));
		ret = -1;
		goto release_nl;
	}

	if (err = rtnl_link_alloc_cache(nl_sock, AF_INET, &link_cache))
	{
		printf("failed to allocate link cache. err = %s\n", nl_geterror(err));
		ret = -1;
		goto release_nl;
	}

	ifindex = rtnl_link_name2i(link_cache, NAME);
	if (0 == ifindex) {
		printf("%s - failed to find.\n", NAME);
		ret = -1;
		goto release_link_cache;
	}

	struct rtnl_link * link = rtnl_link_get(link_cache, ifindex);
	if (link == NULL)
	{
		printf("can't get link.\n");
		ret = -1;
		goto release_link_cache;
	}
	//rtnl_link_get_by_name

	struct nl_addr *lladdr = rtnl_link_get_addr(link);
	if (NULL == lladdr || AF_LLC != nl_addr_get_family(lladdr)) {
		printf("failed to get MAC\n");
		ret = -1;
		goto release_link;
	}

	uint8_t mac_address[ETHER_ADDR_LEN];
	memcpy(mac_address, nl_addr_get_binary_addr(lladdr), ETHER_ADDR_LEN);
	printf("%02X:%02X:%02X:%02X:%02X:%02X\n",
		 mac_address[0],
		 mac_address[1],
		 mac_address[2],
		 mac_address[3],
		 mac_address[4],
		 mac_address[5]);

//addr 
	struct nl_cache * addr_cache;
	if (err  = rtnl_addr_alloc_cache(nl_sock, &addr_cache))
	{
		printf("fail to get addr_cache\n");
		ret = -1;
		goto release_link;
	}
	struct rtnl_addr *addr = rtnl_addr_alloc();
	rtnl_addr_set_ifindex(addr, ifindex);
	rtnl_addr_set_family(addr, AF_INET);
	int prefixlen = 16;
	nl_cache_foreach_filter(addr_cache, (struct nl_object *)addr, get_ip, &prefixlen);
	nl_cache_free(addr_cache);

	uint32_t ipaddr = inet_addr(argv[1]);
	struct nl_addr * local = nl_addr_build(AF_INET, &ipaddr, sizeof(ipaddr));
	rtnl_addr_set_local(addr, local);
	rtnl_addr_set_ifindex(addr, ifindex);
	rtnl_addr_set_family(addr, AF_INET);
	rtnl_addr_set_prefixlen(addr, 32);

	if (!strcmp(argv[2], "on"))
	{
		if (err = rtnl_addr_add(nl_sock, addr, 0))
		{
			printf("fail to add addr %s\n", nl_geterror(err));
			ret = -1;
			goto release_addr;
		}
	}
	else
	{
		if (err = rtnl_addr_delete(nl_sock, addr, 0))
		{
			printf("fail to del addr %s\n", nl_geterror(err));
			ret = -1;
			goto release_addr;
		}
		
	}
//neigh
	struct nl_cache * neigh_cache;
	if (err = rtnl_neigh_alloc_cache(nl_sock, &neigh_cache))
	{
		printf("failed to allocate neighbor cache. err = %s\n", nl_geterror(err));
		ret = -1;
		goto release_neigh_cache;
	}

	uint32_t gw = inet_addr(argv[3]);
	struct nl_addr * gw_addr = nl_addr_build(AF_INET, &gw, sizeof(gw));

	struct rtnl_neigh * neigh = rtnl_neigh_get(neigh_cache, ifindex, gw_addr);
	if (neigh) {
		// It's optional
		struct nl_addr * lladdr = rtnl_neigh_get_lladdr(neigh);
		if (lladdr) {
			uint8_t mac_address[ETHER_ADDR_LEN];
			memcpy(mac_address, nl_addr_get_binary_addr(lladdr), ETHER_ADDR_LEN);
			printf("gw  %02X:%02X:%02X:%02X:%02X:%02X\n",
		 		mac_address[0],
		 		mac_address[1],
		 		mac_address[2],
		 		mac_address[3],
		 		mac_address[4],
		 		mac_address[5]);
		}
	}

	nl_addr_put(gw_addr);

//route
	struct nl_cache *route_cache;
	if (err = rtnl_route_alloc_cache(nl_sock, AF_INET, 0, &route_cache))
	{
		printf("failed to allocate route cache. err = %s\n", nl_geterror(err));
		ret = -1;
		goto release_neigh_cache;
	}

	struct rtnl_route *route = rtnl_route_alloc();
	struct nl_addr * taddr;
	err = nl_addr_parse(argv[4], AF_INET, &taddr);
        if (err)
        {
                printf("failed to get taddr. err = %s\n", nl_geterror(err));
                ret = -1;
                goto release_route_cache;
                
        }

	nl_cache_foreach_filter(route_cache, OBJ_CAST(route), get_route, NULL);
/*
	struct nl_sock *nl_fib_sock;
	nl_fib_sock = nl_socket_alloc();
	if (err = nl_connect(nl_fib_sock, NETLINK_FIB_LOOKUP)) {
		printf("failed to connect NETLINK_ROUTE. err = %s\n", nl_geterror(err));
		ret = -1;
		goto release_nl;
	}
	struct nl_dump_params params = {
		.dp_fd = stdout,
		.dp_type = NL_DUMP_DETAILS,
	};

	struct nl_cache *route_cache = flnl_result_alloc_cache();

        struct flnl_request *req = flnl_request_alloc();
        struct nl_addr * taddr;
	err = nl_addr_parse(argv[4], AF_INET, &taddr);
	if (err)
	{
		printf("failed to get taddr. err = %s\n", nl_geterror(err));
		ret = -1;
		goto release_route;
		
	}
	int table = RT_TABLE_UNSPEC, scope = RT_SCOPE_UNIVERSE;
        flnl_request_set_addr(req, taddr);
	flnl_request_set_table(req, table);
	flnl_request_set_scope(req, scope);
        err = flnl_lookup(nl_fib_sock, req, route_cache);
	if (err)
	{
		printf("failed to fib lookup. err = %s\n", nl_geterror(err));
		ret = -1;
		goto release_route_addr;
	}
	
	nl_cache_dump(route_cache, &params);

release_route_addr:
	nl_addr_put(taddr);	

release_route:
        nl_cache_free(route_cache);
	nl_object_put(OBJ_CAST(req));

	nl_close(nl_fib_sock);
	nl_socket_free(nl_fib_sock);
*/
release_route_cache:
	nl_cache_free(route_cache);
release_neigh_cache:
	nl_cache_free(neigh_cache);
release_addr:
	nl_addr_put(local);
	rtnl_addr_put(addr);
release_link:
	rtnl_link_put(link);
release_link_cache:
	nl_cache_free(link_cache);
release_nl:
	nl_close(nl_sock);
	nl_socket_free(nl_sock);

	return ret;
}