static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
{
	struct wpa_cli_cmd *cmd, *match = NULL;
	int count;
	int ret = 0;

	count = 0;
	cmd = wpa_cli_commands;
	while (cmd->cmd) {
		if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0)
		{
			match = cmd;
			if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
				/* we have an exact match */
				count = 1;
				break;
			}
			count++;
		}
		cmd++;
	}

	if (count > 1) {
		printf("Ambiguous command '%s'; possible commands:", argv[0]);
		cmd = wpa_cli_commands;
		while (cmd->cmd) {
			if (os_strncasecmp(cmd->cmd, argv[0],
					   os_strlen(argv[0])) == 0) {
				printf(" %s", cmd->cmd);
			}
			cmd++;
		}
		printf("\n");
		ret = 1;
	} else if (count == 0) {
		printf("Unknown command '%s'\n", argv[0]);
		ret = 1;
	} else {
#ifdef ANDROID
	if( os_strncasecmp( "level", argv[0], os_strlen(argv[0]) ) == 0 )  {
		ctrl = monitor_conn;
    }
#endif
		ret = match->handler(ctrl, argc - 1, &argv[1]);
	}

	return ret;
}
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;
}
Exemplo n.º 3
0
c_bool
u_userGetSPBFromEnvUri() {
    char *uri = NULL;
    c_bool spb = FALSE;
    cf_element platformConfig = NULL;
    cf_element dc = NULL;
    cf_element elemName = NULL;
    cf_element singleProcess = NULL;
    cf_data elementData = NULL;
    cf_data dataName;
    c_value value;
    cfgprs_status r;

    uri = os_getenv ("OSPL_URI");
    r = cfg_parse_ospl (uri, &platformConfig);
    if (r == CFGPRS_OK)
    {
       dc = cf_element (cf_elementChild (platformConfig, CFG_DOMAIN));
       if (dc) {
      singleProcess = cf_element(cf_elementChild(dc, CFG_SINGLEPROCESS));
      if (singleProcess != NULL) {
         elementData = cf_data(cf_elementChild(singleProcess, "#text"));
         if (elementData != NULL) {
            value = cf_dataValue(elementData);
        if (os_strncasecmp(value.is.String, "TRUE", 4) == 0) {
           /* A SingleProcess value of True implies that Heap is to be used */
          spb = TRUE;
        }
         }
      }
       }
    }
    return spb;

}
Exemplo n.º 4
0
static const char * wps_er_find_wfadevice(const char *data)
{
	const char *tag, *tagname, *end;
	char *val;
	int found = 0;

	while (!found) {
		/* Find next <device> */
		for (;;) {
			if (xml_next_tag(data, &tag, &tagname, &end))
				return NULL;
			data = end;
			if (!os_strncasecmp(tagname, "device", 6) &&
			    *tag != '/' &&
			    (tagname[6] == '>' || !isgraph(tagname[6]))) {
				break;
			}
		}

		/* Check whether deviceType is WFADevice */
		val = xml_get_first_item(data, "deviceType");
		if (val == NULL)
			return NULL;
		wpa_printf(MSG_DEBUG, "WPS ER: Found deviceType '%s'", val);
		found = os_strcasecmp(val, "urn:schemas-wifialliance-org:"
				      "device:WFADevice:1") == 0;
		os_free(val);
	}

	return data;
}
Exemplo n.º 5
0
/* A POST body looks something like (per upnp spec):
 * <?xml version="1.0"?>
 * <s:Envelope
 *     xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"
 *     s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
 *   <s:Body>
 *     <u:actionName xmlns:u="urn:schemas-upnp-org:service:serviceType:v">
 *       <argumentName>in arg value</argumentName>
 *       other in args and their values go here, if any
 *     </u:actionName>
 *   </s:Body>
 * </s:Envelope>
 *
 * where :
 *      s: might be some other namespace name followed by colon
 *      u: might be some other namespace name followed by colon
 *      actionName will be replaced according to action requested
 *      schema following actionName will be WFA scheme instead
 *      argumentName will be actual argument name
 *      (in arg value) will be actual argument value
 */
char * xml_get_first_item(const char *doc, const char *item)
{
	const char *match = item;
	int match_len = os_strlen(item);
	const char *tag, *tagname, *end;
	char *value;

	/*
	 * This is crude: ignore any possible tag name conflicts and go right
	 * to the first tag of this name. This should be ok for the limited
	 * domain of UPnP messages.
	 */
	for (;;) {
		if (xml_next_tag(doc, &tag, &tagname, &end))
			return NULL;
		doc = end;
		if (!os_strncasecmp(tagname, match, match_len) &&
		    *tag != '/' &&
		    (tagname[match_len] == '>' ||
		     !isgraph(tagname[match_len]))) {
			break;
		}
	}
	end = doc;
	while (*end && *end != '<')
		end++;
	value = os_zalloc(1 + (end - doc));
	if (value == NULL)
		return NULL;
	os_memcpy(value, doc, end - doc);
	return value;
}
/*
* update channel list in wpa_supplicant
* if coutry code chanaged
*/
static void wpa_driver_notify_country_change(void *ctx, char *cmd)
{
    if (os_strncasecmp(cmd, "COUNTRY", 7) == 0) {
        union wpa_event_data event;

        os_memset(&event, 0, sizeof(event));
        event.channel_list_changed.initiator = REGDOM_SET_BY_USER;
        if (os_strncasecmp(cmd, "COUNTRY", 7) == 0) {
            event.channel_list_changed.type = REGDOM_TYPE_COUNTRY;
            if (os_strlen(cmd) > 9) {
                event.channel_list_changed.alpha2[0] = cmd[8];
                event.channel_list_changed.alpha2[1] = cmd[9];
            }
        } else
            event.channel_list_changed.type = REGDOM_TYPE_UNKNOWN;
        wpa_supplicant_event(ctx, EVENT_CHANNEL_LIST_CHANGED, &event);
    }
}
Exemplo n.º 7
0
/* Given that we have received a header w/ POST, act upon it
 *
 * Format of POST (case-insensitive):
 *
 * First line must be:
 *      POST /<file> HTTP/1.1
 * Since we don't do anything fancy we just ignore other lines.
 *
 * Our response (if no error) which includes only required lines is:
 * HTTP/1.1 200 OK
 * Connection: close
 * Content-Type: text/xml
 * Date: <rfc1123-date>
 *
 * Header lines must end with \r\n
 * Per RFC 2616, content-length: is not required but connection:close
 * would appear to be required (given that we will be closing it!).
 */
static void web_connection_parse_post(struct upnp_wps_device_sm *sm,
				      struct sockaddr_in *cli,
				      struct http_request *req,
				      const char *filename)
{
	enum http_reply_code ret;
	char *data = http_request_get_data(req); /* body of http msg */
	const char *action = NULL;
	size_t action_len = 0;
	const char *replyname = NULL; /* argument name for the reply */
	struct wpabuf *reply = NULL; /* data for the reply */

	if (os_strcasecmp(filename, UPNP_WPS_DEVICE_CONTROL_FILE)) {
		wpa_printf(MSG_INFO, "WPS UPnP: Invalid POST filename %s",
			   filename);
		ret = HTTP_NOT_FOUND;
		goto bad;
	}

	ret = UPNP_INVALID_ACTION;
	action = web_get_action(req, &action_len);
	if (action == NULL)
		goto bad;

	if (!os_strncasecmp("GetDeviceInfo", action, action_len))
		ret = web_process_get_device_info(sm, &reply, &replyname);
	else if (!os_strncasecmp("PutMessage", action, action_len))
		ret = web_process_put_message(sm, data, &reply, &replyname);
	else if (!os_strncasecmp("PutWLANResponse", action, action_len))
		ret = web_process_put_wlan_response(sm, data, &reply,
						    &replyname);
	else if (!os_strncasecmp("SetSelectedRegistrar", action, action_len))
		ret = web_process_set_selected_registrar(sm, cli, data, &reply,
							 &replyname);
	else
		wpa_printf(MSG_INFO, "WPS UPnP: Unknown POST type");

bad:
	if (ret != HTTP_OK)
		wpa_printf(MSG_INFO, "WPS UPnP: POST failure ret=%d", ret);
	web_connection_send_reply(req, ret, action, action_len, reply,
				  replyname);
	wpabuf_free(reply);
}
Exemplo n.º 8
0
static int ctrl_command(int s, int argc, char *argv[])
{
    const struct wlantest_cli_cmd *cmd, *match = NULL;
    int count = 0;
    int ret = 0;

    for (cmd = wlantest_cli_commands; cmd->cmd; cmd++) {
        if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0)
        {
            match = cmd;
            if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
                /* exact match */
                count = 1;
                break;
            }
            count++;
        }
    }

    if (count > 1) {
        printf("Ambiguous command '%s'; possible commands:", argv[0]);
        for (cmd = wlantest_cli_commands; cmd->cmd; cmd++) {
            if (os_strncasecmp(cmd->cmd, argv[0],
                               os_strlen(argv[0])) == 0) {
                printf(" %s", cmd->cmd);
            }
        }
        printf("\n");
        ret = 1;
    } else if (count == 0) {
        printf("Unknown command '%s'\n", argv[0]);
        ret = 1;
    } else {
        ret = match->handler(s, argc - 1, &argv[1]);
    }

    return ret;
}
Exemplo n.º 9
0
/* scanf does not support this           */
static c_bool
u_cfValueScanBoolean(
    c_char *dataPtr,
    c_bool *resultPtr)
{
    c_bool result = FALSE;
    size_t l;

    l = strspn(dataPtr, CF_SPACES);
    if (l <= strlen(dataPtr)) {
        if (os_strncasecmp(&dataPtr[l], "TRUE", 4) == 0) {
            *resultPtr = TRUE;
            result = TRUE;
        } else {
            if (os_strncasecmp(&dataPtr[l], "FALSE", 5) == 0) {
                *resultPtr = FALSE;
                result = TRUE;
            }
        }
    }

    return result;
}
Exemplo n.º 10
0
static char * wpa_cli_cmd_gen(const char *text, int state)
{
	static int i, len;
	const char *cmd;

	if (state == 0) {
		i = 0;
		len = os_strlen(text);
	}

	while ((cmd = wpa_cli_commands[i].cmd)) {
		i++;
		if (os_strncasecmp(cmd, text, len) == 0)
			return os_strdup(cmd);
	}

	return NULL;
}
static int cmd_has_sensitive_data(const char *cmd)
{
	const char *c, *delim;
	int n;
	size_t len;

	delim = os_strchr(cmd, ' ');
	if (delim)
		len = delim - cmd;
	else
		len = os_strlen(cmd);

	for (n = 0; (c = wpa_cli_commands[n].cmd); n++) {
		if (os_strncasecmp(cmd, c, len) == 0 && len == os_strlen(c))
			return (wpa_cli_commands[n].flags &
				cli_cmd_flag_sensitive);
	}
	return 0;
}
Exemplo n.º 12
0
/* httpread_hdr_line_get -- When file is ready, returns pointer
 * to line within header content matching the given tag
 * (after the tag itself and any spaces/tabs).
 *
 * The tag should end with a colon for reliable matching.
 *
 * If not found, returns NULL;
 */
