/*
 * wl randmac command module
 *
 * Broadcom Proprietary and Confidential. Copyright (C) 2017,
 * All Rights Reserved.
 * 
 * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom;
 * the contents of this file may not be disclosed to third parties, copied
 * or duplicated in any form, in whole or in part, without the prior
 * written permission of Broadcom.
 *
 *
 * <<Broadcom-WL-IPTag/Proprietary:>>
 *
 * $Id$
 */
#ifdef WIN32
#include <windows.h>
#endif

#include <wlioctl.h>

#if	defined(DONGLEBUILD)
#include <typedefs.h>
#include <osl.h>
#endif

/* Because IL_BIGENDIAN was removed there are few warnings that need
 * to be fixed. Windows was not compiled earlier with IL_BIGENDIAN.
 * Hence these warnings were not seen earlier.
 * For now ignore the following warnings
 */
#ifdef WIN32
#pragma warning(push)
#pragma warning(disable : 4244)
#pragma warning(disable : 4761)
#endif

#include <bcmutils.h>
#include <bcmendian.h>
#include "wlu_common.h"
#include "wlu.h"

#ifdef WIN32
#define bzero(b, len)   memset((b), 0, (len))
#endif

#ifdef LINUX
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <net/if.h>
#include <linux/if_packet.h>
#endif /* LINUX */

#include <miniopt.h>
#include <errno.h>

#define RANDMAC_IOC_BUFSZ				2048
#define WL_RANDMAC_IOV_VERSION_SIZE		(sizeof(wl_randmac_version_t))
#define WL_RANDMAC_IOV_CONFIG_SIZE		(sizeof(wl_randmac_config_t))
#define WL_RANDMAC_IOV_STATS_SIZE		(sizeof(wl_randmac_stats_t))

static cmd_func_t wl_randmac;

typedef struct randmac_subcmd_info randmac_subcmd_info_t;
typedef int (randmac_subcmd_handler_t)(void *wl, const randmac_subcmd_info_t *p_subcmd_info,
	char **argv);

struct randmac_subcmd_info {
	char						*name;	/* subcmd-name */
	wl_randmac_subcmd_t			subcmd_id;	/* id */
	wl_randmac_method_t			method;
	randmac_subcmd_handler_t	*handler;		/* subcmd handler */
	char				*helpmsg;	/* message for wl randmac -h config */
};

typedef struct randmac_config_method_param_info {
	char		*name;
	uint16		value;
} randmac_config_method_param_info_t;

static const randmac_config_method_param_info_t randmac_config_methods[] = {
	/* Name				Value */
	{ "None",			WL_RANDMAC_USER_NONE },
	{ "FTM",			WL_RANDMAC_USER_FTM },
	{ "NAN",			WL_RANDMAC_USER_NAN },
	{ "SCAN",			WL_RANDMAC_USER_SCAN },
	{ "ALL",			0xFFFF },
};

typedef struct randmac_config_param_info {
	char		*name;			/* <param-name> identify configuration item */
	wl_randmac_tlv_id_t		tlvid;			/* map config item TLV id */
	char		*name_helpmsg;	/* help message */
} randmac_config_param_info_t;

static const randmac_config_param_info_t randmac_config_param_info[] = {
	/* Name			TLV ID			Help Message */
	{"mac-addr",	WL_RANDMAC_TLV_ADDR,	"Random MAC/OUI as xx:xx:xx:xx:xx:xx" },
	{"bitmask", WL_RANDMAC_TLV_MASK, "Bitmask yy:yy:yy:yy:yy:yy" },
	{"method", WL_RANDMAC_TLV_METHOD, "Methods using random MAC FTM|NAN|SCAN" }
};

