/* 
 *  OpenGGSN - Gateway GPRS Support Node
 *  Copyright (C) 2002 Mondru AB.
 * 
 *  The contents of this file may be used under the terms of the GNU
 *  General Public License Version 2, provided that the above copyright
 *  notice and this permission notice is included in all copies or
 *  substantial portions of the software.
 * 
 */

/*
 * gtpie.c: Contains functions to encapsulate and decapsulate GTP 
 * information elements 
 *
 *
 * Encapsulation
 * - gtpie_tlv, gtpie_tv0, gtpie_tv1, gtpie_tv2 ... Adds information
 * elements to a buffer.
 *
 * Decapsulation
 *  - gtpie_decaps: Returns array with pointers to information elements.
 *  - getie_getie: Returns the pointer of a particular element.
 *  - gtpie_gettlv: Copies tlv information element. Return 0 on success.
 *  - gtpie_gettv: Copies tv information element. Return 0 on success.
 *
 */

#include <../config.h>

#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif

#include <stdio.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <string.h>

#include "gtpie.h"

int gtpie_tlv(void *p, unsigned int *length, unsigned int size, uint8_t t,
	      int l, void *v)
{
	if ((*length + 3 + l) >= size)
		return 1;
	((union gtpie_member *)(p + *length))->tlv.t = hton8(t);
	((union gtpie_member *)(p + *length))->tlv.l = hton16(l);
	memcpy((void *)(p + *length + 3), v, l);
	*length += 3 + l;
	return 0;
}

int gtpie_tv0(void *p, unsigned int *length, unsigned int size, uint8_t t,
	      int l, uint8_t * v)
{
	if ((*length + 1 + l) >= size)
		return 1;
	((union gtpie_member *)(p + *length))->tv0.t = hton8(t);
	memcpy((void *)(p + *length + 1), v, l);
	*length += 1 + l;
	return 0;
}

int gtpie_tv1(void *p, unsigned int *length, unsigned int size, uint8_t t,
	      uint8_t v)
{
	if ((*length + 2) >= size)
		return 1;
	((union gtpie_member *)(p + *length))->tv1.t = hton8(t);
	((union gtpie_member *)(p + *length))->tv1.v = hton8(v);
	*length += 2;
	return 0;
}

int gtpie_tv2(void *p, unsigned int *length, unsigned int size, uint8_t t,
	      uint16_t v)
{
	if ((*length + 3) >= size)
		return 1;
	((union gtpie_member *)(p + *length))->tv2.t = hton8(t);
	((union gtpie_member *)(p + *length))->tv2.v = hton16(v);
	*length += 3;
	return 0;
}

int gtpie_tv4(void *p, unsigned int *length, unsigned int size, uint8_t t,
	      uint32_t v)
{
	if ((*length + 5) >= size)
		return 1;
	((union gtpie_member *)(p + *length))->tv4.t = hton8(t);
	((union gtpie_member *)(p + *length))->tv4.v = hton32(v);
	*length += 5;
	return 0;
}

int gtpie_tv8(void *p, unsigned int *length, unsigned int size, uint8_t t,
	      uint64_t v)
{
	if ((*length + 9) >= size)
		return 1;
	((union gtpie_member *)(p + *length))->tv8.t = hton8(t);
	((union gtpie_member *)(p + *length))->tv8.v = hton64(v);
	*length += 9;
	return 0;
}

int gtpie_getie(union gtpie_member *ie[], int type, int instance)
{
	int j;
	for (j = 0; j < GTPIE_SIZE; j++) {
		if ((ie[j] != 0) && (ie[j]->t == type)) {
			if (instance-- == 0)
				return j;
		}
	}
	return -1;
}

int gtpie_exist(union gtpie_member *ie[], int type, int instance)
{
	int j;
	for (j = 0; j < GTPIE_SIZE; j++) {
		if ((ie[j] != 0) && (ie[j]->t == type)) {
			if (instance-- == 0)
				return 1;
		}
	}
	return 0;
}

int gtpie_gettlv(union gtpie_member *ie[], int type, int instance,
		 unsigned int *length, void *dst, unsigned int size)
{
	int ien;
	ien = gtpie_getie(ie, type, instance);
	if (ien >= 0) {
		*length = ntoh16(ie[ien]->tlv.l);
		if (*length <= size)
			memcpy(dst, ie[ien]->tlv.v, *length);
		else
			return EOF;
	}
	return 0;
}

