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;
}
Example #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;
}
static int wpa_driver_set_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, drv->global->nl80211_id, 0, 0,
		    NL80211_CMD_SET_POWER_SAVE, 0);

	if (state == WPA_PS_ENABLED)
		ps_state = NL80211_PS_ENABLED;
	else
		ps_state = NL80211_PS_DISABLED;

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

	ret = send_and_recv_msgs(drv, msg, NULL, NULL);
	msg = NULL;
	if (ret < 0)
		wpa_printf(MSG_ERROR, "nl80211: Set power mode fail: %d", ret);
nla_put_failure:
	nlmsg_free(msg);
	return ret;
}
int nl80211_get_wiphy_index(struct nl80211_data *ctx, int* phyidx)
{
	struct nl_msg *msg;
	struct wiphy_idx_data data = { 0 };
	if (!(msg = nl80211_cmd_msg(ctx, 0, NL80211_CMD_GET_INTERFACE)))
		return -1;
	if (send_and_recv_msgs(ctx, msg, netdev_info_handler, &data))
		return -1;

	if (phyidx) *phyidx = data.wiphy_idx;
	return 0;
}
Example #5
0
static int nl80211_create_iface_once(struct nl80211_data* ctx, int(*handler)(struct nl_msg *, void *), void *arg)
{
    int ret = -ENOBUFS;
    struct nl_msg *msg;
    struct nlattr *flags;
    int ifidx;
    const char *ifname = ctx->monitor_name;
    fprintf(stderr, "nl80211: Create monitor interface %s\n", ifname);

    msg = nl80211_cmd_msg(ctx, 0, NL80211_CMD_NEW_INTERFACE);
    if (!msg)
        goto fail;

    if (nla_put_string(msg, NL80211_ATTR_IFNAME, ifname))
        goto fail;
    
    if (nla_put_u32(msg, NL80211_ATTR_IFTYPE, NL80211_IFTYPE_MONITOR))
        goto fail;

    flags = nla_nest_start(msg, NL80211_ATTR_MNTR_FLAGS);
    if (!flags)
        goto fail;

    if (nla_put_flag(msg, NL80211_MNTR_FLAG_COOK_FRAMES))
        goto fail;

    nla_nest_end(msg, flags);

    /*
    * Tell cfg80211 that the interface belongs to the socket that created
    * it, and the interface should be deleted when the socket is closed.
    */
    if (nla_put_flag(msg, NL80211_ATTR_IFACE_SOCKET_OWNER))
        goto fail;

    ret = send_and_recv_msgs(ctx, msg, handler, arg);
    msg = NULL;


    if (ret) {
    fail:
        nlmsg_free(msg);
        fprintf(stderr, "nl80211: Failed to create Monitor interface: %d (%s)\n", ret, strerror(-ret));
        return -1;
    }

    ifidx = if_nametoindex(ifname);
    fprintf(stderr, "nl80211: New interface %s created at ifindex=%d\n", ifname, ifidx);
    if (ifidx <= 0)
        return -1;

    return ifidx;
}
Example #6
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;
}
int nl80211_get_ifmode(struct nl80211_data *ctx, enum nl80211_iftype* nlmode)
{
	struct nl_msg *msg;
	struct wiphy_idx_data data = {
		.nlmode = NL80211_IFTYPE_UNSPECIFIED,
		.macaddr = NULL,
	};

	if (!(msg = nl80211_cmd_msg(ctx, 0, NL80211_CMD_GET_INTERFACE)))
		return NL80211_IFTYPE_UNSPECIFIED;
	if (send_and_recv_msgs(ctx, msg, netdev_info_handler, &data))
		return -1;
	
	if (nlmode) *nlmode = data.nlmode;
	return 0;
}
static u32 get_nl80211_protocol_features(struct wpa_driver_nl80211_data *drv)
{
	u32 feat = 0;
	struct nl_msg *msg;

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

	if (!nl80211_cmd(drv, msg, 0, NL80211_CMD_GET_PROTOCOL_FEATURES)) {
		nlmsg_free(msg);
		return 0;
	}

	if (send_and_recv_msgs(drv, msg, protocol_feature_handler, &feat) == 0)
		return feat;

	return 0;
}
int nl80211_get_macaddr(struct nl80211_data *ctx, u8* macaddr)
{
	if (!macaddr) return -1;

	struct nl_msg *msg;
	struct wiphy_idx_data data = { 0 };
	data.macaddr = macaddr;

	if (!(msg = nl80211_cmd_msg(ctx, 0, NL80211_CMD_GET_INTERFACE))) {
		free(data.macaddr);
		return -1;
	}

	if (send_and_recv_msgs(ctx, msg, netdev_info_handler, &data)) {
		free(data.macaddr);
		return -1;
	}

	return 0;
}
int nl80211_set_ifmode(struct nl80211_data* ctx, enum nl80211_iftype mode)
{
	struct nl_msg *msg;
	
	msg = nl80211_cmd_msg(ctx, 0, NL80211_CMD_SET_INTERFACE);
	if (!msg) {
		nlmsg_free(msg);
		return -1;
	}

	if (nla_put_u32(msg, NL80211_ATTR_IFTYPE, mode)) {
		nlmsg_free(msg);
		return -1;
	}

	if (send_and_recv_msgs(ctx, msg, NULL, NULL)) {
		fprintf(stderr, "failed?\n");
		return -1;
	}

	return 0;
}
Example #11
0
int nl80211_unset_ap(struct nl80211_data *ctx)
{
    struct nl_msg *msg = NULL;
    int ret;
    
    if (!ctx) return -1;
    if (ctx->ifindex<0) return -1;

    msg = nlmsg_alloc();
    if (!msg) goto fail;
    if (!nl80211_cmd(ctx, msg, 0, NL80211_CMD_DEL_BEACON)) goto fail;
    if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, ctx->ifindex)) goto fail;
    ret = send_and_recv_msgs(ctx, msg, NULL, NULL);
    if (ret) {
        fprintf(stderr, "nl80211: advanced settings failed: %d (%s)\n", ret, strerror(-ret));
        goto fail;
    } 
    return 0;
