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