* netfilter module for userspace packet logging daemons
*
* (C) 2000-2004 by Harald Welte <laforge@netfilter.org>
- *
- * 2000/09/22 ulog-cprange feature added
- * 2001/01/04 in-kernel queue as proposed by Sebastian Zander
- * <zander@fokus.gmd.de>
- * 2001/01/30 per-rule nlgroup conflicts with global queue.
- * nlgroup now global (sysctl)
- * 2001/04/19 ulog-queue reworked, now fixed buffer size specified at
- * module loadtime -HW
- * 2002/07/07 remove broken nflog_rcv() function -HW
- * 2002/08/29 fix shifted/unshifted nlgroup bug -HW
- * 2002/10/30 fix uninitialized mac_len field - <Anders K. Pedersen>
- * 2004/10/25 fix erroneous calculation of 'len' parameter to NLMSG_PUT
- * resulting in bogus 'error during NLMSG_PUT' messages.
- *
* (C) 1999-2001 Paul `Rusty' Russell
* (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
*
* flushtimeout:
* Specify, after how many hundredths of a second the queue should be
* flushed even if it is not full yet.
- *
- * ipt_ULOG.c,v 1.22 2002/10/30 09:07:31 laforge Exp
*/
#include <linux/module.h>
unsigned int groupnum = ffs(loginfo->nl_group) - 1;
/* calculate the size of the skb needed */
- if ((loginfo->copy_range == 0) ||
- (loginfo->copy_range > skb->len)) {
+ if (loginfo->copy_range == 0 || loginfo->copy_range > skb->len)
copy_len = skb->len;
- } else {
+ else
copy_len = loginfo->copy_range;
- }
size = NLMSG_SPACE(sizeof(*pm) + copy_len);
*(pm->prefix) = '\0';
if (in && in->hard_header_len > 0
- && skb->mac.raw != (void *) skb->nh.iph
+ && skb->mac_header != skb->network_header
&& in->hard_header_len <= ULOG_MAC_LEN) {
- memcpy(pm->mac, skb->mac.raw, in->hard_header_len);
+ memcpy(pm->mac, skb_mac_header(skb), in->hard_header_len);
pm->mac_len = in->hard_header_len;
} else
pm->mac_len = 0;
BUG();
/* check if we are building multi-part messages */
- if (ub->qlen > 1) {
+ if (ub->qlen > 1)
ub->lastnlh->nlmsg_flags |= NLM_F_MULTI;
- }
ub->lastnlh = nlh;
ipt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix);
}
-static int ipt_ulog_checkentry(const char *tablename,
- const void *e,
- const struct xt_target *target,
- void *targinfo,
- unsigned int hookmask)
+static bool ipt_ulog_checkentry(const char *tablename,
+ const void *e,
+ const struct xt_target *target,
+ void *targinfo,
+ unsigned int hookmask)
{
- struct ipt_ulog_info *loginfo = (struct ipt_ulog_info *) targinfo;
+ const struct ipt_ulog_info *loginfo = targinfo;
if (loginfo->prefix[sizeof(loginfo->prefix) - 1] != '\0') {
DEBUGP("ipt_ULOG: prefix term %i\n",
loginfo->prefix[sizeof(loginfo->prefix) - 1]);
- return 0;
+ return false;
}
if (loginfo->qthreshold > ULOG_MAX_QLEN) {
DEBUGP("ipt_ULOG: queue threshold %i > MAX_QLEN\n",
loginfo->qthreshold);
- return 0;
+ return false;
}
- return 1;
+ return true;
+}
+
+#ifdef CONFIG_COMPAT
+struct compat_ipt_ulog_info {
+ compat_uint_t nl_group;
+ compat_size_t copy_range;
+ compat_size_t qthreshold;
+ char prefix[ULOG_PREFIX_LEN];
+};
+
+static void compat_from_user(void *dst, void *src)
+{
+ const struct compat_ipt_ulog_info *cl = src;
+ struct ipt_ulog_info l = {
+ .nl_group = cl->nl_group,
+ .copy_range = cl->copy_range,
+ .qthreshold = cl->qthreshold,
+ };
+
+ memcpy(l.prefix, cl->prefix, sizeof(l.prefix));
+ memcpy(dst, &l, sizeof(l));
+}
+
+static int compat_to_user(void __user *dst, void *src)
+{
+ const struct ipt_ulog_info *l = src;
+ struct compat_ipt_ulog_info cl = {
+ .nl_group = l->nl_group,
+ .copy_range = l->copy_range,
+ .qthreshold = l->qthreshold,
+ };
+
+ memcpy(cl.prefix, l->prefix, sizeof(cl.prefix));
+ return copy_to_user(dst, &cl, sizeof(cl)) ? -EFAULT : 0;
}
+#endif /* CONFIG_COMPAT */
static struct xt_target ipt_ulog_reg = {
.name = "ULOG",
.target = ipt_ulog_target,
.targetsize = sizeof(struct ipt_ulog_info),
.checkentry = ipt_ulog_checkentry,
+#ifdef CONFIG_COMPAT
+ .compatsize = sizeof(struct compat_ipt_ulog_info),
+ .compat_from_user = compat_from_user,
+ .compat_to_user = compat_to_user,
+#endif
.me = THIS_MODULE,
};
}
/* initialize ulog_buffers */
- for (i = 0; i < ULOG_MAXNLGROUPS; i++) {
- init_timer(&ulog_buffers[i].timer);
- ulog_buffers[i].timer.function = ulog_timer;
- ulog_buffers[i].timer.data = i;
- }
+ for (i = 0; i < ULOG_MAXNLGROUPS; i++)
+ setup_timer(&ulog_buffers[i].timer, ulog_timer, i);
nflognl = netlink_kernel_create(NETLINK_NFLOG, ULOG_MAXNLGROUPS, NULL,
- THIS_MODULE);
+ NULL, THIS_MODULE);
if (!nflognl)
return -ENOMEM;