char * httpread_hdr_line_get(struct httpread *h, const char *tag)
{
    int tag_len = os_strlen(tag);
    char *hdr = h->hdr;
    hdr = os_strchr(hdr, '\n');
    if (hdr == NULL)
        return NULL;
    hdr++;
    for (;;) {
        if (!os_strncasecmp(hdr, tag, tag_len)) {
            hdr += tag_len;
            while (*hdr == ' ' || *hdr == '\t')
                hdr++;
            return hdr;
        }
        hdr = os_strchr(hdr, '\n');
        if (hdr == NULL)
            return NULL;
        hdr++;
    }
}
Exemplo n.º 13
0
static const char * web_get_action(struct http_request *req,
				   size_t *action_len)
{
	const char *match;
	int match_len;
	char *b;
	char *action;

	*action_len = 0;
	/* The SOAPAction line of the header tells us what we want to do */
	b = http_request_get_hdr_line(req, "SOAPAction:");
	if (b == NULL)
		return NULL;
	if (*b == '"')
		b++;
	else
		return NULL;
	match = urn_wfawlanconfig;
	match_len = os_strlen(urn_wfawlanconfig) - 1;
	if (os_strncasecmp(b, match, match_len))
		return NULL;
	b += match_len;
	/* skip over version */
	while (isgraph(*b) && *b != '#')
		b++;
	if (*b != '#')
		return NULL;
	b++;
	/* Following the sharp(#) should be the action and a double quote */
	action = b;
	while (isgraph(*b) && *b != '"')
		b++;
	if (*b != '"')
		return NULL;
	*action_len = b - action;
	return action;
}
Exemplo n.º 14
0
u_char *
os_strcasestrn(u_char *s1, char *s2, size_t n)
{
    os_uint_t  c1, c2;

    c2 = (os_uint_t) *s2++;
    c2 = (c2 >= 'A' && c2 <= 'Z') ? (c2 | 0x20) : c2;

    do {
        do {
            c1 = (os_uint_t) *s1++;

            if (c1 == 0) {
                return NULL;
            }

            c1 = (c1 >= 'A' && c1 <= 'Z') ? (c1 | 0x20) : c1;

        } while (c1 != c2);

    } while (os_strncasecmp(s1, (u_char *) s2, n) != 0);

    return --s1;
}
static int hs20_process_icon_binary_file(struct wpa_supplicant *wpa_s,
					 const u8 *sa, const u8 *pos,
					 size_t slen)
{
	char fname[256];
	int png;
	FILE *f;
	u16 data_len;

	wpa_msg(wpa_s, MSG_INFO, "RX-HS20-ANQP " MACSTR " Icon Binary File",
		MAC2STR(sa));

	if (slen < 4) {
		wpa_dbg(wpa_s, MSG_DEBUG, "HS 2.0: Too short Icon Binary File "
			"value from " MACSTR, MAC2STR(sa));
		return -1;
	}

	wpa_printf(MSG_DEBUG, "HS 2.0: Download Status Code %u", *pos);
	if (*pos != 0)
		return -1;
	pos++;
	slen--;

	if ((size_t) 1 + pos[0] > slen) {
		wpa_dbg(wpa_s, MSG_DEBUG, "HS 2.0: Too short Icon Binary File "
			"value from " MACSTR, MAC2STR(sa));
		return -1;
	}
	wpa_hexdump_ascii(MSG_DEBUG, "Icon Type", pos + 1, pos[0]);
	png = os_strncasecmp((char *) pos + 1, "image/png", 9) == 0;
	slen -= 1 + pos[0];
	pos += 1 + pos[0];

	if (slen < 2) {
		wpa_dbg(wpa_s, MSG_DEBUG, "HS 2.0: Too short Icon Binary File "
			"value from " MACSTR, MAC2STR(sa));
		return -1;
	}
	data_len = WPA_GET_LE16(pos);
	pos += 2;
	slen -= 2;

	if (data_len > slen) {
		wpa_dbg(wpa_s, MSG_DEBUG, "HS 2.0: Too short Icon Binary File "
			"value from " MACSTR, MAC2STR(sa));
		return -1;
	}

	wpa_printf(MSG_DEBUG, "Icon Binary Data: %u bytes", data_len);
	if (wpa_s->conf->osu_dir == NULL)
		return -1;

	wpa_s->osu_icon_id++;
	if (wpa_s->osu_icon_id == 0)
		wpa_s->osu_icon_id++;
	snprintf(fname, sizeof(fname), "%s/osu-icon-%u.%s",
		 wpa_s->conf->osu_dir, wpa_s->osu_icon_id,
		 png ? "png" : "icon");
	f = fopen(fname, "wb");
	if (f == NULL)
		return -1;
	if (fwrite(pos, slen, 1, f) != 1) {
		fclose(f);
		unlink(fname);
		return -1;
	}
	fclose(f);

	wpa_msg(wpa_s, MSG_INFO, "RX-HS20-ANQP-ICON %s", fname);
	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;
}
Exemplo n.º 17
0
/*-----------------------------------------------------------------------------
Routine Name: wpa_driver_tista_driver_cmd
Routine Description: executes driver-specific commands
Arguments:
   priv - pointer to private data structure
   cmd - command
   buf - return buffer
   buf_len - buffer length
Return Value: actual buffer length - success, -1 - failure
-----------------------------------------------------------------------------*/
static int wpa_driver_tista_driver_cmd( void *priv, char *cmd, char *buf, size_t buf_len )
{
    struct wpa_driver_ti_data *drv = (struct wpa_driver_ti_data *)priv;
    int ret = -1, prev_events, flags;

    wpa_printf(MSG_DEBUG, "%s %s", __func__, cmd);

    if( os_strcasecmp(cmd, "start") == 0 ) {
        wpa_printf(MSG_DEBUG,"Start command");
        scan_exit(drv); /* Clear scan cache */
        ret = wpa_driver_tista_driver_start(priv);
        if( ret == 0 ) {
            drv->driver_is_loaded = TRUE;
            wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STARTED");
        }
        return( TI2WPA_STATUS(ret) );
    }

    TI_CHECK_DRIVER( drv->driver_is_loaded, -1 );

    if( os_strcasecmp(cmd, "stop") == 0 ) {
        wpa_printf(MSG_DEBUG,"Stop command");
        if ((wpa_driver_wext_get_ifflags(drv->wext, &flags) == 0) &&
                (flags & IFF_UP)) {
            wpa_printf(MSG_ERROR, "TI: %s when iface is UP", cmd);
            wpa_driver_wext_set_ifflags(drv->wext, flags & ~IFF_UP);
        }
        ret = wpa_driver_tista_driver_stop(priv);
        if( ret == 0 ) {
            scan_exit(drv); /* Clear scan cache */
            drv->driver_is_loaded = FALSE;
            wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STOPPED");
        }
    }
    if( os_strcasecmp(cmd, "reload") == 0 ) {
        wpa_printf(MSG_DEBUG,"Reload command");
        ret = 0;
        wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "HANGED");
    }
    else if( os_strcasecmp(cmd, "macaddr") == 0 ) {
        wpa_driver_tista_get_mac_addr(priv);
        wpa_printf(MSG_DEBUG, "Macaddr command");
        ret = sprintf(buf, "Macaddr = " MACSTR "\n", MAC2STR(drv->own_addr));
        wpa_printf(MSG_DEBUG, "buf %s", buf);
    }
    else if( os_strcasecmp(cmd, "scan-passive") == 0 ) {
        wpa_printf(MSG_DEBUG,"Scan Passive command");
        drv->scan_type =  SCAN_TYPE_NORMAL_PASSIVE;
        ret = 0;
    }
    else if( os_strcasecmp(cmd, "scan-active") == 0 ) {
        wpa_printf(MSG_DEBUG,"Scan Active command");
        drv->scan_type =  SCAN_TYPE_NORMAL_ACTIVE;
        ret = 0;
    }
    else if( os_strcasecmp(cmd, "scan-mode") == 0 ) {
        wpa_printf(MSG_DEBUG,"Scan Mode command");
        ret = snprintf(buf, buf_len, "ScanMode = %u\n", drv->scan_type);
        if (ret < (int)buf_len) {
            return( ret );
        }
    }
    else if( os_strcasecmp(cmd, "linkspeed") == 0 ) {
        struct wpa_supplicant *wpa_s = (struct wpa_supplicant *)(drv->ctx);

        wpa_printf(MSG_DEBUG,"Link Speed command");
        drv->link_speed = wpa_s->link_speed / 1000000;
        ret = sprintf(buf,"LinkSpeed %u\n", drv->link_speed);
        wpa_printf(MSG_DEBUG, "buf %s", buf);
    }
    else if( os_strncasecmp(cmd, "scan-channels", 13) == 0 ) {
        int noOfChan;

        noOfChan = atoi(cmd + 13);
        wpa_printf(MSG_DEBUG,"Scan Channels command = %d", noOfChan);
        if( (noOfChan > 0) && (noOfChan <= MAX_NUMBER_OF_CHANNELS_PER_SCAN) )
            drv->scan_channels = noOfChan;
        ret = sprintf(buf,"Scan-Channels = %d\n", drv->scan_channels);
        wpa_printf(MSG_DEBUG, "buf %s", buf);
    }
    else if( os_strcasecmp(cmd, "rssi-approx") == 0 ) {
        scan_result_t *cur_res;
        struct wpa_supplicant *wpa_s = (struct wpa_supplicant *)(drv->ctx);
        scan_ssid_t *p_ssid;
        int rssi, len;

        wpa_printf(MSG_DEBUG,"rssi-approx command");

        if( !wpa_s )
            return( ret );
        cur_res = scan_get_by_bssid(drv, wpa_s->bssid);
        if( cur_res ) {
            p_ssid = scan_get_ssid(cur_res);
            if( p_ssid ) {
                len = (int)(p_ssid->ssid_len);
                rssi = cur_res->level;
                if( (len > 0) && (len <= MAX_SSID_LEN) && (len < (int)buf_len)) {
                    os_memcpy((void *)buf, (void *)(p_ssid->ssid), len);
                    ret = len;
                    ret += snprintf(&buf[ret], buf_len-len, " rssi %d\n", rssi);
                }
            }
        }
    }
    else if( os_strcasecmp(cmd, "rssi") == 0 ) {
        u8 ssid[MAX_SSID_LEN];
        scan_result_t *cur_res;
        struct wpa_supplicant *wpa_s = (struct wpa_supplicant *)(drv->ctx);
        int rssi_data, rssi_beacon, len;

        wpa_printf(MSG_DEBUG,"rssi command");

        ret = wpa_driver_tista_get_rssi(priv, &rssi_data, &rssi_beacon);
        if( ret == 0 ) {
            len = wpa_driver_tista_get_ssid(priv, (u8 *)ssid);
            wpa_printf(MSG_DEBUG,"rssi_data %d rssi_beacon %d", rssi_data, rssi_beacon);
            if( (len > 0) && (len <= MAX_SSID_LEN) ) {
                os_memcpy((void *)buf, (void *)ssid, len);
                ret = len;
                ret += sprintf(&buf[ret], " rssi %d\n", rssi_beacon);
                wpa_printf(MSG_DEBUG, "buf %s", buf);
                /* Update cached value */
                if( !wpa_s )
                    return( ret );
                cur_res = scan_get_by_bssid(drv, wpa_s->bssid);
                if( cur_res )
                    cur_res->level = rssi_beacon;
            }
            else
            {
                wpa_printf(MSG_DEBUG, "Fail to get ssid when reporting rssi");
                ret = -1;
            }
        }
    }
    else if( os_strncasecmp(cmd, "powermode", 9) == 0 ) {
        u32 mode;
        TPowerMgr_PowerMode tMode;

        mode = (u32)atoi(cmd + 9);
        wpa_printf(MSG_DEBUG,"Power Mode command = %u", mode);
        if( mode < POWER_MODE_MAX )
        {
            tMode.PowerMode = (PowerMgr_PowerMode_e)mode;
            tMode.PowerMngPriority = POWER_MANAGER_USER_PRIORITY;
            ret = wpa_driver_tista_config_power_management( priv, &tMode, 1 );
        }
    }
    else if (os_strncasecmp(cmd, "getpower", 8) == 0 ) {
        u32 mode;
        TPowerMgr_PowerMode tMode;

        os_memset(&tMode, 0, sizeof(TPowerMgr_PowerMode));
        ret = wpa_driver_tista_config_power_management( priv, &tMode, 0 );
        if( ret == 0 ) {
            ret = sprintf(buf, "powermode = %u\n", tMode.PowerMode);
            wpa_printf(MSG_DEBUG, "buf %s", buf);
        }
    }
    else if( os_strncasecmp(cmd, "btcoexmode", 10) == 0 ) {
        u32 mode;

        mode = (u32)atoi(cmd + 10);
        wpa_printf(MSG_DEBUG,"BtCoex Mode command = %u", mode);
        ret = wpa_driver_tista_enable_bt_coe( priv, mode );
        if( ret == 0 ) {
            drv->btcoex_mode = mode;
        }
    }
    else if( os_strcasecmp(cmd, "btcoexstat") == 0 ) {
        u32 status = drv->btcoex_mode;

        wpa_printf(MSG_DEBUG,"BtCoex Status");
        ret = wpa_driver_tista_get_bt_coe_status( priv, &status );
        if( ret == 0 ) {
            ret = sprintf(buf, "btcoexstatus = 0x%x\n", status);
            wpa_printf(MSG_DEBUG, "buf %s", buf);
        }
    }
    else if( os_strcasecmp(cmd, "rxfilter-start") == 0 ) {
        wpa_printf(MSG_DEBUG,"Rx Data Filter Start command");
        ret = wpa_driver_tista_driver_enable_rx_data_filter( priv );
    }
    else if( os_strcasecmp(cmd, "rxfilter-stop") == 0 ) {
        wpa_printf(MSG_DEBUG,"Rx Data Filter Stop command");
        ret = wpa_driver_tista_driver_disable_rx_data_filter( priv );
    }
    else if( os_strcasecmp(cmd, "rxfilter-statistics") == 0 ) {
        TCuCommon_RxDataFilteringStatistics stats;
        int len, i;

        os_memset(&stats, 0, sizeof(TCuCommon_RxDataFilteringStatistics));
        wpa_printf(MSG_DEBUG,"Rx Data Filter Statistics command");
        ret = wpa_driver_tista_driver_rx_data_filter_statistics( priv, &stats );
        if( ret == 0 ) {
            ret = snprintf(buf, buf_len, "RxFilterStat: %u", (u32)stats.unmatchedPacketsCount);
            for(i=0; ( i < MAX_DATA_FILTERS ); i++) {
                ret += snprintf(&buf[ret], buf_len-ret, " %u", (u32)stats.matchedPacketsCount[i]);
            }
            ret += snprintf(&buf[ret], buf_len-ret, "\n");
            if (ret >= (int)buf_len) {
                ret = -1;
            }
        }
    }
    else if( os_strncasecmp(cmd, "rxfilter-add", 12) == 0 ) {
        TRxDataFilterRequest dfreq;
        char *cp = cmd + 12;
        char *endp;
        int type;

        if (*cp != '\0') {
            type = (int)strtol(cp, &endp, 0);
            if (endp != cp) {
                wpa_printf(MSG_DEBUG,"Rx Data Filter Add [%d] command", type);
                ret = prepare_filter_struct( priv, type, &dfreq );
                if( ret == 0 ) {
                    ret = wpa_driver_tista_driver_rx_data_filter( priv, &dfreq, 1 );
                }
            }
        }
    }
    else if( os_strncasecmp(cmd, "rxfilter-remove",15) == 0 ) {
        TRxDataFilterRequest dfreq;
        char *cp = cmd + 15;
        char *endp;
        int type;

        if (*cp != '\0') {
            type = (int)strtol(cp, &endp, 0);
            if (endp != cp) {
                wpa_printf(MSG_DEBUG,"Rx Data Filter remove [%d] command", type);
                ret = prepare_filter_struct( priv, type, &dfreq );
                if( ret == 0 ) {
                    ret = wpa_driver_tista_driver_rx_data_filter( priv, &dfreq, 0 );
                }
            }
        }
    }
    else {
        wpa_printf(MSG_DEBUG,"Unsupported command");
    }
    return ret;
}
Exemplo n.º 18
0
static int wpa_driver_priv_driver_cmd(void *priv, char *cmd, char *buf, size_t buf_len)
{

	struct wpa_driver_awext_data *drv = priv;
	int ret = -1;
	int flags;

	wpa_printf(MSG_DEBUG, "AWEXT: %s %s", __func__, cmd);

	if (os_strcasecmp(cmd, "start") == 0) {
		wpa_printf(MSG_DEBUG,"Start command");
		return (ret);
	}

	if (os_strcasecmp(cmd, "stop") == 0) {
		wpa_printf(MSG_DEBUG,"Stop command");
		if ((wpa_driver_awext_get_ifflags(drv, &flags) == 0) &&
		    (flags & IFF_UP)) {
			wpa_printf(MSG_ERROR, "WEXT: %s when iface is UP", cmd);
			wpa_driver_awext_set_ifflags(drv, flags & ~IFF_UP);
		}

	}
	else if (os_strcasecmp(cmd, "reload") == 0) {
		wpa_printf(MSG_DEBUG,"Reload command");
		wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "HANGED");
		return ret;
	}
	else if (os_strcasecmp(cmd, "macaddr") == 0) {
		struct ifreq ifr;
		os_memset(&ifr, 0, sizeof(ifr));
		os_strncpy(ifr.ifr_name, drv->ifname, IFNAMSIZ);

		if (ioctl(drv->ioctl_sock, SIOCGIFHWADDR, &ifr) < 0) {
			perror("ioctl[SIOCGIFHWADDR]");
			ret = -1;
		} else {
			u8 *macaddr = (u8 *) ifr.ifr_hwaddr.sa_data;
			ret = snprintf(buf, buf_len, "Macaddr = " MACSTR "\n",
			               MAC2STR(macaddr));
		}
	}
	else if (os_strcasecmp(cmd, "scan-passive") == 0) {
		wpa_printf(MSG_DEBUG,"Scan Passive command");
	}
	else if (os_strcasecmp(cmd, "scan-active") == 0) {
		wpa_printf(MSG_DEBUG,"Scan Active command");
	}
	else if (os_strcasecmp(cmd, "linkspeed") == 0) {
		struct iwreq wrq;
		unsigned int linkspeed;
		os_strncpy(wrq.ifr_name, drv->ifname, IFNAMSIZ);
		wpa_printf(MSG_DEBUG,"Link Speed command");
		if (ioctl(drv->ioctl_sock, SIOCGIWRATE, &wrq) < 0) {
			perror("ioctl[SIOCGIWRATE]");
			ret = -1;
		} else {
			linkspeed = wrq.u.bitrate.value / 1000000;
			ret = snprintf(buf, buf_len, "LinkSpeed %d\n", linkspeed);
		}
	}
	else if (os_strncasecmp(cmd, "scan-channels", 13) == 0) {
	}
	else if ((os_strcasecmp(cmd, "rssi") == 0) || (os_strcasecmp(cmd, "rssi-approx") == 0)) {
		struct iwreq wrq;
		struct iw_statistics stats;
		signed int rssi;
		wpa_printf(MSG_DEBUG, ">>>. DRIVER AWEXT RSSI ");
		wrq.u.data.pointer = (caddr_t) &stats;
		wrq.u.data.length = sizeof(stats);
		wrq.u.data.flags = 1; /* Clear updated flag */
		strncpy(wrq.ifr_name, drv->ifname, IFNAMSIZ);

		if (ioctl(drv->ioctl_sock, SIOCGIWSTATS, &wrq) < 0) {
			perror("ioctl[SIOCGIWSTATS]");
			ret = -1;
		} else {
			if (stats.qual.updated & IW_QUAL_DBM) {
				/* Values in dBm, stored in u8 with range 63 : -192 */
				rssi = ( stats.qual.level > 63 ) ?
					stats.qual.level - 0x100 :
					stats.qual.level;
			} else {
				rssi = stats.qual.level;
			}

			if (drv->ssid_len != 0 && drv->ssid_len < buf_len) {
				os_memcpy((void *) buf, (void *) (drv->ssid),
						drv->ssid_len );
				ret = drv->ssid_len;
				ret += snprintf(&buf[ret], buf_len-ret,
						" rssi %d\n", rssi);
				if (ret < (int)buf_len) {
					return( ret );
				}
				ret = -1;
			}
		}
	}
	else if (os_strncasecmp(cmd, "powermode", 9) == 0) {
	}
	else if (os_strncasecmp(cmd, "getpower", 8) == 0) {
	}
	else if (os_strncasecmp(cmd, "get-rts-threshold", 17) == 0) {
		struct iwreq wrq;
		unsigned int rtsThreshold;

		strncpy(wrq.ifr_name, drv->ifname, IFNAMSIZ);

		if (ioctl(drv->ioctl_sock, SIOCGIWRTS, &wrq) < 0) {
			perror("ioctl[SIOCGIWRTS]");
			ret = -1;
		} else {
			rtsThreshold = wrq.u.rts.value;
			wpa_printf(MSG_DEBUG,"Get RTS Threshold command = %d",
				rtsThreshold);
			ret = snprintf(buf, buf_len, "rts-threshold = %u\n",
				rtsThreshold);
			if (ret < (int)buf_len) {
				return( ret );
			}
		}
	}
	else if (os_strncasecmp(cmd, "set-rts-threshold", 17) == 0) {
		struct iwreq wrq;
		unsigned int rtsThreshold;
		char *cp = cmd + 17;
		char *endp;

		strncpy(wrq.ifr_name, drv->ifname, IFNAMSIZ);

		if (*cp != '\0') {
			rtsThreshold = (unsigned int)strtol(cp, &endp, 0);
		if (endp != cp) {
				wrq.u.rts.value = rtsThreshold;
				wrq.u.rts.fixed = 1;
				wrq.u.rts.disabled = 0;

				if (ioctl(drv->ioctl_sock, SIOCSIWRTS, &wrq) < 0) {
					perror("ioctl[SIOCGIWRTS]");
					ret = -1;
				} else {
					rtsThreshold = wrq.u.rts.value;
					wpa_printf(MSG_DEBUG,"Set RTS Threshold command = %d", rtsThreshold);
					ret = 0;
				}
			}
		}
	}
	else if (os_strcasecmp(cmd, "btcoexscan-start") == 0) {
	}
	else if (os_strcasecmp(cmd, "btcoexscan-stop") == 0) {
	}
	else if (os_strcasecmp(cmd, "rxfilter-start") == 0) {
		wpa_printf(MSG_DEBUG,"Rx Data Filter Start command");
	}
	else if (os_strcasecmp(cmd, "rxfilter-stop") == 0) {
		wpa_printf(MSG_DEBUG,"Rx Data Filter Stop command");
	}
	else if (os_strcasecmp(cmd, "rxfilter-statistics") == 0) {
	}
	else if (os_strncasecmp(cmd, "rxfilter-add", 12) == 0 ) {
	}
	else if (os_strncasecmp(cmd, "rxfilter-remove",15) == 0) {
	}
	else if (os_strcasecmp(cmd, "snr") == 0) {
		struct iwreq wrq;
		struct iw_statistics stats;
		int snr, rssi, noise;

		wrq.u.data.pointer = (caddr_t) &stats;
		wrq.u.data.length = sizeof(stats);
		wrq.u.data.flags = 1; /* Clear updated flag */
		strncpy(wrq.ifr_name, drv->ifname, IFNAMSIZ);

		if (ioctl(drv->ioctl_sock, SIOCGIWSTATS, &wrq) < 0) {
			perror("ioctl[SIOCGIWSTATS]");
			ret = -1;
		} else {
			if (stats.qual.updated & IW_QUAL_DBM) {
				/* Values in dBm, stored in u8 with range 63 : -192 */
				rssi = ( stats.qual.level > 63 ) ?
					stats.qual.level - 0x100 :
					stats.qual.level;
				noise = ( stats.qual.noise > 63 ) ?
					stats.qual.noise - 0x100 :
					stats.qual.noise;
			} else {
				rssi = stats.qual.level;
				noise = stats.qual.noise;
			}

			snr = rssi - noise;

			ret = snprintf(buf, buf_len, "snr = %u\n", (unsigned int)snr);
			if (ret < (int)buf_len) {
				return( ret );
			}
		}
	}
	else if (os_strncasecmp(cmd, "btcoexmode", 10) == 0) {
	}
	else if( os_strcasecmp(cmd, "btcoexstat") == 0 ) {
	}
	else {
		wpa_printf(MSG_DEBUG,"Unsupported command");
	}
	return (ret);
}
Exemplo n.º 19
0
static void wps_er_ssdp_rx(int sd, void *eloop_ctx, void *sock_ctx)
{
	struct wps_er *er = eloop_ctx;
	struct sockaddr_in addr; /* client address */
	socklen_t addr_len;
	int nread;
	char buf[MULTICAST_MAX_READ], *pos, *pos2, *start;
	int wfa = 0, byebye = 0;
	int max_age = -1;
	char *location = NULL;
	u8 uuid[WPS_UUID_LEN];

	addr_len = sizeof(addr);
	nread = recvfrom(sd, buf, sizeof(buf) - 1, 0,
			 (struct sockaddr *) &addr, &addr_len);
	if (nread <= 0)
		return;
	buf[nread] = '\0';
	if (er->filter_addr.s_addr &&
	    er->filter_addr.s_addr != addr.sin_addr.s_addr)
		return;

	wpa_printf(MSG_DEBUG, "WPS ER: Received SSDP from %s",
		   inet_ntoa(addr.sin_addr));
	wpa_hexdump_ascii(MSG_MSGDUMP, "WPS ER: Received SSDP contents",
			  (u8 *) buf, nread);

	if (sd == er->multicast_sd) {
		/* Reply to M-SEARCH */
		if (os_strncmp(buf, "HTTP/1.1 200 OK", 15) != 0)
			return; /* unexpected response header */
	} else {
		/* Unsolicited message (likely NOTIFY or M-SEARCH) */
		if (os_strncmp(buf, "NOTIFY ", 7) != 0)
			return; /* only process notifications */
	}

	os_memset(uuid, 0, sizeof(uuid));

	for (start = buf; start && *start; start = pos) {
		pos = os_strchr(start, '\n');
		if (pos) {
			if (pos[-1] == '\r')
				pos[-1] = '\0';
			*pos++ = '\0';
		}
		if (os_strstr(start, "schemas-wifialliance-org:device:"
			      "WFADevice:1"))
			wfa = 1;
		if (os_strstr(start, "schemas-wifialliance-org:service:"
			      "WFAWLANConfig:1"))
			wfa = 1;
		if (os_strncasecmp(start, "LOCATION:", 9) == 0) {
			start += 9;
			while (*start == ' ')
				start++;
			location = start;
		} else if (os_strncasecmp(start, "NTS:", 4) == 0) {
			if (os_strstr(start, "ssdp:byebye"))
				byebye = 1;
		} else if (os_strncasecmp(start, "CACHE-CONTROL:", 14) == 0) {
			start += 9;
			while (*start == ' ')
				start++;
			pos2 = os_strstr(start, "max-age=");
			if (pos2 == NULL)
				continue;
			pos2 += 8;
			max_age = atoi(pos2);
		} else if (os_strncasecmp(start, "USN:", 4) == 0) {
			start += 4;
			pos2 = os_strstr(start, "uuid:");
			if (pos2) {
				pos2 += 5;
				while (*pos2 == ' ')
					pos2++;
				if (uuid_str2bin(pos2, uuid) < 0) {
					wpa_printf(MSG_DEBUG, "WPS ER: "
						   "Invalid UUID in USN: %s",
						   pos2);
					return;
				}
			}
		}
	}

	if (!wfa)
		return; /* Not WPS advertisement/reply */

	if (byebye) {
		wps_er_ap_remove(er, &addr.sin_addr);
		return;
	}

	if (!location)
		return; /* Unknown location */

	if (max_age < 1)
		return; /* No max-age reported */

	wpa_printf(MSG_DEBUG, "WPS ER: AP discovered: %s "
		   "(packet source: %s  max-age: %d)",
		   location, inet_ntoa(addr.sin_addr), max_age);

	wps_er_ap_add(er, uuid, &addr.sin_addr, location, max_age);
}
Exemplo n.º 20
0
static int hs20_process_icon_binary_file(struct wpa_supplicant *wpa_s,
					 const u8 *sa, const u8 *pos,
					 size_t slen, u8 dialog_token)
{
	char fname[256];
	int png;
	FILE *f;
	u16 data_len;
	struct icon_entry *icon;

	dl_list_for_each(icon, &wpa_s->icon_head, struct icon_entry, list) {
		if (icon->dialog_token == dialog_token && !icon->image &&
		    os_memcmp(icon->bssid, sa, ETH_ALEN) == 0) {
			icon->image = os_malloc(slen);
			if (!icon->image)
				return -1;
			os_memcpy(icon->image, pos, slen);
			icon->image_len = slen;
			hs20_remove_duplicate_icons(wpa_s, icon);
			wpa_msg(wpa_s, MSG_INFO,
				RX_HS20_ICON MACSTR " %s %u",
				MAC2STR(sa), icon->file_name,
				(unsigned int) icon->image_len);
			return 0;
		}
	}

	wpa_msg(wpa_s, MSG_INFO, RX_HS20_ANQP MACSTR " Icon Binary File",
		MAC2STR(sa));

	if (slen < 4) {
		wpa_dbg(wpa_s, MSG_DEBUG, "HS 2.0: Too short Icon Binary File "
			"value from " MACSTR, MAC2STR(sa));
		return -1;
	}

	wpa_printf(MSG_DEBUG, "HS 2.0: Download Status Code %u", *pos);
	if (*pos != 0)
		return -1;
	pos++;
	slen--;

	if ((size_t) 1 + pos[0] > slen) {
		wpa_dbg(wpa_s, MSG_DEBUG, "HS 2.0: Too short Icon Binary File "
			"value from " MACSTR, MAC2STR(sa));
		return -1;
	}
	wpa_hexdump_ascii(MSG_DEBUG, "Icon Type", pos + 1, pos[0]);
	png = os_strncasecmp((char *) pos + 1, "image/png", 9) == 0;
	slen -= 1 + pos[0];
	pos += 1 + pos[0];

	if (slen < 2) {
		wpa_dbg(wpa_s, MSG_DEBUG, "HS 2.0: Too short Icon Binary File "
			"value from " MACSTR, MAC2STR(sa));
		return -1;
	}
	data_len = WPA_GET_LE16(pos);
	pos += 2;
	slen -= 2;

	if (data_len > slen) {
		wpa_dbg(wpa_s, MSG_DEBUG, "HS 2.0: Too short Icon Binary File "
			"value from " MACSTR, MAC2STR(sa));
		return -1;
	}

	wpa_printf(MSG_DEBUG, "Icon Binary Data: %u bytes", data_len);
	if (wpa_s->conf->osu_dir == NULL)
		return -1;

	wpa_s->osu_icon_id++;
	if (wpa_s->osu_icon_id == 0)
		wpa_s->osu_icon_id++;
	snprintf(fname, sizeof(fname), "%s/osu-icon-%u.%s",
		 wpa_s->conf->osu_dir, wpa_s->osu_icon_id,
		 png ? "png" : "icon");
	f = fopen(fname, "wb");
	if (f == NULL)
		return -1;

	hs20_set_osu_access_permission(wpa_s->conf->osu_dir, fname);

	if (fwrite(pos, slen, 1, f) != 1) {
		fclose(f);
		unlink(fname);
		return -1;
	}
	fclose(f);

	wpa_msg(wpa_s, MSG_INFO, RX_HS20_ANQP_ICON "%s", fname);
	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;
	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;
}
Exemplo n.º 22
0
static void wpa_cli_interactive(void)
{
#define max_args 10
	char cmdbuf[256], *cmd, *argv[max_args], *pos;
	int argc;
#ifdef CONFIG_READLINE
	char *home, *hfile = NULL;
#endif /* CONFIG_READLINE */

	printf("\nInteractive mode\n\n");

#ifdef CONFIG_READLINE
	rl_attempted_completion_function = wpa_cli_completion;
	home = getenv("HOME");
	if (home) {
		const char *fname = ".wpa_cli_history";
		int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1;
		hfile = os_malloc(hfile_len);
		if (hfile) {
			os_snprintf(hfile, hfile_len, "%s/%s", home, fname);
			hfile[hfile_len - 1] = '\0';
			read_history(hfile);
			stifle_history(100);
		}
	}
#endif /* CONFIG_READLINE */

	do {
		wpa_cli_recv_pending(monitor_conn, 0, 0);
#ifndef CONFIG_NATIVE_WINDOWS
		alarm(1);
#endif /* CONFIG_NATIVE_WINDOWS */
#ifdef CONFIG_READLINE
		cmd = readline("> ");
		if (cmd && *cmd) {
			HIST_ENTRY *h;
			while (next_history())
				;
			h = previous_history();
			if (h == NULL || os_strcmp(cmd, h->line) != 0)
				add_history(cmd);
			next_history();
		}
#else /* CONFIG_READLINE */
		printf("> ");
		cmd = fgets(cmdbuf, sizeof(cmdbuf), stdin);
#endif /* CONFIG_READLINE */
#ifndef CONFIG_NATIVE_WINDOWS
		alarm(0);
#endif /* CONFIG_NATIVE_WINDOWS */
		if (cmd == NULL)
			break;
		wpa_cli_recv_pending(monitor_conn, 0, 0);
		pos = cmd;
		while (*pos != '\0') {
			if (*pos == '\n') {
				*pos = '\0';
				break;
			}
			pos++;
		}
		argc = 0;
		pos = cmd;
		for (;;) {
			while (*pos == ' ')
				pos++;
			if (*pos == '\0')
				break;
			argv[argc] = pos;
			argc++;
			if (argc == max_args)
				break;
			if (*pos == '"') {
				char *pos2 = os_strrchr(pos, '"');
				if (pos2)
					pos = pos2 + 1;
			}
			while (*pos != '\0' && *pos != ' ')
				pos++;
			if (*pos == ' ')
				*pos++ = '\0';
		}
		if (argc)
			wpa_request(ctrl_conn, argc, argv);

		if (cmd != cmdbuf)
			os_free(cmd);
	} while (!wpa_cli_quit);

#ifdef CONFIG_READLINE
	if (hfile) {
		/* Save command history, excluding lines that may contain
		 * passwords. */
		HIST_ENTRY *h;
		history_set_pos(0);
		h = next_history();
		while (h) {
			char *p = h->line;
			while (*p == ' ' || *p == '\t')
				p++;
			if (os_strncasecmp(p, "pa", 2) == 0 ||
			    os_strncasecmp(p, "o", 1) == 0 ||
			    os_strncasecmp(p, "n", 1)) {
				h = remove_history(where_history());
				if (h) {
					os_free(h->line);
					os_free(h->data);
					os_free(h);
				}
				h = current_history();
			} else {
				h = next_history();
			}
		}
		write_history(hfile);
		os_free(hfile);
	}
#endif /* CONFIG_READLINE */
}
static void wpa_cli_reconnect(void)
{
	wpa_cli_close_connection();
	ctrl_conn = wpa_cli_open_connection(ctrl_ifname);
	if (ctrl_conn) {
		printf("Connection to wpa_supplicant re-established\n");
#ifdef ANDROID
		if (wpa_ctrl_attach(monitor_conn) == 0) {
#else
		if (wpa_ctrl_attach(ctrl_conn) == 0) {
#endif
			wpa_cli_attached = 1;
		} else {
			printf("Warning: Failed to attach to "
			       "wpa_supplicant.\n");
		}
	}
}


static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int in_read,
				 int action_monitor)
{
	int first = 1;
#ifdef ANDROID
	if (ctrl == NULL) {
#else
	if (ctrl_conn == NULL) {
#endif 
		wpa_cli_reconnect();
		return;
	}
	while (wpa_ctrl_pending(ctrl) > 0) {
		char buf[256];
		size_t len = sizeof(buf) - 1;
		if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
			buf[len] = '\0';
			if (action_monitor)
				wpa_cli_action_process(buf);
			else {
				if (in_read && first)
					printf("\n");
				first = 0;
				printf("%s\n", buf);
			}
		} else {
			printf("Could not read pending message.\n");
			break;
		}
	}

	if (wpa_ctrl_pending(ctrl) < 0) {
		printf("Connection to wpa_supplicant lost - trying to "
		       "reconnect\n");
		wpa_cli_reconnect();
	}
}


