xref: /aosp_15_r20/external/iptables/extensions/libxt_NFLOG.c (revision a71a954618bbadd4a345637e5edcf36eec826889)
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