int wpa_driver_nl80211_driver_cmd(void *priv, char *cmd, char *buf,
				  size_t buf_len )
{
	struct i802_bss *bss = priv;
	struct wpa_driver_nl80211_data *drv = bss->drv;
	struct ifreq ifr;
	android_wifi_priv_cmd priv_cmd;
	int ret = 0;

	if (os_strcasecmp(cmd, "STOP") == 0) {
		linux_set_iface_flags(drv->global->ioctl_sock, bss->ifname, 0);
		wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STOPPED");
	} else if (os_strcasecmp(cmd, "START") == 0) {
		linux_set_iface_flags(drv->global->ioctl_sock, bss->ifname, 1);
		wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STARTED");
	} else if (os_strcasecmp(cmd, "MACADDR") == 0) {
		u8 macaddr[ETH_ALEN] = {};

		ret = linux_get_ifhwaddr(drv->global->ioctl_sock, bss->ifname, macaddr);
		if (!ret)
			ret = os_snprintf(buf, buf_len,
					  "Macaddr = " MACSTR "\n", MAC2STR(macaddr));
	} else { /* Use private command */
		memset(&ifr, 0, sizeof(ifr));
		memset(&priv_cmd, 0, sizeof(priv_cmd));
		os_memcpy(buf, cmd, strlen(cmd) + 1);
		os_strncpy(ifr.ifr_name, bss->ifname, IFNAMSIZ);

		priv_cmd.buf = buf;
		priv_cmd.used_len = buf_len;
		priv_cmd.total_len = buf_len;
		ifr.ifr_data = &priv_cmd;

		if ((ret = ioctl(drv->global->ioctl_sock, SIOCDEVPRIVATE + 1, &ifr)) < 0) {
			wpa_printf(MSG_ERROR, "%s: failed to issue private commands\n", __func__);
		} else {
			drv_errors = 0;
			ret = 0;
			if ((os_strcasecmp(cmd, "LINKSPEED") == 0) ||
			    (os_strcasecmp(cmd, "RSSI") == 0) ||
			    (os_strcasecmp(cmd, "GETBAND") == 0) )
				ret = strlen(buf);
			else if (os_strcasecmp(cmd, "COUNTRY") == 0)
				wpa_supplicant_event(drv->ctx,
					EVENT_CHANNEL_LIST_CHANGED, NULL);
			else if (os_strncasecmp(cmd, "SETBAND", 7) == 0)
				wpa_printf(MSG_DEBUG, "%s: %s ", __func__, cmd);
			else if (os_strcasecmp(cmd, "P2P_DEV_ADDR") == 0)
				wpa_printf(MSG_DEBUG, "%s: P2P: Device address ("MACSTR")",
					__func__, MAC2STR(buf));
			else if (os_strcasecmp(cmd, "P2P_SET_PS") == 0)
				wpa_printf(MSG_DEBUG, "%s: P2P: %s ", __func__, buf);
			else if (os_strcasecmp(cmd, "P2P_SET_NOA") == 0)
				wpa_printf(MSG_DEBUG, "%s: P2P: %s ", __func__, buf);
			else
				wpa_printf(MSG_DEBUG, "%s %s len = %d, %d", __func__, buf, ret, strlen(buf));
		}
	}
	return ret;
}
static int
ar6000_commit(void *priv)
{
    struct ar6000_driver_data *drv = priv;
    struct iwreq iwr;

    memset(&iwr, 0, sizeof(iwr));
    os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ);

    if (ioctl(drv->ioctl_sock, SIOCSIWCOMMIT, &iwr) < 0) {
        perror("ioctl[SIOCSIWCOMMIT]");
    }
    return linux_set_iface_flags(drv->ioctl_sock, drv->iface, 1);
}
int wpa_driver_nl80211_driver_cmd(void *priv, char *cmd, char *buf,
				  size_t buf_len )
{
	struct i802_bss *bss = priv;
	struct wpa_driver_nl80211_data *drv = bss->drv;
	struct wpa_driver_nl80211_data *driver;
	struct ifreq ifr;
	android_wifi_priv_cmd priv_cmd;
	int ret = 0;

	if (os_strcasecmp(cmd, "STOP") == 0) {
		dl_list_for_each(driver, &drv->global->interfaces, struct wpa_driver_nl80211_data, list) {
				linux_set_iface_flags(drv->global->ioctl_sock, driver->first_bss->ifname, 0);
				wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STOPPED");
		}
	} else if (os_strcasecmp(cmd, "START") == 0) {
static void
atheros_deinit(void *priv)
{
    struct atheros_driver_data *drv = priv;

    netlink_deinit(drv->netlink);
    (void) linux_set_iface_flags(drv->ioctl_sock, drv->iface, 0);
    if (drv->ioctl_sock >= 0)
        close(drv->ioctl_sock);
    if (drv->sock_recv != NULL && drv->sock_recv != drv->sock_xmit)
        l2_packet_deinit(drv->sock_recv);
    if (drv->sock_xmit != NULL)
        l2_packet_deinit(drv->sock_xmit);
    if (drv->sock_raw)
        l2_packet_deinit(drv->sock_raw);
    free(drv);
}
static void
ar6000_deinit(void *priv)
{
    struct ar6000_driver_data *drv = priv;

	netlink_deinit(drv->netlink);
	(void) linux_set_iface_flags(drv->ioctl_sock, drv->iface, 0);
    if (drv->ioctl_sock >= 0)
        close(drv->ioctl_sock);
    if (drv->sock_recv != NULL && drv->sock_recv != drv->sock_xmit)
        l2_packet_deinit(drv->sock_recv);
    if (drv->sock_xmit != NULL)
        l2_packet_deinit(drv->sock_xmit);
    if (drv->sock_raw)
        l2_packet_deinit(drv->sock_raw);
	wpabuf_free(drv->wpa_ie);
	wpabuf_free(drv->wps_beacon_ie);
	wpabuf_free(drv->wps_probe_resp_ie);
    free(drv);
}
static int init() {

    ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0);
    if (ioctl_sock < 0) {
      printMsg("Bad socket: %d\n", ioctl_sock);
      return errno;
    } else {
      printMsg("Good socket: %d\n", ioctl_sock);
    }

    int ret = linux_set_iface_flags(ioctl_sock, "wlan0", 1);
    if (ret < 0) {
        return ret;
    }

    wifi_error res = wifi_initialize(&halHandle);
    if (res < 0) {
        return res;
    }

    res = wifi_get_ifaces(halHandle, &numIfaceHandles, &ifaceHandles);
    if (res < 0) {
        return res;
    }

    char buf[EVENT_BUF_SIZE];
    for (int i = 0; i < numIfaceHandles; i++) {
        if (wifi_get_iface_name(ifaceHandles[i], buf, sizeof(buf)) == WIFI_SUCCESS) {
            if (strcmp(buf, "wlan0") == 0) {
                printMsg("found interface %s\n", buf);
                wlan0Handle = ifaceHandles[i];
            } else if (strcmp(buf, "p2p0") == 0) {
                printMsg("found interface %s\n", buf);
                p2p0Handle = ifaceHandles[i];
            }
        }
    }

    return res;
}
Example #7
0
static int hostap_set_iface_flags(void *priv, int dev_up)
{
	struct hostap_driver_data *drv = priv;
	struct ifreq ifr;
	char ifname[IFNAMSIZ];

	os_snprintf(ifname, IFNAMSIZ, "%sap", drv->iface);
	if (linux_set_iface_flags(drv->ioctl_sock, ifname, dev_up) < 0)
		return -1;

	if (dev_up) {
		memset(&ifr, 0, sizeof(ifr));
		os_strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
		ifr.ifr_mtu = HOSTAPD_MTU;
		if (ioctl(drv->ioctl_sock, SIOCSIFMTU, &ifr) != 0) {
			wpa_printf(MSG_INFO,
				   "Setting MTU failed - trying to survive with current value: ioctl[SIOCSIFMTU]: %s",
				   strerror(errno));
		}
	}

	return 0;
}
int wpa_driver_nl80211_driver_cmd(void *priv, char *cmd, char *buf,
				  size_t buf_len )
{
	struct i802_bss *bss = priv;
	struct wpa_driver_nl80211_data *drv = bss->drv;
	struct ifreq ifr;
	android_wifi_priv_cmd priv_cmd;
	int ret = 0;

	if (os_strcasecmp(cmd, "STOP") == 0) {
		linux_set_iface_flags(drv->ioctl_sock, bss->ifname, 0);
		wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STOPPED");
	} else if (os_strcasecmp(cmd, "START") == 0) {
		linux_set_iface_flags(drv->ioctl_sock, bss->ifname, 1);
		wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STARTED");
	} else if (os_strcasecmp(cmd, "MACADDR") == 0) {
		u8 macaddr[ETH_ALEN] = {};

		ret = linux_get_ifhwaddr(drv->ioctl_sock, bss->ifname, macaddr);
		if (!ret)
			ret = os_snprintf(buf, buf_len,
					  "Macaddr = " MACSTR "\n", MAC2STR(macaddr));
	} else if (os_strcasecmp(cmd, "RELOAD") == 0) {
		wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "HANGED");
	} else if (os_strncasecmp(cmd, "POWERMODE ", 10) == 0) {
		int state;

		state = atoi(cmd + 10);
		ret = wpa_driver_set_power_save(priv, state);
		if (ret < 0)
			wpa_driver_send_hang_msg(drv);
		else
			drv_errors = 0;
	} else if (os_strncasecmp(cmd, "GETPOWER", 8) == 0) {
		int state = -1;

		ret = wpa_driver_get_power_save(priv, &state);
		if (!ret && (state != -1)) {
			ret = os_snprintf(buf, buf_len, "POWERMODE = %d\n", state);
			drv_errors = 0;
		} else {
			wpa_driver_send_hang_msg(drv);
		}
	} else { /* Use private command */
		if (os_strcasecmp(cmd, "BGSCAN-START") == 0) {
			ret = wpa_driver_set_backgroundscan_params(priv);
			if (ret < 0) {
				return ret;
			}
			os_memcpy(buf, "PNOFORCE 1", 11);
		} else if (os_strcasecmp(cmd, "BGSCAN-STOP") == 0) {
			os_memcpy(buf, "PNOFORCE 0", 11);
		} else {
			os_memcpy(buf, cmd, strlen(cmd) + 1);
		}
		memset(&ifr, 0, sizeof(ifr));
		memset(&priv_cmd, 0, sizeof(priv_cmd));
		os_strncpy(ifr.ifr_name, bss->ifname, IFNAMSIZ);

		priv_cmd.buf = buf;
		priv_cmd.used_len = buf_len;
		priv_cmd.total_len = buf_len;
		ifr.ifr_data = &priv_cmd;

//alber test		if ((ret = ioctl(drv->ioctl_sock, SIOCDEVPRIVATE + 1, &ifr)) < 0) {
//alber test			wpa_printf(MSG_ERROR, "%s: failed to issue private commands\n", __func__);
//alber test			wpa_driver_send_hang_msg(drv);
//alber		} else {
			drv_errors = 0;
			ret = 0;
			if ((os_strcasecmp(cmd, "LINKSPEED") == 0) ||
			    (os_strcasecmp(cmd, "RSSI") == 0) ||
			    (os_strcasecmp(cmd, "GETBAND") == 0) ||
			    (os_strcasecmp(cmd, "P2P_GET_NOA") == 0))
				ret = strlen(buf);

			wpa_printf(MSG_DEBUG, "%s %s len = %d, %d", __func__, buf, ret, strlen(buf));
//alber test		}
	}
	return ret;
}
Example #9
0
static int
atheros_commit(void *priv)
{
	struct atheros_driver_data *drv = priv;
	return linux_set_iface_flags(drv->ioctl_sock, drv->iface, 1);
}
Example #10
0
static void *
atheros_init(struct hostapd_data *hapd, struct wpa_init_params *params)
{
	struct atheros_driver_data *drv;
	struct ifreq ifr;
	struct iwreq iwr;
	char brname[IFNAMSIZ];

	drv = os_zalloc(sizeof(struct atheros_driver_data));
	if (drv == NULL) {
		printf("Could not allocate memory for atheros driver data\n");
		return NULL;
	}

	drv->hapd = hapd;
	drv->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0);
	if (drv->ioctl_sock < 0) {
		perror("socket[PF_INET,SOCK_DGRAM]");
		goto bad;
	}
	memcpy(drv->iface, params->ifname, sizeof(drv->iface));

	memset(&ifr, 0, sizeof(ifr));
	os_strlcpy(ifr.ifr_name, drv->iface, sizeof(ifr.ifr_name));
	if (ioctl(drv->ioctl_sock, SIOCGIFINDEX, &ifr) != 0) {
		perror("ioctl(SIOCGIFINDEX)");
		goto bad;
	}
	drv->ifindex = ifr.ifr_ifindex;

	drv->sock_xmit = l2_packet_init(drv->iface, NULL, ETH_P_EAPOL,
					handle_read, drv, 1);
	if (drv->sock_xmit == NULL)
		goto bad;
	if (l2_packet_get_own_addr(drv->sock_xmit, params->own_addr))
		goto bad;
	if (params->bridge[0]) {
		wpa_printf(MSG_DEBUG, "Configure bridge %s for EAPOL traffic.",
			   params->bridge[0]);
		drv->sock_recv = l2_packet_init(params->bridge[0], NULL,
						ETH_P_EAPOL, handle_read, drv,
						1);
		if (drv->sock_recv == NULL)
			goto bad;
	} else if (linux_br_get(brname, drv->iface) == 0) {
		wpa_printf(MSG_DEBUG, "Interface in bridge %s; configure for "
			   "EAPOL receive", brname);
		drv->sock_recv = l2_packet_init(brname, NULL, ETH_P_EAPOL,
						handle_read, drv, 1);
		if (drv->sock_recv == NULL)
			goto bad;
	} else
		drv->sock_recv = drv->sock_xmit;

	memset(&iwr, 0, sizeof(iwr));
	os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ);

	iwr.u.mode = IW_MODE_MASTER;

	if (ioctl(drv->ioctl_sock, SIOCSIWMODE, &iwr) < 0) {
		perror("ioctl[SIOCSIWMODE]");
		printf("Could not set interface to master mode!\n");
		goto bad;
	}

	/* mark down during setup */
	linux_set_iface_flags(drv->ioctl_sock, drv->iface, 0);
	atheros_set_privacy(drv, 0); /* default to no privacy */

	atheros_receive_probe_req(drv);

	if (atheros_wireless_event_init(drv))
		goto bad;

	return drv;
