summaryrefslogtreecommitdiffstats
path: root/src/helpers/mdns.c
diff options
context:
space:
mode:
authorKevin Cernekee <cernekee@chromium.org>2016-09-04 19:39:04 -0700
committerPablo Neira Ayuso <pablo@netfilter.org>2016-09-09 00:21:30 +0200
commitdd4b5a1e5e52f2107227b8513fbf87bc4b0df079 (patch)
treea031a06ebea8c62107fd6555c9719526da532301 /src/helpers/mdns.c
parentd833bed181469876c4182156682ca9e5ebd9bd9a (diff)
conntrackd: cthelper: Add new mdns helper
This allows unicast replies to multicast DNS (mDNS / RFC6762) queries. These queries are often used when a full-featured mDNS service (such as avahi-daemon) is not running, or if an mDNS client does not have permission to bind to port 5353. Signed-off-by: Kevin Cernekee <cernekee@chromium.org> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src/helpers/mdns.c')
-rw-r--r--src/helpers/mdns.c89
1 files changed, 89 insertions, 0 deletions
diff --git a/src/helpers/mdns.c b/src/helpers/mdns.c
new file mode 100644
index 0000000..7605589
--- /dev/null
+++ b/src/helpers/mdns.c
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2016 Google Inc.
+ * Author: Kevin Cernekee <cernekee@chromium.org>
+ *
+ * This helper pokes a hole in the firewall for unicast mDNS replies
+ * (RFC6762 section 5.1). It is needed because the destination address of
+ * the outgoing mDNS query (224.0.0.251) will not match the source address
+ * of the incoming response (192.168.x.x or similar). The helper is not used
+ * for standard multicast queries/responses in which the sport and dport are
+ * both 5353, because those can be handled by a standard filter/INPUT rule.
+ *
+ * Usage:
+ *
+ * nfct add helper mdns inet udp
+ * iptables -t raw -A OUTPUT -p udp -d 224.0.0.251 '!' --sport 5353 \
+ * --dport 5353 -j CT --helper mdns
+ * iptables -t filter -A INPUT -p udp -d 224.0.0.251 --dport 5353 -j ACCEPT
+ * iptables -t filter -A INPUT -m state --state ESTABLISHED,RELATED \
+ * -j ACCEPT
+ *
+ * Requires Linux 3.12 or higher. NAT is unsupported.
+ *
+ * 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 "conntrackd.h"
+#include "helper.h"
+#include "myct.h"
+#include "log.h"
+
+#include <libnetfilter_conntrack/libnetfilter_conntrack.h>
+#include <linux/netfilter.h>
+
+static int mdns_helper_cb(struct pkt_buff *pkt, uint32_t protoff,
+ struct myct *myct, uint32_t ctinfo)
+{
+ struct nf_expect *exp;
+ int dir = CTINFO2DIR(ctinfo);
+ union nfct_attr_grp_addr saddr;
+ uint16_t sport, dport;
+
+ exp = nfexp_new();
+ if (exp == NULL) {
+ pr_debug("conntrack_mdns: failed to allocate expectation\n");
+ return NF_ACCEPT;
+ }
+
+ cthelper_get_addr_src(myct->ct, dir, &saddr);
+ cthelper_get_port_src(myct->ct, dir, &sport);
+ cthelper_get_port_src(myct->ct, !dir, &dport);
+
+ if (cthelper_expect_init(exp,
+ myct->ct,
+ 0 /* class */,
+ NULL /* saddr */,
+ &saddr /* daddr */,
+ IPPROTO_UDP,
+ &dport /* sport */,
+ &sport /* dport */,
+ NF_CT_EXPECT_PERMANENT)) {
+ pr_debug("conntrack_mdns: failed to init expectation\n");
+ nfexp_destroy(exp);
+ return NF_ACCEPT;
+ }
+
+ myct->exp = exp;
+ return NF_ACCEPT;
+}
+
+static struct ctd_helper mdns_helper = {
+ .name = "mdns",
+ .l4proto = IPPROTO_UDP,
+ .priv_data_len = 0,
+ .cb = mdns_helper_cb,
+ .policy = {
+ [0] = {
+ .name = "mdns",
+ .expect_max = 8,
+ .expect_timeout = 30,
+ },
+ },
+};
+
+static void __attribute__ ((constructor)) mdns_init(void)
+{
+ helper_register(&mdns_helper);
+}