예제 #1
0
	NetLinkManager::NetLinkManager()
	 : _initialized(false), _sock(NULL), _refresh_cache(false)
	{
		ibrcommon::MutexLock l(_call_mutex);

		_handle = nl_handle_alloc();
		nl_connect(_handle, NETLINK_ROUTE);

		_link_cache = rtnl_link_alloc_cache(_handle);

		if (_link_cache == NULL)
		{
			nl_close(_handle);
			nl_handle_destroy(_handle);
			throw ibrcommon::vsocket_exception("netlink cache allocation failed");
		}

		_addr_cache = rtnl_addr_alloc_cache(_handle);

		if (_addr_cache == NULL)
		{
			nl_close(_handle);
			nl_handle_destroy(_handle);
			nl_cache_free(_link_cache);
			_link_cache = NULL;
			throw ibrcommon::vsocket_exception("netlink cache allocation failed");
		}

		_initialized = true;

		// create a new socket for the netlink interface
		_sock = new ibrcommon::vsocket();
	}
예제 #2
0
/* ---------------------------------------------------------------------- */
static int
nl_open (pid_t *pid)
{
  struct sockaddr_nl nladdr;
  int sd;

  sd = socket (PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
  if (sd < 0)
    return -1;
  memset (&nladdr, 0, sizeof (nladdr));
  nladdr.nl_family = AF_NETLINK;
  if (bind (sd, (struct sockaddr *) &nladdr, sizeof (nladdr)) < 0)
    {
      nl_close (sd);
      return -1;
    }
  if (pid)
    {
      socklen_t len = sizeof(nladdr);
      if (getsockname (sd, (struct sockaddr *) &nladdr, &len) < 0)
        {
          nl_close (sd);
          return -1;
        }
      *pid = nladdr.nl_pid;
    }
  return sd;
}
예제 #3
0
/**
 * Free cache manager and all caches.
 * @arg mngr		Cache manager.
 *
 * Release all resources held by a cache manager.
 */
void nl_cache_mngr_free(struct nl_cache_mngr *mngr)
{
	int i;

	if (!mngr)
		return;

	if (mngr->cm_sock)
		nl_close(mngr->cm_sock);

	if (mngr->cm_sync_sock) {
		nl_close(mngr->cm_sync_sock);
		nl_socket_free(mngr->cm_sync_sock);
	}

	if (mngr->cm_flags & NL_ALLOCATED_SOCK)
		nl_socket_free(mngr->cm_sock);

	for (i = 0; i < mngr->cm_nassocs; i++) {
		if (mngr->cm_assocs[i].ca_cache) {
			nl_cache_mngt_unprovide(mngr->cm_assocs[i].ca_cache);
			nl_cache_free(mngr->cm_assocs[i].ca_cache);
		}
	}

	free(mngr->cm_assocs);

	NL_DBG(1, "Cache manager %p freed\n", mngr);

	free(mngr);
}
예제 #4
0
파일: netlink.c 프로젝트: alphadx/NAT64
int netlink_request(void *request, __u16 request_len, int (*cb)(struct nl_msg *, void *),
		void *cb_arg)
{
	struct nl_sock *sk;
	enum nl_cb_type callbacks[] = { NL_CB_VALID, NL_CB_FINISH, NL_CB_ACK };
	int i;
	int error;

	sk = nl_socket_alloc();
	if (!sk) {
		log_err(ERR_ALLOC_FAILED, "Could not allocate a socket; cannot speak to the NAT64.");
		return -ENOMEM;
	}

	for (i = 0; i < (sizeof(callbacks) / sizeof(callbacks[0])); i++) {
		error = nl_socket_modify_cb(sk, callbacks[i], NL_CB_CUSTOM, cb, cb_arg);
		if (error < 0) {
			log_err(ERR_NETLINK, "Could not register response handler. "
					"I won't be able to parse the NAT64's response, so I won't send the request.\n"
					"Netlink error message: %s (Code %d)", nl_geterror(error), error);
			goto fail_free;
		}
	}

	error = nl_connect(sk, NETLINK_USERSOCK);
	if (error < 0) {
		log_err(ERR_NETLINK, "Could not bind the socket to the NAT64.\n"
				"Netlink error message: %s (Code %d)", nl_geterror(error), error);
		goto fail_free;
	}

	error = nl_send_simple(sk, MSG_TYPE_NAT64, 0, request, request_len);
	if (error < 0) {
		log_err(ERR_NETLINK, "Could not send the request to the NAT64 (is it really up?).\n"
				"Netlink error message: %s (Code %d)", nl_geterror(error), error);
		goto fail_close;
	}

	error = nl_recvmsgs_default(sk);
	if (error < 0) {
		log_err(ERR_NETLINK, "%s (System error %d)", nl_geterror(error), error);
		goto fail_close;
	}

	nl_close(sk);
	nl_socket_free(sk);
	return 0;

fail_close:
	nl_close(sk);
	/* Fall through. */

fail_free:
	nl_socket_free(sk);
	return -EINVAL;
}
예제 #5
0
파일: stream.c 프로젝트: binasc/utils
static void accept_handler(nl_event_t *ev)
{
    nl_socket_t         *sock;
    nl_stream_t         *s;
    int                 rc;

    sock = ev->data;
    log_trace("#%d accept_handler", sock->fd);
    s = sock->data;

    s->error = 0;
    for ( ; ; ) {
        rc = nl_accept(sock, &s->accepted_sock);
        if (rc == -1) {
            if (sock->error) {
                s->error = 1;
                nl_stream_close(s);
                break;
            }
            else if (s->accepted_sock.error) {
                continue;
            }
            else {
                break;
            }
        }

        s->accepted = 0;
        s->cbs.on_accepted(s);
        if (!s->accepted) {
            nl_close(&s->accepted_sock);
        }
    }
}
예제 #6
0
int
kern_bcache_init()
{
	supsocket_t *sock;

	nl_bcache = nl_handle_alloc();
	nl_disable_sequence_check(nl_bcache);
	nl_join_groups(nl_bcache, ~0);

	nl_cb_set(nl_handle_get_cb(nl_bcache), NL_CB_VALID, NL_CB_CUSTOM,
		  nl_bcache_event, NULL);

	if (nl_connect(nl_bcache, NETLINK_IP6MBLTY) < 0) {
		debug_log(1, "nl_connect(NETLINK_IP6MBLTY) failed: %s.\n",
			  strerror(errno));
		nl_close(nl_bcache);
		nl_bcache = NULL;
		return -1;
	}

	fcntl(nl_handle_get_fd(nl_bcache), F_SETFL, O_NONBLOCK);

	sock = support_register_socket(nl_handle_get_fd(nl_bcache),
				       nl_bcache_events_waiting, NULL, NULL);
	sock->mode = SUPSOCKET_READ;

	return 0;
}
int main(int argc, char *argv[])
{
	struct nl_sock *sock;
	struct nl_msg *msg;
	void *hdr;
	int err;

	sock = nlt_alloc_socket();
	nlt_connect(sock, NETLINK_GENERIC);

	msg = nlmsg_alloc();
	if (msg == NULL)
		fatal(NLE_NOMEM, "Unable to allocate netlink message");

	hdr = genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, GENL_ID_CTRL,
			  0, 0, CTRL_CMD_GETFAMILY, 1);
	if (hdr == NULL)
		fatal(ENOMEM, "Unable to write genl header");

	if ((err = nla_put_u32(msg, CTRL_ATTR_FAMILY_ID, GENL_ID_CTRL)) < 0)
		fatal(err, "Unable to add attribute: %s", nl_geterror(err));

	if ((err = nl_send_auto_complete(sock, msg)) < 0)
		fatal(err, "Unable to send message: %s", nl_geterror(err));

	if ((err = nl_recvmsgs_default(sock)) < 0)
		fatal(err, "Unable to receive message: %s", nl_geterror(err));

	nlmsg_free(msg);
	nl_close(sock);
	nl_socket_free(sock);

	return 0;
}
예제 #8
0
파일: stream.c 프로젝트: binasc/utils
static void nl_stream_destroy(nl_stream_t *s)
{
    struct list_iterator_t  it;
    nl_buf_t                *buf;

    for (it = list_begin(s->tosend);
         !list_iterator_equal(list_end(s->tosend), it);
         it = list_iterator_next(it)) {
        buf = list_iterator_item(it);
        free(buf->buf);
    }
    list_destroy(s->tosend);

    while (s->encoders != NULL) {
        nl_stream_encoder_pop_back(s);
    }
    while (s->decoders != NULL) {
        nl_stream_decoder_pop_back(s);
    }

    log_trace("#%d destroyed", s->sock.fd);

    nl_close(&s->sock);

    if (s->cbs.on_closed != NULL) {
        s->cbs.on_closed(s);
    }
}
예제 #9
0
int main(int argc, char *argv[])
{
	struct rtnl_link *link;
	struct nl_sock *sk;
	int err;

	sk = nl_socket_alloc();
	if ((err = nl_connect(sk, NETLINK_ROUTE)) < 0) {
		nl_perror(err, "Unable to connect socket");
		return err;
	}

	link = rtnl_link_alloc();
	rtnl_link_set_name(link, "my_bond");

	if ((err = rtnl_link_delete(sk, link)) < 0) {
		nl_perror(err, "Unable to delete link");
		return err;
	}

	rtnl_link_put(link);
	nl_close(sk);

	return 0;
}
예제 #10
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;
}
예제 #11
0
/**
 * virNetlinkEventServiceStop:
 *
 * stop the monitor to receive netlink messages for libvirtd.
 * This removes the netlink socket fd from the event handler.
 *
 * @protocol: netlink protocol
 *
 * Returns -1 if the monitor cannot be unregistered, 0 upon success
 */
