/*
 * hostapd / 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 htagg[7 + 2 + 1];  // ",htagg:" + %02hx + trailing NUL
	char htmcs[7 + 8 + 1];  // ",htmcs:" + %08x + trailing NUL
	char vhtcap[8 + 8 + 1];  // ",vhtcap:" + %08x + trailing NUL
	char vhtrxmcs[10 + 8 + 1];  // ",vhtrxmcs:" + %08x + trailing NUL
	char vhttxmcs[10 + 8 + 1];  // ",vhttxmcs:" + %08x + trailing NUL
	char intwrk[8 + 2 + 1];  // ",intwrk:" + %02hx + trailing NUL
	char extcap[8 + 8 + 1];  // ",extcap:" + %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(htagg, 0, sizeof(htagg));
	memset(htmcs, 0, sizeof(htmcs));
	memset(vhtcap, 0, sizeof(vhtcap));
	memset(vhtrxmcs, 0, sizeof(vhtrxmcs));
	memset(vhttxmcs, 0, sizeof(vhttxmcs));
	memset(intwrk, 0, sizeof(intwrk));
	memset(extcap, 0, sizeof(extcap));
	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 == 45) && (elen >= 3)) {
				/* HT Capabilities (802.11n), A-MPDU information */
				u8 agg;
				memcpy(&agg, ie + 2, sizeof(agg));
				snprintf(htagg, sizeof(htagg), ",htagg:%02hx", agg);
			}
			if ((id == 45) && (elen >= 7)) {
				/* HT Capabilities (802.11n), MCS information */
				u32 mcs;
				memcpy(&mcs, ie + 3, sizeof(mcs));
				snprintf(htmcs, sizeof(htmcs), ",htmcs:%08hx",
						le_to_host32(mcs));
			}
			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));
			}
			if ((id == 191) && (elen >= 8)) {
				/* VHT Capabilities (802.11ac), RX MCS information */
				u32 mcs;
				memcpy(&mcs, ie + 4, sizeof(mcs));
				snprintf(vhtrxmcs, sizeof(vhtrxmcs), ",vhtrxmcs:%08x",
				         le_to_host32(mcs));
			}
			if ((id == 191) && (elen >= 12)) {
				/* VHT Capabilities (802.11ac), TX MCS information */
				u32 mcs;
				memcpy(&mcs, ie + 8, sizeof(mcs));
				snprintf(vhttxmcs, sizeof(vhttxmcs), ",vhttxmcs:%08x",
				         le_to_host32(mcs));
			}
			if ((id == 107) && (elen >= 1)) {
				/* Interworking */
				snprintf(intwrk, sizeof(intwrk), ",intwrk:%02hx", *ie);
			}
			if ((id == 127) && (elen >= 4)) {
				/* Extended Capabilities */
				u32 ext;
				memcpy(&ext, ie, sizeof(ext));
				snprintf(extcap, sizeof(extcap), ",extcap:%08x",
				         le_to_host32(ext));
			}

			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(htagg)) {
		strncat(fstr, htagg, flen);
		flen = fstr_len - strlen(fstr) - 1;
	}
	if (strlen(htmcs)) {
		strncat(fstr, htmcs, flen);
		flen = fstr_len - strlen(fstr) - 1;
	}
	if (strlen(vhtcap)) {
		strncat(fstr, vhtcap, flen);
		flen = fstr_len - strlen(fstr) - 1;
	}
	if (strlen(vhtrxmcs)) {
		strncat(fstr, vhtrxmcs, flen);
		flen = fstr_len - strlen(fstr) - 1;
	}
	if (strlen(vhttxmcs)) {
		strncat(fstr, vhttxmcs, flen);
		flen = fstr_len - strlen(fstr) - 1;
	}
	if (strlen(intwrk)) {
		strncat(fstr, intwrk, flen);
		flen = fstr_len - strlen(fstr) - 1;
	}
	if (strlen(extcap)) {
		strncat(fstr, extcap, 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 : */