bad:
	if (drv->sock_recv != NULL && drv->sock_recv != drv->sock_xmit)
		l2_packet_deinit(drv->sock_recv);
	if (drv->sock_xmit != NULL)
		l2_packet_deinit(drv->sock_xmit);
	if (drv->ioctl_sock >= 0)
		close(drv->ioctl_sock);
	if (drv != NULL)
		free(drv);
	return NULL;
}
Example #11
0
int wpa_driver_nl80211_driver_cmd(void *priv, char *cmd, char *buf,
				  size_t buf_len )
{
	struct i802_bss *bss = priv;
	struct wpa_driver_nl80211_data *drv = bss->drv;
	struct ifreq ifr;
	android_wifi_priv_cmd priv_cmd;
	int ret = 0;

	if (os_strcasecmp(cmd, "STOP") == 0) {
		linux_set_iface_flags(drv->global->ioctl_sock, bss->ifname, 0);
		wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STOPPED");
	} else if (os_strcasecmp(cmd, "START") == 0) {
		linux_set_iface_flags(drv->global->ioctl_sock, bss->ifname, 1);
		wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STARTED");
	} else if (os_strcasecmp(cmd, "MACADDR") == 0) {
		u8 macaddr[ETH_ALEN] = {};

		ret = linux_get_ifhwaddr(drv->global->ioctl_sock, bss->ifname, macaddr);
		if (!ret)
			ret = os_snprintf(buf, buf_len,
					  "Macaddr = " MACSTR "\n", MAC2STR(macaddr));
	} else if (os_strcasecmp(cmd, "RELOAD") == 0) {
		wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "HANGED");
	} else if (os_strncasecmp(cmd, "POWERMODE ", 10) == 0) {
		int state;

		state = atoi(cmd + 10);
		ret = wpa_driver_set_power_save(priv, state);
		if (ret < 0)
			wpa_driver_send_hang_msg(drv);
		else
			drv_errors = 0;
	} else if (os_strncasecmp(cmd, "GETPOWER", 8) == 0) {
		int state = -1;

		ret = wpa_driver_get_power_save(priv, &state);
		if (!ret && (state != -1)) {
			ret = os_snprintf(buf, buf_len, "POWERMODE = %d\n", state);
			drv_errors = 0;
		} else {
			wpa_driver_send_hang_msg(drv);
		}
	} else if(os_strcmp(cmd, "SCAN-ACTIVE") == 0) {
		return 0; /* unsupported function */
	} else if(os_strcmp(cmd, "SCAN-PASSIVE") == 0) {
		return 0; /* unsupported function */
	} else if(os_strncmp(cmd, "RXFILTER-ADD ", 13) == 0) {
		return 0; /* Ignore it */
	} else if(os_strncmp(cmd, "RXFILTER-REMOVE ", 16) == 0) {
		return 0; /* Ignore it */
	} else if(os_strncmp(cmd, "BTCOEXMODE ", 11) == 0) {
                int mode;
                if (sscanf(cmd, "%*s %d", &mode)==1) {
                        /*
                         * Android disable BT-COEX when obtaining dhcp packet except there is headset is connected
                         * It enable the BT-COEX after dhcp process is finished
                         * We ignore since we have our way to do bt-coex during dhcp obtaining.
                         */
                        switch (mode) {
                        case 1: /* Disable*/
                                break;
                        case 0: /* Enable */
                                /* fall through */
                        case 2: /* Sense*/
                                /* fall through */
                        default:
                                break;
                        }
                        return 0; /* ignore it */
                }

	} else if(os_strcmp(cmd, "RXFILTER-START") == 0) {
		// STUB
		return 0;
	} else if(os_strcmp(cmd, "RXFILTER-STOP") == 0) {
		// STUB
		return 0;
	} else { /* Use private command */
		if (os_strcasecmp(cmd, "BGSCAN-START") == 0) {
			ret = wpa_driver_set_backgroundscan_params(priv);
			if (ret < 0) {
				return ret;
			}
			os_memcpy(buf, "PNOFORCE 1", 11);
		} else if (os_strcasecmp(cmd, "BGSCAN-STOP") == 0) {
			os_memcpy(buf, "PNOFORCE 0", 11);
		} else {
			os_memcpy(buf, cmd, strlen(cmd) + 1);
		}
		memset(&ifr, 0, sizeof(ifr));
		memset(&priv_cmd, 0, sizeof(priv_cmd));
		os_strncpy(ifr.ifr_name, bss->ifname, IFNAMSIZ);

		priv_cmd.buf = buf;
		priv_cmd.used_len = buf_len;
		priv_cmd.total_len = buf_len;
		ifr.ifr_data = &priv_cmd;

		if ((ret = ioctl(drv->global->ioctl_sock, SIOCDEVPRIVATE + 1, &ifr)) < 0) {
			wpa_printf(MSG_ERROR, "%s: failed to issue private commands\n", __func__);
			wpa_driver_send_hang_msg(drv);
		} else {
			drv_errors = 0;
			ret = 0;
			if ((os_strcasecmp(cmd, "LINKSPEED") == 0) ||
			    (os_strcasecmp(cmd, "RSSI") == 0) ||
			    (os_strcasecmp(cmd, "GETBAND") == 0) )
				ret = strlen(buf);

			wpa_printf(MSG_DEBUG, "%s %s len = %d, %d", __func__, buf, ret, strlen(buf));
		}
	}
	return ret;
}
Example #12
0
int nl80211_create_monitor_interface(struct nl80211_data* ctx)
{
    if (ctx->monitor_ifidx < 0) {
        // create monitor
        ctx->monitor_ifidx = nl80211_create_iface_once(ctx, NULL, NULL);
        if (ctx->monitor_ifidx == -EOPNOTSUPP) {
            /*
            * This is backward compatibility for a few versions of
            * the kernel only that didn't advertise the right
            * attributes for the only driver that then supported
            * AP mode w/o monitor -- ath6kl.
            */
            fprintf(stderr, "nl80211: Driver does not support monitor interface type - try to run without it\n");
        }
    } else {
        fprintf(stderr, "nl80211: re-use monitor '%s' index: %d\n",ctx->monitor_name, ctx->monitor_ifidx);
    }

    if (ctx->monitor_ifidx < 0)
        return -1;

    // interface up!    
    if (linux_set_iface_flags(ctx->cfg->ioctl_sock, ctx->monitor_name, 1))
        goto error;

    // create socket on monitor interface
    {
        struct sockaddr_ll ll;
        int optval;
        socklen_t optlen;

        memset(&ll, 0, sizeof(ll));
        ll.sll_family = AF_PACKET;
        ll.sll_ifindex = ctx->monitor_ifidx;
        ctx->monitor_sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));

        if (ctx->monitor_sock < 0) {
            fprintf(stderr, "nl80211: socket[PF_PACKET,SOCK_RAW] failed: %s\n", strerror(errno));
            goto error;
        }

        if (add_monitor_filter(ctx->monitor_sock)) {
            fprintf(stderr, "Failed to set socket filter for monitor interface; do filtering in user space\n");
            /* This works, but will cost in performance. */
        }

        if (bind(ctx->monitor_sock, (struct sockaddr *) &ll, sizeof(ll)) < 0) {
            fprintf(stderr, "nl80211: monitor socket bind failed: %s\n", strerror(errno));
            goto error;
        }

        optlen = sizeof(optval);
        optval = 20;
        if (setsockopt(ctx->monitor_sock, SOL_SOCKET, SO_PRIORITY, &optval, optlen)) {
            fprintf(stderr, "nl80211: Failed to set socket priority: %s\n", strerror(errno));
            goto error;
        }

        if (eloop_register_read_sock(ctx->monitor_sock, handle_monitor_read, ctx, NULL)) {
            fprintf(stderr, "nl80211: Could not register monitor read socket\n");
            goto error;
        }
    }
    
    return 0;
    
