Busybox: Upgrade to 1.21.1 (stable). lsof active.
[tomato.git] / release / src / router / iptables / extensions / libip6t_LOG.c
blob61d2b4a9f72bac66df3205273df3a7a6b22c5352
1 /* Shared library add-on to iptables to add LOG support. */
2 #include <stdio.h>
3 #include <netdb.h>
4 #include <string.h>
5 #include <stdlib.h>
6 #include <syslog.h>
7 #include <getopt.h>
8 #include <ip6tables.h>
9 #include <linux/netfilter_ipv6/ip6_tables.h>
10 #include <linux/netfilter_ipv6/ip6t_LOG.h>
12 #ifndef IP6T_LOG_UID /* Old kernel */
13 #define IP6T_LOG_UID 0x08
14 #undef IP6T_LOG_MASK
15 #define IP6T_LOG_MASK 0x0f
16 #endif
18 #ifndef IPT_LOG_MACDECODE /* Old kernel */
19 #define IPT_LOG_MACDECODE 0x20
20 #undef IPT_LOG_MASK
21 #define IPT_LOG_MASK 0x2f
22 #endif
24 #define LOG_DEFAULT_LEVEL LOG_WARNING
26 /* Function which prints out usage message. */
27 static void
28 help(void)
30 printf(
31 "LOG v%s options:\n"
32 " --log-level level Level of logging (numeric or see syslog.conf)\n"
33 " --log-prefix prefix Prefix log messages with this prefix.\n\n"
34 " --log-tcp-sequence Log TCP sequence numbers.\n\n"
35 " --log-tcp-options Log TCP options.\n\n"
36 " --log-ip-options Log IP options.\n\n"
37 " --log-uid Log UID owning the local socket.\n\n"
38 " --log-macdecode Decode MAC addresses and protocol.\n\n",
39 IPTABLES_VERSION);
42 static struct option opts[] = {
43 { .name = "log-level", .has_arg = 1, .flag = 0, .val = '!' },
44 { .name = "log-prefix", .has_arg = 1, .flag = 0, .val = '#' },
45 { .name = "log-tcp-sequence", .has_arg = 0, .flag = 0, .val = '1' },
46 { .name = "log-tcp-options", .has_arg = 0, .flag = 0, .val = '2' },
47 { .name = "log-ip-options", .has_arg = 0, .flag = 0, .val = '3' },
48 { .name = "log-uid", .has_arg = 0, .flag = 0, .val = '4' },
49 { .name = "log-macdecode", .has_arg = 0, .flag = 0, .val = '5' },
50 { .name = 0 }
53 /* Initialize the target. */
54 static void
55 init(struct ip6t_entry_target *t, unsigned int *nfcache)
57 struct ip6t_log_info *loginfo = (struct ip6t_log_info *)t->data;
59 loginfo->level = LOG_DEFAULT_LEVEL;
63 struct ip6t_log_names {
64 const char *name;
65 unsigned int level;
68 static struct ip6t_log_names ip6t_log_names[]
69 = { { .name = "alert", .level = LOG_ALERT },
70 { .name = "crit", .level = LOG_CRIT },
71 { .name = "debug", .level = LOG_DEBUG },
72 { .name = "emerg", .level = LOG_EMERG },
73 { .name = "error", .level = LOG_ERR }, /* DEPRECATED */
74 { .name = "info", .level = LOG_INFO },
75 { .name = "notice", .level = LOG_NOTICE },
76 { .name = "panic", .level = LOG_EMERG }, /* DEPRECATED */
77 { .name = "warning", .level = LOG_WARNING }
80 static u_int8_t
81 parse_level(const char *level)
83 unsigned int lev = -1;
84 unsigned int set = 0;
86 if (string_to_number(level, 0, 7, &lev) == -1) {
87 unsigned int i = 0;
89 for (i = 0;
90 i < sizeof(ip6t_log_names) / sizeof(struct ip6t_log_names);
91 i++) {
92 if (strncasecmp(level, ip6t_log_names[i].name,
93 strlen(level)) == 0) {
94 if (set++)
95 exit_error(PARAMETER_PROBLEM,
96 "log-level `%s' ambiguous",
97 level);
98 lev = ip6t_log_names[i].level;
102 if (!set)
103 exit_error(PARAMETER_PROBLEM,
104 "log-level `%s' unknown", level);
107 return (u_int8_t)lev;
110 #define IP6T_LOG_OPT_LEVEL 0x01
111 #define IP6T_LOG_OPT_PREFIX 0x02
112 #define IP6T_LOG_OPT_TCPSEQ 0x04
113 #define IP6T_LOG_OPT_TCPOPT 0x08
114 #define IP6T_LOG_OPT_IPOPT 0x10
115 #define IP6T_LOG_OPT_UID 0x20
116 #define IPT_LOG_OPT_MACDECODE 0x40
118 /* Function which parses command options; returns true if it
119 ate an option */
120 static int
121 parse(int c, char **argv, int invert, unsigned int *flags,
122 const struct ip6t_entry *entry,
123 struct ip6t_entry_target **target)
125 struct ip6t_log_info *loginfo = (struct ip6t_log_info *)(*target)->data;
127 switch (c) {
128 case '!':
129 if (*flags & IP6T_LOG_OPT_LEVEL)
130 exit_error(PARAMETER_PROBLEM,
131 "Can't specify --log-level twice");
133 if (check_inverse(optarg, &invert, NULL, 0))
134 exit_error(PARAMETER_PROBLEM,
135 "Unexpected `!' after --log-level");
137 loginfo->level = parse_level(optarg);
138 *flags |= IP6T_LOG_OPT_LEVEL;
139 break;
141 case '#':
142 if (*flags & IP6T_LOG_OPT_PREFIX)
143 exit_error(PARAMETER_PROBLEM,
144 "Can't specify --log-prefix twice");
146 if (check_inverse(optarg, &invert, NULL, 0))
147 exit_error(PARAMETER_PROBLEM,
148 "Unexpected `!' after --log-prefix");
150 if (strlen(optarg) > sizeof(loginfo->prefix) - 1)
151 exit_error(PARAMETER_PROBLEM,
152 "Maximum prefix length %u for --log-prefix",
153 (unsigned int)sizeof(loginfo->prefix) - 1);
155 if (strlen(optarg) == 0)
156 exit_error(PARAMETER_PROBLEM,
157 "No prefix specified for --log-prefix");
159 if (strlen(optarg) != strlen(strtok(optarg, "\n")))
160 exit_error(PARAMETER_PROBLEM,
161 "Newlines not allowed in --log-prefix");
163 strcpy(loginfo->prefix, optarg);
164 *flags |= IP6T_LOG_OPT_PREFIX;
165 break;
167 case '1':
168 if (*flags & IP6T_LOG_OPT_TCPSEQ)
169 exit_error(PARAMETER_PROBLEM,
170 "Can't specify --log-tcp-sequence "
171 "twice");
173 loginfo->logflags |= IP6T_LOG_TCPSEQ;
174 *flags |= IP6T_LOG_OPT_TCPSEQ;
175 break;
177 case '2':
178 if (*flags & IP6T_LOG_OPT_TCPOPT)
179 exit_error(PARAMETER_PROBLEM,
180 "Can't specify --log-tcp-options twice");
182 loginfo->logflags |= IP6T_LOG_TCPOPT;
183 *flags |= IP6T_LOG_OPT_TCPOPT;
184 break;
186 case '3':
187 if (*flags & IP6T_LOG_OPT_IPOPT)
188 exit_error(PARAMETER_PROBLEM,
189 "Can't specify --log-ip-options twice");
191 loginfo->logflags |= IP6T_LOG_IPOPT;
192 *flags |= IP6T_LOG_OPT_IPOPT;
193 break;
195 case '4':
196 if (*flags & IP6T_LOG_OPT_UID)
197 exit_error(PARAMETER_PROBLEM,
198 "Can't specify --log-uid twice");
200 loginfo->logflags |= IP6T_LOG_UID;
201 *flags |= IP6T_LOG_OPT_UID;
202 break;
204 case '5':
205 if (*flags & IPT_LOG_OPT_MACDECODE)
206 exit_error(PARAMETER_PROBLEM,
207 "Can't specify --log-macdecode twice");
209 loginfo->logflags |= IPT_LOG_MACDECODE;
210 *flags |= IPT_LOG_OPT_MACDECODE;
211 break;
213 default:
214 return 0;
217 return 1;
220 /* Final check; nothing. */
221 static void final_check(unsigned int flags)
225 /* Prints out the targinfo. */
226 static void
227 print(const struct ip6t_ip6 *ip,
228 const struct ip6t_entry_target *target,
229 int numeric)
231 const struct ip6t_log_info *loginfo
232 = (const struct ip6t_log_info *)target->data;
233 unsigned int i = 0;
235 printf("LOG ");
236 if (numeric)
237 printf("flags %u level %u ",
238 loginfo->logflags, loginfo->level);
239 else {
240 for (i = 0;
241 i < sizeof(ip6t_log_names) / sizeof(struct ip6t_log_names);
242 i++) {
243 if (loginfo->level == ip6t_log_names[i].level) {
244 printf("level %s ", ip6t_log_names[i].name);
245 break;
248 if (i == sizeof(ip6t_log_names) / sizeof(struct ip6t_log_names))
249 printf("UNKNOWN level %u ", loginfo->level);
250 if (loginfo->logflags & IP6T_LOG_TCPSEQ)
251 printf("tcp-sequence ");
252 if (loginfo->logflags & IP6T_LOG_TCPOPT)
253 printf("tcp-options ");
254 if (loginfo->logflags & IP6T_LOG_IPOPT)
255 printf("ip-options ");
256 if (loginfo->logflags & IP6T_LOG_UID)
257 printf("uid ");
258 if (loginfo->logflags & IPT_LOG_MACDECODE)
259 printf("macdecode ");
260 if (loginfo->logflags & ~(IP6T_LOG_MASK))
261 printf("unknown-flags ");
264 if (strcmp(loginfo->prefix, "") != 0)
265 printf("prefix `%s' ", loginfo->prefix);
268 /* Saves the union ip6t_targinfo in parsable form to stdout. */
269 static void
270 save(const struct ip6t_ip6 *ip, const struct ip6t_entry_target *target)
272 #ifdef IPTABLES_SAVE
273 const struct ip6t_log_info *loginfo
274 = (const struct ip6t_log_info *)target->data;
276 if (strcmp(loginfo->prefix, "") != 0)
277 printf("--log-prefix \"%s\" ", loginfo->prefix);
279 if (loginfo->level != LOG_DEFAULT_LEVEL)
280 printf("--log-level %d ", loginfo->level);
282 if (loginfo->logflags & IP6T_LOG_TCPSEQ)
283 printf("--log-tcp-sequence ");
284 if (loginfo->logflags & IP6T_LOG_TCPOPT)
285 printf("--log-tcp-options ");
286 if (loginfo->logflags & IP6T_LOG_IPOPT)
287 printf("--log-ip-options ");
288 if (loginfo->logflags & IP6T_LOG_UID)
289 printf("--log-uid ");
290 if (loginfo->logflags & IPT_LOG_MACDECODE)
291 printf("--log-macdecode ");
292 #endif
295 static
296 struct ip6tables_target log
298 .name = "LOG",
299 .version = IPTABLES_VERSION,
300 .size = IP6T_ALIGN(sizeof(struct ip6t_log_info)),
301 .userspacesize = IP6T_ALIGN(sizeof(struct ip6t_log_info)),
302 .help = &help,
303 .init = &init,
304 .parse = &parse,
305 .final_check = &final_check,
306 .print = &print,
307 .save = &save,
308 .extra_opts = opts
311 void _init(void)
313 register_target6(&log);