int
virNetlinkEventServiceStop(unsigned int protocol)
{
    if (protocol >= MAX_LINKS)
        return -EINVAL;

    virNetlinkEventSrvPrivatePtr srv = server[protocol];
    size_t i;

    VIR_INFO("stopping netlink event service");

    if (!server[protocol])
        return 0;

    virNetlinkEventServerLock(srv);
    nl_close(srv->netlinknh);
    virNetlinkFree(srv->netlinknh);
    virEventRemoveHandle(srv->eventwatch);

    /* free any remaining clients on the list */
    for (i = 0; i < srv->handlesCount; i++) {
        if (srv->handles[i].deleted == VIR_NETLINK_HANDLE_VALID)
            virNetlinkEventRemoveClientPrimitive(i, protocol);
    }

    server[protocol] = NULL;
    virNetlinkEventServerUnlock(srv);

    virMutexDestroy(&srv->lock);
    VIR_FREE(srv);
    return 0;
}
예제 #12
0
파일: virnetlink.c 프로젝트: intgr/libvirt
/**
 * virNetlinkEventServiceStop:
 *
 * stop the monitor to receive netlink messages for libvirtd.
 * This removes the netlink socket fd from the event handler.
 *
 * Returns -1 if the monitor cannot be unregistered, 0 upon success
 */
