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 <xtables.h>
18 #include <linux/netfilter_bridge/ebt_log.h>
19
20 #define LOG_DEFAULT_LEVEL LOG_INFO
21
22 struct code {
23 char *c_name;
24 int c_val;
25 };
26
27 static struct code eight_priority[] = {
28 { "emerg", LOG_EMERG },
29 { "alert", LOG_ALERT },
30 { "crit", LOG_CRIT },
31 { "error", LOG_ERR },
32 { "warning", LOG_WARNING },
33 { "notice", LOG_NOTICE },
34 { "info", LOG_INFO },
35 { "debug", LOG_DEBUG }
36 };
37
38 enum {
39 /* first three must correspond with bit pos in respective EBT_LOG_* */
40 O_LOG_IP = 0,
41 O_LOG_ARP = 1,
42 O_LOG_IP6 = 3,
43 O_LOG_PREFIX,
44 O_LOG_LEVEL,
45 O_LOG_LOG,
46 };
47
48 static const struct xt_option_entry brlog_opts[] = {
49 { .name = "log-prefix", .id = O_LOG_PREFIX, .type = XTTYPE_STRING,
50 .flags = XTOPT_PUT, XTOPT_POINTER(struct ebt_log_info, prefix) },
51 { .name = "log-level", .id = O_LOG_LEVEL, .type = XTTYPE_SYSLOGLEVEL,
52 .flags = XTOPT_PUT, XTOPT_POINTER(struct ebt_log_info, loglevel) },
53 { .name = "log-arp", .id = O_LOG_ARP, .type = XTTYPE_NONE },
54 { .name = "log-ip", .id = O_LOG_IP, .type = XTTYPE_NONE },
55 { .name = "log", .id = O_LOG_LOG, .type = XTTYPE_NONE },
56 { .name = "log-ip6", .id = O_LOG_IP6, .type = XTTYPE_NONE },
57 XTOPT_TABLEEND,
58 };
59
brlog_help(void)60 static void brlog_help(void)
61 {
62 int i;
63
64 printf(
65 "log options:\n"
66 "--log : use this if you're not specifying anything\n"
67 "--log-level level : level = [1-8] or a string\n"
68 "--log-prefix prefix : max. %d chars.\n"
69 "--log-ip : put ip info. in the log for ip packets\n"
70 "--log-arp : put (r)arp info. in the log for (r)arp packets\n"
71 "--log-ip6 : put ip6 info. in the log for ip6 packets\n"
72 , EBT_LOG_PREFIX_SIZE - 1);
73 for (i = 0; i < 8; i++)
74 printf("%d = %s\n", eight_priority[i].c_val,
75 eight_priority[i].c_name);
76 }
77
brlog_init(struct xt_entry_target * t)78 static void brlog_init(struct xt_entry_target *t)
79 {
80 struct ebt_log_info *loginfo = (struct ebt_log_info *)t->data;
81
82 loginfo->loglevel = LOG_NOTICE;
83 }
84
brlog_parse(struct xt_option_call * cb)85 static void brlog_parse(struct xt_option_call *cb)
86 {
87 struct ebt_log_info *loginfo = cb->data;
88
89 xtables_option_parse(cb);
90 switch (cb->entry->id) {
91 case O_LOG_IP:
92 case O_LOG_ARP:
93 case O_LOG_IP6:
94 loginfo->bitmask |= 1 << cb->entry->id;
95 break;
96 }
97 }
98
brlog_print(const void * ip,const struct xt_entry_target * target,int numeric)99 static void brlog_print(const void *ip, const struct xt_entry_target *target,
100 int numeric)
101 {
102 struct ebt_log_info *loginfo = (struct ebt_log_info *)target->data;
103
104 printf("--log-level %s", eight_priority[loginfo->loglevel].c_name);
105
106 if (loginfo->prefix[0])
107 printf(" --log-prefix \"%s\"", loginfo->prefix);
108
109 if (loginfo->bitmask & EBT_LOG_IP)
110 printf(" --log-ip");
111 if (loginfo->bitmask & EBT_LOG_ARP)
112 printf(" --log-arp");
113 if (loginfo->bitmask & EBT_LOG_IP6)
114 printf(" --log-ip6");
115 printf(" ");
116 }
117
brlog_xlate(struct xt_xlate * xl,const struct xt_xlate_tg_params * params)118 static int brlog_xlate(struct xt_xlate *xl,
119 const struct xt_xlate_tg_params *params)
120 {
121 const struct ebt_log_info *loginfo = (const void *)params->target->data;
122
123 xt_xlate_add(xl, "log");
124 if (loginfo->prefix[0])
125 xt_xlate_add(xl, " prefix \"%s\"", loginfo->prefix);
126
127 if (loginfo->loglevel != LOG_DEFAULT_LEVEL)
128 xt_xlate_add(xl, " level %s", eight_priority[loginfo->loglevel].c_name);
129
130 /* ebt_log always decodes MAC header, nft_log always decodes upper header -
131 * so set flags ether and ignore EBT_LOG_IP, EBT_LOG_ARP and EBT_LOG_IP6 */
132 xt_xlate_add(xl, " flags ether ");
133
134 return 1;
135 }
136
137 static struct xtables_target brlog_target = {
138 .name = "log",
139 .revision = 0,
140 .ext_flags = XTABLES_EXT_WATCHER,
141 .version = XTABLES_VERSION,
142 .family = NFPROTO_BRIDGE,
143 .size = XT_ALIGN(sizeof(struct ebt_log_info)),
144 .userspacesize = XT_ALIGN(sizeof(struct ebt_log_info)),
145 .init = brlog_init,
146 .help = brlog_help,
147 .x6_parse = brlog_parse,
148 .print = brlog_print,
149 .xlate = brlog_xlate,
150 .x6_options = brlog_opts,
151 };
152
_init(void)153 void _init(void)
154 {
155 xtables_register_target(&brlog_target);
156 }
157