diff -Nur linux-2.4.32-orig/include/linux/netfilter_ipv4/ip_logging.h linux-2.4.32-pab2/include/linux/netfilter_ipv4/ip_logging.h --- linux-2.4.32-orig/include/linux/netfilter_ipv4/ip_logging.h 1970-01-01 01:00:00 +0100 +++ linux-2.4.32-pab2/include/linux/netfilter_ipv4/ip_logging.h 2005-10-27 17:17:54 +0200 @@ -0,0 +1,20 @@ +/* IPv4 macros for the internal logging interface. */ +#ifndef __IP_LOGGING_H +#define __IP_LOGGING_H + +#ifdef __KERNEL__ +#include +#include + +#define nf_log_ip_packet(pskb,hooknum,in,out,fmt,args...) \ + nf_log_packet(AF_INET,pskb,hooknum,in,out,fmt,##args) + +#define nf_log_ip(pfh,len,fmt,args...) \ + nf_log(AF_INET,pfh,len,fmt,##args) + +#define nf_ip_log_register(logging) nf_log_register(AF_INET,logging) +#define nf_ip_log_unregister(logging) nf_log_unregister(AF_INET,logging) + +#endif /*__KERNEL__*/ + +#endif /*__IP_LOGGING_H*/ diff -Nur linux-2.4.32-orig/include/linux/netfilter_ipv4/ipt_ULOG.h linux-2.4.32-pab2/include/linux/netfilter_ipv4/ipt_ULOG.h --- linux-2.4.32-orig/include/linux/netfilter_ipv4/ipt_ULOG.h 2002-02-25 20:38:13 +0100 +++ linux-2.4.32-pab2/include/linux/netfilter_ipv4/ipt_ULOG.h 2005-10-27 17:17:54 +0200 @@ -11,6 +11,9 @@ #define NETLINK_NFLOG 5 #endif +#define NFLOG_DEFAULT_NLGROUP 1 +#define NFLOG_DEFAULT_QTHRESHOLD 1 + #define ULOG_MAC_LEN 80 #define ULOG_PREFIX_LEN 32 diff -Nur linux-2.4.32-orig/include/linux/netfilter_ipv6/ip6_logging.h linux-2.4.32-pab2/include/linux/netfilter_ipv6/ip6_logging.h --- linux-2.4.32-orig/include/linux/netfilter_ipv6/ip6_logging.h 1970-01-01 01:00:00 +0100 +++ linux-2.4.32-pab2/include/linux/netfilter_ipv6/ip6_logging.h 2005-10-27 17:17:54 +0200 @@ -0,0 +1,20 @@ +/* IPv6 macros for the nternal logging interface. */ +#ifndef __IP6_LOGGING_H +#define __IP6_LOGGING_H + +#ifdef __KERNEL__ +#include +#include + +#define nf_log_ip6_packet(pskb,hooknum,in,out,fmt,args...) \ + nf_log_packet(AF_INET6,pskb,hooknum,in,out,fmt,##args) + +#define nf_log_ip6(pfh,len,fmt,args...) \ + nf_log(AF_INET6,pfh,len,fmt,##args) + +#define nf_ip6_log_register(logging) nf_log_register(AF_INET6,logging) +#define nf_ip6_log_unregister(logging) nf_log_unregister(AF_INET6,logging) + +#endif /*__KERNEL__*/ + +#endif /*__IP6_LOGGING_H*/ diff -Nur linux-2.4.32-orig/include/linux/netfilter_logging.h linux-2.4.32-pab2/include/linux/netfilter_logging.h --- linux-2.4.32-orig/include/linux/netfilter_logging.h 1970-01-01 01:00:00 +0100 +++ linux-2.4.32-pab2/include/linux/netfilter_logging.h 2005-10-27 17:17:54 +0200 @@ -0,0 +1,33 @@ +/* Internal logging interface, which relies on the real + LOG target modules */ +#ifndef __LINUX_NETFILTER_LOGGING_H +#define __LINUX_NETFILTER_LOGGING_H + +#ifdef __KERNEL__ +#include + +struct nf_logging_t { + void (*nf_log_packet)(struct sk_buff **pskb, + unsigned int hooknum, + const struct net_device *in, + const struct net_device *out, + const char *prefix); + void (*nf_log)(char *pfh, size_t len, + const char *prefix); +}; + +extern void nf_log_register(int pf, const struct nf_logging_t *logging); +extern void nf_log_unregister(int pf, const struct nf_logging_t *logging); + +extern void nf_log_packet(int pf, + struct sk_buff **pskb, + unsigned int hooknum, + const struct net_device *in, + const struct net_device *out, + const char *fmt, ...); +extern void nf_log(int pf, + char *pfh, size_t len, + const char *fmt, ...); +#endif /*__KERNEL__*/ + +#endif /*__LINUX_NETFILTER_LOGGING_H*/ diff -Nur linux-2.4.32-orig/net/core/netfilter.c linux-2.4.32-pab2/net/core/netfilter.c --- linux-2.4.32-orig/net/core/netfilter.c 2005-01-19 15:10:13 +0100 +++ linux-2.4.32-pab2/net/core/netfilter.c 2005-10-27 17:17:54 +0200 @@ -8,9 +8,12 @@ * * February 2000: Modified by James Morris to have 1 queue per protocol. * 15-Mar-2000: Added NF_REPEAT --RR. + * 08-May-2003: Internal logging interface added by Jozsef Kadlecsik. */ #include +#include #include +#include #include #include #include @@ -622,6 +625,75 @@ } #endif /*CONFIG_INET*/ +/* Internal logging interface, which relies on the real + LOG target modules */ + +#define NF_LOG_PREFIXLEN 128 + +static struct nf_logging_t nf_logging[NPROTO] = {}; +static int reported = 0; + +void nf_log_register(int pf, const struct nf_logging_t *logging) +{ + br_write_lock_bh(BR_NETPROTO_LOCK); + if (!nf_logging[pf].nf_log_packet) { + nf_logging[pf].nf_log_packet = logging->nf_log_packet; + nf_logging[pf].nf_log = logging->nf_log; + } + br_write_unlock_bh(BR_NETPROTO_LOCK); +} + +void nf_log_unregister(int pf, const struct nf_logging_t *logging) +{ + br_write_lock_bh(BR_NETPROTO_LOCK); + if (nf_logging[pf].nf_log_packet == logging->nf_log_packet) { + nf_logging[pf].nf_log_packet = NULL; + nf_logging[pf].nf_log = NULL; + } + br_write_unlock_bh(BR_NETPROTO_LOCK); +} + +void nf_log_packet(int pf, + struct sk_buff **pskb, + unsigned int hooknum, + const struct net_device *in, + const struct net_device *out, + const char *fmt, ...) +{ + va_list args; + char prefix[NF_LOG_PREFIXLEN]; + + if (nf_logging[pf].nf_log_packet) { + va_start(args, fmt); + vsnprintf(prefix, sizeof(prefix), fmt, args); + va_end(args); + nf_logging[pf].nf_log_packet(pskb, hooknum, in, out, prefix); + } else if (!reported) { + printk(KERN_WARNING "nf_log_packet: can\'t log yet, " + "no backend logging module loaded in!\n"); + reported++; + } +} + +void nf_log(int pf, + char *pfh, size_t len, + const char *fmt, ...) +{ + va_list args; + char prefix[NF_LOG_PREFIXLEN]; + + if (nf_logging[pf].nf_log) { + va_start(args, fmt); + vsnprintf(prefix, sizeof(prefix), fmt, args); + va_end(args); + nf_logging[pf].nf_log(pfh, len, prefix); + } else if (!reported) { + printk(KERN_WARNING "nf_log: can\'t log yet, " + "no backend logging module loaded in!\n"); + reported++; + } +} + /* This does not belong here, but locally generated errors need it if connection tracking in use: without this, connection may not be in hash table, and hence manufactured ICMP or RST packets will not be associated with it. */ diff -Nur linux-2.4.32-orig/net/ipv4/netfilter/ipt_LOG.c linux-2.4.32-pab2/net/ipv4/netfilter/ipt_LOG.c --- linux-2.4.32-orig/net/ipv4/netfilter/ipt_LOG.c 2005-04-04 03:42:20 +0200 +++ linux-2.4.32-pab2/net/ipv4/netfilter/ipt_LOG.c 2005-10-27 17:17:54 +0200 @@ -10,9 +10,14 @@ #include #include +#include #include #include +static unsigned int nflog = 1; +MODULE_PARM(nflog, "i"); +MODULE_PARM_DESC(nflog, "register as internal netfilter logging module"); + #if 0 #define DEBUGP printk #else @@ -298,23 +303,21 @@ /* maxlen = 230+ 91 + 230 + 252 = 803 */ } -static unsigned int -ipt_log_target(struct sk_buff **pskb, +static void +ipt_log_packet(struct sk_buff **pskb, unsigned int hooknum, const struct net_device *in, const struct net_device *out, - const void *targinfo, - void *userinfo) + const struct ipt_log_info *loginfo, + const char *level_string, + const char *prefix) { struct iphdr *iph = (*pskb)->nh.iph; - const struct ipt_log_info *loginfo = targinfo; - char level_string[4] = "< >"; - level_string[1] = '0' + (loginfo->level % 8); spin_lock_bh(&log_lock); printk(level_string); printk("%sIN=%s OUT=%s ", - loginfo->prefix, + prefix == NULL ? loginfo->prefix : prefix, in ? in->name : "", out ? out->name : ""); if (in && !out) { @@ -334,10 +337,59 @@ dump_packet(loginfo, iph, (*pskb)->len, 1); printk("\n"); spin_unlock_bh(&log_lock); +} + +static unsigned int +ipt_log_target(struct sk_buff **pskb, + unsigned int hooknum, + const struct net_device *in, + const struct net_device *out, + const void *targinfo, + void *userinfo) +{ + const struct ipt_log_info *loginfo = targinfo; + char level_string[4] = "< >"; + + level_string[1] = '0' + (loginfo->level % 8); + ipt_log_packet(pskb, hooknum, in, out, loginfo, level_string, NULL); return IPT_CONTINUE; } +static void +ip_log_packet_fn(struct sk_buff **pskb, + unsigned int hooknum, + const struct net_device *in, + const struct net_device *out, + const char *prefix) +{ + struct ipt_log_info loginfo = { + .level = 0, + .logflags = IPT_LOG_MASK, + .prefix = "" + }; + + ipt_log_packet(pskb, hooknum, in, out, &loginfo, KERN_WARNING, prefix); +} + +static void +ip_log_fn(char *pfh, size_t len, + const char *prefix) +{ + struct iphdr *iph = (struct iphdr *)pfh; + struct ipt_log_info loginfo = { + .level = 0, + .logflags = IPT_LOG_MASK, + .prefix = "", + }; + + spin_lock_bh(&log_lock); + printk(KERN_WARNING "%s", prefix); + dump_packet(&loginfo, iph, len, 1); + printk("\n"); + spin_unlock_bh(&log_lock); +} + static int ipt_log_checkentry(const char *tablename, const struct ipt_entry *e, void *targinfo, @@ -369,17 +421,23 @@ static struct ipt_target ipt_log_reg = { { NULL, NULL }, "LOG", ipt_log_target, ipt_log_checkentry, NULL, THIS_MODULE }; +static struct nf_logging_t ip_logging_fn += { ip_log_packet_fn, ip_log_fn }; static int __init init(void) { if (ipt_register_target(&ipt_log_reg)) return -EINVAL; - + if (nflog) + nf_log_register(PF_INET, &ip_logging_fn); + return 0; } static void __exit fini(void) { + if (nflog) + nf_log_unregister(PF_INET, &ip_logging_fn); ipt_unregister_target(&ipt_log_reg); } diff -Nur linux-2.4.32-orig/net/ipv4/netfilter/ipt_ULOG.c linux-2.4.32-pab2/net/ipv4/netfilter/ipt_ULOG.c --- linux-2.4.32-orig/net/ipv4/netfilter/ipt_ULOG.c 2004-11-17 12:54:22 +0100 +++ linux-2.4.32-pab2/net/ipv4/netfilter/ipt_ULOG.c 2005-10-27 17:17:54 +0200 @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -79,6 +80,10 @@ MODULE_PARM(flushtimeout, "i"); MODULE_PARM_DESC(flushtimeout, "buffer flush timeout"); +static unsigned int nflog = 1; +MODULE_PARM(nflog, "i"); +MODULE_PARM_DESC(nflog, "register as internal netfilter logging module"); + /* global data structures */ typedef struct { @@ -155,17 +160,17 @@ return skb; } -static unsigned int ipt_ulog_target(struct sk_buff **pskb, - unsigned int hooknum, - const struct net_device *in, - const struct net_device *out, - const void *targinfo, void *userinfo) +static void ipt_ulog_packet(struct sk_buff **pskb, + unsigned int hooknum, + const struct net_device *in, + const struct net_device *out, + const struct ipt_ulog_info *loginfo, + const char *prefix) { ulog_buff_t *ub; ulog_packet_msg_t *pm; size_t size, copy_len; struct nlmsghdr *nlh; - struct ipt_ulog_info *loginfo = (struct ipt_ulog_info *) targinfo; /* ffs == find first bit set, necessary because userspace * is already shifting groupnumber, but we need unshifted. @@ -216,7 +221,9 @@ pm->timestamp_usec = (*pskb)->stamp.tv_usec; pm->mark = (*pskb)->nfmark; pm->hook = hooknum; - if (loginfo->prefix[0] != '\0') + if (prefix != NULL) + strncpy(pm->prefix, prefix, sizeof(pm->prefix)); + else if (loginfo->prefix[0] != '\0') strncpy(pm->prefix, loginfo->prefix, sizeof(pm->prefix)); else *(pm->prefix) = '\0'; @@ -264,8 +271,7 @@ UNLOCK_BH(&ulog_lock); - return IPT_CONTINUE; - + return; nlmsg_failure: PRINTR("ipt_ULOG: error during NLMSG_PUT\n"); @@ -274,8 +280,128 @@ PRINTR("ipt_ULOG: Error building netlink message\n"); UNLOCK_BH(&ulog_lock); +} + +static unsigned int ipt_ulog_target(struct sk_buff **pskb, + unsigned int hooknum, + const struct net_device *in, + const struct net_device *out, + const void *targinfo, void *userinfo) +{ + struct ipt_ulog_info *loginfo = (struct ipt_ulog_info *) targinfo; - return IPT_CONTINUE; + ipt_ulog_packet(pskb, hooknum, in, out, loginfo, NULL); + + return IPT_CONTINUE; +} + +static void ip_ulog_packet_fn(struct sk_buff **pskb, + unsigned int hooknum, + const struct net_device *in, + const struct net_device *out, + const char *prefix) +{ + struct ipt_ulog_info loginfo = { + .nl_group = NFLOG_DEFAULT_NLGROUP, + .copy_range = 0, + .qthreshold = NFLOG_DEFAULT_QTHRESHOLD, + .prefix = "" + }; + + ipt_ulog_packet(pskb, hooknum, in, out, &loginfo, prefix); +} + +static void ip_ulog_fn(char *pfh, size_t len, + const char *prefix) +{ + struct ipt_ulog_info loginfo = { + .nl_group = NFLOG_DEFAULT_NLGROUP, + .copy_range = 0, + .qthreshold = NFLOG_DEFAULT_QTHRESHOLD, + .prefix = "" + }; + ulog_buff_t *ub; + ulog_packet_msg_t *pm; + size_t size; + struct nlmsghdr *nlh; + + /* ffs == find first bit set, necessary because userspace + * is already shifting groupnumber, but we need unshifted. + * ffs() returns [1..32], we need [0..31] */ + unsigned int groupnum = ffs(loginfo.nl_group) - 1; + + size = NLMSG_SPACE(sizeof(*pm) + len); + + ub = &ulog_buffers[groupnum]; + + LOCK_BH(&ulog_lock); + + if (!ub->skb) { + if (!(ub->skb = ulog_alloc_skb(size))) + goto alloc_failure; + } else if (ub->qlen >= loginfo.qthreshold || + size > skb_tailroom(ub->skb)) { + /* either the queue len is too high or we don't have + * enough room in nlskb left. send it to userspace. */ + + ulog_send(groupnum); + + if (!(ub->skb = ulog_alloc_skb(size))) + goto alloc_failure; + } + + DEBUGP("ipt_ULOG: qlen %d, qthreshold %d\n", ub->qlen, + loginfo.qthreshold); + + /* NLMSG_PUT contains a hidden goto nlmsg_failure !!! */ + nlh = NLMSG_PUT(ub->skb, 0, ub->qlen, ULOG_NL_EVENT, + size - sizeof(*nlh)); + ub->qlen++; + + pm = NLMSG_DATA(nlh); + + /* Set fake hook, prefix, timestamp etc. */ + pm->data_len = len; + pm->timestamp_sec = 0; + pm->timestamp_usec = 0; + pm->mark = 0; + pm->hook = 0; + strncpy(pm->prefix, prefix, sizeof(pm->prefix)); + pm->mac_len = 0; + pm->indev_name[0] = '\0'; + pm->outdev_name[0] = '\0'; + memcpy(pm->payload, pfh, len); + + /* check if we are building multi-part messages */ + if (ub->qlen > 1) { + ub->lastnlh->nlmsg_flags |= NLM_F_MULTI; + } + + /* if threshold is reached, send message to userspace */ + if (ub->qlen >= loginfo.qthreshold) { + if (loginfo.qthreshold > 1) + nlh->nlmsg_type = NLMSG_DONE; + } + + ub->lastnlh = nlh; + + /* if timer isn't already running, start it */ + if (!timer_pending(&ub->timer)) { + ub->timer.expires = jiffies + flushtimeout; + add_timer(&ub->timer); + } + + UNLOCK_BH(&ulog_lock); + + return; + +nlmsg_failure: + PRINTR("ipt_ULOG: error during NLMSG_PUT\n"); + +alloc_failure: + PRINTR("ipt_ULOG: Error building netlink message\n"); + + UNLOCK_BH(&ulog_lock); } static int ipt_ulog_checkentry(const char *tablename, @@ -310,6 +436,8 @@ { {NULL, NULL}, "ULOG", ipt_ulog_target, ipt_ulog_checkentry, NULL, THIS_MODULE }; +static struct nf_logging_t ip_logging_fn += { ip_ulog_packet_fn, ip_ulog_fn }; static int __init init(void) { @@ -337,7 +465,9 @@ sock_release(nflognl->socket); return -EINVAL; } - + if (nflog) + nf_log_register(PF_INET, &ip_logging_fn); + return 0; } @@ -348,6 +478,8 @@ DEBUGP("ipt_ULOG: cleanup_module\n"); + if (nflog) + nf_log_unregister(PF_INET, &ip_logging_fn); ipt_unregister_target(&ipt_ulog_reg); sock_release(nflognl->socket); diff -Nur linux-2.4.32-orig/net/ipv6/netfilter/ip6t_LOG.c linux-2.4.32-pab2/net/ipv6/netfilter/ip6t_LOG.c --- linux-2.4.32-orig/net/ipv6/netfilter/ip6t_LOG.c 2005-10-27 17:17:10 +0200 +++ linux-2.4.32-pab2/net/ipv6/netfilter/ip6t_LOG.c 2005-10-27 17:17:54 +0200 @@ -9,6 +9,7 @@ #include #include #include +#include #include MODULE_AUTHOR("Jan Rekorajski "); @@ -355,22 +356,19 @@ } } -static unsigned int -ip6t_log_target(struct sk_buff **pskb, +static void +ip6t_log_packet(struct sk_buff **pskb, unsigned int hooknum, const struct net_device *in, const struct net_device *out, - const void *targinfo, - void *userinfo) + const struct ip6t_log_info *loginfo, + const char *level_string, + const char *prefix) { - const struct ip6t_log_info *loginfo = targinfo; - char level_string[4] = "< >"; - - level_string[1] = '0' + (loginfo->level % 8); spin_lock_bh(&log_lock); printk(level_string); printk("%sIN=%s OUT=%s ", - loginfo->prefix, + prefix == NULL ? loginfo->prefix : prefix, in ? in->name : "", out ? out->name : ""); if (in && !out) { @@ -409,10 +407,41 @@ 1); printk("\n"); spin_unlock_bh(&log_lock); +} + +static unsigned int +ip6t_log_target(struct sk_buff **pskb, + unsigned int hooknum, + const struct net_device *in, + const struct net_device *out, + const void *targinfo, + void *userinfo) +{ + const struct ip6t_log_info *loginfo = targinfo; + char level_string[4] = "< >"; + + level_string[1] = '0' + (loginfo->level % 8); + ip6t_log_packet(pskb, hooknum, in, out, loginfo, level_string, NULL); return IP6T_CONTINUE; } +static void +ip6_log_packet_fn(struct sk_buff **pskb, + unsigned int hooknum, + const struct net_device *in, + const struct net_device *out, + const char *prefix) +{ + struct ip6t_log_info loginfo = { + .level = 0, + .logflags = IP6T_LOG_MASK, + .prefix = "" + }; + + ip6t_log_packet(pskb, hooknum, in, out, &loginfo, KERN_WARNING, prefix); +} + static int ip6t_log_checkentry(const char *tablename, const struct ip6t_entry *e, void *targinfo, @@ -444,17 +473,21 @@ static struct ip6t_target ip6t_log_reg = { { NULL, NULL }, "LOG", ip6t_log_target, ip6t_log_checkentry, NULL, THIS_MODULE }; +static struct nf_logging_t ip6_logging_fn += { ip6_log_packet_fn }; static int __init init(void) { if (ip6t_register_target(&ip6t_log_reg)) return -EINVAL; + nf_log_register(PF_INET6, &ip6_logging_fn); return 0; } static void __exit fini(void) { + nf_log_unregister(PF_INET6, &ip6_logging_fn); ip6t_unregister_target(&ip6t_log_reg); } diff -Nur linux-2.4.32-orig/net/netsyms.c linux-2.4.32-pab2/net/netsyms.c --- linux-2.4.32-orig/net/netsyms.c 2005-04-04 03:42:20 +0200 +++ linux-2.4.32-pab2/net/netsyms.c 2005-10-27 17:18:23 +0200 @@ -594,6 +594,7 @@ #endif #ifdef CONFIG_NETFILTER #include +#include EXPORT_SYMBOL(nf_register_hook); EXPORT_SYMBOL(nf_unregister_hook); EXPORT_SYMBOL(nf_register_sockopt); @@ -607,6 +608,10 @@ EXPORT_SYMBOL(nf_getsockopt); EXPORT_SYMBOL(ip_ct_attach); EXPORT_SYMBOL(nf_ct_attach); +EXPORT_SYMBOL(nf_log_register); +EXPORT_SYMBOL(nf_log_unregister); +EXPORT_SYMBOL(nf_log_packet); +EXPORT_SYMBOL(nf_log); #ifdef CONFIG_INET #include EXPORT_SYMBOL(ip_route_me_harder);