linux/net/netfilter/xt_AUDIT.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Creates audit record for dropped/accepted packets
   4 *
   5 * (C) 2010-2011 Thomas Graf <tgraf@redhat.com>
   6 * (C) 2010-2011 Red Hat, Inc.
   7*/
   8
   9#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  10
  11#include <linux/audit.h>
  12#include <linux/module.h>
  13#include <linux/skbuff.h>
  14#include <linux/tcp.h>
  15#include <linux/udp.h>
  16#include <linux/if_arp.h>
  17#include <linux/netfilter/x_tables.h>
  18#include <linux/netfilter/xt_AUDIT.h>
  19#include <linux/netfilter_bridge/ebtables.h>
  20#include <net/ipv6.h>
  21#include <net/ip.h>
  22
  23MODULE_LICENSE("GPL");
  24MODULE_AUTHOR("Thomas Graf <tgraf@redhat.com>");
  25MODULE_DESCRIPTION("Xtables: creates audit records for dropped/accepted packets");
  26MODULE_ALIAS("ipt_AUDIT");
  27MODULE_ALIAS("ip6t_AUDIT");
  28MODULE_ALIAS("ebt_AUDIT");
  29MODULE_ALIAS("arpt_AUDIT");
  30
  31static bool audit_ip4(struct audit_buffer *ab, struct sk_buff *skb)
  32{
  33        struct iphdr _iph;
  34        const struct iphdr *ih;
  35
  36        ih = skb_header_pointer(skb, skb_network_offset(skb), sizeof(_iph), &_iph);
  37        if (!ih)
  38                return false;
  39
  40        audit_log_format(ab, " saddr=%pI4 daddr=%pI4 proto=%hhu",
  41                         &ih->saddr, &ih->daddr, ih->protocol);
  42
  43        return true;
  44}
  45
  46static bool audit_ip6(struct audit_buffer *ab, struct sk_buff *skb)
  47{
  48        struct ipv6hdr _ip6h;
  49        const struct ipv6hdr *ih;
  50        u8 nexthdr;
  51        __be16 frag_off;
  52
  53        ih = skb_header_pointer(skb, skb_network_offset(skb), sizeof(_ip6h), &_ip6h);
  54        if (!ih)
  55                return false;
  56
  57        nexthdr = ih->nexthdr;
  58        ipv6_skip_exthdr(skb, skb_network_offset(skb) + sizeof(_ip6h), &nexthdr, &frag_off);
  59
  60        audit_log_format(ab, " saddr=%pI6c daddr=%pI6c proto=%hhu",
  61                         &ih->saddr, &ih->daddr, nexthdr);
  62
  63        return true;
  64}
  65
  66static unsigned int
  67audit_tg(struct sk_buff *skb, const struct xt_action_param *par)
  68{
  69        struct audit_buffer *ab;
  70        int fam = -1;
  71
  72        if (audit_enabled == AUDIT_OFF)
  73                goto errout;
  74        ab = audit_log_start(NULL, GFP_ATOMIC, AUDIT_NETFILTER_PKT);
  75        if (ab == NULL)
  76                goto errout;
  77
  78        audit_log_format(ab, "mark=%#x", skb->mark);
  79
  80        switch (xt_family(par)) {
  81        case NFPROTO_BRIDGE:
  82                switch (eth_hdr(skb)->h_proto) {
  83                case htons(ETH_P_IP):
  84                        fam = audit_ip4(ab, skb) ? NFPROTO_IPV4 : -1;
  85                        break;
  86                case htons(ETH_P_IPV6):
  87                        fam = audit_ip6(ab, skb) ? NFPROTO_IPV6 : -1;
  88                        break;
  89                }
  90                break;
  91        case NFPROTO_IPV4:
  92                fam = audit_ip4(ab, skb) ? NFPROTO_IPV4 : -1;
  93                break;
  94        case NFPROTO_IPV6:
  95                fam = audit_ip6(ab, skb) ? NFPROTO_IPV6 : -1;
  96                break;
  97        }
  98
  99        if (fam == -1)
 100                audit_log_format(ab, " saddr=? daddr=? proto=-1");
 101
 102        audit_log_end(ab);
 103
 104errout:
 105        return XT_CONTINUE;
 106}
 107
 108static unsigned int
 109audit_tg_ebt(struct sk_buff *skb, const struct xt_action_param *par)
 110{
 111        audit_tg(skb, par);
 112        return EBT_CONTINUE;
 113}
 114
 115static int audit_tg_check(const struct xt_tgchk_param *par)
 116{
 117        const struct xt_audit_info *info = par->targinfo;
 118
 119        if (info->type > XT_AUDIT_TYPE_MAX) {
 120                pr_info_ratelimited("Audit type out of range (valid range: 0..%hhu)\n",
 121                                    XT_AUDIT_TYPE_MAX);
 122                return -ERANGE;
 123        }
 124
 125        return 0;
 126}
 127
 128static struct xt_target audit_tg_reg[] __read_mostly = {
 129        {
 130                .name           = "AUDIT",
 131                .family         = NFPROTO_UNSPEC,
 132                .target         = audit_tg,
 133                .targetsize     = sizeof(struct xt_audit_info),
 134                .checkentry     = audit_tg_check,
 135                .me             = THIS_MODULE,
 136        },
 137        {
 138                .name           = "AUDIT",
 139                .family         = NFPROTO_BRIDGE,
 140                .target         = audit_tg_ebt,
 141                .targetsize     = sizeof(struct xt_audit_info),
 142                .checkentry     = audit_tg_check,
 143                .me             = THIS_MODULE,
 144        },
 145};
 146
 147static int __init audit_tg_init(void)
 148{
 149        return xt_register_targets(audit_tg_reg, ARRAY_SIZE(audit_tg_reg));
 150}
 151
 152static void __exit audit_tg_exit(void)
 153{
 154        xt_unregister_targets(audit_tg_reg, ARRAY_SIZE(audit_tg_reg));
 155}
 156
 157module_init(audit_tg_init);
 158module_exit(audit_tg_exit);
 159