/*
 * wlantest - IEEE 802.11 protocol monitoring and testing tool
 * Copyright (c) 2010-2013, Jouni Malinen <j@w1.fi>
 *
 * This software may be distributed under the terms of the BSD license.
 * See README for more details.
 */

#include "utils/includes.h"

#include "utils/common.h"
#include "utils/eloop.h"
#include "wlantest.h"


extern int wpa_debug_level;
extern int wpa_debug_show_keys;
extern int wpa_debug_timestamp;


static void wlantest_terminate(int sig, void *signal_ctx)
{
	eloop_terminate();
}


static void usage(void)
{
	printf("wlantest [-cddhqqFt] [-i<ifname>] [-r<pcap file>] "
	       "[-p<passphrase>]\n"
	       "         [-I<wired ifname>] [-R<wired pcap file>] "
	       "[-P<RADIUS shared secret>]\n"
	       "         [-n<write pcapng file>]\n"
	       "         [-w<write pcap file>] [-f<MSK/PMK file>]\n"
	       "         [-L<log file>] [-T<PTK file>]\n");
}


static void passphrase_deinit(struct wlantest_passphrase *p)
{
	dl_list_del(&p->list);
	os_free(p);
}


static void secret_deinit(struct wlantest_radius_secret *r)
{
	dl_list_del(&r->list);
	os_free(r);
}


static void wlantest_init(struct wlantest *wt)
{
	int i;
	os_memset(wt, 0, sizeof(*wt));
	wt->monitor_sock = -1;
	wt->ctrl_sock = -1;
	for (i = 0; i < MAX_CTRL_CONNECTIONS; i++)
		wt->ctrl_socks[i] = -1;
	dl_list_init(&wt->passphrase);
	dl_list_init(&wt->bss);
	dl_list_init(&wt->secret);
	dl_list_init(&wt->radius);
	dl_list_init(&wt->pmk);
	dl_list_init(&wt->ptk);
	dl_list_init(&wt->wep);
}


void radius_deinit(struct wlantest_radius *r)
{
	dl_list_del(&r->list);
	os_free(r);
}


static void ptk_deinit(struct wlantest_ptk *ptk)
{
	dl_list_del(&ptk->list);
	os_free(ptk);
}


static void wlantest_deinit(struct wlantest *wt)
{
	struct wlantest_passphrase *p, *pn;
	struct wlantest_radius_secret *s, *sn;
	struct wlantest_radius *r, *rn;
	struct wlantest_pmk *pmk, *np;
	struct wlantest_ptk *ptk, *npt;
	struct wlantest_wep *wep, *nw;

	if (wt->ctrl_sock >= 0)
		ctrl_deinit(wt);
	if (wt->monitor_sock >= 0)
		monitor_deinit(wt);
	bss_flush(wt);
	dl_list_for_each_safe(p, pn, &wt->passphrase,
			      struct wlantest_passphrase, list)
		passphrase_deinit(p);
	dl_list_for_each_safe(s, sn, &wt->secret,
			      struct wlantest_radius_secret, list)
		secret_deinit(s);
	dl_list_for_each_safe(r, rn, &wt->radius, struct wlantest_radius, list)
		radius_deinit(r);
	dl_list_for_each_safe(pmk, np, &wt->pmk, struct wlantest_pmk, list)
		pmk_deinit(pmk);
	dl_list_for_each_safe(ptk, npt, &wt->ptk, struct wlantest_ptk, list)
		ptk_deinit(ptk);
	dl_list_for_each_safe(wep, nw, &wt->wep, struct wlantest_wep, list)
		os_free(wep);
	write_pcap_deinit(wt);
	write_pcapng_deinit(wt);
	clear_notes(wt);
	os_free(wt->decrypted);
	wt->decrypted = NULL;
}


static void add_passphrase(struct wlantest *wt, const char *passphrase)
{
	struct wlantest_passphrase *p;
	size_t len = os_strlen(passphrase);

	if (len < 8 || len > 63)
		return;
	p = os_zalloc(sizeof(*p));
	if (p == NULL)
		return;
	os_memcpy(p->passphrase, passphrase, len);
	dl_list_add(&wt->passphrase, &p->list);
}


