root/net/bridge/netfilter/ebt_log.c

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

DEFINITIONS

This source file includes following definitions.
  1. ebt_log_tg_check
  2. print_ports
  3. ebt_log_packet
  4. ebt_log_tg
  5. ebt_log_init
  6. ebt_log_fini

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  *  ebt_log
   4  *
   5  *      Authors:
   6  *      Bart De Schuymer <bdschuym@pandora.be>
   7  *      Harald Welte <laforge@netfilter.org>
   8  *
   9  *  April, 2002
  10  *
  11  */
  12 #include <linux/module.h>
  13 #include <linux/ip.h>
  14 #include <linux/in.h>
  15 #include <linux/if_arp.h>
  16 #include <linux/spinlock.h>
  17 #include <net/netfilter/nf_log.h>
  18 #include <linux/ipv6.h>
  19 #include <net/ipv6.h>
  20 #include <linux/in6.h>
  21 #include <linux/netfilter/x_tables.h>
  22 #include <linux/netfilter_bridge/ebtables.h>
  23 #include <linux/netfilter_bridge/ebt_log.h>
  24 #include <linux/netfilter.h>
  25 
  26 static DEFINE_SPINLOCK(ebt_log_lock);
  27 
  28 static int ebt_log_tg_check(const struct xt_tgchk_param *par)
  29 {
  30         struct ebt_log_info *info = par->targinfo;
  31 
  32         if (info->bitmask & ~EBT_LOG_MASK)
  33                 return -EINVAL;
  34         if (info->loglevel >= 8)
  35                 return -EINVAL;
  36         info->prefix[EBT_LOG_PREFIX_SIZE - 1] = '\0';
  37         return 0;
  38 }
  39 
  40 struct tcpudphdr {
  41         __be16 src;
  42         __be16 dst;
  43 };
  44 
  45 struct arppayload {
  46         unsigned char mac_src[ETH_ALEN];
  47         unsigned char ip_src[4];
  48         unsigned char mac_dst[ETH_ALEN];
  49         unsigned char ip_dst[4];
  50 };
  51 
  52 static void
  53 print_ports(const struct sk_buff *skb, uint8_t protocol, int offset)
  54 {
  55         if (protocol == IPPROTO_TCP ||
  56             protocol == IPPROTO_UDP ||
  57             protocol == IPPROTO_UDPLITE ||
  58             protocol == IPPROTO_SCTP ||
  59             protocol == IPPROTO_DCCP) {
  60                 const struct tcpudphdr *pptr;
  61                 struct tcpudphdr _ports;
  62 
  63                 pptr = skb_header_pointer(skb, offset,
  64                                           sizeof(_ports), &_ports);
  65                 if (pptr == NULL) {
  66                         pr_cont(" INCOMPLETE TCP/UDP header");
  67                         return;
  68                 }
  69                 pr_cont(" SPT=%u DPT=%u", ntohs(pptr->src), ntohs(pptr->dst));
  70         }
  71 }
  72 
  73 static void
  74 ebt_log_packet(struct net *net, u_int8_t pf, unsigned int hooknum,
  75                const struct sk_buff *skb, const struct net_device *in,
  76                const struct net_device *out, const struct nf_loginfo *loginfo,
  77                const char *prefix)
  78 {
  79         unsigned int bitmask;
  80 
  81         /* FIXME: Disabled from containers until syslog ns is supported */
  82         if (!net_eq(net, &init_net) && !sysctl_nf_log_all_netns)
  83                 return;
  84 
  85         spin_lock_bh(&ebt_log_lock);
  86         printk(KERN_SOH "%c%s IN=%s OUT=%s MAC source = %pM MAC dest = %pM proto = 0x%04x",
  87                '0' + loginfo->u.log.level, prefix,
  88                in ? in->name : "", out ? out->name : "",
  89                eth_hdr(skb)->h_source, eth_hdr(skb)->h_dest,
  90                ntohs(eth_hdr(skb)->h_proto));
  91 
  92         if (loginfo->type == NF_LOG_TYPE_LOG)
  93                 bitmask = loginfo->u.log.logflags;
  94         else
  95                 bitmask = NF_LOG_DEFAULT_MASK;
  96 
  97         if ((bitmask & EBT_LOG_IP) && eth_hdr(skb)->h_proto ==
  98            htons(ETH_P_IP)) {
  99                 const struct iphdr *ih;
 100                 struct iphdr _iph;
 101 
 102                 ih = skb_header_pointer(skb, 0, sizeof(_iph), &_iph);
 103                 if (ih == NULL) {
 104                         pr_cont(" INCOMPLETE IP header");
 105                         goto out;
 106                 }
 107                 pr_cont(" IP SRC=%pI4 IP DST=%pI4, IP tos=0x%02X, IP proto=%d",
 108                         &ih->saddr, &ih->daddr, ih->tos, ih->protocol);
 109                 print_ports(skb, ih->protocol, ih->ihl*4);
 110                 goto out;
 111         }
 112 
 113 #if IS_ENABLED(CONFIG_BRIDGE_EBT_IP6)
 114         if ((bitmask & EBT_LOG_IP6) && eth_hdr(skb)->h_proto ==
 115            htons(ETH_P_IPV6)) {
 116                 const struct ipv6hdr *ih;
 117                 struct ipv6hdr _iph;
 118                 uint8_t nexthdr;
 119                 __be16 frag_off;
 120                 int offset_ph;
 121 
 122                 ih = skb_header_pointer(skb, 0, sizeof(_iph), &_iph);
 123                 if (ih == NULL) {
 124                         pr_cont(" INCOMPLETE IPv6 header");
 125                         goto out;
 126                 }
 127                 pr_cont(" IPv6 SRC=%pI6 IPv6 DST=%pI6, IPv6 priority=0x%01X, Next Header=%d",
 128                         &ih->saddr, &ih->daddr, ih->priority, ih->nexthdr);
 129                 nexthdr = ih->nexthdr;
 130                 offset_ph = ipv6_skip_exthdr(skb, sizeof(_iph), &nexthdr, &frag_off);
 131                 if (offset_ph == -1)
 132                         goto out;
 133                 print_ports(skb, nexthdr, offset_ph);
 134                 goto out;
 135         }
 136 #endif
 137 
 138         if ((bitmask & EBT_LOG_ARP) &&
 139             ((eth_hdr(skb)->h_proto == htons(ETH_P_ARP)) ||
 140              (eth_hdr(skb)->h_proto == htons(ETH_P_RARP)))) {
 141                 const struct arphdr *ah;
 142                 struct arphdr _arph;
 143 
 144                 ah = skb_header_pointer(skb, 0, sizeof(_arph), &_arph);
 145                 if (ah == NULL) {
 146                         pr_cont(" INCOMPLETE ARP header");
 147                         goto out;
 148                 }
 149                 pr_cont(" ARP HTYPE=%d, PTYPE=0x%04x, OPCODE=%d",
 150                         ntohs(ah->ar_hrd), ntohs(ah->ar_pro),
 151                         ntohs(ah->ar_op));
 152 
 153                 /* If it's for Ethernet and the lengths are OK,
 154                  * then log the ARP payload
 155                  */
 156                 if (ah->ar_hrd == htons(1) &&
 157                     ah->ar_hln == ETH_ALEN &&
 158                     ah->ar_pln == sizeof(__be32)) {
 159                         const struct arppayload *ap;
 160                         struct arppayload _arpp;
 161 
 162                         ap = skb_header_pointer(skb, sizeof(_arph),
 163                                                 sizeof(_arpp), &_arpp);
 164                         if (ap == NULL) {
 165                                 pr_cont(" INCOMPLETE ARP payload");
 166                                 goto out;
 167                         }
 168                         pr_cont(" ARP MAC SRC=%pM ARP IP SRC=%pI4 ARP MAC DST=%pM ARP IP DST=%pI4",
 169                                 ap->mac_src, ap->ip_src,
 170                                 ap->mac_dst, ap->ip_dst);
 171                 }
 172         }
 173 out:
 174         pr_cont("\n");
 175         spin_unlock_bh(&ebt_log_lock);
 176 }
 177 
 178 static unsigned int
 179 ebt_log_tg(struct sk_buff *skb, const struct xt_action_param *par)
 180 {
 181         const struct ebt_log_info *info = par->targinfo;
 182         struct nf_loginfo li;
 183         struct net *net = xt_net(par);
 184 
 185         li.type = NF_LOG_TYPE_LOG;
 186         li.u.log.level = info->loglevel;
 187         li.u.log.logflags = info->bitmask;
 188 
 189         /* Remember that we have to use ebt_log_packet() not to break backward
 190          * compatibility. We cannot use the default bridge packet logger via
 191          * nf_log_packet() with NFT_LOG_TYPE_LOG here. --Pablo
 192          */
 193         if (info->bitmask & EBT_LOG_NFLOG)
 194                 nf_log_packet(net, NFPROTO_BRIDGE, xt_hooknum(par), skb,
 195                               xt_in(par), xt_out(par), &li, "%s",
 196                               info->prefix);
 197         else
 198                 ebt_log_packet(net, NFPROTO_BRIDGE, xt_hooknum(par), skb,
 199                                xt_in(par), xt_out(par), &li, info->prefix);
 200         return EBT_CONTINUE;
 201 }
 202 
 203 static struct xt_target ebt_log_tg_reg __read_mostly = {
 204         .name           = "log",
 205         .revision       = 0,
 206         .family         = NFPROTO_BRIDGE,
 207         .target         = ebt_log_tg,
 208         .checkentry     = ebt_log_tg_check,
 209         .targetsize     = sizeof(struct ebt_log_info),
 210         .me             = THIS_MODULE,
 211 };
 212 
 213 static int __init ebt_log_init(void)
 214 {
 215         return xt_register_target(&ebt_log_tg_reg);
 216 }
 217 
 218 static void __exit ebt_log_fini(void)
 219 {
 220         xt_unregister_target(&ebt_log_tg_reg);
 221 }
 222 
 223 module_init(ebt_log_init);
 224 module_exit(ebt_log_fini);
 225 MODULE_DESCRIPTION("Ebtables: Packet logging to syslog");
 226 MODULE_LICENSE("GPL");

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