int gtpie_gettv0(union gtpie_member *ie[], int type, int instance,
		 void *dst, unsigned int size)
{
	int ien;
	ien = gtpie_getie(ie, type, instance);
	if (ien >= 0)
		memcpy(dst, ie[ien]->tv0.v, size);
	else
		return EOF;
	return 0;
}

int gtpie_gettv1(union gtpie_member *ie[], int type, int instance,
		 uint8_t * dst)
{
	int ien;
	ien = gtpie_getie(ie, type, instance);
	if (ien >= 0)
		*dst = ntoh8(ie[ien]->tv1.v);
	else
		return EOF;
	return 0;
}

int gtpie_gettv2(union gtpie_member *ie[], int type, int instance,
		 uint16_t * dst)
{
	int ien;
	ien = gtpie_getie(ie, type, instance);
	if (ien >= 0)
		*dst = ntoh16(ie[ien]->tv2.v);
	else
		return EOF;
	return 0;
}

int gtpie_gettv4(union gtpie_member *ie[], int type, int instance,
		 uint32_t * dst)
{
	int ien;
	ien = gtpie_getie(ie, type, instance);
	if (ien >= 0)
		*dst = ntoh32(ie[ien]->tv4.v);
	else
		return EOF;
	return 0;
}

int gtpie_gettv8(union gtpie_member *ie[], int type, int instance,
		 uint64_t * dst)
{
	int ien;
	ien = gtpie_getie(ie, type, instance);
	if (ien >= 0)
		*dst = ntoh64(ie[ien]->tv8.v);
	else
		return EOF;
	return 0;
}

