aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/netfilter
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2010-06-28 08:16:08 -0400
committerPatrick McHardy <kaber@trash.net>2010-06-28 08:16:08 -0400
commit7eb9282cd0efac08b8377cbd5037ba297c77e3f7 (patch)
tree7dcb6e149c96e27da69a75ff828de9681c6636f8 /net/ipv6/netfilter
parentcf377eb4aeded926375d4d0fe0b66ba95f0521e1 (diff)
netfilter: ipt_LOG/ip6t_LOG: add option to print decoded MAC header
The LOG targets print the entire MAC header as one long string, which is not readable very well: IN=eth0 OUT= MAC=00:15:f2:24:91:f8:00:1b:24:dc:61:e6:08:00 ... Add an option to decode known header formats (currently just ARPHRD_ETHER devices) in their individual fields: IN=eth0 OUT= MACSRC=00:1b:24:dc:61:e6 MACDST=00:15:f2:24:91:f8 MACPROTO=0800 ... IN=eth0 OUT= MACSRC=00:1b:24:dc:61:e6 MACDST=00:15:f2:24:91:f8 MACPROTO=86dd ... The option needs to be explicitly enabled by userspace to avoid breaking existing parsers. Signed-off-by: Patrick McHardy <kaber@trash.net>
Diffstat (limited to 'net/ipv6/netfilter')
-rw-r--r--net/ipv6/netfilter/ip6t_LOG.c81
1 files changed, 53 insertions, 28 deletions
diff --git a/net/ipv6/netfilter/ip6t_LOG.c b/net/ipv6/netfilter/ip6t_LOG.c
index 4c7ddac7c62..0a07ae7b933 100644
--- a/net/ipv6/netfilter/ip6t_LOG.c
+++ b/net/ipv6/netfilter/ip6t_LOG.c
@@ -373,6 +373,56 @@ static void dump_packet(const struct nf_loginfo *info,
373 printk("MARK=0x%x ", skb->mark); 373 printk("MARK=0x%x ", skb->mark);
374} 374}
375 375
376static void dump_mac_header(const struct nf_loginfo *info,
377 const struct sk_buff *skb)
378{
379 struct net_device *dev = skb->dev;
380 unsigned int logflags = 0;
381
382 if (info->type == NF_LOG_TYPE_LOG)
383 logflags = info->u.log.logflags;
384
385 if (!(logflags & IP6T_LOG_MACDECODE))
386 goto fallback;
387
388 switch (dev->type) {
389 case ARPHRD_ETHER:
390 printk("MACSRC=%pM MACDST=%pM MACPROTO=%04x ",
391 eth_hdr(skb)->h_source, eth_hdr(skb)->h_dest,
392 ntohs(eth_hdr(skb)->h_proto));
393 return;
394 default:
395 break;
396 }
397
398fallback:
399 printk("MAC=");
400 if (dev->hard_header_len &&
401 skb->mac_header != skb->network_header) {
402 const unsigned char *p = skb_mac_header(skb);
403 unsigned int len = dev->hard_header_len;
404 unsigned int i;
405
406 if (dev->type == ARPHRD_SIT &&
407 (p -= ETH_HLEN) < skb->head)
408 p = NULL;
409
410 if (p != NULL) {
411 printk("%02x", *p++);
412 for (i = 1; i < len; i++)
413 printk(":%02x", p[i]);
414 }
415 printk(" ");
416
417 if (dev->type == ARPHRD_SIT) {
418 const struct iphdr *iph =
419 (struct iphdr *)skb_mac_header(skb);
420 printk("TUNNEL=%pI4->%pI4 ", &iph->saddr, &iph->daddr);
421 }
422 } else
423 printk(" ");
424}
425
376static struct nf_loginfo default_loginfo = { 426static struct nf_loginfo default_loginfo = {
377 .type = NF_LOG_TYPE_LOG, 427 .type = NF_LOG_TYPE_LOG,
378 .u = { 428 .u = {
@@ -400,35 +450,10 @@ ip6t_log_packet(u_int8_t pf,
400 prefix, 450 prefix,
401 in ? in->name : "", 451 in ? in->name : "",
402 out ? out->name : ""); 452 out ? out->name : "");
403 if (in && !out) {
404 unsigned int len;
405 /* MAC logging for input chain only. */
406 printk("MAC=");
407 if (skb->dev && (len = skb->dev->hard_header_len) &&
408 skb->mac_header != skb->network_header) {
409 const unsigned char *p = skb_mac_header(skb);
410 int i;
411
412 if (skb->dev->type == ARPHRD_SIT &&
413 (p -= ETH_HLEN) < skb->head)
414 p = NULL;
415
416 if (p != NULL) {
417 printk("%02x", *p++);
418 for (i = 1; i < len; i++)
419 printk(":%02x", p[i]);
420 }
421 printk(" ");
422 453
423 if (skb->dev->type == ARPHRD_SIT) { 454 /* MAC logging for input path only. */
424 const struct iphdr *iph = 455 if (in && !out)
425 (struct iphdr *)skb_mac_header(skb); 456 dump_mac_header(loginfo, skb);
426 printk("TUNNEL=%pI4->%pI4 ",
427 &iph->saddr, &iph->daddr);
428 }
429 } else
430 printk(" ");
431 }
432 457
433 dump_packet(loginfo, skb, skb_network_offset(skb), 1); 458 dump_packet(loginfo, skb, skb_network_offset(skb), 1);
434 printk("\n"); 459 printk("\n");