/* parser.c
 *
 * Copyright (C) 2010 - 2013 UNISYS CORPORATION
 * All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or (at
 * your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
 * NON INFRINGEMENT.  See the GNU General Public License for more
 * details.
 */

#include "parser.h"
#include "memregion.h"
#include "controlvmchannel.h"
#include <linux/ctype.h>
#include <linux/mm.h>
#include <linux/uuid.h>

#define MYDRVNAME "visorchipset_parser"
#define CURRENT_FILE_PC VISOR_CHIPSET_PC_parser_c

/* We will refuse to allocate more than this many bytes to copy data from
 * incoming payloads.  This serves as a throttling mechanism.
 */
#define MAX_CONTROLVM_PAYLOAD_BYTES (1024*128)
static ulong Controlvm_Payload_Bytes_Buffered;

struct PARSER_CONTEXT_Tag {
	ulong allocbytes;
	ulong param_bytes;
	u8 *curr;
	ulong bytes_remaining;
	BOOL byte_stream;
	char data[0];
};

static PARSER_CONTEXT *
parser_init_guts(U64 addr, U32 bytes, BOOL isLocal,
		 BOOL hasStandardPayloadHeader, BOOL *tryAgain)
{
	int allocbytes = sizeof(PARSER_CONTEXT) + bytes;
	PARSER_CONTEXT *rc = NULL;
	PARSER_CONTEXT *ctx = NULL;
	MEMREGION *rgn = NULL;
	ULTRA_CONTROLVM_PARAMETERS_HEADER *phdr = NULL;

	if (tryAgain)
		*tryAgain = FALSE;
	if (!hasStandardPayloadHeader)
		/* alloc and 0 extra byte to ensure payload is
		 * '\0'-terminated
		 */
		allocbytes++;
	if ((Controlvm_Payload_Bytes_Buffered + bytes)
	    > MAX_CONTROLVM_PAYLOAD_BYTES) {
		ERRDRV("%s (%s:%d) - prevented allocation of %d bytes to prevent exceeding throttling max (%d)",
		       __func__, __FILE__, __LINE__, allocbytes,
		       MAX_CONTROLVM_PAYLOAD_BYTES);
		if (tryAgain)
			*tryAgain = TRUE;
		rc = NULL;
		goto Away;
	}
	ctx = kzalloc(allocbytes, GFP_KERNEL|__GFP_NORETRY);
	if (ctx == NULL) {
		ERRDRV("%s (%s:%d) - failed to allocate %d bytes",
		       __func__, __FILE__, __LINE__, allocbytes);
		if (tryAgain)
			*tryAgain = TRUE;
		rc = NULL;
		goto Away;
	}

	ctx->allocbytes = allocbytes;
	ctx->param_bytes = bytes;
	ctx->curr = NULL;
	ctx->bytes_remaining = 0;
	ctx->byte_stream = FALSE;
	if (isLocal) {
		void *p;
		if (addr > virt_to_phys(high_memory - 1)) {
			ERRDRV("%s - bad local address (0x%-16.16Lx for %lu)",
			       __func__,
			       (unsigned long long) addr, (ulong) bytes);
			rc = NULL;
			goto Away;
		}
		p = __va((ulong) (addr));
		memcpy(ctx->data, p, bytes);
	} else {
		rgn = visor_memregion_create(addr, bytes);
		if (!rgn) {
			rc = NULL;
			goto Away;
		}
		if (visor_memregion_read(rgn, 0, ctx->data, bytes) < 0) {
			rc = NULL;
			goto Away;
		}
	}
	if (!hasStandardPayloadHeader) {
		ctx->byte_stream = TRUE;
		rc = ctx;
		goto Away;
	}
	phdr = (ULTRA_CONTROLVM_PARAMETERS_HEADER *) (ctx->data);
	if (phdr->TotalLength != bytes) {
		ERRDRV("%s - bad total length %lu (should be %lu)",
		       __func__,
		       (ulong) (phdr->TotalLength), (ulong) (bytes));
		rc = NULL;
		goto Away;
	}
	if (phdr->TotalLength < phdr->HeaderLength) {
		ERRDRV("%s - total length < header length (%lu < %lu)",
		       __func__,
		       (ulong) (phdr->TotalLength),
		       (ulong) (phdr->HeaderLength));
		rc = NULL;
		goto Away;
	}
	if (phdr->HeaderLength < sizeof(ULTRA_CONTROLVM_PARAMETERS_HEADER)) {
		ERRDRV("%s - header is too small (%lu < %lu)",
		       __func__,
		       (ulong) (phdr->HeaderLength),
		       (ulong) (sizeof(ULTRA_CONTROLVM_PARAMETERS_HEADER)));
		rc = NULL;
		goto Away;
	}

	rc = ctx;
Away:
	if (rgn) {
		visor_memregion_destroy(rgn);
		rgn = NULL;
	}
	if (rc)
		Controlvm_Payload_Bytes_Buffered += ctx->param_bytes;
	else {
		if (ctx) {
			parser_done(ctx);
			ctx = NULL;
		}
	}
	return rc;
}

