Esempio n. 1
0
static int send_and_recv(struct nl_sock *nl_sock, struct nl_msg *msg,
                         int (*valid_handler)(struct nl_msg *, void *),
                         void *valid_data)
{
        struct nl_cb *cb;
        int err = -ENOMEM;

        cb = nl_cb_clone(nlcfg.nl_cb);
        if (!cb)
                goto out;

        err = nl_send_auto_complete(nl_sock, msg);
        if (err < 0)
                goto out;

        err = 1;

        nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err);
        nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err);
        nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err);

        if (valid_handler)
                nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM,
                          valid_handler, valid_data);

        while (err > 0)
                nl_recvmsgs(nl_sock, cb);
 out:
        nl_cb_put(cb);
        nlmsg_free(msg);
        return err;
}
Esempio n. 2
0
static int
wprobe_send_msg(struct nl_msg *msg, void *callback, void *arg)
{
    struct nl_cb *cb;
    int err = 0;

    cb = nl_cb_alloc(NL_CB_DEFAULT);
    if (!cb)
        goto out_no_cb;

    if (callback)
        nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, callback, arg);

    err = nl_send_auto_complete(handle, msg);
    if (err < 0)
        goto out;

    err = 1;

    nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err);
    nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err);
    nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err);

    while (err > 0)
        nl_recvmsgs(handle, cb);

out:
    nl_cb_put(cb);
out_no_cb:
    nlmsg_free(msg);
    return err;
}
int dhd_nl_sock_connect(struct dhd_netlink_info *dhd_nli)
{
	dhd_nli->nl = nl_socket_alloc();
	if (dhd_nli->nl == NULL)
		return -1;

	if (genl_connect(dhd_nli->nl) < 0) {
		fprintf(stderr, "netlink connection failed\n");
		goto err;
	}

	dhd_nli->nl_id = genl_ctrl_resolve(dhd_nli->nl, "nl80211");
	if (dhd_nli->nl_id < 0) {
		fprintf(stderr, "'nl80211' netlink not found\n");
		goto err;
	}

	dhd_nli->cb = nl_cb_alloc(NL_CB_DEBUG);
	if (dhd_nli->cb == NULL)
		goto err;

	nl_socket_set_cb(dhd_nli->nl, dhd_nli->cb);
	return 0;

err:
	nl_cb_put(dhd_nli->cb);
	nl_socket_free(dhd_nli->nl);
	fprintf(stderr, "nl80211 connection failed\n");
	return -1;
}
Esempio n. 4
0
/**
 * Pickup netlink answer, parse is and return object
 * @arg sk		Netlink socket
 * @arg parser		Parser function to parse answer
 * @arg result		Result pointer to return parsed object
 *
 * @return 0 on success or a negative error code.
 */
int nl_pickup(struct nl_sock *sk,
	      int (*parser)(struct nl_cache_ops *, struct sockaddr_nl *,
			    struct nlmsghdr *, struct nl_parser_param *),
	      struct nl_object **result)
{
	struct nl_cb *cb;
	int err;
	struct pickup_param pp = {
		.parser = parser,
	};

	cb = nl_cb_clone(sk->s_cb);
	if (cb == NULL)
		return -NLE_NOMEM;

	nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, __pickup_answer, &pp);

	err = nl_recvmsgs(sk, cb);
	if (err < 0)
		goto errout;

	*result = pp.result;
errout:
	nl_cb_put(cb);

	return err;
}
Esempio n. 5
0
int unl_genl_request(struct unl *unl, struct nl_msg *msg, unl_cb handler, void *arg)
{
	struct nlmsghdr *nlh;
	struct nl_cb *cb;
	int err;

	cb = nl_cb_alloc(NL_CB_CUSTOM);
	nlh = nlmsg_hdr(msg);

	err = nl_send_auto_complete(unl->sock, msg);
	if (err < 0)
		goto out;

	err = 1;
	nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err);
	nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err);
	nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err);
	if (handler)
		nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, handler, arg);

	while (err > 0)
		nl_recvmsgs(unl->sock, cb);