int gtpie_decaps(union gtpie_member *ie[], int version, void *pack,
		 unsigned len)
{
	int i;
	int j = 0;
	unsigned char *p;
	unsigned char *end;

	end = (unsigned char *)pack + len;
	p = pack;

	memset(ie, 0, sizeof(union gtpie_member *) * GTPIE_SIZE);

	while ((p < end) && (j < GTPIE_SIZE)) {
		if (GTPIE_DEBUG) {
			printf("The packet looks like this:\n");
			for (i = 0; i < (end - p); i++) {
				printf("%02x ",
				       (unsigned char)*(char *)(p + i));
				if (!((i + 1) % 16))
					printf("\n");
			};
			printf("\n");
		}

		switch (*p) {
		case GTPIE_CAUSE:	/* TV GTPIE types with value length 1 */
		case GTPIE_REORDER:
		case GTPIE_MAP_CAUSE:
		case GTPIE_MS_VALIDATED:
		case GTPIE_RECOVERY:
		case GTPIE_SELECTION_MODE:
		case GTPIE_TEARDOWN:
		case GTPIE_NSAPI:
		case GTPIE_RANAP_CAUSE:
		case GTPIE_RP_SMS:
		case GTPIE_RP:
		case GTPIE_MS_NOT_REACH:
			if (j < GTPIE_SIZE) {
				ie[j] = (union gtpie_member *)p;
				if (GTPIE_DEBUG)
					printf
					    ("GTPIE TV1 found. Type %d, value %d\n",
					     ie[j]->tv1.t, ie[j]->tv1.v);
				p += 1 + 1;
				j++;
			}
			break;
		case GTPIE_FL_DI:	/* TV GTPIE types with value length 2 or 4 */
		case GTPIE_FL_C:
			if (version != 0) {
				if (j < GTPIE_SIZE) {	/* GTPIE_TEI_DI & GTPIE_TEI_C with length 4 */
					/* case GTPIE_TEI_DI: gtp1 */
					/* case GTPIE_TEI_C:  gtp1 */
					ie[j] = (union gtpie_member *)p;
					if (GTPIE_DEBUG)
						printf
						    ("GTPIE TV 4 found. Type %d, value %d\n",
						     ie[j]->tv4.t,
						     ie[j]->tv4.v);
					p += 1 + 4;
					j++;
				}
				break;
			}
		case GTPIE_PFI:	/* TV GTPIE types with value length 2 */
		case GTPIE_CHARGING_C:
		case GTPIE_TRACE_REF:
		case GTPIE_TRACE_TYPE:
			if (j < GTPIE_SIZE) {
				ie[j] = (union gtpie_member *)p;
				if (GTPIE_DEBUG)
					printf
					    ("GTPIE TV2 found. Type %d, value %d\n",
					     ie[j]->tv2.t, ie[j]->tv2.v);
				p += 1 + 2;
				j++;
			}
			break;
		case GTPIE_QOS_PROFILE0:	/* TV GTPIE types with value length 3 */
		case GTPIE_P_TMSI_S:
			if (j < GTPIE_SIZE) {
				ie[j] = (union gtpie_member *)p;
				if (GTPIE_DEBUG)
					printf
					    ("GTPIE TV 3 found. Type %d, value %d, %d, %d\n",
					     ie[j]->tv0.t, ie[j]->tv0.v[0],
					     ie[j]->tv0.v[1], ie[j]->tv0.v[2]);
				p += 1 + 3;
				j++;
			}
			break;
		case GTPIE_TLLI:	/* TV GTPIE types with value length 4 */
		case GTPIE_P_TMSI:
		case GTPIE_CHARGING_ID:
			/* case GTPIE_TEI_DI: Handled by GTPIE_FL_DI */
			/* case GTPIE_TEI_C:  Handled by GTPIE_FL_DI */
			if (j < GTPIE_SIZE) {
				ie[j] = (union gtpie_member *)p;
				if (GTPIE_DEBUG)
					printf
					    ("GTPIE TV 4 found. Type %d, value %d\n",
					     ie[j]->tv4.t, ie[j]->tv4.v);
				p += 1 + 4;
				j++;
			}
			break;
		case GTPIE_TEI_DII:	/* TV GTPIE types with value length 5 */
			if (j < GTPIE_SIZE) {
				ie[j] = (union gtpie_member *)p;
				if (GTPIE_DEBUG)
					printf("GTPIE TV 5 found. Type %d\n",
					       ie[j]->tv0.t);
				p += 1 + 5;
				j++;
			}
			break;
		case GTPIE_RAB_CONTEXT:	/* TV GTPIE types with value length 7 */
			if (j < GTPIE_SIZE) {
				ie[j] = (union gtpie_member *)p;
				if (GTPIE_DEBUG)
					printf("GTPIE TV 7 found. Type %d\n",
					       ie[j]->tv0.t);
				p += 1 + 7;
				j++;
			}
			break;
		case GTPIE_IMSI:	/* TV GTPIE types with value length 8 */
			if (j < GTPIE_SIZE) {
				ie[j] = (union gtpie_member *)p;
				if (GTPIE_DEBUG)
					printf
					    ("GTPIE_IMSI - GTPIE TV 8 found. Type %d, value 0x%llx\n",
					     ie[j]->tv0.t, ie[j]->tv8.v);
				p += 1 + 8;
				j++;
			}
			break;
		case GTPIE_RAI:	/* TV GTPIE types with value length 6 */
			if (j < GTPIE_SIZE) {
				ie[j] = (union gtpie_member *)p;
				if (GTPIE_DEBUG)
					printf
					    ("GTPIE_RAI - GTPIE TV 6 found. Type %d, value 0x%llx\n",
					     ie[j]->tv0.t, ie[j]->tv8.v);
				p += 1 + 6;
				j++;
			}
			break;
		case GTPIE_AUTH_TRIPLET:	/* TV GTPIE types with value length 28 */
			if (j < GTPIE_SIZE) {
				ie[j] = (union gtpie_member *)p;
				if (GTPIE_DEBUG)
					printf("GTPIE TV 28 found. Type %d\n",
					       ie[j]->tv0.t);
				p += 1 + 28;
				j++;
			}
			break;
		case GTPIE_EXT_HEADER_T:	/* GTP extension header */
			if (j < GTPIE_SIZE) {
				ie[j] = (union gtpie_member *)p;
				if (GTPIE_DEBUG)
					printf
					    ("GTPIE GTP extension header found. Type %d\n",
					     ie[j]->ext.t);
				p += 2 + ntoh8(ie[j]->ext.l);
				j++;
			}
			break;
		case GTPIE_EUA:	/* TLV GTPIE types with variable length */
		case GTPIE_MM_CONTEXT:
		case GTPIE_PDP_CONTEXT:
		case GTPIE_APN:
		case GTPIE_PCO:
		case GTPIE_GSN_ADDR:
		case GTPIE_MSISDN:
		case GTPIE_QOS_PROFILE:
		case GTPIE_AUTH_QUINTUP:
		case GTPIE_TFT:
		case GTPIE_TARGET_INF:
		case GTPIE_UTRAN_TRANS:
		case GTPIE_RAB_SETUP:
		case GTPIE_TRIGGER_ID:
		case GTPIE_OMC_ID:
		case GTPIE_CHARGING_ADDR:
		case GTPIE_RAT_TYPE:
		case GTPIE_USER_LOC:
		case GTPIE_MS_TZ:
		case GTPIE_IMEI_SV:
		case GTPIE_PRIVATE:
			if (j < GTPIE_SIZE) {
				ie[j] = (union gtpie_member *)p;
				if (GTPIE_DEBUG)
					printf("GTPIE TLV found. Type %d\n",
					       ie[j]->tlv.t);
				p += 3 + ntoh16(ie[j]->tlv.l);
				j++;
			}
			break;
		default:
			if (GTPIE_DEBUG)
				printf("GTPIE something unknown. Type %d\n",
				       *p);
			return EOF;	/* We received something unknown */
		}
	}
	if (p == end) {
		if (GTPIE_DEBUG)
			printf("GTPIE normal return. %lx %lx\n",
			       (unsigned long)p, (unsigned long)end);
		return 0;	/* We landed at the end of the packet: OK */
	} else if (!(j < GTPIE_SIZE)) {
		if (GTPIE_DEBUG)
			printf("GTPIE too many elements.\n");
		return EOF;	/* We received too many information elements */
	} else {
		if (GTPIE_DEBUG)
			printf("GTPIE exceeded end of packet. %lx %lx\n",
			       (unsigned long)p, (unsigned long)end);
		return EOF;	/* We exceeded the end of the packet: Error */
	}
}