#ifdef CONFIG_READLINE
static char * wpa_cli_cmd_gen(const char *text, int state)
{
	static int i, len;
	const char *cmd;

	if (state == 0) {
		i = 0;
		len = os_strlen(text);
	}

	while ((cmd = wpa_cli_commands[i].cmd)) {
		i++;
		if (os_strncasecmp(cmd, text, len) == 0)
			return os_strdup(cmd);
	}

	return NULL;
}


static char * wpa_cli_dummy_gen(const char *text, int state)
{
	return NULL;
}


static char ** wpa_cli_completion(const char *text, int start, int end)
{
	return rl_completion_matches(text, start == 0 ?
				     wpa_cli_cmd_gen : wpa_cli_dummy_gen);
}
#endif /* CONFIG_READLINE */


static void wpa_cli_interactive(void)
{
#define max_args 10
	char cmdbuf[256], *cmd, *argv[max_args], *pos;
	int argc;
#ifdef CONFIG_READLINE
	char *home, *hfile = NULL;
#endif /* CONFIG_READLINE */

	printf("\nInteractive mode\n\n");

#ifdef CONFIG_READLINE
	rl_attempted_completion_function = wpa_cli_completion;
	home = getenv("HOME");
	if (home) {
		const char *fname = ".wpa_cli_history";
		int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1;
		hfile = os_malloc(hfile_len);
		if (hfile) {
			int res;
			res = os_snprintf(hfile, hfile_len, "%s/%s", home,
					  fname);
			if (res >= 0 && res < hfile_len) {
				hfile[hfile_len - 1] = '\0';
				read_history(hfile);
				stifle_history(100);
			}
		}
	}
#endif /* CONFIG_READLINE */

	do {
#ifdef ANDROID
		wpa_cli_recv_pending(monitor_conn, 0, 0);
#else
		wpa_cli_recv_pending(ctrl_conn, 0, 0);
#endif
#ifndef CONFIG_NATIVE_WINDOWS
		alarm(ping_interval);
#endif /* CONFIG_NATIVE_WINDOWS */
#ifdef CONFIG_READLINE
		cmd = readline("> ");
		if (cmd && *cmd) {
			HIST_ENTRY *h;
			while (next_history())
				;
			h = previous_history();
			if (h == NULL || os_strcmp(cmd, h->line) != 0)
				add_history(cmd);
			next_history();
		}
#else /* CONFIG_READLINE */
		printf("> ");
		cmd = fgets(cmdbuf, sizeof(cmdbuf), stdin);
#endif /* CONFIG_READLINE */
#ifndef CONFIG_NATIVE_WINDOWS
		alarm(0);
#endif /* CONFIG_NATIVE_WINDOWS */
		if (cmd == NULL)
			break;
#ifdef ANDROID
		wpa_cli_recv_pending(monitor_conn, 0, 0);
#else
		wpa_cli_recv_pending(ctrl_conn, 0, 0);
#endif
		pos = cmd;
		while (*pos != '\0') {
			if (*pos == '\n') {
				*pos = '\0';
				break;
			}
			pos++;
		}
		argc = 0;
		pos = cmd;
		for (;;) {
			while (*pos == ' ')
				pos++;
			if (*pos == '\0')
				break;
			argv[argc] = pos;
			argc++;
			if (argc == max_args)
				break;
			if (*pos == '"') {
				char *pos2 = os_strrchr(pos, '"');
				if (pos2)
					pos = pos2 + 1;
			}
			while (*pos != '\0' && *pos != ' ')
				pos++;
			if (*pos == ' ')
				*pos++ = '\0';
		}
		if (argc)
			wpa_request(ctrl_conn, argc, argv);

		if (cmd != cmdbuf)
			os_free(cmd);
	} while (!wpa_cli_quit);

#ifdef CONFIG_READLINE
	if (hfile) {
		/* Save command history, excluding lines that may contain
		 * passwords. */
		HIST_ENTRY *h;
		history_set_pos(0);
		while ((h = current_history())) {
			char *p = h->line;
			while (*p == ' ' || *p == '\t')
				p++;
			if (cmd_has_sensitive_data(p)) {
				h = remove_history(where_history());
				if (h) {
					os_free(h->line);
					os_free(h->data);
					os_free(h);
				} else
					next_history();
			} else
				next_history();
		}
		write_history(hfile);
		os_free(hfile);
	}
#endif /* CONFIG_READLINE */
}
Exemplo n.º 24
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;
}
Exemplo n.º 25
0
/* subscr_addr_add_url -- add address(es) for one url to subscription */
static void subscr_addr_add_url(struct subscription *s, const char *url,
				size_t url_len)
{
	int alloc_len;
	char *scratch_mem = NULL;
	char *mem;
	char *domain_and_port;
	char *delim;
	char *path;
	char *domain;
	int port = 80;  /* port to send to (default is port 80) */
	struct addrinfo hints;
	struct addrinfo *result = NULL;
	struct addrinfo *rp;
	int rerr;

	/* url MUST begin with http: */
	if (url_len < 7 || os_strncasecmp(url, "http://", 7))
		goto fail;
	url += 7;
	url_len -= 7;

	/* allocate memory for the extra stuff we need */
	alloc_len = 2 * (url_len + 1);
	scratch_mem = os_zalloc(alloc_len);
	if (scratch_mem == NULL)
		goto fail;
	mem = scratch_mem;
	os_strncpy(mem, url, url_len);
	wpa_printf(MSG_DEBUG, "WPS UPnP: Adding URL '%s'", mem);
	domain_and_port = mem;
	mem += 1 + os_strlen(mem);
	delim = os_strchr(domain_and_port, '/');
	if (delim) {
		*delim++ = 0;   /* null terminate domain and port */
		path = delim;
	} else {
		path = domain_and_port + os_strlen(domain_and_port);
	}
	domain = mem;
	strcpy(domain, domain_and_port);
	delim = os_strchr(domain, ':');
	if (delim) {
		*delim++ = 0;   /* null terminate domain */
		if (isdigit(*delim))
			port = atol(delim);
	}

	/*
	 * getaddrinfo does the right thing with dotted decimal notations, or
	 * will resolve domain names. Resolving domain names will unfortunately
	 * hang the entire program until it is resolved or it times out
	 * internal to getaddrinfo; fortunately we think that the use of actual
	 * domain names (vs. dotted decimal notations) should be uncommon.
	 */
	os_memset(&hints, 0, sizeof(struct addrinfo));
	hints.ai_family = AF_INET;      /* IPv4 */
	hints.ai_socktype = SOCK_STREAM;
#if NO_DOMAIN_NAME_RESOLUTION
	/* Suppress domain name resolutions that would halt
	 * the program for periods of time
	 */
	hints.ai_flags = AI_NUMERICHOST;
#else
	/* Allow domain name resolution. */
	hints.ai_flags = 0;
#endif
	hints.ai_protocol = 0;          /* Any protocol? */
	rerr = getaddrinfo(domain, NULL /* fill in port ourselves */,
			   &hints, &result);
	if (rerr) {
		wpa_printf(MSG_INFO, "WPS UPnP: Resolve error %d (%s) on: %s",
			   rerr, gai_strerror(rerr), domain);
		goto fail;
	}
	for (rp = result; rp; rp = rp->ai_next) {
		struct subscr_addr *a;

		/* Limit no. of address to avoid denial of service attack */
		if (dl_list_len(&s->addr_list) >= MAX_ADDR_PER_SUBSCRIPTION) {
			wpa_printf(MSG_INFO, "WPS UPnP: subscr_addr_add_url: "
				   "Ignoring excessive addresses");
			break;
		}

		a = os_zalloc(sizeof(*a) + alloc_len);
		if (a == NULL)
			continue;
		mem = (void *) (a + 1);
		a->domain_and_port = mem;
		strcpy(mem, domain_and_port);
		mem += 1 + strlen(mem);
		a->path = mem;
		if (path[0] != '/')
			*mem++ = '/';
		strcpy(mem, path);
		mem += 1 + os_strlen(mem);
		os_memcpy(&a->saddr, rp->ai_addr, sizeof(a->saddr));
		a->saddr.sin_port = htons(port);

		dl_list_add(&s->addr_list, &a->list);
	}

fail:
	if (result)
		freeaddrinfo(result);
	os_free(scratch_mem);
}
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;
}
Exemplo n.º 27
0
/* httpread_read_handler -- called when socket ready to read
 *
 * Note: any extra data we read past end of transmitted file is ignored;
 * if we were to support keeping connections open for multiple files then
 * this would have to be addressed.
 */
