/* Copyright 2004 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu)
 *
 * 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.  See the          
 * GNU General Public License for more details.                           
 *                                                                         
 * You should have received a copy of the GNU General Public License      
 * along with this program; if not, write to the Free Software            
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */


#include <stdio.h>			/* *printf */
#include <string.h>			/* mem* */

#include "ipset.h"

#include <linux/netfilter_ipv4/ip_set_keyword.h>

/* Initialize the create. */
static void
keyword_create_init(void *data UNUSED)
{
	struct ip_set_req_keyword_create *mydata = data;
	
	mydata->size = 0;
	
	return;
}

/* Function which parses command options; returns true if it ate an option */
static int
keyword_create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
{
	return 1;
}

/* Final check; exit if not ok. */
static void
keyword_create_final(void *data, unsigned int flags)
{
	return;
}

/* Create commandline options */
static const struct option create_opts[] = {
	{NULL},
};

/* Add, del, test parser */
static ip_set_ip_t
keyword_adt_parser(int cmd UNUSED, const char *arg, void *data)
{
	struct ip_set_req_keyword *mydata = data;

	DP("%s", arg);

	if (strlen(arg) < IP_SET_KEYWORD_MAXCONTENTSLEN)
		strcpy(mydata->contents, arg);
	else
		exit_error(PARAMETER_PROBLEM,
			   "Content length is too large. Max content lengh is %d\n",
			   IP_SET_KEYWORD_MAXCONTENTSLEN);
	return 1;	
}

/*
 * Print and save
 */

static void
keyword_initheader(struct set *set, const void *data)
{
	const struct ip_set_req_keyword_create *header = data;
	struct ip_set_req_keyword_create *map = set->settype->header;
		
	memset(map, 0, sizeof(struct ip_set_req_keyword_create));
	map->size = header->size;
}

static void
keyword_printheader(struct set *set, unsigned options)
{
	printf("%s %s\n", 
	       set->name,
	       set->settype->typename);

}

static void
keyword_printips_sorted(struct set *set, void *data,
			u_int32_t len, unsigned options,
			char dont_align)
{
	struct ip_set_req_keyword *ip;
	size_t offset = 0;

	while (offset < len) {
		ip = data + offset;
		printf("%s\n", ip->contents);
		offset += sizeof(struct ip_set_req_keyword);
	}
}

static void
keyword_saveheader(struct set *set, unsigned options)
{
	printf("-N %s %s\n", 
	       set->name,
	       set->settype->typename);
}

static void
keyword_saveips(struct set *set, void *data,
		u_int32_t len, unsigned options,
		char dont_align)
{
	struct ip_set_req_keyword *ip;
	size_t offset = 0;
		
	while (offset < len) {
		ip = data + offset;
		printf("-A %s %s\n", set->name, ip->contents);
		offset += sizeof(struct ip_set_req_keyword);
	}
}

static void
keyword_usage(void)
{
	printf
	    ("-N set keyword\n"
	     "-A set CONTENTS\n"
	     "-D set CONTENTS\n"
	     "-T set CONTENTS\n");
}

static struct settype settype_keyword = {
	.typename = SETTYPE_NAME,
	.protocol_version = IP_SET_PROTOCOL_VERSION,

	/* Create */
	.create_size = sizeof(struct ip_set_req_keyword_create),
	.create_init = keyword_create_init,
	.create_parse = keyword_create_parse,
	.create_final = keyword_create_final,
	.create_opts = create_opts,

	/* Add/del/test */
	.adt_size = sizeof(struct ip_set_req_keyword),
	.adt_parser = keyword_adt_parser,

	/* Printing */
	.header_size = sizeof(struct ip_set_req_keyword_create),
	.initheader = keyword_initheader,
	.printheader = keyword_printheader,
	.printips = keyword_printips_sorted,
	.printips_sorted = keyword_printips_sorted,
	.saveheader = keyword_saveheader,
	.saveips = keyword_saveips,
	
	.usage = keyword_usage,
};

CONSTRUCTOR(keyword)
{
	settype_register(&settype_keyword);

}
