1 #include <stdbool.h>
2 #include <stdlib.h>
3 #include <stdio.h>
4 #include <string.h>
5 #include <getopt.h>
6 #include <xtables.h>
7
8 #include <linux/netfilter/nf_log.h>
9 #include <linux/netfilter/x_tables.h>
10 #include <linux/netfilter/xt_NFLOG.h>
11
12 enum {
13 O_GROUP = 0,
14 O_PREFIX,
15 O_RANGE,
16 O_SIZE,
17 O_THRESHOLD,
18 F_RANGE = 1 << O_RANGE,
19 F_SIZE = 1 << O_SIZE,
20 };
21
22 #define s struct xt_nflog_info
23 static const struct xt_option_entry NFLOG_opts[] = {
24 {.name = "nflog-group", .id = O_GROUP, .type = XTTYPE_UINT16,
25 .flags = XTOPT_PUT, XTOPT_POINTER(s, group)},
26 {.name = "nflog-prefix", .id = O_PREFIX, .type = XTTYPE_STRING,
27 .min = 1, .flags = XTOPT_PUT, XTOPT_POINTER(s, prefix)},
28 {.name = "nflog-range", .id = O_RANGE, .type = XTTYPE_UINT32,
29 .excl = F_SIZE, .flags = XTOPT_PUT, XTOPT_POINTER(s, len)},
30 {.name = "nflog-size", .id = O_SIZE, .type = XTTYPE_UINT32,
31 .excl = F_RANGE, .flags = XTOPT_PUT, XTOPT_POINTER(s, len)},
32 {.name = "nflog-threshold", .id = O_THRESHOLD, .type = XTTYPE_UINT16,
33 .flags = XTOPT_PUT, XTOPT_POINTER(s, threshold)},
34 XTOPT_TABLEEND,
35 };
36 #undef s
37
NFLOG_help(void)38 static void NFLOG_help(void)
39 {
40 printf("NFLOG target options:\n"
41 " --nflog-group NUM NETLINK group used for logging\n"
42 " --nflog-range NUM This option has no effect, use --nflog-size\n"
43 " --nflog-size NUM Number of bytes to copy\n"
44 " --nflog-threshold NUM Message threshold of in-kernel queue\n"
45 " --nflog-prefix STRING Prefix string for log messages\n");
46 }
47
NFLOG_init(struct xt_entry_target * t)48 static void NFLOG_init(struct xt_entry_target *t)
49 {
50 struct xt_nflog_info *info = (struct xt_nflog_info *)t->data;
51
52 info->threshold = XT_NFLOG_DEFAULT_THRESHOLD;
53 }
54
NFLOG_parse(struct xt_option_call * cb)55 static void NFLOG_parse(struct xt_option_call *cb)
56 {
57 char *nf_log_prefix = cb->udata;
58
59 xtables_option_parse(cb);
60 switch (cb->entry->id) {
61 case O_PREFIX:
62 if (strchr(cb->arg, '\n') != NULL)
63 xtables_error(PARAMETER_PROBLEM,
64 "Newlines not allowed in --log-prefix");
65
66 snprintf(nf_log_prefix, NF_LOG_PREFIXLEN, "%s", cb->arg);
67 break;
68 }
69 }
70
NFLOG_check(struct xt_fcheck_call * cb)71 static void NFLOG_check(struct xt_fcheck_call *cb)
72 {
73 struct xt_nflog_info *info = cb->data;
74
75 if (cb->xflags & F_RANGE)
76 fprintf(stderr, "warn: --nflog-range has never worked and is no"
77 " longer supported, please use --nflog-size instead\n");
78
79 if (cb->xflags & F_SIZE)
80 info->flags |= XT_NFLOG_F_COPY_LEN;
81 }
82
nflog_print(const struct xt_nflog_info * info,char * prefix)83 static void nflog_print(const struct xt_nflog_info *info, char *prefix)
84 {
85 if (info->prefix[0] != '\0') {
86 printf(" %snflog-prefix", prefix);
87 xtables_save_string(info->prefix);
88 }
89 if (info->group)
90 printf(" %snflog-group %u", prefix, info->group);
91 if (info->flags & XT_NFLOG_F_COPY_LEN)
92 printf(" %snflog-size %u", prefix, info->len);
93 else if (info->len)
94 printf(" %snflog-range %u", prefix, info->len);
95 if (info->threshold != XT_NFLOG_DEFAULT_THRESHOLD)
96 printf(" %snflog-threshold %u", prefix, info->threshold);
97 }
98
NFLOG_print(const void * ip,const struct xt_entry_target * target,int numeric)99 static void NFLOG_print(const void *ip, const struct xt_entry_target *target,
100 int numeric)
101 {
102 const struct xt_nflog_info *info = (struct xt_nflog_info *)target->data;
103
104 nflog_print(info, "");
105 }
106
NFLOG_save(const void * ip,const struct xt_entry_target * target)107 static void NFLOG_save(const void *ip, const struct xt_entry_target *target)
108 {
109 const struct xt_nflog_info *info = (struct xt_nflog_info *)target->data;
110
111 nflog_print(info, "--");
112 }
113
nflog_print_xlate(const struct xt_nflog_info * info,struct xt_xlate * xl)114 static void nflog_print_xlate(const struct xt_nflog_info *info,
115 struct xt_xlate *xl)
116 {
117 xt_xlate_add(xl, "log ");
118 if (info->prefix[0] != '\0')
119 xt_xlate_add(xl, "prefix \"%s\" ", info->prefix);
120
121 if (info->flags & XT_NFLOG_F_COPY_LEN)
122 xt_xlate_add(xl, "snaplen %u ", info->len);
123 if (info->threshold != XT_NFLOG_DEFAULT_THRESHOLD)
124 xt_xlate_add(xl, "queue-threshold %u ", info->threshold);
125 xt_xlate_add(xl, "group %u ", info->group);
126 }
127
NFLOG_xlate(struct xt_xlate * xl,const struct xt_xlate_tg_params * params)128 static int NFLOG_xlate(struct xt_xlate *xl,
129 const struct xt_xlate_tg_params *params)
130 {
131 const struct xt_nflog_info *info =
132 (struct xt_nflog_info *)params->target->data;
133
134 nflog_print_xlate(info, xl);
135
136 return 1;
137 }
138
139 static struct xtables_target nflog_target = {
140 .family = NFPROTO_UNSPEC,
141 .name = "NFLOG",
142 .version = XTABLES_VERSION,
143 .size = XT_ALIGN(sizeof(struct xt_nflog_info)),
144 .userspacesize = XT_ALIGN(sizeof(struct xt_nflog_info)),
145 .help = NFLOG_help,
146 .init = NFLOG_init,
147 .x6_fcheck = NFLOG_check,
148 .x6_parse = NFLOG_parse,
149 .print = NFLOG_print,
150 .save = NFLOG_save,
151 .x6_options = NFLOG_opts,
152 .xlate = NFLOG_xlate,
153 .udata_size = NF_LOG_PREFIXLEN
154 };
155
_init(void)156 void _init(void)
157 {
158 xtables_register_target(&nflog_target);
159 }
160