diff options
author | Richard Weinberger <richard@nod.at> | 2012-02-10 17:10:52 -0500 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2012-03-07 11:40:49 -0500 |
commit | 6939c33a757bd006c5e0b8b5fd429fc587a4d0f4 (patch) | |
tree | c635fa7ceeb8a1a80540b45cf9e059ccb98ecdb1 /net/ipv4 | |
parent | 544d5c7d9f4d1ec4f170bc5bcc522012cb7704bc (diff) |
netfilter: merge ipt_LOG and ip6_LOG into xt_LOG
ipt_LOG and ip6_LOG have a lot of common code, merge them
to reduce duplicate code.
Signed-off-by: Richard Weinberger <richard@nod.at>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/netfilter/Kconfig | 9 | ||||
-rw-r--r-- | net/ipv4/netfilter/Makefile | 1 | ||||
-rw-r--r-- | net/ipv4/netfilter/ipt_LOG.c | 516 |
3 files changed, 0 insertions, 526 deletions
diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig index 74dfc9e5211f..fcc543cd987a 100644 --- a/net/ipv4/netfilter/Kconfig +++ b/net/ipv4/netfilter/Kconfig | |||
@@ -123,15 +123,6 @@ config IP_NF_TARGET_REJECT | |||
123 | 123 | ||
124 | To compile it as a module, choose M here. If unsure, say N. | 124 | To compile it as a module, choose M here. If unsure, say N. |
125 | 125 | ||
126 | config IP_NF_TARGET_LOG | ||
127 | tristate "LOG target support" | ||
128 | default m if NETFILTER_ADVANCED=n | ||
129 | help | ||
130 | This option adds a `LOG' target, which allows you to create rules in | ||
131 | any iptables table which records the packet header to the syslog. | ||
132 | |||
133 | To compile it as a module, choose M here. If unsure, say N. | ||
134 | |||
135 | config IP_NF_TARGET_ULOG | 126 | config IP_NF_TARGET_ULOG |
136 | tristate "ULOG target support" | 127 | tristate "ULOG target support" |
137 | default m if NETFILTER_ADVANCED=n | 128 | default m if NETFILTER_ADVANCED=n |
diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile index 213a462b739b..240b68469a7a 100644 --- a/net/ipv4/netfilter/Makefile +++ b/net/ipv4/netfilter/Makefile | |||
@@ -54,7 +54,6 @@ obj-$(CONFIG_IP_NF_MATCH_RPFILTER) += ipt_rpfilter.o | |||
54 | # targets | 54 | # targets |
55 | obj-$(CONFIG_IP_NF_TARGET_CLUSTERIP) += ipt_CLUSTERIP.o | 55 | obj-$(CONFIG_IP_NF_TARGET_CLUSTERIP) += ipt_CLUSTERIP.o |
56 | obj-$(CONFIG_IP_NF_TARGET_ECN) += ipt_ECN.o | 56 | obj-$(CONFIG_IP_NF_TARGET_ECN) += ipt_ECN.o |
57 | obj-$(CONFIG_IP_NF_TARGET_LOG) += ipt_LOG.o | ||
58 | obj-$(CONFIG_IP_NF_TARGET_MASQUERADE) += ipt_MASQUERADE.o | 57 | obj-$(CONFIG_IP_NF_TARGET_MASQUERADE) += ipt_MASQUERADE.o |
59 | obj-$(CONFIG_IP_NF_TARGET_NETMAP) += ipt_NETMAP.o | 58 | obj-$(CONFIG_IP_NF_TARGET_NETMAP) += ipt_NETMAP.o |
60 | obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o | 59 | obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o |
diff --git a/net/ipv4/netfilter/ipt_LOG.c b/net/ipv4/netfilter/ipt_LOG.c deleted file mode 100644 index d76d6c9ed946..000000000000 --- a/net/ipv4/netfilter/ipt_LOG.c +++ /dev/null | |||
@@ -1,516 +0,0 @@ | |||
1 | /* | ||
2 | * This is a module which is used for logging packets. | ||
3 | */ | ||
4 | |||
5 | /* (C) 1999-2001 Paul `Rusty' Russell | ||
6 | * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/spinlock.h> | ||
15 | #include <linux/skbuff.h> | ||
16 | #include <linux/if_arp.h> | ||
17 | #include <linux/ip.h> | ||
18 | #include <net/icmp.h> | ||
19 | #include <net/udp.h> | ||
20 | #include <net/tcp.h> | ||
21 | #include <net/route.h> | ||
22 | |||
23 | #include <linux/netfilter.h> | ||
24 | #include <linux/netfilter/x_tables.h> | ||
25 | #include <linux/netfilter_ipv4/ipt_LOG.h> | ||
26 | #include <net/netfilter/nf_log.h> | ||
27 | #include <net/netfilter/xt_log.h> | ||
28 | |||
29 | MODULE_LICENSE("GPL"); | ||
30 | MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>"); | ||
31 | MODULE_DESCRIPTION("Xtables: IPv4 packet logging to syslog"); | ||
32 | |||
33 | /* One level of recursion won't kill us */ | ||
34 | static void dump_packet(struct sbuff *m, | ||
35 | const struct nf_loginfo *info, | ||
36 | const struct sk_buff *skb, | ||
37 | unsigned int iphoff) | ||
38 | { | ||
39 | struct iphdr _iph; | ||
40 | const struct iphdr *ih; | ||
41 | unsigned int logflags; | ||
42 | |||
43 | if (info->type == NF_LOG_TYPE_LOG) | ||
44 | logflags = info->u.log.logflags; | ||
45 | else | ||
46 | logflags = NF_LOG_MASK; | ||
47 | |||
48 | ih = skb_header_pointer(skb, iphoff, sizeof(_iph), &_iph); | ||
49 | if (ih == NULL) { | ||
50 | sb_add(m, "TRUNCATED"); | ||
51 | return; | ||
52 | } | ||
53 | |||
54 | /* Important fields: | ||
55 | * TOS, len, DF/MF, fragment offset, TTL, src, dst, options. */ | ||
56 | /* Max length: 40 "SRC=255.255.255.255 DST=255.255.255.255 " */ | ||
57 | sb_add(m, "SRC=%pI4 DST=%pI4 ", | ||
58 | &ih->saddr, &ih->daddr); | ||
59 | |||
60 | /* Max length: 46 "LEN=65535 TOS=0xFF PREC=0xFF TTL=255 ID=65535 " */ | ||
61 | sb_add(m, "LEN=%u TOS=0x%02X PREC=0x%02X TTL=%u ID=%u ", | ||
62 | ntohs(ih->tot_len), ih->tos & IPTOS_TOS_MASK, | ||
63 | ih->tos & IPTOS_PREC_MASK, ih->ttl, ntohs(ih->id)); | ||
64 | |||
65 | /* Max length: 6 "CE DF MF " */ | ||
66 | if (ntohs(ih->frag_off) & IP_CE) | ||
67 | sb_add(m, "CE "); | ||
68 | if (ntohs(ih->frag_off) & IP_DF) | ||
69 | sb_add(m, "DF "); | ||
70 | if (ntohs(ih->frag_off) & IP_MF) | ||
71 | sb_add(m, "MF "); | ||
72 | |||
73 | /* Max length: 11 "FRAG:65535 " */ | ||
74 | if (ntohs(ih->frag_off) & IP_OFFSET) | ||
75 | sb_add(m, "FRAG:%u ", ntohs(ih->frag_off) & IP_OFFSET); | ||
76 | |||
77 | if ((logflags & IPT_LOG_IPOPT) && | ||
78 | ih->ihl * 4 > sizeof(struct iphdr)) { | ||
79 | const unsigned char *op; | ||
80 | unsigned char _opt[4 * 15 - sizeof(struct iphdr)]; | ||
81 | unsigned int i, optsize; | ||
82 | |||
83 | optsize = ih->ihl * 4 - sizeof(struct iphdr); | ||
84 | op = skb_header_pointer(skb, iphoff+sizeof(_iph), | ||
85 | optsize, _opt); | ||
86 | if (op == NULL) { | ||
87 | sb_add(m, "TRUNCATED"); | ||
88 | return; | ||
89 | } | ||
90 | |||
91 | /* Max length: 127 "OPT (" 15*4*2chars ") " */ | ||
92 | sb_add(m, "OPT ("); | ||
93 | for (i = 0; i < optsize; i++) | ||
94 | sb_add(m, "%02X", op[i]); | ||
95 | sb_add(m, ") "); | ||
96 | } | ||
97 | |||
98 | switch (ih->protocol) { | ||
99 | case IPPROTO_TCP: { | ||
100 | struct tcphdr _tcph; | ||
101 | const struct tcphdr *th; | ||
102 | |||
103 | /* Max length: 10 "PROTO=TCP " */ | ||
104 | sb_add(m, "PROTO=TCP "); | ||
105 | |||
106 | if (ntohs(ih->frag_off) & IP_OFFSET) | ||
107 | break; | ||
108 | |||
109 | /* Max length: 25 "INCOMPLETE [65535 bytes] " */ | ||
110 | th = skb_header_pointer(skb, iphoff + ih->ihl * 4, | ||
111 | sizeof(_tcph), &_tcph); | ||
112 | if (th == NULL) { | ||
113 | sb_add(m, "INCOMPLETE [%u bytes] ", | ||
114 | skb->len - iphoff - ih->ihl*4); | ||
115 | break; | ||
116 | } | ||
117 | |||
118 | /* Max length: 20 "SPT=65535 DPT=65535 " */ | ||
119 | sb_add(m, "SPT=%u DPT=%u ", | ||
120 | ntohs(th->source), ntohs(th->dest)); | ||
121 | /* Max length: 30 "SEQ=4294967295 ACK=4294967295 " */ | ||
122 | if (logflags & IPT_LOG_TCPSEQ) | ||
123 | sb_add(m, "SEQ=%u ACK=%u ", | ||
124 | ntohl(th->seq), ntohl(th->ack_seq)); | ||
125 | /* Max length: 13 "WINDOW=65535 " */ | ||
126 | sb_add(m, "WINDOW=%u ", ntohs(th->window)); | ||
127 | /* Max length: 9 "RES=0x3F " */ | ||
128 | sb_add(m, "RES=0x%02x ", (u8)(ntohl(tcp_flag_word(th) & TCP_RESERVED_BITS) >> 22)); | ||
129 | /* Max length: 32 "CWR ECE URG ACK PSH RST SYN FIN " */ | ||
130 | if (th->cwr) | ||
131 | sb_add(m, "CWR "); | ||
132 | if (th->ece) | ||
133 | sb_add(m, "ECE "); | ||
134 | if (th->urg) | ||
135 | sb_add(m, "URG "); | ||
136 | if (th->ack) | ||
137 | sb_add(m, "ACK "); | ||
138 | if (th->psh) | ||
139 | sb_add(m, "PSH "); | ||
140 | if (th->rst) | ||
141 | sb_add(m, "RST "); | ||
142 | if (th->syn) | ||
143 | sb_add(m, "SYN "); | ||
144 | if (th->fin) | ||
145 | sb_add(m, "FIN "); | ||
146 | /* Max length: 11 "URGP=65535 " */ | ||
147 | sb_add(m, "URGP=%u ", ntohs(th->urg_ptr)); | ||
148 | |||
149 | if ((logflags & IPT_LOG_TCPOPT) && | ||
150 | th->doff * 4 > sizeof(struct tcphdr)) { | ||
151 | unsigned char _opt[4 * 15 - sizeof(struct tcphdr)]; | ||
152 | const unsigned char *op; | ||
153 | unsigned int i, optsize; | ||
154 | |||
155 | optsize = th->doff * 4 - sizeof(struct tcphdr); | ||
156 | op = skb_header_pointer(skb, | ||
157 | iphoff+ih->ihl*4+sizeof(_tcph), | ||
158 | optsize, _opt); | ||
159 | if (op == NULL) { | ||
160 | sb_add(m, "TRUNCATED"); | ||
161 | return; | ||
162 | } | ||
163 | |||
164 | /* Max length: 127 "OPT (" 15*4*2chars ") " */ | ||
165 | sb_add(m, "OPT ("); | ||
166 | for (i = 0; i < optsize; i++) | ||
167 | sb_add(m, "%02X", op[i]); | ||
168 | sb_add(m, ") "); | ||
169 | } | ||
170 | break; | ||
171 | } | ||
172 | case IPPROTO_UDP: | ||
173 | case IPPROTO_UDPLITE: { | ||
174 | struct udphdr _udph; | ||
175 | const struct udphdr *uh; | ||
176 | |||
177 | if (ih->protocol == IPPROTO_UDP) | ||
178 | /* Max length: 10 "PROTO=UDP " */ | ||
179 | sb_add(m, "PROTO=UDP " ); | ||
180 | else /* Max length: 14 "PROTO=UDPLITE " */ | ||
181 | sb_add(m, "PROTO=UDPLITE "); | ||
182 | |||
183 | if (ntohs(ih->frag_off) & IP_OFFSET) | ||
184 | break; | ||
185 | |||
186 | /* Max length: 25 "INCOMPLETE [65535 bytes] " */ | ||
187 | uh = skb_header_pointer(skb, iphoff+ih->ihl*4, | ||
188 | sizeof(_udph), &_udph); | ||
189 | if (uh == NULL) { | ||
190 | sb_add(m, "INCOMPLETE [%u bytes] ", | ||
191 | skb->len - iphoff - ih->ihl*4); | ||
192 | break; | ||
193 | } | ||
194 | |||
195 | /* Max length: 20 "SPT=65535 DPT=65535 " */ | ||
196 | sb_add(m, "SPT=%u DPT=%u LEN=%u ", | ||
197 | ntohs(uh->source), ntohs(uh->dest), | ||
198 | ntohs(uh->len)); | ||
199 | break; | ||
200 | } | ||
201 | case IPPROTO_ICMP: { | ||
202 | struct icmphdr _icmph; | ||
203 | const struct icmphdr *ich; | ||
204 | static const size_t required_len[NR_ICMP_TYPES+1] | ||
205 | = { [ICMP_ECHOREPLY] = 4, | ||
206 | [ICMP_DEST_UNREACH] | ||
207 | = 8 + sizeof(struct iphdr), | ||
208 | [ICMP_SOURCE_QUENCH] | ||
209 | = 8 + sizeof(struct iphdr), | ||
210 | [ICMP_REDIRECT] | ||
211 | = 8 + sizeof(struct iphdr), | ||
212 | [ICMP_ECHO] = 4, | ||
213 | [ICMP_TIME_EXCEEDED] | ||
214 | = 8 + sizeof(struct iphdr), | ||
215 | [ICMP_PARAMETERPROB] | ||
216 | = 8 + sizeof(struct iphdr), | ||
217 | [ICMP_TIMESTAMP] = 20, | ||
218 | [ICMP_TIMESTAMPREPLY] = 20, | ||
219 | [ICMP_ADDRESS] = 12, | ||
220 | [ICMP_ADDRESSREPLY] = 12 }; | ||
221 | |||
222 | /* Max length: 11 "PROTO=ICMP " */ | ||
223 | sb_add(m, "PROTO=ICMP "); | ||
224 | |||
225 | if (ntohs(ih->frag_off) & IP_OFFSET) | ||
226 | break; | ||
227 | |||
228 | /* Max length: 25 "INCOMPLETE [65535 bytes] " */ | ||
229 | ich = skb_header_pointer(skb, iphoff + ih->ihl * 4, | ||
230 | sizeof(_icmph), &_icmph); | ||
231 | if (ich == NULL) { | ||
232 | sb_add(m, "INCOMPLETE [%u bytes] ", | ||
233 | skb->len - iphoff - ih->ihl*4); | ||
234 | break; | ||
235 | } | ||
236 | |||
237 | /* Max length: 18 "TYPE=255 CODE=255 " */ | ||
238 | sb_add(m, "TYPE=%u CODE=%u ", ich->type, ich->code); | ||
239 | |||
240 | /* Max length: 25 "INCOMPLETE [65535 bytes] " */ | ||
241 | if (ich->type <= NR_ICMP_TYPES && | ||
242 | required_len[ich->type] && | ||
243 | skb->len-iphoff-ih->ihl*4 < required_len[ich->type]) { | ||
244 | sb_add(m, "INCOMPLETE [%u bytes] ", | ||
245 | skb->len - iphoff - ih->ihl*4); | ||
246 | break; | ||
247 | } | ||
248 | |||
249 | switch (ich->type) { | ||
250 | case ICMP_ECHOREPLY: | ||
251 | case ICMP_ECHO: | ||
252 | /* Max length: 19 "ID=65535 SEQ=65535 " */ | ||
253 | sb_add(m, "ID=%u SEQ=%u ", | ||
254 | ntohs(ich->un.echo.id), | ||
255 | ntohs(ich->un.echo.sequence)); | ||
256 | break; | ||
257 | |||
258 | case ICMP_PARAMETERPROB: | ||
259 | /* Max length: 14 "PARAMETER=255 " */ | ||
260 | sb_add(m, "PARAMETER=%u ", | ||
261 | ntohl(ich->un.gateway) >> 24); | ||
262 | break; | ||
263 | case ICMP_REDIRECT: | ||
264 | /* Max length: 24 "GATEWAY=255.255.255.255 " */ | ||
265 | sb_add(m, "GATEWAY=%pI4 ", &ich->un.gateway); | ||
266 | /* Fall through */ | ||
267 | case ICMP_DEST_UNREACH: | ||
268 | case ICMP_SOURCE_QUENCH: | ||
269 | case ICMP_TIME_EXCEEDED: | ||
270 | /* Max length: 3+maxlen */ | ||
271 | if (!iphoff) { /* Only recurse once. */ | ||
272 | sb_add(m, "["); | ||
273 | dump_packet(m, info, skb, | ||
274 | iphoff + ih->ihl*4+sizeof(_icmph)); | ||
275 | sb_add(m, "] "); | ||
276 | } | ||
277 | |||
278 | /* Max length: 10 "MTU=65535 " */ | ||
279 | if (ich->type == ICMP_DEST_UNREACH && | ||
280 | ich->code == ICMP_FRAG_NEEDED) | ||
281 | sb_add(m, "MTU=%u ", ntohs(ich->un.frag.mtu)); | ||
282 | } | ||
283 | break; | ||
284 | } | ||
285 | /* Max Length */ | ||
286 | case IPPROTO_AH: { | ||
287 | struct ip_auth_hdr _ahdr; | ||
288 | const struct ip_auth_hdr *ah; | ||
289 | |||
290 | if (ntohs(ih->frag_off) & IP_OFFSET) | ||
291 | break; | ||
292 | |||
293 | /* Max length: 9 "PROTO=AH " */ | ||
294 | sb_add(m, "PROTO=AH "); | ||
295 | |||
296 | /* Max length: 25 "INCOMPLETE [65535 bytes] " */ | ||
297 | ah = skb_header_pointer(skb, iphoff+ih->ihl*4, | ||
298 | sizeof(_ahdr), &_ahdr); | ||
299 | if (ah == NULL) { | ||
300 | sb_add(m, "INCOMPLETE [%u bytes] ", | ||
301 | skb->len - iphoff - ih->ihl*4); | ||
302 | break; | ||
303 | } | ||
304 | |||
305 | /* Length: 15 "SPI=0xF1234567 " */ | ||
306 | sb_add(m, "SPI=0x%x ", ntohl(ah->spi)); | ||
307 | break; | ||
308 | } | ||
309 | case IPPROTO_ESP: { | ||
310 | struct ip_esp_hdr _esph; | ||
311 | const struct ip_esp_hdr *eh; | ||
312 | |||
313 | /* Max length: 10 "PROTO=ESP " */ | ||
314 | sb_add(m, "PROTO=ESP "); | ||
315 | |||
316 | if (ntohs(ih->frag_off) & IP_OFFSET) | ||
317 | break; | ||
318 | |||
319 | /* Max length: 25 "INCOMPLETE [65535 bytes] " */ | ||
320 | eh = skb_header_pointer(skb, iphoff+ih->ihl*4, | ||
321 | sizeof(_esph), &_esph); | ||
322 | if (eh == NULL) { | ||
323 | sb_add(m, "INCOMPLETE [%u bytes] ", | ||
324 | skb->len - iphoff - ih->ihl*4); | ||
325 | break; | ||
326 | } | ||
327 | |||
328 | /* Length: 15 "SPI=0xF1234567 " */ | ||
329 | sb_add(m, "SPI=0x%x ", ntohl(eh->spi)); | ||
330 | break; | ||
331 | } | ||
332 | /* Max length: 10 "PROTO 255 " */ | ||
333 | default: | ||
334 | sb_add(m, "PROTO=%u ", ih->protocol); | ||
335 | } | ||
336 | |||
337 | /* Max length: 15 "UID=4294967295 " */ | ||
338 | if ((logflags & IPT_LOG_UID) && !iphoff && skb->sk) { | ||
339 | read_lock_bh(&skb->sk->sk_callback_lock); | ||
340 | if (skb->sk->sk_socket && skb->sk->sk_socket->file) | ||
341 | sb_add(m, "UID=%u GID=%u ", | ||
342 | skb->sk->sk_socket->file->f_cred->fsuid, | ||
343 | skb->sk->sk_socket->file->f_cred->fsgid); | ||
344 | read_unlock_bh(&skb->sk->sk_callback_lock); | ||
345 | } | ||
346 | |||
347 | /* Max length: 16 "MARK=0xFFFFFFFF " */ | ||
348 | if (!iphoff && skb->mark) | ||
349 | sb_add(m, "MARK=0x%x ", skb->mark); | ||
350 | |||
351 | /* Proto Max log string length */ | ||
352 | /* IP: 40+46+6+11+127 = 230 */ | ||
353 | /* TCP: 10+max(25,20+30+13+9+32+11+127) = 252 */ | ||
354 | /* UDP: 10+max(25,20) = 35 */ | ||
355 | /* UDPLITE: 14+max(25,20) = 39 */ | ||
356 | /* ICMP: 11+max(25, 18+25+max(19,14,24+3+n+10,3+n+10)) = 91+n */ | ||
357 | /* ESP: 10+max(25)+15 = 50 */ | ||
358 | /* AH: 9+max(25)+15 = 49 */ | ||
359 | /* unknown: 10 */ | ||
360 | |||
361 | /* (ICMP allows recursion one level deep) */ | ||
362 | /* maxlen = IP + ICMP + IP + max(TCP,UDP,ICMP,unknown) */ | ||
363 | /* maxlen = 230+ 91 + 230 + 252 = 803 */ | ||
364 | } | ||
365 | |||
366 | static void dump_mac_header(struct sbuff *m, | ||
367 | const struct nf_loginfo *info, | ||
368 | const struct sk_buff *skb) | ||
369 | { | ||
370 | struct net_device *dev = skb->dev; | ||
371 | unsigned int logflags = 0; | ||
372 | |||
373 | if (info->type == NF_LOG_TYPE_LOG) | ||
374 | logflags = info->u.log.logflags; | ||
375 | |||
376 | if (!(logflags & IPT_LOG_MACDECODE)) | ||
377 | goto fallback; | ||
378 | |||
379 | switch (dev->type) { | ||
380 | case ARPHRD_ETHER: | ||
381 | sb_add(m, "MACSRC=%pM MACDST=%pM MACPROTO=%04x ", | ||
382 | eth_hdr(skb)->h_source, eth_hdr(skb)->h_dest, | ||
383 | ntohs(eth_hdr(skb)->h_proto)); | ||
384 | return; | ||
385 | default: | ||
386 | break; | ||
387 | } | ||
388 | |||
389 | fallback: | ||
390 | sb_add(m, "MAC="); | ||
391 | if (dev->hard_header_len && | ||
392 | skb->mac_header != skb->network_header) { | ||
393 | const unsigned char *p = skb_mac_header(skb); | ||
394 | unsigned int i; | ||
395 | |||
396 | sb_add(m, "%02x", *p++); | ||
397 | for (i = 1; i < dev->hard_header_len; i++, p++) | ||
398 | sb_add(m, ":%02x", *p); | ||
399 | } | ||
400 | sb_add(m, " "); | ||
401 | } | ||
402 | |||
403 | static struct nf_loginfo default_loginfo = { | ||
404 | .type = NF_LOG_TYPE_LOG, | ||
405 | .u = { | ||
406 | .log = { | ||
407 | .level = 5, | ||
408 | .logflags = NF_LOG_MASK, | ||
409 | }, | ||
410 | }, | ||
411 | }; | ||
412 | |||
413 | static void | ||
414 | ipt_log_packet(u_int8_t pf, | ||
415 | unsigned int hooknum, | ||
416 | const struct sk_buff *skb, | ||
417 | const struct net_device *in, | ||
418 | const struct net_device *out, | ||
419 | const struct nf_loginfo *loginfo, | ||
420 | const char *prefix) | ||
421 | { | ||
422 | struct sbuff *m = sb_open(); | ||
423 | |||
424 | if (!loginfo) | ||
425 | loginfo = &default_loginfo; | ||
426 | |||
427 | sb_add(m, "<%d>%sIN=%s OUT=%s ", loginfo->u.log.level, | ||
428 | prefix, | ||
429 | in ? in->name : "", | ||
430 | out ? out->name : ""); | ||
431 | #ifdef CONFIG_BRIDGE_NETFILTER | ||
432 | if (skb->nf_bridge) { | ||
433 | const struct net_device *physindev; | ||
434 | const struct net_device *physoutdev; | ||
435 | |||
436 | physindev = skb->nf_bridge->physindev; | ||
437 | if (physindev && in != physindev) | ||
438 | sb_add(m, "PHYSIN=%s ", physindev->name); | ||
439 | physoutdev = skb->nf_bridge->physoutdev; | ||
440 | if (physoutdev && out != physoutdev) | ||
441 | sb_add(m, "PHYSOUT=%s ", physoutdev->name); | ||
442 | } | ||
443 | #endif | ||
444 | |||
445 | if (in != NULL) | ||
446 | dump_mac_header(m, loginfo, skb); | ||
447 | |||
448 | dump_packet(m, loginfo, skb, 0); | ||
449 | |||
450 | sb_close(m); | ||
451 | } | ||
452 | |||
453 | static unsigned int | ||
454 | log_tg(struct sk_buff *skb, const struct xt_action_param *par) | ||
455 | { | ||
456 | const struct ipt_log_info *loginfo = par->targinfo; | ||
457 | struct nf_loginfo li; | ||
458 | |||
459 | li.type = NF_LOG_TYPE_LOG; | ||
460 | li.u.log.level = loginfo->level; | ||
461 | li.u.log.logflags = loginfo->logflags; | ||
462 | |||
463 | ipt_log_packet(NFPROTO_IPV4, par->hooknum, skb, par->in, par->out, &li, | ||
464 | loginfo->prefix); | ||
465 | return XT_CONTINUE; | ||
466 | } | ||
467 | |||
468 | static int log_tg_check(const struct xt_tgchk_param *par) | ||
469 | { | ||
470 | const struct ipt_log_info *loginfo = par->targinfo; | ||
471 | |||
472 | if (loginfo->level >= 8) { | ||
473 | pr_debug("level %u >= 8\n", loginfo->level); | ||
474 | return -EINVAL; | ||
475 | } | ||
476 | if (loginfo->prefix[sizeof(loginfo->prefix)-1] != '\0') { | ||
477 | pr_debug("prefix is not null-terminated\n"); | ||
478 | return -EINVAL; | ||
479 | } | ||
480 | return 0; | ||
481 | } | ||
482 | |||
483 | static struct xt_target log_tg_reg __read_mostly = { | ||
484 | .name = "LOG", | ||
485 | .family = NFPROTO_IPV4, | ||
486 | .target = log_tg, | ||
487 | .targetsize = sizeof(struct ipt_log_info), | ||
488 | .checkentry = log_tg_check, | ||
489 | .me = THIS_MODULE, | ||
490 | }; | ||
491 | |||
492 | static struct nf_logger ipt_log_logger __read_mostly = { | ||
493 | .name = "ipt_LOG", | ||
494 | .logfn = &ipt_log_packet, | ||
495 | .me = THIS_MODULE, | ||
496 | }; | ||
497 | |||
498 | static int __init log_tg_init(void) | ||
499 | { | ||
500 | int ret; | ||
501 | |||
502 | ret = xt_register_target(&log_tg_reg); | ||
503 | if (ret < 0) | ||
504 | return ret; | ||
505 | nf_log_register(NFPROTO_IPV4, &ipt_log_logger); | ||
506 | return 0; | ||
507 | } | ||
508 | |||
509 | static void __exit log_tg_exit(void) | ||
510 | { | ||
511 | nf_log_unregister(&ipt_log_logger); | ||
512 | xt_unregister_target(&log_tg_reg); | ||
513 | } | ||
514 | |||
515 | module_init(log_tg_init); | ||
516 | module_exit(log_tg_exit); | ||