Re: [PATCH] userspace SSDP conntrack helper

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



A quick question: do I need to change anything to allow responses from multiple devices, seeing as SSDP uses a multicast?

Does expect_max affect this?

Ash

On 08/03/14 15:59, Ash Hughes wrote:
> Hi,
> 
> Here is a patch which adds a userspace conntrack helper for the SSDP
> protocol. This is based on the code found at:
> 
> http://marc.info/?t=132945775100001&r=1&w=2
> 
> I'm not sure how to get my laptop to play at IPv6, so I've not tested
> this part, but I've tested the IPv4 section and it works. What more
> needs to be done to get this merged in? :)
> 
> To get this to work, I've followed the instructions here:
> 
> http://conntrack-tools.netfilter.org/manual.html#helpers
> 
> That is:
> 
> nfct helper add ssdp inet udp
> iptables --verbose -I OUTPUT 1 -t raw -p udp --dport 1900 -j CT --helper ssdp
> 
> And the following in conntrackd.conf:
> 
> Type ssdp inet udp {
> 	#
> 	# Set NFQUEUE number you want to use to receive traffic from
> 	# the kernel.
> 	#
> 	QueueNum 0
> 
> 	#
> 	# Maximum number of packets waiting in the queue to receive
> 	# a verdict from user-space. Default is 1024.
> 	#
> 	# Rise value if you hit the following error message:
> 	# "nf_queue: full at X entries, dropping packets(s)"
> 	#
> 	QueueLen 10240
> 
> 	#
> 	# Set the Expectation policy for this helper.
> 	#
> 	Policy ssdp {
> 		#
> 		# Maximum number of simultaneous expectations
> 		#
> 		ExpectMax 1
> 		#
> 		# Maximum living time for one expectation (in seconds).
> 		#
> 		ExpectTimeout 300
> 	}
> }
> 
> Thanks,
> 
> Ash
> 
> ---
> diff --git a/src/helpers/Makefile.am b/src/helpers/Makefile.am
> index fe28e83..947e58b 100644
> --- a/src/helpers/Makefile.am
> +++ b/src/helpers/Makefile.am
> @@ -6,7 +6,8 @@ pkglib_LTLIBRARIES = ct_helper_amanda.la \
>  		     ct_helper_rpc.la	\
>  		     ct_helper_tftp.la	\
>  		     ct_helper_tns.la	\
> -		     ct_helper_sane.la
> +		     ct_helper_sane.la  \
> +             ct_helper_ssdp.la
> 
>  ct_helper_amanda_la_SOURCES = amanda.c
>  ct_helper_amanda_la_LDFLAGS = -avoid-version -module $(LIBNETFILTER_CONNTRACK_LIBS)
> @@ -35,3 +36,7 @@ ct_helper_tns_la_CFLAGS = $(AM_CFLAGS) $(LIBNETFILTER_CONNTRACK_CFLAGS)
>  ct_helper_sane_la_SOURCES = sane.c
>  ct_helper_sane_la_LDFLAGS = -avoid-version -module $(LIBNETFILTER_CONNTRACK_LIBS)
>  ct_helper_sane_la_CFLAGS = $(AM_CFLAGS) $(LIBNETFILTER_CONNTRACK_CFLAGS)
> +
> +ct_helper_ssdp_la_SOURCES = ssdp.c
> +ct_helper_ssdp_la_LDFLAGS = -avoid-version -module $(LIBNETFILTER_CONNTRACK_LIBS)
> +ct_helper_ssdp_la_CFLAGS = $(AM_CFLAGS) $(LIBNETFILTER_CONNTRACK_CFLAGS)
> diff --git a/src/helpers/ssdp.c b/src/helpers/ssdp.c
> new file mode 100644
> index 0000000..0011f51
> --- /dev/null
> +++ b/src/helpers/ssdp.c
> @@ -0,0 +1,135 @@
> +/*
> + * SSDP connection tracking helper
> + * (SSDP = Simple Service Discovery Protocol)
> + * For documentation about SSDP see
> + * http://en.wikipedia.org/wiki/Simple_Service_Discovery_Protocol
> + *
> + * Copyright (C) 2014 Ashley Hughes <ashley.hughes@xxxxxxxxxxxxxxxx>
> + * Based on the SSDP conntrack helper (nf_conntrack_ssdp.c),
> + * :http://marc.info/?t=132945775100001&r=1&w=2
> + *  (C) 2012 Ian Pilcher <arequipeno@xxxxxxxxx>
> + *
> + * 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 <errno.h>
> +#include <arpa/inet.h>
> +#include <netinet/ip.h>
> +#include <netinet/udp.h>
> +#include <libmnl/libmnl.h>
> +#include <libnetfilter_conntrack/libnetfilter_conntrack.h>
> +#include <libnetfilter_queue/libnetfilter_queue.h>
> +#include <libnetfilter_queue/libnetfilter_queue_tcp.h>
> +#include <libnetfilter_queue/pktbuff.h>
> +#include <linux/netfilter.h>
> +
> +#define SSDP_MCAST_ADDR		"239.255.255.250"
> +#define UPNP_MCAST_LL_ADDR "FF02::C" /* link-local */
> +#define UPNP_MCAST_SL_ADDR "FF05::C" /* site-local */
> +
> +#define SSDP_M_SEARCH		"M-SEARCH"
> +#define SSDP_M_SEARCH_SIZE	(sizeof SSDP_M_SEARCH - 1)
> +
> +static int
> +ssdp_helper_cb(struct pkt_buff *pkt, uint32_t protoff,
> +		 struct myct *myct, uint32_t ctinfo)
> +{
> +
> +	int ret = NF_ACCEPT;
> +	union nfct_attr_grp_addr daddr, saddr, taddr;
> +    struct iphdr *net_hdr = (struct iphdr *)pktb_network_header(pkt);
> +    int good_packet = 0;
> +	struct nf_expect *exp;
> +    u_int16_t port;
> +	unsigned int dataoff;
> +	void *sb_ptr;
> +
> +    cthelper_get_addr_dst(myct->ct, MYCT_DIR_ORIG, &daddr);
> +    switch(nfct_get_attr_u8(myct->ct, ATTR_L3PROTO)) {
> +		case AF_INET:
> +            inet_pton(AF_INET, SSDP_MCAST_ADDR, &(taddr.ip));
> +            if (daddr.ip == taddr.ip)
> +                good_packet = 1;
> +			break;
> +		case AF_INET6:
> +            inet_pton(AF_INET6, UPNP_MCAST_LL_ADDR, &(taddr.ip6));
> +            if (daddr.ip6[0] == taddr.ip6[0] && daddr.ip6[1] == taddr.ip6[1]
> +                && daddr.ip6[2] == taddr.ip6[2] && daddr.ip6[3] == taddr.ip6[3]) {
> +                good_packet = 1;
> +                break;
> +            }
> +            inet_pton(AF_INET6, UPNP_MCAST_SL_ADDR, &(taddr.ip6));
> +            if (daddr.ip6[0] == taddr.ip6[0] && daddr.ip6[1] == taddr.ip6[1]
> +                && daddr.ip6[2] == taddr.ip6[2] && daddr.ip6[3] == taddr.ip6[3]) {
> +                good_packet = 1;
> +                break;
> +            }
> +			break;
> +		default:
> +			break;
> +    }
> +
> +    if (!good_packet) {
> +        pr_debug("ssdp_help: destination address not multicast; ignoring\n");
> +        return NF_ACCEPT;
> +    }
> +
> +    /* No data? Ignore */
> +	dataoff = net_hdr->ihl*4 + sizeof(struct udphdr);
> +	if (dataoff >= pktb_len(pkt)) {
> +		pr_debug("ssdp_help: UDP payload too small for M-SEARCH; ignoring\n");
> +		return NF_ACCEPT;
> +    }
> +
> +	sb_ptr = pktb_network_header(pkt) + dataoff;
> +
> +	if (memcmp(sb_ptr, SSDP_M_SEARCH, SSDP_M_SEARCH_SIZE) != 0) {
> +		pr_debug("ssdp_help: UDP payload does not begin with 'M-SEARCH'; ignoring\n");
> +		return NF_ACCEPT;
> +	}
> +
> +
> +
> +	cthelper_get_addr_src(myct->ct, MYCT_DIR_ORIG, &saddr);
> +    cthelper_get_port_src(myct->ct, MYCT_DIR_ORIG, &port);
> +
> +	exp = nfexp_new();
> +	if (exp == NULL)
> +		return NF_DROP;
> +
> +	if (cthelper_expect_init(exp, myct->ct, 0, NULL, &saddr,
> +				 IPPROTO_UDP, NULL, &port, 0)) {
> +		nfexp_destroy(exp);
> +		return NF_DROP;
> +	}
> +
> +    myct->exp = exp;
> +
> +	return ret;
> +}
> +
> +static struct ctd_helper ssdp_helper = {
> +	.name		= "ssdp",
> +	.l4proto	= IPPROTO_UDP,
> +	.priv_data_len	= 0,
> +	.cb		= ssdp_helper_cb,
> +	.policy		= {
> +		[0] = {
> +			.name			= "ssdp",
> +			.expect_max		= 1,
> +			.expect_timeout		= 5 * 60,
> +		},
> +	},
> +};
> +
> +static void __attribute__ ((constructor)) ssdp_init(void)
> +{
> +	helper_register(&ssdp_helper);
> +}
> +
> 
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Netfitler Users]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux