16939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger/*
26939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger * This is a module which is used for logging packets.
36939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger */
46939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
56939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger/* (C) 1999-2001 Paul `Rusty' Russell
66939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
76939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger *
86939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger * This program is free software; you can redistribute it and/or modify
96939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger * it under the terms of the GNU General Public License version 2 as
106939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger * published by the Free Software Foundation.
116939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger */
126939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
136939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
146939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger#include <linux/module.h>
156939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger#include <linux/spinlock.h>
166939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger#include <linux/skbuff.h>
176939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger#include <linux/if_arp.h>
186939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger#include <linux/ip.h>
196939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger#include <net/ipv6.h>
206939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger#include <net/icmp.h>
216939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger#include <net/udp.h>
226939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger#include <net/tcp.h>
236939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger#include <net/route.h>
246939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
256939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger#include <linux/netfilter.h>
266939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger#include <linux/netfilter/x_tables.h>
276939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger#include <linux/netfilter/xt_LOG.h>
286939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger#include <linux/netfilter_ipv6/ip6_tables.h>
296939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger#include <net/netfilter/nf_log.h>
306939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
316939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinbergerstatic unsigned int
326939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinbergerlog_tg(struct sk_buff *skb, const struct xt_action_param *par)
336939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger{
346939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	const struct xt_log_info *loginfo = par->targinfo;
356939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	struct nf_loginfo li;
368cdb46da06ea94543a3b2e53e3e92736421d1093Hans Schillstrom	struct net *net = dev_net(par->in ? par->in : par->out);
376939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
386939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	li.type = NF_LOG_TYPE_LOG;
396939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	li.u.log.level = loginfo->level;
406939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	li.u.log.logflags = loginfo->logflags;
416939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
42fab4085f4e248b8a80bb1dadbbacb2bacd8017c3Pablo Neira Ayuso	nf_log_packet(net, par->family, par->hooknum, skb, par->in, par->out,
43ca1aa54f272d47bec77baa292f803df7a81f966bPablo Neira Ayuso		      &li, "%s", loginfo->prefix);
446939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	return XT_CONTINUE;
456939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger}
466939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
476939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinbergerstatic int log_tg_check(const struct xt_tgchk_param *par)
486939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger{
496939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	const struct xt_log_info *loginfo = par->targinfo;
506939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
516939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	if (par->family != NFPROTO_IPV4 && par->family != NFPROTO_IPV6)
526939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		return -EINVAL;
536939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
546939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	if (loginfo->level >= 8) {
556939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		pr_debug("level %u >= 8\n", loginfo->level);
566939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		return -EINVAL;
576939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	}
586939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
596939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	if (loginfo->prefix[sizeof(loginfo->prefix)-1] != '\0') {
606939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		pr_debug("prefix is not null-terminated\n");
616939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		return -EINVAL;
626939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	}
636939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
64fab4085f4e248b8a80bb1dadbbacb2bacd8017c3Pablo Neira Ayuso	return nf_logger_find_get(par->family, NF_LOG_TYPE_LOG);
65fab4085f4e248b8a80bb1dadbbacb2bacd8017c3Pablo Neira Ayuso}
66fab4085f4e248b8a80bb1dadbbacb2bacd8017c3Pablo Neira Ayuso
67fab4085f4e248b8a80bb1dadbbacb2bacd8017c3Pablo Neira Ayusostatic void log_tg_destroy(const struct xt_tgdtor_param *par)
68fab4085f4e248b8a80bb1dadbbacb2bacd8017c3Pablo Neira Ayuso{
69fab4085f4e248b8a80bb1dadbbacb2bacd8017c3Pablo Neira Ayuso	nf_logger_put(par->family, NF_LOG_TYPE_LOG);
706939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger}
716939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
726939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinbergerstatic struct xt_target log_tg_regs[] __read_mostly = {
736939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	{
746939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		.name		= "LOG",
756939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		.family		= NFPROTO_IPV4,
766939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		.target		= log_tg,
776939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		.targetsize	= sizeof(struct xt_log_info),
786939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		.checkentry	= log_tg_check,
79fab4085f4e248b8a80bb1dadbbacb2bacd8017c3Pablo Neira Ayuso		.destroy	= log_tg_destroy,
806939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		.me		= THIS_MODULE,
816939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	},
82a0f65a267dd62aef4e003f833ea6290fd1e07b34Pablo Neira Ayuso#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
836939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	{
846939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		.name		= "LOG",
856939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		.family		= NFPROTO_IPV6,
866939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		.target		= log_tg,
876939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		.targetsize	= sizeof(struct xt_log_info),
886939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		.checkentry	= log_tg_check,
89fab4085f4e248b8a80bb1dadbbacb2bacd8017c3Pablo Neira Ayuso		.destroy	= log_tg_destroy,
906939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		.me		= THIS_MODULE,
916939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	},
926939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger#endif
936939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger};
946939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
956939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinbergerstatic int __init log_tg_init(void)
966939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger{
9783e96d443b372611adf19e4171d41deb1d8760cfPablo Neira Ayuso	return xt_register_targets(log_tg_regs, ARRAY_SIZE(log_tg_regs));
986939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger}
996939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
1006939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinbergerstatic void __exit log_tg_exit(void)
1016939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger{
1026939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	xt_unregister_targets(log_tg_regs, ARRAY_SIZE(log_tg_regs));
1036939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger}
1046939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
1056939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinbergermodule_init(log_tg_init);
1066939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinbergermodule_exit(log_tg_exit);
1076939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
1086939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard WeinbergerMODULE_LICENSE("GPL");
1096939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard WeinbergerMODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
1106939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard WeinbergerMODULE_AUTHOR("Jan Rekorajski <baggins@pld.org.pl>");
1116939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard WeinbergerMODULE_DESCRIPTION("Xtables: IPv4/IPv6 packet logging");
1126939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard WeinbergerMODULE_ALIAS("ipt_LOG");
1136939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard WeinbergerMODULE_ALIAS("ip6t_LOG");
114