static unsigned int ulog_tg(struct sk_buff *skb, const struct xt_action_param *par) { ipt_ulog_packet(par->hooknum, skb, par->in, par->out, par->targinfo, NULL); return XT_CONTINUE; }
static void ipt_logfn(struct net *net, u_int8_t pf, unsigned int hooknum, const struct sk_buff *skb, const struct net_device *in, const struct net_device *out, const struct nf_loginfo *li, const char *prefix) { struct ipt_ulog_info loginfo; if (!li || li->type != NF_LOG_TYPE_ULOG) { loginfo.nl_group = ULOG_DEFAULT_NLGROUP; loginfo.copy_range = 0; loginfo.qthreshold = ULOG_DEFAULT_QTHRESHOLD; loginfo.prefix[0] = '\0'; } else { loginfo.nl_group = li->u.ulog.group; loginfo.copy_range = li->u.ulog.copy_len; loginfo.qthreshold = li->u.ulog.qthreshold; strlcpy(loginfo.prefix, prefix, sizeof(loginfo.prefix)); } ipt_ulog_packet(net, hooknum, skb, in, out, &loginfo, prefix); }
static unsigned int ipt_ulog_target(struct sk_buff **pskb, const struct net_device *in, const struct net_device *out, unsigned int hooknum, const void *targinfo, void *userinfo) { struct ipt_ulog_info *loginfo = (struct ipt_ulog_info *) targinfo; ipt_ulog_packet(hooknum, *pskb, in, out, loginfo, NULL); return IPT_CONTINUE; }
static void ipt_logfn(unsigned int hooknum, const struct sk_buff *skb, const struct net_device *in, const struct net_device *out, const char *prefix) { struct ipt_ulog_info loginfo = { .nl_group = ULOG_DEFAULT_NLGROUP, .copy_range = 0, .qthreshold = ULOG_DEFAULT_QTHRESHOLD, .prefix = "" }; ipt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix); } static int ipt_ulog_checkentry(const char *tablename, const struct ipt_entry *e, void *targinfo, unsigned int targinfosize, unsigned int hookmask) { struct ipt_ulog_info *loginfo = (struct ipt_ulog_info *) targinfo; if (targinfosize != IPT_ALIGN(sizeof(struct ipt_ulog_info))) { DEBUGP("ipt_ULOG: targinfosize %u != 0\n", targinfosize); return 0; } if (loginfo->prefix[sizeof(loginfo->prefix) - 1] != '\0') { DEBUGP("ipt_ULOG: prefix term %i\n", loginfo->prefix[sizeof(loginfo->prefix) - 1]); return 0; } if (loginfo->qthreshold > ULOG_MAX_QLEN) { DEBUGP("ipt_ULOG: queue threshold %i > MAX_QLEN\n", loginfo->qthreshold); return 0; } return 1; } static struct ipt_target ipt_ulog_reg = { .name = "ULOG", .target = ipt_ulog_target, .checkentry = ipt_ulog_checkentry, .me = THIS_MODULE, }; static int __init init(void) { int i; DEBUGP("ipt_ULOG: init module\n"); if (nlbufsiz >= 128*1024) { printk("Netlink buffer has to be <= 128kB\n"); return -EINVAL; } /* 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; } nflognl = netlink_kernel_create(NETLINK_NFLOG, NULL); if (!nflognl) return -ENOMEM; if (ipt_register_target(&ipt_ulog_reg) != 0) { sock_release(nflognl->sk_socket); return -EINVAL; } if (nflog) nf_log_register(PF_INET, &ipt_logfn); return 0; } static void __exit fini(void) { ulog_buff_t *ub; int i; DEBUGP("ipt_ULOG: cleanup_module\n"); if (nflog) nf_log_unregister(PF_INET, &ipt_logfn); ipt_unregister_target(&ipt_ulog_reg); sock_release(nflognl->sk_socket); /* remove pending timers and free allocated skb's */ for (i = 0; i < ULOG_MAXNLGROUPS; i++) { ub = &ulog_buffers[i]; if (timer_pending(&ub->timer)) { DEBUGP("timer was pending, deleting\n"); del_timer(&ub->timer); } if (ub->skb) { kfree_skb(ub->skb); ub->skb = NULL; } } }