error:
    nl80211_remove_monitor_interface(ctx);
    return -1;
}
int wpa_driver_nl80211_driver_cmd(void *priv, char *cmd, char *buf,
				  size_t buf_len )
{
	struct i802_bss *bss = priv;
	struct wpa_driver_nl80211_data *drv = bss->drv;
	struct ifreq ifr;
	int ret = 0;

	if (os_strcasecmp(cmd, "STOP") == 0) {
		linux_set_iface_flags(drv->global->ioctl_sock, bss->ifname, 0);
		wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STOPPED");
	} else if (os_strcasecmp(cmd, "START") == 0) {
		linux_set_iface_flags(drv->global->ioctl_sock, bss->ifname, 1);
		wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STARTED");
	} else if (os_strcasecmp(cmd, "RELOAD") == 0) {
		wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "HANGED");
	} else if (os_strncasecmp(cmd, "POWERMODE ", 10) == 0) {
		int mode;
		mode = atoi(cmd + 10);
		ret = wpa_driver_set_power_save(priv, mode);
		if (ret < 0) {
			wpa_driver_send_hang_msg(drv);
		} else {
			g_power_mode = mode;
			g_drv_errors = 0;
		}
	} else if (os_strncasecmp(cmd, "GETPOWER", 8) == 0) {
		ret = os_snprintf(buf, buf_len, "POWERMODE = %d\n", g_power_mode);
	} else if (os_strncasecmp(cmd, "BTCOEXMODE ", 11) == 0) {
		int mode = atoi(cmd + 11);
		if (mode == BLUETOOTH_COEXISTENCE_MODE_DISABLED) { /* disable BT-coex */
			ret = wpa_driver_toggle_btcoex_state('0');
		} else if (mode == BLUETOOTH_COEXISTENCE_MODE_SENSE) { /* enable BT-coex */
			ret = wpa_driver_toggle_btcoex_state('1');
		} else {
			wpa_printf(MSG_DEBUG, "invalid btcoex mode: %d", mode);
			ret = -1;
		}
	} else if (os_strcasecmp(cmd, "MACADDR") == 0) {
		u8 macaddr[ETH_ALEN] = {};

		ret = linux_get_ifhwaddr(drv->global->ioctl_sock, bss->ifname, macaddr);
		if (!ret)
			ret = os_snprintf(buf, buf_len,
					  "Macaddr = " MACSTR "\n", MAC2STR(macaddr));
	} else if( os_strncasecmp(cmd, "RXFILTER-ADD ", 13) == 0 ) {
		int i = nl80211_parse_wowlan_trigger_nr(cmd + 13);
		if(i < 0)
			return i;
		return nl80211_toggle_wowlan_trigger(bss, i, 1);
	} else if( os_strncasecmp(cmd, "RXFILTER-REMOVE ", 16) == 0 ) {
		int i = nl80211_parse_wowlan_trigger_nr(cmd + 16);
		if(i < 0)
			return i;
		return nl80211_toggle_wowlan_trigger(bss, i, 0);
	} else if( os_strcasecmp(cmd, "RXFILTER-START") == 0 ) {
		return nl80211_set_wowlan_triggers(bss, 1);
	} else if( os_strcasecmp(cmd, "RXFILTER-STOP") == 0 ) {
		return nl80211_set_wowlan_triggers(bss, 0);
	} else if( os_strncasecmp(cmd, "DROPBCAST", 9) == 0 ) {
		char *value = cmd + 10;

		if (!os_strcasecmp(value, "ENABLE") ||
		    !os_strcasecmp(value, "1")) {
			ret = nl80211_toggle_dropbcast(1);
		} else if (!os_strcasecmp(value, "DISABLE") ||
			   !os_strcasecmp(value, "0")) {
			ret = nl80211_toggle_dropbcast(0);
		} else if (!os_strcasecmp(value, "GET") ||
			   !os_strlen(value)) {
			ret = nl80211_dropbcast_get(buf, buf_len);
		} else {
			wpa_printf(MSG_ERROR,
				   "Invalid parameter for DROPBCAST: %s",
				   value);
			ret = -1;
		}
	} else if( os_strncasecmp(cmd, "SETBAND ", 8) == 0 ) {
		int val = atoi(cmd + 8);
		ret = 0;
		if ( val < 0 || val > 2 )
			ret = -1;
	} else {
		wpa_printf(MSG_INFO, "%s: Unsupported command %s", __func__, cmd);
	}
	return ret;
}
Example #14
0
int nl80211_create_monitor_interface(struct wpa_driver_nl80211_data *drv)
{
	char buf[IFNAMSIZ];
	struct sockaddr_ll ll;
	int optval;
	socklen_t optlen;

	if (drv->monitor_ifidx >= 0) {
		drv->monitor_refcount++;
		wpa_printf(MSG_DEBUG, "nl80211: Re-use existing monitor interface: refcount=%d",
			   drv->monitor_refcount);
		return 0;
	}

	if (os_strncmp(drv->first_bss->ifname, "p2p-", 4) == 0) {
		/*
		 * P2P interface name is of the format p2p-%s-%d. For monitor
		 * interface name corresponding to P2P GO, replace "p2p-" with
		 * "mon-" to retain the same interface name length and to
		 * indicate that it is a monitor interface.
		 */
		snprintf(buf, IFNAMSIZ, "mon-%s", drv->first_bss->ifname + 4);
	} else {
		/* Non-P2P interface with AP functionality. */
		snprintf(buf, IFNAMSIZ, "mon.%s", drv->first_bss->ifname);
	}

	buf[IFNAMSIZ - 1] = '\0';

	drv->monitor_ifidx =
		nl80211_create_iface(drv, buf, NL80211_IFTYPE_MONITOR, NULL,
				     0, NULL, NULL, 0);

	if (drv->monitor_ifidx == -EOPNOTSUPP) {
		/*
		 * This is backward compatibility for a few versions of
		 * the kernel only that didn't advertise the right
		 * attributes for the only driver that then supported
		 * AP mode w/o monitor -- ath6kl.
		 */
		wpa_printf(MSG_DEBUG, "nl80211: Driver does not support "
			   "monitor interface type - try to run without it");
		drv->device_ap_sme = 1;
	}

	if (drv->monitor_ifidx < 0)
		return -1;

	if (linux_set_iface_flags(drv->global->ioctl_sock, buf, 1))
		goto error;

	memset(&ll, 0, sizeof(ll));
	ll.sll_family = AF_PACKET;
	ll.sll_ifindex = drv->monitor_ifidx;
	drv->monitor_sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
	if (drv->monitor_sock < 0) {
		wpa_printf(MSG_ERROR, "nl80211: socket[PF_PACKET,SOCK_RAW] failed: %s",
			   strerror(errno));
		goto error;
	}

	if (add_monitor_filter(drv->monitor_sock)) {
		wpa_printf(MSG_INFO, "Failed to set socket filter for monitor "
			   "interface; do filtering in user space");
		/* This works, but will cost in performance. */
	}

	if (bind(drv->monitor_sock, (struct sockaddr *) &ll, sizeof(ll)) < 0) {
		wpa_printf(MSG_ERROR, "nl80211: monitor socket bind failed: %s",
			   strerror(errno));
		goto error;
	}

	optlen = sizeof(optval);
	optval = 20;
	if (setsockopt
	    (drv->monitor_sock, SOL_SOCKET, SO_PRIORITY, &optval, optlen)) {
		wpa_printf(MSG_ERROR, "nl80211: Failed to set socket priority: %s",
			   strerror(errno));
		goto error;
	}

	if (eloop_register_read_sock(drv->monitor_sock, handle_monitor_read,
				     drv, NULL)) {
		wpa_printf(MSG_INFO, "nl80211: Could not register monitor read socket");
		goto error;
	}

	drv->monitor_refcount++;
	return 0;
 error:
	nl80211_remove_monitor_interface(drv);
	return -1;
}
Example #15
0
static void *rtl871x_driver_init_ops(struct hostapd_data *hapd, struct wpa_init_params *params)
{
	struct rtl871x_driver_data *drv;
	struct ifreq ifr;
	char	ifrn_name[IFNAMSIZ + 1]; // for mgnt_l2_sock/mgnt_sock
	char brname[IFNAMSIZ];

	drv = os_zalloc(sizeof(struct rtl871x_driver_data));
	if (drv == NULL) {
		printf("Could not allocate memory for rtl871x driver data\n");
		return NULL;
	}

	drv->hapd = hapd;
	drv->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0);
	if (drv->ioctl_sock < 0) {
		perror("socket[PF_INET,SOCK_DGRAM]");
		goto bad;
	}
	os_memcpy(drv->iface, params->ifname, sizeof(drv->iface));

	linux_set_iface_flags(drv->ioctl_sock, drv->iface, 1); // set interface up

	os_memset(&ifr, 0, sizeof(ifr));
	os_strlcpy(ifr.ifr_name, drv->iface, sizeof(ifr.ifr_name));
	if (ioctl(drv->ioctl_sock, SIOCGIFINDEX, &ifr) != 0) {
		perror("ioctl(SIOCGIFINDEX)");
		goto bad;
	}
	drv->ifindex = ifr.ifr_ifindex;
	printf("drv->ifindex=%d\n", drv->ifindex);

	drv->l2_sock = l2_packet_init(drv->iface, NULL, ETH_P_EAPOL,
					rtl871x_handle_read, drv, 1);

	if (drv->l2_sock == NULL)
		goto bad;

	if (l2_packet_get_own_addr(drv->l2_sock, params->own_addr))
		goto bad;

	if (params->bridge[0]) {
		wpa_printf(MSG_DEBUG, "Configure bridge %s for EAPOL traffic.",
			   params->bridge[0]);
		drv->l2_sock_recv = l2_packet_init(params->bridge[0], NULL,
						ETH_P_EAPOL, rtl871x_handle_read, drv,
						1);
		if (drv->l2_sock_recv == NULL) {
			drv->l2_sock_recv = drv->l2_sock;
			printf("no br0 interface , let l2_sock_recv==l2_sock_xmit=0x%p\n", drv->l2_sock);	
		}
		
	} else if (linux_br_get(brname, drv->iface) == 0) {
		wpa_printf(MSG_DEBUG, "Interface in bridge %s; configure for "
			   "EAPOL receive", brname);
		drv->l2_sock_recv = l2_packet_init(brname, NULL, ETH_P_EAPOL,
						rtl871x_handle_read, drv, 1);
		if (drv->l2_sock_recv == NULL)
			goto bad;
	} else {
		drv->l2_sock_recv = drv->l2_sock;
		printf("l2_sock_recv==l2_sock_xmit=0x%p\n", drv->l2_sock);	
	}


	os_memset(ifrn_name, 0, sizeof(ifrn_name));
	snprintf(ifrn_name, sizeof(ifrn_name), "mgnt.%s", "wlan0");

