libipt_LOG.c revision 4e98e81ecdcc321d232edc42fac168d257e712ff
1b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include <stdio.h>
2b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include <string.h>
38393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius#include <syslog.h>
4b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include <xtables.h>
5b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include <linux/netfilter_ipv4/ipt_LOG.h>
6b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
7b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define LOG_DEFAULT_LEVEL LOG_WARNING
8b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
9b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifndef IPT_LOG_UID /* Old kernel */
10b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define IPT_LOG_UID	0x08	/* Log UID owning local socket */
11b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#undef  IPT_LOG_MASK
1254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#define IPT_LOG_MASK	0x0f
13b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif
14b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
15b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruenum {
16b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru	O_LOG_LEVEL = 0,
17b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru	O_LOG_PREFIX,
18b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru	O_LOG_TCPSEQ,
19b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru	O_LOG_TCPOPTS,
20b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru	O_LOG_IPOPTS,
21b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru	O_LOG_UID,
22b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru	O_LOG_MAC,
23b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru};
2454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
2554dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusstatic void LOG_help(void)
2654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius{
2754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius	printf(
2854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius"LOG target options:\n"
2954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius" --log-level level		Level of logging (numeric or see syslog.conf)\n"
3054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius" --log-prefix prefix		Prefix log messages with this prefix.\n\n"
31b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru" --log-tcp-sequence		Log TCP sequence numbers.\n\n"
32b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru" --log-tcp-options		Log TCP options.\n\n"
33b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru" --log-ip-options		Log IP options.\n\n"
3450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho" --log-uid			Log UID owning the local socket.\n\n"
3550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho" --log-macdecode		Decode MAC addresses and protocol.\n\n");
3650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
3750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
38103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#define s struct ipt_log_info
39103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusstatic const struct xt_option_entry LOG_opts[] = {
4050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	{.name = "log-level", .id = O_LOG_LEVEL, .type = XTTYPE_SYSLOGLEVEL,
4150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	 .flags = XTOPT_PUT, XTOPT_POINTER(s, level)},
4250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	{.name = "log-prefix", .id = O_LOG_PREFIX, .type = XTTYPE_STRING,
4350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	 .flags = XTOPT_PUT, XTOPT_POINTER(s, prefix), .min = 1},
4450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	{.name = "log-tcp-sequence", .id = O_LOG_TCPSEQ, .type = XTTYPE_NONE},
4550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	{.name = "log-tcp-options", .id = O_LOG_TCPOPTS, .type = XTTYPE_NONE},
4650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	{.name = "log-ip-options", .id = O_LOG_IPOPTS, .type = XTTYPE_NONE},
4750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	{.name = "log-uid", .id = O_LOG_UID, .type = XTTYPE_NONE},
4850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	{.name = "log-macdecode", .id = O_LOG_MAC, .type = XTTYPE_NONE},
4950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	XTOPT_TABLEEND,
5050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho};
5150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#undef s
5250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
5350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic void LOG_init(struct xt_entry_target *t)
54b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
55b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru	struct ipt_log_info *loginfo = (struct ipt_log_info *)t->data;
5650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
5750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	loginfo->level = LOG_DEFAULT_LEVEL;
5850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
5950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
6050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
6150294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostruct ipt_log_names {
6250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	const char *name;
6350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	unsigned int level;
6450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho};
6550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
6650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic const struct ipt_log_names ipt_log_names[]
6750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho= { { .name = "alert",   .level = LOG_ALERT },
6850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    { .name = "crit",    .level = LOG_CRIT },
6950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    { .name = "debug",   .level = LOG_DEBUG },
7050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    { .name = "emerg",   .level = LOG_EMERG },
7150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    { .name = "error",   .level = LOG_ERR },		/* DEPRECATED */
7250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    { .name = "info",    .level = LOG_INFO },
7350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    { .name = "notice",  .level = LOG_NOTICE },
7450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    { .name = "panic",   .level = LOG_EMERG },		/* DEPRECATED */
7550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    { .name = "warning", .level = LOG_WARNING }
7650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho};
7750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
78b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic void LOG_parse(struct xt_option_call *cb)
7950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{
8050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	struct ipt_log_info *info = cb->data;
8150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
8250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	xtables_option_parse(cb);
8350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	switch (cb->entry->id) {
8450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	case O_LOG_PREFIX:
8550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho		if (strchr(cb->arg, '\n') != NULL)
8650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho			xtables_error(PARAMETER_PROBLEM,
8750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho				   "Newlines not allowed in --log-prefix");
8850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho		break;
8950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	case O_LOG_TCPSEQ:
9050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho		info->logflags |= IPT_LOG_TCPSEQ;
9150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho		break;
9250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	case O_LOG_TCPOPTS:
9350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho		info->logflags |= IPT_LOG_TCPOPT;
9450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho		break;
9550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	case O_LOG_IPOPTS:
9650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho		info->logflags |= IPT_LOG_IPOPT;
9750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho		break;
9850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	case O_LOG_UID:
9950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho		info->logflags |= IPT_LOG_UID;
10050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho		break;
10150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	case O_LOG_MAC:
10250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho		info->logflags |= IPT_LOG_MACDECODE;
10350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho		break;
10450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	}
10550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
10650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
10750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic void LOG_print(const void *ip, const struct xt_entry_target *target,
10850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                      int numeric)
10950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{
11050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	const struct ipt_log_info *loginfo
11150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho		= (const struct ipt_log_info *)target->data;
11250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	unsigned int i = 0;
11350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
11450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	printf(" LOG");
11550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	if (numeric)
11650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho		printf(" flags %u level %u",
11750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho		       loginfo->logflags, loginfo->level);
11850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	else {
11950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho		for (i = 0; i < ARRAY_SIZE(ipt_log_names); ++i)
12050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho			if (loginfo->level == ipt_log_names[i].level) {
12150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho				printf(" level %s", ipt_log_names[i].name);
12250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho				break;
12350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho			}
12450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho		if (i == ARRAY_SIZE(ipt_log_names))
12550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho			printf(" UNKNOWN level %u", loginfo->level);
12650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho		if (loginfo->logflags & IPT_LOG_TCPSEQ)
12750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho			printf(" tcp-sequence");
12850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho		if (loginfo->logflags & IPT_LOG_TCPOPT)
12950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho			printf(" tcp-options");
13050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho		if (loginfo->logflags & IPT_LOG_IPOPT)
13150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho			printf(" ip-options");
13250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho		if (loginfo->logflags & IPT_LOG_UID)
13327f654740f2a26ad62a5c155af9199af9e69b889claireho			printf(" uid");
13450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho		if (loginfo->logflags & IPT_LOG_MACDECODE)
13550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho			printf(" macdecode");
13650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho		if (loginfo->logflags & ~(IPT_LOG_MASK))
13750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho			printf(" unknown-flags");
13850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	}
13950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
14050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	if (strcmp(loginfo->prefix, "") != 0)
14150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho		printf(" prefix \"%s\"", loginfo->prefix);
14250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
14350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
14450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic void LOG_save(const void *ip, const struct xt_entry_target *target)
14550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{
14650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	const struct ipt_log_info *loginfo
14750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho		= (const struct ipt_log_info *)target->data;
14850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
14950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	if (strcmp(loginfo->prefix, "") != 0) {
15050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho		printf(" --log-prefix");
15150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho		xtables_save_string(loginfo->prefix);
15250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	}
15350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
15450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	if (loginfo->level != LOG_DEFAULT_LEVEL)
15550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho		printf(" --log-level %d", loginfo->level);
15650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
15750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	if (loginfo->logflags & IPT_LOG_TCPSEQ)
15850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho		printf(" --log-tcp-sequence");
15950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	if (loginfo->logflags & IPT_LOG_TCPOPT)
16050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho		printf(" --log-tcp-options");
16150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	if (loginfo->logflags & IPT_LOG_IPOPT)
16250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho		printf(" --log-ip-options");
16350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	if (loginfo->logflags & IPT_LOG_UID)
16450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho		printf(" --log-uid");
16550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	if (loginfo->logflags & IPT_LOG_MACDECODE)
16650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho		printf(" --log-macdecode");
16750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
16850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
16950294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic struct xtables_target log_tg_reg = {
17050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	.name          = "LOG",
17150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	.version       = XTABLES_VERSION,
17250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	.family        = NFPROTO_IPV4,
17350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	.size          = XT_ALIGN(sizeof(struct ipt_log_info)),
17450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	.userspacesize = XT_ALIGN(sizeof(struct ipt_log_info)),
17550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	.help          = LOG_help,
17650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	.init          = LOG_init,
17750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	.print         = LOG_print,
17850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	.save          = LOG_save,
17950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	.x6_parse      = LOG_parse,
18050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	.x6_options    = LOG_opts,
18150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho};
18250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
18350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid _init(void)
18450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{
18550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	xtables_register_target(&log_tg_reg);
18650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
18750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho