Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753081Ab3EGOTn (ORCPT ); Tue, 7 May 2013 10:19:43 -0400 Received: from ip4-83-240-18-99.cust.nbox.cz ([83.240.18.99]:59328 "EHLO anemoi" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1752678Ab3EGOSG (ORCPT ); Tue, 7 May 2013 10:18:06 -0400 From: Jiri Slaby To: jirislaby@gmail.com Cc: linux-kernel@vger.kernel.org, Jiri Bohac , Jiri Slaby , netfilter-devel@vger.kernel.org, netfilter@vger.kernel.org, coreteam@netfilter.org, netdev@vger.kernel.org, "David S. Miller" , Patrick McHardy , Pablo Neira Ayuso Subject: [PATCH 05/15] connection tracking helper for SLP Date: Tue, 7 May 2013 16:18:13 +0200 Message-Id: <1367936303-13386-5-git-send-email-jslaby@suse.cz> X-Mailer: git-send-email 1.8.2.1 In-Reply-To: <1367936303-13386-1-git-send-email-jslaby@suse.cz> References: <1367936303-13386-1-git-send-email-jslaby@suse.cz> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 6638 Lines: 205 From: Jiri Bohac A simple connection tracking helper for SLP. Marks replies to a SLP broadcast query as ESTABLISHED to allow them to pass through the firewall. Signed-off-by: Jiri Bohac Signed-off-by: Jiri Slaby Cc: netfilter-devel@vger.kernel.org Cc: netfilter@vger.kernel.org Cc: coreteam@netfilter.org Cc: netdev@vger.kernel.org Cc: "David S. Miller" Cc: Patrick McHardy Cc: Pablo Neira Ayuso --- net/netfilter/Kconfig | 15 +++++ net/netfilter/Makefile | 1 + net/netfilter/nf_conntrack_slp.c | 131 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 147 insertions(+) create mode 100644 net/netfilter/nf_conntrack_slp.c diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig index 56d22ca..ec61b30 100644 --- a/net/netfilter/Kconfig +++ b/net/netfilter/Kconfig @@ -320,6 +320,21 @@ config NF_CONNTRACK_TFTP To compile it as a module, choose M here. If unsure, say N. +config NF_CONNTRACK_SLP + tristate "SLP protocol support" + depends on NF_CONNTRACK + depends on NETFILTER_ADVANCED + help + SLP queries are sometimes sent as broadcast messages from an + unprivileged port and responded to with unicast messages to the + same port. This make them hard to firewall properly because connection + tracking doesn't deal with broadcasts. This helper tracks locally + originating broadcast SLP queries and the corresponding + responses. It relies on correct IP address configuration, specifically + netmask and broadcast address. + + To compile it as a module, choose M here. If unsure, say N. + config NF_CT_NETLINK tristate 'Connection tracking netlink interface' select NETFILTER_NETLINK diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile index a1abf87..aa7d5f1 100644 --- a/net/netfilter/Makefile +++ b/net/netfilter/Makefile @@ -43,6 +43,7 @@ obj-$(CONFIG_NF_CONNTRACK_PPTP) += nf_conntrack_pptp.o obj-$(CONFIG_NF_CONNTRACK_SANE) += nf_conntrack_sane.o obj-$(CONFIG_NF_CONNTRACK_SIP) += nf_conntrack_sip.o obj-$(CONFIG_NF_CONNTRACK_TFTP) += nf_conntrack_tftp.o +obj-$(CONFIG_NF_CONNTRACK_SLP) += nf_conntrack_slp.o nf_nat-y := nf_nat_core.o nf_nat_proto_unknown.o nf_nat_proto_common.o \ nf_nat_proto_udp.o nf_nat_proto_tcp.o nf_nat_helper.o diff --git a/net/netfilter/nf_conntrack_slp.c b/net/netfilter/nf_conntrack_slp.c new file mode 100644 index 0000000..0174dd0 --- /dev/null +++ b/net/netfilter/nf_conntrack_slp.c @@ -0,0 +1,131 @@ +/* + * NetBIOS name service broadcast connection tracking helper + * + * (c) 2007 Jiri Bohac + * (c) 2005 Patrick McHardy + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +/* + * This helper tracks locally originating NetBIOS name service + * requests by issuing permanent expectations (valid until + * timing out) matching all reply connections from the + * destination network. The only NetBIOS specific thing is + * actually the port number. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#define SLP_PORT 427 + +MODULE_AUTHOR("Jiri Bohac "); +MODULE_DESCRIPTION("SLP broadcast connection tracking helper"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("ip_conntrack_slp"); + +static unsigned int timeout __read_mostly = 3; +module_param(timeout, uint, 0400); +MODULE_PARM_DESC(timeout, "timeout for master connection/replies in seconds"); + +static int help(struct sk_buff *skb, unsigned int protoff, + struct nf_conn *ct, enum ip_conntrack_info ctinfo) +{ + struct nf_conntrack_expect *exp; + struct rtable *rt = skb_rtable(skb); + struct in_device *in_dev; + __be32 mask = 0; + __be32 src = 0; + + /* we're only interested in locally generated packets */ + if (skb->sk == NULL) + goto out; + if (rt == NULL || !(rt->rt_flags & (RTCF_MULTICAST|RTCF_BROADCAST))) + goto out; + if (CTINFO2DIR(ctinfo) != IP_CT_DIR_ORIGINAL) + goto out; + + rcu_read_lock(); + in_dev = __in_dev_get_rcu(rt->dst.dev); + if (in_dev != NULL) { + for_primary_ifa(in_dev) { + /* this is a hack as slp uses multicast we can't match + * the destination address to some broadcast address. So + * just take the first one. Better would be to install + * expectations for all addresses */ + mask = ifa->ifa_mask; + src = ifa->ifa_broadcast; + break; + } endfor_ifa(in_dev); + } + rcu_read_unlock(); + + if (mask == 0 || src == 0) + goto out; + + exp = nf_ct_expect_alloc(ct); + if (exp == NULL) + goto out; + + exp->tuple = ct->tuplehash[IP_CT_DIR_REPLY].tuple; + exp->tuple.src.u3.ip = src; + exp->tuple.src.u.udp.port = htons(SLP_PORT); + + exp->mask.src.u3.ip = mask; + exp->mask.src.u.udp.port = htons(0xFFFF); + + exp->expectfn = NULL; + exp->flags = NF_CT_EXPECT_PERMANENT; + exp->class = NF_CT_EXPECT_CLASS_DEFAULT; + exp->helper = NULL; + + nf_ct_expect_related(exp); + nf_ct_expect_put(exp); + + nf_ct_refresh(ct, skb, timeout * HZ); +out: + return NF_ACCEPT; +} + +static struct nf_conntrack_expect_policy exp_policy = { + .max_expected = 1, +}; + +static struct nf_conntrack_helper helper __read_mostly = { + .name = "slp", + .tuple.src.l3num = AF_INET, + .tuple.src.u.udp.port = __constant_htons(SLP_PORT), + .tuple.dst.protonum = IPPROTO_UDP, + .me = THIS_MODULE, + .help = help, + .expect_policy = &exp_policy, +}; + +static int __init nf_conntrack_slp_init(void) +{ + exp_policy.timeout = timeout; + return nf_conntrack_helper_register(&helper); +} + +static void __exit nf_conntrack_slp_fini(void) +{ + nf_conntrack_helper_unregister(&helper); +} + +module_init(nf_conntrack_slp_init); +module_exit(nf_conntrack_slp_fini); -- 1.8.2.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/