out:
	nlmsg_free(msg);
	nl_cb_put(cb);
	return err;
}
Esempio n. 6
0
static struct nl80211_msg_conveyor * nl80211_new(struct genl_family *family,
                                                 int cmd, int flags)
{
	static struct nl80211_msg_conveyor cv;

	struct nl_msg *req = NULL;
	struct nl_cb *cb = NULL;

	req = nlmsg_alloc();
	if (!req)
		goto err;

	cb = nl_cb_alloc(NL_CB_DEFAULT);
	if (!cb)
		goto err;

	genlmsg_put(req, 0, 0, genl_family_get_id(family), 0, flags, cmd, 0);

	cv.msg = req;
	cv.cb  = cb;

	return &cv;

err:
nla_put_failure:
	if (cb)
		nl_cb_put(cb);

	if (req)
		nlmsg_free(req);

	return NULL;
}
Esempio n. 7
0
static struct nl80211_msg_conveyor * nl80211_send(
	struct nl80211_msg_conveyor *cv,
	int (*cb_func)(struct nl_msg *, void *), void *cb_arg
) {
	static struct nl80211_msg_conveyor rcv;
	int err = 1;

	if (cb_func)
		nl_cb_set(cv->cb, NL_CB_VALID, NL_CB_CUSTOM, cb_func, cb_arg);
	else
		nl_cb_set(cv->cb, NL_CB_VALID, NL_CB_CUSTOM, nl80211_msg_response, &rcv);

	if (nl_send_auto_complete(nls->nl_sock, cv->msg) < 0)
		goto err;

	nl_cb_err(cv->cb,               NL_CB_CUSTOM, nl80211_msg_error,  &err);
	nl_cb_set(cv->cb, NL_CB_FINISH, NL_CB_CUSTOM, nl80211_msg_finish, &err);
	nl_cb_set(cv->cb, NL_CB_ACK,    NL_CB_CUSTOM, nl80211_msg_ack,    &err);

	while (err > 0)
		nl_recvmsgs(nls->nl_sock, cv->cb);

	return &rcv;

err:
	nl_cb_put(cv->cb);
	nlmsg_free(cv->msg);

	return NULL;
}
static int internal_pollin_handler(wifi_handle handle)
{
    hal_info *info = getHalInfo(handle);
    struct nl_cb *cb = nl_socket_get_cb(info->event_sock);
    int res = nl_recvmsgs(info->event_sock, cb);
    nl_cb_put(cb);
    return res;
}
Esempio n. 9
0
int SoftapController::executeScanLinkCmd(const char *iface, int *iface_freq)
{
    struct nl_cb *cb;
    struct nl_msg *msg;
    int devidx = 0;
    int err;

    // initialize to non-valid freq
    *iface_freq = 0;

    devidx = if_nametoindex(iface);
    if (devidx == 0) {
        LOGE("failed to translate ifname to idx");
        return -errno;
    }

    msg = nlmsg_alloc();
    if (!msg) {
        LOGE("failed to allocate netlink message");
        return 2;
    }

    cb = nl_cb_alloc(NL_CB_DEFAULT);
    if (!cb) {
        LOGE("failed to allocate netlink callbacks");
        err = 2;
        goto out_free_msg;
    }

    genlmsg_put(msg, 0, 0, genl_family_get_id(nl80211), 0,
                NLM_F_DUMP, NL80211_CMD_GET_SCAN, 0);

    NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, devidx);

    // iface_freq will be filled out by the callback
    nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, linkDumpCbHandler, iface_freq);

    err = nl_send_auto_complete(nl_soc, msg);
    if (err < 0)
        goto out;

    err = 1;
    nl_cb_err(cb, NL_CB_CUSTOM, NlErrorHandler, &err);
    nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, NlFinishHandler, &err);
    nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, NlAckHandler, &err);

    while (err > 0)
        nl_recvmsgs(nl_soc, cb);

out:
    nl_cb_put(cb);
