Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Creates audit record for dropped/accepted packets
0004  *
0005  * (C) 2010-2011 Thomas Graf <tgraf@redhat.com>
0006  * (C) 2010-2011 Red Hat, Inc.
0007 */
0008 
0009 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0010 
0011 #include <linux/audit.h>
0012 #include <linux/module.h>
0013 #include <linux/skbuff.h>
0014 #include <linux/tcp.h>
0015 #include <linux/udp.h>
0016 #include <linux/if_arp.h>
0017 #include <linux/netfilter/x_tables.h>
0018 #include <linux/netfilter/xt_AUDIT.h>
0019 #include <linux/netfilter_bridge/ebtables.h>
0020 #include <net/ipv6.h>
0021 #include <net/ip.h>
0022 
0023 MODULE_LICENSE("GPL");
0024 MODULE_AUTHOR("Thomas Graf <tgraf@redhat.com>");
0025 MODULE_DESCRIPTION("Xtables: creates audit records for dropped/accepted packets");
0026 MODULE_ALIAS("ipt_AUDIT");
0027 MODULE_ALIAS("ip6t_AUDIT");
0028 MODULE_ALIAS("ebt_AUDIT");
0029 MODULE_ALIAS("arpt_AUDIT");
0030 
0031 static bool audit_ip4(struct audit_buffer *ab, struct sk_buff *skb)
0032 {
0033     struct iphdr _iph;
0034     const struct iphdr *ih;
0035 
0036     ih = skb_header_pointer(skb, skb_network_offset(skb), sizeof(_iph), &_iph);
0037     if (!ih)
0038         return false;
0039 
0040     audit_log_format(ab, " saddr=%pI4 daddr=%pI4 proto=%hhu",
0041              &ih->saddr, &ih->daddr, ih->protocol);
0042 
0043     return true;
0044 }
0045 
0046 static bool audit_ip6(struct audit_buffer *ab, struct sk_buff *skb)
0047 {
0048     struct ipv6hdr _ip6h;
0049     const struct ipv6hdr *ih;
0050     u8 nexthdr;
0051     __be16 frag_off;
0052 
0053     ih = skb_header_pointer(skb, skb_network_offset(skb), sizeof(_ip6h), &_ip6h);
0054     if (!ih)
0055         return false;
0056 
0057     nexthdr = ih->nexthdr;
0058     ipv6_skip_exthdr(skb, skb_network_offset(skb) + sizeof(_ip6h), &nexthdr, &frag_off);
0059 
0060     audit_log_format(ab, " saddr=%pI6c daddr=%pI6c proto=%hhu",
0061              &ih->saddr, &ih->daddr, nexthdr);
0062 
0063     return true;
0064 }
0065 
0066 static unsigned int
0067 audit_tg(struct sk_buff *skb, const struct xt_action_param *par)
0068 {
0069     struct audit_buffer *ab;
0070     int fam = -1;
0071 
0072     if (audit_enabled == AUDIT_OFF)
0073         goto errout;
0074     ab = audit_log_start(NULL, GFP_ATOMIC, AUDIT_NETFILTER_PKT);
0075     if (ab == NULL)
0076         goto errout;
0077 
0078     audit_log_format(ab, "mark=%#x", skb->mark);
0079 
0080     switch (xt_family(par)) {
0081     case NFPROTO_BRIDGE:
0082         switch (eth_hdr(skb)->h_proto) {
0083         case htons(ETH_P_IP):
0084             fam = audit_ip4(ab, skb) ? NFPROTO_IPV4 : -1;
0085             break;
0086         case htons(ETH_P_IPV6):
0087             fam = audit_ip6(ab, skb) ? NFPROTO_IPV6 : -1;
0088             break;
0089         }
0090         break;
0091     case NFPROTO_IPV4:
0092         fam = audit_ip4(ab, skb) ? NFPROTO_IPV4 : -1;
0093         break;
0094     case NFPROTO_IPV6:
0095         fam = audit_ip6(ab, skb) ? NFPROTO_IPV6 : -1;
0096         break;
0097     }
0098 
0099     if (fam == -1)
0100         audit_log_format(ab, " saddr=? daddr=? proto=-1");
0101 
0102     audit_log_end(ab);
0103 
0104 errout:
0105     return XT_CONTINUE;
0106 }
0107 
0108 static unsigned int
0109 audit_tg_ebt(struct sk_buff *skb, const struct xt_action_param *par)
0110 {
0111     audit_tg(skb, par);
0112     return EBT_CONTINUE;
0113 }
0114 
0115 static int audit_tg_check(const struct xt_tgchk_param *par)
0116 {
0117     const struct xt_audit_info *info = par->targinfo;
0118 
0119     if (info->type > XT_AUDIT_TYPE_MAX) {
0120         pr_info_ratelimited("Audit type out of range (valid range: 0..%u)\n",
0121                     XT_AUDIT_TYPE_MAX);
0122         return -ERANGE;
0123     }
0124 
0125     return 0;
0126 }
0127 
0128 static struct xt_target audit_tg_reg[] __read_mostly = {
0129     {
0130         .name       = "AUDIT",
0131         .family     = NFPROTO_UNSPEC,
0132         .target     = audit_tg,
0133         .targetsize = sizeof(struct xt_audit_info),
0134         .checkentry = audit_tg_check,
0135         .me     = THIS_MODULE,
0136     },
0137     {
0138         .name       = "AUDIT",
0139         .family     = NFPROTO_BRIDGE,
0140         .target     = audit_tg_ebt,
0141         .targetsize = sizeof(struct xt_audit_info),
0142         .checkentry = audit_tg_check,
0143         .me     = THIS_MODULE,
0144     },
0145 };
0146 
0147 static int __init audit_tg_init(void)
0148 {
0149     return xt_register_targets(audit_tg_reg, ARRAY_SIZE(audit_tg_reg));
0150 }
0151 
0152 static void __exit audit_tg_exit(void)
0153 {
0154     xt_unregister_targets(audit_tg_reg, ARRAY_SIZE(audit_tg_reg));
0155 }
0156 
0157 module_init(audit_tg_init);
0158 module_exit(audit_tg_exit);