/* 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;
	struct memregion *rgn = NULL;
	struct spar_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 = (struct spar_controlvm_parameters_header *)(ctx->data);
	if (phdr->total_length != bytes) {
		ERRDRV("%s - bad total length %lu (should be %lu)",
		       __func__,
		       (ulong) (phdr->total_length), (ulong) (bytes));
		rc = NULL;
		goto Away;
	}
	if (phdr->total_length < phdr->header_length) {
		ERRDRV("%s - total length < header length (%lu < %lu)",
		       __func__,
		       (ulong) (phdr->total_length),
		       (ulong) (phdr->header_length));
		rc = NULL;
		goto Away;
	}
	if (phdr->header_length <
	    sizeof(struct spar_controlvm_parameters_header)) {
		ERRDRV("%s - header is too small (%lu < %lu)",
		       __func__,
		       (ulong) (phdr->header_length),
		       (ulong)(sizeof(
				struct spar_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 struct spar_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)
{
	struct spar_controlvm_parameters_header *phdr = NULL;

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

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

	if (ctx == NULL) {
		ERRDRV("%s (%s:%d) - no context",
		       __func__, __FILE__, __LINE__);
		goto Away;
	}
	phdr = (struct spar_controlvm_parameters_header *)(ctx->data);
	switch (which_string) {
	case PARSERSTRING_INITIATOR:
		ctx->curr = ctx->data + phdr->initiator_offset;
		ctx->bytes_remaining = phdr->initiator_length;
		break;
	case PARSERSTRING_TARGET:
		ctx->curr = ctx->data + phdr->target_offset;
		ctx->bytes_remaining = phdr->target_length;
		break;
	case PARSERSTRING_CONNECTION:
		ctx->curr = ctx->data + phdr->connection_offset;
		ctx->bytes_remaining = phdr->connection_length;
		break;
	case PARSERSTRING_NAME:
		ctx->curr = ctx->data + phdr->name_offset;
		ctx->bytes_remaining = phdr->name_length;
		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;
}