int
virNetlinkEventServiceStop(void)
{
    virNetlinkEventSrvPrivatePtr srv = server;
    int i;

    VIR_INFO("stopping netlink event service");

    if (!server)
        return 0;

    virNetlinkEventServerLock(srv);
    nl_close(srv->netlinknh);
    virNetlinkFree(srv->netlinknh);
    virEventRemoveHandle(srv->eventwatch);

    /* free any remaining clients on the list */
    for (i = 0; i < srv->handlesCount; i++) {
        if (srv->handles[i].deleted == VIR_NETLINK_HANDLE_VALID)
            virNetlinkEventRemoveClientPrimitive(i);
    }

    server = 0;
    virNetlinkEventServerUnlock(srv);

    virMutexDestroy(&srv->lock);
    VIR_FREE(srv);
    return 0;
}
예제 #13
0
파일: netlink.cpp 프로젝트: direvius/porto
void TNl::Disconnect() {
    if (Sock) {
        nl_close(Sock);
        nl_socket_free(Sock);
        Sock = nullptr;
    }
}
예제 #14
0
/**
 * virNetlinkEventServiceStopAll:
 *
 * Stop all the monitors to receive netlink messages for libvirtd.
 *
 * Returns -1 if any monitor cannot be unregistered, 0 upon success
 */
