linux/net/netfilter/nf_log_common.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/* (C) 1999-2001 Paul `Rusty' Russell
   3 * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
   4 */
   5
   6#include <linux/module.h>
   7#include <linux/spinlock.h>
   8#include <linux/skbuff.h>
   9#include <linux/if_arp.h>
  10#include <linux/ip.h>
  11#include <net/icmp.h>
  12#include <net/udp.h>
  13#include <net/tcp.h>
  14#include <net/route.h>
  15
  16#include <linux/netfilter.h>
  17#include <linux/netfilter_bridge.h>
  18#include <linux/netfilter/xt_LOG.h>
  19#include <net/netfilter/nf_log.h>
  20
  21int nf_log_dump_udp_header(struct nf_log_buf *m, const struct sk_buff *skb,
  22                           u8 proto, int fragment, unsigned int offset)
  23{
  24        struct udphdr _udph;
  25        const struct udphdr *uh;
  26
  27        if (proto == IPPROTO_UDP)
  28                /* Max length: 10 "PROTO=UDP "     */
  29                nf_log_buf_add(m, "PROTO=UDP ");
  30        else    /* Max length: 14 "PROTO=UDPLITE " */
  31                nf_log_buf_add(m, "PROTO=UDPLITE ");
  32
  33        if (fragment)
  34                goto out;
  35
  36        /* Max length: 25 "INCOMPLETE [65535 bytes] " */
  37        uh = skb_header_pointer(skb, offset, sizeof(_udph), &_udph);
  38        if (uh == NULL) {
  39                nf_log_buf_add(m, "INCOMPLETE [%u bytes] ", skb->len - offset);
  40
  41                return 1;
  42        }
  43
  44        /* Max length: 20 "SPT=65535 DPT=65535 " */
  45        nf_log_buf_add(m, "SPT=%u DPT=%u LEN=%u ",
  46                       ntohs(uh->source), ntohs(uh->dest), ntohs(uh->len));
  47
  48out:
  49        return 0;
  50}
  51EXPORT_SYMBOL_GPL(nf_log_dump_udp_header);
  52
  53int nf_log_dump_tcp_header(struct nf_log_buf *m, const struct sk_buff *skb,
  54                           u8 proto, int fragment, unsigned int offset,
  55                           unsigned int logflags)
  56{
  57        struct tcphdr _tcph;
  58        const struct tcphdr *th;
  59
  60        /* Max length: 10 "PROTO=TCP " */
  61        nf_log_buf_add(m, "PROTO=TCP ");
  62
  63        if (fragment)
  64                return 0;
  65
  66        /* Max length: 25 "INCOMPLETE [65535 bytes] " */
  67        th = skb_header_pointer(skb, offset, sizeof(_tcph), &_tcph);
  68        if (th == NULL) {
  69                nf_log_buf_add(m, "INCOMPLETE [%u bytes] ", skb->len - offset);
  70                return 1;
  71        }
  72
  73        /* Max length: 20 "SPT=65535 DPT=65535 " */
  74        nf_log_buf_add(m, "SPT=%u DPT=%u ",
  75                       ntohs(th->source), ntohs(th->dest));
  76        /* Max length: 30 "SEQ=4294967295 ACK=4294967295 " */
  77        if (logflags & NF_LOG_TCPSEQ) {
  78                nf_log_buf_add(m, "SEQ=%u ACK=%u ",
  79                               ntohl(th->seq), ntohl(th->ack_seq));
  80        }
  81
  82        /* Max length: 13 "WINDOW=65535 " */
  83        nf_log_buf_add(m, "WINDOW=%u ", ntohs(th->window));
  84        /* Max length: 9 "RES=0x3C " */
  85        nf_log_buf_add(m, "RES=0x%02x ", (u_int8_t)(ntohl(tcp_flag_word(th) &
  86                                            TCP_RESERVED_BITS) >> 22));
  87        /* Max length: 32 "CWR ECE URG ACK PSH RST SYN FIN " */
  88        if (th->cwr)
  89                nf_log_buf_add(m, "CWR ");
  90        if (th->ece)
  91                nf_log_buf_add(m, "ECE ");
  92        if (th->urg)
  93                nf_log_buf_add(m, "URG ");
  94        if (th->ack)
  95                nf_log_buf_add(m, "ACK ");
  96        if (th->psh)
  97                nf_log_buf_add(m, "PSH ");
  98        if (th->rst)
  99                nf_log_buf_add(m, "RST ");
 100        if (th->syn)
 101                nf_log_buf_add(m, "SYN ");
 102        if (th->fin)
 103                nf_log_buf_add(m, "FIN ");
 104        /* Max length: 11 "URGP=65535 " */
 105        nf_log_buf_add(m, "URGP=%u ", ntohs(th->urg_ptr));
 106
 107        if ((logflags & NF_LOG_TCPOPT) && th->doff*4 > sizeof(struct tcphdr)) {
 108                u_int8_t _opt[60 - sizeof(struct tcphdr)];
 109                const u_int8_t *op;
 110                unsigned int i;
 111                unsigned int optsize = th->doff*4 - sizeof(struct tcphdr);
 112
 113                op = skb_header_pointer(skb, offset + sizeof(struct tcphdr),
 114                                        optsize, _opt);
 115                if (op == NULL) {
 116                        nf_log_buf_add(m, "OPT (TRUNCATED)");
 117                        return 1;
 118                }
 119
 120                /* Max length: 127 "OPT (" 15*4*2chars ") " */
 121                nf_log_buf_add(m, "OPT (");
 122                for (i = 0; i < optsize; i++)
 123                        nf_log_buf_add(m, "%02X", op[i]);
 124
 125                nf_log_buf_add(m, ") ");
 126        }
 127
 128        return 0;
 129}
 130EXPORT_SYMBOL_GPL(nf_log_dump_tcp_header);
 131
 132void nf_log_dump_sk_uid_gid(struct net *net, struct nf_log_buf *m,
 133                            struct sock *sk)
 134{
 135        if (!sk || !sk_fullsock(sk) || !net_eq(net, sock_net(sk)))
 136                return;
 137
 138        read_lock_bh(&sk->sk_callback_lock);
 139        if (sk->sk_socket && sk->sk_socket->file) {
 140                const struct cred *cred = sk->sk_socket->file->f_cred;
 141                nf_log_buf_add(m, "UID=%u GID=%u ",
 142                        from_kuid_munged(&init_user_ns, cred->fsuid),
 143                        from_kgid_munged(&init_user_ns, cred->fsgid));
 144        }
 145        read_unlock_bh(&sk->sk_callback_lock);
 146}
 147EXPORT_SYMBOL_GPL(nf_log_dump_sk_uid_gid);
 148
 149void
 150nf_log_dump_packet_common(struct nf_log_buf *m, u_int8_t pf,
 151                          unsigned int hooknum, const struct sk_buff *skb,
 152                          const struct net_device *in,
 153                          const struct net_device *out,
 154                          const struct nf_loginfo *loginfo, const char *prefix)
 155{
 156        const struct net_device *physoutdev __maybe_unused;
 157        const struct net_device *physindev __maybe_unused;
 158
 159        nf_log_buf_add(m, KERN_SOH "%c%sIN=%s OUT=%s ",
 160               '0' + loginfo->u.log.level, prefix,
 161               in ? in->name : "",
 162               out ? out->name : "");
 163#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
 164        physindev = nf_bridge_get_physindev(skb);
 165        if (physindev && in != physindev)
 166                nf_log_buf_add(m, "PHYSIN=%s ", physindev->name);
 167        physoutdev = nf_bridge_get_physoutdev(skb);
 168        if (physoutdev && out != physoutdev)
 169                nf_log_buf_add(m, "PHYSOUT=%s ", physoutdev->name);
 170#endif
 171}
 172EXPORT_SYMBOL_GPL(nf_log_dump_packet_common);
 173
 174/* bridge and netdev logging families share this code. */
 175void nf_log_l2packet(struct net *net, u_int8_t pf,
 176                     __be16 protocol,
 177                     unsigned int hooknum,
 178                     const struct sk_buff *skb,
 179                     const struct net_device *in,
 180                     const struct net_device *out,
 181                     const struct nf_loginfo *loginfo,
 182                     const char *prefix)
 183{
 184        switch (protocol) {
 185        case htons(ETH_P_IP):
 186                nf_log_packet(net, NFPROTO_IPV4, hooknum, skb, in, out,
 187                              loginfo, "%s", prefix);
 188                break;
 189        case htons(ETH_P_IPV6):
 190                nf_log_packet(net, NFPROTO_IPV6, hooknum, skb, in, out,
 191                              loginfo, "%s", prefix);
 192                break;
 193        case htons(ETH_P_ARP):
 194        case htons(ETH_P_RARP):
 195                nf_log_packet(net, NFPROTO_ARP, hooknum, skb, in, out,
 196                              loginfo, "%s", prefix);
 197                break;
 198        }
 199}
 200EXPORT_SYMBOL_GPL(nf_log_l2packet);
 201
 202static int __init nf_log_common_init(void)
 203{
 204        return 0;
 205}
 206
 207static void __exit nf_log_common_exit(void) {}
 208
 209module_init(nf_log_common_init);
 210module_exit(nf_log_common_exit);
 211
 212MODULE_LICENSE("GPL");
 213