out_free_msg:
    nlmsg_free(msg);
    return err;
nla_put_failure:
    LOGW("building message failed");
    return 2;
}
Esempio n. 10
0
static int nl80211_add_mon_if(struct nl80211_state *state, const char *device,
			      const char *mondevice)
{
	int ifindex, ret;
	struct nl_msg *msg;
	struct nl_cb *cb = NULL;
	int finished = 0;

	ifindex = device_ifindex(device);

	msg = nl80211_nlmsg_xalloc();

	genlmsg_put(msg, 0, 0, genl_family_get_id(state->nl80211), 0,
		    0, NL80211_CMD_NEW_INTERFACE, 0);

	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifindex);
	NLA_PUT_STRING(msg, NL80211_ATTR_IFNAME, mondevice);
	NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, NL80211_IFTYPE_MONITOR);

	ret = nl_send_auto_complete(state->nl_sock, msg);
	if (ret < 0) {
		if (ret == -ENFILE) {
			nlmsg_free(msg);
			return -EBUSY;
		}

		panic("Cannot send_auto_complete!\n");
	}

	cb = nl_cb_alloc(NL_CB_CUSTOM);
	if (!cb)
		panic("Cannot alloc nl_cb!\n");

	nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, nl80211_wait_handler, &finished);
	nl_cb_err(cb, NL_CB_CUSTOM, nl80211_error_handler, NULL);

	nl_recvmsgs(state->nl_sock, cb);

	if (!finished) {
		ret = nl_wait_for_ack(state->nl_sock);
		if (ret < 0) {
			if (ret == -ENFILE) {
				nlmsg_free(msg);
				return -EBUSY;
			}

			panic("Waiting for netlink ack failed!\n");
		}
	}

	nl_cb_put(cb);
	nlmsg_free(msg);
	return 0;

