Exemple #1
0
static int nl80211_del_mon_if(struct nl80211_state *state, const char *device,
			      const char *mondevice)
{
	int ifindex, ret;
	struct nl_msg *msg;

	ifindex = device_ifindex(mondevice);

	msg = nl80211_nlmsg_xalloc();

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

	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifindex);

	ret = nl_send_auto_complete(state->nl_sock, msg);
	if (ret < 0)
		panic("Cannot send_auto_complete!\n");

	ret = nl_wait_for_ack(state->nl_sock);
	if (ret < 0)
		panic("Waiting for netlink ack failed!\n");

	nlmsg_free(msg);
	return 0;

nla_put_failure:
	panic("nla put failure!\n");
	return -EIO; /* dummy */
}
Exemple #2
0
int reroute_path_selection_frames(char* ifname)
{
        struct nl_msg *msg;
        uint8_t cmd = NL80211_CMD_REGISTER_FRAME;
        int ret;
	char *pret;
	char action_code[2] = { 0x20, 0x00 };

        int ifindex = if_nametoindex(ifname);

        msg = nlmsg_alloc();
        if (!msg)
                return -ENOMEM;

	pret = genlmsg_put(msg, 0, 0,
		genl_family_get_id(nlcfg.nl80211), 0, 0, cmd, 0);
	if (pret == NULL)
		goto nla_put_failure;

        NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifindex);
	NLA_PUT(msg, NL80211_ATTR_FRAME_MATCH, sizeof(action_code), action_code);

        ret = send_and_recv_msgs(msg, receive_ps_frames, NULL);
        if (ret)
		printf("Registering for path selection frames failed: %d (%s)\n", ret,
			strerror(-ret));
	else
		printf("Registering for path selection frames succeeded.  Yay!\n");

        return ret;
 nla_put_failure:
        return -ENOBUFS;
}
Exemple #3
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;
}
Exemple #4
0
void CNL80211::scan() {
	//Get interface index for device:
	unsigned int devidx = if_nametoindex(m_ifname.toAscii().constData());
	if (devidx == 0) {
		emit message("Could not get interface index");
		return;
	}
	//Allocate a new netlink message
	nl_msg * msg;
	msg = nlmsg_alloc();
	if (!msg) {
		emit message("Could not allocate netlink message");
		return;
	}
	
	//allocate the callback function with default verbosity
// 	nl_cb * cb = nl_cb_alloc(NL_CB_DEFAULT);
// 	if (!cb) {
// 		emit message("Could not allocate netlink callback");
// 		nlmsg_free(msg);
// 		return;
// 	}

	nl_socket_modify_cb(m_nlSocket, NL_CB_VALID, NL_CB_CUSTOM, &cbForScanResults, this);
	
	genlmsg_put(msg, 0, 0, genl_family_get_id(m_nlFamily), 0, (NLM_F_REQUEST | NLM_F_DUMP), NL80211_CMD_GET_SCAN, 0);
	//Set the interface we want to operate on
	nla_put_u32(msg, NL80211_ATTR_IFNAME,devidx);
	
	//hier kommt noch was rein
	
	//Send the message
	nl_send_auto_complete(m_nlSocket,msg);
	nlmsg_free(msg);
}
Exemple #5
0
static bool nl80211_msg_prepare(struct nl_msg **const msgp,
				const enum nl80211_commands cmd,
				const char *const interface)
{
	struct nl_msg *msg = nlmsg_alloc();
	if (!msg) {
		fprintf(stderr, "failed to allocate netlink message\n");
		return false;
	}

	if (!genlmsg_put(msg, 0, 0, genl_family_get_id(family), 0, 0 /*flags*/, cmd, 0)) {
		fprintf(stderr, "failed to add generic netlink headers\n");
		goto nla_put_failure;
	}

	if (interface) { //TODO: PHY commands don't need interface name but wiphy index
		unsigned int if_index = if_nametoindex(interface);
		if (!if_index) {
			fprintf(stderr, "interface %s does not exist\n", interface);
			goto nla_put_failure;
		}
		NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_index);
	}

	*msgp = msg;
	return true;