static void httpread_read_handler(int sd, void *eloop_ctx, void *sock_ctx)
{
    struct httpread *h = sock_ctx;
    int nread;
    char *rbp;      /* pointer into read buffer */
    char *hbp;      /* pointer into header buffer */
    char *bbp;      /* pointer into body buffer */
    char readbuf[HTTPREAD_READBUF_SIZE];  /* temp use to read into */

    if (httpread_debug >= 20)
        wpa_printf(MSG_DEBUG, "ENTER httpread_read_handler(%p)", h);

    /* read some at a time, then search for the interal
     * boundaries between header and data and etc.
     */
    nread = read(h->sd, readbuf, sizeof(readbuf));
    if (nread < 0)
        goto bad;
    if (nread == 0) {
        /* end of transmission... this may be normal
         * or may be an error... in some cases we can't
         * tell which so we must assume it is normal then.
         */
        if (!h->got_hdr) {
            /* Must at least have completed header */
            wpa_printf(MSG_DEBUG, "httpread premature eof(%p)", h);
            goto bad;
        }
        if (h->chunked || h->got_content_length) {
            /* Premature EOF; e.g. dropped connection */
            wpa_printf(MSG_DEBUG,
                       "httpread premature eof(%p) %d/%d",
                       h, h->body_nbytes,
                       h->content_length);
            goto bad;
        }
        /* No explicit length, hopefully we have all the data
         * although dropped connections can cause false
         * end
         */
        if (httpread_debug >= 10)
            wpa_printf(MSG_DEBUG, "httpread ok eof(%p)", h);
        h->got_body = 1;
        goto got_file;
    }
    rbp = readbuf;

    /* Header consists of text lines (terminated by both CR and LF)
     * and an empty line (CR LF only).
     */
    if (!h->got_hdr) {
        hbp = h->hdr + h->hdr_nbytes;
        /* add to headers until:
         *      -- we run out of data in read buffer
         *      -- or, we run out of header buffer room
         *      -- or, we get double CRLF in headers
         */
        for (;;) {
            if (nread == 0)
                goto get_more;
            if (h->hdr_nbytes == HTTPREAD_HEADER_MAX_SIZE) {
                goto bad;
            }
            *hbp++ = *rbp++;
            nread--;
            h->hdr_nbytes++;
            if (h->hdr_nbytes >= 4 &&
                    hbp[-1] == '\n' &&
                    hbp[-2] == '\r' &&
                    hbp[-3] == '\n' &&
                    hbp[-4] == '\r' ) {
                h->got_hdr = 1;
                *hbp = 0;       /* null terminate */
                break;
            }
        }
        /* here we've just finished reading the header */
        if (httpread_hdr_analyze(h)) {
            wpa_printf(MSG_DEBUG, "httpread bad hdr(%p)", h);
            goto bad;
        }
        if (h->max_bytes == 0) {
            if (httpread_debug >= 10)
                wpa_printf(MSG_DEBUG,
                           "httpread no body hdr end(%p)", h);
            goto got_file;
        }
        if (h->got_content_length && h->content_length == 0) {
            if (httpread_debug >= 10)
                wpa_printf(MSG_DEBUG,
                           "httpread zero content length(%p)",
                           h);
            goto got_file;
        }
    }

    /* Certain types of requests never have data and so
     * must be specially recognized.
     */
    if (!os_strncasecmp(h->hdr, "SUBSCRIBE", 9) ||
            !os_strncasecmp(h->hdr, "UNSUBSCRIBE", 11) ||
            !os_strncasecmp(h->hdr, "HEAD", 4) ||
            !os_strncasecmp(h->hdr, "GET", 3)) {
        if (!h->got_body) {
            if (httpread_debug >= 10)
                wpa_printf(MSG_DEBUG,
                           "httpread NO BODY for sp. type");
        }
        h->got_body = 1;
        goto got_file;
    }

    /* Data can be just plain binary data, or if "chunked"
     * consists of chunks each with a header, ending with
     * an ending header.
     */
    if (!h->got_body) {
        /* Here to get (more of) body */
        /* ensure we have enough room for worst case for body
         * plus a null termination character
         */
        if (h->body_alloc_nbytes < (h->body_nbytes + nread + 1)) {
            char *new_body;
            int new_alloc_nbytes;

            if (h->body_nbytes >= h->max_bytes)
                goto bad;
            new_alloc_nbytes = h->body_alloc_nbytes +
                               HTTPREAD_BODYBUF_DELTA;
            /* For content-length case, the first time
             * through we allocate the whole amount
             * we need.
             */
            if (h->got_content_length &&
                    new_alloc_nbytes < (h->content_length + 1))
                new_alloc_nbytes = h->content_length + 1;
            if ((new_body = os_realloc(h->body, new_alloc_nbytes))
                    == NULL)
                goto bad;

            h->body = new_body;
            h->body_alloc_nbytes = new_alloc_nbytes;
        }
        /* add bytes */
        bbp = h->body + h->body_nbytes;
        for (;;) {
            int ncopy;
            /* See if we need to stop */
            if (h->chunked && h->in_chunk_data == 0) {
                /* in chunk header */
                char *cbp = h->body + h->chunk_start;
                if (bbp-cbp >= 2 && bbp[-2] == '\r' &&
                        bbp[-1] == '\n') {
                    /* end of chunk hdr line */
                    /* hdr line consists solely
                     * of a hex numeral and CFLF
                     */
                    if (!isxdigit(*cbp))
                        goto bad;
                    h->chunk_size = strtoul(cbp, NULL, 16);
                    /* throw away chunk header
                     * so we have only real data
                     */
                    h->body_nbytes = h->chunk_start;
                    bbp = cbp;
                    if (h->chunk_size == 0) {
                        /* end of chunking */
                        /* trailer follows */
                        h->in_trailer = 1;
                        if (httpread_debug >= 20)
                            wpa_printf(
                                MSG_DEBUG,
                                "httpread end chunks(%p)", h);
                        break;
                    }
                    h->in_chunk_data = 1;
                    /* leave chunk_start alone */
                }
            } else if (h->chunked) {
                /* in chunk data */
                if ((h->body_nbytes - h->chunk_start) ==
                        (h->chunk_size + 2)) {
                    /* end of chunk reached,
                     * new chunk starts
                     */
                    /* check chunk ended w/ CRLF
                     * which we'll throw away
                     */
                    if (bbp[-1] == '\n' &&
                            bbp[-2] == '\r') {
                    } else
                        goto bad;
                    h->body_nbytes -= 2;
                    bbp -= 2;
                    h->chunk_start = h->body_nbytes;
                    h->in_chunk_data = 0;
                    h->chunk_size = 0; /* just in case */
                }
            } else if (h->got_content_length &&
                       h->body_nbytes >= h->content_length) {
                h->got_body = 1;
                if (httpread_debug >= 10)
                    wpa_printf(
                        MSG_DEBUG,
                        "httpread got content(%p)", h);
                goto got_file;
            }
            if (nread <= 0)
                break;
            /* Now transfer. Optimize using memcpy where we can. */
            if (h->chunked && h->in_chunk_data) {
                /* copy up to remainder of chunk data
                 * plus the required CR+LF at end
                 */
                ncopy = (h->chunk_start + h->chunk_size + 2) -
                        h->body_nbytes;
            } else if (h->chunked) {
                /*in chunk header -- don't optimize */
                *bbp++ = *rbp++;
                nread--;
                h->body_nbytes++;
                continue;
            } else if (h->got_content_length) {
                ncopy = h->content_length - h->body_nbytes;
            } else {
                ncopy = nread;
            }
            /* Note: should never be 0 */
            if (ncopy > nread)
                ncopy = nread;
            os_memcpy(bbp, rbp, ncopy);
            bbp += ncopy;
            h->body_nbytes += ncopy;
            rbp += ncopy;
            nread -= ncopy;
        }       /* body copy loop */
    }       /* !got_body */
    if (h->chunked && h->in_trailer) {
        /* If "chunked" then there is always a trailer,
         * consisting of zero or more non-empty lines
         * ending with CR LF and then an empty line w/ CR LF.
         * We do NOT support trailers except to skip them --
         * this is supported (generally) by the http spec.
         */
        bbp = h->body + h->body_nbytes;
        for (;;) {
            int c;
            if (nread <= 0)
                break;
            c = *rbp++;
            nread--;
            switch (h->trailer_state) {
            case trailer_line_begin:
                if (c == '\r')
                    h->trailer_state = trailer_empty_cr;
                else
                    h->trailer_state = trailer_nonempty;
                break;
            case trailer_empty_cr:
                /* end empty line */
                if (c == '\n') {
                    h->trailer_state = trailer_line_begin;
                    h->in_trailer = 0;
                    if (httpread_debug >= 10)
                        wpa_printf(
                            MSG_DEBUG,
                            "httpread got content(%p)", h);
                    h->got_body = 1;
                    goto got_file;
                }
                h->trailer_state = trailer_nonempty;
                break;
            case trailer_nonempty:
                if (c == '\r')
                    h->trailer_state = trailer_nonempty_cr;
                break;
            case trailer_nonempty_cr:
                if (c == '\n')
                    h->trailer_state = trailer_line_begin;
                else
                    h->trailer_state = trailer_nonempty;
                break;
            }
        }
    }
    goto get_more;

bad:
    /* Error */
    wpa_printf(MSG_DEBUG, "httpread read/parse failure (%p)", h);
    (*h->cb)(h, h->cookie, HTTPREAD_EVENT_ERROR);
    return;

get_more:
    return;

got_file:
    if (httpread_debug >= 10)
        wpa_printf(MSG_DEBUG,
                   "httpread got file %d bytes type %d",
                   h->body_nbytes, h->hdr_type);
    /* Null terminate for convenience of some applications */
    if (h->body)
        h->body[h->body_nbytes] = 0; /* null terminate */
    h->got_file = 1;
    /* Assume that we do NOT support keeping connection alive,
     * and just in case somehow we don't get destroyed right away,
     * unregister now.
     */
    if (h->sd_registered)
        eloop_unregister_sock(h->sd, EVENT_TYPE_READ);
    h->sd_registered = 0;
    /* The application can destroy us whenever they feel like...
     * cancel timeout.
     */
    if (h->to_registered)
        eloop_cancel_timeout(httpread_timeout_handler, NULL, h);
    h->to_registered = 0;
    (*h->cb)(h, h->cookie, HTTPREAD_EVENT_FILE_READY);
}
Exemplo n.º 28
0
/* Given that we have received a header w/ SUBSCRIBE, act upon it
 *
 * Format of SUBSCRIBE (case-insensitive):
 *
 * First line must be:
 *      SUBSCRIBE /wps_event HTTP/1.1
 *
 * Our response (if no error) which includes only required lines is:
 * HTTP/1.1 200 OK
 * Server: xx, UPnP/1.0, xx
 * SID: uuid:xxxxxxxxx
 * Timeout: Second-<n>
 * Content-Length: 0
 * Date: xxxx
 *
 * Header lines must end with \r\n
 * Per RFC 2616, content-length: is not required but connection:close
 * would appear to be required (given that we will be closing it!).
 */