static void add_secret(struct wlantest *wt, const char *secret)
{
	struct wlantest_radius_secret *s;
	size_t len = os_strlen(secret);

	if (len >= MAX_RADIUS_SECRET_LEN)
		return;
	s = os_zalloc(sizeof(*s));
	if (s == NULL)
		return;
	os_memcpy(s->secret, secret, len);
	dl_list_add(&wt->secret, &s->list);
}


static int add_pmk_file(struct wlantest *wt, const char *pmk_file)
{
	FILE *f;
	u8 pmk[32];
	char buf[300], *pos;
	struct wlantest_pmk *p;

	f = fopen(pmk_file, "r");
	if (f == NULL) {
		wpa_printf(MSG_ERROR, "Could not open '%s'", pmk_file);
		return -1;
	}

	while (fgets(buf, sizeof(buf), f)) {
		pos = buf;
		while (*pos && *pos != '\r' && *pos != '\n')
			pos++;
		*pos = '\0';
		if (pos - buf < 2 * 32)
			continue;
		if (hexstr2bin(buf, pmk, 32) < 0)
			continue;
		p = os_zalloc(sizeof(*p));
		if (p == NULL)
			break;
		os_memcpy(p->pmk, pmk, 32);
		dl_list_add(&wt->pmk, &p->list);
		wpa_hexdump(MSG_DEBUG, "Added PMK from file", pmk, 32);
	}

	fclose(f);
	return 0;
}


static int add_ptk_file(struct wlantest *wt, const char *ptk_file)
{
	FILE *f;
	u8 ptk[64];
	size_t ptk_len;
	char buf[300], *pos;
	struct wlantest_ptk *p;

	f = fopen(ptk_file, "r");
	if (f == NULL) {
		wpa_printf(MSG_ERROR, "Could not open '%s'", ptk_file);
		return -1;
	}

	while (fgets(buf, sizeof(buf), f)) {
		pos = buf;
		while (*pos && *pos != '\r' && *pos != '\n')
			pos++;
		*pos = '\0';
		ptk_len = pos - buf;
		if (ptk_len & 1)
			continue;
		ptk_len /= 2;
		if (ptk_len != 16 && ptk_len != 32 &&
		    ptk_len != 48 && ptk_len != 64)
			continue;
		if (hexstr2bin(buf, ptk, ptk_len) < 0)
			continue;
		p = os_zalloc(sizeof(*p));
		if (p == NULL)
			break;
		if (ptk_len < 48) {
			os_memcpy(p->ptk.tk1, ptk, ptk_len);
			p->ptk_len = 32 + ptk_len;
		} else {
			os_memcpy(&p->ptk, ptk, ptk_len);
			p->ptk_len = ptk_len;
		}
		dl_list_add(&wt->ptk, &p->list);
		wpa_hexdump(MSG_DEBUG, "Added PTK from file", ptk, ptk_len);
	}

	fclose(f);
	return 0;
}


int add_wep(struct wlantest *wt, const char *key)
{
	struct wlantest_wep *w;
	size_t len = os_strlen(key);

	if (len != 2 * 5 && len != 2 * 13) {
		wpa_printf(MSG_INFO, "Invalid WEP key '%s'", key);
		return -1;
	}
	w = os_zalloc(sizeof(*w));
	if (w == NULL)
		return -1;
	if (hexstr2bin(key, w->key, len / 2) < 0) {
		os_free(w);
		wpa_printf(MSG_INFO, "Invalid WEP key '%s'", key);
		return -1;
	}
	w->key_len = len / 2;
	dl_list_add(&wt->wep, &w->list);
	return 0;
}


void add_note(struct wlantest *wt, int level, const char *fmt, ...)
{
	va_list ap;
	size_t len = 1000;
	int wlen;

	if (wt->num_notes == MAX_NOTES)
		return;

	wt->notes[wt->num_notes] = os_malloc(len);
	if (wt->notes[wt->num_notes] == NULL)
		return;
	va_start(ap, fmt);
	wlen = vsnprintf(wt->notes[wt->num_notes], len, fmt, ap);
	va_end(ap);
	if (wlen < 0) {
		os_free(wt->notes[wt->num_notes]);
		wt->notes[wt->num_notes] = NULL;
		return;
	}
	if (wlen >= len)
		wt->notes[wt->num_notes][len - 1] = '\0';
	wpa_printf(level, "%s", wt->notes[wt->num_notes]);
	wt->num_notes++;
}