#ifdef CONFIG_MGNT_L2SOCK	
	drv->mgnt_l2_sock = NULL;
	drv->mgnt_l2_sock = l2_packet_init(ifrn_name, NULL, ETH_P_80211_RAW,
				       rtl871x_recvive_mgmt_frame, drv, 1);
	if (drv->mgnt_l2_sock == NULL)
		goto bad;
#else
#ifdef CONFIG_MLME_OFFLOAD
	drv->mgnt_sock = -1;
#else
	drv->mgnt_sock = rtl871x_mgnt_sock_init(drv, ifrn_name);
	if (drv->mgnt_sock < 0) {		
		goto bad;
	}
#endif

#endif
	if (rtl871x_set_mode(drv, IW_MODE_MASTER)<0) {
		printf("Could not set interface to master mode!\n");
		goto bad;
	}

#ifndef CONFIG_MLME_OFFLOAD
	rtl871x_set_iface_flags(drv, 1); // set mgnt interface up
#endif

	if (rtl871x_wireless_event_init(drv))
		goto bad;

	os_memcpy(drv->hw_mac, params->own_addr, ETH_ALEN);

	return drv;
	
bad:

	if (drv->l2_sock_recv != NULL && drv->l2_sock_recv != drv->l2_sock)
		l2_packet_deinit(drv->l2_sock_recv);
	
	if (drv->l2_sock != NULL)
		l2_packet_deinit(drv->l2_sock);
	
	if (drv->ioctl_sock >= 0)
		close(drv->ioctl_sock);