PARSER_CONTEXT *
parser_init(U64 addr, U32 bytes, BOOL isLocal, BOOL *tryAgain)
{
	return parser_init_guts(addr, bytes, isLocal, TRUE, tryAgain);
}

/* Call this instead of parser_init() if the payload area consists of just
 * a sequence of bytes, rather than a ULTRA_CONTROLVM_PARAMETERS_HEADER
 * structures.  Afterwards, you can call parser_simpleString_get() or
 * parser_byteStream_get() to obtain the data.
 */
PARSER_CONTEXT *
parser_init_byteStream(U64 addr, U32 bytes, BOOL isLocal, BOOL *tryAgain)
{
	return parser_init_guts(addr, bytes, isLocal, FALSE, tryAgain);
}

/* Obtain '\0'-terminated copy of string in payload area.
 */
char *
parser_simpleString_get(PARSER_CONTEXT *ctx)
{
	if (!ctx->byte_stream)
		return NULL;
	return ctx->data;	/* note this IS '\0'-terminated, because of
				 * the num of bytes we alloc+clear in
				 * parser_init_byteStream() */
}

/* Obtain a copy of the buffer in the payload area.
 */
void *
parser_byteStream_get(PARSER_CONTEXT *ctx, ulong *nbytes)
{
	if (!ctx->byte_stream)
		return NULL;
	if (nbytes)
		*nbytes = ctx->param_bytes;
	return (void *) ctx->data;
}

uuid_le
parser_id_get(PARSER_CONTEXT *ctx)
{
	ULTRA_CONTROLVM_PARAMETERS_HEADER *phdr = NULL;

	if (ctx == NULL) {
		ERRDRV("%s (%s:%d) - no context",
		       __func__, __FILE__, __LINE__);
		return NULL_UUID_LE;
	}
	phdr = (ULTRA_CONTROLVM_PARAMETERS_HEADER *) (ctx->data);
	return phdr->Id;
}

void
parser_param_start(PARSER_CONTEXT *ctx, PARSER_WHICH_STRING which_string)
{
	ULTRA_CONTROLVM_PARAMETERS_HEADER *phdr = NULL;

	if (ctx == NULL) {
		ERRDRV("%s (%s:%d) - no context",
		       __func__, __FILE__, __LINE__);
		goto Away;
	}
	phdr = (ULTRA_CONTROLVM_PARAMETERS_HEADER *) (ctx->data);
	switch (which_string) {
	case PARSERSTRING_INITIATOR:
		ctx->curr = ctx->data + phdr->InitiatorOffset;
		ctx->bytes_remaining = phdr->InitiatorLength;
		break;
	case PARSERSTRING_TARGET:
		ctx->curr = ctx->data + phdr->TargetOffset;
		ctx->bytes_remaining = phdr->TargetLength;
		break;
	case PARSERSTRING_CONNECTION:
		ctx->curr = ctx->data + phdr->ConnectionOffset;
		ctx->bytes_remaining = phdr->ConnectionLength;
		break;
	case PARSERSTRING_NAME:
		ctx->curr = ctx->data + phdr->NameOffset;
		ctx->bytes_remaining = phdr->NameLength;
		break;
	default:
		ERRDRV("%s - bad which_string %d", __func__, which_string);
		break;
	}

Away:
	return;
}

void
parser_done(PARSER_CONTEXT *ctx)
{
	if (!ctx)
		return;
	Controlvm_Payload_Bytes_Buffered -= ctx->param_bytes;
	kfree(ctx);
}

/** Return length of string not counting trailing spaces. */
static int
string_length_no_trail(char *s, int len)
{
	int i = len - 1;
	while (i >= 0) {
		if (!isspace(s[i]))
			return i + 1;
		i--;
	}
	return 0;
}

/** Grab the next name and value out of the parameter buffer.
 *  The entire parameter buffer looks like this:
 *      <name>=<value>\0
 *      <name>=<value>\0
 *      ...
 *      \0
 *  If successful, the next <name> value is returned within the supplied
 *  <nam> buffer (the value is always upper-cased), and the corresponding
 *  <value> is returned within a kmalloc()ed buffer, whose pointer is
 *  provided as the return value of this function.
 *  (The total number of bytes allocated is strlen(<value>)+1.)
 *
 *  NULL is returned to indicate failure, which can occur for several reasons:
 *  - all <name>=<value> pairs have already been processed
 *  - bad parameter
 *  - parameter buffer ends prematurely (couldn't find an '=' or '\0' within
 *    the confines of the parameter buffer)
 *  - the <nam> buffer is not large enough to hold the <name> of the next
 *    parameter
 */