nla_put_failure:
	panic("nla put failure!\n");
	return -EIO; /* dummy */
}
Esempio n. 11
0
File: mgmt.c Progetto: greearb/iw-ct
static int handle_mgmt_dump(struct nl80211_state *state,
			       struct nl_msg *msg, int argc,
			       char **argv, enum id_input id)
{
	struct nl_cb *mgmt_cb;
	char *ndev = argv[0];
	int mgmt_argc = 5;
	char **mgmt_argv;
	unsigned int count = 0;
	int err = 0;
	int i;

	mgmt_argv = calloc(mgmt_argc, sizeof(char*));
	if (!mgmt_argv)
		return -ENOMEM;

	mgmt_argv[0] = ndev;
	mgmt_argv[1] = "mgmt";
	mgmt_argv[2] = "reg";

	for (i = 3; i < argc; i += 3) {
		if (strcmp(argv[i], "count") == 0) {
			count = 1 + atoi(argv[i + 1]);
			break;
		}

		if (strcmp(argv[i], "frame") != 0) {
			err = 1;
			goto out;
		}

		mgmt_argv[3] = argv[i + 1];
		mgmt_argv[4] = argv[i + 2];

		err = handle_cmd(state, II_NETDEV, mgmt_argc, mgmt_argv);
		if (err)
			goto out;
	}

	mgmt_cb = nl_cb_alloc(iw_debug ? NL_CB_DEBUG : NL_CB_DEFAULT);
	if (!mgmt_cb) {
		err = 1;
		goto out;
	}

	/* need to turn off sequence number checking */
	nl_cb_set(mgmt_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, seq_handler, NULL);
	nl_cb_set(mgmt_cb, NL_CB_VALID, NL_CB_CUSTOM, dump_mgmt_frame, NULL);

	while (--count)
		nl_recvmsgs(state->nl_sock, mgmt_cb);

	nl_cb_put(mgmt_cb);
out:
	free(mgmt_argv);
	return err;
}
/* NOTE: this function consumes 'msg' */
static int
_nl80211_send_and_recv (struct nl_sock *nl_sock,
                        struct nl_cb *nl_cb,
                        struct nl_msg *msg,
                        int (*valid_handler) (struct nl_msg *, void *),
                        void *valid_data)
{
	struct nl_cb *cb;
	int err, done;

	g_return_val_if_fail (msg != NULL, -ENOMEM);

	cb = nl_cb_clone (nl_cb);
	if (!cb) {
		err = -ENOMEM;
		goto out;
	}

	err = nl_send_auto_complete (nl_sock, msg);
	if (err < 0)
		goto out;

	done = 0;
	nl_cb_err (cb, NL_CB_CUSTOM, error_handler, &done);
	nl_cb_set (cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &done);
	nl_cb_set (cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &done);
	if (valid_handler)
		nl_cb_set (cb, NL_CB_VALID, NL_CB_CUSTOM, valid_handler, valid_data);

	/* Loop until one of our NL callbacks says we're done; on success
	 * done will be 1, on error it will be < 0.
	 */
	while (!done) {
		err = nl_recvmsgs (nl_sock, cb);
		if (err && err != -NLE_AGAIN) {
			/* Kernel scan list can change while we are dumping it, as new scan
			 * results from H/W can arrive. BSS info is assured to be consistent
			 * and we don't need consistent view of whole scan list. Hence do
			 * not warn on DUMP_INTR error for get scan command.
			 */
			if (err == -NLE_DUMP_INTR &&
			    genlmsg_hdr(nlmsg_hdr(msg))->cmd == NL80211_CMD_GET_SCAN)
				break;

			nm_log_warn (LOGD_WIFI, "nl_recvmsgs() error: (%d) %s",
			             err, nl_geterror (err));
			break;
		}
	}
	if (err == 0 && done < 0)
		err = done;

 out:
	nl_cb_put (cb);
	nlmsg_free (msg);
	return err;
}
Esempio n. 13
0
int main() 
{
    int ret;
    struct nl_cb * nl_cb;
    struct nl_handle * nl_handle;
    struct netlink_data * netlink;
    int ioctl_sock = -1;
    struct dl_list interfaces;
	int if_add_ifindex = -1;
    dl_list_init(&interfaces);
/*
 * global_init
 */
    ret = netlink_init_nl80211_event_rtm(&netlink,NULL,nl80211_event_rtm_newlink,nl80211_event_rtm_dellink);
    if (ret == -1 || netlink == NULL) 
    {
        goto err;
    }
    
    ret = nl80211_init_event(&nl_cb, &nl_handle);
    if (ret == -1) 
    {
        wpa_printf(MSG_DEBUG, "nl80211: Init failure ");
        goto err;
    } 
    wpa_printf(MSG_INFO, "nl80211: wait for event... ");
    nl_cb_set(nl_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM,
          no_seq_check, NULL);
    nl_cb_set(nl_cb, NL_CB_VALID, NL_CB_CUSTOM,
          process_event, NULL); 
    eloop_register_wrapper(nl_socket_get_fd(nl_handle),
				 nl80211_event_receive,
				 nl_cb, nl_handle);

    ioctl_sock = init_ioctl_sock();
    if (ioctl_sock < 0) 
	{
        perror("socket(PF_INET,SOCK_DGRAM)");
        goto err;
	}
/*
 * hapd_init
 */
    
	eloop_run();
    return 0;
err:
    netlink_deinit(netlink);
    nl_destroy_handles(&nl_handle);
    nl_cb_put(nl_cb);
    if (ioctl_sock >= 0)
    {
        close(ioctl_sock);
    }
    return -1;
}
Esempio n. 14
0
static int internal_pollin_handler(wifi_handle handle)
{
    hal_info *info = getHalInfo(handle);
    struct nl_cb *cb = nl_socket_get_cb(info->event_sock);
    int res = nl_recvmsgs(info->event_sock, cb);
    if(res)
        ALOGE("Error :%d while reading nl msg", res);
    nl_cb_put(cb);
    return res;
}
static void
wifi_nl80211_deinit (WifiData *parent)
{
	WifiDataNl80211 *nl80211 = (WifiDataNl80211 *) parent;

	if (nl80211->nl_sock)
		nl_socket_free (nl80211->nl_sock);
	if (nl80211->nl_cb)
		nl_cb_put (nl80211->nl_cb);
}
Esempio n. 16
0
static int internal_pollin_handler(wifi_handle handle, struct nl_sock *sock)
{
    struct nl_cb *cb = nl_socket_get_cb(sock);

    int res = nl_recvmsgs(sock, cb);
    if(res)
        ALOGE("Error :%d while reading nl msg", res);
    nl_cb_put(cb);
    return res;
}
Esempio n. 17
0
static struct nl80211_msg_conveyor * nl80211_msg(const char *ifname, int cmd, int flags)
{
	static struct nl80211_msg_conveyor cv;

