~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise

« back to all changes in this revision

Viewing changes to net/netfilter/xt_AUDIT.c

  • Committer: Bazaar Package Importer
  • Author(s): Paolo Pisati
  • Date: 2011-06-29 15:23:51 UTC
  • mfrom: (26.1.1 natty-proposed)
  • Revision ID: james.westby@ubuntu.com-20110629152351-xs96tm303d95rpbk
Tags: 3.0.0-1200.2
* Rebased against 3.0.0-6.7
* BSP from TI based on 3.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Creates audit record for dropped/accepted packets
 
3
 *
 
4
 * (C) 2010-2011 Thomas Graf <tgraf@redhat.com>
 
5
 * (C) 2010-2011 Red Hat, Inc.
 
6
 *
 
7
 * This program is free software; you can redistribute it and/or modify
 
8
 * it under the terms of the GNU General Public License version 2 as
 
9
 * published by the Free Software Foundation.
 
10
*/
 
11
 
 
12
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
13
 
 
14
#include <linux/audit.h>
 
15
#include <linux/module.h>
 
16
#include <linux/skbuff.h>
 
17
#include <linux/tcp.h>
 
18
#include <linux/udp.h>
 
19
#include <linux/if_arp.h>
 
20
#include <linux/netfilter/x_tables.h>
 
21
#include <linux/netfilter/xt_AUDIT.h>
 
22
#include <linux/netfilter_bridge/ebtables.h>
 
23
#include <net/ipv6.h>
 
24
#include <net/ip.h>
 
25
 
 
26
MODULE_LICENSE("GPL");
 
27
MODULE_AUTHOR("Thomas Graf <tgraf@redhat.com>");
 
28
MODULE_DESCRIPTION("Xtables: creates audit records for dropped/accepted packets");
 
29
MODULE_ALIAS("ipt_AUDIT");
 
30
MODULE_ALIAS("ip6t_AUDIT");
 
31
MODULE_ALIAS("ebt_AUDIT");
 
32
MODULE_ALIAS("arpt_AUDIT");
 
33
 
 
34
static void audit_proto(struct audit_buffer *ab, struct sk_buff *skb,
 
35
                        unsigned int proto, unsigned int offset)
 
36
{
 
37
        switch (proto) {
 
38
        case IPPROTO_TCP:
 
39
        case IPPROTO_UDP:
 
40
        case IPPROTO_UDPLITE: {
 
41
                const __be16 *pptr;
 
42
                __be16 _ports[2];
 
43
 
 
44
                pptr = skb_header_pointer(skb, offset, sizeof(_ports), _ports);
 
45
                if (pptr == NULL) {
 
46
                        audit_log_format(ab, " truncated=1");
 
47
                        return;
 
48
                }
 
49
 
 
50
                audit_log_format(ab, " sport=%hu dport=%hu",
 
51
                                 ntohs(pptr[0]), ntohs(pptr[1]));
 
52
                }
 
53
                break;
 
54
 
 
55
        case IPPROTO_ICMP:
 
56
        case IPPROTO_ICMPV6: {
 
57
                const u8 *iptr;
 
58
                u8 _ih[2];
 
59
 
 
60
                iptr = skb_header_pointer(skb, offset, sizeof(_ih), &_ih);
 
61
                if (iptr == NULL) {
 
62
                        audit_log_format(ab, " truncated=1");
 
63
                        return;
 
64
                }
 
65
 
 
66
                audit_log_format(ab, " icmptype=%hhu icmpcode=%hhu",
 
67
                                 iptr[0], iptr[1]);
 
68
 
 
69
                }
 
70
                break;
 
71
        }
 
72
}
 
73
 
 
74
static void audit_ip4(struct audit_buffer *ab, struct sk_buff *skb)
 
75
{
 
76
        struct iphdr _iph;
 
77
        const struct iphdr *ih;
 
78
 
 
79
        ih = skb_header_pointer(skb, 0, sizeof(_iph), &_iph);
 
80
        if (!ih) {
 
81
                audit_log_format(ab, " truncated=1");
 
82
                return;
 
83
        }
 
84
 
 
85
        audit_log_format(ab, " saddr=%pI4 daddr=%pI4 ipid=%hu proto=%hhu",
 
86
                &ih->saddr, &ih->daddr, ntohs(ih->id), ih->protocol);
 
87
 
 
88
        if (ntohs(ih->frag_off) & IP_OFFSET) {
 
89
                audit_log_format(ab, " frag=1");
 
90
                return;
 
91
        }
 
92
 
 
93
        audit_proto(ab, skb, ih->protocol, ih->ihl * 4);
 
94
}
 
95
 
 
96
static void audit_ip6(struct audit_buffer *ab, struct sk_buff *skb)
 