#ifdef CONFIG_MGNT_L2SOCK
	if ( drv->mgnt_l2_sock != NULL)
		l2_packet_deinit(drv->mgnt_l2_sock);
#else
	if (drv->mgnt_sock >= 0)
		close(drv->mgnt_sock);
#endif
	
	if (drv != NULL)
		free(drv);
	
	return NULL;
}
int wpa_driver_nl80211_driver_cmd(void *priv, char *cmd, char *buf,
                  size_t buf_len )
{
    struct i802_bss *bss = priv;
    struct wpa_driver_nl80211_data *drv = bss->drv;
    struct ifreq ifr;
    struct wpa_supplicant *wpa_s;
    struct hostapd_data *hapd;
    int handled = 0;
    int cmd_len = 0;
    union wpa_event_data event;
    static int user_force_band = 0;
    int ret = -1;

    if (drv == NULL) {
        wpa_printf(MSG_ERROR, "%s: drv is NULL. Exiting", __func__);
        return -1;
    }
    if (drv->ctx == NULL) {
        wpa_printf(MSG_ERROR, "%s: drv->ctx is NULL. Exiting", __func__);
        return -1;
    }

    if (os_strcmp(bss->ifname, "ap0") == 0) {
        hapd = (struct hostapd_data *)(drv->ctx);
    }
    else {
        wpa_s = (struct wpa_supplicant *)(drv->ctx);
        if (wpa_s->conf == NULL) {
            wpa_printf(MSG_ERROR, "%s: wpa_s->conf is NULL. Exiting", __func__);
            return -1;
        }
    }

    wpa_printf(MSG_DEBUG, "iface %s recv cmd %s", bss->ifname, cmd);
    handled = 1;

    if (os_strncasecmp(cmd, "POWERMODE ", 10) == 0) {
        int state;
        state = atoi(cmd + 10);
        wpa_printf(MSG_DEBUG, "POWERMODE=%d", state);
    }  else if (os_strncmp(cmd, "MACADDR", os_strlen("MACADDR")) == 0) {
        u8 macaddr[ETH_ALEN] = {};
        os_memcpy(&macaddr, wpa_s->own_addr, ETH_ALEN);
        ret = snprintf(buf, buf_len, "Macaddr = " MACSTR "\n", MAC2STR(macaddr));
        wpa_printf(MSG_DEBUG, "%s", buf);
    } else if(os_strncasecmp(cmd, "COUNTRY", os_strlen("COUNTRY"))==0) {
        if (os_strlen(cmd) != os_strlen("COUNTRY") + 3) {
            wpa_printf(MSG_DEBUG, "Ignore COUNTRY cmd %s", cmd);
            ret = 0;
        } else {
            wpa_printf(MSG_INFO, "set country: %s", cmd+8);
            // ret = wpa_drv_set_country(wpa_s, cmd+8);
            ret = wpa_driver_mediatek_set_country(priv, cmd+8);
            if (ret == 0) {
                wpa_printf(MSG_DEBUG, "Update channel list after country code changed");
                wpa_driver_notify_country_change(wpa_s, cmd);
            }
        }
    } else if (os_strcasecmp(cmd, "start") == 0) {
        if (ret = linux_set_iface_flags(drv->global->ioctl_sock,
            drv->first_bss->ifname, 1)) {
            wpa_printf(MSG_INFO, "nl80211: Could not set interface UP, ret=%d \n", ret);
        } else {
            wpa_msg(drv->ctx, MSG_INFO, "CTRL-EVENT-DRIVER-STATE STARTED");
        }
    } else if (os_strcasecmp(cmd, "stop") == 0) {
        if (drv->associated) {
            ret = wpa_drv_deauthenticate(wpa_s, drv->bssid, WLAN_REASON_DEAUTH_LEAVING);
            if (ret != 0)
                wpa_printf(MSG_DEBUG, "DRIVER-STOP error, ret=%d", ret);
        } else {
            wpa_printf(MSG_INFO, "nl80211: not associated, no need to deauthenticate \n");
        }

        if (ret = linux_set_iface_flags(drv->global->ioctl_sock,
            drv->first_bss->ifname, 0)) {
            wpa_printf(MSG_INFO, "nl80211: Could not set interface Down, ret=%d \n", ret);
        } else {
            wpa_msg(drv->ctx, MSG_INFO, "CTRL-EVENT-DRIVER-STATE STOPPED");
        }
    } else if (os_strncasecmp(cmd, "getpower", 8) == 0) {
        u32 mode;
        // ret = wpa_driver_wext_driver_get_power(drv, &mode);
        if (ret == 0) {
            ret = snprintf(buf, buf_len, "powermode = %u\n", mode);
            wpa_printf(MSG_DEBUG, "%s", buf);
            if (ret < (int)buf_len)
                return ret;
        }
    } else if (os_strncasecmp(cmd, "get-rts-threshold", 17) == 0) {
        u32 thd;
        // ret = wpa_driver_wext_driver_get_rts(drv, &thd);
        if (ret == 0) {
            ret = snprintf(buf, buf_len, "rts-threshold = %u\n", thd);
            wpa_printf(MSG_DEBUG, "%s", buf);
            if (ret < (int)buf_len)
                return ret;
        }
    } else if (os_strncasecmp(cmd, "set-rts-threshold", 17) == 0) {
        u32 thd = 0;
        char *cp = cmd + 17;
        char *endp;
        if (*cp != '\0') {
            thd = (u32)strtol(cp, &endp, 0);
            // if (endp != cp)
                // ret = wpa_driver_wext_driver_set_rts(drv, thd);
        }
    } else if (os_strcasecmp(cmd, "btcoexscan-start") == 0) {
        ret = 0; /* mt5921 linux driver not implement yet */
    } else if (os_strcasecmp(cmd, "btcoexscan-stop") == 0) {
        ret = 0; /* mt5921 linux driver not implement yet */
    } else if (os_strncasecmp(cmd, "btcoexmode", 10) == 0) {
        ret = 0; /* mt5921 linux driver not implement yet */
    } else {
        handled = 0;
        wpa_printf(MSG_INFO, "Unsupported command");
    }

    return ret;
}