	int ifidx = -1, phyidx = -1;
	struct nl_msg *req = NULL;
	struct nl_cb *cb = NULL;

	if (nl80211_init() < 0)
		goto err;

	if (!strncmp(ifname, "phy", 3))
		phyidx = atoi(&ifname[3]);
	else if (!strncmp(ifname, "radio", 5))
		phyidx = atoi(&ifname[5]);
	else if (!strncmp(ifname, "mon.", 4))
		ifidx = if_nametoindex(&ifname[4]);
	else
		ifidx = if_nametoindex(ifname);

	if ((ifidx < 0) && (phyidx < 0))
		return NULL;

	req = nlmsg_alloc();
	if (!req)
		goto err;

	cb = nl_cb_alloc(NL_CB_DEFAULT);
	if (!cb)
		goto err;

	genlmsg_put(req, 0, 0, genl_family_get_id(nls->nl80211), 0,
		flags, cmd, 0);

	if (ifidx > -1)
		NLA_PUT_U32(req, NL80211_ATTR_IFINDEX, ifidx);

	if (phyidx > -1)
		NLA_PUT_U32(req, NL80211_ATTR_WIPHY, phyidx);

	cv.msg = req;
	cv.cb  = cb;

	return &cv;

err:
nla_put_failure:
	if (cb)
		nl_cb_put(cb);

	if (req)
		nlmsg_free(req);

