Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  *  ebt_log
0004  *
0005  *  Authors:
0006  *  Bart De Schuymer <bdschuym@pandora.be>
0007  *  Harald Welte <laforge@netfilter.org>
0008  *
0009  *  April, 2002
0010  *
0011  */
0012 #include <linux/module.h>
0013 #include <linux/ip.h>
0014 #include <linux/in.h>
0015 #include <linux/if_arp.h>
0016 #include <linux/spinlock.h>
0017 #include <net/netfilter/nf_log.h>
0018 #include <linux/ipv6.h>
0019 #include <net/ipv6.h>
0020 #include <linux/in6.h>
0021 #include <linux/netfilter/x_tables.h>
0022 #include <linux/netfilter_bridge/ebtables.h>
0023 #include <linux/netfilter_bridge/ebt_log.h>
0024 #include <linux/netfilter.h>
0025 
0026 static DEFINE_SPINLOCK(ebt_log_lock);
0027 
0028 static int ebt_log_tg_check(const struct xt_tgchk_param *par)
0029 {
0030     struct ebt_log_info *info = par->targinfo;
0031 
0032     if (info->bitmask & ~EBT_LOG_MASK)
0033         return -EINVAL;
0034     if (info->loglevel >= 8)
0035         return -EINVAL;
0036     info->prefix[EBT_LOG_PREFIX_SIZE - 1] = '\0';
0037     return 0;
0038 }
0039 
0040 struct tcpudphdr {
0041     __be16 src;
0042     __be16 dst;
0043 };
0044 
0045 struct arppayload {
0046     unsigned char mac_src[ETH_ALEN];
0047     unsigned char ip_src[4];
0048     unsigned char mac_dst[ETH_ALEN];
0049     unsigned char ip_dst[4];
0050 };
0051 
0052 static void
0053 print_ports(const struct sk_buff *skb, uint8_t protocol, int offset)
0054 {
0055     if (protocol == IPPROTO_TCP ||
0056         protocol == IPPROTO_UDP ||
0057         protocol == IPPROTO_UDPLITE ||
0058         protocol == IPPROTO_SCTP ||
0059         protocol == IPPROTO_DCCP) {
0060         const struct tcpudphdr *pptr;
0061         struct tcpudphdr _ports;
0062 
0063         pptr = skb_header_pointer(skb, offset,
0064                       sizeof(_ports), &_ports);
0065         if (pptr == NULL) {
0066             pr_cont(" INCOMPLETE TCP/UDP header");
0067             return;
0068         }
0069         pr_cont(" SPT=%u DPT=%u", ntohs(pptr->src), ntohs(pptr->dst));
0070     }
0071 }
0072 
0073 static void
0074 ebt_log_packet(struct net *net, u_int8_t pf, unsigned int hooknum,
0075            const struct sk_buff *skb, const struct net_device *in,
0076            const struct net_device *out, const struct nf_loginfo *loginfo,
0077            const char *prefix)
0078 {
0079     unsigned int bitmask;
0080 
0081     /* FIXME: Disabled from containers until syslog ns is supported */
0082     if (!net_eq(net, &init_net) && !sysctl_nf_log_all_netns)
0083         return;
0084 
0085     spin_lock_bh(&ebt_log_lock);
0086     printk(KERN_SOH "%c%s IN=%s OUT=%s MAC source = %pM MAC dest = %pM proto = 0x%04x",
0087            '0' + loginfo->u.log.level, prefix,
0088            in ? in->name : "", out ? out->name : "",
0089            eth_hdr(skb)->h_source, eth_hdr(skb)->h_dest,
0090            ntohs(eth_hdr(skb)->h_proto));
0091 
0092     if (loginfo->type == NF_LOG_TYPE_LOG)
0093         bitmask = loginfo->u.log.logflags;
0094     else
0095         bitmask = NF_LOG_DEFAULT_MASK;
0096 
0097     if ((bitmask & EBT_LOG_IP) && eth_hdr(skb)->h_proto ==
0098        htons(ETH_P_IP)) {
0099         const struct iphdr *ih;
0100         struct iphdr _iph;
0101 
0102         ih = skb_header_pointer(skb, 0, sizeof(_iph), &_iph);
0103         if (ih == NULL) {
0104             pr_cont(" INCOMPLETE IP header");
0105             goto out;
0106         }
0107         pr_cont(" IP SRC=%pI4 IP DST=%pI4, IP tos=0x%02X, IP proto=%d",
0108             &ih->saddr, &ih->daddr, ih->tos, ih->protocol);
0109         print_ports(skb, ih->protocol, ih->ihl*4);
0110         goto out;
0111     }
0112 
0113 #if IS_ENABLED(CONFIG_BRIDGE_EBT_IP6)
0114     if ((bitmask & EBT_LOG_IP6) && eth_hdr(skb)->h_proto ==
0115        htons(ETH_P_IPV6)) {
0116         const struct ipv6hdr *ih;
0117         struct ipv6hdr _iph;
0118         uint8_t nexthdr;
0119         __be16 frag_off;
0120         int offset_ph;
0121 
0122         ih = skb_header_pointer(skb, 0, sizeof(_iph), &_iph);
0123         if (ih == NULL) {
0124             pr_cont(" INCOMPLETE IPv6 header");
0125             goto out;
0126         }
0127         pr_cont(" IPv6 SRC=%pI6 IPv6 DST=%pI6, IPv6 priority=0x%01X, Next Header=%d",
0128             &ih->saddr, &ih->daddr, ih->priority, ih->nexthdr);
0129         nexthdr = ih->nexthdr;
0130         offset_ph = ipv6_skip_exthdr(skb, sizeof(_iph), &nexthdr, &frag_off);
0131         if (offset_ph == -1)
0132             goto out;
0133         print_ports(skb, nexthdr, offset_ph);
0134         goto out;
0135     }
0136 #endif
0137 
0138     if ((bitmask & EBT_LOG_ARP) &&
0139         ((eth_hdr(skb)->h_proto == htons(ETH_P_ARP)) ||
0140          (eth_hdr(skb)->h_proto == htons(ETH_P_RARP)))) {
0141         const struct arphdr *ah;
0142         struct arphdr _arph;
0143 
0144         ah = skb_header_pointer(skb, 0, sizeof(_arph), &_arph);
0145         if (ah == NULL) {
0146             pr_cont(" INCOMPLETE ARP header");
0147             goto out;
0148         }
0149         pr_cont(" ARP HTYPE=%d, PTYPE=0x%04x, OPCODE=%d",
0150             ntohs(ah->ar_hrd), ntohs(ah->ar_pro),
0151             ntohs(ah->ar_op));
0152 
0153         /* If it's for Ethernet and the lengths are OK,
0154          * then log the ARP payload
0155          */
0156         if (ah->ar_hrd == htons(1) &&
0157             ah->ar_hln == ETH_ALEN &&
0158             ah->ar_pln == sizeof(__be32)) {
0159             const struct arppayload *ap;
0160             struct arppayload _arpp;
0161 
0162             ap = skb_header_pointer(skb, sizeof(_arph),
0163                         sizeof(_arpp), &_arpp);
0164             if (ap == NULL) {
0165                 pr_cont(" INCOMPLETE ARP payload");
0166                 goto out;
0167             }
0168             pr_cont(" ARP MAC SRC=%pM ARP IP SRC=%pI4 ARP MAC DST=%pM ARP IP DST=%pI4",
0169                 ap->mac_src, ap->ip_src,
0170                 ap->mac_dst, ap->ip_dst);
0171         }
0172     }
0173 out:
0174     pr_cont("\n");
0175     spin_unlock_bh(&ebt_log_lock);
0176 }
0177 
0178 static unsigned int
0179 ebt_log_tg(struct sk_buff *skb, const struct xt_action_param *par)
0180 {
0181     const struct ebt_log_info *info = par->targinfo;
0182     struct nf_loginfo li;
0183     struct net *net = xt_net(par);
0184 
0185     li.type = NF_LOG_TYPE_LOG;
0186     li.u.log.level = info->loglevel;
0187     li.u.log.logflags = info->bitmask;
0188 
0189     /* Remember that we have to use ebt_log_packet() not to break backward
0190      * compatibility. We cannot use the default bridge packet logger via
0191      * nf_log_packet() with NFT_LOG_TYPE_LOG here. --Pablo
0192      */
0193     if (info->bitmask & EBT_LOG_NFLOG)
0194         nf_log_packet(net, NFPROTO_BRIDGE, xt_hooknum(par), skb,
0195                   xt_in(par), xt_out(par), &li, "%s",
0196                   info->prefix);
0197     else
0198         ebt_log_packet(net, NFPROTO_BRIDGE, xt_hooknum(par), skb,
0199                    xt_in(par), xt_out(par), &li, info->prefix);
0200     return EBT_CONTINUE;
0201 }
0202 
0203 static struct xt_target ebt_log_tg_reg __read_mostly = {
0204     .name       = "log",
0205     .revision   = 0,
0206     .family     = NFPROTO_BRIDGE,
0207     .target     = ebt_log_tg,
0208     .checkentry = ebt_log_tg_check,
0209     .targetsize = sizeof(struct ebt_log_info),
0210     .me     = THIS_MODULE,
0211 };
0212 
0213 static int __init ebt_log_init(void)
0214 {
0215     return xt_register_target(&ebt_log_tg_reg);
0216 }
0217 
0218 static void __exit ebt_log_fini(void)
0219 {
0220     xt_unregister_target(&ebt_log_tg_reg);
0221 }
0222 
0223 module_init(ebt_log_init);
0224 module_exit(ebt_log_fini);
0225 MODULE_DESCRIPTION("Ebtables: Packet logging to syslog");
0226 MODULE_LICENSE("GPL");