int
virNetlinkEventServiceStopAll(void)
{
    size_t i, j;
    virNetlinkEventSrvPrivatePtr srv = NULL;

    VIR_INFO("stopping all netlink event services");

    for (i = 0; i < MAX_LINKS; i++) {
        srv = server[i];
        if (!srv)
            continue;

        virNetlinkEventServerLock(srv);
        nl_close(srv->netlinknh);
        virNetlinkFree(srv->netlinknh);
        virEventRemoveHandle(srv->eventwatch);

        for (j = 0; j < srv->handlesCount; j++) {
            if (srv->handles[j].deleted == VIR_NETLINK_HANDLE_VALID)
                virNetlinkEventRemoveClientPrimitive(j, i);
        }

        server[i] = NULL;
        virNetlinkEventServerUnlock(srv);

        virMutexDestroy(&srv->lock);
        VIR_FREE(srv);
    }

    return 0;
}
예제 #15
0
void ompi_btl_usnic_rtnl_sk_free(struct usnic_rtnl_sk *unlsk)
{
    if (unlsk != NULL) {
	nl_close(unlsk->sock);
	nl_socket_free(unlsk->sock);
	free(unlsk);
    }
}
예제 #16
0
void usnic_rtnl_sk_free(struct usnic_rtnl_sk* u_nlsk)
{
    if (u_nlsk != NULL) {
	nl_close(u_nlsk->nlh);
	nl_handle_destroy(u_nlsk->nlh);
	free(u_nlsk);
    }
}
int main(int argc, char *argv[])
{
	struct nl_handle *nlh;
	struct rtnl_addr *addr;
	struct nl_addr *local;
	int err = 1;

	if (argc < 3 || !strcmp(argv[1], "-h")) {
		printf("Usage: nl-addr-delete <addr> <ifindex>\n");
		goto errout;
	}

	if (nltool_init(argc, argv) < 0)
		goto errout;

	nlh = nltool_alloc_handle();
	if (!nlh)
		goto errout;

	addr = rtnl_addr_alloc();
	if (!addr)
		goto errout_free_handle;

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

	local = nltool_addr_parse(argv[1]);
	if (!local)
		goto errout_close;

	if (rtnl_addr_set_local(addr, local) < 0) {
		fprintf(stderr, "Unable to set local address: %s\n",
			nl_geterror());
		goto errout_addr_put;
	}

	rtnl_addr_set_ifindex(addr, strtoul(argv[2], NULL, 0));

	if (rtnl_addr_delete(nlh, addr, 0) < 0) {
		fprintf(stderr, "Unable to delete address: %s\n",
			nl_geterror());
		goto errout_addr_put;
	}

	err = 0;

errout_addr_put:
	nl_addr_put(local);
errout_close:
	nl_close(nlh);
errout_free_addr:
	rtnl_addr_put(addr);
errout_free_handle:
	nl_handle_destroy(nlh);
errout:
	return err;
}
예제 #18
0
int main(int argc, char *argv[])
{
    struct nl_handle *nlh;
    struct nl_cache *link_cache, *addr_cache;
    struct rtnl_addr *addr;
    struct nl_dump_params params = {
        .dp_fd = stdout,
        .dp_type = NL_DUMP_BRIEF
    };
    int err = 1;

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

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

    addr = rtnl_addr_alloc();
    if (!addr)
        goto errout;

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

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

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

    addr_cache = nltool_alloc_addr_cache(nlh);
    if (!addr_cache)
        goto errout_link_cache;

    params.dp_type = nltool_parse_dumptype(argv[1]);
    if (params.dp_type < 0)
        goto errout_addr_cache;
    get_filter(addr, argc, argv, 2, link_cache);

    nl_cache_dump_filter(addr_cache, &params, (struct nl_object *) addr);

    err = 0;

errout_addr_cache:
    nl_cache_free(addr_cache);
errout_link_cache:
    nl_cache_free(link_cache);
errout_close:
    nl_close(nlh);
errout_free:
    rtnl_addr_put(addr);
errout:
    return err;
}
예제 #19
0
void
kern_bcache_shutdown()
{
	if (nl_bcache) {
		support_unregister_socket(nl_handle_get_fd(nl_bcache));
		nl_close(nl_bcache);
		nl_handle_destroy(nl_bcache);
		nl_bcache = NULL;
	}
}
예제 #20
0
int main(int argc, char *argv[])
{
	struct nl_cache *link_cache;
	struct rtnl_link *link, *link2;
	struct nl_sock *sk;
	uint32_t tb_id;
	int err;

	sk = nl_socket_alloc();
	if ((err = nl_connect(sk, NETLINK_ROUTE)) < 0) {
		nl_perror(err, "Unable to connect socket");
		return err;
	}

	if (!(link = rtnl_link_vrf_alloc())) {
		fprintf(stderr, "Unable to allocate link");
		return -1;
	}

	rtnl_link_set_name(link, "vrf-red");

	if ((err = rtnl_link_vrf_set_tableid(link, 10)) < 0) {
		nl_perror(err, "Unable to set VRF table id");
		return err;
	}

	if ((err = rtnl_link_add(sk, link, NLM_F_CREATE)) < 0) {
		nl_perror(err, "Unable to add link");
		return err;
	}

	if ((err = rtnl_link_alloc_cache(sk, AF_UNSPEC, &link_cache)) < 0) {
		nl_perror(err, "Unable to allocate cache");
		return err;
	}

	if (!(link2 = rtnl_link_get_by_name(link_cache, "vrf-red"))) {
		fprintf(stderr, "Unable to lookup vrf-red");
		return -1;
	}

	if ((err = rtnl_link_vrf_get_tableid(link2, &tb_id)) < 0) {
		nl_perror(err, "Unable to get VRF table id");
		return err;
	}

	if (tb_id != 10) {
		fprintf(stderr, "Mismatch with VRF table id\n");
	}

	rtnl_link_put(link);
	nl_close(sk);

	return 0;
}
예제 #21
0
static void lib_fini(void)
{
	if (lib_cfg.head == NULL) {
#ifdef KNET_LINUX
		nl_close(lib_cfg.nlsock);
		nl_socket_free(lib_cfg.nlsock);
#endif
		close(lib_cfg.ioctlfd);
		lib_init = 0;
	}
}
예제 #22
0
static void ovs_global_init(void)
{
	struct nl_handle hnd;

	if (genl_open(&hnd)) {
		vport_genl_id = 0;
		return;
	}
	vport_genl_id = genl_family_id(&hnd, OVS_VPORT_FAMILY);
	nl_close(&hnd);
	return;
}
예제 #23
0
int main(int argc, char *argv[])
{
	struct nl_cache *link_cache;
	struct rtnl_link *link;
	struct in_addr addr;
	struct nl_sock *sk;
	int err, if_index;

	sk = nl_socket_alloc();
	if ((err = nl_connect(sk, NETLINK_ROUTE)) < 0) {
		nl_perror(err, "Unable to connect socket");
		return err;
	}

	err = rtnl_link_alloc_cache(sk, AF_UNSPEC, &link_cache);
	if ( err < 0) {
		nl_perror(err, "Unable to allocate cache");
		return err;
	}

	if_index = rtnl_link_name2i(link_cache, "eno16777736");
	if (!if_index) {
		fprintf(stderr, "Unable to lookup eno16777736");
		return -1;
	}

	link = rtnl_link_sit_alloc();
	if(!link) {
		nl_perror(err, "Unable to allocate link");
		return -1;

	}
	rtnl_link_set_name(link, "sit-tun");
	rtnl_link_sit_set_link(link, if_index);

	inet_pton(AF_INET, "192.168.254.12", &addr.s_addr);
	rtnl_link_sit_set_local(link, addr.s_addr);

	inet_pton(AF_INET, "192.168.254.13", &addr.s_addr);
	rtnl_link_sit_set_remote(link, addr.s_addr);

	rtnl_link_sit_set_ttl(link, 64);
	err = rtnl_link_add(sk, link, NLM_F_CREATE);
	if (err < 0) {
		nl_perror(err, "Unable to add link");
		return err;
	}

	rtnl_link_put(link);
	nl_close(sk);

	return 0;
}
예제 #24
0
int main(int argc, char *argv[])
{
	struct nl_cache *link_cache;
	struct rtnl_link *link;
        struct in6_addr addr;
	struct nl_sock *sk;
	int err, if_index;

	sk = nl_socket_alloc();
	if ((err = nl_connect(sk, NETLINK_ROUTE)) < 0) {
		nl_perror(err, "Unable to connect socket");
		return err;
	}

	err = rtnl_link_alloc_cache(sk, AF_UNSPEC, &link_cache);
	if ( err < 0) {
		nl_perror(err, "Unable to allocate cache");
		return err;
	}

	if_index = rtnl_link_name2i(link_cache, "ens33");
	if (!if_index) {
		fprintf(stderr, "Unable to lookup ens33");
		return -1;
	}

	link = rtnl_link_ip6_tnl_alloc();
	if(!link) {
		nl_perror(err, "Unable to allocate link");
		return -1;

	}
	rtnl_link_set_name(link, "ip6tnl-tun");
	rtnl_link_ip6_tnl_set_link(link, if_index);

	inet_pton(AF_INET6, "2607:f0d0:1002:51::4", &addr);
	rtnl_link_ip6_tnl_set_local(link, &addr);

	inet_pton(AF_INET6, "2607:f0d0:1002:52::5", &addr);
	rtnl_link_ip6_tnl_set_remote(link, &addr);

	err = rtnl_link_add(sk, link, NLM_F_CREATE);
	if (err < 0) {
		nl_perror(err, "Unable to add link");
		return err;
	}

	rtnl_link_put(link);
	nl_close(sk);

	return 0;
}
예제 #25
0
	void lowpansocket::getAddress(struct ieee802154_addr *ret, const vinterface &iface)
	{
#if defined HAVE_LIBNL || HAVE_LIBNL3
#ifdef HAVE_LIBNL3
		struct nl_sock *nl = nl_socket_alloc();
#else
		struct nl_handle *nl = nl_handle_alloc();
#endif
		unsigned char *buf = NULL;
		struct sockaddr_nl nla;
		struct nlattr *attrs[IEEE802154_ATTR_MAX+1];
		struct genlmsghdr *ghdr;
		struct nlmsghdr *nlh;
		struct nl_msg *msg;
		int family;

		if (!nl)
		        return;

		genl_connect(nl);

		/* Build and send message */
		msg = nlmsg_alloc();
		family = genl_ctrl_resolve(nl, "802.15.4 MAC");
		genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, family, 0, NLM_F_ECHO, IEEE802154_LIST_IFACE, 1);
		nla_put_string(msg, IEEE802154_ATTR_DEV_NAME, iface.toString().c_str());
		nl_send_auto_complete(nl, msg);
		nlmsg_free(msg);

		/* Receive and parse answer */
		nl_recv(nl, &nla, &buf, NULL);
		nlh = (struct nlmsghdr*)buf;
		genlmsg_parse(nlh, 0, attrs, IEEE802154_ATTR_MAX, ieee802154_policy);
		ghdr = (genlmsghdr*)nlmsg_data(nlh);
		if (!attrs[IEEE802154_ATTR_SHORT_ADDR] || !attrs[IEEE802154_ATTR_SHORT_ADDR])
		        return;

		// We only handle short addresses right now
		ret->addr_type = IEEE802154_ADDR_SHORT;
		ret->pan_id = nla_get_u16(attrs[IEEE802154_ATTR_PAN_ID]);
		ret->short_addr = nla_get_u16(attrs[IEEE802154_ATTR_SHORT_ADDR]);

		free(buf);
		nl_close(nl);