	return NULL;
}
Esempio n. 18
0
static int __nl_send_msg(struct nl_sock *sock, struct nl_msg *msg,
			int (*rx_handler)(struct nl_msg *, void *),
			int (*finish_handler)(struct nl_msg *, void *),
			void *data)
{
	struct nl_cb *cb;
	int err, done;
	struct send_msg_data send_data;

	DBG("");

	cb = nl_cb_alloc(NL_CB_DEFAULT);
	if (!cb)
		return -ENOMEM;

	err = nl_send_auto_complete(sock, msg);
	if (err < 0) {
		nl_cb_put(cb);
		near_error("%s", strerror(err));

		return err;
	}

	err = done = 0;
	send_data.done = &done;
	send_data.data = data;
	send_data.finish_handler = finish_handler;

	nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, __finish_handler, &send_data);
	nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err);
	nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &done);

	if (rx_handler)
		nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, rx_handler, data);

	while (err == 0 && done == 0)
		nl_recvmsgs(sock, cb);

	nl_cb_put(cb);

	return err;
}
Esempio n. 19
0
static int go_offchan_freq(struct nl80211_state *state, int devidx, int freq)
{
	struct nl_cb *cb;
	struct nl_cb *s_cb;
	struct nl_msg *msg;
	int err;

	msg = nlmsg_alloc();
	if (!msg) {
		fprintf(stderr, "failed to allocate netlink message\n");
		return 2;
	}

	cb = nl_cb_alloc(nl_debug ? NL_CB_DEBUG : NL_CB_DEFAULT);
	s_cb = nl_cb_alloc(nl_debug ? NL_CB_DEBUG : NL_CB_DEFAULT);
	if (!cb || !s_cb) {
		fprintf(stderr, "failed to allocate netlink callbacks\n");
		err = 2;
		goto out_free_msg;
	}

	genlmsg_put(msg, 0, 0, genl_family_get_id(state->nl80211), 0,
		    0,
		    NL80211_CMD_REMAIN_ON_CHANNEL, 0);

	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, devidx);
	NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq);
	/* 5 seconds is the max allowed, values passed are in ms */
	NLA_PUT_U32(msg, NL80211_ATTR_DURATION, 60);

	nl_socket_set_cb(state->nl_sock, s_cb);

	err = nl_send_auto_complete(state->nl_sock, msg);
	if (err < 0)
		goto out;

	err = 1;

	nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err);
	nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err);
	nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err);

	while (err > 0)
		nl_recvmsgs(state->nl_sock, cb);
 out:
	nl_cb_put(cb);
 out_free_msg:
	nlmsg_free(msg);
	return err;
 nla_put_failure:
	fprintf(stderr, "building message failed\n");
	return 2;
}
// Retrieve monitor interface for a given physical interface
int ret_mon_IF(struct nl80211_state *state)
{
	struct nl_msg *msg;
	struct nl_cb *cb, *s_cb;
	int err = 1;

	msg = nlmsg_alloc();
	if (!msg)
	{
		fprintf(stderr, "failed to allocate netlink message\n");
		return 2;
	}

	// Allocate a new callback handle.
	cb = nl_cb_alloc(NL_CB_DEFAULT);
	s_cb = nl_cb_alloc(NL_CB_DEFAULT);
	if (!cb || !s_cb)
	{
		fprintf(stderr, "failed to allocate netlink callbacks\n");
		err = 2;
		goto out_free_msg;
	}

	// Add Generic Netlink header (i.e. NL80211_CMD_GET_INTERFACE) to Netlink message
	genlmsg_put(msg, 0, 0, state->nl80211_id, 0, 768, NL80211_CMD_GET_INTERFACE, 0);

	// Set up a valid callback function
	if (nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, iface_handler, NULL))
		goto out;

	// Attach the callback function to a netlink socket
	nl_socket_set_cb(state->nl_sock, s_cb);

	// Finalize and transmit Netlink message
	if(nl_send_auto_complete(state->nl_sock, msg) < 0)
		goto out;

	// Set up error, finish and acknowledgment callback function
	nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err);
	nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err);
	nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err);

	while (err > 0)
		nl_recvmsgs(state->nl_sock, cb);

out:
	nl_cb_put(cb);