void clear_notes(struct wlantest *wt)
{
	size_t i;

	for (i = 0; i < wt->num_notes; i++) {
		os_free(wt->notes[i]);
		wt->notes[i] = NULL;
	}

	wt->num_notes = 0;
}


size_t notes_len(struct wlantest *wt, size_t hdrlen)
{
	size_t i;
	size_t len = wt->num_notes * hdrlen;

	for (i = 0; i < wt->num_notes; i++)
		len += os_strlen(wt->notes[i]);

	return len;
}


int wlantest_relog(struct wlantest *wt)
{
	int ret = 0;

	wpa_printf(MSG_INFO, "Re-open log/capture files");
	if (wpa_debug_reopen_file())
		ret = -1;

	if (wt->write_file) {
		write_pcap_deinit(wt);
		if (write_pcap_init(wt, wt->write_file) < 0)
			ret = -1;
	}

	if (wt->pcapng_file) {
		write_pcapng_deinit(wt);
		if (write_pcapng_init(wt, wt->pcapng_file) < 0)
			ret = -1;
	}

	return ret;
}


int main(int argc, char *argv[])
{
	int c;
	const char *read_file = NULL;
	const char *read_wired_file = NULL;
	const char *ifname = NULL;
	const char *ifname_wired = NULL;
	const char *logfile = NULL;
	struct wlantest wt;
	int ctrl_iface = 0;

	wpa_debug_level = MSG_INFO;
	wpa_debug_show_keys = 1;

	if (os_program_init())
		return -1;

	wlantest_init(&wt);

	for (;;) {
		c = getopt(argc, argv, "cdf:Fhi:I:L:n:p:P:qr:R:tT:w:W:");
		if (c < 0)
			break;
		switch (c) {
		case 'c':
			ctrl_iface = 1;
			break;
		case 'd':
			if (wpa_debug_level > 0)
				wpa_debug_level--;
			break;
		case 'f':
			if (add_pmk_file(&wt, optarg) < 0)
				return -1;
			break;
		case 'F':
			wt.assume_fcs = 1;
			break;
		case 'h':
			usage();
			return 0;
		case 'i':
			ifname = optarg;
			break;
		case 'I':
			ifname_wired = optarg;
			break;
		case 'L':
			logfile = optarg;
			break;
		case 'n':
			wt.pcapng_file = optarg;
			break;
		case 'p':
			add_passphrase(&wt, optarg);
			break;
		case 'P':
			add_secret(&wt, optarg);
			break;
		case 'q':
			wpa_debug_level++;
			break;
		case 'r':
			read_file = optarg;
			break;
		case 'R':
			read_wired_file = optarg;
			break;
		case 't':
			wpa_debug_timestamp = 1;
			break;
		case 'T':
			if (add_ptk_file(&wt, optarg) < 0)
				return -1;
			break;
		case 'w':
			wt.write_file = optarg;
			break;
		case 'W':
			if (add_wep(&wt, optarg) < 0)
				return -1;
			break;
		default:
			usage();
			return -1;
		}
	}

	if (ifname == NULL && ifname_wired == NULL &&
	    read_file == NULL && read_wired_file == NULL) {
		usage();
		return 0;
	}

	if (eloop_init())
		return -1;

	if (logfile)
		wpa_debug_open_file(logfile);

	if (wt.write_file && write_pcap_init(&wt, wt.write_file) < 0)
		return -1;

	if (wt.pcapng_file && write_pcapng_init(&wt, wt.pcapng_file) < 0)
		return -1;

	if (read_wired_file && read_wired_cap_file(&wt, read_wired_file) < 0)
		return -1;

	if (read_file && read_cap_file(&wt, read_file) < 0)
		return -1;

	if (ifname && monitor_init(&wt, ifname) < 0)
		return -1;

	if (ifname_wired && monitor_init_wired(&wt, ifname_wired) < 0)
		return -1;

	if (ctrl_iface && ctrl_init(&wt) < 0)
		return -1;

	eloop_register_signal_terminate(wlantest_terminate, &wt);

	eloop_run();

	wpa_printf(MSG_INFO, "Processed: rx_mgmt=%u rx_ctrl=%u rx_data=%u "
		   "fcs_error=%u",
		   wt.rx_mgmt, wt.rx_ctrl, wt.rx_data, wt.fcs_error);

	wlantest_deinit(&wt);

	wpa_debug_close_file();
	eloop_destroy();
	os_program_deinit();

	return 0;
}
