ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / net / ipv4 / netfilter / ipt_LOG.c
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
13 #include <linux/module.h>
14 #include <linux/spinlock.h>
15 #include <linux/skbuff.h>
16 #include <linux/ip.h>
17 #include <net/icmp.h>
18 #include <net/udp.h>
19 #include <net/tcp.h>
20 #include <net/route.h>
21
22 #include <linux/netfilter.h>
23 #include <linux/netfilter_ipv4/ip_tables.h>
24 #include <linux/netfilter_ipv4/ipt_LOG.h>
25
26 MODULE_LICENSE("GPL");
27 MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
28 MODULE_DESCRIPTION("iptables syslog logging module");
29
30 static unsigned int nflog = 1;
31 MODULE_PARM(nflog, "i");
32 MODULE_PARM_DESC(nflog, "register as internal netfilter logging module");
33  
34 #if 0
35 #define DEBUGP printk
36 #else
37 #define DEBUGP(format, args...)
38 #endif
39
40 /* Use lock to serialize, so printks don't overlap */
41 static spinlock_t log_lock = SPIN_LOCK_UNLOCKED;
42
43 /* One level of recursion won't kill us */
44 static void dump_packet(const struct ipt_log_info *info,
45                         const struct sk_buff *skb,
46                         unsigned int iphoff)
47 {
48         struct iphdr iph;
49
50         if (skb_copy_bits(skb, iphoff, &iph, sizeof(iph)) < 0) {
51                 printk("TRUNCATED");
52                 return;
53         }
54
55         /* Important fields:
56          * TOS, len, DF/MF, fragment offset, TTL, src, dst, options. */
57         /* Max length: 40 "SRC=255.255.255.255 DST=255.255.255.255 " */
58         printk("SRC=%u.%u.%u.%u DST=%u.%u.%u.%u ",
59                NIPQUAD(iph.saddr), NIPQUAD(iph.daddr));
60
61         /* Max length: 46 "LEN=65535 TOS=0xFF PREC=0xFF TTL=255 ID=65535 " */
62         printk("LEN=%u TOS=0x%02X PREC=0x%02X TTL=%u ID=%u ",
63                ntohs(iph.tot_len), iph.tos & IPTOS_TOS_MASK,
64                iph.tos & IPTOS_PREC_MASK, iph.ttl, ntohs(iph.id));
65
66         /* Max length: 6 "CE DF MF " */
67         if (ntohs(iph.frag_off) & IP_CE)
68                 printk("CE ");
69         if (ntohs(iph.frag_off) & IP_DF)
70                 printk("DF ");
71         if (ntohs(iph.frag_off) & IP_MF)
72                 printk("MF ");
73
74         /* Max length: 11 "FRAG:65535 " */
75         if (ntohs(iph.frag_off) & IP_OFFSET)
76                 printk("FRAG:%u ", ntohs(iph.frag_off) & IP_OFFSET);
77
78         if ((info->logflags & IPT_LOG_IPOPT)
79             && iph.ihl * 4 != sizeof(struct iphdr)) {
80                 unsigned char opt[4 * 15 - sizeof(struct iphdr)];
81                 unsigned int i, optsize;
82
83                 optsize = iph.ihl * 4 - sizeof(struct iphdr);
84                 if (skb_copy_bits(skb, iphoff+sizeof(iph), opt, optsize) < 0) {
85                         printk("TRUNCATED");
86                         return;
87                 }
88
89                 /* Max length: 127 "OPT (" 15*4*2chars ") " */
90                 printk("OPT (");
91                 for (i = 0; i < optsize; i++)
92                         printk("%02X", opt[i]);
93                 printk(") ");
94         }
95
96         switch (iph.protocol) {
97         case IPPROTO_TCP: {
98                 struct tcphdr tcph;
99
100                 /* Max length: 10 "PROTO=TCP " */
101                 printk("PROTO=TCP ");
102
103                 if (ntohs(iph.frag_off) & IP_OFFSET)
104                         break;
105
106                 /* Max length: 25 "INCOMPLETE [65535 bytes] " */
107                 if (skb_copy_bits(skb, iphoff+iph.ihl*4, &tcph, sizeof(tcph))
108                     < 0) {
109                         printk("INCOMPLETE [%u bytes] ",
110                                skb->len - iphoff - iph.ihl*4);
111                         break;
112                 }
113
114                 /* Max length: 20 "SPT=65535 DPT=65535 " */
115                 printk("SPT=%u DPT=%u ",
116                        ntohs(tcph.source), ntohs(tcph.dest));
117                 /* Max length: 30 "SEQ=4294967295 ACK=4294967295 " */
118                 if (info->logflags & IPT_LOG_TCPSEQ)
119                         printk("SEQ=%u ACK=%u ",
120                                ntohl(tcph.seq), ntohl(tcph.ack_seq));
121                 /* Max length: 13 "WINDOW=65535 " */
122                 printk("WINDOW=%u ", ntohs(tcph.window));
123                 /* Max length: 9 "RES=0x3F " */
124                 printk("RES=0x%02x ", (u8)(ntohl(tcp_flag_word(&tcph) & TCP_RESERVED_BITS) >> 22));
125                 /* Max length: 32 "CWR ECE URG ACK PSH RST SYN FIN " */
126                 if (tcph.cwr)
127                         printk("CWR ");
128                 if (tcph.ece)
129                         printk("ECE ");
130                 if (tcph.urg)
131                         printk("URG ");
132                 if (tcph.ack)
133                         printk("ACK ");
134                 if (tcph.psh)
135                         printk("PSH ");
136                 if (tcph.rst)
137                         printk("RST ");
138                 if (tcph.syn)
139                         printk("SYN ");
140                 if (tcph.fin)
141                         printk("FIN ");
142                 /* Max length: 11 "URGP=65535 " */
143                 printk("URGP=%u ", ntohs(tcph.urg_ptr));
144
145                 if ((info->logflags & IPT_LOG_TCPOPT)
146                     && tcph.doff * 4 != sizeof(struct tcphdr)) {
147                         unsigned char opt[4 * 15 - sizeof(struct tcphdr)];
148                         unsigned int i, optsize;
149
150                         optsize = tcph.doff * 4 - sizeof(struct tcphdr);
151                         if (skb_copy_bits(skb, iphoff+iph.ihl*4 + sizeof(tcph),
152                                           opt, optsize) < 0) {
153                                 printk("TRUNCATED");
154                                 return;
155                         }
156
157                         /* Max length: 127 "OPT (" 15*4*2chars ") " */
158                         printk("OPT (");
159                         for (i = 0; i < optsize; i++)
160                                 printk("%02X", opt[i]);
161                         printk(") ");
162                 }
163                 break;
164         }
165         case IPPROTO_UDP: {
166                 struct udphdr udph;
167
168                 /* Max length: 10 "PROTO=UDP " */
169                 printk("PROTO=UDP ");
170
171                 if (ntohs(iph.frag_off) & IP_OFFSET)
172                         break;
173
174                 /* Max length: 25 "INCOMPLETE [65535 bytes] " */
175                 if (skb_copy_bits(skb, iphoff+iph.ihl*4, &udph, sizeof(udph))
176                     < 0) {
177                         printk("INCOMPLETE [%u bytes] ",
178                                skb->len - iphoff - iph.ihl*4);
179                         break;
180                 }
181
182                 /* Max length: 20 "SPT=65535 DPT=65535 " */
183                 printk("SPT=%u DPT=%u LEN=%u ",
184                        ntohs(udph.source), ntohs(udph.dest),
185                        ntohs(udph.len));
186                 break;
187         }
188         case IPPROTO_ICMP: {
189                 struct icmphdr icmph;
190                 static size_t required_len[NR_ICMP_TYPES+1]
191                         = { [ICMP_ECHOREPLY] = 4,
192                             [ICMP_DEST_UNREACH]
193                             = 8 + sizeof(struct iphdr) + 8,
194                             [ICMP_SOURCE_QUENCH]
195                             = 8 + sizeof(struct iphdr) + 8,
196                             [ICMP_REDIRECT]
197                             = 8 + sizeof(struct iphdr) + 8,
198                             [ICMP_ECHO] = 4,
199                             [ICMP_TIME_EXCEEDED]
200                             = 8 + sizeof(struct iphdr) + 8,
201                             [ICMP_PARAMETERPROB]
202                             = 8 + sizeof(struct iphdr) + 8,
203                             [ICMP_TIMESTAMP] = 20,
204                             [ICMP_TIMESTAMPREPLY] = 20,
205                             [ICMP_ADDRESS] = 12,
206                             [ICMP_ADDRESSREPLY] = 12 };
207
208                 /* Max length: 11 "PROTO=ICMP " */
209                 printk("PROTO=ICMP ");
210
211                 if (ntohs(iph.frag_off) & IP_OFFSET)
212                         break;
213
214                 /* Max length: 25 "INCOMPLETE [65535 bytes] " */
215                 if (skb_copy_bits(skb, iphoff+iph.ihl*4, &icmph, sizeof(icmph))
216                     < 0) {
217                         printk("INCOMPLETE [%u bytes] ",
218                                skb->len - iphoff - iph.ihl*4);
219                         break;
220                 }
221
222                 /* Max length: 18 "TYPE=255 CODE=255 " */
223                 printk("TYPE=%u CODE=%u ", icmph.type, icmph.code);
224
225                 /* Max length: 25 "INCOMPLETE [65535 bytes] " */
226                 if (icmph.type <= NR_ICMP_TYPES
227                     && required_len[icmph.type]
228                     && skb->len-iphoff-iph.ihl*4 < required_len[icmph.type]) {
229                         printk("INCOMPLETE [%u bytes] ",
230                                skb->len - iphoff - iph.ihl*4);
231                         break;
232                 }
233
234                 switch (icmph.type) {
235                 case ICMP_ECHOREPLY:
236                 case ICMP_ECHO:
237                         /* Max length: 19 "ID=65535 SEQ=65535 " */
238                         printk("ID=%u SEQ=%u ",
239                                ntohs(icmph.un.echo.id),
240                                ntohs(icmph.un.echo.sequence));
241                         break;
242
243                 case ICMP_PARAMETERPROB:
244                         /* Max length: 14 "PARAMETER=255 " */
245                         printk("PARAMETER=%u ",
246                                ntohl(icmph.un.gateway) >> 24);
247                         break;
248                 case ICMP_REDIRECT:
249                         /* Max length: 24 "GATEWAY=255.255.255.255 " */
250                         printk("GATEWAY=%u.%u.%u.%u ",
251                                NIPQUAD(icmph.un.gateway));
252                         /* Fall through */
253                 case ICMP_DEST_UNREACH:
254                 case ICMP_SOURCE_QUENCH:
255                 case ICMP_TIME_EXCEEDED:
256                         /* Max length: 3+maxlen */
257                         if (!iphoff) { /* Only recurse once. */
258                                 printk("[");
259                                 dump_packet(info, skb,
260                                             iphoff + iph.ihl*4+sizeof(icmph));
261                                 printk("] ");
262                         }
263
264                         /* Max length: 10 "MTU=65535 " */
265                         if (icmph.type == ICMP_DEST_UNREACH
266                             && icmph.code == ICMP_FRAG_NEEDED)
267                                 printk("MTU=%u ", ntohs(icmph.un.frag.mtu));
268                 }
269                 break;
270         }
271         /* Max Length */
272         case IPPROTO_AH: {
273                 struct ip_auth_hdr ah;
274
275                 if (ntohs(iph.frag_off) & IP_OFFSET)
276                         break;
277                 
278                 /* Max length: 9 "PROTO=AH " */
279                 printk("PROTO=AH ");
280
281                 /* Max length: 25 "INCOMPLETE [65535 bytes] " */
282                 if (skb_copy_bits(skb, iphoff+iph.ihl*4, &ah, sizeof(ah)) < 0) {
283                         printk("INCOMPLETE [%u bytes] ",
284                                skb->len - iphoff - iph.ihl*4);
285                         break;
286                 }
287
288                 /* Length: 15 "SPI=0xF1234567 " */
289                 printk("SPI=0x%x ", ntohl(ah.spi));
290                 break;
291         }
292         case IPPROTO_ESP: {
293                 struct ip_esp_hdr esph;
294
295                 /* Max length: 10 "PROTO=ESP " */
296                 printk("PROTO=ESP ");
297
298                 if (ntohs(iph.frag_off) & IP_OFFSET)
299                         break;
300
301                 /* Max length: 25 "INCOMPLETE [65535 bytes] " */
302                 if (skb_copy_bits(skb, iphoff+iph.ihl*4, &esph, sizeof(esph))
303                     < 0) {
304                         printk("INCOMPLETE [%u bytes] ",
305                                skb->len - iphoff - iph.ihl*4);
306                         break;
307                 }
308
309                 /* Length: 15 "SPI=0xF1234567 " */
310                 printk("SPI=0x%x ", ntohl(esph.spi));
311                 break;
312         }
313         /* Max length: 10 "PROTO 255 " */
314         default:
315                 printk("PROTO=%u ", iph.protocol);
316         }
317
318         /* Proto    Max log string length */
319         /* IP:      40+46+6+11+127 = 230 */
320         /* TCP:     10+max(25,20+30+13+9+32+11+127) = 252 */
321         /* UDP:     10+max(25,20) = 35 */
322         /* ICMP:    11+max(25, 18+25+max(19,14,24+3+n+10,3+n+10)) = 91+n */
323         /* ESP:     10+max(25)+15 = 50 */
324         /* AH:      9+max(25)+15 = 49 */
325         /* unknown: 10 */
326
327         /* (ICMP allows recursion one level deep) */
328         /* maxlen =  IP + ICMP +  IP + max(TCP,UDP,ICMP,unknown) */
329         /* maxlen = 230+   91  + 230 + 252 = 803 */
330 }
331
332 static void
333 ipt_log_packet(unsigned int hooknum,
334                const struct sk_buff *skb,
335                const struct net_device *in,
336                const struct net_device *out,
337                const struct ipt_log_info *loginfo,
338                const char *level_string,
339                const char *prefix)
340 {
341         spin_lock_bh(&log_lock);
342         printk(level_string);
343         printk("%sIN=%s OUT=%s ",
344                prefix == NULL ? loginfo->prefix : prefix,
345                in ? in->name : "",
346                out ? out->name : "");
347 #ifdef CONFIG_BRIDGE_NETFILTER
348         if (skb->nf_bridge) {
349                 struct net_device *physindev = skb->nf_bridge->physindev;
350                 struct net_device *physoutdev = skb->nf_bridge->physoutdev;
351
352                 if (physindev && in != physindev)
353                         printk("PHYSIN=%s ", physindev->name);
354                 if (physoutdev && out != physoutdev)
355                         printk("PHYSOUT=%s ", physoutdev->name);
356         }
357 #endif
358
359         if (in && !out) {
360                 /* MAC logging for input chain only. */
361                 printk("MAC=");
362                 if (skb->dev && skb->dev->hard_header_len
363                     && skb->mac.raw != (void*)skb->nh.iph) {
364                         int i;
365                         unsigned char *p = skb->mac.raw;
366                         for (i = 0; i < skb->dev->hard_header_len; i++,p++)
367                                 printk("%02x%c", *p,
368                                        i==skb->dev->hard_header_len - 1
369                                        ? ' ':':');
370                 } else
371                         printk(" ");
372         }
373
374         dump_packet(loginfo, skb, 0);
375         printk("\n");
376         spin_unlock_bh(&log_lock);
377 }
378
379 static unsigned int
380 ipt_log_target(struct sk_buff **pskb,
381                const struct net_device *in,
382                const struct net_device *out,
383                unsigned int hooknum,
384                const void *targinfo,
385                void *userinfo)
386 {
387         const struct ipt_log_info *loginfo = targinfo;
388         char level_string[4] = "< >";
389
390         level_string[1] = '0' + (loginfo->level % 8);
391         ipt_log_packet(hooknum, *pskb, in, out, loginfo, level_string, NULL);
392
393         return IPT_CONTINUE;
394 }
395
396 static void
397 ipt_logfn(unsigned int hooknum,
398           const struct sk_buff *skb,
399           const struct net_device *in,
400           const struct net_device *out,
401           const char *prefix)
402 {
403         struct ipt_log_info loginfo = { 
404                 .level = 0, 
405                 .logflags = IPT_LOG_MASK, 
406                 .prefix = "" 
407         };
408
409         ipt_log_packet(hooknum, skb, in, out, &loginfo, KERN_WARNING, prefix);
410 }
411
412 static int ipt_log_checkentry(const char *tablename,
413                               const struct ipt_entry *e,
414                               void *targinfo,
415                               unsigned int targinfosize,
416                               unsigned int hook_mask)
417 {
418         const struct ipt_log_info *loginfo = targinfo;
419
420         if (targinfosize != IPT_ALIGN(sizeof(struct ipt_log_info))) {
421                 DEBUGP("LOG: targinfosize %u != %u\n",
422                        targinfosize, IPT_ALIGN(sizeof(struct ipt_log_info)));
423                 return 0;
424         }
425
426         if (loginfo->level >= 8) {
427                 DEBUGP("LOG: level %u >= 8\n", loginfo->level);
428                 return 0;
429         }
430
431         if (loginfo->prefix[sizeof(loginfo->prefix)-1] != '\0') {
432                 DEBUGP("LOG: prefix term %i\n",
433                        loginfo->prefix[sizeof(loginfo->prefix)-1]);
434                 return 0;
435         }
436
437         return 1;
438 }
439
440 static struct ipt_target ipt_log_reg = {
441         .name           = "LOG",
442         .target         = ipt_log_target,
443         .checkentry     = ipt_log_checkentry,
444         .me             = THIS_MODULE,
445 };
446
447 static int __init init(void)
448 {
449         if (ipt_register_target(&ipt_log_reg))
450                 return -EINVAL;
451         if (nflog)
452                 nf_log_register(PF_INET, &ipt_logfn);
453         
454         return 0;
455 }
456
457 static void __exit fini(void)
458 {
459         if (nflog)
460                 nf_log_unregister(PF_INET, &ipt_logfn);
461         ipt_unregister_target(&ipt_log_reg);
462 }
463
464 module_init(init);
465 module_exit(fini);