blob: 5de8ee0e01069b6151969f7665ec884d4de8978b [file] [log] [blame]
Harald Welte015dffb2000-07-31 23:38:14 +00001/* Shared library add-on to iptables to add ULOG support.
2 *
Harald Welted3beea32001-01-31 07:30:19 +00003 * (C) 2000 by Harald Welte <laforge@gnumonks.org>
4 *
5 * multipart netlink support based on ideas by Sebastian Zander
6 * <zander@fokus.gmd.de>
Harald Welte015dffb2000-07-31 23:38:14 +00007 *
8 * This software is released under the terms of GNU GPL
9 *
Harald Welted3beea32001-01-31 07:30:19 +000010 * libipt_ULOG.c,v 1.7 2001/01/30 11:55:02 laforge Exp
Harald Welte015dffb2000-07-31 23:38:14 +000011 */
Harald Weltec5bdb402000-07-31 14:24:57 +000012#include <stdio.h>
13#include <netdb.h>
14#include <string.h>
15#include <stdlib.h>
16#include <syslog.h>
17#include <getopt.h>
18#include <iptables.h>
19#include <linux/netfilter_ipv4/ip_tables.h>
20#include <linux/netfilter_ipv4/ipt_ULOG.h>
21
22#define ULOG_DEFAULT_NLGROUP 1
Harald Welted3beea32001-01-31 07:30:19 +000023#define ULOG_DEFAULT_QTHRESHOLD 1
Harald Weltec5bdb402000-07-31 14:24:57 +000024
25
26void print_groups(unsigned int gmask)
27{
28 int b;
29 unsigned int test;
30
Harald Welte015dffb2000-07-31 23:38:14 +000031 for (b = 31; b >= 0; b--) {
Harald Weltec5bdb402000-07-31 14:24:57 +000032 test = (1 << b);
33 if (gmask & test)
34 printf("%d ", b + 1);
35 }
36}
37
38/* Function which prints out usage message. */
39static void help(void)
40{
Harald Welte015dffb2000-07-31 23:38:14 +000041 printf("ULOG v%s options:\n"
Marc Boucher44540942000-09-12 01:39:41 +000042 " --ulog-nlgroup nlgroup NETLINK group used for logging\n"
Harald Welte015dffb2000-07-31 23:38:14 +000043 " --ulog-cprange size Bytes of each packet to be passed\n"
Harald Welted3beea32001-01-31 07:30:19 +000044 " --ulog-qthreshold Threshold of in-kernel queue\n"
Harald Welte015dffb2000-07-31 23:38:14 +000045 " --ulog-prefix prefix Prefix log messages with this prefix.\n\n",
46 NETFILTER_VERSION);
Harald Weltec5bdb402000-07-31 14:24:57 +000047}
48
49static struct option opts[] = {
Harald Welte015dffb2000-07-31 23:38:14 +000050 {"ulog-nlgroup", 1, 0, '!'},
51 {"ulog-prefix", 1, 0, '#'},
52 {"ulog-cprange", 1, 0, 'A'},
Harald Welted3beea32001-01-31 07:30:19 +000053 {"ulog-qthreshold", 1, 0, 'B'},
Harald Welte015dffb2000-07-31 23:38:14 +000054 {0}
Harald Weltec5bdb402000-07-31 14:24:57 +000055};
56
57/* Initialize the target. */
58static void init(struct ipt_entry_target *t, unsigned int *nfcache)
59{
Harald Welte015dffb2000-07-31 23:38:14 +000060 struct ipt_ulog_info *loginfo = (struct ipt_ulog_info *) t->data;
Harald Weltec5bdb402000-07-31 14:24:57 +000061
62 loginfo->nl_group = ULOG_DEFAULT_NLGROUP;
Harald Welted3beea32001-01-31 07:30:19 +000063 loginfo->qthreshold = ULOG_DEFAULT_QTHRESHOLD;
Harald Weltec5bdb402000-07-31 14:24:57 +000064
65 /* Can't cache this */
66 *nfcache |= NFC_UNKNOWN;
67}
68
69#define IPT_LOG_OPT_NLGROUP 0x01
70#define IPT_LOG_OPT_PREFIX 0x02
Harald Welte015dffb2000-07-31 23:38:14 +000071#define IPT_LOG_OPT_CPRANGE 0x04
Harald Welted3beea32001-01-31 07:30:19 +000072#define IPT_LOG_OPT_QTHRESHOLD 0x08
Harald Weltec5bdb402000-07-31 14:24:57 +000073
74/* Function which parses command options; returns true if it
75 ate an option */
76static int parse(int c, char **argv, int invert, unsigned int *flags,
Harald Welte015dffb2000-07-31 23:38:14 +000077 const struct ipt_entry *entry,
78 struct ipt_entry_target **target)
Harald Weltec5bdb402000-07-31 14:24:57 +000079{
Harald Welte015dffb2000-07-31 23:38:14 +000080 struct ipt_ulog_info *loginfo =
81 (struct ipt_ulog_info *) (*target)->data;
Harald Weltec5bdb402000-07-31 14:24:57 +000082 int group_d;
83
84 switch (c) {
85 case '!':
86 if (*flags & IPT_LOG_OPT_NLGROUP)
87 exit_error(PARAMETER_PROBLEM,
88 "Can't specify --ulog-nlgroup twice");
89
90 if (check_inverse(optarg, &invert))
91 exit_error(PARAMETER_PROBLEM,
92 "Unexpected `!' after --ulog-nlgroup");
93 group_d = atoi(optarg);
94 if (group_d > 32 || group_d < 1)
95 exit_error(PARAMETER_PROBLEM,
Harald Welte015dffb2000-07-31 23:38:14 +000096 "--ulog-nlgroup has to be between 1 and 32");
Harald Weltec5bdb402000-07-31 14:24:57 +000097
Harald Welte015dffb2000-07-31 23:38:14 +000098 loginfo->nl_group = (1 << (group_d - 1));
Harald Weltec5bdb402000-07-31 14:24:57 +000099
100 *flags |= IPT_LOG_OPT_NLGROUP;
101 break;
102
103 case '#':
104 if (*flags & IPT_LOG_OPT_PREFIX)
105 exit_error(PARAMETER_PROBLEM,
106 "Can't specify --ulog-prefix twice");
107
108 if (check_inverse(optarg, &invert))
109 exit_error(PARAMETER_PROBLEM,
110 "Unexpected `!' after --ulog-prefix");
111
112 if (strlen(optarg) > sizeof(loginfo->prefix) - 1)
113 exit_error(PARAMETER_PROBLEM,
114 "Maximum prefix length %u for --ulog-prefix",
115 sizeof(loginfo->prefix) - 1);
116
117 strcpy(loginfo->prefix, optarg);
118 *flags |= IPT_LOG_OPT_PREFIX;
119 break;
Harald Welte015dffb2000-07-31 23:38:14 +0000120 case 'A':
121 if (*flags & IPT_LOG_OPT_CPRANGE)
122 exit_error(PARAMETER_PROBLEM,
123 "Can't specify --ulog-cprange twice");
124 if (atoi(optarg) < 0)
125 exit_error(PARAMETER_PROBLEM,
126 "Negative copy range?");
127 loginfo->copy_range = atoi(optarg);
128 *flags |= IPT_LOG_OPT_CPRANGE;
129 break;
Harald Welted3beea32001-01-31 07:30:19 +0000130 case 'B':
131 if (*flags & IPT_LOG_OPT_QTHRESHOLD)
132 exit_error(PARAMETER_PROBLEM,
133 "Can't specify --ulog-qthreshold twice");
134 if (atoi(optarg) < 1)
135 exit_error(PARAMETER_PROBLEM,
136 "Negative or zero queue threshold ?");
137 if (atoi(optarg) > ULOG_MAX_QLEN)
138 exit_error(PARAMETER_PROBLEM,
139 "Maximum queue length exceeded");
140 loginfo->qthreshold = atoi(optarg);
141 *flags |= IPT_LOG_OPT_QTHRESHOLD;
142 break;
Harald Weltec5bdb402000-07-31 14:24:57 +0000143 }
144 return 1;
145}
146
147/* Final check; nothing. */
148static void final_check(unsigned int flags)
149{
150}
151
152/* Saves the union ipt_targinfo in parsable form to stdout. */
Harald Welte015dffb2000-07-31 23:38:14 +0000153static void save(const struct ipt_ip *ip,
154 const struct ipt_entry_target *target)
Harald Weltec5bdb402000-07-31 14:24:57 +0000155{
Harald Welte015dffb2000-07-31 23:38:14 +0000156 const struct ipt_ulog_info *loginfo
157 = (const struct ipt_ulog_info *) target->data;
Harald Weltec5bdb402000-07-31 14:24:57 +0000158
Harald Welte015dffb2000-07-31 23:38:14 +0000159 if (strcmp(loginfo->prefix, "") != 0)
Harald Welted3beea32001-01-31 07:30:19 +0000160 printf("--ulog-prefix %s ", loginfo->prefix);
Harald Weltec5bdb402000-07-31 14:24:57 +0000161
Harald Welte015dffb2000-07-31 23:38:14 +0000162 if (loginfo->nl_group != ULOG_DEFAULT_NLGROUP) {
163 printf("--ulog-nlgroup ");
Harald Weltec5bdb402000-07-31 14:24:57 +0000164 print_groups(loginfo->nl_group);
Harald Welte67f23b22000-11-05 17:53:06 +0000165 printf("\n");
Harald Weltec5bdb402000-07-31 14:24:57 +0000166 }
Harald Welte015dffb2000-07-31 23:38:14 +0000167 if (loginfo->copy_range)
Harald Welted3beea32001-01-31 07:30:19 +0000168 printf("--ulog-cprange %d ", loginfo->copy_range);
169
170 if (loginfo->qthreshold != ULOG_DEFAULT_QTHRESHOLD)
171 printf("--ulog-qthreshold %d ", loginfo->qthreshold);
Harald Weltec5bdb402000-07-31 14:24:57 +0000172}
173
174/* Prints out the targinfo. */
175static void
176print(const struct ipt_ip *ip,
Harald Welte015dffb2000-07-31 23:38:14 +0000177 const struct ipt_entry_target *target, int numeric)
Harald Weltec5bdb402000-07-31 14:24:57 +0000178{
179 const struct ipt_ulog_info *loginfo
Harald Welte015dffb2000-07-31 23:38:14 +0000180 = (const struct ipt_ulog_info *) target->data;
Harald Weltec5bdb402000-07-31 14:24:57 +0000181
182 printf("ULOG ");
Harald Welte015dffb2000-07-31 23:38:14 +0000183 printf("copy_range %d nlgroup ", loginfo->copy_range);
Harald Weltec5bdb402000-07-31 14:24:57 +0000184 print_groups(loginfo->nl_group);
185 if (strcmp(loginfo->prefix, "") != 0)
186 printf("prefix `%s' ", loginfo->prefix);
Harald Welted3beea32001-01-31 07:30:19 +0000187 printf("queue_threshold %d ", loginfo->qthreshold);
Harald Weltec5bdb402000-07-31 14:24:57 +0000188}
189
Harald Welte3efb6ea2001-08-06 18:50:21 +0000190static
Harald Welte015dffb2000-07-31 23:38:14 +0000191struct iptables_target ulog = { NULL,
192 "ULOG",
193 NETFILTER_VERSION,
194 IPT_ALIGN(sizeof(struct ipt_ulog_info)),
195 IPT_ALIGN(sizeof(struct ipt_ulog_info)),
196 &help,
197 &init,
198 &parse,
199 &final_check,
200 &print,
201 &save,
202 opts
Harald Weltec5bdb402000-07-31 14:24:57 +0000203};
204
205void _init(void)
206{
207 register_target(&ulog);
208}