xref: /aosp_15_r20/external/iptables/extensions/libxt_LOG.c (revision a71a954618bbadd4a345637e5edcf36eec826889)
1 #include <stdio.h>
2 #include <string.h>
3 #define SYSLOG_NAMES
4 #include <syslog.h>
5 #include <xtables.h>
6 #include <linux/netfilter/xt_LOG.h>
7 
8 #define LOG_DEFAULT_LEVEL LOG_WARNING
9 
10 enum {
11 	/* make sure the values correspond with XT_LOG_* bit positions */
12 	O_LOG_TCPSEQ = 0,
13 	O_LOG_TCPOPTS,
14 	O_LOG_IPOPTS,
15 	O_LOG_UID,
16 	__O_LOG_NFLOG,
17 	O_LOG_MAC,
18 	O_LOG_LEVEL,
19 	O_LOG_PREFIX,
20 };
21 
LOG_help(void)22 static void LOG_help(void)
23 {
24 	printf(
25 "LOG target options:\n"
26 " --log-level level		Level of logging (numeric or see syslog.conf)\n"
27 " --log-prefix prefix		Prefix log messages with this prefix.\n"
28 " --log-tcp-sequence		Log TCP sequence numbers.\n"
29 " --log-tcp-options		Log TCP options.\n"
30 " --log-ip-options		Log IP options.\n"
31 " --log-uid			Log UID owning the local socket.\n"
32 " --log-macdecode		Decode MAC addresses and protocol.\n");
33 }
34 
35 #define s struct xt_log_info
36 static const struct xt_option_entry LOG_opts[] = {
37 	{.name = "log-level", .id = O_LOG_LEVEL, .type = XTTYPE_SYSLOGLEVEL,
38 	 .flags = XTOPT_PUT, XTOPT_POINTER(s, level)},
39 	{.name = "log-prefix", .id = O_LOG_PREFIX, .type = XTTYPE_STRING,
40 	 .flags = XTOPT_PUT, XTOPT_POINTER(s, prefix), .min = 1},
41 	{.name = "log-tcp-sequence", .id = O_LOG_TCPSEQ, .type = XTTYPE_NONE},
42 	{.name = "log-tcp-options", .id = O_LOG_TCPOPTS, .type = XTTYPE_NONE},
43 	{.name = "log-ip-options", .id = O_LOG_IPOPTS, .type = XTTYPE_NONE},
44 	{.name = "log-uid", .id = O_LOG_UID, .type = XTTYPE_NONE},
45 	{.name = "log-macdecode", .id = O_LOG_MAC, .type = XTTYPE_NONE},
46 	XTOPT_TABLEEND,
47 };
48 #undef s
49 
LOG_init(struct xt_entry_target * t)50 static void LOG_init(struct xt_entry_target *t)
51 {
52 	struct xt_log_info *loginfo = (void *)t->data;
53 
54 	loginfo->level = LOG_DEFAULT_LEVEL;
55 }
56 
LOG_parse(struct xt_option_call * cb)57 static void LOG_parse(struct xt_option_call *cb)
58 {
59 	struct xt_log_info *info = cb->data;
60 
61 	xtables_option_parse(cb);
62 	switch (cb->entry->id) {
63 	case O_LOG_PREFIX:
64 		if (strchr(cb->arg, '\n') != NULL)
65 			xtables_error(PARAMETER_PROBLEM,
66 				   "Newlines not allowed in --log-prefix");
67 		break;
68 	case O_LOG_TCPSEQ:
69 	case O_LOG_TCPOPTS:
70 	case O_LOG_IPOPTS:
71 	case O_LOG_UID:
72 	case O_LOG_MAC:
73 		info->logflags |= 1 << cb->entry->id;
74 		break;
75 	}
76 }
77 
priority2name(unsigned char level)78 static const char *priority2name(unsigned char level)
79 {
80 	int i;
81 
82 	for (i = 0; prioritynames[i].c_name; ++i) {
83 		if (level == prioritynames[i].c_val)
84 			return prioritynames[i].c_name;
85 	}
86 	return NULL;
87 }
88 
LOG_print(const void * ip,const struct xt_entry_target * target,int numeric)89 static void LOG_print(const void *ip, const struct xt_entry_target *target,
90                       int numeric)
91 {
92 	const struct xt_log_info *loginfo = (const void *)target->data;
93 
94 	printf(" LOG");
95 	if (numeric)
96 		printf(" flags %u level %u",
97 		       loginfo->logflags, loginfo->level);
98 	else {
99 		const char *pname = priority2name(loginfo->level);
100 
101 		if (pname)
102 			printf(" level %s", pname);
103 		else
104 			printf(" UNKNOWN level %u", loginfo->level);
105 		if (loginfo->logflags & XT_LOG_TCPSEQ)
106 			printf(" tcp-sequence");
107 		if (loginfo->logflags & XT_LOG_TCPOPT)
108 			printf(" tcp-options");
109 		if (loginfo->logflags & XT_LOG_IPOPT)
110 			printf(" ip-options");
111 		if (loginfo->logflags & XT_LOG_UID)
112 			printf(" uid");
113 		if (loginfo->logflags & XT_LOG_MACDECODE)
114 			printf(" macdecode");
115 		if (loginfo->logflags & ~(XT_LOG_MASK))
116 			printf(" unknown-flags");
117 	}
118 
119 	if (strcmp(loginfo->prefix, "") != 0)
120 		printf(" prefix \"%s\"", loginfo->prefix);
121 }
122 
LOG_save(const void * ip,const struct xt_entry_target * target)123 static void LOG_save(const void *ip, const struct xt_entry_target *target)
124 {
125 	const struct xt_log_info *loginfo = (const void *)target->data;
126 
127 	if (strcmp(loginfo->prefix, "") != 0) {
128 		printf(" --log-prefix");
129 		xtables_save_string(loginfo->prefix);
130 	}
131 
132 	if (loginfo->level != LOG_DEFAULT_LEVEL)
133 		printf(" --log-level %d", loginfo->level);
134 
135 	if (loginfo->logflags & XT_LOG_TCPSEQ)
136 		printf(" --log-tcp-sequence");
137 	if (loginfo->logflags & XT_LOG_TCPOPT)
138 		printf(" --log-tcp-options");
139 	if (loginfo->logflags & XT_LOG_IPOPT)
140 		printf(" --log-ip-options");
141 	if (loginfo->logflags & XT_LOG_UID)
142 		printf(" --log-uid");
143 	if (loginfo->logflags & XT_LOG_MACDECODE)
144 		printf(" --log-macdecode");
145 }
146 
LOG_xlate(struct xt_xlate * xl,const struct xt_xlate_tg_params * params)147 static int LOG_xlate(struct xt_xlate *xl,
148 		     const struct xt_xlate_tg_params *params)
149 {
150 	const struct xt_log_info *loginfo = (const void *)params->target->data;
151 	const char *pname = priority2name(loginfo->level);
152 
153 	xt_xlate_add(xl, "log");
154 	if (strcmp(loginfo->prefix, "") != 0)
155 		xt_xlate_add(xl, " prefix \"%s\"", loginfo->prefix);
156 
157 	if (loginfo->level != LOG_DEFAULT_LEVEL && pname)
158 		xt_xlate_add(xl, " level %s", pname);
159 	else if (!pname)
160 		return 0;
161 
162 	if ((loginfo->logflags & XT_LOG_MASK) == XT_LOG_MASK) {
163 		xt_xlate_add(xl, " flags all");
164 	} else {
165 		if (loginfo->logflags & (XT_LOG_TCPSEQ | XT_LOG_TCPOPT)) {
166 			const char *delim = " ";
167 
168 			xt_xlate_add(xl, " flags tcp");
169 			if (loginfo->logflags & XT_LOG_TCPSEQ) {
170 				xt_xlate_add(xl, " sequence");
171 				delim = ",";
172 			}
173 			if (loginfo->logflags & XT_LOG_TCPOPT)
174 				xt_xlate_add(xl, "%soptions", delim);
175 		}
176 		if (loginfo->logflags & XT_LOG_IPOPT)
177 			xt_xlate_add(xl, " flags ip options");
178 		if (loginfo->logflags & XT_LOG_UID)
179 			xt_xlate_add(xl, " flags skuid");
180 		if (loginfo->logflags & XT_LOG_MACDECODE)
181 			xt_xlate_add(xl, " flags ether");
182 	}
183 
184 	return 1;
185 }
186 static struct xtables_target log_tg_reg = {
187 	.name          = "LOG",
188 	.version       = XTABLES_VERSION,
189 	.family        = NFPROTO_UNSPEC,
190 	.size          = XT_ALIGN(sizeof(struct xt_log_info)),
191 	.userspacesize = XT_ALIGN(sizeof(struct xt_log_info)),
192 	.help          = LOG_help,
193 	.init          = LOG_init,
194 	.print         = LOG_print,
195 	.save          = LOG_save,
196 	.x6_parse      = LOG_parse,
197 	.x6_options    = LOG_opts,
198 	.xlate	       = LOG_xlate,
199 };
200 
_init(void)201 void _init(void)
202 {
203 	xtables_register_target(&log_tg_reg);
204 }
205