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>
This commit is contained in:
parent
cf377eb4ae
commit
7eb9282cd0
|
@ -7,7 +7,8 @@
|
||||||
#define IPT_LOG_IPOPT 0x04 /* Log IP options */
|
#define IPT_LOG_IPOPT 0x04 /* Log IP options */
|
||||||
#define IPT_LOG_UID 0x08 /* Log UID owning local socket */
|
#define IPT_LOG_UID 0x08 /* Log UID owning local socket */
|
||||||
#define IPT_LOG_NFLOG 0x10 /* Unsupported, don't reuse */
|
#define IPT_LOG_NFLOG 0x10 /* Unsupported, don't reuse */
|
||||||
#define IPT_LOG_MASK 0x1f
|
#define IPT_LOG_MACDECODE 0x20 /* Decode MAC header */
|
||||||
|
#define IPT_LOG_MASK 0x2f
|
||||||
|
|
||||||
struct ipt_log_info {
|
struct ipt_log_info {
|
||||||
unsigned char level;
|
unsigned char level;
|
||||||
|
|
|
@ -7,7 +7,8 @@
|
||||||
#define IP6T_LOG_IPOPT 0x04 /* Log IP options */
|
#define IP6T_LOG_IPOPT 0x04 /* Log IP options */
|
||||||
#define IP6T_LOG_UID 0x08 /* Log UID owning local socket */
|
#define IP6T_LOG_UID 0x08 /* Log UID owning local socket */
|
||||||
#define IP6T_LOG_NFLOG 0x10 /* Unsupported, don't use */
|
#define IP6T_LOG_NFLOG 0x10 /* Unsupported, don't use */
|
||||||
#define IP6T_LOG_MASK 0x1f
|
#define IP6T_LOG_MACDECODE 0x20 /* Decode MAC header */
|
||||||
|
#define IP6T_LOG_MASK 0x2f
|
||||||
|
|
||||||
struct ip6t_log_info {
|
struct ip6t_log_info {
|
||||||
unsigned char level;
|
unsigned char level;
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/spinlock.h>
|
#include <linux/spinlock.h>
|
||||||
#include <linux/skbuff.h>
|
#include <linux/skbuff.h>
|
||||||
|
#include <linux/if_arp.h>
|
||||||
#include <linux/ip.h>
|
#include <linux/ip.h>
|
||||||
#include <net/icmp.h>
|
#include <net/icmp.h>
|
||||||
#include <net/udp.h>
|
#include <net/udp.h>
|
||||||
|
@ -363,6 +364,42 @@ static void dump_packet(const struct nf_loginfo *info,
|
||||||
/* maxlen = 230+ 91 + 230 + 252 = 803 */
|
/* maxlen = 230+ 91 + 230 + 252 = 803 */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void dump_mac_header(const struct nf_loginfo *info,
|
||||||
|
const struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
struct net_device *dev = skb->dev;
|
||||||
|
unsigned int logflags = 0;
|
||||||
|
|
||||||
|
if (info->type == NF_LOG_TYPE_LOG)
|
||||||
|
logflags = info->u.log.logflags;
|
||||||
|
|
||||||
|
if (!(logflags & IPT_LOG_MACDECODE))
|
||||||
|
goto fallback;
|
||||||
|
|
||||||
|
switch (dev->type) {
|
||||||
|
case ARPHRD_ETHER:
|
||||||
|
printk("MACSRC=%pM MACDST=%pM MACPROTO=%04x ",
|
||||||
|
eth_hdr(skb)->h_source, eth_hdr(skb)->h_dest,
|
||||||
|
ntohs(eth_hdr(skb)->h_proto));
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
fallback:
|
||||||
|
printk("MAC=");
|
||||||
|
if (dev->hard_header_len &&
|
||||||
|
skb->mac_header != skb->network_header) {
|
||||||
|
const unsigned char *p = skb_mac_header(skb);
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
printk("%02x", *p++);
|
||||||
|
for (i = 1; i < dev->hard_header_len; i++, p++)
|
||||||
|
printk(":%02x", *p);
|
||||||
|
}
|
||||||
|
printk(" ");
|
||||||
|
}
|
||||||
|
|
||||||
static struct nf_loginfo default_loginfo = {
|
static struct nf_loginfo default_loginfo = {
|
||||||
.type = NF_LOG_TYPE_LOG,
|
.type = NF_LOG_TYPE_LOG,
|
||||||
.u = {
|
.u = {
|
||||||
|
@ -404,20 +441,9 @@ ipt_log_packet(u_int8_t pf,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (in && !out) {
|
/* MAC logging for input path only. */
|
||||||
/* MAC logging for input chain only. */
|
if (in && !out)
|
||||||
printk("MAC=");
|
dump_mac_header(loginfo, skb);
|
||||||
if (skb->dev && skb->dev->hard_header_len &&
|
|
||||||
skb->mac_header != skb->network_header) {
|
|
||||||
int i;
|
|
||||||
const unsigned char *p = skb_mac_header(skb);
|
|
||||||
|
|
||||||
printk("%02x", *p++);
|
|
||||||
for (i = 1; i < skb->dev->hard_header_len; i++, p++)
|
|
||||||
printk(":%02x", *p);
|
|
||||||
}
|
|
||||||
printk(" ");
|
|
||||||
}
|
|
||||||
|
|
||||||
dump_packet(loginfo, skb, 0);
|
dump_packet(loginfo, skb, 0);
|
||||||
printk("\n");
|
printk("\n");
|
||||||
|
|
|
@ -373,6 +373,56 @@ static void dump_packet(const struct nf_loginfo *info,
|
||||||
printk("MARK=0x%x ", skb->mark);
|
printk("MARK=0x%x ", skb->mark);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void dump_mac_header(const struct nf_loginfo *info,
|
||||||
|
const struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
struct net_device *dev = skb->dev;
|
||||||
|
unsigned int logflags = 0;
|
||||||
|
|
||||||
|
if (info->type == NF_LOG_TYPE_LOG)
|
||||||
|
logflags = info->u.log.logflags;
|
||||||
|
|
||||||
|
if (!(logflags & IP6T_LOG_MACDECODE))
|
||||||
|
goto fallback;
|
||||||
|
|
||||||
|
switch (dev->type) {
|
||||||
|
case ARPHRD_ETHER:
|
||||||
|
printk("MACSRC=%pM MACDST=%pM MACPROTO=%04x ",
|
||||||
|
eth_hdr(skb)->h_source, eth_hdr(skb)->h_dest,
|
||||||
|
ntohs(eth_hdr(skb)->h_proto));
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
fallback:
|
||||||
|
printk("MAC=");
|
||||||
|
if (dev->hard_header_len &&
|
||||||
|
skb->mac_header != skb->network_header) {
|
||||||
|
const unsigned char *p = skb_mac_header(skb);
|
||||||
|
unsigned int len = dev->hard_header_len;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
if (dev->type == ARPHRD_SIT &&
|
||||||
|
(p -= ETH_HLEN) < skb->head)
|
||||||
|
p = NULL;
|
||||||
|
|
||||||
|
if (p != NULL) {
|
||||||
|
printk("%02x", *p++);
|
||||||
|
for (i = 1; i < len; i++)
|
||||||
|
printk(":%02x", p[i]);
|
||||||
|
}
|
||||||
|
printk(" ");
|
||||||
|
|
||||||
|
if (dev->type == ARPHRD_SIT) {
|
||||||
|
const struct iphdr *iph =
|
||||||
|
(struct iphdr *)skb_mac_header(skb);
|
||||||
|
printk("TUNNEL=%pI4->%pI4 ", &iph->saddr, &iph->daddr);
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
printk(" ");
|
||||||
|
}
|
||||||
|
|
||||||
static struct nf_loginfo default_loginfo = {
|
static struct nf_loginfo default_loginfo = {
|
||||||
.type = NF_LOG_TYPE_LOG,
|
.type = NF_LOG_TYPE_LOG,
|
||||||
.u = {
|
.u = {
|
||||||
|
@ -400,35 +450,10 @@ ip6t_log_packet(u_int8_t pf,
|
||||||
prefix,
|
prefix,
|
||||||
in ? in->name : "",
|
in ? in->name : "",
|
||||||
out ? out->name : "");
|
out ? out->name : "");
|
||||||
if (in && !out) {
|
|
||||||
unsigned int len;
|
|
||||||
/* MAC logging for input chain only. */
|
|
||||||
printk("MAC=");
|
|
||||||
if (skb->dev && (len = skb->dev->hard_header_len) &&
|
|
||||||
skb->mac_header != skb->network_header) {
|
|
||||||
const unsigned char *p = skb_mac_header(skb);
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (skb->dev->type == ARPHRD_SIT &&
|
/* MAC logging for input path only. */
|
||||||
(p -= ETH_HLEN) < skb->head)
|
if (in && !out)
|
||||||
p = NULL;
|
dump_mac_header(loginfo, skb);
|
||||||
|
|
||||||
if (p != NULL) {
|
|
||||||
printk("%02x", *p++);
|
|
||||||
for (i = 1; i < len; i++)
|
|
||||||
printk(":%02x", p[i]);
|
|
||||||
}
|
|
||||||
printk(" ");
|
|
||||||
|
|
||||||
if (skb->dev->type == ARPHRD_SIT) {
|
|
||||||
const struct iphdr *iph =
|
|
||||||
(struct iphdr *)skb_mac_header(skb);
|
|
||||||
printk("TUNNEL=%pI4->%pI4 ",
|
|
||||||
&iph->saddr, &iph->daddr);
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
printk(" ");
|
|
||||||
}
|
|
||||||
|
|
||||||
dump_packet(loginfo, skb, skb_network_offset(skb), 1);
|
dump_packet(loginfo, skb, skb_network_offset(skb), 1);
|
||||||
printk("\n");
|
printk("\n");
|
||||||
|
|
Loading…
Reference in New Issue