Blame extensions/libipt_LOG.c

Packit Service d1fe03
#include <stdio.h>
Packit Service d1fe03
#include <string.h>
Packit Service d1fe03
#include <syslog.h>
Packit Service d1fe03
#include <xtables.h>
Packit Service d1fe03
#include <linux/netfilter_ipv4/ipt_LOG.h>
Packit Service d1fe03
Packit Service d1fe03
#define LOG_DEFAULT_LEVEL LOG_WARNING
Packit Service d1fe03
Packit Service d1fe03
#ifndef IPT_LOG_UID /* Old kernel */
Packit Service d1fe03
#define IPT_LOG_UID	0x08	/* Log UID owning local socket */
Packit Service d1fe03
#undef  IPT_LOG_MASK
Packit Service d1fe03
#define IPT_LOG_MASK	0x0f
Packit Service d1fe03
#endif
Packit Service d1fe03
Packit Service d1fe03
enum {
Packit Service d1fe03
	O_LOG_LEVEL = 0,
Packit Service d1fe03
	O_LOG_PREFIX,
Packit Service d1fe03
	O_LOG_TCPSEQ,
Packit Service d1fe03
	O_LOG_TCPOPTS,
Packit Service d1fe03
	O_LOG_IPOPTS,
Packit Service d1fe03
	O_LOG_UID,
Packit Service d1fe03
	O_LOG_MAC,
Packit Service d1fe03
};
Packit Service d1fe03
Packit Service d1fe03
static void LOG_help(void)
Packit Service d1fe03
{
Packit Service d1fe03
	printf(
Packit Service d1fe03
"LOG target options:\n"
Packit Service d1fe03
" --log-level level		Level of logging (numeric or see syslog.conf)\n"
Packit Service d1fe03
" --log-prefix prefix		Prefix log messages with this prefix.\n\n"
Packit Service d1fe03
" --log-tcp-sequence		Log TCP sequence numbers.\n\n"
Packit Service d1fe03
" --log-tcp-options		Log TCP options.\n\n"
Packit Service d1fe03
" --log-ip-options		Log IP options.\n\n"
Packit Service d1fe03
" --log-uid			Log UID owning the local socket.\n\n"
Packit Service d1fe03
" --log-macdecode		Decode MAC addresses and protocol.\n\n");
Packit Service d1fe03
}
Packit Service d1fe03
Packit Service d1fe03
#define s struct ipt_log_info
Packit Service d1fe03
static const struct xt_option_entry LOG_opts[] = {
Packit Service d1fe03
	{.name = "log-level", .id = O_LOG_LEVEL, .type = XTTYPE_SYSLOGLEVEL,
Packit Service d1fe03
	 .flags = XTOPT_PUT, XTOPT_POINTER(s, level)},
Packit Service d1fe03
	{.name = "log-prefix", .id = O_LOG_PREFIX, .type = XTTYPE_STRING,
Packit Service d1fe03
	 .flags = XTOPT_PUT, XTOPT_POINTER(s, prefix), .min = 1},
Packit Service d1fe03
	{.name = "log-tcp-sequence", .id = O_LOG_TCPSEQ, .type = XTTYPE_NONE},
Packit Service d1fe03
	{.name = "log-tcp-options", .id = O_LOG_TCPOPTS, .type = XTTYPE_NONE},
Packit Service d1fe03
	{.name = "log-ip-options", .id = O_LOG_IPOPTS, .type = XTTYPE_NONE},
Packit Service d1fe03
	{.name = "log-uid", .id = O_LOG_UID, .type = XTTYPE_NONE},
Packit Service d1fe03
	{.name = "log-macdecode", .id = O_LOG_MAC, .type = XTTYPE_NONE},
Packit Service d1fe03
	XTOPT_TABLEEND,
Packit Service d1fe03
};
Packit Service d1fe03
#undef s
Packit Service d1fe03
Packit Service d1fe03
static void LOG_init(struct xt_entry_target *t)
Packit Service d1fe03
{
Packit Service d1fe03
	struct ipt_log_info *loginfo = (struct ipt_log_info *)t->data;
Packit Service d1fe03
Packit Service d1fe03
	loginfo->level = LOG_DEFAULT_LEVEL;
Packit Service d1fe03
Packit Service d1fe03
}
Packit Service d1fe03
Packit Service d1fe03
struct ipt_log_names {
Packit Service d1fe03
	const char *name;
Packit Service d1fe03
	unsigned int level;
Packit Service d1fe03
};
Packit Service d1fe03
Packit Service d1fe03
struct ipt_log_xlate {
Packit Service d1fe03
	const char *name;
Packit Service d1fe03
	unsigned int level;
Packit Service d1fe03
};
Packit Service d1fe03
Packit Service d1fe03
static const struct ipt_log_names ipt_log_names[]
Packit Service d1fe03
= { { .name = "alert",   .level = LOG_ALERT },
Packit Service d1fe03
    { .name = "crit",    .level = LOG_CRIT },
Packit Service d1fe03
    { .name = "debug",   .level = LOG_DEBUG },
Packit Service d1fe03
    { .name = "emerg",   .level = LOG_EMERG },
Packit Service d1fe03
    { .name = "error",   .level = LOG_ERR },		/* DEPRECATED */
Packit Service d1fe03
    { .name = "info",    .level = LOG_INFO },
Packit Service d1fe03
    { .name = "notice",  .level = LOG_NOTICE },
Packit Service d1fe03
    { .name = "panic",   .level = LOG_EMERG },		/* DEPRECATED */
Packit Service d1fe03
    { .name = "warning", .level = LOG_WARNING }
Packit Service d1fe03
};
Packit Service d1fe03
Packit Service d1fe03
static void LOG_parse(struct xt_option_call *cb)
Packit Service d1fe03
{
Packit Service d1fe03
	struct ipt_log_info *info = cb->data;
Packit Service d1fe03
Packit Service d1fe03
	xtables_option_parse(cb);
Packit Service d1fe03
	switch (cb->entry->id) {
Packit Service d1fe03
	case O_LOG_PREFIX:
Packit Service d1fe03
		if (strchr(cb->arg, '\n') != NULL)
Packit Service d1fe03
			xtables_error(PARAMETER_PROBLEM,
Packit Service d1fe03
				   "Newlines not allowed in --log-prefix");
Packit Service d1fe03
		break;
Packit Service d1fe03
	case O_LOG_TCPSEQ:
Packit Service d1fe03
		info->logflags |= IPT_LOG_TCPSEQ;
Packit Service d1fe03
		break;
Packit Service d1fe03
	case O_LOG_TCPOPTS:
Packit Service d1fe03
		info->logflags |= IPT_LOG_TCPOPT;
Packit Service d1fe03
		break;
Packit Service d1fe03
	case O_LOG_IPOPTS:
Packit Service d1fe03
		info->logflags |= IPT_LOG_IPOPT;
Packit Service d1fe03
		break;
Packit Service d1fe03
	case O_LOG_UID:
Packit Service d1fe03
		info->logflags |= IPT_LOG_UID;
Packit Service d1fe03
		break;
Packit Service d1fe03
	case O_LOG_MAC:
Packit Service d1fe03
		info->logflags |= IPT_LOG_MACDECODE;
Packit Service d1fe03
		break;
Packit Service d1fe03
	}
Packit Service d1fe03
}
Packit Service d1fe03
Packit Service d1fe03
static void LOG_print(const void *ip, const struct xt_entry_target *target,
Packit Service d1fe03
                      int numeric)