nla_put_failure:
	nlmsg_free(msg);
	return false;
}
static int wpa_driver_get_power_save(void *priv, int *state)
{
	struct i802_bss *bss = priv;
	struct wpa_driver_nl80211_data *drv = bss->drv;
	struct nl_msg *msg;
	int ret = -1;
	enum nl80211_ps_state ps_state;

	msg = nlmsg_alloc();
	if (!msg)
		return -1;

	genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0,
		    NL80211_CMD_GET_POWER_SAVE, 0);

	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);

	ret = send_and_recv_msgs(drv, msg, get_power_mode_handler, state);
	msg = NULL;
	if (ret < 0)
		wpa_printf(MSG_ERROR, "nl80211: Get power mode fail: %d", ret);
nla_put_failure:
	nlmsg_free(msg);
	return ret;
}
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;
}
Exemple #8
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 */
}
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;
}
Exemple #10
0
int nl80211_createvap(const char *interface, const char *newinterface, char *errstr) {
#ifndef HAVE_LINUX_NETLINK
	snprintf(errstr, LORCON_STATUS_MAX, "LORCON was not compiled with "
			 "netlink/nl80211 support, check the output of ./configure for why");
	return -1;
#else

	struct nl_sock *nl_handle;
	struct nl_cache *nl_cache;
	struct genl_family *nl80211;
	struct nl_msg *msg;

	if (if_nametoindex(newinterface) > 0) 
		return 1;

	if (nl80211_connect(interface, (void **) &nl_handle, 
						 (void **) &nl_cache, (void **) &nl80211, errstr) < 0)
		return -1;

	if ((msg = nlmsg_alloc()) == NULL) {
		snprintf(errstr, LORCON_STATUS_MAX, "nl80211_createvap() failed to allocate "
				 "message");
		nl80211_disconnect(nl_handle);
		return -1;
	}

	genlmsg_put(msg, 0, 0, genl_family_get_id(nl80211), 0, 0, 
				NL80211_CMD_NEW_INTERFACE, 0);
	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(interface));
	NLA_PUT_STRING(msg, NL80211_ATTR_IFNAME, newinterface);
	NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, NL80211_IFTYPE_MONITOR);

	if (nl_send_auto_complete(nl_handle, msg) < 0 || nl_wait_for_ack(nl_handle) < 0) {
nla_put_failure:
		snprintf(errstr, LORCON_STATUS_MAX, "nl80211_createvap() failed to create "
				 "interface '%s'", newinterface);
		nlmsg_free(msg);
		nl80211_disconnect(nl_handle);
		return -1;
	}

	nlmsg_free(msg);

	nl80211_disconnect(nl_handle);

	if (if_nametoindex(newinterface) <= 0) {
		snprintf(errstr, LORCON_STATUS_MAX, "nl80211_createvap() thought we made a "
				 "vap, but it wasn't there when we looked");
		return -1;
	}

	return 0;
#endif
}
Exemple #11
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;
}
Exemple #12
0
int nl80211_setchannel_cache(const char *interface, void *handle,
							  void *family, int channel,
							  unsigned int chmode, char *errstr) {
#ifndef HAVE_LINUX_NETLINK
	snprintf(errstr, LORCON_STATUS_MAX, "LORCON was not compiled with netlink/nl80211 "
			 "support, check the output of ./configure for why");
	// Return the same error as we get if the device doesn't support nlfreq
	return -22;
#else
	struct nl_sock *nl_handle = (struct nl_sock *) handle;
	struct genl_family *nl80211 = (struct genl_family *) family;
	struct nl_msg *msg;
	int ret = 0;

	int chanmode[] = {
		NL80211_CHAN_NO_HT, NL80211_CHAN_HT20, 
		NL80211_CHAN_HT40PLUS, NL80211_CHAN_HT40MINUS
	};

	if (chmode > 4) {
		snprintf(errstr, LORCON_STATUS_MAX, "Invalid channel mode\n");
		return -1;
	}

	if ((msg = nlmsg_alloc()) == NULL) {
		snprintf(errstr, LORCON_STATUS_MAX, "nl80211_setchannel() failed to allocate "
				 "message");
		return -1;
	}

	genlmsg_put(msg, 0, 0, genl_family_get_id(nl80211), 0, 0, 
				NL80211_CMD_SET_WIPHY, 0);
	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(interface));
	NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, ChanToFreq(channel));
	NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE, chanmode[chmode]);

	if ((ret = nl_send_auto_complete(nl_handle, msg)) >= 0) {
		if ((ret = nl_wait_for_ack(nl_handle)) < 0) 
			goto nla_put_failure;
	}

	nlmsg_free(msg);

	return 0;

nla_put_failure:
	snprintf(errstr, LORCON_STATUS_MAX, "nl80211_setchannel() could not set channel "
			 "%d/%d on interface '%s' err %d", channel, ChanToFreq(channel), 
			 interface, ret);
	nlmsg_free(msg);
	return ret;