97
{
 
98
        struct ipv6hdr _ip6h;
 
99
        const struct ipv6hdr *ih;
 
100
        u8 nexthdr;
 
101
        int offset;
 
102
 
 
103
        ih = skb_header_pointer(skb, skb_network_offset(skb), sizeof(_ip6h), &_ip6h);
 
104
        if (!ih) {
 
105
                audit_log_format(ab, " truncated=1");
 
106
                return;
 
107
        }
 
108
 
 
109
        nexthdr = ih->nexthdr;
 
110
        offset = ipv6_skip_exthdr(skb, skb_network_offset(skb) + sizeof(_ip6h),
 
111
                                  &nexthdr);
 
112
 
 
113
        audit_log_format(ab, " saddr=%pI6c daddr=%pI6c proto=%hhu",
 
114
                         &ih->saddr, &ih->daddr, nexthdr);
 
115
 
 
116
        if (offset)
 
117
                audit_proto(ab, skb, nexthdr, offset);
 
118
}
 
119
 
 
120
static unsigned int
 
121
audit_tg(struct sk_buff *skb, const struct xt_action_param *par)
 
122
{
 
123
        const struct xt_audit_info *info = par->targinfo;
 
124
        struct audit_buffer *ab;
 
125
 
 
126
        ab = audit_log_start(NULL, GFP_ATOMIC, AUDIT_NETFILTER_PKT);
 
127
        if (ab == NULL)
 
128
                goto errout;
 
129
 
 
130
        audit_log_format(ab, "action=%hhu hook=%u len=%u inif=%s outif=%s",
 
131
                         info->type, par->hooknum, skb->len,
 
132
                         par->in ? par->in->name : "?",
 
133
                         par->out ? par->out->name : "?");
 
134
 
 
135
        if (skb->mark)
 
136
                audit_log_format(ab, " mark=%#x", skb->mark);
 
137
 
 
138
        if (skb->dev && skb->dev->type == ARPHRD_ETHER) {
 
139
                audit_log_format(ab, " smac=%pM dmac=%pM macproto=0x%04x",
 
140
                                 eth_hdr(skb)->h_source, eth_hdr(skb)->h_dest,
 
141
                                 ntohs(eth_hdr(skb)->h_proto));
 
142
 
 
143
                if (par->family == NFPROTO_BRIDGE) {
 
144
                        switch (eth_hdr(skb)->h_proto) {
 
145
                        case __constant_htons(ETH_P_IP):
 
146
                                audit_ip4(ab, skb);
 
147
                                break;
 
148
 
 
149
                        case __constant_htons(ETH_P_IPV6):
 
150
                                audit_ip6(ab, skb);
 
151
                                break;
 
152
                        }
 
153
                }
 
154
        }
 
155
 
 
156
        switch (par->family) {
 
157
        case NFPROTO_IPV4:
 
158
                audit_ip4(ab, skb);
 
159
                break;
 
160
 
 
161
        case NFPROTO_IPV6:
 
162
                audit_ip6(ab, skb);
 
163
                break;
 
164
        }
 
165
 
 
166
        audit_log_end(ab);
 
167
 
 
168
errout:
 
169
        return XT_CONTINUE;
 
170
}
 
171
 
 
172
static unsigned int
 
173
audit_tg_ebt(struct sk_buff *skb, const struct xt_action_param *par)
 
174
{
 
175
        audit_tg(skb, par);
 
176
        return EBT_CONTINUE;
 
177
}
 
178
 
 
179
static int audit_tg_check(const struct xt_tgchk_param *par)
 
180
{
 
181
        const struct xt_audit_info *info = par->targinfo;
 
182
 
 
183
        if (info->type > XT_AUDIT_TYPE_MAX) {
 
184
                pr_info("Audit type out of range (valid range: 0..%hhu)\n",
 
185
                        XT_AUDIT_TYPE_MAX);
 
186
                return -ERANGE;
 
187
        }
 
188
 
 
189
        return 0;
 
190
}
 
191
 
 
192
static struct xt_target audit_tg_reg[] __read_mostly = {
 
193
        {
 
194
                .name           = "AUDIT",
 
195
                .family         = NFPROTO_UNSPEC,
 
196
                .target         = audit_tg,
 
197
                .targetsize     = sizeof(struct xt_audit_info),
 
198
                .checkentry     = audit_tg_check,
 
199
                .me             = THIS_MODULE,
 
200
        },
 
201
        {
 
202
                .name           = "AUDIT",
 
203
                .family         = NFPROTO_BRIDGE,
 
204
                .target         = audit_tg_ebt,
 
205
                .targetsize     = sizeof(struct xt_audit_info),
 
206
                .checkentry     = audit_tg_check,
 
207
                .me             = THIS_MODULE,
 
208
        },
 
209
};
 
210
 
 
211
static int __init audit_tg_init(void)
 
212
{
 
213
        return xt_register_targets(audit_tg_reg, ARRAY_SIZE(audit_tg_reg));
 
214
}
 
215
 
 
216
static void __exit audit_tg_exit(void)
 
217
{
 
218
        xt_unregister_targets(audit_tg_reg, ARRAY_SIZE(audit_tg_reg));
 
219
}
 
220
 
 
221
module_init(audit_tg_init);
 
222
module_exit(audit_tg_exit);