out_free_msg:
	nlmsg_free(msg);
	return err;
}
Esempio n. 21
0
void unl_genl_loop(struct unl *unl, unl_cb handler, void *arg)
{
	struct nl_cb *cb;

	cb = nl_cb_alloc(NL_CB_CUSTOM);
	unl->loop_done = false;
	nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL);
	nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, handler, arg);

	while (!unl->loop_done)
		nl_recvmsgs(unl->sock, cb);

	nl_cb_put(cb);
}
Esempio n. 22
0
static int call_survey_freq(struct nl80211_state *state, int devidx, int freq)
{
	struct nl_cb *cb;
	struct nl_cb *s_cb;
	struct nl_msg *msg;
	int err;

	msg = nlmsg_alloc();
	if (!msg) {
		fprintf(stderr, "failed to allocate netlink message\n");
		return 2;
	}

	cb = nl_cb_alloc(nl_debug ? NL_CB_DEBUG : NL_CB_DEFAULT);
	s_cb = nl_cb_alloc(nl_debug ? NL_CB_DEBUG : NL_CB_DEFAULT);
	if (!cb || !s_cb) {
		fprintf(stderr, "failed to allocate netlink callbacks\n");
		err = 2;
		goto out_free_msg;
	}

	genlmsg_put(msg, 0, 0, genl_family_get_id(state->nl80211), 0,
		    NLM_F_DUMP,
		    NL80211_CMD_GET_SURVEY, 0);

	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, devidx);
	nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, handle_survey_dump, (void *) &freq);
	nl_socket_set_cb(state->nl_sock, s_cb);

	err = nl_send_auto_complete(state->nl_sock, msg);
	if (err < 0)
		goto out;

	err = 1;

	nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err);
	nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err);
	nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err);

	while (err > 0)
		nl_recvmsgs(state->nl_sock, cb);
 out:
	nl_cb_put(cb);
 out_free_msg:
	nlmsg_free(msg);
	return err;
 nla_put_failure:
	fprintf(stderr, "building message failed\n");
	return 2;
}
Esempio n. 23
0
static void nl80211_free(struct nl80211_msg_conveyor *cv)
{
	if (cv)
	{
		if (cv->cb)
			nl_cb_put(cv->cb);

		if (cv->msg)
			nlmsg_free(cv->msg);

		cv->cb  = NULL;
		cv->msg = NULL;
	}
}
Esempio n. 24
0
void ac_kmod_free(void) {
	if (g_ac.kmodhandle.nl) {
		nl_socket_free(g_ac.kmodhandle.nl);
	}

	if (g_ac.kmodhandle.nl_cb) {
		nl_cb_put(g_ac.kmodhandle.nl_cb);
	}

	if (g_ac.kmodhandle.nlmsg) {
		nl_socket_free(g_ac.kmodhandle.nlmsg);
	}

	if (g_ac.kmodhandle.nlmsg_cb) {
		nl_cb_put(g_ac.kmodhandle.nlmsg_cb);
	}

	/* */
	capwap_lock_destroy(&g_ac.kmodhandle.msglock);

	/* */
	memset(&g_ac.kmodhandle, 0, sizeof(struct ac_kmod_handle));
}
Esempio n. 25
0
/**
 * Wait for ACK.
 * @arg sk		Netlink socket.
 * @pre The netlink socket must be in blocking state.
 *
 * Waits until an ACK is received for the latest not yet acknowledged
 * netlink message.
 */
int nl_wait_for_ack(struct nl_sock *sk)
{
	int err;
	struct nl_cb *cb;

	cb = nl_cb_clone(sk->s_cb);
	if (cb == NULL)
		return -NLE_NOMEM;

	nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_wait_handler, NULL);
	err = nl_recvmsgs(sk, cb);
	nl_cb_put(cb);

	return err;
}
Esempio n. 26
0
/* function: netlink_sendrecv
 * send a nl_msg and return an int status - only supports OK/ERROR responses
 * msg - msg to send
 */