#endif
}
Exemple #13
0
int nl80211_setvapflag(const char *interface, char *errstr, int nflags, int *in_flags) {
#ifndef HAVE_LINUX_NETLINK
	snprintf(errstr, LORCON_STATUS_MAX, "LORCON was not compiled with netlink/nl80211 "
			 "support, check the output of ./configure for why");
	return -1;
#else

	struct nl_sock *nl_handle;
	struct nl_cache *nl_cache;
	struct genl_family *nl80211;
	struct nl_msg *msg;

	if (nl80211_connect(interface, (void **) &nl_handle, 
						 (void **) &nl_cache, (void **) &nl80211, errstr) < 0)
		return -1;

	if ((msg = nlmsg_alloc()) == NULL) {
		snprintf(errstr, LORCON_STATUS_MAX, "%s failed to allocate message",
				 __FUNCTION__);
		nl80211_disconnect(nl_handle);
		return -1;
	}

	genlmsg_put(msg, 0, 0, genl_family_get_id(nl80211), 0, 0, 
				NL80211_CMD_SET_INTERFACE, 0);

	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(interface));
	NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, NL80211_IFTYPE_MONITOR);

	nl80211_parseflags(nflags, in_flags, msg);

	if (nl_send_auto_complete(nl_handle, msg) >= 0) { 
		if (nl_wait_for_ack(nl_handle) < 0) {
			goto nla_put_failure;
		}
	} else {
nla_put_failure:
		snprintf(errstr, LORCON_STATUS_MAX, "%s failed to set flags on "
				 "interface '%s': %s", __FUNCTION__, interface,
				 strerror(errno));
		nlmsg_free(msg);
		nl80211_disconnect(nl_handle);
		return -1;
	}

	nlmsg_free(msg);

	nl80211_disconnect(nl_handle);

	return 0;
#endif
}
Exemple #14
0
int join_mesh(char* ifname, char *mesh_id, int mesh_id_len, char *vendor_ie, int vendor_ie_len)
{
        struct nl_msg *msg;
        uint8_t cmd = NL80211_CMD_JOIN_MESH;
        int ret;
	char *pret;

        int ifindex = if_nametoindex(ifname);

        msg = nlmsg_alloc();
        if (!msg)
                return -ENOMEM;

	if (!mesh_id || !mesh_id_len)
		return -EINVAL;

        printf("o11s-pathseld: Staring mesh with mesh id = %s\n", mesh_id);

	pret = genlmsg_put(msg, 0, 0,
		genl_family_get_id(nlcfg.nl80211), 0, 0, cmd, 0);
	if (pret == NULL)
		goto nla_put_failure;

	if (vendor_ie) {
		struct nlattr *container = nla_nest_start(msg,
				NL80211_ATTR_MESH_PARAMS);

		if (!container)
			return -ENOBUFS;

		NLA_PUT(msg, NL80211_MESHCONF_VENDOR_PATH_SEL_IE,
				vendor_ie_len, vendor_ie);
		NLA_PUT_U8(msg, NL80211_MESHCONF_ENABLE_VENDOR_PATH_SEL, 1);
		NLA_PUT_U8(msg, NL80211_MESHCONF_ENABLE_VENDOR_METRIC, 1);
		nla_nest_end(msg, container);
	}

        NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifindex);
        NLA_PUT(msg, NL80211_ATTR_MESH_ID, mesh_id_len, mesh_id);

        ret = send_and_recv_msgs(msg, NULL, NULL);
        if (ret)
		printf("Mesh start failed: %d (%s)\n", ret,
			strerror(-ret));
	else
		printf("Mesh start succeeded.  Yay!\n");

        return ret;
 nla_put_failure:
        return -ENOBUFS;
}
Exemple #15
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;
}
Exemple #16
0
struct nl_msg *unl_genl_msg(struct unl *unl, int cmd, bool dump)
{
	struct nl_msg *msg;
	int flags = 0;

	msg = nlmsg_alloc();
	if (!msg)
		goto out;

	if (dump)
		flags |= NLM_F_DUMP;

	genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ,
		    genl_family_get_id(unl->family), 0, flags, cmd, 0);

out:
	return msg;
}
Exemple #17
0
static int set_mesh_conf(struct netlink_config_s *nlcfg,
                         struct mesh_node *mesh, uint32_t changed)
{

