%{
/*
 * (C) 2012 by Pablo Neira Ayuso <pablo@netfilter.org>
 *
 * 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 software has been sponsored by Sophos Astaro <http://www.sophos.com>
 */

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <stdarg.h>
#include <libiptc/linux_list.h>
#include <libnftnl/table.h>
#include <libnftnl/chain.h>

#include <netinet/in.h>
#include <linux/netfilter.h>

extern char *yytext;
extern int yylineno;

static LIST_HEAD(xtables_stack);

struct stack_elem {
	struct list_head	head;
	int			token;
	size_t			size;
	char			data[];
};

static void *stack_push(int token, size_t size)
{
	struct stack_elem *e;

	e = calloc(1, sizeof(struct stack_elem) + size);

	e->token = token;
	e->size = size;

	list_add(&e->head, &xtables_stack);

	return e->data;
}

static struct stack_elem *stack_pop(void)
{
	struct stack_elem *e;

	e = list_entry(xtables_stack.next, struct stack_elem, head);

	if (&e->head == &xtables_stack)
		return NULL;

	list_del(&e->head);
	return e;
}

static inline void stack_put_i32(void *data, int value)
{
	memcpy(data, &value, sizeof(int));
}

static inline void stack_put_str(void *data, const char *str)
{
	memcpy(data, str, strlen(str));
}

static void stack_free(struct stack_elem *e)
{
	free(e);
}

%}

%union {
	int	val;
	char	*string;
}

%token T_FAMILY
%token T_TABLE
%token T_CHAIN
%token T_HOOK
%token T_PRIO

%token <string> T_STRING
%token <val>	T_INTEGER

%%

configfile	:
		| lines
		;

lines		: line
		| lines line
		;

line		: family
		;

family		: T_FAMILY T_STRING '{' tables '}'
		{
			void *data = stack_push(T_FAMILY, strlen($2)+1);
			stack_put_str(data, $2);
		}
		;

tables		: table
		| tables table
		;

table		: T_TABLE T_STRING '{' chains '}'
		{
			/* added in reverse order to pop it in order */
			void *data = stack_push(T_TABLE, strlen($2)+1);
			stack_put_str(data, $2);
		}
		;

chains		: chain
		| chains chain
		;

chain		: T_CHAIN T_STRING T_HOOK T_STRING T_PRIO T_INTEGER
		{
			/* added in reverse order to pop it in order */
			void *data = stack_push(T_PRIO, sizeof(int32_t));
			stack_put_i32(data, $6);
			data = stack_push(T_HOOK, strlen($4)+1);
			stack_put_str(data, $4);
			data = stack_push(T_CHAIN, strlen($2)+1);
			stack_put_str(data, $2);
		}
		;

%%

int __attribute__((noreturn))
yyerror(char *msg)
{
	fprintf(stderr, "parsing config file in line (%d), symbol '%s': %s\n",
			 yylineno, yytext, msg);
	exit(EXIT_FAILURE);
}

static int hooknametonum(const char *hookname)
{
	if (strcmp(hookname, "NF_INET_LOCAL_IN") == 0)
		return NF_INET_LOCAL_IN;
	else if (strcmp(hookname, "NF_INET_FORWARD") == 0)
		return NF_INET_FORWARD;
	else if (strcmp(hookname, "NF_INET_LOCAL_OUT") == 0)
		return NF_INET_LOCAL_OUT;
	else if (strcmp(hookname, "NF_INET_PRE_ROUTING") == 0)
		return NF_INET_PRE_ROUTING;
	else if (strcmp(hookname, "NF_INET_POST_ROUTING") == 0)
		return NF_INET_POST_ROUTING;

	return -1;
}

static int32_t familytonumber(const char *family)
{
	if (strcmp(family, "ipv4") == 0)
		return AF_INET;
	else if (strcmp(family, "ipv6") == 0)
		return AF_INET6;

	return -1;
}

int xtables_config_parse(char *filename, struct nft_table_list *table_list,
			 struct nft_chain_list *chain_list)
{
	FILE *fp;
	struct stack_elem *e;
	struct nft_table *table = NULL;
	struct nft_chain *chain = NULL;
	int prio = 0;
	int32_t family = 0;

	fp = fopen(filename, "r");
	if (!fp)
		return -1;

	yyrestart(fp);
	yyparse();
	fclose(fp);

	for (e = stack_pop(); e != NULL; e = stack_pop()) {
		switch(e->token) {
		case T_FAMILY:
			family = familytonumber(e->data);
			if (family == -1)
				return -1;
			break;
		case T_TABLE:
			table = nft_table_alloc();
			if (table == NULL) {
				perror("nft_table_alloc");
				return -1;
			}
			nft_table_attr_set_u32(table, NFT_TABLE_ATTR_FAMILY, family);
			nft_table_attr_set(table, NFT_TABLE_ATTR_NAME, e->data);
			/* This is intentionally prepending, instead of
			 * appending, since the elements in the stack are in
			 * the reverse order that chains appear in the
			 * configuration file.
			 */
			nft_table_list_add(table, table_list);
			break;
		case T_PRIO:
			memcpy(&prio, e->data, sizeof(int32_t));
			break;
		case T_CHAIN:
			chain = nft_chain_alloc();
			if (chain == NULL) {
				perror("nft_chain_alloc");
				return -1;
			}
			nft_chain_attr_set(chain, NFT_CHAIN_ATTR_TABLE,
				(char *)nft_table_attr_get(table, NFT_TABLE_ATTR_NAME));
			nft_chain_attr_set_u32(chain, NFT_CHAIN_ATTR_FAMILY,
				nft_table_attr_get_u32(table, NFT_TABLE_ATTR_FAMILY));
			nft_chain_attr_set_s32(chain, NFT_CHAIN_ATTR_PRIO, prio);
			nft_chain_attr_set(chain, NFT_CHAIN_ATTR_NAME, e->data);
			/* Intentionally prepending, instead of appending */
			nft_chain_list_add(chain, chain_list);
			break;
		case T_HOOK:
			nft_chain_attr_set_u32(chain, NFT_CHAIN_ATTR_HOOKNUM,
						hooknametonum(e->data));
			break;
		default:
			printf("unknown token type %d\n", e->token);
			break;
		}
		stack_free(e);
	}

	return 0;
}
