blob: 4af42e25f057b700ae0a85cdc89809e7b03ed38e [file] [log] [blame]
Bart De Schuymerb78a7e82004-11-20 13:05:22 +00001#define __need_time_t
2#define __need_suseconds_t
3#include <stdio.h>
4#include <stdlib.h>
5#include <string.h>
6#include <getopt.h>
7#include "../include/ebtables_u.h"
8#include <sys/time.h>
9#include <linux/netfilter_bridge/ebt_ulog.h>
10
11#define CP_NO_LIMIT_S "default_cprange"
12#define CP_NO_LIMIT_N 0
13
14#define ULOG_PREFIX '1'
15#define ULOG_NLGROUP '2'
16#define ULOG_CPRANGE '3'
17#define ULOG_QTHRESHOLD '4'
18#define ULOG_ULOG '5'
19static struct option opts[] =
20{
21 { "ulog-prefix" , required_argument, 0, ULOG_PREFIX },
22 { "ulog-nlgroup" , required_argument, 0, ULOG_NLGROUP },
23 { "ulog-cprange" , required_argument, 0, ULOG_CPRANGE },
24 { "ulog-qthreshold", required_argument, 0, ULOG_QTHRESHOLD },
25 { "ulog" , no_argument , 0, ULOG_ULOG },
26 { 0 }
27};
28
29static void print_help()
30{
31 printf(
32"ulog options:\n"
33"--ulog : use the default ulog parameters\n"
34"--ulog-prefix prefix : max %d characters (default is no prefix)\n"
35"--ulog-nlgroup group : 0 < group number < %d (default = %d)\n"
36"--ulog-cprange range : max copy range (default is " CP_NO_LIMIT_S ")\n"
37"--ulog-qthreshold : 0 < queueing threshold < %d (default = %d)\n",
38 EBT_ULOG_PREFIX_LEN - 1, EBT_ULOG_MAXNLGROUPS + 1,
39 EBT_ULOG_DEFAULT_NLGROUP + 1, EBT_ULOG_MAX_QLEN + 1,
40 EBT_ULOG_DEFAULT_QTHRESHOLD);
41}
42
43static void init(struct ebt_entry_watcher *watcher)
44{
45 struct ebt_ulog_info *uloginfo = (struct ebt_ulog_info *)watcher->data;
46
47 uloginfo->prefix[0] = '\0';
48 uloginfo->nlgroup = EBT_ULOG_DEFAULT_NLGROUP;
49 uloginfo->cprange = CP_NO_LIMIT_N; /* Use default netlink buffer size */
50 uloginfo->qthreshold = EBT_ULOG_DEFAULT_QTHRESHOLD;
51}
52
53#define OPT_PREFIX 0x01
54#define OPT_NLGROUP 0x02
55#define OPT_CPRANGE 0x04
56#define OPT_QTHRESHOLD 0x08
57#define OPT_ULOG 0x10
58static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry,
59 unsigned int *flags, struct ebt_entry_watcher **watcher)
60{
61 struct ebt_ulog_info *uloginfo;
62 unsigned int i;
63 char *end;
64
65 uloginfo = (struct ebt_ulog_info *)(*watcher)->data;
66 switch (c) {
67 case ULOG_PREFIX:
68 if (ebt_check_inverse(optarg))
69 goto inverse_invalid;
70 ebt_check_option(flags, OPT_PREFIX);
71 if (strlen(optarg) > EBT_ULOG_PREFIX_LEN - 1)
72 ebt_print_error("Prefix too long for ulog-prefix");
73 strcpy(uloginfo->prefix, optarg);
74 break;
75
76 case ULOG_NLGROUP:
77 if (ebt_check_inverse(optarg))
78 goto inverse_invalid;
79 ebt_check_option(flags, OPT_NLGROUP);
80 i = strtoul(optarg, &end, 10);
81 if (*end != '\0')
82 ebt_print_error("Problem with ulog-nlgroup: %s", optarg);
83 if (i < 1 || i > EBT_ULOG_MAXNLGROUPS)
84 ebt_print_error("the ulog-nlgroup number must be "
85 "between 1 and 32");
86 uloginfo->nlgroup = i - 1;
87 break;
88
89 case ULOG_CPRANGE:
90 if (ebt_check_inverse(optarg))
91 goto inverse_invalid;
92 ebt_check_option(flags, OPT_CPRANGE);
93 i = strtoul(optarg, &end, 10);
94 if (*end != '\0') {
95 if (strcasecmp(optarg, CP_NO_LIMIT_S))
96 ebt_print_error("Problem with ulog-cprange: "
97 "%s", optarg);
98 i = CP_NO_LIMIT_N;
99 }
100 uloginfo->cprange = i;
101 break;
102
103 case ULOG_QTHRESHOLD:
104 if (ebt_check_inverse(optarg))
105 goto inverse_invalid;
106 ebt_check_option(flags, OPT_QTHRESHOLD);
107 i = strtoul(optarg, &end, 10);
108 if (*end != '\0')
109 ebt_print_error("Problem with ulog-qthreshold: %s",
110 optarg);
111 if (i > EBT_ULOG_MAX_QLEN)
112 ebt_print_error("ulog-qthreshold argument %d exceeds "
113 "the maximum of %d", i,
114 EBT_ULOG_MAX_QLEN);
115 uloginfo->qthreshold = i;
116 break;
117 case ULOG_ULOG:
118 if (ebt_check_inverse(optarg))
119 goto inverse_invalid;
120 ebt_check_option(flags, OPT_ULOG);
121 break;
122
123 default:
124 return 0;
125 }
126 return 1;
127
128inverse_invalid:
129 ebt_print_error("The use of '!' makes no sense for the ulog watcher");
130 return 0;
131}
132
133static void final_check(const struct ebt_u_entry *entry,
134 const struct ebt_entry_watcher *watcher, const char *name,
135 unsigned int hookmask, unsigned int time)
136{
137 return;
138}
139
140static void print(const struct ebt_u_entry *entry,
141 const struct ebt_entry_watcher *watcher)
142{
143 struct ebt_ulog_info *uloginfo = (struct ebt_ulog_info *)watcher->data;
144
145 printf("--ulog-prefix \"%s\" --ulog-nlgroup %d --ulog-cprange ",
146 uloginfo->prefix, uloginfo->nlgroup + 1);
147 if (uloginfo->cprange == CP_NO_LIMIT_N)
148 printf(CP_NO_LIMIT_S);
149 else
150 printf("%d", uloginfo->cprange);
151 printf(" --ulog-qthreshold %d ", uloginfo->qthreshold);
152}
153
154static int compare(const struct ebt_entry_watcher *w1,
155 const struct ebt_entry_watcher *w2)
156{
157 struct ebt_ulog_info *uloginfo1 = (struct ebt_ulog_info *)w1->data;
158 struct ebt_ulog_info *uloginfo2 = (struct ebt_ulog_info *)w2->data;
159
160 if (uloginfo1->nlgroup != uloginfo2->nlgroup ||
161 uloginfo1->cprange != uloginfo2->cprange ||
162 uloginfo1->qthreshold != uloginfo2->qthreshold ||
163 strcmp(uloginfo1->prefix, uloginfo2->prefix))
164 return 0;
165 return 1;
166}
167
168static struct ebt_u_watcher ulog_watcher =
169{
170 .name = EBT_ULOG_WATCHER,
171 .size = sizeof(struct ebt_ulog_info),
172 .help = print_help,
173 .init = init,
174 .parse = parse,
175 .final_check = final_check,
176 .print = print,
177 .compare = compare,
178 .extra_ops = opts,
179};
180
181void _init(void)
182{
183 ebt_register_watcher(&ulog_watcher);
184}