int gtpie_encaps(union gtpie_member *ie[], void *pack, unsigned *len)
{
	int i;
	unsigned char *p;
	unsigned char *end;
	union gtpie_member *m;
	int iesize;

	p = pack;

	memset(pack, 0, GTPIE_MAX);
	end = p + GTPIE_MAX;
	for (i = 1; i < GTPIE_SIZE; i++)
		if (ie[i] != 0) {
			if (GTPIE_DEBUG)
				printf("gtpie_encaps. Type %d\n", i);
			m = (union gtpie_member *)p;
			switch (i) {
			case GTPIE_CAUSE:	/* TV GTPIE types with value length 1 */
			case GTPIE_REORDER:
			case GTPIE_MAP_CAUSE:
			case GTPIE_MS_VALIDATED:
			case GTPIE_RECOVERY:
			case GTPIE_SELECTION_MODE:
			case GTPIE_TEARDOWN:
			case GTPIE_NSAPI:
			case GTPIE_RANAP_CAUSE:
			case GTPIE_RP_SMS:
			case GTPIE_RP:
			case GTPIE_MS_NOT_REACH:
				iesize = 2;
				break;
			case GTPIE_FL_DI:	/* TV GTPIE types with value length 2 */
			case GTPIE_FL_C:
			case GTPIE_PFI:
			case GTPIE_CHARGING_C:
			case GTPIE_TRACE_REF:
			case GTPIE_TRACE_TYPE:
				iesize = 3;
				break;
			case GTPIE_QOS_PROFILE0:	/* TV GTPIE types with value length 3 */
			case GTPIE_P_TMSI_S:
				iesize = 4;
				break;
			case GTPIE_TLLI:	/* TV GTPIE types with value length 4 */
			case GTPIE_P_TMSI:
				/* case GTPIE_TEI_DI: only in gtp1 */
				/* case GTPIE_TEI_C: only in gtp1 */
			case GTPIE_CHARGING_ID:
				iesize = 5;
				break;
			case GTPIE_TEI_DII:	/* TV GTPIE types with value length 5 */
				iesize = 6;
				break;
			case GTPIE_RAB_CONTEXT:	/* TV GTPIE types with value length 7 */
				iesize = 8;
				break;
			case GTPIE_IMSI:	/* TV GTPIE types with value length 8 */
			case GTPIE_RAI:
				iesize = 9;
				break;
			case GTPIE_AUTH_TRIPLET:	/* TV GTPIE types with value length 28 */
				iesize = 29;
				break;
			case GTPIE_EXT_HEADER_T:	/* GTP extension header */
				iesize = 2 + hton8(ie[i]->ext.l);
				break;
			case GTPIE_EUA:	/* TLV GTPIE types with length length 2 */
			case GTPIE_MM_CONTEXT:
			case GTPIE_PDP_CONTEXT:
			case GTPIE_APN:
			case GTPIE_PCO:
			case GTPIE_GSN_ADDR:
			case GTPIE_MSISDN:
			case GTPIE_QOS_PROFILE:
			case GTPIE_AUTH_QUINTUP:
			case GTPIE_TFT:
			case GTPIE_TARGET_INF:
			case GTPIE_UTRAN_TRANS:
			case GTPIE_RAB_SETUP:
			case GTPIE_TRIGGER_ID:
			case GTPIE_OMC_ID:
			case GTPIE_CHARGING_ADDR:
			case GTPIE_PRIVATE:
				iesize = 3 + hton16(ie[i]->tlv.l);
				break;
			default:
				return 2;	/* We received something unknown */
			}
			if (p + iesize < end) {
				memcpy(p, ie[i], iesize);
				p += iesize;
				*len += iesize;
			} else
				return 2;	/* Out of space */
		}
	return 0;
}

