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