root/net/ipv4/netfilter/nf_log_arp.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. dump_arp_packet
  2. nf_log_arp_packet
  3. nf_log_arp_net_init
  4. nf_log_arp_net_exit
  5. nf_log_arp_init
  6. nf_log_arp_exit

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * (C) 2014 by Pablo Neira Ayuso <pablo@netfilter.org>
   4  *
   5  * Based on code from ebt_log from:
   6  *
   7  * Bart De Schuymer <bdschuym@pandora.be>
   8  * Harald Welte <laforge@netfilter.org>
   9  */
  10 
  11 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  12 
  13 #include <linux/kernel.h>
  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 const struct nf_loginfo default_loginfo = {
  26         .type   = NF_LOG_TYPE_LOG,
  27         .u = {
  28                 .log = {
  29                         .level    = LOGLEVEL_NOTICE,
  30                         .logflags = NF_LOG_DEFAULT_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(ARPHRD_ETHER) ||
  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 static 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) && !sysctl_nf_log_all_netns)
  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         return nf_log_set(net, NFPROTO_ARP, &nf_arp_logger);
 112 }
 113 
 114 static void __net_exit nf_log_arp_net_exit(struct net *net)
 115 {
 116         nf_log_unset(net, &nf_arp_logger);
 117 }
 118 
 119 static struct pernet_operations nf_log_arp_net_ops = {
 120         .init = nf_log_arp_net_init,
 121         .exit = nf_log_arp_net_exit,
 122 };
 123 
 124 static int __init nf_log_arp_init(void)
 125 {
 126         int ret;
 127 
 128         ret = register_pernet_subsys(&nf_log_arp_net_ops);
 129         if (ret < 0)
 130                 return ret;
 131 
 132         ret = nf_log_register(NFPROTO_ARP, &nf_arp_logger);
 133         if (ret < 0) {
 134                 pr_err("failed to register logger\n");
 135                 goto err1;
 136         }
 137 
 138         return 0;
 139 
 140 err1:
 141         unregister_pernet_subsys(&nf_log_arp_net_ops);
 142         return ret;
 143 }
 144 
 145 static void __exit nf_log_arp_exit(void)
 146 {
 147         unregister_pernet_subsys(&nf_log_arp_net_ops);
 148         nf_log_unregister(&nf_arp_logger);
 149 }
 150 
 151 module_init(nf_log_arp_init);
 152 module_exit(nf_log_arp_exit);
 153 
 154 MODULE_AUTHOR("Pablo Neira Ayuso <pablo@netfilter.org>");
 155 MODULE_DESCRIPTION("Netfilter ARP packet logging");
 156 MODULE_LICENSE("GPL");
 157 MODULE_ALIAS_NF_LOGGER(3, 0);

/* [<][>][^][v][top][bottom][index][help] */