void *
parser_param_get(PARSER_CONTEXT *ctx, char *nam, int namesize)
{
	u8 *pscan, *pnam = nam;
	ulong nscan;
	int value_length = -1, orig_value_length = -1;
	void *value = NULL;
	int i;
	int closing_quote = 0;

	if (!ctx)
		return NULL;
	pscan = ctx->curr;
	nscan = ctx->bytes_remaining;
	if (nscan == 0)
		return NULL;
	if (*pscan == '\0')
		/*  This is the normal return point after you have processed
		 *  all of the <name>=<value> pairs in a syntactically-valid
		 *  parameter buffer.
		 */
		return NULL;

	/* skip whitespace */
	while (isspace(*pscan)) {
		pscan++;
		nscan--;
		if (nscan == 0)
			return NULL;
	}

	while (*pscan != ':') {
		if (namesize <= 0) {
			ERRDRV("%s - name too big", __func__);
			return NULL;
		}
		*pnam = toupper(*pscan);
		pnam++;
		namesize--;
		pscan++;
		nscan--;
		if (nscan == 0) {
			ERRDRV("%s - unexpected end of input parsing name",
			       __func__);
			return NULL;
		}
	}
	if (namesize <= 0) {
		ERRDRV("%s - name too big", __func__);
		return NULL;
	}
	*pnam = '\0';
	nam[string_length_no_trail(nam, strlen(nam))] = '\0';

	/* point to char immediately after ":" in "<name>:<value>" */
	pscan++;
	nscan--;
	/* skip whitespace */
	while (isspace(*pscan)) {
		pscan++;
		nscan--;
		if (nscan == 0) {
			ERRDRV("%s - unexpected end of input looking for value",
			       __func__);
			return NULL;
		}
	}
	if (nscan == 0) {
		ERRDRV("%s - unexpected end of input looking for value",
		       __func__);
		return NULL;
	}
	if (*pscan == '\'' || *pscan == '"') {
		closing_quote = *pscan;
		pscan++;
		nscan--;
		if (nscan == 0) {
			ERRDRV("%s - unexpected end of input after %c",
			       __func__, closing_quote);
			return NULL;
		}
	}

	/* look for a separator character, terminator character, or
	 * end of data
	 */
	for (i = 0, value_length = -1; i < nscan; i++) {
		if (closing_quote) {
			if (pscan[i] == '\0') {
				ERRDRV("%s - unexpected end of input parsing quoted value", __func__);
				return NULL;
			}
			if (pscan[i] == closing_quote) {
				value_length = i;
				break;
			}
		} else
		    if (pscan[i] == ',' || pscan[i] == ';'
			|| pscan[i] == '\0') {
			value_length = i;
			break;
		}
	}
	if (value_length < 0) {
		if (closing_quote) {
			ERRDRV("%s - unexpected end of input parsing quoted value", __func__);
			return NULL;
		}
		value_length = nscan;
	}
	orig_value_length = value_length;
	if (closing_quote == 0)
		value_length = string_length_no_trail(pscan, orig_value_length);
	value = kmalloc(value_length + 1, GFP_KERNEL|__GFP_NORETRY);
	if (value == NULL)
		return NULL;
	memcpy(value, pscan, value_length);
	((u8 *) (value))[value_length] = '\0';

	pscan += orig_value_length;
	nscan -= orig_value_length;

	/* skip past separator or closing quote */
	if (nscan > 0) {
		if (*pscan != '\0') {
			pscan++;
			nscan--;
		}
	}

	if (closing_quote && (nscan > 0)) {
		/* we still need to skip around the real separator if present */
		/* first, skip whitespace */
		while (isspace(*pscan)) {
			pscan++;
			nscan--;
			if (nscan == 0)
				break;
		}
		if (nscan > 0) {
			if (*pscan == ',' || *pscan == ';') {
				pscan++;
				nscan--;
			} else if (*pscan != '\0') {
				ERRDRV("%s - missing separator after quoted string", __func__);
				kfree(value);
				value = NULL;
				return NULL;
			}
		}
	}
	ctx->curr = pscan;
	ctx->bytes_remaining = nscan;
	return value;
}

void *
parser_string_get(PARSER_CONTEXT *ctx)
{
	u8 *pscan;
	ulong nscan;
	int value_length = -1;
	void *value = NULL;
	int i;

	if (!ctx)
		return NULL;
	pscan = ctx->curr;
	nscan = ctx->bytes_remaining;
	if (nscan == 0)
		return NULL;
	if (!pscan)
		return NULL;
	for (i = 0, value_length = -1; i < nscan; i++)
		if (pscan[i] == '\0') {
			value_length = i;
			break;
		}
	if (value_length < 0)	/* '\0' was not included in the length */
		value_length = nscan;
	value = kmalloc(value_length + 1, GFP_KERNEL|__GFP_NORETRY);
	if (value == NULL)
		return NULL;
	if (value_length > 0)
		memcpy(value, pscan, value_length);
	((u8 *) (value))[value_length] = '\0';
	return value;
}