fail:
    if (msg) nlmsg_free(msg);
    return -1;

}
Example #12
0
void nl80211_remove_iface(struct nl80211_data *ctx, int ifidx)
{
    struct nl_msg *msg = NULL;

    fprintf(stderr, "nl80211: Remove interface ifindex=%d\n", ifidx);

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

    if (!nl80211_cmd(ctx, msg, 0, NL80211_CMD_DEL_INTERFACE)) 
        goto failed;

    if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifidx))
        goto failed;

    if (send_and_recv_msgs(ctx, msg, NULL, NULL) == 0)
        return;

failed:
    if (msg) nlmsg_free(msg);
    fprintf(stderr, "failed to remove interface (ifidx=%d)\n", ifidx);
}
Example #13
0
int nl80211_set_ap(struct nl80211_data *ctx)
{
    struct nl_msg *msg = NULL;
    int ret;

    u16   beacon_period = 100;
    u8    beacon_DTIM = 1;
    char* ssid_name = "TEST";
    u8    ssid_sz = strlen(ssid_name);

    int j;
    u8 rates[NL80211_MAX_SUPP_RATES];
    u8 nbBascis = (u8)(sizeof(BASIC_RATES)/sizeof(int));
    
    // format basics rates
    for (j = 0; j<nbBascis; j++) rates[j] = BASIC_RATE(BASIC_RATES[j]);

    //portion of the beacon before the TIM IE
    u8 * head = NULL;
    int  head_sz = 0;
    
    //portion of the beacon after the TIM IE
    u8 * tail = NULL;
    int  tail_sz = 0;

    // BEACON HEAD
    {
        u8 * pos = NULL;        
        packet_element_t macheader = { 0 };
        packet_element_t ssid = { 0 };
        packet_element_t rates = { 0 };
        packet_element_t ds = { 0 };

        head_sz += hostapd_header_beacon(&macheader, ctx->macaddr, beacon_period);
        head_sz += hostapd_eid_ssid(&ssid, ssid_name);
        head_sz += hostapd_eid_supp_rates(&rates);
        head_sz += hostapd_eid_ds_params(&ds);

        head = (u8*)malloc(head_sz); pos = head;
        pos = packet_element_concatnfree(pos, macheader);
        pos = packet_element_concatnfree(pos, ssid);
        pos = packet_element_concatnfree(pos, rates);
        pos = packet_element_concatnfree(pos, ds);

        fhexdump(stderr, "nl80211: Beacon head", head, head_sz);
    }

    // BEACON TAIL
    {
        u8 * pos = NULL;
        packet_element_t rates = { 0 };
        //packet_element_t emilie = { 0 };

        tail_sz += hostapd_eid_ext_rates(&rates);
        //tail_sz += hostapd_eid_emilie(&emilie);

        tail = (u8*)malloc(tail_sz); pos = tail;
        pos = packet_element_concatnfree(pos, rates);
        //pos = packet_element_concatnfree(pos, emilie);

        fhexdump(stderr, "nl80211: Beacon tail", tail, tail_sz);
    }

    // NL80211 BEACON SETTING
    msg = nlmsg_alloc();
    if (!msg) goto fail;
    if (!nl80211_cmd(ctx, msg, 0, NL80211_CMD_NEW_BEACON)) goto fail;
    if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, ctx->ifindex)) goto fail;
    
    if (nla_put(msg, NL80211_ATTR_BEACON_HEAD, head_sz, head)) goto fail;
    if (nla_put(msg, NL80211_ATTR_BEACON_TAIL, tail_sz, tail)) goto fail;
    if (nla_put_u32(msg, NL80211_ATTR_BEACON_INTERVAL, beacon_period)) goto fail;
    if (nla_put_u32(msg, NL80211_ATTR_DTIM_PERIOD, beacon_DTIM)) goto fail;    
    if (nla_put(msg, NL80211_ATTR_SSID, ssid_sz, ssid_name)) goto fail;
    
    
    if (nla_put_u32(msg, NL80211_ATTR_HIDDEN_SSID, NL80211_HIDDEN_SSID_NOT_IN_USE)) goto fail;
    if (nla_put_flag(msg, NL80211_ATTR_PRIVACY)) goto fail;
    if (nla_put_u32(msg, NL80211_ATTR_AUTH_TYPE, NL80211_AUTHTYPE_OPEN_SYSTEM)) goto fail;
    if (nla_put_u32(msg, NL80211_ATTR_SMPS_MODE, NL80211_SMPS_OFF)) goto fail;
    ret = send_and_recv_msgs(ctx, msg, NULL, NULL);
    if (ret) {
        fprintf(stderr, "nl80211: Beacon set failed: %d (%s)\n", ret, strerror(-ret));
        goto fail;
    }

    // NL80211 BSS ADVDANCED SETTING
    msg = nlmsg_alloc();
    if (!msg)
        goto fail;
    if (!nl80211_cmd(ctx, msg, 0, NL80211_CMD_SET_BSS))
        goto fail;
    if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, ctx->ifindex))
        goto fail;
    if (nla_put_u8(msg, NL80211_ATTR_BSS_CTS_PROT, 0))
        goto fail;
    if (nla_put_u8(msg, NL80211_ATTR_BSS_SHORT_PREAMBLE, 0))
        goto fail;
    if (nla_put_u8(msg, NL80211_ATTR_BSS_SHORT_SLOT_TIME, 1))
        goto fail;
    if (nla_put_u16(msg, NL80211_ATTR_BSS_HT_OPMODE, 0))
        goto fail;
    if (nla_put_u8(msg, NL80211_ATTR_AP_ISOLATE, 0))
        goto fail;
    if (nla_put(msg, NL80211_ATTR_BSS_BASIC_RATES, nbBascis, rates))
       goto fail;;
    ret = send_and_recv_msgs(ctx, msg, NULL, NULL);
    if (ret) {
        fprintf(stderr, "nl80211: advanced settings failed: %d (%s)\n", ret, strerror(-ret));
        goto fail;
    } 

    if (head) free(head);
    if (tail) free(tail);
    return 0;
fail:
    if (msg) nlmsg_free(msg);
    if (head) free(head);
    if (tail) free(tail);
    return -1;
}
static int nl80211_set_wowlan_triggers(struct i802_bss *bss, int enable)
{
	struct nl_msg *msg, *pats = NULL;
	struct wpa_driver_nl80211_data *drv = bss->drv;
	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, drv->global->nl80211_id, 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;
}