blob: b6e62ebb40b7acf7010a0d2ab820e06b796af70c [file] [log] [blame]
Bart De Schuymer1abc55d2002-06-01 19:23:47 +00001#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <sys/socket.h>
Bart De Schuymer1abc55d2002-06-01 19:23:47 +00005#include <getopt.h>
6#include "../include/ebtables_u.h"
7#include <linux/netfilter_bridge/ebt_log.h>
8
9// copied from syslog.h
10// used for the LOG target
11#define LOG_EMERG 0 // system is unusable
12#define LOG_ALERT 1 // action must be taken immediately
13#define LOG_CRIT 2 // critical conditions
14#define LOG_ERR 3 // error conditions
15#define LOG_WARNING 4 // warning conditions
16#define LOG_NOTICE 5 // normal but significant condition
17#define LOG_INFO 6 // informational
18#define LOG_DEBUG 7 // debug-level messages
19#define LOG_DEFAULT_LEVEL LOG_INFO
20
21typedef struct _code {
22 char *c_name;
23 int c_val;
24} CODE;
25
26static CODE eight_priority[] = {
27 { "emerg", LOG_EMERG },
28 { "alert", LOG_ALERT },
29 { "crit", LOG_CRIT },
30 { "error", LOG_ERR },
31 { "warning", LOG_WARNING },
32 { "notice", LOG_NOTICE },
33 { "info", LOG_INFO },
34 { "debug", LOG_DEBUG },
35 { NULL, -1 }
36};
37
38static int name_to_loglevel(char* arg)
39{
40 int i = 0, c_val = eight_priority[0].c_val;
41
42 while (c_val != -1) {
43 if (!strcmp(arg, eight_priority[i].c_name))
44 return c_val;
45 i++;
46 c_val = eight_priority[i].c_val;
47 }
48 // return bad loglevel
49 return 9;
50}
51
52#define LOG_PREFIX '1'
53#define LOG_LEVEL '2'
54#define LOG_ARP '3'
55#define LOG_IP '4'
56#define LOG_LOG '5'
57static struct option opts[] =
58{
59 { "log-prefix", required_argument, 0, LOG_PREFIX },
60 { "log-level" , required_argument, 0, LOG_LEVEL },
61 { "log-arp" , no_argument , 0, LOG_ARP },
62 { "log-ip" , no_argument , 0, LOG_IP },
63 { "log" , no_argument , 0, LOG_LOG },
64 { 0 }
65};
66
67static void print_help()
68{
69 int i;
70
71 printf(
72"log options:\n"
73"--log : use this if you're not specifying anything\n"
74"--log-level level : level = [1-8] or a string\n"
75"--log-prefix prefix : max. %d chars.\n"
76"--log-ip : put ip info. in the log for ip packets\n"
77"--log-arp : put (r)arp info. in the log for (r)arp packets\n"
78 , EBT_LOG_PREFIX_SIZE - 1);
79 printf("levels:\n");
80 for (i = 0; i < 8; i++)
81 printf("%d = %s\n", eight_priority[i].c_val,
82 eight_priority[i].c_name);
83}
84
85static void init(struct ebt_entry_watcher *watcher)
86{
87 struct ebt_log_info *loginfo = (struct ebt_log_info *)watcher->data;
88
89 loginfo->bitmask = 0;
90 loginfo->prefix[0] = '\0';
91 loginfo->loglevel = LOG_NOTICE;
92}
93
94#define OPT_PREFIX 0x01
95#define OPT_LEVEL 0x02
96#define OPT_ARP 0x04
97#define OPT_IP 0x08
98#define OPT_LOG 0x10
99static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry,
100 unsigned int *flags, struct ebt_entry_watcher **watcher)
101{
102 struct ebt_log_info *loginfo = (struct ebt_log_info *)(*watcher)->data;
103 int i;
104 char *end;
105
106 switch (c) {
107 case LOG_PREFIX:
108 check_option(flags, OPT_PREFIX);
109 if (strlen(optarg) > sizeof(loginfo->prefix) - 1)
110 print_error("Prefix too long");
111 strcpy(loginfo->prefix, optarg);
112 break;
113
114 case LOG_LEVEL:
115 check_option(flags, OPT_LEVEL);
116 i = strtol(optarg, &end, 16);
117 if (*end != '\0' || i < 0 || i > 7)
118 loginfo->loglevel = name_to_loglevel(optarg);
119 else
120 loginfo->loglevel = i;
121 if (loginfo->loglevel == 9)
122 print_error("Problem with the log-level");
123 break;
124
125 case LOG_IP:
126 check_option(flags, OPT_IP);
127 loginfo->bitmask |= EBT_LOG_IP;
128 break;
129
130 case LOG_ARP:
131 check_option(flags, OPT_ARP);
132 loginfo->bitmask |= EBT_LOG_ARP;
133 break;
134
135 case LOG_LOG:
136 check_option(flags, OPT_LOG);
137 break;
138 default:
139 return 0;
140 }
141 return 1;
142}
143
144static void final_check(const struct ebt_u_entry *entry,
Bart De Schuymer7b9aaeb2002-06-23 20:38:34 +0000145 const struct ebt_entry_watcher *watcher, const char *name,
146 unsigned int hook_mask, unsigned int time)
Bart De Schuymer1abc55d2002-06-01 19:23:47 +0000147{
148 return;
149}
150
151static void print(const struct ebt_u_entry *entry,
152 const struct ebt_entry_watcher *watcher)
153{
154 struct ebt_log_info *loginfo = (struct ebt_log_info *)watcher->data;
155
Bart De Schuymer41e8a192002-06-23 08:03:12 +0000156 printf("--log-level %s --log-prefix \"%s\"",
Bart De Schuymer1abc55d2002-06-01 19:23:47 +0000157 eight_priority[loginfo->loglevel].c_name,
158 loginfo->prefix);
159 if (loginfo->bitmask & EBT_LOG_IP)
Bart De Schuymer41e8a192002-06-23 08:03:12 +0000160 printf(" --log-ip");
Bart De Schuymer1abc55d2002-06-01 19:23:47 +0000161 if (loginfo->bitmask & EBT_LOG_ARP)
Bart De Schuymer41e8a192002-06-23 08:03:12 +0000162 printf(" --log-arp");
Bart De Schuymer1abc55d2002-06-01 19:23:47 +0000163 printf(" ");
164}
165
166static int compare(const struct ebt_entry_watcher *w1,
167 const struct ebt_entry_watcher *w2)
168{
169 struct ebt_log_info *loginfo1 = (struct ebt_log_info *)w1->data;
170 struct ebt_log_info *loginfo2 = (struct ebt_log_info *)w2->data;
171
172 if (loginfo1->loglevel != loginfo2->loglevel)
173 return 0;
174 if (loginfo1->bitmask != loginfo2->bitmask)
175 return 0;
176 return !strcmp(loginfo1->prefix, loginfo2->prefix);
177}
178
179static struct ebt_u_watcher log_watcher =
180{
181 EBT_LOG_WATCHER,
182 sizeof(struct ebt_log_info),
183 print_help,
184 init,
185 parse,
186 final_check,
187 print,
188 compare,
189 opts,
190};
191
192#undef _init
193static void _init(void) __attribute__ ((constructor));
194static void _init(void)
195{
196 register_watcher(&log_watcher);
197}