    struct nl_msg *msg;
    uint8_t cmd = NL80211_CMD_SET_MESH_CONFIG;
    int ret = 0;
    char *pret;

    sae_debug(MESHD_DEBUG, "%s(%p, %d)\n", __FUNCTION__, nlcfg, changed);
    msg = nlmsg_alloc();
    if (!msg)
        return -ENOMEM;

    pret = genlmsg_put(msg, 0, NL_AUTO_SEQ,
            genl_family_get_id(nlcfg->nl80211), 0, 0, cmd, 0);

    if (pret == NULL)
        goto nla_put_failure;

    struct nlattr *container = nla_nest_start(msg,
            NL80211_ATTR_MESH_CONFIG);

    if (!container)
        goto nla_put_failure;

    if (changed & MESH_CONF_CHANGED_HT)
        NLA_PUT_U32(msg, NL80211_MESHCONF_HT_OPMODE, mesh->conf->ht_prot_mode);
    nla_nest_end(msg, container);

    NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, nlcfg->ifindex);

    ret = send_nlmsg(nlcfg->nl_sock, msg);
    sae_debug(MESHD_DEBUG, "set meshconf (seq num=%d)\n",
            nlmsg_hdr(msg)->nlmsg_seq);
    if (ret < 0)
        sae_debug(MESHD_DEBUG, "set meshconf failed: %d (%s)\n", ret,
                strerror(-ret));
    return ret;
nla_put_failure:
    nlmsg_free(msg);
    return -ENOBUFS;
}
Exemple #18
0
static struct nl_msg *
wprobe_new_msg(const char *ifname, int cmd, bool dump)
{
    struct nl_msg *msg;
    uint32_t flags = 0;

    msg = nlmsg_alloc();
    if (!msg)
        return NULL;

    if (dump)
        flags |= NLM_F_DUMP;

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

    NLA_PUT_STRING(msg, WPROBE_ATTR_INTERFACE, ifname);
nla_put_failure:
    return msg;
}
Exemple #19
0
static int tx_frame(struct netlink_config_s *nlcfg, struct mesh_node *mesh,
                    unsigned char *frame, int len)
{
    struct nl_msg *msg;
    uint8_t cmd = NL80211_CMD_FRAME;
    int ret = 0;
    char *pret;

    sae_debug(MESHD_DEBUG, "%s(%p, %p, %d)\n", __FUNCTION__, nlcfg, frame, len);
    msg = nlmsg_alloc();
    if (!msg)
        return -ENOMEM;

    if (!frame || !len)
        return -EINVAL;

    pret = genlmsg_put(msg, 0, NL_AUTO_SEQ,
            genl_family_get_id(nlcfg->nl80211), 0, 0, cmd, 0);

    if (pret == NULL)
        goto nla_put_failure;

    NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, nlcfg->ifindex);
    NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, mesh->freq);
    NLA_PUT(msg, NL80211_ATTR_FRAME, len, frame);

    ret = send_nlmsg(nlcfg->nl_sock, msg);
    sae_debug(MESHD_DEBUG, "tx frame (seq num=%d)\n",
            nlmsg_hdr(msg)->nlmsg_seq);
    if (ret < 0)
        sae_debug(MESHD_DEBUG, "tx frame failed: %d (%s)\n", ret,
                strerror(-ret));
    else
        sae_hexdump(MESHD_DEBUG, "tx frame", frame, len);
    return ret;