int gtpie_encaps2(union gtpie_member ie[], unsigned int size,
		  void *pack, unsigned *len)
{
	unsigned int i, j;
	unsigned char *p;
	unsigned char *end;
	union gtpie_member *m;
	int iesize;

	p = pack;

	memset(pack, 0, GTPIE_MAX);
	end = p + GTPIE_MAX;
	for (j = 0; j < GTPIE_SIZE; j++)
		for (i = 0; i < size; i++)
			if (ie[i].t == j) {
				if (GTPIE_DEBUG)
					printf
					    ("gtpie_encaps. Number %d, Type %d\n",
					     i, ie[i].t);
				m = (union gtpie_member *)p;
				switch (ie[i].t) {
				case GTPIE_CAUSE:	/* TV GTPIE types with value length 1 */
				case GTPIE_REORDER:
				case GTPIE_MAP_CAUSE:
				case GTPIE_MS_VALIDATED:
				case GTPIE_RECOVERY:
				case GTPIE_SELECTION_MODE:
				case GTPIE_TEARDOWN:
				case GTPIE_NSAPI:
				case GTPIE_RANAP_CAUSE:
				case GTPIE_RP_SMS:
				case GTPIE_RP:
				case GTPIE_MS_NOT_REACH:
					iesize = 2;
					break;
				case GTPIE_PFI:	/* TV GTPIE types with value length 2 */
				case GTPIE_CHARGING_C:
				case GTPIE_TRACE_REF:
				case GTPIE_TRACE_TYPE:
					iesize = 3;
					break;
				case GTPIE_QOS_PROFILE0:	/* TV GTPIE types with value length 3 */
				case GTPIE_P_TMSI_S:
					iesize = 4;
					break;
				case GTPIE_TLLI:	/* TV GTPIE types with value length 4 */
				case GTPIE_P_TMSI:
				case GTPIE_TEI_DI:
				case GTPIE_TEI_C:
					iesize = 5;
					break;
				case GTPIE_TEI_DII:	/* TV GTPIE types with value length 5 */
					iesize = 6;
					break;
				case GTPIE_RAB_CONTEXT:	/* TV GTPIE types with value length 7 */
					iesize = 8;
					break;
				case GTPIE_IMSI:	/* TV GTPIE types with value length 8 */
				case GTPIE_RAI:
					iesize = 9;
					break;
				case GTPIE_AUTH_TRIPLET:	/* TV GTPIE types with value length 28 */
					iesize = 29;
					break;
				case GTPIE_EXT_HEADER_T:	/* GTP extension header */
					iesize = 2 + hton8(ie[i].ext.l);
					break;
				case GTPIE_CHARGING_ID:	/* TLV GTPIE types with length length 2 */
				case GTPIE_EUA:
				case GTPIE_MM_CONTEXT:
				case GTPIE_PDP_CONTEXT:
				case GTPIE_APN:
				case GTPIE_PCO:
				case GTPIE_GSN_ADDR:
				case GTPIE_MSISDN:
				case GTPIE_QOS_PROFILE:
				case GTPIE_AUTH_QUINTUP:
				case GTPIE_TFT:
				case GTPIE_TARGET_INF:
				case GTPIE_UTRAN_TRANS:
				case GTPIE_RAB_SETUP:
				case GTPIE_TRIGGER_ID:
				case GTPIE_OMC_ID:
				case GTPIE_CHARGING_ADDR:
				case GTPIE_PRIVATE:
					iesize = 3 + hton16(ie[i].tlv.l);
					break;
				default:
					return 2;	/* We received something unknown */
				}
				if (p + iesize < end) {
					memcpy(p, &ie[i], iesize);
					p += iesize;
					*len += iesize;
				} else
					return 2;	/* Out of space */
			}
	return 0;
}
