diff options
author | Pablo Neira Ayuso <pablo@netfilter.org> | 2014-06-20 14:36:23 -0400 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2014-06-27 07:20:38 -0400 |
commit | 35b9395104d51f4b85847fa72a1bf4136d36c56e (patch) | |
tree | 7d3e26af1af9a9050b1c5b4faa07419ee2d00ef7 /net | |
parent | fab4085f4e248b8a80bb1dadbbacb2bacd8017c3 (diff) |
netfilter: add generic ARP packet logger
This adds the generic plain text packet loggger for ARP packets. It is
based on the ebt_log code. Nevertheless, the output has been modified
to make it consistent with the original xt_LOG output.
This is an example output:
IN=wlan0 OUT= ARP HTYPE=1 PTYPE=0x0800 OPCODE=2 MACSRC=00:ab:12:34:55:63 IPSRC=192.168.10.1 MACDST=80:09:12:70:4f:50 IPDST=192.168.10.150
This patch enables packet logging from ARP chains, eg.
nft add rule arp filter input log prefix "input: "
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv4/netfilter/Kconfig | 5 | ||||
-rw-r--r-- | net/ipv4/netfilter/Makefile | 1 | ||||
-rw-r--r-- | net/ipv4/netfilter/nf_log_arp.c | 149 |
3 files changed, 155 insertions, 0 deletions
diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig index 0c980293d225..12e6057daea1 100644 --- a/net/ipv4/netfilter/Kconfig +++ b/net/ipv4/netfilter/Kconfig | |||
@@ -159,6 +159,11 @@ config IP_NF_TARGET_SYNPROXY | |||
159 | 159 | ||
160 | To compile it as a module, choose M here. If unsure, say N. | 160 | To compile it as a module, choose M here. If unsure, say N. |
161 | 161 | ||
162 | config NF_LOG_ARP | ||
163 | tristate "ARP packet logging" | ||
164 | default m if NETFILTER_ADVANCED=n | ||
165 | select NF_LOG_INET | ||
166 | |||
162 | config NF_LOG_IPV4 | 167 | config NF_LOG_IPV4 |
163 | tristate "IPv4 packet logging" | 168 | tristate "IPv4 packet logging" |
164 | default m if NETFILTER_ADVANCED=n | 169 | default m if NETFILTER_ADVANCED=n |
diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile index 730e0c1ead90..245db9df3337 100644 --- a/net/ipv4/netfilter/Makefile +++ b/net/ipv4/netfilter/Makefile | |||
@@ -20,6 +20,7 @@ obj-$(CONFIG_NF_NAT_IPV4) += nf_nat_ipv4.o | |||
20 | obj-$(CONFIG_NF_DEFRAG_IPV4) += nf_defrag_ipv4.o | 20 | obj-$(CONFIG_NF_DEFRAG_IPV4) += nf_defrag_ipv4.o |
21 | 21 | ||
22 | # logging | 22 | # logging |
23 | obj-$(CONFIG_NF_LOG_ARP) += nf_log_arp.o | ||
23 | obj-$(CONFIG_NF_LOG_IPV4) += nf_log_ipv4.o | 24 | obj-$(CONFIG_NF_LOG_IPV4) += nf_log_ipv4.o |
24 | 25 | ||
25 | # NAT helpers (nf_conntrack) | 26 | # NAT helpers (nf_conntrack) |
diff --git a/net/ipv4/netfilter/nf_log_arp.c b/net/ipv4/netfilter/nf_log_arp.c new file mode 100644 index 000000000000..ccfc78db12ee --- /dev/null +++ b/net/ipv4/netfilter/nf_log_arp.c | |||
@@ -0,0 +1,149 @@ | |||
1 | /* | ||
2 | * (C) 2014 by Pablo Neira Ayuso <pablo@netfilter.org> | ||
3 | * | ||
4 | * Based on code from ebt_log from: | ||
5 | * | ||
6 | * Bart De Schuymer <bdschuym@pandora.be> | ||
7 | * Harald Welte <laforge@netfilter.org> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | |||
14 | #include <linux/module.h> | ||
15 | #include <linux/spinlock.h> | ||
16 | #include <linux/skbuff.h> | ||
17 | #include <linux/if_arp.h> | ||
18 | #include <linux/ip.h> | ||
19 | #include <net/route.h> | ||
20 | |||
21 | #include <linux/netfilter.h> | ||
22 | #include <linux/netfilter/xt_LOG.h> | ||
23 | #include <net/netfilter/nf_log.h> | ||
24 | |||
25 | static struct nf_loginfo default_loginfo = { | ||
26 | .type = NF_LOG_TYPE_LOG, | ||
27 | .u = { | ||
28 | .log = { | ||
29 | .level = 5, | ||
30 | .logflags = NF_LOG_MASK, | ||
31 | }, | ||
32 | }, | ||
33 | }; | ||
34 | |||
35 | struct arppayload { | ||
36 | unsigned char mac_src[ETH_ALEN]; | ||
37 | unsigned char ip_src[4]; | ||
38 | unsigned char mac_dst[ETH_ALEN]; | ||
39 | unsigned char ip_dst[4]; | ||
40 | }; | ||
41 | |||
42 | static void dump_arp_packet(struct nf_log_buf *m, | ||
43 | const struct nf_loginfo *info, | ||
44 | const struct sk_buff *skb, unsigned int nhoff) | ||
45 | { | ||
46 | const struct arphdr *ah; | ||
47 | struct arphdr _arph; | ||
48 | const struct arppayload *ap; | ||
49 | struct arppayload _arpp; | ||
50 | |||
51 | ah = skb_header_pointer(skb, 0, sizeof(_arph), &_arph); | ||
52 | if (ah == NULL) { | ||
53 | nf_log_buf_add(m, "TRUNCATED"); | ||
54 | return; | ||
55 | } | ||
56 | nf_log_buf_add(m, "ARP HTYPE=%d PTYPE=0x%04x OPCODE=%d", | ||
57 | ntohs(ah->ar_hrd), ntohs(ah->ar_pro), ntohs(ah->ar_op)); | ||
58 | |||
59 | /* If it's for Ethernet and the lengths are OK, then log the ARP | ||
60 | * payload. | ||
61 | */ | ||
62 | if (ah->ar_hrd != htons(1) || | ||
63 | ah->ar_hln != ETH_ALEN || | ||
64 | ah->ar_pln != sizeof(__be32)) | ||
65 | return; | ||
66 | |||
67 | ap = skb_header_pointer(skb, sizeof(_arph), sizeof(_arpp), &_arpp); | ||
68 | if (ap == NULL) { | ||
69 | nf_log_buf_add(m, " INCOMPLETE [%Zu bytes]", | ||
70 | skb->len - sizeof(_arph)); | ||
71 | return; | ||
72 | } | ||
73 | nf_log_buf_add(m, " MACSRC=%pM IPSRC=%pI4 MACDST=%pM IPDST=%pI4", | ||
74 | ap->mac_src, ap->ip_src, ap->mac_dst, ap->ip_dst); | ||
75 | } | ||
76 | |||
77 | void nf_log_arp_packet(struct net *net, u_int8_t pf, | ||
78 | unsigned int hooknum, const struct sk_buff *skb, | ||
79 | const struct net_device *in, | ||
80 | const struct net_device *out, | ||
81 | const struct nf_loginfo *loginfo, | ||
82 | const char *prefix) | ||
83 | { | ||
84 | struct nf_log_buf *m; | ||
85 | |||
86 | /* FIXME: Disabled from containers until syslog ns is supported */ | ||
87 | if (!net_eq(net, &init_net)) | ||
88 | return; | ||
89 | |||
90 | m = nf_log_buf_open(); | ||
91 | |||
92 | if (!loginfo) | ||
93 | loginfo = &default_loginfo; | ||
94 | |||
95 | nf_log_dump_packet_common(m, pf, hooknum, skb, in, out, loginfo, | ||
96 | prefix); | ||
97 | dump_arp_packet(m, loginfo, skb, 0); | ||
98 | |||
99 | nf_log_buf_close(m); | ||
100 | } | ||
101 | |||
102 | static struct nf_logger nf_arp_logger __read_mostly = { | ||
103 | .name = "nf_log_arp", | ||
104 | .type = NF_LOG_TYPE_LOG, | ||
105 | .logfn = nf_log_arp_packet, | ||
106 | .me = THIS_MODULE, | ||
107 | }; | ||
108 | |||
109 | static int __net_init nf_log_arp_net_init(struct net *net) | ||
110 | { | ||
111 | nf_log_set(net, NFPROTO_ARP, &nf_arp_logger); | ||
112 | return 0; | ||
113 | } | ||
114 | |||
115 | static void __net_exit nf_log_arp_net_exit(struct net *net) | ||
116 | { | ||
117 | nf_log_unset(net, &nf_arp_logger); | ||
118 | } | ||
119 | |||
120 | static struct pernet_operations nf_log_arp_net_ops = { | ||
121 | .init = nf_log_arp_net_init, | ||
122 | .exit = nf_log_arp_net_exit, | ||
123 | }; | ||
124 | |||
125 | static int __init nf_log_arp_init(void) | ||
126 | { | ||
127 | int ret; | ||
128 | |||
129 | ret = register_pernet_subsys(&nf_log_arp_net_ops); | ||
130 | if (ret < 0) | ||
131 | return ret; | ||
132 | |||
133 | nf_log_register(NFPROTO_ARP, &nf_arp_logger); | ||
134 | return 0; | ||
135 | } | ||
136 | |||
137 | static void __exit nf_log_arp_exit(void) | ||
138 | { | ||
139 | unregister_pernet_subsys(&nf_log_arp_net_ops); | ||
140 | nf_log_unregister(&nf_arp_logger); | ||
141 | } | ||
142 | |||
143 | module_init(nf_log_arp_init); | ||
144 | module_exit(nf_log_arp_exit); | ||
145 | |||
146 | MODULE_AUTHOR("Pablo Neira Ayuso <pablo@netfilter.org>"); | ||
147 | MODULE_DESCRIPTION("Netfilter ARP packet logging"); | ||
148 | MODULE_LICENSE("GPL"); | ||
149 | MODULE_ALIAS_NF_LOGGER(3, 0); | ||