nla_put_failure:
    nlmsg_free(msg);
    return -ENOBUFS;
}
Exemple #20
0
static int handle_interface_del(struct nl80211_state *state,
				char *phy, char *dev, int argc, char **argv)
{
	int err;
	struct nl_msg *msg;

	if (argc) {
		fprintf(stderr, "too many arguments\n");
		return -1;
	}

        msg = nlmsg_alloc();
	if (!msg)
        	return -1;

	genlmsg_put(msg, 0, 0, genl_family_get_id(state->nl80211), 0,
		    0, NL80211_CMD_DEL_INTERFACE, 0);
	if (!dev) {
		fprintf(stderr, "need device\n");
		nlmsg_free(msg);
		return -1;
	}
	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(dev));

	if ((err = nl_send_auto_complete(state->nl_handle, msg)) < 0 ||
	    (err = nl_wait_for_ack(state->nl_handle)) < 0) {
 nla_put_failure:
		fprintf(stderr, "failed to remove interface: %d\n", err);
		nlmsg_free(msg);
		return -1;
	}

	nlmsg_free(msg);

	return 0;
}
static int nl80211_set_wowlan_triggers(struct i802_bss *bss, int enable)
{
	struct nl_msg *msg, *pats = NULL;
	struct nlattr *wowtrig, *pat;
	int i, ret = -1;
	int filters;

	bss->drv->wowlan_enabled = !!enable;

	msg = nlmsg_alloc();
	if (!msg)
		return -ENOMEM;

	genlmsg_put(msg, 0, 0, genl_family_get_id(bss->drv->nl80211), 0,
		    0, NL80211_CMD_SET_WOWLAN, 0);

	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, bss->drv->first_bss.ifindex);
	wowtrig = nla_nest_start(msg, NL80211_ATTR_WOWLAN_TRIGGERS);

	if (!wowtrig) {
		ret = -ENOBUFS;
		goto nla_put_failure;
	}

	if (!enable) {
		NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_ANY);
	} else {
		pats = nlmsg_alloc();
		if (!pats) {
			ret = -ENOMEM;
			goto nla_put_failure;
		}

		/* In ginger filter 0 and 1 are always set but in ICS we
		 * only enable unicast. Make sure to always set it, otherwise
		 * unicast packets will be dropped.
		 * bcast packets are dropped and handled by the firmware */

		filters = bss->drv->wowlan_triggers |= 1;

		for (i = 0; i < NR_RX_FILTERS; i++) {
			if (filters & (1 << i)) {
				struct rx_filter *rx_filter = &rx_filters[i];
				int patnr = 1;
				u8 *pattern = nl80211_rx_filter_get_pattern(rx_filter,bss);

				if (!pattern)
					continue;

				pat = nla_nest_start(pats, patnr++);
				NLA_PUT(pats, NL80211_WOWLAN_PKTPAT_MASK,
					rx_filter->mask_len,
					rx_filter->mask);
				NLA_PUT(pats, NL80211_WOWLAN_PKTPAT_PATTERN,
					rx_filter->pattern_len,
					pattern);

				nla_nest_end(pats, pat);
			}
		}
	}

	if (pats)
		nla_put_nested(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN, pats);

	nla_nest_end(msg, wowtrig);

	ret = send_and_recv_msgs(bss->drv, msg, NULL, NULL);

	if (ret < 0)
		wpa_printf(MSG_ERROR, "Failed to set WoWLAN trigger:%d\n", ret);

	if (pats)
		nlmsg_free(pats);

	return 0;

nla_put_failure:
	nlmsg_free(msg);
	return ret;
}
static int execute_nl_interface_cmd(const char *iface,
                                    enum nl80211_iftype type,
                                    uint8_t cmd)
{
    struct nl_cb *cb;
    struct nl_msg *msg;
    int devidx = 0;
    int err;
    int add_interface = (cmd == NL80211_CMD_NEW_INTERFACE);

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

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

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

    genlmsg_put(msg, 0, 0, genl_family_get_id(nl80211), 0, 0, cmd, 0);

    if (add_interface) {
        NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, devidx);
    } else {
        NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, devidx);
    }

    if (add_interface) {
        NLA_PUT_STRING(msg, NL80211_ATTR_IFNAME, iface);
        NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, type);
    }

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

    err = 1;

    nl_cb_err(cb, NL_CB_CUSTOM, nl_error_handler, &err);
    nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, nl_finish_handler, &err);
    nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, nl_ack_handler, &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:
    ALOGW("building message failed");
    return 2;
}
Exemple #23
0
int nl80211_get_chanlist(const char *interface, int *ret_num_chans, int **ret_chan_list,
						  char *errstr) {
	nl80211_channel_block_t cblock;

#ifndef HAVE_LINUX_NETLINK
	snprintf(errstr, LORCON_STATUS_MAX, "LORCON was not compiled with netlink/nl80211 "
			 "support, check the output of ./configure for why");
	return NL80211_CHANLIST_NOT_NL80211;
#else
	void *handle, *cache, *family;
	struct nl_cb *cb;
	int err;
	struct nl_msg *msg;

	cblock.phyname = nl80211_find_parent(interface);
	if (strlen(cblock.phyname) == 0) {
		if (if_nametoindex(interface) <= 0) {
			snprintf(errstr, LORCON_STATUS_MAX, "Interface %s doesn't exist", interface);
			return NL80211_CHANLIST_NO_INTERFACE;
		} 

		snprintf(errstr, LORCON_STATUS_MAX, "LORCON could not find a parent phy device "
				 "for interface %s, it isn't nl80211?", interface);
		return NL80211_CHANLIST_NOT_NL80211;
	}

	if (nl80211_connect(interface, &handle, &cache, &family, errstr) < 0) {
		return NL80211_CHANLIST_GENERIC;
	}

	msg = nlmsg_alloc();
	cb = nl_cb_alloc(NL_CB_DEFAULT);

	err = 1;

	nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, nl80211_freqlist_cb, &cblock);
	nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, nl80211_finish_cb, &err);
	nl_cb_err(cb, NL_CB_CUSTOM, nl80211_error_cb, &err);

	genlmsg_put(msg, 0, 0, genl_family_get_id((struct genl_family *) family),
			  0, NLM_F_DUMP, NL80211_CMD_GET_WIPHY, 0);

	if (nl_send_auto_complete((struct nl_sock *) handle, msg) < 0) {
		snprintf(errstr, LORCON_STATUS_MAX, "%s: Failed to write nl80211 message",
				__FUNCTION__);
		nl80211_disconnect(handle);
		return NL80211_CHANLIST_GENERIC;
	}

	while (err)
		nl_recvmsgs((struct nl_sock *) handle, cb);

	nl80211_disconnect(handle);
	(*ret_num_chans) = cblock.nfreqs;
	(*ret_chan_list) = (int *) malloc(sizeof(int) * cblock.nfreqs);
	memcpy(*ret_chan_list, cblock.channel_list, sizeof(int) * cblock.nfreqs);

	free(cblock.channel_list);
	free(cblock.phyname);

	return (*ret_num_chans);
