* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
-
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h>
+#include <linux/syslog.h>
#include <linux/spinlock.h>
#include <linux/skbuff.h>
#include <linux/ip.h>
#include <linux/netfilter.h>
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter_ipv4/ipt_LOG.h>
+#include <net/netfilter/nf_log.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
-MODULE_DESCRIPTION("iptables syslog logging module");
-
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
+MODULE_DESCRIPTION("Xtables: IPv4 packet logging to syslog");
/* Use lock to serialize, so printks don't overlap */
static DEFINE_SPINLOCK(log_lock);
const struct sk_buff *skb,
unsigned int iphoff)
{
- struct iphdr _iph, *ih;
+ struct iphdr _iph;
+ const struct iphdr *ih;
unsigned int logflags;
if (info->type == NF_LOG_TYPE_LOG)
/* Important fields:
* TOS, len, DF/MF, fragment offset, TTL, src, dst, options. */
/* Max length: 40 "SRC=255.255.255.255 DST=255.255.255.255 " */
- printk("SRC=%u.%u.%u.%u DST=%u.%u.%u.%u ",
- NIPQUAD(ih->saddr), NIPQUAD(ih->daddr));
+ printk("SRC=%pI4 DST=%pI4 ",
+ &ih->saddr, &ih->daddr);
/* Max length: 46 "LEN=65535 TOS=0xFF PREC=0xFF TTL=255 ID=65535 " */
printk("LEN=%u TOS=0x%02X PREC=0x%02X TTL=%u ID=%u ",
if (ntohs(ih->frag_off) & IP_OFFSET)
printk("FRAG:%u ", ntohs(ih->frag_off) & IP_OFFSET);
- if ((logflags & IPT_LOG_IPOPT)
- && ih->ihl * 4 > sizeof(struct iphdr)) {
- unsigned char _opt[4 * 15 - sizeof(struct iphdr)], *op;
+ if ((logflags & IPT_LOG_IPOPT) &&
+ ih->ihl * 4 > sizeof(struct iphdr)) {
+ const unsigned char *op;
+ unsigned char _opt[4 * 15 - sizeof(struct iphdr)];
unsigned int i, optsize;
optsize = ih->ihl * 4 - sizeof(struct iphdr);
switch (ih->protocol) {
case IPPROTO_TCP: {
- struct tcphdr _tcph, *th;
+ struct tcphdr _tcph;
+ const struct tcphdr *th;
/* Max length: 10 "PROTO=TCP " */
printk("PROTO=TCP ");
/* Max length: 11 "URGP=65535 " */
printk("URGP=%u ", ntohs(th->urg_ptr));
- if ((logflags & IPT_LOG_TCPOPT)
- && th->doff * 4 > sizeof(struct tcphdr)) {
+ if ((logflags & IPT_LOG_TCPOPT) &&
+ th->doff * 4 > sizeof(struct tcphdr)) {
unsigned char _opt[4 * 15 - sizeof(struct tcphdr)];
- unsigned char *op;
+ const unsigned char *op;
unsigned int i, optsize;
optsize = th->doff * 4 - sizeof(struct tcphdr);
}
case IPPROTO_UDP:
case IPPROTO_UDPLITE: {
- struct udphdr _udph, *uh;
+ struct udphdr _udph;
+ const struct udphdr *uh;
if (ih->protocol == IPPROTO_UDP)
/* Max length: 10 "PROTO=UDP " */
break;
}
case IPPROTO_ICMP: {
- struct icmphdr _icmph, *ich;
+ struct icmphdr _icmph;
+ const struct icmphdr *ich;
static const size_t required_len[NR_ICMP_TYPES+1]
= { [ICMP_ECHOREPLY] = 4,
[ICMP_DEST_UNREACH]
printk("TYPE=%u CODE=%u ", ich->type, ich->code);
/* Max length: 25 "INCOMPLETE [65535 bytes] " */
- if (ich->type <= NR_ICMP_TYPES
- && required_len[ich->type]
- && skb->len-iphoff-ih->ihl*4 < required_len[ich->type]) {
+ if (ich->type <= NR_ICMP_TYPES &&
+ required_len[ich->type] &&
+ skb->len-iphoff-ih->ihl*4 < required_len[ich->type]) {
printk("INCOMPLETE [%u bytes] ",
skb->len - iphoff - ih->ihl*4);
break;
break;
case ICMP_REDIRECT:
/* Max length: 24 "GATEWAY=255.255.255.255 " */
- printk("GATEWAY=%u.%u.%u.%u ",
- NIPQUAD(ich->un.gateway));
+ printk("GATEWAY=%pI4 ", &ich->un.gateway);
/* Fall through */
case ICMP_DEST_UNREACH:
case ICMP_SOURCE_QUENCH:
}
/* Max length: 10 "MTU=65535 " */
- if (ich->type == ICMP_DEST_UNREACH
- && ich->code == ICMP_FRAG_NEEDED)
+ if (ich->type == ICMP_DEST_UNREACH &&
+ ich->code == ICMP_FRAG_NEEDED)
printk("MTU=%u ", ntohs(ich->un.frag.mtu));
}
break;
}
/* Max Length */
case IPPROTO_AH: {
- struct ip_auth_hdr _ahdr, *ah;
+ struct ip_auth_hdr _ahdr;
+ const struct ip_auth_hdr *ah;
if (ntohs(ih->frag_off) & IP_OFFSET)
break;
break;
}
case IPPROTO_ESP: {
- struct ip_esp_hdr _esph, *eh;
+ struct ip_esp_hdr _esph;
+ const struct ip_esp_hdr *eh;
/* Max length: 10 "PROTO=ESP " */
printk("PROTO=ESP ");
if ((logflags & IPT_LOG_UID) && !iphoff && skb->sk) {
read_lock_bh(&skb->sk->sk_callback_lock);
if (skb->sk->sk_socket && skb->sk->sk_socket->file)
- printk("UID=%u ", skb->sk->sk_socket->file->f_uid);
+ printk("UID=%u GID=%u ",
+ skb->sk->sk_socket->file->f_cred->fsuid,
+ skb->sk->sk_socket->file->f_cred->fsgid);
read_unlock_bh(&skb->sk->sk_callback_lock);
}
+ /* Max length: 16 "MARK=0xFFFFFFFF " */
+ if (!iphoff && skb->mark)
+ printk("MARK=0x%x ", skb->mark);
+
/* Proto Max log string length */
/* IP: 40+46+6+11+127 = 230 */
/* TCP: 10+max(25,20+30+13+9+32+11+127) = 252 */
.type = NF_LOG_TYPE_LOG,
.u = {
.log = {
- .level = 0,
+ .level = 5,
.logflags = NF_LOG_MASK,
},
},
};
static void
-ipt_log_packet(unsigned int pf,
+ipt_log_packet(u_int8_t pf,
unsigned int hooknum,
const struct sk_buff *skb,
const struct net_device *in,
const struct nf_loginfo *loginfo,
const char *prefix)
{
+ register struct syslog_ns *syslog_ns;
+
+
+ syslog_ns = (struct syslog_ns *)0;
+ if (skb->dev) /*another syslog_ns possible? */
+ syslog_ns = skb->dev->syslog_ns;
+ syslog_ns = switch_syslog_ns(syslog_ns);
+
if (!loginfo)
loginfo = &default_loginfo;
out ? out->name : "");
#ifdef CONFIG_BRIDGE_NETFILTER
if (skb->nf_bridge) {
- struct net_device *physindev = skb->nf_bridge->physindev;
- struct net_device *physoutdev = skb->nf_bridge->physoutdev;
+ const struct net_device *physindev;
+ const struct net_device *physoutdev;
+ physindev = skb->nf_bridge->physindev;
if (physindev && in != physindev)
printk("PHYSIN=%s ", physindev->name);
+ physoutdev = skb->nf_bridge->physoutdev;
if (physoutdev && out != physoutdev)
printk("PHYSOUT=%s ", physoutdev->name);
}
if (in && !out) {
/* MAC logging for input chain only. */
printk("MAC=");
- if (skb->dev && skb->dev->hard_header_len
- && skb->mac.raw != (void*)skb->nh.iph) {
+ if (skb->dev && skb->dev->hard_header_len &&
+ skb->mac_header != skb->network_header) {
int i;
- unsigned char *p = skb->mac.raw;
+ const unsigned char *p = skb_mac_header(skb);
for (i = 0; i < skb->dev->hard_header_len; i++,p++)
printk("%02x%c", *p,
i==skb->dev->hard_header_len - 1
dump_packet(loginfo, skb, 0);
printk("\n");
spin_unlock_bh(&log_lock);
+ (void) switch_syslog_ns(syslog_ns);
}
static unsigned int
-ipt_log_target(struct sk_buff **pskb,
- const struct net_device *in,
- const struct net_device *out,
- unsigned int hooknum,
- const struct xt_target *target,
- const void *targinfo)
+log_tg(struct sk_buff *skb, const struct xt_action_param *par)
{
- const struct ipt_log_info *loginfo = targinfo;
+ const struct ipt_log_info *loginfo = par->targinfo;
struct nf_loginfo li;
li.type = NF_LOG_TYPE_LOG;
li.u.log.level = loginfo->level;
li.u.log.logflags = loginfo->logflags;
- ipt_log_packet(PF_INET, hooknum, *pskb, in, out, &li,
+ ipt_log_packet(NFPROTO_IPV4, par->hooknum, skb, par->in, par->out, &li,
loginfo->prefix);
return XT_CONTINUE;
}
-static int ipt_log_checkentry(const char *tablename,
- const void *e,
- const struct xt_target *target,
- void *targinfo,
- unsigned int hook_mask)
+static int log_tg_check(const struct xt_tgchk_param *par)
{
- const struct ipt_log_info *loginfo = targinfo;
+ const struct ipt_log_info *loginfo = par->targinfo;
if (loginfo->level >= 8) {
- DEBUGP("LOG: level %u >= 8\n", loginfo->level);
- return 0;
+ pr_debug("level %u >= 8\n", loginfo->level);
+ return -EINVAL;
}
if (loginfo->prefix[sizeof(loginfo->prefix)-1] != '\0') {
- DEBUGP("LOG: prefix term %i\n",
- loginfo->prefix[sizeof(loginfo->prefix)-1]);
- return 0;
+ pr_debug("prefix is not null-terminated\n");
+ return -EINVAL;
}
- return 1;
+ return 0;
}
-static struct xt_target ipt_log_reg = {
+static struct xt_target log_tg_reg __read_mostly = {
.name = "LOG",
- .family = AF_INET,
- .target = ipt_log_target,
+ .family = NFPROTO_IPV4,
+ .target = log_tg,
.targetsize = sizeof(struct ipt_log_info),
- .checkentry = ipt_log_checkentry,
+ .checkentry = log_tg_check,
.me = THIS_MODULE,
};
-static struct nf_logger ipt_log_logger ={
+static struct nf_logger ipt_log_logger __read_mostly = {
.name = "ipt_LOG",
.logfn = &ipt_log_packet,
.me = THIS_MODULE,
};
-static int __init ipt_log_init(void)
+static int __init log_tg_init(void)
{
int ret;
- ret = xt_register_target(&ipt_log_reg);
+ ret = xt_register_target(&log_tg_reg);
if (ret < 0)
return ret;
- if (nf_log_register(PF_INET, &ipt_log_logger) < 0) {
- printk(KERN_WARNING "ipt_LOG: not logging via system console "
- "since somebody else already registered for PF_INET\n");
- /* we cannot make module load fail here, since otherwise
- * iptables userspace would abort */
- }
-
+ nf_log_register(NFPROTO_IPV4, &ipt_log_logger);
return 0;
}
-static void __exit ipt_log_fini(void)
+static void __exit log_tg_exit(void)
{
nf_log_unregister(&ipt_log_logger);
- xt_unregister_target(&ipt_log_reg);
+ xt_unregister_target(&log_tg_reg);
}
-module_init(ipt_log_init);
-module_exit(ipt_log_fini);
+module_init(log_tg_init);
+module_exit(log_tg_exit);