static cmd_t wl_randmac_cmds[] = {
	{ "randmac", wl_randmac, WLC_GET_VAR, WLC_SET_VAR,
	"\tEnable/Disable MAC Address Randomization\n"
	"\t0 : disable\n"
	"\t1 : enable\n"
	"\tUsage: wl randmac enable\n\n"
	"\t\t wl randmac disable\n\n"
	"config [<param-name><param-value>...]\n"
	"\tGet/Set MAC address (OUI), bitmask, method\n\n"
	"\tGet current configuration\n"
	"\tUsage: wl randmac config\n"
	"\tSet or update new configuration\n"
	"\tUsage: wl randmac config mac-addr <xx:xx:xx:xx:xx:xx> bitmask <yy:yy:yy:yy:yy:yy> "
	"<method [ALL|FTM|NAN|SCAN]>"
	"version"
	"\tGet version\n\n"
	"\tUsage: wl randmac version\n\n"
	"getstats"
	"\tGet statistics\n\n"
	"\tUsage: wl randmac getstats\n\n"
	"clearstats"
	"\tClear statistics\n\n"
	"\tUsage: wl randmac clearstats\n\n" },

	{ NULL, NULL, 0, 0, NULL }
};

static char *buf;

static wl_randmac_t *randmac_alloc_getset_buf(wl_randmac_subcmd_t subcmd_id,
	uint16 subcmd_bufsize);
static int wl_randmac_subcmd_method_handler(void *wl, cmd_t *cmd, char **argv);
static int randmac_common_getcmd_handler(void *wl,
	const randmac_subcmd_info_t *p_subcmd_info, char **argv);
static int randmac_do_get_ioctl(void *wl, wl_randmac_t *p_iov, uint16 iov_len,
	const randmac_subcmd_info_t *p_subcmd_info);
static int randmac_handle_help(char **argv);
static void randmac_display_config_help();

/* module initialization */
void
wluc_randmac_module_init(void)
{
	/* get the global buf */
	buf = wl_get_buf();

	/* register randmac commands */
	wl_module_cmds_register(wl_randmac_cmds);
}

static int
wl_randmac(void *wl, cmd_t *cmd, char **argv)
{
	uint16 randmac_iovsize;
	wl_randmac_t *p_randmac_iov = NULL;
	int ret;

	/* skip the command name and check if NULL */
	if (argv[1] == NULL) {
		wl_randmac_t *iov_resp;
		randmac_iovsize = 0;
		p_randmac_iov = randmac_alloc_getset_buf(WL_RANDMAC_SUBCMD_ENABLE,
			randmac_iovsize);
		/* Get wl randmac */
		if (!p_randmac_iov) {
			ret = BCME_NOMEM;
			goto done;
		}
		ret = wlu_var_getbuf(wl, cmd->name, p_randmac_iov, sizeof(*p_randmac_iov),
			(void *)&iov_resp);
		if (ret != BCME_OK) {
			goto done;
		}

		printf(">%s\n",
			(iov_resp->subcmd_id == WL_RANDMAC_SUBCMD_ENABLE) ? "Enabled" : "Disabled");
		goto done;

	} else {
		/* Set */
		argv++;
		ret = wl_randmac_subcmd_method_handler(wl, cmd, argv);
	}
done:
	if (p_randmac_iov) {
		free(p_randmac_iov);
	}
	return ret;
}

/* declare randmac subcommand handlers randmac_subcmd_xxxx() */
/* e.g. static randmac_cmd_handler_t randmac_subcmd_get_version; */
#define RANDMAC_SUBCMD_FUNC(suffix) randmac_subcmd_ ##suffix
#define DECL_CMDHANDLER(X) static randmac_subcmd_handler_t randmac_subcmd_##X

/* get */
DECL_CMDHANDLER(get_version);		/* method-only */

/* set */
DECL_CMDHANDLER(enable);			/* method */
DECL_CMDHANDLER(disable);			/* method */
DECL_CMDHANDLER(config);			/* method */
DECL_CMDHANDLER(getstats);			/* method */
DECL_CMDHANDLER(clearstats);		/* method */