#endif
}
Exemple #24
0
static int __handle_cmd(struct nl80211_state *state, const char *iface, int get)
{
    struct nl_cb *cb;
    struct nl_msg *msg;
    int devidx = 0;
    int err;

    devidx = if_nametoindex(iface);
    if (devidx == 0)
        devidx = -1;
    if (devidx < 0)
        return -errno;

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

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

    if (get)
        genlmsg_put(msg, 0, 0, genl_family_get_id(state->nl80211), 0,
                    0, NL80211_CMD_GET_POWER_SAVE, 0);
    else
        genlmsg_put(msg, 0, 0, genl_family_get_id(state->nl80211), 0,
                    0, NL80211_CMD_SET_POWER_SAVE, 0);


    NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, devidx);

    if (get)
        err = get_power_save(state, cb, msg);
    else
        err = set_power_save(state, cb, msg);

    if (err)
        goto out;

    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;
}
Exemple #25
0
static int handle_interface_add(struct nl80211_state *state,
				char *phy, char *dev, int argc, char **argv)
{
	char *name;
	char *mesh_id = NULL;
	enum nl80211_iftype type;
	int tpset, err;
	struct nl_msg *msg;

	if (argc < 1) {
		fprintf(stderr, "not enough arguments\n");
		return -1;
	}

	name = argv[0];
	argc--;
	argv++;

	tpset = get_if_type(&argc, &argv, &type);
	if (tpset == 0)
		fprintf(stderr, "you must specify an interface type\n");
	if (tpset <= 0)
		return -1;

	if (argc) {
		if (strcmp(argv[0], "mesh_id") != 0) {
			fprintf(stderr, "option %s not supported\n", argv[0]);
			return -1;
		}
		argc--;
		argv++;

		if (!argc) {
			fprintf(stderr, "not enough arguments\n");
			return -1;
		}
		mesh_id = argv[0];
		argc--;
		argv++;
	}

	if (argc) {
		fprintf(stderr, "too many arguments\n");
		return -1;
	}

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

	genlmsg_put(msg, 0, 0, genl_family_get_id(state->nl80211), 0,
		    0, NL80211_CMD_NEW_INTERFACE, 0);
	if (dev)
		NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(dev));
	if (phy)
		return -1; /* XXX TODO */
	NLA_PUT_STRING(msg, NL80211_ATTR_IFNAME, name);
	if (tpset)
		NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, type);
	if (mesh_id)
		NLA_PUT(msg, NL80211_ATTR_MESH_ID, strlen(mesh_id), mesh_id);

	if ((err = nl_send_auto_complete(state->nl_handle, msg)) < 0 ||
	    (err = nl_wait_for_ack(state->nl_handle)) < 0) {
 nla_put_failure:
		fprintf(stderr, "failed to create interface: %d\n", err);
		nlmsg_free(msg);
		return -1;
	}

	nlmsg_free(msg);

	return 0;
}