libipt_ULOG.c revision d09b6d591ca7d7d7575cb6aa20384c9830f777ab
1/* Shared library add-on to iptables to add ULOG support.
2 *
3 * (C) 2000 by Harald Welte <laforge@gnumonks.org>
4 *
5 * multipart netlink support based on ideas by Sebastian Zander
6 * 						<zander@fokus.gmd.de>
7 *
8 * This software is released under the terms of GNU GPL
9 *
10 * libipt_ULOG.c,v 1.7 2001/01/30 11:55:02 laforge Exp
11 */
12#include <stdbool.h>
13#include <stdio.h>
14#include <netdb.h>
15#include <string.h>
16#include <stdlib.h>
17#include <syslog.h>
18#include <getopt.h>
19#include <xtables.h>
20/* For 64bit kernel / 32bit userspace */
21#include <linux/netfilter_ipv4/ipt_ULOG.h>
22
23
24static void print_groups(unsigned int gmask)
25{
26	int b;
27	unsigned int test;
28
29	for (b = 31; b >= 0; b--) {
30		test = (1 << b);
31		if (gmask & test)
32			printf("%d ", b + 1);
33	}
34}
35
36static void ULOG_help(void)
37{
38	printf("ULOG target options:\n"
39	       " --ulog-nlgroup nlgroup		NETLINK group used for logging\n"
40	       " --ulog-cprange size		Bytes of each packet to be passed\n"
41	       " --ulog-qthreshold		Threshold of in-kernel queue\n"
42	       " --ulog-prefix prefix		Prefix log messages with this prefix.\n");
43}
44
45static const struct option ULOG_opts[] = {
46	{.name = "ulog-nlgroup",    .has_arg = true, .val = '!'},
47	{.name = "ulog-prefix",     .has_arg = true, .val = '#'},
48	{.name = "ulog-cprange",    .has_arg = true, .val = 'A'},
49	{.name = "ulog-qthreshold", .has_arg = true, .val = 'B'},
50	XT_GETOPT_TABLEEND,
51};
52
53static void ULOG_init(struct xt_entry_target *t)
54{
55	struct ipt_ulog_info *loginfo = (struct ipt_ulog_info *) t->data;
56
57	loginfo->nl_group = ULOG_DEFAULT_NLGROUP;
58	loginfo->qthreshold = ULOG_DEFAULT_QTHRESHOLD;
59
60}
61
62#define IPT_LOG_OPT_NLGROUP 0x01
63#define IPT_LOG_OPT_PREFIX 0x02
64#define IPT_LOG_OPT_CPRANGE 0x04
65#define IPT_LOG_OPT_QTHRESHOLD 0x08
66
67static int ULOG_parse(int c, char **argv, int invert, unsigned int *flags,
68                      const void *entry, struct xt_entry_target **target)
69{
70	struct ipt_ulog_info *loginfo =
71	    (struct ipt_ulog_info *) (*target)->data;
72	int group_d;
73
74	switch (c) {
75	case '!':
76		if (*flags & IPT_LOG_OPT_NLGROUP)
77			xtables_error(PARAMETER_PROBLEM,
78				   "Can't specify --ulog-nlgroup twice");
79
80		if (xtables_check_inverse(optarg, &invert, NULL, 0, argv))
81			xtables_error(PARAMETER_PROBLEM,
82				   "Unexpected `!' after --ulog-nlgroup");
83		group_d = atoi(optarg);
84		if (group_d > 32 || group_d < 1)
85			xtables_error(PARAMETER_PROBLEM,
86				   "--ulog-nlgroup has to be between 1 and 32");
87
88		loginfo->nl_group = (1 << (group_d - 1));
89
90		*flags |= IPT_LOG_OPT_NLGROUP;
91		break;
92
93	case '#':
94		if (*flags & IPT_LOG_OPT_PREFIX)
95			xtables_error(PARAMETER_PROBLEM,
96				   "Can't specify --ulog-prefix twice");
97
98		if (xtables_check_inverse(optarg, &invert, NULL, 0, argv))
99			xtables_error(PARAMETER_PROBLEM,
100				   "Unexpected `!' after --ulog-prefix");
101
102		if (strlen(optarg) > sizeof(loginfo->prefix) - 1)
103			xtables_error(PARAMETER_PROBLEM,
104				   "Maximum prefix length %u for --ulog-prefix",
105				   (unsigned int)sizeof(loginfo->prefix) - 1);
106
107		if (strlen(optarg) == 0)
108			xtables_error(PARAMETER_PROBLEM,
109				   "No prefix specified for --ulog-prefix");
110
111		if (strlen(optarg) != strlen(strtok(optarg, "\n")))
112			xtables_error(PARAMETER_PROBLEM,
113				   "Newlines not allowed in --ulog-prefix");
114
115		strcpy(loginfo->prefix, optarg);
116		*flags |= IPT_LOG_OPT_PREFIX;
117		break;
118	case 'A':
119		if (*flags & IPT_LOG_OPT_CPRANGE)
120			xtables_error(PARAMETER_PROBLEM,
121				   "Can't specify --ulog-cprange twice");
122		if (atoi(optarg) < 0)
123			xtables_error(PARAMETER_PROBLEM,
124				   "Negative copy range?");
125		loginfo->copy_range = atoi(optarg);
126		*flags |= IPT_LOG_OPT_CPRANGE;
127		break;
128	case 'B':
129		if (*flags & IPT_LOG_OPT_QTHRESHOLD)
130			xtables_error(PARAMETER_PROBLEM,
131				   "Can't specify --ulog-qthreshold twice");
132		if (atoi(optarg) < 1)
133			xtables_error(PARAMETER_PROBLEM,
134				   "Negative or zero queue threshold ?");
135		if (atoi(optarg) > ULOG_MAX_QLEN)
136			xtables_error(PARAMETER_PROBLEM,
137				   "Maximum queue length exceeded");
138		loginfo->qthreshold = atoi(optarg);
139		*flags |= IPT_LOG_OPT_QTHRESHOLD;
140		break;
141	}
142	return 1;
143}
144
145static void ULOG_save(const void *ip, const struct xt_entry_target *target)
146{
147	const struct ipt_ulog_info *loginfo
148	    = (const struct ipt_ulog_info *) target->data;
149
150	if (strcmp(loginfo->prefix, "") != 0) {
151		fputs("--ulog-prefix ", stdout);
152		xtables_save_string(loginfo->prefix);
153	}
154
155	if (loginfo->nl_group != ULOG_DEFAULT_NLGROUP) {
156		printf("--ulog-nlgroup ");
157		print_groups(loginfo->nl_group);
158	}
159	if (loginfo->copy_range)
160		printf("--ulog-cprange %u ", (unsigned int)loginfo->copy_range);
161
162	if (loginfo->qthreshold != ULOG_DEFAULT_QTHRESHOLD)
163		printf("--ulog-qthreshold %u ", (unsigned int)loginfo->qthreshold);
164}
165
166static void ULOG_print(const void *ip, const struct xt_entry_target *target,
167                       int numeric)
168{
169	const struct ipt_ulog_info *loginfo
170	    = (const struct ipt_ulog_info *) target->data;
171
172	printf("ULOG ");
173	printf("copy_range %u nlgroup ", (unsigned int)loginfo->copy_range);
174	print_groups(loginfo->nl_group);
175	if (strcmp(loginfo->prefix, "") != 0)
176		printf("prefix `%s' ", loginfo->prefix);
177	printf("queue_threshold %u ", (unsigned int)loginfo->qthreshold);
178}
179
180static struct xtables_target ulog_tg_reg = {
181	.name		= "ULOG",
182	.version	= XTABLES_VERSION,
183	.family		= NFPROTO_IPV4,
184	.size		= XT_ALIGN(sizeof(struct ipt_ulog_info)),
185	.userspacesize	= XT_ALIGN(sizeof(struct ipt_ulog_info)),
186	.help		= ULOG_help,
187	.init		= ULOG_init,
188	.parse		= ULOG_parse,
189	.print		= ULOG_print,
190	.save		= ULOG_save,
191	.extra_opts	= ULOG_opts,
192};
193
194void _init(void)
195{
196	xtables_register_target(&ulog_tg_reg);
197}
198