/* Shared library add-on to iptables to add LOG support. */
#include <stdio.h>
#include <netdb.h>
#include <string.h>
#include <stdlib.h>
#include <syslog.h>
#include <getopt.h>
#include <ip6tables.h>
#include <linux/netfilter_ipv6/ip6_tables.h>
#include <linux/netfilter_ipv6/ip6t_LOG.h>

#define LOG_DEFAULT_LEVEL LOG_WARNING

/* Function which prints out usage message. */
static void
help(void)
{
	printf(
"LOG v%s options:\n"
" --log-level level		Level of logging (numeric or see syslog.conf)\n"
" --log-prefix prefix		Prefix log messages with this prefix.\n\n"
" --log-tcp-sequence		Log TCP sequence numbers.\n\n"
" --log-tcp-options		Log TCP options.\n\n"
" --log-ip-options		Log IP options.\n\n",
NETFILTER_VERSION);
}

static struct option opts[] = {
	{ "log-level", 1, 0, '!' },
	{ "log-prefix", 1, 0, '#' },
	{ "log-tcp-sequence", 0, 0, '1' },
	{ "log-tcp-options", 0, 0, '2' },
	{ "log-ip-options", 0, 0, '3' },
	{ 0 }
};

/* Initialize the target. */
static void
init(struct ip6t_entry_target *t, unsigned int *nfcache)
{
	struct ip6t_log_info *loginfo = (struct ip6t_log_info *)t->data;

	loginfo->level = LOG_DEFAULT_LEVEL;

	/* Can't cache this */
	*nfcache |= NFC_UNKNOWN;
}

struct ip6t_log_names {
	const char *name;
	unsigned int level;
};

static struct ip6t_log_names ip6t_log_names[]
= { { "alert", LOG_ALERT },
    { "crit", LOG_CRIT },
    { "debug", LOG_DEBUG },
    { "emerg", LOG_EMERG },
    { "error", LOG_ERR },		/* DEPRECATED */
    { "info", LOG_INFO },
    { "notice", LOG_NOTICE },
    { "panic", LOG_EMERG },		/* DEPRECATED */
    { "warning", LOG_WARNING }
};

static u_int8_t
parse_level(const char *level)
{
	int lev;

	lev = string_to_number(level, 0, 7);
	if (lev == -1) {
		unsigned int i = 0;

		for (i = 0;
		     i < sizeof(ip6t_log_names) / sizeof(struct ip6t_log_names);
		     i++) {
			if (strncasecmp(level, ip6t_log_names[i].name,
					strlen(level)) == 0) {
				if (lev != -1)
					exit_error(PARAMETER_PROBLEM,
						   "log-level `%s' ambiguous",
						   level);
				lev = ip6t_log_names[i].level;
			}
		}

		if (lev == -1)
			exit_error(PARAMETER_PROBLEM,
				   "log-level `%s' unknown", level);
	}

	return (u_int8_t)lev;
}

#define IP6T_LOG_OPT_LEVEL 0x01
#define IP6T_LOG_OPT_PREFIX 0x02
#define IP6T_LOG_OPT_TCPSEQ 0x04
#define IP6T_LOG_OPT_TCPOPT 0x08
#define IP6T_LOG_OPT_IPOPT 0x10

/* Function which parses command options; returns true if it
   ate an option */
static int
parse(int c, char **argv, int invert, unsigned int *flags,
      const struct ip6t_entry *entry,
      struct ip6t_entry_target **target)
{
	struct ip6t_log_info *loginfo = (struct ip6t_log_info *)(*target)->data;