static const randmac_subcmd_info_t randmac_subcmdlist[] = {
	/* Name		Subcommand		Method		Handler		Help */
	{"version", WL_RANDMAC_SUBCMD_GET_VERSION, WL_RANDMAC_USER_NONE,
	RANDMAC_SUBCMD_FUNC(get_version), "Get randmac method API version information" },
	{"enable", WL_RANDMAC_SUBCMD_ENABLE, WL_RANDMAC_USER_NONE,
	RANDMAC_SUBCMD_FUNC(enable), "Enable randmac method"},
	{"disable", WL_RANDMAC_SUBCMD_ENABLE, WL_RANDMAC_USER_NONE,
	RANDMAC_SUBCMD_FUNC(disable), "Disable randmac method"},
	{"config", WL_RANDMAC_SUBCMD_CONFIG, WL_RANDMAC_USER_NONE,
	RANDMAC_SUBCMD_FUNC(config),
	"Configure random MAC OUI, bitmask to randomize MAC address and method"},
	{"getstats", WL_RANDMAC_SUBCMD_STATS, WL_RANDMAC_USER_NONE,
	RANDMAC_SUBCMD_FUNC(getstats),
	"Get MAC randomization method statistics"},
	{"clearstats", WL_RANDMAC_SUBCMD_CLEAR_STATS, WL_RANDMAC_USER_NONE,
	RANDMAC_SUBCMD_FUNC(clearstats), "Clear MAC randomization method statistics"},
};

const randmac_subcmd_info_t *
randmac_get_subcmd_info(char *cmdname)
{
	int i;
	const randmac_subcmd_info_t *p_subcmd_info;

	/* Search subcmd name */
	p_subcmd_info = &randmac_subcmdlist[0];
	for (i = 0; i < (int)ARRAYSIZE(randmac_subcmdlist); i++) {
		if (stricmp(p_subcmd_info->name, cmdname) == 0)
			return p_subcmd_info;
		p_subcmd_info++;
	}

	return NULL;
}

static int
randmac_subcmd_get_version(void *wl,
	const randmac_subcmd_info_t *p_subcmd_info, char **argv)
{
	/* Issue IOVAR and display version information */
	return randmac_common_getcmd_handler(wl, p_subcmd_info, argv);
}
/*
* 'wl randmac ascii-method' handler
*     handle 'wl randmac <cmdname> [<param-name><param-value>]*'
*/
static int
wl_randmac_subcmd_method_handler(void *wl, cmd_t *cmd, char **argv)
{
	const randmac_subcmd_info_t *p_subcmd_info;

	/* ignore the command name 'proxd' */
	UNUSED_PARAMETER(cmd);

	/*
	 * check for "wl randmac -h config" or
	 * "wl randmac help config" --> display the usage
	 */
	if (!stricmp(*argv, "-h") || !stricmp(*argv, "help"))  {
		return randmac_handle_help(++argv); /* return BCME_USAGE_ERROR; */
	}

	/*
	 * search for the specified <cmdname> from the
	 * pre-defined supported cmd list
	 */
	p_subcmd_info = randmac_get_subcmd_info(*argv);
	if (p_subcmd_info == NULL) {
		/* cannot find the cmd in the randmac_subcmdlist */
		return BCME_USAGE_ERROR;
	}

	/* dispatch cmd to appropriate handler */
	if (p_subcmd_info->handler) {
		return p_subcmd_info->handler(wl, p_subcmd_info, ++argv);
	} else {
		return BCME_USAGE_ERROR;
	}

	return BCME_OK;

}

/* ***************************** set commands ********************* */

/* randmac config-category definition */
typedef enum {
	RANDMAC_CONFIG_CAT_GENERAL = 1,	/* generial configuration */
} randmac_config_category_t;

/*
* display help-messages for 'wl randmac -h config'
*/
static void
randmac_display_method_help()
{
	int i;
	int max_cmdname_len = 20;
	const randmac_subcmd_info_t *p_subcmd_info;

	/* a header */
	printf("\n\tMAC Address Randomization\n");
	printf("\tUsage: wl randmac <cmd> [<param-name> <param-value>]*\n");
	printf("\t\t<cmd>: specify a command from the following list,\n");

	/* show the command list and the help messages for each FTM command */
	p_subcmd_info = &randmac_subcmdlist[0];
	for (i = 0; i < (int) ARRAYSIZE(randmac_subcmdlist); i++) {
		printf("\t\t  %*s: %s\n", max_cmdname_len, p_subcmd_info->name,
			p_subcmd_info->helpmsg);
		p_subcmd_info++;
	}

	printf("\t\t<param-name> <param-value>: <cmd>-specific parameters\n\n");

	printf("\t\ttype 'wl randmac -h config' for configuration command usage.\n");

	/* show examples */
	printf("\tExample: wl randmac [0/1 0 - Disable, 1 - Enable]\n\n");
	printf("\tExample: wl randmac config "
		"[Random MAC Address/OUI<xx:xx:xx:xx:xx:xx>] "
		"[Bitmask to randmize MAC Address<yy:yy:yy:yy:yy:yy>] [Method <FTM>]\n\n");

	return;
}

