/*
 * hostapd / Station client taxonomy
 * Copyright (c) 2015 Google, Inc.
 *
 * This software may be distributed under the terms of the BSD license.
 * See README for more details.
 */

/*
 * Parse a series of IEs, as in Probe or Association packets,
 * and render them to a descriptive string. The tag number of
 * standard options is written to the string, while the vendor
 * ID and subtag are written for vendor options.
 *
 * Example strings:
 * 0,1,50,45,221(00904c,51)
 * 0,1,33,36,48,45,221(00904c,51),221(0050f2,2)
 */

#include "utils/includes.h"
#include "utils/common.h"
#include "sta_info.h"

/* Copy a string with no funny schtuff allowed; only alphanumerics. */
static void no_mischief_strncpy(char *dst, const char *src, size_t n)
{
	size_t i;
	for (i = 0; i < n; i++) {
		unsigned char s = src[i];
		int is_lower = (s >= 'a' && s <= 'z');
		int is_upper = (s >= 'A' && s <= 'Z');
		int is_digit = (s >= '0' && s <= '9');
		if (is_lower || is_upper || is_digit) {
			/* TODO: if any manufacturer uses Unicode within the
			 * WPS header, it will get mangled here. */
			dst[i] = s;
		} else {
			/* note that even spaces will be transformed to underscores,
			 * so 'Nexus 7' will turn into 'Nexus_7'. This is deliberate,
			 * to make the string easier to parse. */
			dst[i] = '_';
		}
	}
}

static int get_wps_name(char *name, size_t name_len,
		const u8 *data, size_t data_len)
{
	/* Inside the WPS IE are a series of sub-IEs, using two byte IDs
	 * and two byte lengths. We're looking for the model name, if
	 * present. */
	while (data_len >= 4) {
		u16 id, elen;
		id = (data[0] << 8) | data[1];
		elen = (data[2] << 8) | data[3];
		data += 4;
		data_len -= 4;

		if (elen > data_len) {
			return 0;
		}

		if (id == 0x1023) {
			/* Model name, like 'Nexus 7' */
			size_t n = (elen < name_len) ? elen : name_len;
			no_mischief_strncpy(name, data, n);
			return n;
		}

		data += elen;
		data_len -= elen;
	}

	return 0;
}

static void ie_to_string(char *fstr, size_t fstr_len,
                         const u8 *ie, size_t ie_len)
{
	size_t flen = fstr_len - 1;
	char htcap[7 + 4 + 1];  // ",htcap:" + %04hx + trailing NUL
	char vhtcap[8 + 8 + 1];  // ",vhtcap:" + %08x + trailing NUL
	#define WPS_NAME_LEN		32
	char wps[WPS_NAME_LEN + 5 + 1];  // room to prepend ",wps:" + trailing NUL
	int num = 0;

	memset(htcap, 0, sizeof(htcap));
	memset(vhtcap, 0, sizeof(vhtcap));
	memset(wps, 0, sizeof(wps));
	fstr[0] = '\0';

	while (ie_len >= 2) {
		u8 id, elen;
		char tagbuf[32];
		char *sep = (num++ == 0) ? "" : ",";

		id = *ie++;
		elen = *ie++;
		ie_len -= 2;

		if (elen > ie_len) {
			break;
		}

		if ((id == 221) && (elen >= 4)) {
			/* Vendor specific */
			int is_MSFT = (ie[0] == 0x00 && ie[1] == 0x50 && ie[2] == 0xf2);
			if (is_MSFT && ie[3] == 0x04) {
				/* WPS */
				char model_name[WPS_NAME_LEN + 1];
				const u8 *data = &ie[4];
				size_t data_len = elen - 4;
				memset(model_name, 0, sizeof(model_name));
				if (get_wps_name(model_name, WPS_NAME_LEN, data, data_len)) {
					snprintf(wps, sizeof(wps), ",wps:%s", model_name);
				}
			}

			snprintf(tagbuf, sizeof(tagbuf), "%s%d(%02x%02x%02x,%d)",
			         sep, id, ie[0], ie[1], ie[2], ie[3]);
		} else {
			if ((id == 45) && (elen > 2)) {
				/* HT Capabilities (802.11n) */
				u16 cap;
				memcpy(&cap, ie, sizeof(cap));
				snprintf(htcap, sizeof(htcap), ",htcap:%04hx",
				         le_to_host16(cap));
			}
			if ((id == 191) && (elen > 4)) {
				/* VHT Capabilities (802.11ac) */
				u32 cap;
				memcpy(&cap, ie, sizeof(cap));
				snprintf(vhtcap, sizeof(vhtcap), ",vhtcap:%08x",
				         le_to_host32(cap));
			}
			snprintf(tagbuf, sizeof(tagbuf), "%s%d", sep, id);
		}

		strncat(fstr, tagbuf, flen);
		flen = fstr_len - strlen(fstr) - 1;

		ie += elen;
		ie_len -= elen;
	}

	if (strlen(htcap)) {
		strncat(fstr, htcap, flen);
		flen = fstr_len - strlen(fstr) - 1;
	}
	if (strlen(vhtcap)) {
		strncat(fstr, vhtcap, flen);
		flen = fstr_len - strlen(fstr) - 1;
	}
	if (strlen(wps)) {
		strncat(fstr, wps, flen);
		flen = fstr_len - strlen(fstr) - 1;
	}

	fstr[fstr_len - 1] = '\0';
}

void hostapd_taxonomy_probe_req(struct sta_info *sta,
	const u8 *ie, size_t ie_len)
{
	ie_to_string(sta->probe_ie_taxonomy,
			     sizeof(sta->probe_ie_taxonomy),
				 ie, ie_len);
}

void hostapd_taxonomy_assoc_req(struct sta_info *sta,
	const u8 *ie, size_t ie_len)
{
	ie_to_string(sta->assoc_ie_taxonomy,
	             sizeof(sta->assoc_ie_taxonomy),
	             ie, ie_len);
}

/* vim: set tabstop=4 softtabstop=4 shiftwidth=4 noexpandtab : */