Packit Service d1fe03
{
Packit Service d1fe03
	const struct ipt_log_info *loginfo
Packit Service d1fe03
		= (const struct ipt_log_info *)target->data;
Packit Service d1fe03
	unsigned int i = 0;
Packit Service d1fe03
Packit Service d1fe03
	printf(" LOG");
Packit Service d1fe03
	if (numeric)
Packit Service d1fe03
		printf(" flags %u level %u",
Packit Service d1fe03
		       loginfo->logflags, loginfo->level);
Packit Service d1fe03
	else {
Packit Service d1fe03
		for (i = 0; i < ARRAY_SIZE(ipt_log_names); ++i)
Packit Service d1fe03
			if (loginfo->level == ipt_log_names[i].level) {
Packit Service d1fe03
				printf(" level %s", ipt_log_names[i].name);
Packit Service d1fe03
				break;
Packit Service d1fe03
			}
Packit Service d1fe03
		if (i == ARRAY_SIZE(ipt_log_names))
Packit Service d1fe03
			printf(" UNKNOWN level %u", loginfo->level);
Packit Service d1fe03
		if (loginfo->logflags & IPT_LOG_TCPSEQ)
Packit Service d1fe03
			printf(" tcp-sequence");
Packit Service d1fe03
		if (loginfo->logflags & IPT_LOG_TCPOPT)
Packit Service d1fe03
			printf(" tcp-options");
Packit Service d1fe03
		if (loginfo->logflags & IPT_LOG_IPOPT)
Packit Service d1fe03
			printf(" ip-options");
Packit Service d1fe03
		if (loginfo->logflags & IPT_LOG_UID)
Packit Service d1fe03
			printf(" uid");
Packit Service d1fe03
		if (loginfo->logflags & IPT_LOG_MACDECODE)
Packit Service d1fe03
			printf(" macdecode");
Packit Service d1fe03
		if (loginfo->logflags & ~(IPT_LOG_MASK))
Packit Service d1fe03
			printf(" unknown-flags");
Packit Service d1fe03
	}
Packit Service d1fe03
Packit Service d1fe03
	if (strcmp(loginfo->prefix, "") != 0)
Packit Service d1fe03
		printf(" prefix \"%s\"", loginfo->prefix);
Packit Service d1fe03
}
Packit Service d1fe03
Packit Service d1fe03
static void LOG_save(const void *ip, const struct xt_entry_target *target)
Packit Service d1fe03
{
Packit Service d1fe03
	const struct ipt_log_info *loginfo
Packit Service d1fe03
		= (const struct ipt_log_info *)target->data;
Packit Service d1fe03
Packit Service d1fe03
	if (strcmp(loginfo->prefix, "") != 0) {
Packit Service d1fe03
		printf(" --log-prefix");
Packit Service d1fe03
		xtables_save_string(loginfo->prefix);
Packit Service d1fe03
	}
Packit Service d1fe03
Packit Service d1fe03
	if (loginfo->level != LOG_DEFAULT_LEVEL)
Packit Service d1fe03
		printf(" --log-level %d", loginfo->level);
Packit Service d1fe03
Packit Service d1fe03
	if (loginfo->logflags & IPT_LOG_TCPSEQ)
Packit Service d1fe03
		printf(" --log-tcp-sequence");
Packit Service d1fe03
	if (loginfo->logflags & IPT_LOG_TCPOPT)
Packit Service d1fe03
		printf(" --log-tcp-options");
Packit Service d1fe03
	if (loginfo->logflags & IPT_LOG_IPOPT)
Packit Service d1fe03
		printf(" --log-ip-options");
Packit Service d1fe03
	if (loginfo->logflags & IPT_LOG_UID)
Packit Service d1fe03
		printf(" --log-uid");
Packit Service d1fe03
	if (loginfo->logflags & IPT_LOG_MACDECODE)
Packit Service d1fe03
		printf(" --log-macdecode");
Packit Service d1fe03
}
Packit Service d1fe03
Packit Service d1fe03
static const struct ipt_log_xlate ipt_log_xlate_names[] = {
Packit Service d1fe03
	{"alert",	LOG_ALERT },
Packit Service d1fe03
	{"crit",	LOG_CRIT },
Packit Service d1fe03
	{"debug",	LOG_DEBUG },
Packit Service d1fe03
	{"emerg",	LOG_EMERG },
Packit Service d1fe03
	{"err",		LOG_ERR },
Packit Service d1fe03
	{"info",	LOG_INFO },
Packit Service d1fe03
	{"notice",	LOG_NOTICE },
Packit Service d1fe03
	{"warn",	LOG_WARNING }
Packit Service d1fe03
};
Packit Service d1fe03
Packit Service d1fe03
static int LOG_xlate(struct xt_xlate *xl,
Packit Service d1fe03
		     const struct xt_xlate_tg_params *params)
