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;
}
Ejemplo n.º 2
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;
}
Ejemplo n.º 4
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;
}
Ejemplo n.º 5
0
static int send_recv_nlcmd(void *nla, size_t nla_len)
{
	int err, nla_offset = 0;
	struct nl_cb *cb;
	struct nl_cb *s_cb;
	struct nl_msg *msg;

	if (cur_cmd <= NL80211_CMD_UNSPEC) {
		LOG_ERR_("Unsupported nl command: %d\n", cur_cmd);
		return 1;
	}

	if (devidx_set)
		/* Since devidx is a uint32_t the attribute will consume 8
		 * bytes. The nla input stream must be appended after this
		 * attribute.
		 */
		nla_offset = 8;

	LOG_DBG_("%s: Allocating %d bytes for nlmsg\n", __func__,
		  nla_len + nla_offset + NLMSG_HDRLEN + GENL_HDRLEN);
	msg = nlmsg_alloc_size(nla_len + nla_offset + NLMSG_HDRLEN + GENL_HDRLEN);
	if (!msg) {
		LOG_ERR_("failed to allocate netlink message\n");
		return 2;
	}

	cb = nl_cb_alloc((log_level > LOG_WARNING) ?
			 NL_CB_DEBUG : NL_CB_DEFAULT);
	s_cb = nl_cb_alloc((log_level > LOG_WARNING) ?
			   NL_CB_DEBUG : NL_CB_DEFAULT);
	if (!cb || !s_cb) {
		LOG_ERR_("failed to allocate netlink callbacks\n");
		err = 2;
		goto out;
	}

	genlmsg_put(msg, 0, 0, state.nl80211_id, 0, 0, cur_cmd, 0);

	if (devidx_set) {
		LOG_DBG_("%s: Adding devidx %d attribute\n", __func__, devidx);
		if (dev_by_phy)
			NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, devidx);
		else
			NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, devidx);
	}

	add_nla_stream_to_msg(msg, nla, nla_len);

	nl_socket_set_cb(state.nl_sock, s_cb);

	err = nl_send_auto_complete(state.nl_sock, msg);
	if (err < 0) {
		LOG_ERR_("nl_send_auto_complete %d\n", err);
		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);
	nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, valid_handler, NULL);

	while (err > 0)
		nl_recvmsgs(state.nl_sock, cb);
 out:
	nl_cb_put(cb);
	nl_cb_put(s_cb);
	nlmsg_free(msg);
	return err;
 nla_put_failure:
	LOG_ERR_("building message failed\n");
	return 2;
}