コード例 #1
0
ファイル: gas.c プロジェクト: RTEMS/rtems-libbsd
struct wpabuf * gas_anqp_build_initial_resp(u8 dialog_token, u16 status_code,
					    u16 comeback_delay, size_t size)
{
	struct wpabuf *buf;

	buf = gas_build_initial_resp(dialog_token, status_code, comeback_delay,
				     4 + size);
	if (buf == NULL)
		return NULL;

	gas_add_adv_proto_anqp(buf, 0x7f, 0);

	wpabuf_put(buf, 2); /* Query Response Length to be filled */

	return buf;
}
コード例 #2
0
static void
gas_server_send_resp(struct gas_server *gas, struct gas_server_handler *handler,
		     const u8 *da, int freq, u8 dialog_token,
		     struct wpabuf *query_resp)
{
	size_t max_len = (freq > 56160) ? 928 : 1400;
	size_t hdr_len = 24 + 2 + 5 + 3 + handler->adv_proto_id_len + 2;
	size_t resp_frag_len;
	struct wpabuf *resp;
	u16 comeback_delay;
	struct gas_server_response *response;

	if (!query_resp)
		return;

	response = os_zalloc(sizeof(*response));
	if (!response)
		return;
	wpa_printf(MSG_DEBUG, "DPP: Allocated GAS response @%p", response);
	response->freq = freq;
	response->handler = handler;
	os_memcpy(response->dst, da, ETH_ALEN);
	response->dialog_token = dialog_token;
	if (hdr_len + wpabuf_len(query_resp) > max_len) {
		/* Need to use comeback to initiate fragmentation */
		comeback_delay = 1;
		resp_frag_len = 0;
	} else {
		/* Full response fits into the initial response */
		comeback_delay = 0;
		resp_frag_len = wpabuf_len(query_resp);
	}

	resp = gas_build_initial_resp(dialog_token, WLAN_STATUS_SUCCESS,
				      comeback_delay,
				      handler->adv_proto_id_len +
				      resp_frag_len);
	if (!resp) {
		gas_server_free_response(response);
		return;
	}

	/* Advertisement Protocol element */
	wpabuf_put_u8(resp, WLAN_EID_ADV_PROTO);
	wpabuf_put_u8(resp, 1 + handler->adv_proto_id_len); /* Length */
	wpabuf_put_u8(resp, 0x7f);
	/* Advertisement Protocol ID */
	wpabuf_put_data(resp, handler->adv_proto_id, handler->adv_proto_id_len);

	/* Query Response Length */
	wpabuf_put_le16(resp, resp_frag_len);
	if (!comeback_delay)
		wpabuf_put_buf(resp, query_resp);

	if (comeback_delay) {
		wpa_printf(MSG_DEBUG,
			   "GAS: Need to fragment query response");
	} else {
		wpa_printf(MSG_DEBUG,
			   "GAS: Full query response fits in the GAS Initial Response frame");
	}
	response->offset = resp_frag_len;
	response->resp = query_resp;
	dl_list_add(&gas->responses, &response->list);
	gas->tx(gas->ctx, freq, da, resp, comeback_delay ? 2000 : 0);
	wpabuf_free(resp);
	eloop_register_timeout(GAS_QUERY_TIMEOUT, 0,
			       gas_server_response_timeout, response, NULL);
}
コード例 #3
0
ファイル: gas_serv.c プロジェクト: ArcherHood/ti-hostap
static void gas_serv_rx_gas_initial_req(struct hostapd_data *hapd,
					const u8 *sa,
					const u8 *data, size_t len)
{
	const u8 *pos = data;
	const u8 *end = data + len;
	const u8 *next;
	u8 dialog_token;
	u16 slen;
	struct anqp_query_info qi;
	const u8 *adv_proto;

	if (len < 1 + 2)
		return;

	os_memset(&qi, 0, sizeof(qi));

	dialog_token = *pos++;
	wpa_msg(hapd->msg_ctx, MSG_DEBUG,
		"GAS: GAS Initial Request from " MACSTR " (dialog token %u) ",
		MAC2STR(sa), dialog_token);

	if (*pos != WLAN_EID_ADV_PROTO) {
		wpa_msg(hapd->msg_ctx, MSG_DEBUG,
			"GAS: Unexpected IE in GAS Initial Request: %u", *pos);
		return;
	}
	adv_proto = pos++;

	slen = *pos++;
	next = pos + slen;
	if (next > end || slen < 2) {
		wpa_msg(hapd->msg_ctx, MSG_DEBUG,
			"GAS: Invalid IE in GAS Initial Request");
		return;
	}
	pos++; /* skip QueryRespLenLimit and PAME-BI */

	if (*pos != ACCESS_NETWORK_QUERY_PROTOCOL) {
		struct wpabuf *buf;
		wpa_msg(hapd->msg_ctx, MSG_DEBUG,
			"GAS: Unsupported GAS advertisement protocol id %u",
			*pos);
		if (sa[0] & 0x01)
			return; /* Invalid source address - drop silently */
		buf = gas_build_initial_resp(
			dialog_token, WLAN_STATUS_GAS_ADV_PROTO_NOT_SUPPORTED,
			0, 2 + slen + 2);
		if (buf == NULL)
			return;
		wpabuf_put_data(buf, adv_proto, 2 + slen);
		wpabuf_put_le16(buf, 0); /* Query Response Length */
		hostapd_drv_send_action(hapd, hapd->iface->freq, 0, sa,
					wpabuf_head(buf), wpabuf_len(buf));
		wpabuf_free(buf);
		return;
	}

	pos = next;
	/* Query Request */
	if (pos + 2 > end)
		return;
	slen = WPA_GET_LE16(pos);
	pos += 2;
	if (pos + slen > end)
		return;
	end = pos + slen;

	/* ANQP Query Request */
	while (pos < end) {
		u16 info_id, elen;

		if (pos + 4 > end)
			return;

		info_id = WPA_GET_LE16(pos);
		pos += 2;
		elen = WPA_GET_LE16(pos);
		pos += 2;

		if (pos + elen > end) {
			wpa_printf(MSG_DEBUG, "ANQP: Invalid Query Request");
			return;
		}

		switch (info_id) {
		case ANQP_QUERY_LIST:
			rx_anqp_query_list(hapd, pos, pos + elen, &qi);
			break;
#ifdef CONFIG_HS20
		case ANQP_VENDOR_SPECIFIC:
			rx_anqp_vendor_specific(hapd, pos, pos + elen, &qi);
			break;
#endif /* CONFIG_HS20 */
		default:
			wpa_printf(MSG_DEBUG, "ANQP: Unsupported Query "
				   "Request element %u", info_id);
			break;
		}

		pos += elen;
	}

	gas_serv_req_local_processing(hapd, sa, dialog_token, &qi);
}