2 * This is a module which is used for logging packets.
4 #include <linux/module.h>
5 #include <linux/skbuff.h>
7 #include <linux/spinlock.h>
11 #include <linux/netfilter_ipv4/ip_tables.h>
14 #include <net/route.h>
15 #include <linux/netfilter_ipv4/ipt_LOG.h>
20 #define DEBUGP(format, args...)
25 }; /* FIXME evil kludge */
27 /* Use lock to serialize, so printks don't overlap */
28 static spinlock_t log_lock = SPIN_LOCK_UNLOCKED;
30 /* One level of recursion won't kill us */
31 static void dump_packet(const struct ipt_log_info *info,
32 const struct sk_buff *skb,
37 if (skb_copy_bits(skb, iphoff, &iph, sizeof(iph)) < 0) {
43 * TOS, len, DF/MF, fragment offset, TTL, src, dst, options. */
44 /* Max length: 40 "SRC=255.255.255.255 DST=255.255.255.255 " */
45 printk("SRC=%u.%u.%u.%u DST=%u.%u.%u.%u ",
46 NIPQUAD(iph.saddr), NIPQUAD(iph.daddr));
48 /* Max length: 46 "LEN=65535 TOS=0xFF PREC=0xFF TTL=255 ID=65535 " */
49 printk("LEN=%u TOS=0x%02X PREC=0x%02X TTL=%u ID=%u ",
50 ntohs(iph.tot_len), iph.tos & IPTOS_TOS_MASK,
51 iph.tos & IPTOS_PREC_MASK, iph.ttl, ntohs(iph.id));
53 /* Max length: 6 "CE DF MF " */
54 if (ntohs(iph.frag_off) & IP_CE)
56 if (ntohs(iph.frag_off) & IP_DF)
58 if (ntohs(iph.frag_off) & IP_MF)
61 /* Max length: 11 "FRAG:65535 " */
62 if (ntohs(iph.frag_off) & IP_OFFSET)
63 printk("FRAG:%u ", ntohs(iph.frag_off) & IP_OFFSET);
65 if ((info->logflags & IPT_LOG_IPOPT)
66 && iph.ihl * 4 != sizeof(struct iphdr)) {
67 unsigned char opt[4 * 15 - sizeof(struct iphdr)];
68 unsigned int i, optsize;
70 optsize = iph.ihl * 4 - sizeof(struct iphdr);
71 if (skb_copy_bits(skb, iphoff+sizeof(iph), opt, optsize) < 0) {
76 /* Max length: 127 "OPT (" 15*4*2chars ") " */
78 for (i = 0; i < optsize; i++)
79 printk("%02X", opt[i]);
83 switch (iph.protocol) {
87 /* Max length: 10 "PROTO=TCP " */
90 if (ntohs(iph.frag_off) & IP_OFFSET)
93 /* Max length: 25 "INCOMPLETE [65535 bytes] " */
94 if (skb_copy_bits(skb, iphoff+iph.ihl*4, &tcph, sizeof(tcph))
96 printk("INCOMPLETE [%u bytes] ",
97 skb->len - iphoff - iph.ihl*4);
101 /* Max length: 20 "SPT=65535 DPT=65535 " */
102 printk("SPT=%u DPT=%u ",
103 ntohs(tcph.source), ntohs(tcph.dest));
104 /* Max length: 30 "SEQ=4294967295 ACK=4294967295 " */
105 if (info->logflags & IPT_LOG_TCPSEQ)
106 printk("SEQ=%u ACK=%u ",
107 ntohl(tcph.seq), ntohl(tcph.ack_seq));
108 /* Max length: 13 "WINDOW=65535 " */
109 printk("WINDOW=%u ", ntohs(tcph.window));
110 /* Max length: 9 "RES=0x3F " */
111 printk("RES=0x%02x ", (u8)(ntohl(tcp_flag_word(&tcph) & TCP_RESERVED_BITS) >> 22));
112 /* Max length: 32 "CWR ECE URG ACK PSH RST SYN FIN " */
129 /* Max length: 11 "URGP=65535 " */
130 printk("URGP=%u ", ntohs(tcph.urg_ptr));
132 if ((info->logflags & IPT_LOG_TCPOPT)
133 && tcph.doff * 4 != sizeof(struct tcphdr)) {
134 unsigned char opt[4 * 15 - sizeof(struct tcphdr)];
135 unsigned int i, optsize;
137 optsize = tcph.doff * 4 - sizeof(struct tcphdr);
138 if (skb_copy_bits(skb, iphoff+iph.ihl*4 + sizeof(tcph),
144 /* Max length: 127 "OPT (" 15*4*2chars ") " */
146 for (i = 0; i < optsize; i++)
147 printk("%02X", opt[i]);
155 /* Max length: 10 "PROTO=UDP " */
156 printk("PROTO=UDP ");
158 if (ntohs(iph.frag_off) & IP_OFFSET)
161 /* Max length: 25 "INCOMPLETE [65535 bytes] " */
162 if (skb_copy_bits(skb, iphoff+iph.ihl*4, &udph, sizeof(udph))
164 printk("INCOMPLETE [%u bytes] ",
165 skb->len - iphoff - iph.ihl*4);
169 /* Max length: 20 "SPT=65535 DPT=65535 " */
170 printk("SPT=%u DPT=%u LEN=%u ",
171 ntohs(udph.source), ntohs(udph.dest),
176 struct icmphdr icmph;
177 static size_t required_len[NR_ICMP_TYPES+1]
178 = { [ICMP_ECHOREPLY] = 4,
180 = 8 + sizeof(struct iphdr) + 8,
182 = 8 + sizeof(struct iphdr) + 8,
184 = 8 + sizeof(struct iphdr) + 8,
187 = 8 + sizeof(struct iphdr) + 8,
189 = 8 + sizeof(struct iphdr) + 8,
190 [ICMP_TIMESTAMP] = 20,
191 [ICMP_TIMESTAMPREPLY] = 20,
193 [ICMP_ADDRESSREPLY] = 12 };
195 /* Max length: 11 "PROTO=ICMP " */
196 printk("PROTO=ICMP ");
198 if (ntohs(iph.frag_off) & IP_OFFSET)
201 /* Max length: 25 "INCOMPLETE [65535 bytes] " */
202 if (skb_copy_bits(skb, iphoff+iph.ihl*4, &icmph, sizeof(icmph))
204 printk("INCOMPLETE [%u bytes] ",
205 skb->len - iphoff - iph.ihl*4);
209 /* Max length: 18 "TYPE=255 CODE=255 " */
210 printk("TYPE=%u CODE=%u ", icmph.type, icmph.code);
212 /* Max length: 25 "INCOMPLETE [65535 bytes] " */
213 if (icmph.type <= NR_ICMP_TYPES
214 && required_len[icmph.type]
215 && skb->len-iphoff-iph.ihl*4 < required_len[icmph.type]) {
216 printk("INCOMPLETE [%u bytes] ",
217 skb->len - iphoff - iph.ihl*4);
221 switch (icmph.type) {
224 /* Max length: 19 "ID=65535 SEQ=65535 " */
225 printk("ID=%u SEQ=%u ",
226 ntohs(icmph.un.echo.id),
227 ntohs(icmph.un.echo.sequence));
230 case ICMP_PARAMETERPROB:
231 /* Max length: 14 "PARAMETER=255 " */
232 printk("PARAMETER=%u ",
233 ntohl(icmph.un.gateway) >> 24);
236 /* Max length: 24 "GATEWAY=255.255.255.255 " */
237 printk("GATEWAY=%u.%u.%u.%u ",
238 NIPQUAD(icmph.un.gateway));
240 case ICMP_DEST_UNREACH:
241 case ICMP_SOURCE_QUENCH:
242 case ICMP_TIME_EXCEEDED:
243 /* Max length: 3+maxlen */
244 if (!iphoff) { /* Only recurse once. */
246 dump_packet(info, skb,
247 iphoff + iph.ihl*4+sizeof(icmph));
251 /* Max length: 10 "MTU=65535 " */
252 if (icmph.type == ICMP_DEST_UNREACH
253 && icmph.code == ICMP_FRAG_NEEDED)
254 printk("MTU=%u ", ntohs(icmph.un.frag.mtu));
262 int esp = (iph.protocol==IPPROTO_ESP);
264 /* Max length: 10 "PROTO=ESP " */
265 printk("PROTO=%s ",esp? "ESP" : "AH");
267 if (ntohs(iph.frag_off) & IP_OFFSET)
270 /* Max length: 25 "INCOMPLETE [65535 bytes] " */
271 if (skb_copy_bits(skb, iphoff+iph.ihl*4, &esph, sizeof(esph))
273 printk("INCOMPLETE [%u bytes] ",
274 skb->len - iphoff - iph.ihl*4);
278 /* Length: 15 "SPI=0xF1234567 " */
279 printk("SPI=0x%x ", ntohl(esph.spi));
282 /* Max length: 10 "PROTO 255 " */
284 printk("PROTO=%u ", iph.protocol);
287 /* Proto Max log string length */
288 /* IP: 40+46+6+11+127 = 230 */
289 /* TCP: 10+max(25,20+30+13+9+32+11+127) = 252 */
290 /* UDP: 10+max(25,20) = 35 */
291 /* ICMP: 11+max(25, 18+25+max(19,14,24+3+n+10,3+n+10)) = 91+n */
292 /* ESP: 10+max(25)+15 = 50 */
293 /* AH: 9+max(25)+15 = 49 */
296 /* (ICMP allows recursion one level deep) */
297 /* maxlen = IP + ICMP + IP + max(TCP,UDP,ICMP,unknown) */
298 /* maxlen = 230+ 91 + 230 + 252 = 803 */
302 ipt_log_target(struct sk_buff **pskb,
303 const struct net_device *in,
304 const struct net_device *out,
305 unsigned int hooknum,
306 const void *targinfo,
309 const struct ipt_log_info *loginfo = targinfo;
310 char level_string[4] = "< >";
312 level_string[1] = '0' + (loginfo->level % 8);
313 spin_lock_bh(&log_lock);
314 printk(level_string);
315 printk("%sIN=%s OUT=%s ",
318 out ? out->name : "");
319 #if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
320 if ((*pskb)->nf_bridge) {
321 struct net_device *physindev = (*pskb)->nf_bridge->physindev;
322 struct net_device *physoutdev = (*pskb)->nf_bridge->physoutdev;
324 if (physindev && in != physindev)
325 printk("PHYSIN=%s ", physindev->name);
326 if (physoutdev && out != physoutdev)
327 printk("PHYSOUT=%s ", physoutdev->name);
332 /* MAC logging for input chain only. */
334 if ((*pskb)->dev && (*pskb)->dev->hard_header_len
335 && (*pskb)->mac.raw != (void*)(*pskb)->nh.iph) {
337 unsigned char *p = (*pskb)->mac.raw;
338 for (i = 0; i < (*pskb)->dev->hard_header_len; i++,p++)
340 i==(*pskb)->dev->hard_header_len - 1
346 dump_packet(loginfo, *pskb, 0);
348 spin_unlock_bh(&log_lock);
353 static int ipt_log_checkentry(const char *tablename,
354 const struct ipt_entry *e,
356 unsigned int targinfosize,
357 unsigned int hook_mask)
359 const struct ipt_log_info *loginfo = targinfo;
361 if (targinfosize != IPT_ALIGN(sizeof(struct ipt_log_info))) {
362 DEBUGP("LOG: targinfosize %u != %u\n",
363 targinfosize, IPT_ALIGN(sizeof(struct ipt_log_info)));
367 if (loginfo->level >= 8) {
368 DEBUGP("LOG: level %u >= 8\n", loginfo->level);
372 if (loginfo->prefix[sizeof(loginfo->prefix)-1] != '\0') {
373 DEBUGP("LOG: prefix term %i\n",
374 loginfo->prefix[sizeof(loginfo->prefix)-1]);
381 static struct ipt_target ipt_log_reg = {
383 .target = ipt_log_target,
384 .checkentry = ipt_log_checkentry,
388 static int __init init(void)
390 if (ipt_register_target(&ipt_log_reg))
396 static void __exit fini(void)
398 ipt_unregister_target(&ipt_log_reg);
403 MODULE_LICENSE("GPL");