blob: d73a3f65eb636f1433e0b439bba366ec9de08415 [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>
Jan Engelhardt5d9678a2008-11-20 10:15:35 +010018#include <xtables.h>
Harald Weltec5bdb402000-07-31 14:24:57 +000019#include <linux/netfilter_ipv4/ip_tables.h>
Martin Josefsson1eb00812004-05-26 15:58:07 +000020/* For 64bit kernel / 32bit userspace */
Jan Engelhardta2a7f2b2008-09-01 14:20:13 +020021#include <linux/netfilter_ipv4/ipt_ULOG.h>
Harald Weltec5bdb402000-07-31 14:24:57 +000022
23
Jan Engelhardt33690a12008-02-11 00:54:00 +010024static void print_groups(unsigned int gmask)
Harald Weltec5bdb402000-07-31 14:24:57 +000025{
26 int b;
27 unsigned int test;
28
Harald Welte015dffb2000-07-31 23:38:14 +000029 for (b = 31; b >= 0; b--) {
Harald Weltec5bdb402000-07-31 14:24:57 +000030 test = (1 << b);
31 if (gmask & test)
32 printf("%d ", b + 1);
33 }
34}
35
Jan Engelhardt1d5b63d2007-10-04 16:29:00 +000036static void ULOG_help(void)
Harald Weltec5bdb402000-07-31 14:24:57 +000037{
Jan Engelhardt8b7c64d2008-04-15 11:48:25 +020038 printf("ULOG target options:\n"
Marc Boucher44540942000-09-12 01:39:41 +000039 " --ulog-nlgroup nlgroup NETLINK group used for logging\n"
Harald Welte015dffb2000-07-31 23:38:14 +000040 " --ulog-cprange size Bytes of each packet to be passed\n"
Harald Welted3beea32001-01-31 07:30:19 +000041 " --ulog-qthreshold Threshold of in-kernel queue\n"
Jan Engelhardt8b7c64d2008-04-15 11:48:25 +020042 " --ulog-prefix prefix Prefix log messages with this prefix.\n");
Harald Weltec5bdb402000-07-31 14:24:57 +000043}
44
Jan Engelhardt1d5b63d2007-10-04 16:29:00 +000045static const struct option ULOG_opts[] = {
Patrick McHardy500f4832007-09-08 15:59:04 +000046 {"ulog-nlgroup", 1, NULL, '!'},
47 {"ulog-prefix", 1, NULL, '#'},
48 {"ulog-cprange", 1, NULL, 'A'},
49 {"ulog-qthreshold", 1, NULL, 'B'},
Max Kellermann9ee386a2008-01-29 13:48:05 +000050 { .name = NULL }
Harald Weltec5bdb402000-07-31 14:24:57 +000051};
52
Jan Engelhardt1d5b63d2007-10-04 16:29:00 +000053static void ULOG_init(struct xt_entry_target *t)
Harald Weltec5bdb402000-07-31 14:24:57 +000054{
Harald Welte015dffb2000-07-31 23:38:14 +000055 struct ipt_ulog_info *loginfo = (struct ipt_ulog_info *) t->data;
Harald Weltec5bdb402000-07-31 14:24:57 +000056
57 loginfo->nl_group = ULOG_DEFAULT_NLGROUP;
Harald Welted3beea32001-01-31 07:30:19 +000058 loginfo->qthreshold = ULOG_DEFAULT_QTHRESHOLD;
Harald Weltec5bdb402000-07-31 14:24:57 +000059
Harald Weltec5bdb402000-07-31 14:24:57 +000060}
61
62#define IPT_LOG_OPT_NLGROUP 0x01
63#define IPT_LOG_OPT_PREFIX 0x02
Harald Welte015dffb2000-07-31 23:38:14 +000064#define IPT_LOG_OPT_CPRANGE 0x04
Harald Welted3beea32001-01-31 07:30:19 +000065#define IPT_LOG_OPT_QTHRESHOLD 0x08
Harald Weltec5bdb402000-07-31 14:24:57 +000066
Jan Engelhardt1d5b63d2007-10-04 16:29:00 +000067static int ULOG_parse(int c, char **argv, int invert, unsigned int *flags,
68 const void *entry, struct xt_entry_target **target)
Harald Weltec5bdb402000-07-31 14:24:57 +000069{
Harald Welte015dffb2000-07-31 23:38:14 +000070 struct ipt_ulog_info *loginfo =
71 (struct ipt_ulog_info *) (*target)->data;
Harald Weltec5bdb402000-07-31 14:24:57 +000072 int group_d;
73
74 switch (c) {
75 case '!':
76 if (*flags & IPT_LOG_OPT_NLGROUP)
77 exit_error(PARAMETER_PROBLEM,
78 "Can't specify --ulog-nlgroup twice");
79
Harald Welteb77f1da2002-03-14 11:35:58 +000080 if (check_inverse(optarg, &invert, NULL, 0))
Harald Weltec5bdb402000-07-31 14:24:57 +000081 exit_error(PARAMETER_PROBLEM,
82 "Unexpected `!' after --ulog-nlgroup");
83 group_d = atoi(optarg);
84 if (group_d > 32 || group_d < 1)
85 exit_error(PARAMETER_PROBLEM,
Harald Welte015dffb2000-07-31 23:38:14 +000086 "--ulog-nlgroup has to be between 1 and 32");
Harald Weltec5bdb402000-07-31 14:24:57 +000087
Harald Welte015dffb2000-07-31 23:38:14 +000088 loginfo->nl_group = (1 << (group_d - 1));
Harald Weltec5bdb402000-07-31 14:24:57 +000089
90 *flags |= IPT_LOG_OPT_NLGROUP;
91 break;
92
93 case '#':
94 if (*flags & IPT_LOG_OPT_PREFIX)
95 exit_error(PARAMETER_PROBLEM,
96 "Can't specify --ulog-prefix twice");
97
Harald Welteb77f1da2002-03-14 11:35:58 +000098 if (check_inverse(optarg, &invert, NULL, 0))
Harald Weltec5bdb402000-07-31 14:24:57 +000099 exit_error(PARAMETER_PROBLEM,
100 "Unexpected `!' after --ulog-prefix");
101
102 if (strlen(optarg) > sizeof(loginfo->prefix) - 1)
103 exit_error(PARAMETER_PROBLEM,
104 "Maximum prefix length %u for --ulog-prefix",
Martin Josefssona28d4952004-05-26 16:04:48 +0000105 (unsigned int)sizeof(loginfo->prefix) - 1);
Harald Weltec5bdb402000-07-31 14:24:57 +0000106
Mike Frysingered26b7b2006-10-10 06:18:40 +0000107 if (strlen(optarg) == 0)
108 exit_error(PARAMETER_PROBLEM,
109 "No prefix specified for --ulog-prefix");
110
111 if (strlen(optarg) != strlen(strtok(optarg, "\n")))
112 exit_error(PARAMETER_PROBLEM,
113 "Newlines not allowed in --ulog-prefix");
114
Harald Weltec5bdb402000-07-31 14:24:57 +0000115 strcpy(loginfo->prefix, optarg);
116 *flags |= IPT_LOG_OPT_PREFIX;
117 break;
Harald Welte015dffb2000-07-31 23:38:14 +0000118 case 'A':
119 if (*flags & IPT_LOG_OPT_CPRANGE)
120 exit_error(PARAMETER_PROBLEM,
121 "Can't specify --ulog-cprange twice");
122 if (atoi(optarg) < 0)
123 exit_error(PARAMETER_PROBLEM,
124 "Negative copy range?");
125 loginfo->copy_range = atoi(optarg);
126 *flags |= IPT_LOG_OPT_CPRANGE;
127 break;
Harald Welted3beea32001-01-31 07:30:19 +0000128 case 'B':
129 if (*flags & IPT_LOG_OPT_QTHRESHOLD)
130 exit_error(PARAMETER_PROBLEM,
131 "Can't specify --ulog-qthreshold twice");
132 if (atoi(optarg) < 1)
133 exit_error(PARAMETER_PROBLEM,
134 "Negative or zero queue threshold ?");
135 if (atoi(optarg) > ULOG_MAX_QLEN)
136 exit_error(PARAMETER_PROBLEM,
137 "Maximum queue length exceeded");
138 loginfo->qthreshold = atoi(optarg);
139 *flags |= IPT_LOG_OPT_QTHRESHOLD;
140 break;
Patrick McHardye5568002005-05-02 20:37:39 +0000141 default:
142 return 0;
Harald Weltec5bdb402000-07-31 14:24:57 +0000143 }
144 return 1;
145}
146
Jan Engelhardt1d5b63d2007-10-04 16:29:00 +0000147static void ULOG_save(const void *ip, const struct xt_entry_target *target)
Harald Weltec5bdb402000-07-31 14:24:57 +0000148{
Harald Welte015dffb2000-07-31 23:38:14 +0000149 const struct ipt_ulog_info *loginfo
150 = (const struct ipt_ulog_info *) target->data;
Harald Weltec5bdb402000-07-31 14:24:57 +0000151
Max Kellermanna5d09942008-01-29 13:44:34 +0000152 if (strcmp(loginfo->prefix, "") != 0) {
153 fputs("--ulog-prefix ", stdout);
154 save_string(loginfo->prefix);
155 }
Harald Weltec5bdb402000-07-31 14:24:57 +0000156
Harald Welte015dffb2000-07-31 23:38:14 +0000157 if (loginfo->nl_group != ULOG_DEFAULT_NLGROUP) {
158 printf("--ulog-nlgroup ");
Harald Weltec5bdb402000-07-31 14:24:57 +0000159 print_groups(loginfo->nl_group);
Harald Weltec5bdb402000-07-31 14:24:57 +0000160 }
Harald Welte015dffb2000-07-31 23:38:14 +0000161 if (loginfo->copy_range)
Martin Josefssona28d4952004-05-26 16:04:48 +0000162 printf("--ulog-cprange %u ", (unsigned int)loginfo->copy_range);
Harald Welted3beea32001-01-31 07:30:19 +0000163
164 if (loginfo->qthreshold != ULOG_DEFAULT_QTHRESHOLD)
Martin Josefssona28d4952004-05-26 16:04:48 +0000165 printf("--ulog-qthreshold %u ", (unsigned int)loginfo->qthreshold);
Harald Weltec5bdb402000-07-31 14:24:57 +0000166}
167
Jan Engelhardt1d5b63d2007-10-04 16:29:00 +0000168static void ULOG_print(const void *ip, const struct xt_entry_target *target,
169 int numeric)
Harald Weltec5bdb402000-07-31 14:24:57 +0000170{
171 const struct ipt_ulog_info *loginfo
Harald Welte015dffb2000-07-31 23:38:14 +0000172 = (const struct ipt_ulog_info *) target->data;
Harald Weltec5bdb402000-07-31 14:24:57 +0000173
174 printf("ULOG ");
Martin Josefssona28d4952004-05-26 16:04:48 +0000175 printf("copy_range %u nlgroup ", (unsigned int)loginfo->copy_range);
Harald Weltec5bdb402000-07-31 14:24:57 +0000176 print_groups(loginfo->nl_group);
177 if (strcmp(loginfo->prefix, "") != 0)
178 printf("prefix `%s' ", loginfo->prefix);
Martin Josefssona28d4952004-05-26 16:04:48 +0000179 printf("queue_threshold %u ", (unsigned int)loginfo->qthreshold);
Harald Weltec5bdb402000-07-31 14:24:57 +0000180}
181
Jan Engelhardt8b7c64d2008-04-15 11:48:25 +0200182static struct xtables_target ulog_tg_reg = {
Pablo Neira8caee8b2004-12-28 13:11:59 +0000183 .name = "ULOG",
Jan Engelhardt8b7c64d2008-04-15 11:48:25 +0200184 .version = XTABLES_VERSION,
Jan Engelhardt03d99482008-11-18 12:27:54 +0100185 .family = NFPROTO_IPV4,
Jan Engelhardt8b7c64d2008-04-15 11:48:25 +0200186 .size = XT_ALIGN(sizeof(struct ipt_ulog_info)),
187 .userspacesize = XT_ALIGN(sizeof(struct ipt_ulog_info)),
Jan Engelhardt1d5b63d2007-10-04 16:29:00 +0000188 .help = ULOG_help,
189 .init = ULOG_init,
190 .parse = ULOG_parse,
191 .print = ULOG_print,
192 .save = ULOG_save,
193 .extra_opts = ULOG_opts,
Harald Weltec5bdb402000-07-31 14:24:57 +0000194};
195
196void _init(void)
197{
Jan Engelhardt8b7c64d2008-04-15 11:48:25 +0200198 xtables_register_target(&ulog_tg_reg);
Harald Weltec5bdb402000-07-31 14:24:57 +0000199}