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; }
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; }
static int atheros_commit(void *priv) { struct atheros_driver_data *drv = priv; return linux_set_iface_flags(drv->ioctl_sock, drv->iface, 1); }
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; }
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; }
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; }
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; }
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; }