	switch (c) {
	case '!':
		if (*flags & IP6T_LOG_OPT_LEVEL)
			exit_error(PARAMETER_PROBLEM,
				   "Can't specify --log-level twice");

		if (check_inverse(optarg, &invert))
			exit_error(PARAMETER_PROBLEM,
				   "Unexpected `!' after --log-level");

		loginfo->level = parse_level(optarg);
		*flags |= IP6T_LOG_OPT_LEVEL;
		break;

	case '#':
		if (*flags & IP6T_LOG_OPT_PREFIX)
			exit_error(PARAMETER_PROBLEM,
				   "Can't specify --log-prefix twice");

		if (check_inverse(optarg, &invert))
			exit_error(PARAMETER_PROBLEM,
				   "Unexpected `!' after --log-prefix");

		if (strlen(optarg) > sizeof(loginfo->prefix) - 1)
			exit_error(PARAMETER_PROBLEM,
				   "Maximum prefix length %u for --log-prefix",
				   sizeof(loginfo->prefix) - 1);

		strcpy(loginfo->prefix, optarg);
		*flags |= IP6T_LOG_OPT_PREFIX;
		break;

	case '1':
		if (*flags & IP6T_LOG_OPT_TCPSEQ)
			exit_error(PARAMETER_PROBLEM,
				   "Can't specify --log-tcp-sequence "
				   "twice");

		loginfo->logflags |= IP6T_LOG_TCPSEQ;
		*flags |= IP6T_LOG_OPT_TCPSEQ;
		break;

	case '2':
		if (*flags & IP6T_LOG_OPT_TCPOPT)
			exit_error(PARAMETER_PROBLEM,
				   "Can't specify --log-tcp-options twice");

		loginfo->logflags |= IP6T_LOG_TCPOPT;
		*flags |= IP6T_LOG_OPT_TCPOPT;
		break;

	case '3':
		if (*flags & IP6T_LOG_OPT_IPOPT)
			exit_error(PARAMETER_PROBLEM,
				   "Can't specify --log-ip-options twice");

		loginfo->logflags |= IP6T_LOG_IPOPT;
		*flags |= IP6T_LOG_OPT_IPOPT;
		break;

	default:
		return 0;
	}

	return 1;
}

/* Final check; nothing. */
static void final_check(unsigned int flags)
{
}

/* Prints out the targinfo. */
static void
print(const struct ip6t_ip6 *ip,
      const struct ip6t_entry_target *target,
      int numeric)
{
	const struct ip6t_log_info *loginfo
		= (const struct ip6t_log_info *)target->data;
	unsigned int i = 0;

	printf("LOG ");
	if (numeric)
		printf("flags %u level %u ",
		       loginfo->logflags, loginfo->level);
	else {
		for (i = 0;
		     i < sizeof(ip6t_log_names) / sizeof(struct ip6t_log_names);
		     i++) {
			if (loginfo->level == ip6t_log_names[i].level) {
				printf("level %s ", ip6t_log_names[i].name);
				break;
			}
		}
		if (i == sizeof(ip6t_log_names) / sizeof(struct ip6t_log_names))
			printf("UNKNOWN level %u ", loginfo->level);
		if (loginfo->logflags & IP6T_LOG_TCPSEQ)
			printf("tcp-sequence ");
		if (loginfo->logflags & IP6T_LOG_TCPOPT)
			printf("tcp-options ");
		if (loginfo->logflags & IP6T_LOG_IPOPT)
			printf("ip-options ");
		if (loginfo->logflags & ~(IP6T_LOG_MASK))
			printf("unknown-flags ");
	}

	if (strcmp(loginfo->prefix, "") != 0)
		printf("prefix `%s' ", loginfo->prefix);
}

/* Saves the union ip6t_targinfo in parsable form to stdout. */
static void
save(const struct ip6t_ip6 *ip, const struct ip6t_entry_target *target)
{
	const struct ip6t_log_info *loginfo
		= (const struct ip6t_log_info *)target->data;

	if (strcmp(loginfo->prefix, "") != 0)
		printf("--log-prefix %s ", loginfo->prefix);

	if (loginfo->level != LOG_DEFAULT_LEVEL)
		printf("--log-level %u ", loginfo->level);

	if (loginfo->logflags & IP6T_LOG_TCPSEQ)
		printf("--log-tcp-sequence ");
	if (loginfo->logflags & IP6T_LOG_TCPOPT)
		printf("--log-tcp-options ");
	if (loginfo->logflags & IP6T_LOG_IPOPT)
		printf("--log-ip-options ");
}

struct ip6tables_target log
= { NULL,
    "LOG",
    NETFILTER_VERSION,
    IP6T_ALIGN(sizeof(struct ip6t_log_info)),
    IP6T_ALIGN(sizeof(struct ip6t_log_info)),
    &help,
    &init,
    &parse,
    &final_check,
    &print,
    &save,
    opts
};

void _init(void)
{
	register_target6(&log);
}
