blob: 575d12ea2ca44e493c6e8e37f41f333105019d67 [file] [log] [blame]
Bart De Schuymerff587202005-02-08 20:02:28 +00001/* ebt_log
2 *
3 * Authors:
4 * Bart De Schuymer <bdschuym@pandora.be>
5 *
6 * April, 2002
7 */
8
Bart De Schuymer1abc55d2002-06-01 19:23:47 +00009#include <stdio.h>
10#include <stdlib.h>
11#include <string.h>
Bart De Schuymer1abc55d2002-06-01 19:23:47 +000012#include <getopt.h>
13#include "../include/ebtables_u.h"
14#include <linux/netfilter_bridge/ebt_log.h>
15
Bart De Schuymer9895a8e2003-01-11 10:14:24 +000016/*
17 * copied from syslog.h
18 * used for the LOG target
19 */
20#define LOG_EMERG 0 /* system is unusable */
21#define LOG_ALERT 1 /* action must be taken immediately */
22#define LOG_CRIT 2 /* critical conditions */
23#define LOG_ERR 3 /* error conditions */
24#define LOG_WARNING 4 /* warning conditions */
25#define LOG_NOTICE 5 /* normal but significant condition */
26#define LOG_INFO 6 /* informational */
27#define LOG_DEBUG 7 /* debug-level messages */
Bart De Schuymer9cfd6542002-08-13 16:08:08 +000028
Bart De Schuymer1abc55d2002-06-01 19:23:47 +000029#define LOG_DEFAULT_LEVEL LOG_INFO
30
31typedef struct _code {
Bart De Schuymer9cfd6542002-08-13 16:08:08 +000032 char *c_name;
33 int c_val;
Bart De Schuymer1abc55d2002-06-01 19:23:47 +000034} CODE;
35
36static CODE eight_priority[] = {
37 { "emerg", LOG_EMERG },
38 { "alert", LOG_ALERT },
39 { "crit", LOG_CRIT },
40 { "error", LOG_ERR },
41 { "warning", LOG_WARNING },
42 { "notice", LOG_NOTICE },
43 { "info", LOG_INFO },
Bart De Schuymer9cfd6542002-08-13 16:08:08 +000044 { "debug", LOG_DEBUG }
Bart De Schuymer1abc55d2002-06-01 19:23:47 +000045};
46
47static int name_to_loglevel(char* arg)
48{
Bart De Schuymer9cfd6542002-08-13 16:08:08 +000049 int i;
Bart De Schuymer1abc55d2002-06-01 19:23:47 +000050
Bart De Schuymer9cfd6542002-08-13 16:08:08 +000051 for (i = 0; i < 8; i++)
Bart De Schuymer1abc55d2002-06-01 19:23:47 +000052 if (!strcmp(arg, eight_priority[i].c_name))
Bart De Schuymer9cfd6542002-08-13 16:08:08 +000053 return eight_priority[i].c_val;
Bart De Schuymer9895a8e2003-01-11 10:14:24 +000054 /* return bad loglevel */
Bart De Schuymer1abc55d2002-06-01 19:23:47 +000055 return 9;
56}
57
58#define LOG_PREFIX '1'
59#define LOG_LEVEL '2'
60#define LOG_ARP '3'
61#define LOG_IP '4'
62#define LOG_LOG '5'
63static struct option opts[] =
64{
65 { "log-prefix", required_argument, 0, LOG_PREFIX },
66 { "log-level" , required_argument, 0, LOG_LEVEL },
67 { "log-arp" , no_argument , 0, LOG_ARP },
68 { "log-ip" , no_argument , 0, LOG_IP },
69 { "log" , no_argument , 0, LOG_LOG },
70 { 0 }
71};
72
73static void print_help()
74{
75 int i;
76
77 printf(
78"log options:\n"
79"--log : use this if you're not specifying anything\n"
80"--log-level level : level = [1-8] or a string\n"
81"--log-prefix prefix : max. %d chars.\n"
82"--log-ip : put ip info. in the log for ip packets\n"
83"--log-arp : put (r)arp info. in the log for (r)arp packets\n"
84 , EBT_LOG_PREFIX_SIZE - 1);
85 printf("levels:\n");
86 for (i = 0; i < 8; i++)
87 printf("%d = %s\n", eight_priority[i].c_val,
88 eight_priority[i].c_name);
89}
90
91static void init(struct ebt_entry_watcher *watcher)
92{
93 struct ebt_log_info *loginfo = (struct ebt_log_info *)watcher->data;
94
95 loginfo->bitmask = 0;
96 loginfo->prefix[0] = '\0';
97 loginfo->loglevel = LOG_NOTICE;
98}
99
100#define OPT_PREFIX 0x01
101#define OPT_LEVEL 0x02
102#define OPT_ARP 0x04
103#define OPT_IP 0x08
104#define OPT_LOG 0x10
105static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry,
106 unsigned int *flags, struct ebt_entry_watcher **watcher)
107{
108 struct ebt_log_info *loginfo = (struct ebt_log_info *)(*watcher)->data;
Bart De Schuymer9cfd6542002-08-13 16:08:08 +0000109 long int i;
Bart De Schuymer1abc55d2002-06-01 19:23:47 +0000110 char *end;
111
112 switch (c) {
113 case LOG_PREFIX:
Bart De Schuymerff587202005-02-08 20:02:28 +0000114 ebt_check_option2(flags, OPT_PREFIX);
115 if (ebt_check_inverse(optarg))
116 ebt_print_error2("Unexpected `!' after --log-prefix");
Bart De Schuymer1abc55d2002-06-01 19:23:47 +0000117 if (strlen(optarg) > sizeof(loginfo->prefix) - 1)
Bart De Schuymerff587202005-02-08 20:02:28 +0000118 ebt_print_error2("Prefix too long");
Bart De Schuymerfa747392005-09-26 20:33:47 +0000119 if (strchr(optarg, '\"'))
120 ebt_print_error2("Use of \\\" is not allowed in the prefix");
Bart De Schuymer510c9ce2006-01-23 18:50:54 +0000121 strcpy((char *)loginfo->prefix, (char *)optarg);
Bart De Schuymer1abc55d2002-06-01 19:23:47 +0000122 break;
123
124 case LOG_LEVEL:
Bart De Schuymerff587202005-02-08 20:02:28 +0000125 ebt_check_option2(flags, OPT_LEVEL);
Bart De Schuymer1abc55d2002-06-01 19:23:47 +0000126 i = strtol(optarg, &end, 16);
127 if (*end != '\0' || i < 0 || i > 7)
128 loginfo->loglevel = name_to_loglevel(optarg);
129 else
130 loginfo->loglevel = i;
131 if (loginfo->loglevel == 9)
Bart De Schuymerff587202005-02-08 20:02:28 +0000132 ebt_print_error2("Problem with the log-level");
Bart De Schuymer1abc55d2002-06-01 19:23:47 +0000133 break;
134
135 case LOG_IP:
Bart De Schuymerff587202005-02-08 20:02:28 +0000136 ebt_check_option2(flags, OPT_IP);
137 if (ebt_check_inverse(optarg))
138 ebt_print_error2("Unexpected `!' after --log-ip");
Bart De Schuymer1abc55d2002-06-01 19:23:47 +0000139 loginfo->bitmask |= EBT_LOG_IP;
140 break;
141
142 case LOG_ARP:
Bart De Schuymerff587202005-02-08 20:02:28 +0000143 ebt_check_option2(flags, OPT_ARP);
144 if (ebt_check_inverse(optarg))
145 ebt_print_error2("Unexpected `!' after --log-arp");
Bart De Schuymer1abc55d2002-06-01 19:23:47 +0000146 loginfo->bitmask |= EBT_LOG_ARP;
147 break;
148
149 case LOG_LOG:
Bart De Schuymerff587202005-02-08 20:02:28 +0000150 ebt_check_option2(flags, OPT_LOG);
151 if (ebt_check_inverse(optarg))
152 ebt_print_error2("Unexpected `!' after --log");
Bart De Schuymer1abc55d2002-06-01 19:23:47 +0000153 break;
154 default:
155 return 0;
156 }
157 return 1;
158}
159
160static void final_check(const struct ebt_u_entry *entry,
Bart De Schuymer7b9aaeb2002-06-23 20:38:34 +0000161 const struct ebt_entry_watcher *watcher, const char *name,
Bart De Schuymerc9b52932002-08-24 13:26:34 +0000162 unsigned int hookmask, unsigned int time)
Bart De Schuymer1abc55d2002-06-01 19:23:47 +0000163{
Bart De Schuymer1abc55d2002-06-01 19:23:47 +0000164}
165
166static void print(const struct ebt_u_entry *entry,
167 const struct ebt_entry_watcher *watcher)
168{
169 struct ebt_log_info *loginfo = (struct ebt_log_info *)watcher->data;
170
Bart De Schuymer41e8a192002-06-23 08:03:12 +0000171 printf("--log-level %s --log-prefix \"%s\"",
Bart De Schuymer1abc55d2002-06-01 19:23:47 +0000172 eight_priority[loginfo->loglevel].c_name,
173 loginfo->prefix);
174 if (loginfo->bitmask & EBT_LOG_IP)
Bart De Schuymer41e8a192002-06-23 08:03:12 +0000175 printf(" --log-ip");
Bart De Schuymer1abc55d2002-06-01 19:23:47 +0000176 if (loginfo->bitmask & EBT_LOG_ARP)
Bart De Schuymer41e8a192002-06-23 08:03:12 +0000177 printf(" --log-arp");
Bart De Schuymer1abc55d2002-06-01 19:23:47 +0000178 printf(" ");
179}
180
181static int compare(const struct ebt_entry_watcher *w1,
182 const struct ebt_entry_watcher *w2)
183{
184 struct ebt_log_info *loginfo1 = (struct ebt_log_info *)w1->data;
185 struct ebt_log_info *loginfo2 = (struct ebt_log_info *)w2->data;
186
187 if (loginfo1->loglevel != loginfo2->loglevel)
188 return 0;
189 if (loginfo1->bitmask != loginfo2->bitmask)
190 return 0;
Bart De Schuymer510c9ce2006-01-23 18:50:54 +0000191 return !strcmp((char *)loginfo1->prefix, (char *)loginfo2->prefix);
Bart De Schuymer1abc55d2002-06-01 19:23:47 +0000192}
193
194static struct ebt_u_watcher log_watcher =
195{
Bart De Schuymer7cf1cca2003-08-30 16:20:19 +0000196 .name = EBT_LOG_WATCHER,
197 .size = sizeof(struct ebt_log_info),
198 .help = print_help,
199 .init = init,
200 .parse = parse,
201 .final_check = final_check,
202 .print = print,
203 .compare = compare,
204 .extra_ops = opts,
Bart De Schuymer1abc55d2002-06-01 19:23:47 +0000205};
206
Bart De Schuymer64182a32004-01-21 20:39:54 +0000207void _init(void)
Bart De Schuymer1abc55d2002-06-01 19:23:47 +0000208{
Bart De Schuymer8339ff12004-01-14 20:05:27 +0000209 ebt_register_watcher(&log_watcher);
Bart De Schuymer1abc55d2002-06-01 19:23:47 +0000210}