1 /*
2 * Bart De Schuymer <bdschuym@pandora.be>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * Giuseppe Longo <giuseppelng@gmail.com> adapted the original code to the
9 * xtables-compat environment in 2015.
10 *
11 */
12
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <syslog.h>
16 #include <string.h>
17 #include <getopt.h>
18 #include <xtables.h>
19 #include <linux/netfilter_bridge/ebt_log.h>
20
21 #define LOG_DEFAULT_LEVEL LOG_INFO
22
23 #define LOG_PREFIX '1'
24 #define LOG_LEVEL '2'
25 #define LOG_ARP '3'
26 #define LOG_IP '4'
27 #define LOG_LOG '5'
28 #define LOG_IP6 '6'
29
30 typedef struct _code {
31 char *c_name;
32 int c_val;
33 } CODE;
34
35 static CODE eight_priority[] = {
36 { "emerg", LOG_EMERG },
37 { "alert", LOG_ALERT },
38 { "crit", LOG_CRIT },
39 { "error", LOG_ERR },
40 { "warning", LOG_WARNING },
41 { "notice", LOG_NOTICE },
42 { "info", LOG_INFO },
43 { "debug", LOG_DEBUG }
44 };
45
name_to_loglevel(const char * arg)46 static int name_to_loglevel(const char *arg)
47 {
48 int i;
49
50 for (i = 0; i < 8; i++)
51 if (!strcmp(arg, eight_priority[i].c_name))
52 return eight_priority[i].c_val;
53
54 /* return bad loglevel */
55 return 9;
56 }
57
58 static const struct option brlog_opts[] = {
59 { .name = "log-prefix", .has_arg = true, .val = LOG_PREFIX },
60 { .name = "log-level", .has_arg = true, .val = LOG_LEVEL },
61 { .name = "log-arp", .has_arg = false, .val = LOG_ARP },
62 { .name = "log-ip", .has_arg = false, .val = LOG_IP },
63 { .name = "log", .has_arg = false, .val = LOG_LOG },
64 { .name = "log-ip6", .has_arg = false, .val = LOG_IP6 },
65 XT_GETOPT_TABLEEND,
66 };
67
brlog_help(void)68 static void brlog_help(void)
69 {
70 int i;
71
72 printf(
73 "log options:\n"
74 "--log : use this if you're not specifying anything\n"
75 "--log-level level : level = [1-8] or a string\n"
76 "--log-prefix prefix : max. %d chars.\n"
77 "--log-ip : put ip info. in the log for ip packets\n"
78 "--log-arp : put (r)arp info. in the log for (r)arp packets\n"
79 "--log-ip6 : put ip6 info. in the log for ip6 packets\n"
80 , EBT_LOG_PREFIX_SIZE - 1);
81 for (i = 0; i < 8; i++)
82 printf("%d = %s\n", eight_priority[i].c_val,
83 eight_priority[i].c_name);
84 }
85
brlog_init(struct xt_entry_target * t)86 static void brlog_init(struct xt_entry_target *t)
87 {
88 struct ebt_log_info *loginfo = (struct ebt_log_info *)t->data;
89
90 loginfo->bitmask = 0;
91 loginfo->prefix[0] = '\0';
92 loginfo->loglevel = LOG_NOTICE;
93 }
94
brlog_parse(int c,char ** argv,int invert,unsigned int * flags,const void * entry,struct xt_entry_target ** target)95 static int brlog_parse(int c, char **argv, int invert, unsigned int *flags,
96 const void *entry, struct xt_entry_target **target)
97 {
98 struct ebt_log_info *loginfo = (struct ebt_log_info *)(*target)->data;
99 long int i;
100 char *end;
101
102 switch (c) {
103 case LOG_PREFIX:
104 if (invert)
105 xtables_error(PARAMETER_PROBLEM,
106 "Unexpected `!` after --log-prefix");
107 if (strlen(optarg) > sizeof(loginfo->prefix) - 1)
108 xtables_error(PARAMETER_PROBLEM,
109 "Prefix too long");
110 if (strchr(optarg, '\"'))
111 xtables_error(PARAMETER_PROBLEM,
112 "Use of \\\" is not allowed"
113 " in the prefix");
114 strcpy((char *)loginfo->prefix, (char *)optarg);
115 break;
116 case LOG_LEVEL:
117 i = strtol(optarg, &end, 16);
118 if (*end != '\0' || i < 0 || i > 7)
119 loginfo->loglevel = name_to_loglevel(optarg);
120 else
121 loginfo->loglevel = i;
122
123 if (loginfo->loglevel == 9)
124 xtables_error(PARAMETER_PROBLEM,
125 "Problem with the log-level");
126 break;
127 case LOG_IP:
128 if (invert)
129 xtables_error(PARAMETER_PROBLEM,
130 "Unexpected `!' after --log-ip");
131 loginfo->bitmask |= EBT_LOG_IP;
132 break;
133 case LOG_ARP:
134 if (invert)
135 xtables_error(PARAMETER_PROBLEM,
136 "Unexpected `!' after --log-arp");
137 loginfo->bitmask |= EBT_LOG_ARP;
138 case LOG_LOG:
139 if (invert)
140 xtables_error(PARAMETER_PROBLEM,
141 "Unexpected `!' after --log");
142 break;
143 case LOG_IP6:
144 if (invert)
145 xtables_error(PARAMETER_PROBLEM,
146 "Unexpected `!' after --log-ip6");
147 loginfo->bitmask |= EBT_LOG_IP6;
148 break;
149 default:
150 return 0;
151 }
152
153 *flags |= loginfo->bitmask;
154 return 1;
155 }
156
brlog_final_check(unsigned int flags)157 static void brlog_final_check(unsigned int flags)
158 {
159 }
160
brlog_print(const void * ip,const struct xt_entry_target * target,int numeric)161 static void brlog_print(const void *ip, const struct xt_entry_target *target,
162 int numeric)
163 {
164 struct ebt_log_info *loginfo = (struct ebt_log_info *)target->data;
165
166 printf("--log-level %s --log-prefix \"%s\"",
167 eight_priority[loginfo->loglevel].c_name,
168 loginfo->prefix);
169
170 if (loginfo->bitmask & EBT_LOG_IP)
171 printf(" --log-ip");
172 if (loginfo->bitmask & EBT_LOG_ARP)
173 printf(" --log-arp");
174 if (loginfo->bitmask & EBT_LOG_IP6)
175 printf(" --log-ip6");
176 printf(" ");
177 }
178
179 static struct xtables_target brlog_target = {
180 .name = "log",
181 .revision = 0,
182 .version = XTABLES_VERSION,
183 .family = NFPROTO_BRIDGE,
184 .size = XT_ALIGN(sizeof(struct ebt_log_info)),
185 .userspacesize = XT_ALIGN(sizeof(struct ebt_log_info)),
186 .init = brlog_init,
187 .help = brlog_help,
188 .parse = brlog_parse,
189 .final_check = brlog_final_check,
190 .print = brlog_print,
191 .extra_opts = brlog_opts,
192 };
193
_init(void)194 void _init(void)
195 {
196 xtables_register_target(&brlog_target);
197 }
198