/*
* display help-messages for 'wl randmac -h config'
*/
static void
randmac_display_config_help()
{
	int i;
	int max_param_name_len = 20;
	const randmac_config_param_info_t *p_config_param_info;

	/* a header */
	printf("\n\tConfigure MAC Address Randomization feature\n");
	printf("\tUsage: wl randmac config { <param-name> <param-value> }+ \n");
	/* print helpmsg for each config-item */
	printf("\t\t<param-name> <param-value>: "
		"configuration parameters from the following\n");
	p_config_param_info = &randmac_config_param_info[0];
	for (i = 0; i < (int) ARRAYSIZE(randmac_config_param_info); i++) {
		printf("\t\t  %*s: %s\n", max_param_name_len, p_config_param_info->name,
			p_config_param_info->name_helpmsg);

		p_config_param_info++;
	}

	/* show examples */
	printf("\n\tExample: wl randmac config mac-addr <xx:xx:xx:xx:xx:xx> "
		"bitmask <yy:yy:yy:yy:yy:yy> method <FTM>\n");
}

/*
* handle
*        wl randmac -h
*        wl randmac -h config
* Output:
*        BCME_USAGE_ERROR -- caller should bring up 'randmac' level help messages
*        BCME_OK          -- this func displays context-help for RANDMAC method,
*                            caller does not need to show any help messages.
*/
static int
randmac_handle_help(char **argv)
{
	if (!*argv)
		return BCME_USAGE_ERROR;

	if (stricmp(*argv, "config") != 0)	/* check 'wl randmac -h config' */
		return BCME_USAGE_ERROR;

	++argv;
	if (*argv == NULL) {
		/* show help messages for 'wl randmac -h config' */
		randmac_display_config_help();
		return BCME_OK;
	}

	/* invalid <cmd>, display help messages for RANDMAC method */
	randmac_display_method_help();
	return BCME_OK;
}

static randmac_config_category_t
randmac_parse_config_category(char *arg_category)
{
	BCM_REFERENCE(arg_category);
	return RANDMAC_CONFIG_CAT_GENERAL;
}

static const randmac_config_param_info_t *
randmac_get_config_param_info(char *p_param_name)
{
	int i;
	const randmac_config_param_info_t   *p_config_param_info;

	p_config_param_info = &randmac_config_param_info[0];
	for (i = 0; i < (int) ARRAYSIZE(randmac_config_param_info); i++) {
		if (stricmp(p_param_name, p_config_param_info->name) == 0) {
			return p_config_param_info;
		}
		p_config_param_info++;      /* next */
	}
	return (randmac_config_param_info_t *) NULL;	/* 'invalid param name' */
}

static uint16
randmac_parse_method(char *method_name)
{
	int i = 0;
	const randmac_config_method_param_info_t *p_method_param_info;

	p_method_param_info = &randmac_config_methods[0];

	for (; i < (int) ARRAYSIZE(randmac_config_methods); i++) {
		if (stricmp(method_name, p_method_param_info->name) == 0) {
			return p_method_param_info->value;
		}
		p_method_param_info++;
	}

	return 0;
}