Packit Service d1fe03
{
Packit Service d1fe03
	const struct ipt_log_info *loginfo =
Packit Service d1fe03
		(const struct ipt_log_info *)params->target->data;
Packit Service d1fe03
	unsigned int i = 0;
Packit Service d1fe03
Packit Service d1fe03
	xt_xlate_add(xl, "log");
Packit Service d1fe03
	if (strcmp(loginfo->prefix, "") != 0) {
Packit Service d1fe03
		if (params->escape_quotes)
Packit Service d1fe03
			xt_xlate_add(xl, " prefix \\\"%s\\\"", loginfo->prefix);
Packit Service d1fe03
		else
Packit Service d1fe03
			xt_xlate_add(xl, " prefix \"%s\"", loginfo->prefix);
Packit Service d1fe03
	}
Packit Service d1fe03
Packit Service d1fe03
	for (i = 0; i < ARRAY_SIZE(ipt_log_xlate_names); ++i)
Packit Service d1fe03
		if (loginfo->level != LOG_DEFAULT_LEVEL &&
Packit Service d1fe03
		    loginfo->level == ipt_log_xlate_names[i].level) {
Packit Service d1fe03
			xt_xlate_add(xl, " level %s",
Packit Service d1fe03
				   ipt_log_xlate_names[i].name);
Packit Service d1fe03
			break;
Packit Service d1fe03
		}
Packit Service d1fe03
Packit Service d1fe03
	if ((loginfo->logflags & IPT_LOG_MASK) == IPT_LOG_MASK) {
Packit Service d1fe03
		xt_xlate_add(xl, " flags all");
Packit Service d1fe03
	} else {
Packit Service d1fe03
		if (loginfo->logflags & (IPT_LOG_TCPSEQ | IPT_LOG_TCPOPT)) {
Packit Service d1fe03
			const char *delim = " ";
Packit Service d1fe03
Packit Service d1fe03
			xt_xlate_add(xl, " flags tcp");
Packit Service d1fe03
			if (loginfo->logflags & IPT_LOG_TCPSEQ) {
Packit Service d1fe03
				xt_xlate_add(xl, " sequence");
Packit Service d1fe03
				delim = ",";
Packit Service d1fe03
			}
Packit Service d1fe03
			if (loginfo->logflags & IPT_LOG_TCPOPT)
Packit Service d1fe03
				xt_xlate_add(xl, "%soptions", delim);
Packit Service d1fe03
		}
Packit Service d1fe03
		if (loginfo->logflags & IPT_LOG_IPOPT)
Packit Service d1fe03
			xt_xlate_add(xl, " flags ip options");
Packit Service d1fe03
		if (loginfo->logflags & IPT_LOG_UID)
Packit Service d1fe03
			xt_xlate_add(xl, " flags skuid");
Packit Service d1fe03
		if (loginfo->logflags & IPT_LOG_MACDECODE)
Packit Service d1fe03
			xt_xlate_add(xl, " flags ether");
Packit Service d1fe03
	}
Packit Service d1fe03
Packit Service d1fe03
	return 1;
Packit Service d1fe03
}
Packit Service d1fe03
static struct xtables_target log_tg_reg = {
Packit Service d1fe03
	.name          = "LOG",
Packit Service d1fe03
	.version       = XTABLES_VERSION,
Packit Service d1fe03
	.family        = NFPROTO_IPV4,
Packit Service d1fe03
	.size          = XT_ALIGN(sizeof(struct ipt_log_info)),
Packit Service d1fe03
	.userspacesize = XT_ALIGN(sizeof(struct ipt_log_info)),
Packit Service d1fe03
	.help          = LOG_help,
Packit Service d1fe03
	.init          = LOG_init,
Packit Service d1fe03
	.print         = LOG_print,
Packit Service d1fe03
	.save          = LOG_save,
Packit Service d1fe03
	.x6_parse      = LOG_parse,
Packit Service d1fe03
	.x6_options    = LOG_opts,
Packit Service d1fe03
	.xlate	       = LOG_xlate,
Packit Service d1fe03
};
Packit Service d1fe03
Packit Service d1fe03
void _init(void)
Packit Service d1fe03
{
Packit Service d1fe03
	xtables_register_target(&log_tg_reg);
Packit Service d1fe03
}