int netlink_sendrecv(struct nl_msg *msg) {
  struct nl_cb *callbacks = NULL;
  int retval = -EIO;

  callbacks = alloc_ack_callbacks(&retval);
  if(!callbacks) {
    return -ENOMEM;
  }

  send_netlink_msg(msg, callbacks);

  nl_cb_put(callbacks);

  return retval;
}
Esempio n. 27
0
/* NOTE: this function consumes 'msg' */
static int
_nl80211_send_and_recv (struct nl_sock *nl_sock, 
                        struct nl_cb *nl_cb,
                        struct nl_msg *msg,
                        int (*valid_handler)(struct nl_msg *, void *),
                        void *valid_data)
{
	struct nl_cb *cb;
	int err, done;

	g_return_val_if_fail (msg != NULL, -ENOMEM);

	cb = nl_cb_clone (nl_cb);
	if (!cb) {
		err = -ENOMEM;
		goto out;
	}

	err = nl_send_auto_complete (nl_sock, msg);
	if (err < 0)
		goto out;

	done = 0;
	nl_cb_err (cb, NL_CB_CUSTOM, error_handler, &done);
	nl_cb_set (cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &done);
	nl_cb_set (cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &done);
	if (valid_handler)
		nl_cb_set (cb, NL_CB_VALID, NL_CB_CUSTOM, valid_handler, valid_data);

	/* Loop until one of our NL callbacks says we're done; on success
	 * done will be 1, on error it will be < 0.
	 */
	while (!done) {
		err = nl_recvmsgs (nl_sock, cb);
		if (err && err != -NLE_AGAIN) {
			nm_log_warn (LOGD_WIFI, "nl_recvmsgs() error: (%d) %s",
			             err, nl_geterror (err));
			break;
		}
	}
	if (err == 0 && done < 0)
		err = done;

 out:
	nl_cb_put (cb);
	nlmsg_free (msg);
	return err;
}
Esempio n. 28
0
static wifi_error wifi_init_user_sock(hal_info *info)
{
    struct nl_sock *user_sock =
        wifi_create_nl_socket(WIFI_HAL_USER_SOCK_PORT, NETLINK_USERSOCK);
    if (user_sock == NULL) {
        ALOGE("Could not create diag sock");
        return WIFI_ERROR_UNKNOWN;
    }

    /* Set the socket buffer size */
    if (nl_socket_set_buffer_size(user_sock, (256*1024), 0) < 0) {
        ALOGE("Could not set size for user_sock: %s",
                   strerror(errno));
        /* continue anyway with the default (smaller) buffer */
    }
    else {
        ALOGV("nl_socket_set_buffer_size successful for user_sock");
    }

    struct nl_cb *cb = nl_socket_get_cb(user_sock);
    if (cb == NULL) {
        ALOGE("Could not get cb");
        return WIFI_ERROR_UNKNOWN;
    }

    info->user_sock_arg = 1;
    nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL);
    nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &info->user_sock_arg);
    nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &info->user_sock_arg);
    nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &info->user_sock_arg);

    nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, user_sock_message_handler, info);
    nl_cb_put(cb);

    int ret = nl_socket_add_membership(user_sock, 1);
    if (ret < 0) {
        ALOGE("Could not add membership");
        return WIFI_ERROR_UNKNOWN;
    }

    info->user_sock = user_sock;
    ALOGV("Initiialized diag sock successfully");
    return WIFI_SUCCESS;
}
Esempio n. 29
0
static wifi_error wifi_init_cld80211_sock_cb(hal_info *info)
{
    struct nl_cb *cb = nl_socket_get_cb(info->cldctx->sock);
    if (cb == NULL) {
        ALOGE("Could not get cb");
        return WIFI_ERROR_UNKNOWN;
    }

    info->user_sock_arg = 1;
    nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL);
    nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &info->user_sock_arg);
    nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &info->user_sock_arg);
    nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &info->user_sock_arg);

    nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, user_sock_message_handler, info);
    nl_cb_put(cb);

    return WIFI_SUCCESS;
}
Esempio n. 30
0
/* function: getinterface_ip
 * finds the first global non-privacy IP of the given family for the given interface, or returns NULL.  caller frees pointer
 * interface - interface to look for
 * family    - family
 */
union anyip *getinterface_ip(const char *interface, int family) {
  struct ifaddrmsg ifa;
  struct nl_cb *callbacks = NULL;
  struct target targ;
  union anyip *retval = NULL;

  targ.family = family;
  targ.foundip = 0;
  targ.ifindex = if_nametoindex(interface);
  if(targ.ifindex == 0) {
    return NULL; // interface not found
  }

  memset(&ifa, 0, sizeof(ifa));
  ifa.ifa_family = targ.family;

  callbacks = nl_cb_alloc(NL_CB_DEFAULT);
  if(!callbacks) {
    goto cleanup;
  }
  nl_cb_set(callbacks, NL_CB_VALID, NL_CB_CUSTOM, getaddr_cb, &targ);
  nl_cb_err(callbacks, NL_CB_CUSTOM, error_handler, &targ);

  // sends message and waits for a response
  send_ifaddrmsg(RTM_GETADDR, NLM_F_REQUEST | NLM_F_ROOT, &ifa, callbacks);

  if(targ.foundip) {
    retval = malloc(sizeof(union anyip));
    if(!retval) {
      logmsg(ANDROID_LOG_FATAL,"getinterface_ip/out of memory");
      goto cleanup;
    }
    memcpy(retval, &targ.ip, sizeof(union anyip));
  }

cleanup:
  if(callbacks)
    nl_cb_put(callbacks);

  return retval;
}