static int
randmac_handle_config_general(char **argv, wl_randmac_config_t *p_config)
{
	int     status = BCME_OK;
	const randmac_config_param_info_t *p_config_param_info;
	char *method_name;

	/* check if user provides param-values for 'config options' command */
	if (*argv == NULL)
		return BCME_USAGE_ERROR;

	/* <param-value>  followed 'wl proxd ftm [session-id] config options' */
	while (*argv != NULL) {
		/* look up 'config-param-info' based on 'param-name' */
		p_config_param_info = randmac_get_config_param_info(*argv);
		if (p_config_param_info == (randmac_config_param_info_t *) NULL) {
			printf("error: invalid param-name (%s)\n", *argv);
			status = BCME_USAGE_ERROR;  /* param-name is not specified */
			break;
		}

		/* parse 'param-value' */
		if (*(argv + 1) == NULL) {
			printf("error: invalid param-value\n");
			status = BCME_USAGE_ERROR;  /* param-value is not specified */
			break;
		}
		++argv;

		/* parse param-value */
		switch (p_config_param_info->tlvid) {
		case WL_RANDMAC_TLV_ADDR:
			p_config->addr = ether_null;
			if (!wl_ether_atoe(*argv, &p_config->addr)) {
				printf("error: invalid MAC address parameter\n");
				status = BCME_USAGE_ERROR;
				break;
			}
			p_config->flags |= WL_RANDMAC_FLAGS_ADDR;
			break;

		case WL_RANDMAC_TLV_MASK:
			p_config->addr_mask = ether_null;
			if (!wl_ether_atoe(*argv, &p_config->addr_mask)) {
				printf("error: invalid MAC address parameter\n");
				status = BCME_USAGE_ERROR;
				break;
			}
			p_config->flags |= WL_RANDMAC_FLAGS_MASK;
			break;

		case WL_RANDMAC_TLV_METHOD:
			method_name = *argv;
			p_config->method |= randmac_parse_method(method_name);
			p_config->flags |= WL_RANDMAC_FLAGS_METHOD;
			break;

		default:
			/* not supported */
			status = BCME_USAGE_ERROR;
			break;
		}

		if (status != BCME_OK)
			break;              /* abort */

		++argv; /* Next param */
	}

	return status;
}

static int
randmac_subcmd_disable(void *wl, const randmac_subcmd_info_t *p_subcmd_info,
	char **argv)
{
	return randmac_subcmd_enable(wl, p_subcmd_info, argv);
}

static int
randmac_subcmd_enable(void *wl, const randmac_subcmd_info_t *p_subcmd_info,
	char **argv)
{
	wl_randmac_t *p_iov = NULL;
	int status = BCME_OK;
	uint16  iov_len = WL_RANDMAC_IOV_HDR_SIZE;

	BCM_REFERENCE(*argv);
	/* allocate a buffer for randmac config via 'set' iovar */
	p_iov = randmac_alloc_getset_buf(p_subcmd_info->subcmd_id, iov_len);
	if (p_iov == (wl_randmac_t *) NULL) {
		status = BCME_NOMEM;
		goto done;
	}

	if (!(stricmp("enable", p_subcmd_info->name))) {
		p_iov->subcmd_id = WL_RANDMAC_SUBCMD_ENABLE;
	} else if (!(stricmp("disable", p_subcmd_info->name))) {
		p_iov->subcmd_id = WL_RANDMAC_SUBCMD_DISABLE;
	} else {
		randmac_display_method_help();
	}
	p_iov->version = WL_RANDMAC_API_VERSION;
	p_iov->len = iov_len;
	status = wlu_var_setbuf(wl, "randmac", p_iov, iov_len);

done:
	if (p_iov) {
		/* clean up */
		free(p_iov);
	}
	return status;
}

static int
randmac_subcmd_config(void *wl, const randmac_subcmd_info_t *p_subcmd_info,
	char **argv)
{
	wl_randmac_t *p_iov = NULL;
	int status = BCME_OK;
	wl_randmac_config_t *p_config;
	uint16  iov_len = WL_RANDMAC_IOV_HDR_SIZE;
	randmac_config_category_t category;

	if (*argv == NULL) {
		status = randmac_common_getcmd_handler(wl, p_subcmd_info, argv);
		goto done;
	}

	/* allocate a buffer for randmac config via 'set' iovar */
	iov_len += sizeof(*p_config);
	p_iov = randmac_alloc_getset_buf(p_subcmd_info->subcmd_id, iov_len);
	if (p_iov == (wl_randmac_t *) NULL) {
		status = BCME_NOMEM;
		goto done;
	}

	/* setup config data */
	p_config = (wl_randmac_config_t *)&p_iov->data[0];

	/* parse the cmd-line,  get the config-category and dispatch to the handler */
	/* to parse the parameters based on the 'config-category' */
	category = randmac_parse_config_category(*argv);
	if (category == RANDMAC_CONFIG_CAT_GENERAL)
		status = randmac_handle_config_general(argv, p_config);

	if (status == BCME_USAGE_ERROR) {
		randmac_display_config_help();
	} else {
		p_iov->version = WL_RANDMAC_API_VERSION;
		p_iov->subcmd_id = WL_RANDMAC_SUBCMD_CONFIG;
		p_iov->len = WL_RANDMAC_IOV_CONFIG_SIZE;
		status = wlu_var_setbuf(wl, "randmac", p_iov, iov_len);
	}

done:
	if (p_iov) {
		/* clean up */
		free(p_iov);
	}
	return status;
}