static void web_connection_parse_subscribe(struct upnp_wps_device_sm *sm,
					   struct http_request *req,
					   const char *filename)
{
	struct wpabuf *buf;
	char *b;
	char *hdr = http_request_get_hdr(req);
	char *h;
	char *match;
	int match_len;
	char *end;
	int len;
	int got_nt = 0;
	u8 uuid[UUID_LEN];
	int got_uuid = 0;
	char *callback_urls = NULL;
	struct subscription *s = NULL;
	enum http_reply_code ret = HTTP_INTERNAL_SERVER_ERROR;

	buf = wpabuf_alloc(1000);
	if (buf == NULL) {
		http_request_deinit(req);
		return;
	}

	wpa_hexdump_ascii(MSG_DEBUG, "WPS UPnP: HTTP SUBSCRIBE",
			  (u8 *) hdr, os_strlen(hdr));

	/* Parse/validate headers */
	h = hdr;
	/* First line: SUBSCRIBE /wps_event HTTP/1.1
	 * has already been parsed.
	 */
	if (os_strcasecmp(filename, UPNP_WPS_DEVICE_EVENT_FILE) != 0) {
		ret = HTTP_PRECONDITION_FAILED;
		goto error;
	}
	wpa_printf(MSG_DEBUG, "WPS UPnP: HTTP SUBSCRIBE for event");
	end = os_strchr(h, '\n');

	while (end) {
		/* Option line by option line */
		h = end + 1;
		end = os_strchr(h, '\n');
		if (end == NULL)
			break; /* no unterminated lines allowed */

		/* NT assures that it is our type of subscription;
		 * not used for a renewal.
		 **/
		match = "NT:";
		match_len = os_strlen(match);
		if (os_strncasecmp(h, match, match_len) == 0) {
			h += match_len;
			while (*h == ' ' || *h == '\t')
				h++;
			match = "upnp:event";
			match_len = os_strlen(match);
			if (os_strncasecmp(h, match, match_len) != 0) {
				ret = HTTP_BAD_REQUEST;
				goto error;
			}
			got_nt = 1;
			continue;
		}
		/* HOST should refer to us */
#if 0
		match = "HOST:";
		match_len = os_strlen(match);
		if (os_strncasecmp(h, match, match_len) == 0) {
			h += match_len;
			while (*h == ' ' || *h == '\t')
				h++;
			.....
		}
#endif
		/* CALLBACK gives one or more URLs for NOTIFYs
		 * to be sent as a result of the subscription.
		 * Each URL is enclosed in angle brackets.
		 */
		match = "CALLBACK:";
		match_len = os_strlen(match);
		if (os_strncasecmp(h, match, match_len) == 0) {
			h += match_len;
			while (*h == ' ' || *h == '\t')
				h++;
			len = end - h;
			os_free(callback_urls);
			callback_urls = dup_binstr(h, len);
			if (callback_urls == NULL) {
				ret = HTTP_INTERNAL_SERVER_ERROR;
				goto error;
			}
			if (len > 0 && callback_urls[len - 1] == '\r')
				callback_urls[len - 1] = '\0';
			continue;
		}
		/* SID is only for renewal */
		match = "SID:";
		match_len = os_strlen(match);
		if (os_strncasecmp(h, match, match_len) == 0) {
			h += match_len;
			while (*h == ' ' || *h == '\t')
				h++;
			match = "uuid:";
			match_len = os_strlen(match);
			if (os_strncasecmp(h, match, match_len) != 0) {
				ret = HTTP_BAD_REQUEST;
				goto error;
			}
			h += match_len;
			while (*h == ' ' || *h == '\t')
				h++;
			if (uuid_str2bin(h, uuid)) {
				ret = HTTP_BAD_REQUEST;
				goto error;
			}
			got_uuid = 1;
			continue;
		}
		/* TIMEOUT is requested timeout, but apparently we can
		 * just ignore this.
		 */
	}
Exemplo n.º 29
0
/* subscr_addr_add_url -- add address(es) for one url to subscription */
static void subscr_addr_add_url(struct subscription *s, const char *url,
				size_t url_len)
{
	int alloc_len;
	char *scratch_mem = NULL;
	char *mem;
	char *host;
	char *delim;
	char *path;
	int port = 80;  /* port to send to (default is port 80) */
	struct addrinfo hints;
	struct addrinfo *result = NULL;
	struct addrinfo *rp;
	int rerr;
	size_t host_len, path_len;

	/* url MUST begin with http: */
	if (url_len < 7 || os_strncasecmp(url, "http://", 7))
		goto fail;
	url += 7;
	url_len -= 7;

	/* Make a copy of the string to allow modification during parsing */
	scratch_mem = dup_binstr(url, url_len);
	if (scratch_mem == NULL)
		goto fail;
	wpa_printf(MSG_DEBUG, "WPS UPnP: Adding URL '%s'", scratch_mem);
	host = scratch_mem;
	path = os_strchr(host, '/');
	if (path)
		*path++ = '\0'; /* null terminate host */

	/* Process and remove optional port component */
	delim = os_strchr(host, ':');
	if (delim) {
		*delim = '\0'; /* null terminate host name for now */
		if (isdigit(delim[1]))
			port = atol(delim + 1);
	}

	/*
	 * getaddrinfo does the right thing with dotted decimal notations, or
	 * will resolve domain names. Resolving domain names will unfortunately
	 * hang the entire program until it is resolved or it times out
	 * internal to getaddrinfo; fortunately we think that the use of actual
	 * domain names (vs. dotted decimal notations) should be uncommon.
	 */
	os_memset(&hints, 0, sizeof(struct addrinfo));
	hints.ai_family = AF_INET;      /* IPv4 */
	hints.ai_socktype = SOCK_STREAM;
#if NO_DOMAIN_NAME_RESOLUTION
	/* Suppress domain name resolutions that would halt
	 * the program for periods of time
	 */
	hints.ai_flags = AI_NUMERICHOST;
#else
	/* Allow domain name resolution. */
	hints.ai_flags = 0;
#endif
	hints.ai_protocol = 0;          /* Any protocol? */
	rerr = getaddrinfo(host, NULL /* fill in port ourselves */,
			   &hints, &result);
	if (rerr) {
		wpa_printf(MSG_INFO, "WPS UPnP: Resolve error %d (%s) on: %s",
			   rerr, gai_strerror(rerr), host);
		goto fail;
	}

	if (delim)
		*delim = ':'; /* Restore port */

	host_len = os_strlen(host);
	path_len = path ? os_strlen(path) : 0;
	alloc_len = host_len + 1 + 1 + path_len + 1;

	for (rp = result; rp; rp = rp->ai_next) {
		struct subscr_addr *a;

		/* Limit no. of address to avoid denial of service attack */
		if (dl_list_len(&s->addr_list) >= MAX_ADDR_PER_SUBSCRIPTION) {
			wpa_printf(MSG_INFO, "WPS UPnP: subscr_addr_add_url: "
				   "Ignoring excessive addresses");
			break;
		}

		a = os_zalloc(sizeof(*a) + alloc_len);
		if (a == NULL)
			break;
		mem = (char *) (a + 1);
		a->domain_and_port = mem;
		os_memcpy(mem, host, host_len);
		mem += host_len + 1;
		a->path = mem;
		if (path == NULL || path[0] != '/')
			*mem++ = '/';
		if (path)
			os_memcpy(mem, path, path_len);
		os_memcpy(&a->saddr, rp->ai_addr, sizeof(a->saddr));
		a->saddr.sin_port = htons(port);

		dl_list_add(&s->addr_list, &a->list);
	}

fail:
	if (result)
		freeaddrinfo(result);
	os_free(scratch_mem);
}