270 lines
7.2 KiB
Diff
270 lines
7.2 KiB
Diff
---
|
|
include/linux/netfilter_ipv4/ipt_IFWLOG.h | 26 +++
|
|
net/ipv4/netfilter/Kconfig | 11 +
|
|
net/ipv4/netfilter/Makefile | 1
|
|
net/ipv4/netfilter/ipt_IFWLOG.c | 200 ++++++++++++++++++++++++++++++
|
|
4 files changed, 238 insertions(+)
|
|
|
|
--- /dev/null
|
|
+++ b/net/ipv4/netfilter/ipt_IFWLOG.c
|
|
@@ -0,0 +1,200 @@
|
|
+/* Interactive Firewall for Mandriva
|
|
+ * Samir Bellabes <sbellabes@mandriva.com>
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify
|
|
+ * it under the terms of the GNU General Public License version 2 as
|
|
+ * published by the Free Software Foundation.
|
|
+ */
|
|
+
|
|
+#include <linux/module.h>
|
|
+#include <asm/types.h>
|
|
+#include <linux/jiffies.h>
|
|
+#include <linux/skbuff.h>
|
|
+#include <linux/ip.h>
|
|
+#include <net/icmp.h>
|
|
+#include <net/udp.h>
|
|
+#include <net/tcp.h>
|
|
+#include <net/sock.h>
|
|
+#include <linux/netlink.h>
|
|
+#include <linux/string.h>
|
|
+
|
|
+#include <linux/netfilter.h>
|
|
+#include <linux/netfilter_ipv4/ip_tables.h>
|
|
+#include <linux/netfilter_ipv4/ipt_IFWLOG.h>
|
|
+
|
|
+MODULE_LICENSE("GPL");
|
|
+MODULE_AUTHOR("Samir Bellabes <sbellabes@mandriva.com>");
|
|
+MODULE_DESCRIPTION("Interactive firewall logging and module");
|
|
+
|
|
+#if 0
|
|
+#define DEBUGP PRINTR
|
|
+#else
|
|
+#define DEBUGP(format, args...)
|
|
+#endif
|
|
+
|
|
+#define PRINTR(format, args...) do { if(net_ratelimit()) printk(format, ##args); } while(0)
|
|
+
|
|
+static struct sock *nl;
|
|
+
|
|
+#define GROUP 10
|
|
+
|
|
+/* send struct to userspace */
|
|
+static void send_packet(struct nl_msg msg)
|
|
+{
|
|
+ struct sk_buff *skb = NULL;
|
|
+ struct nlmsghdr *nlh;
|
|
+
|
|
+ skb = alloc_skb(NLMSG_SPACE(sizeof(struct nl_msg)), GFP_ATOMIC);
|
|
+ if (!skb) {
|
|
+ PRINTR(KERN_WARNING "IFWLOG: OOM can't allocate skb\n");
|
|
+ return ;
|
|
+ }
|
|
+
|
|
+ nlh = NLMSG_PUT(skb, 0, 0, 0, sizeof(struct nl_msg) - sizeof(*nlh));
|
|
+
|
|
+ memcpy(NLMSG_DATA(nlh), (const void*)&msg, sizeof(struct nl_msg));
|
|
+
|
|
+ NETLINK_CB(skb).pid = 0; /* from kernel */
|
|
+ NETLINK_CB(skb).dst_pid = 0; /* multicast */
|
|
+ NETLINK_CB(skb).dst_group = 10;
|
|
+
|
|
+ if (nl) {
|
|
+ DEBUGP(KERN_WARNING
|
|
+ "IFWLOG: nlmsg_len=%ld\nnlmsg_type=%d nlmsg_flags=%d\nnlmsg_seq=%ld nlmsg_pid = %ld\n",
|
|
+ (long)nlh->nlmsg_len, nlh->nlmsg_type, nlh->nlmsg_flags,
|
|
+ (long)nlh->nlmsg_seq, (long)nlh->nlmsg_pid);
|
|
+ DEBUGP(KERN_WARNING "prefix : %s\n", msg.prefix);
|
|
+
|
|
+ netlink_broadcast(nl, skb, 0, 10, GFP_ATOMIC);
|
|
+ return ;
|
|
+ }
|
|
+
|
|
+ nlmsg_failure:
|
|
+ if (skb)
|
|
+ kfree_skb(skb);
|
|
+ PRINTR(KERN_WARNING "IFWLOG: Error sending netlink packet\n");
|
|
+ return ;
|
|
+}
|
|
+
|
|
+/* fill struct for userspace */
|
|
+static void ipt_IFWLOG_packet(const struct sk_buff *skb,
|
|
+ const struct net_device *in,
|
|
+ const struct net_device *out,
|
|
+ const struct ipt_IFWLOG_info *info)
|
|
+{
|
|
+ struct iphdr iph;
|
|
+ struct tcphdr tcph;
|
|
+ struct udphdr udph;
|
|
+ struct nl_msg msg;
|
|
+ struct iphdr _iph, *ih;
|
|
+ struct timeval tv;
|
|
+
|
|
+ memset(&msg, 0, sizeof(struct nl_msg));
|
|
+
|
|
+ ih = skb_header_pointer(skb, 0, sizeof(_iph), &_iph);
|
|
+ if (ih == NULL) {
|
|
+ PRINTR(KERN_WARNING "IFWLOG: skb truncated");
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ /* save interface name */
|
|
+ if (in)
|
|
+ strcpy(msg.indev_name, in->name);
|
|
+ if (out)
|
|
+ strcpy(msg.outdev_name, out->name);
|
|
+
|
|
+ /* save log-prefix */
|
|
+ strcpy(msg.prefix, info->prefix);
|
|
+
|
|
+ /* save ip header */
|
|
+ skb_copy_bits(skb, 0, &iph, sizeof(iph));
|
|
+ memcpy(&msg.ip, &iph, sizeof(struct iphdr));
|
|
+
|
|
+ /* save transport header */
|
|
+ switch (iph.protocol){
|
|
+ case IPPROTO_TCP:
|
|
+ skb_copy_bits(skb, iph.ihl*4 , &tcph, sizeof(tcph));
|
|
+ memcpy(&msg.h.th, &tcph, sizeof(struct tcphdr));
|
|
+ break;
|
|
+ case IPPROTO_UDP:
|
|
+ skb_copy_bits(skb, iph.ihl*4 , &udph, sizeof(udph));
|
|
+ memcpy(&msg.h.uh, &udph, sizeof(struct udphdr));
|
|
+ break;
|
|
+ default:
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ /* save timetamp */
|
|
+ do_gettimeofday((struct timeval *)&tv);
|
|
+ msg.timestamp_sec = tv.tv_sec;
|
|
+
|
|
+ send_packet(msg);
|
|
+}
|
|
+
|
|
+static unsigned int ipt_IFWLOG_target(struct sk_buff **pskb,
|
|
+ const struct net_device *in,
|
|
+ const struct net_device *out,
|
|
+ unsigned int hooknum,
|
|
+ const void *targinfo,
|
|
+ void *userinfo)
|
|
+{
|
|
+ const struct ipt_IFWLOG_info *info = targinfo;
|
|
+
|
|
+ ipt_IFWLOG_packet(*pskb, in, out, info);
|
|
+
|
|
+ return IPT_CONTINUE;
|
|
+}
|
|
+
|
|
+static int ipt_IFWLOG_checkentry(const char *tablename,
|
|
+ const struct ipt_entry *e,
|
|
+ void *targinfo,
|
|
+ unsigned int targinfosize,
|
|
+ unsigned int hook_mask)
|
|
+{
|
|
+ const struct ipt_IFWLOG_info *info = targinfo;
|
|
+
|
|
+ if (info->prefix[sizeof(info->prefix)-1] != '\0') {
|
|
+ DEBUGP("IFWLOG: prefix term %i\n",
|
|
+ info->prefix[sizeof(info->prefix)-1]);
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ return 1;
|
|
+}
|
|
+
|
|
+static struct ipt_target ipt_IFWLOG = {
|
|
+ .name = "IFWLOG",
|
|
+ .target = ipt_IFWLOG_target,
|
|
+ .targetsize = sizeof(struct ipt_IFWLOG_info),
|
|
+ .checkentry = ipt_IFWLOG_checkentry,
|
|
+ .me = THIS_MODULE,
|
|
+};
|
|
+
|
|
+static int __init init(void)
|
|
+{
|
|
+ nl = (struct sock*) netlink_kernel_create(NETLINK_IFWLOG, GROUP, NULL, THIS_MODULE);
|
|
+ if (!nl) {
|
|
+ PRINTR(KERN_WARNING "IFWLOG: cannot create netlink socket\n");
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
+ if (ipt_register_target(&ipt_IFWLOG)) {
|
|
+ if (nl && nl->sk_socket)
|
|
+ sock_release(nl->sk_socket);
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
+ PRINTR(KERN_INFO "IFWLOG: register target\n");
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static void __exit fini(void)
|
|
+{
|
|
+ if (nl && nl->sk_socket)
|
|
+ sock_release(nl->sk_socket);
|
|
+ PRINTR(KERN_INFO "IFWLOG: unregister target\n");
|
|
+ ipt_unregister_target(&ipt_IFWLOG);
|
|
+}
|
|
+
|
|
+module_init(init);
|
|
+module_exit(fini);
|
|
--- a/net/ipv4/netfilter/Kconfig
|
|
+++ b/net/ipv4/netfilter/Kconfig
|
|
@@ -331,6 +331,17 @@ config IP_NF_TARGET_TTL
|
|
(e.g. when running oldconfig). It selects
|
|
CONFIG_NETFILTER_XT_TARGET_HL.
|
|
|
|
+config IP_NF_TARGET_IFWLOG
|
|
+ tristate 'IFWLOG target support'
|
|
+ depends on IP_NF_IPTABLES
|
|
+ help
|
|
+ This option adds a `IFWLOG' target, which is used by
|
|
+ Interactive Firewall for sending informations to a userspace
|
|
+ daemon
|
|
+
|
|
+ If you want to compile it as a module, say M here and read
|
|
+ Documentation/modules.txt. If unsure, say `N'.
|
|
+
|
|
# raw + specific targets
|
|
config IP_NF_RAW
|
|
tristate 'raw table support (required for NOTRACK/TRACE)'
|
|
--- /dev/null
|
|
+++ b/include/linux/netfilter_ipv4/ipt_IFWLOG.h
|
|
@@ -0,0 +1,26 @@
|
|
+#ifndef _IPT_IFWLOG_H
|
|
+#define _IPT_IFWLOG_H
|
|
+
|
|
+#ifndef NETLINK_IFWLOG
|
|
+#define NETLINK_IFWLOG 19
|
|
+#endif
|
|
+
|
|
+#define PREFSIZ 32
|
|
+
|
|
+struct nl_msg { /* Netlink message */
|
|
+ long timestamp_sec; /* time packet */
|
|
+ char indev_name[IFNAMSIZ]; /* name of the ingoing interface */
|
|
+ char outdev_name[IFNAMSIZ]; /* name of the outgoing interface */
|
|
+ unsigned char prefix[PREFSIZ]; /* informations on the logging reason */
|
|
+ struct iphdr ip;
|
|
+ union {
|
|
+ struct tcphdr th;
|
|
+ struct udphdr uh;
|
|
+ } h;
|
|
+};
|
|
+
|
|
+struct ipt_IFWLOG_info {
|
|
+ char prefix[PREFSIZ];
|
|
+};
|
|
+
|
|
+#endif /* _IPT_IFWLOG_H */
|
|
--- linux/net/ipv4/netfilter/Makefile.net-netfilter-IFWLOG.orig 2012-05-21 01:29:13.000000000 +0300
|
|
+++ linux/net/ipv4/netfilter/Makefile 2012-05-26 01:23:57.511514194 +0300
|
|
@@ -53,6 +53,7 @@ obj-$(CONFIG_IP_NF_MATCH_RPFILTER) += ip
|
|
|
|
# targets
|
|
obj-$(CONFIG_IP_NF_TARGET_CLUSTERIP) += ipt_CLUSTERIP.o
|
|
+obj-$(CONFIG_IP_NF_TARGET_IFWLOG) += ipt_IFWLOG.o
|
|
obj-$(CONFIG_IP_NF_TARGET_ECN) += ipt_ECN.o
|
|
obj-$(CONFIG_IP_NF_TARGET_MASQUERADE) += ipt_MASQUERADE.o
|
|
obj-$(CONFIG_IP_NF_TARGET_NETMAP) += ipt_NETMAP.o
|