static int
randmac_subcmd_getstats(void *wl, const randmac_subcmd_info_t *p_subcmd_info,
	char **argv)
{
	return randmac_common_getcmd_handler(wl, p_subcmd_info, argv);
}

static int
randmac_subcmd_clearstats(void *wl, const randmac_subcmd_info_t *p_subcmd_info,
	char **argv)
{
	wl_randmac_t *p_iov;
	int status = BCME_OK;
	uint16  iov_len = WL_RANDMAC_IOV_HDR_SIZE;

	BCM_REFERENCE(*argv);
	/* allocate a buffer for randmac config via 'set' iovar */
	p_iov = randmac_alloc_getset_buf(p_subcmd_info->subcmd_id, iov_len);
	if (p_iov == (wl_randmac_t *) NULL) {
		status = BCME_NOMEM;
		goto done;
	}

	p_iov->version = WL_RANDMAC_API_VERSION;
	p_iov->subcmd_id = WL_RANDMAC_SUBCMD_CLEAR_STATS;
	p_iov->len = iov_len;
	status = wlu_var_setbuf(wl, "randmac", p_iov, iov_len);

done:
	if (p_iov) {
		/* clean up */
		free(p_iov);
	}
	return status;
}

static wl_randmac_t *
randmac_alloc_getset_buf(wl_randmac_subcmd_t subcmd_id, uint16 subcmd_bufsize)
{
	uint16 randmac_iovsize;
	wl_randmac_t *p_randmac_iov = (wl_randmac_t *)NULL;

	BCM_REFERENCE(subcmd_id);
	/* header + subcommand */
	randmac_iovsize = sizeof(wl_randmac_t) + subcmd_bufsize;

	p_randmac_iov = calloc(1, randmac_iovsize);
	if (p_randmac_iov == NULL) {
		printf("error: failed to allocate %d bytes of memory\n", randmac_iovsize);
		return NULL;
	}

	/* setup randmac method iovar header */
	p_randmac_iov->version = htol16(WL_RANDMAC_API_VERSION);
	/* caller may adjust it based on subcommand */
	p_randmac_iov->len = htol16(randmac_iovsize);
	p_randmac_iov->subcmd_id = htol16(subcmd_id);

	return p_randmac_iov;
}

static int
randmac_common_getcmd_handler(void *wl, const randmac_subcmd_info_t *p_subcmd_info,
	char **argv)
{
	int status = BCME_OK;
	uint16 iov_len = WL_RANDMAC_IOV_HDR_SIZE;
	wl_randmac_t *p_iov = (wl_randmac_t *) NULL;

	BCM_REFERENCE(*argv);
	switch (p_subcmd_info->subcmd_id) {
	case WL_RANDMAC_SUBCMD_GET_VERSION:
		iov_len += WL_RANDMAC_IOV_VERSION_SIZE;
		p_iov = randmac_alloc_getset_buf(p_subcmd_info->subcmd_id, iov_len);
		break;

	case WL_RANDMAC_SUBCMD_CONFIG:
		iov_len += WL_RANDMAC_IOV_CONFIG_SIZE;
		p_iov = randmac_alloc_getset_buf(p_subcmd_info->subcmd_id, iov_len);
		break;

	case WL_RANDMAC_SUBCMD_STATS:
		iov_len += WL_RANDMAC_IOV_STATS_SIZE;
		p_iov = randmac_alloc_getset_buf(p_subcmd_info->subcmd_id, iov_len);
		break;

	default:
		/* Unknown subcommand */
		break;
	}

	if (p_iov != NULL) {
		/* get */
		status = randmac_do_get_ioctl(wl, p_iov, iov_len, p_subcmd_info);
	}

	/* Clean up memory */
	free(p_iov);

	return status;
}

