1/* 2 * netfilter module for userspace packet logging daemons 3 * 4 * (C) 2000-2004 by Harald Welte <laforge@netfilter.org> 5 * (C) 1999-2001 Paul `Rusty' Russell 6 * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org> 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License version 2 as 10 * published by the Free Software Foundation. 11 * 12 * This module accepts two parameters: 13 * 14 * nlbufsiz: 15 * The parameter specifies how big the buffer for each netlink multicast 16 * group is. e.g. If you say nlbufsiz=8192, up to eight kb of packets will 17 * get accumulated in the kernel until they are sent to userspace. It is 18 * NOT possible to allocate more than 128kB, and it is strongly discouraged, 19 * because atomically allocating 128kB inside the network rx softirq is not 20 * reliable. Please also keep in mind that this buffer size is allocated for 21 * each nlgroup you are using, so the total kernel memory usage increases 22 * by that factor. 23 * 24 * Actually you should use nlbufsiz a bit smaller than PAGE_SIZE, since 25 * nlbufsiz is used with alloc_skb, which adds another 26 * sizeof(struct skb_shared_info). Use NLMSG_GOODSIZE instead. 27 * 28 * flushtimeout: 29 * Specify, after how many hundredths of a second the queue should be 30 * flushed even if it is not full yet. 31 */ 32#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 33#include <linux/module.h> 34#include <linux/spinlock.h> 35#include <linux/socket.h> 36#include <linux/slab.h> 37#include <linux/skbuff.h> 38#include <linux/kernel.h> 39#include <linux/timer.h> 40#include <linux/netlink.h> 41#include <linux/netdevice.h> 42#include <linux/mm.h> 43#include <linux/moduleparam.h> 44#include <linux/netfilter.h> 45#include <linux/netfilter/x_tables.h> 46#include <linux/netfilter_ipv4/ipt_ULOG.h> 47#include <net/netfilter/nf_log.h> 48#include <net/sock.h> 49#include <linux/bitops.h> 50#include <asm/unaligned.h> 51 52MODULE_LICENSE("GPL"); 53MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>"); 54MODULE_DESCRIPTION("Xtables: packet logging to netlink using ULOG"); 55MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_NFLOG); 56 57#define ULOG_NL_EVENT 111 /* Harald's favorite number */ 58#define ULOG_MAXNLGROUPS 32 /* numer of nlgroups */ 59 60static unsigned int nlbufsiz = NLMSG_GOODSIZE; 61module_param(nlbufsiz, uint, 0400); 62MODULE_PARM_DESC(nlbufsiz, "netlink buffer size"); 63 64static unsigned int flushtimeout = 10; 65module_param(flushtimeout, uint, 0600); 66MODULE_PARM_DESC(flushtimeout, "buffer flush timeout (hundredths of a second)"); 67 68static int nflog = 1; 69module_param(nflog, bool, 0400); 70MODULE_PARM_DESC(nflog, "register as internal netfilter logging module"); 71 72/* global data structures */ 73 74typedef struct { 75 unsigned int qlen; /* number of nlmsgs' in the skb */ 76 struct nlmsghdr *lastnlh; /* netlink header of last msg in skb */ 77 struct sk_buff *skb; /* the pre-allocated skb */ 78 struct timer_list timer; /* the timer function */ 79} ulog_buff_t; 80 81static ulog_buff_t ulog_buffers[ULOG_MAXNLGROUPS]; /* array of buffers */ 82 83static struct sock *nflognl; /* our socket */ 84static DEFINE_SPINLOCK(ulog_lock); /* spinlock */ 85 86/* send one ulog_buff_t to userspace */ 87static void ulog_send(unsigned int nlgroupnum) 88{ 89 ulog_buff_t *ub = &ulog_buffers[nlgroupnum]; 90 91 if (timer_pending(&ub->timer)) { 92 pr_debug("ulog_send: timer was pending, deleting\n"); 93 del_timer(&ub->timer); 94 } 95 96 if (!ub->skb) { 97 pr_debug("ulog_send: nothing to send\n"); 98 return; 99 } 100 101 /* last nlmsg needs NLMSG_DONE */ 102 if (ub->qlen > 1) 103 ub->lastnlh->nlmsg_type = NLMSG_DONE; 104 105 NETLINK_CB(ub->skb).dst_group = nlgroupnum + 1; 106 pr_debug("throwing %d packets to netlink group %u\n", 107 ub->qlen, nlgroupnum + 1); 108 netlink_broadcast(nflognl, ub->skb, 0, nlgroupnum + 1, GFP_ATOMIC); 109 110 ub->qlen = 0; 111 ub->skb = NULL; 112 ub->lastnlh = NULL; 113} 114 115 116/* timer function to flush queue in flushtimeout time */ 117static void ulog_timer(unsigned long data) 118{ 119 pr_debug("timer function called, calling ulog_send\n"); 120 121 /* lock to protect against somebody modifying our structure 122 * from ipt_ulog_target at the same time */ 123 spin_lock_bh(&ulog_lock); 124 ulog_send(data); 125 spin_unlock_bh(&ulog_lock); 126} 127 128static struct sk_buff *ulog_alloc_skb(unsigned int size) 129{ 130 struct sk_buff *skb; 131 unsigned int n; 132 133 /* alloc skb which should be big enough for a whole 134 * multipart message. WARNING: has to be <= 131000 135 * due to slab allocator restrictions */ 136 137 n = max(size, nlbufsiz); 138 skb = alloc_skb(n, GFP_ATOMIC); 139 if (!skb) { 140 pr_debug("cannot alloc whole buffer %ub!\n", n); 141 142 if (n > size) { 143 /* try to allocate only as much as we need for 144 * current packet */ 145 146 skb = alloc_skb(size, GFP_ATOMIC); 147 if (!skb) 148 pr_debug("cannot even allocate %ub\n", size); 149 } 150 } 151 152 return skb; 153} 154 155static void ipt_ulog_packet(unsigned int hooknum, 156 const struct sk_buff *skb, 157 const struct net_device *in, 158 const struct net_device *out, 159 const struct ipt_ulog_info *loginfo, 160 const char *prefix) 161{ 162 ulog_buff_t *ub; 163 ulog_packet_msg_t *pm; 164 size_t size, copy_len; 165 struct nlmsghdr *nlh; 166 struct timeval tv; 167 168 /* ffs == find first bit set, necessary because userspace 169 * is already shifting groupnumber, but we need unshifted. 170 * ffs() returns [1..32], we need [0..31] */ 171 unsigned int groupnum = ffs(loginfo->nl_group) - 1; 172 173 /* calculate the size of the skb needed */ 174 if (loginfo->copy_range == 0 || loginfo->copy_range > skb->len) 175 copy_len = skb->len; 176 else 177 copy_len = loginfo->copy_range; 178 179 size = NLMSG_SPACE(sizeof(*pm) + copy_len); 180 181 ub = &ulog_buffers[groupnum]; 182 183 spin_lock_bh(&ulog_lock); 184 185 if (!ub->skb) { 186 if (!(ub->skb = ulog_alloc_skb(size))) 187 goto alloc_failure; 188 } else if (ub->qlen >= loginfo->qthreshold || 189 size > skb_tailroom(ub->skb)) { 190 /* either the queue len is too high or we don't have 191 * enough room in nlskb left. send it to userspace. */ 192 193 ulog_send(groupnum); 194 195 if (!(ub->skb = ulog_alloc_skb(size))) 196 goto alloc_failure; 197 } 198 199 pr_debug("qlen %d, qthreshold %Zu\n", ub->qlen, loginfo->qthreshold); 200 201 /* NLMSG_PUT contains a hidden goto nlmsg_failure !!! */ 202 nlh = NLMSG_PUT(ub->skb, 0, ub->qlen, ULOG_NL_EVENT, 203 sizeof(*pm)+copy_len); 204 ub->qlen++; 205 206 pm = NLMSG_DATA(nlh); 207 208 /* We might not have a timestamp, get one */ 209 if (skb->tstamp.tv64 == 0) 210 __net_timestamp((struct sk_buff *)skb); 211 212 /* copy hook, prefix, timestamp, payload, etc. */ 213 pm->data_len = copy_len; 214 tv = ktime_to_timeval(skb->tstamp); 215 put_unaligned(tv.tv_sec, &pm->timestamp_sec); 216 put_unaligned(tv.tv_usec, &pm->timestamp_usec); 217 put_unaligned(skb->mark, &pm->mark); 218 pm->hook = hooknum; 219 if (prefix != NULL) 220 strncpy(pm->prefix, prefix, sizeof(pm->prefix)); 221 else if (loginfo->prefix[0] != '\0') 222 strncpy(pm->prefix, loginfo->prefix, sizeof(pm->prefix)); 223 else 224 *(pm->prefix) = '\0'; 225 226 if (in && in->hard_header_len > 0 && 227 skb->mac_header != skb->network_header && 228 in->hard_header_len <= ULOG_MAC_LEN) { 229 memcpy(pm->mac, skb_mac_header(skb), in->hard_header_len); 230 pm->mac_len = in->hard_header_len; 231 } else 232 pm->mac_len = 0; 233 234 if (in) 235 strncpy(pm->indev_name, in->name, sizeof(pm->indev_name)); 236 else 237 pm->indev_name[0] = '\0'; 238 239 if (out) 240 strncpy(pm->outdev_name, out->name, sizeof(pm->outdev_name)); 241 else 242 pm->outdev_name[0] = '\0'; 243 244 /* copy_len <= skb->len, so can't fail. */ 245 if (skb_copy_bits(skb, 0, pm->payload, copy_len) < 0) 246 BUG(); 247 248 /* check if we are building multi-part messages */ 249 if (ub->qlen > 1) 250 ub->lastnlh->nlmsg_flags |= NLM_F_MULTI; 251 252 ub->lastnlh = nlh; 253 254 /* if timer isn't already running, start it */ 255 if (!timer_pending(&ub->timer)) { 256 ub->timer.expires = jiffies + flushtimeout * HZ / 100; 257 add_timer(&ub->timer); 258 } 259 260 /* if threshold is reached, send message to userspace */ 261 if (ub->qlen >= loginfo->qthreshold) { 262 if (loginfo->qthreshold > 1) 263 nlh->nlmsg_type = NLMSG_DONE; 264 ulog_send(groupnum); 265 } 266 267 spin_unlock_bh(&ulog_lock); 268 269 return; 270 271nlmsg_failure: 272 pr_debug("error during NLMSG_PUT\n"); 273alloc_failure: 274 pr_debug("Error building netlink message\n"); 275 spin_unlock_bh(&ulog_lock); 276} 277 278static unsigned int 279ulog_tg(struct sk_buff *skb, const struct xt_action_param *par) 280{ 281 ipt_ulog_packet(par->hooknum, skb, par->in, par->out, 282 par->targinfo, NULL); 283 return XT_CONTINUE; 284} 285 286static void ipt_logfn(u_int8_t pf, 287 unsigned int hooknum, 288 const struct sk_buff *skb, 289 const struct net_device *in, 290 const struct net_device *out, 291 const struct nf_loginfo *li, 292 const char *prefix) 293{ 294 struct ipt_ulog_info loginfo; 295 296 if (!li || li->type != NF_LOG_TYPE_ULOG) { 297 loginfo.nl_group = ULOG_DEFAULT_NLGROUP; 298 loginfo.copy_range = 0; 299 loginfo.qthreshold = ULOG_DEFAULT_QTHRESHOLD; 300 loginfo.prefix[0] = '\0'; 301 } else { 302 loginfo.nl_group = li->u.ulog.group; 303 loginfo.copy_range = li->u.ulog.copy_len; 304 loginfo.qthreshold = li->u.ulog.qthreshold; 305 strlcpy(loginfo.prefix, prefix, sizeof(loginfo.prefix)); 306 } 307 308 ipt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix); 309} 310 311static int ulog_tg_check(const struct xt_tgchk_param *par) 312{ 313 const struct ipt_ulog_info *loginfo = par->targinfo; 314 315 if (loginfo->prefix[sizeof(loginfo->prefix) - 1] != '\0') { 316 pr_debug("prefix not null-terminated\n"); 317 return -EINVAL; 318 } 319 if (loginfo->qthreshold > ULOG_MAX_QLEN) { 320 pr_debug("queue threshold %Zu > MAX_QLEN\n", 321 loginfo->qthreshold); 322 return -EINVAL; 323 } 324 return 0; 325} 326 327#ifdef CONFIG_COMPAT 328struct compat_ipt_ulog_info { 329 compat_uint_t nl_group; 330 compat_size_t copy_range; 331 compat_size_t qthreshold; 332 char prefix[ULOG_PREFIX_LEN]; 333}; 334 335static void ulog_tg_compat_from_user(void *dst, const void *src) 336{ 337 const struct compat_ipt_ulog_info *cl = src; 338 struct ipt_ulog_info l = { 339 .nl_group = cl->nl_group, 340 .copy_range = cl->copy_range, 341 .qthreshold = cl->qthreshold, 342 }; 343 344 memcpy(l.prefix, cl->prefix, sizeof(l.prefix)); 345 memcpy(dst, &l, sizeof(l)); 346} 347 348static int ulog_tg_compat_to_user(void __user *dst, const void *src) 349{ 350 const struct ipt_ulog_info *l = src; 351 struct compat_ipt_ulog_info cl = { 352 .nl_group = l->nl_group, 353 .copy_range = l->copy_range, 354 .qthreshold = l->qthreshold, 355 }; 356 357 memcpy(cl.prefix, l->prefix, sizeof(cl.prefix)); 358 return copy_to_user(dst, &cl, sizeof(cl)) ? -EFAULT : 0; 359} 360#endif /* CONFIG_COMPAT */ 361 362static struct xt_target ulog_tg_reg __read_mostly = { 363 .name = "ULOG", 364 .family = NFPROTO_IPV4, 365 .target = ulog_tg, 366 .targetsize = sizeof(struct ipt_ulog_info), 367 .checkentry = ulog_tg_check, 368#ifdef CONFIG_COMPAT 369 .compatsize = sizeof(struct compat_ipt_ulog_info), 370 .compat_from_user = ulog_tg_compat_from_user, 371 .compat_to_user = ulog_tg_compat_to_user, 372#endif 373 .me = THIS_MODULE, 374}; 375 376static struct nf_logger ipt_ulog_logger __read_mostly = { 377 .name = "ipt_ULOG", 378 .logfn = ipt_logfn, 379 .me = THIS_MODULE, 380}; 381 382static int __init ulog_tg_init(void) 383{ 384 int ret, i; 385 386 pr_debug("init module\n"); 387 388 if (nlbufsiz > 128*1024) { 389 pr_warning("Netlink buffer has to be <= 128kB\n"); 390 return -EINVAL; 391 } 392 393 /* initialize ulog_buffers */ 394 for (i = 0; i < ULOG_MAXNLGROUPS; i++) 395 setup_timer(&ulog_buffers[i].timer, ulog_timer, i); 396 397 nflognl = netlink_kernel_create(&init_net, 398 NETLINK_NFLOG, ULOG_MAXNLGROUPS, NULL, 399 NULL, THIS_MODULE); 400 if (!nflognl) 401 return -ENOMEM; 402 403 ret = xt_register_target(&ulog_tg_reg); 404 if (ret < 0) { 405 netlink_kernel_release(nflognl); 406 return ret; 407 } 408 if (nflog) 409 nf_log_register(NFPROTO_IPV4, &ipt_ulog_logger); 410 411 return 0; 412} 413 414static void __exit ulog_tg_exit(void) 415{ 416 ulog_buff_t *ub; 417 int i; 418 419 pr_debug("cleanup_module\n"); 420 421 if (nflog) 422 nf_log_unregister(&ipt_ulog_logger); 423 xt_unregister_target(&ulog_tg_reg); 424 netlink_kernel_release(nflognl); 425 426 /* remove pending timers and free allocated skb's */ 427 for (i = 0; i < ULOG_MAXNLGROUPS; i++) { 428 ub = &ulog_buffers[i]; 429 if (timer_pending(&ub->timer)) { 430 pr_debug("timer was pending, deleting\n"); 431 del_timer(&ub->timer); 432 } 433 434 if (ub->skb) { 435 kfree_skb(ub->skb); 436 ub->skb = NULL; 437 } 438 } 439} 440 441module_init(ulog_tg_init); 442module_exit(ulog_tg_exit); 443