#ifdef HAVE_LIBNL3
		nl_socket_free(nl);
#else
		nl_handle_destroy(nl);
#endif
#endif
	}
예제 #26
0
	NetLinkManager::~NetLinkManager()
	{
		stop();
		join();

		// destroy the socket for the netlink interface
		delete _sock;

		nl_close(_handle);
		nl_cache_free(_addr_cache);
		nl_cache_free(_link_cache);
		nl_handle_destroy(_handle);
	}
예제 #27
0
	void NetLinkManager::run()
	{
		struct nl_handle *handle = nl_handle_alloc();
		nl_connect(handle, NETLINK_ROUTE);

		// init route messages
		nl_socket_add_membership(handle, RTNLGRP_IPV4_IFADDR);

//		IPv6 requires further support in the parsing procedures!
//		nl_socket_add_membership(handle, RTNLGRP_IPV6_IFADDR);
		nl_socket_add_membership(handle, RTNLGRP_LINK);

		// add netlink fd to vsocket
		_sock->add(nl_socket_get_fd(handle));

		try {
			while (_initialized)
			{
				std::list<int> fds;
				_sock->select(fds, NULL);
				int fd = fds.front();

				// create a new event object
				NetLinkManagerEvent lme(fd);

				// ignore if the event is unknown
				if (lme.getType() == LinkManagerEvent::EVENT_UNKOWN) continue;

				// ignore if this is an wireless extension event
				if (lme.isWirelessExtension()) continue;

				// need to refresh the cache
				{
					ibrcommon::MutexLock l(_call_mutex);
					_refresh_cache = true;
				}

				// print out some debugging
				IBRCOMMON_LOGGER_DEBUG(10) << lme.toString() << IBRCOMMON_LOGGER_ENDL;

				// notify all subscribers about this event
				raiseEvent(lme);
			}
		} catch (const vsocket_exception&) {
			// stopped / interrupted
			IBRCOMMON_LOGGER(error) << "NetLink connection stopped" << IBRCOMMON_LOGGER_ENDL;
		}

		nl_close(handle);
		nl_handle_destroy(handle);
	}
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;
}
예제 #29
0
int main()
{
  struct nl_sock * sk;
  int cbarg;

  // nl_debug = 4;

  // setup netlink socket
  sk = nl_socket_alloc();
  nl_socket_disable_seq_check(sk);	// disable sequence number check
  genl_connect(sk);

  int id = genl_ctrl_resolve(sk, DEMO_FAMILY_NAME);

  struct nl_msg * msg;


  // create a messgae
  msg = nlmsg_alloc();
  genlmsg_put(msg, NL_AUTO_PORT, NL_AUTO_SEQ, id, 0,	// hdrlen
                        0,	// flags
                        DEMO_CMD,	// numeric command identifier
                        DEMO_VERSION	// interface version
                       );

  nla_put_string(msg, DEMO_ATTR1_STRING, "hola");
  nla_put_u16(msg, DEMO_ATTR2_UINT16, 0xf1);

  // send it
  nl_send_auto(sk, msg);

  // handle reply
  struct nl_cb * cb = NULL;
  cb = nl_cb_alloc(NL_CB_CUSTOM);

  //nl_cb_set_all(cb, NL_CB_DEBUG, NULL, NULL);
  nl_cb_set_all(cb, NL_CB_CUSTOM, cb_handler, &cbarg);
  nl_cb_err(cb, NL_CB_DEBUG, NULL, NULL);

  int nrecv = nl_recvmsgs_report(sk, cb);

  printf("cbarg %d nrecv %d\n", cbarg, nrecv);

  // cleanup
  nlmsg_free(msg);
  nl_close(sk);
  nl_socket_free(sk);

  return 0;
}
예제 #30
0
/*
 * Return an NETLINK_ROUTE cache.
 */
static struct nl_cache *_iface_get_link_cache(struct nl_handle **handle) {
    struct nl_cache *cache = NULL;

    if ((*handle = _iface_get_handle()) == NULL) {
        return NULL;
    }

    if ((cache = rtnl_link_alloc_cache(*handle)) == NULL) {
        nl_close(*handle);
        nl_handle_destroy(*handle);
        return NULL;
    }

    return cache;
}