static int
randmac_do_get_ioctl(void *wl, wl_randmac_t *p_iov, uint16 iov_len,
const randmac_subcmd_info_t *p_subcmd_info)
{
	/* for gets we only need to pass ioc header */
	wl_randmac_t *p_iovresp = NULL;
	int status;
	/*  send getbuf proxd iovar */
	status = wlu_var_getbuf(wl, "randmac", p_iov, iov_len, (void *)&p_iovresp);
	if (status != BCME_OK) {
		return status;
	}

	if (p_iovresp != NULL) {
		switch (p_subcmd_info->subcmd_id) {
		case WL_RANDMAC_SUBCMD_GET_VERSION:
			{
				wl_randmac_version_t *p_iov_ver;
				p_iov_ver = (wl_randmac_version_t *)(&p_iovresp->data[0]);
				printf("> Version: 0x%04x\n", p_iov_ver->version);
			}
			break;

		case WL_RANDMAC_SUBCMD_DISABLE:
		case WL_RANDMAC_SUBCMD_ENABLE:
			{
				printf(">%s\n",
					(p_subcmd_info->subcmd_id == WL_RANDMAC_SUBCMD_ENABLE) ?
					"Enabled" : "Disabled");
			}
			break;

		case WL_RANDMAC_SUBCMD_CONFIG:
			{
				uint32 i = 0;
				const randmac_config_method_param_info_t *methods_info;
				wl_randmac_config_t *p_iov_config;
				p_iov_config = (wl_randmac_config_t *)(&p_iovresp->data[0]);
				printf(">MAC Address:%02x:%02x:%02x:%02x:%02x:%02x\n",
					p_iov_config->addr.octet[0],
					p_iov_config->addr.octet[1],
					p_iov_config->addr.octet[2],
					p_iov_config->addr.octet[3],
					p_iov_config->addr.octet[4],
					p_iov_config->addr.octet[5]);
				printf(">Bitmask:%02x:%02x:%02x:%02x:%02x:%02x\n",
					p_iov_config->addr_mask.octet[0],
					p_iov_config->addr_mask.octet[1],
					p_iov_config->addr_mask.octet[2],
					p_iov_config->addr_mask.octet[3],
					p_iov_config->addr_mask.octet[4],
					p_iov_config->addr_mask.octet[5]);
				if (p_iov_config->method == WL_RANDMAC_USER_NONE) {
					printf("> Method: None\n");
				} else if (p_iov_config->method == WL_RANDMAC_USER_ALL) {
					printf(">Method: All\n");
				} else {
					printf(">Method:");
					while (p_iov_config->method) {
						if (p_iov_config->method & (1 << i)) {
							methods_info =
								&randmac_config_methods[i + 1];
							printf(" %s ", methods_info->name);
							p_iov_config->method &= ~(1 << i);
						}
						i++;
					}
					printf("\n");
				}
			}
			break;
		case WL_RANDMAC_SUBCMD_STATS:
			{
				wl_randmac_stats_t *pstats =
					(wl_randmac_stats_t *)(&p_iovresp->data[0]);
				printf(">MAC randomization set calls success:\t %u\n",
					pstats->set_ok);
				printf(">MAC randomization set calls failed:\t %u\n",
					pstats->set_fail);
				printf(">MAC randomization set requests:\t %u\n",
					pstats->set_reqs);
				printf(">MAC randomization reset requests:\t %u\n",
					pstats->reset_reqs);
				printf(">MAC randomization restore calls success:%u\n",
					pstats->restore_ok);
				printf(">MAC randomization restore calls failed: %u\n",
					pstats->restore_fail);
				printf(">MAC randomization events sent:\t\t %u\n",
					pstats->events_sent);
				printf(">MAC randomization events received:\t %u\n",
					pstats->events_rcvd);
				printf("\n");
			}
			break;

		default:
			/* Unknown response */
			break;
		}
	}

	return status;
}
