igmpproxy: move to trunk, add myself as maintainer
SVN-Revision: 40730
This commit is contained in:
		
							
								
								
									
										58
									
								
								package/network/services/igmpproxy/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								package/network/services/igmpproxy/Makefile
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,58 @@
 | 
			
		||||
#
 | 
			
		||||
# Copyright (C) 2006-2011 OpenWrt.org
 | 
			
		||||
#
 | 
			
		||||
# This is free software, licensed under the GNU General Public License v2.
 | 
			
		||||
# See /LICENSE for more information.
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
include $(TOPDIR)/rules.mk
 | 
			
		||||
 | 
			
		||||
PKG_NAME:=igmpproxy
 | 
			
		||||
PKG_VERSION:=0.1
 | 
			
		||||
PKG_RELEASE:=8
 | 
			
		||||
 | 
			
		||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 | 
			
		||||
PKG_SOURCE_URL:=@SF/igmpproxy
 | 
			
		||||
PKG_MD5SUM:=c56f41ec195bc1fe016369bf74efc5a1
 | 
			
		||||
PKG_MAINTAINER:=Felix Fietkau <nbd@openwrt.org>
 | 
			
		||||
 | 
			
		||||
include $(INCLUDE_DIR)/package.mk
 | 
			
		||||
 | 
			
		||||
PKG_FIXUP:=autoreconf
 | 
			
		||||
 | 
			
		||||
define Package/igmpproxy
 | 
			
		||||
  SECTION:=net
 | 
			
		||||
  CATEGORY:=Network
 | 
			
		||||
  SUBMENU:=Routing and Redirection
 | 
			
		||||
  DEPENDS:=+USE_EGLIBC:librt
 | 
			
		||||
  TITLE:=Multicast Routing Daemon
 | 
			
		||||
  URL:=http://sourceforge.net/projects/igmpproxy
 | 
			
		||||
endef
 | 
			
		||||
 | 
			
		||||
define Package/igmpproxy/description
 | 
			
		||||
	IGMPproxy is a simple dynamic Multicast Routing Daemon using
 | 
			
		||||
	only IGMP signalling (Internet Group Management Protocol).
 | 
			
		||||
endef
 | 
			
		||||
 | 
			
		||||
define Package/igmpproxy/conffiles
 | 
			
		||||
/etc/config/igmpproxy
 | 
			
		||||
endef
 | 
			
		||||
 | 
			
		||||
TARGET_CFLAGS += -Dlog=igmpproxy_log
 | 
			
		||||
 | 
			
		||||
define Build/Compile
 | 
			
		||||
	$(MAKE) -C $(PKG_BUILD_DIR)/src \
 | 
			
		||||
		CC="$(TARGET_CC)" \
 | 
			
		||||
		CFLAGS="$(TARGET_CFLAGS) -std=gnu99"
 | 
			
		||||
endef
 | 
			
		||||
 | 
			
		||||
define Package/igmpproxy/install
 | 
			
		||||
	$(INSTALL_DIR) $(1)/etc/config
 | 
			
		||||
	$(INSTALL_CONF) ./files/igmpproxy.config $(1)/etc/config/igmpproxy
 | 
			
		||||
	$(INSTALL_DIR) $(1)/etc/init.d
 | 
			
		||||
	$(INSTALL_BIN) ./files/igmpproxy.init $(1)/etc/init.d/igmpproxy
 | 
			
		||||
	$(INSTALL_DIR) $(1)/usr/sbin
 | 
			
		||||
	$(INSTALL_BIN) $(PKG_BUILD_DIR)/src/igmpproxy $(1)/usr/sbin/
 | 
			
		||||
endef
 | 
			
		||||
 | 
			
		||||
$(eval $(call BuildPackage,igmpproxy))
 | 
			
		||||
							
								
								
									
										11
									
								
								package/network/services/igmpproxy/files/igmpproxy.config
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								package/network/services/igmpproxy/files/igmpproxy.config
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
			
		||||
config igmpproxy
 | 
			
		||||
	option quickleave 1
 | 
			
		||||
 | 
			
		||||
config phyint
 | 
			
		||||
	option network wan
 | 
			
		||||
	option direction upstream
 | 
			
		||||
	list altnet 192.168.1.0/24
 | 
			
		||||
 | 
			
		||||
config phyint
 | 
			
		||||
	option network lan
 | 
			
		||||
	option direction downstream
 | 
			
		||||
							
								
								
									
										63
									
								
								package/network/services/igmpproxy/files/igmpproxy.init
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								package/network/services/igmpproxy/files/igmpproxy.init
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,63 @@
 | 
			
		||||
#!/bin/sh /etc/rc.common
 | 
			
		||||
# Copyright (C) 2010-2012 OpenWrt.org
 | 
			
		||||
 | 
			
		||||
START=99
 | 
			
		||||
STOP=10
 | 
			
		||||
 | 
			
		||||
SERVICE_DAEMONIZE=1
 | 
			
		||||
SERVICE_WRITE_PID=1
 | 
			
		||||
 | 
			
		||||
# igmpproxy supports both a debug mode and verbosity, which are very useful
 | 
			
		||||
# when something isn't working.
 | 
			
		||||
#
 | 
			
		||||
# Debug mode will print everything to stdout instead of syslog. Generally
 | 
			
		||||
# verbosity should NOT be set as it will quickly fill your syslog.
 | 
			
		||||
#
 | 
			
		||||
# Put any debug or verbosity options into IGMP_OPTS
 | 
			
		||||
#
 | 
			
		||||
# Examples:
 | 
			
		||||
# OPTIONS="-d -v -v" - debug mode and very verbose, this will land in
 | 
			
		||||
#                        stdout and not in syslog
 | 
			
		||||
# OPTIONS="-v" - be verbose, this will write aditional information to syslog
 | 
			
		||||
 | 
			
		||||
OPTIONS=""
 | 
			
		||||
 | 
			
		||||
igmp_header() {
 | 
			
		||||
	local quickleave
 | 
			
		||||
	config_get_bool quickleave "$1" quickleave 0
 | 
			
		||||
 | 
			
		||||
	mkdir -p /var/etc
 | 
			
		||||
	rm -f /var/etc/igmpproxy.conf
 | 
			
		||||
	[ $quickleave -gt 0 ] && echo "quickleave" >> /var/etc/igmpproxy.conf
 | 
			
		||||
 | 
			
		||||
	[ -L /etc/igmpproxy.conf ] || ln -nsf /var/etc/igmpproxy.conf /etc/igmpproxy.conf
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
igmp_add_phyint() {
 | 
			
		||||
        local network direction altnets
 | 
			
		||||
 | 
			
		||||
        config_get network $1 network
 | 
			
		||||
        config_get direction $1 direction
 | 
			
		||||
        config_get altnets $1 altnet
 | 
			
		||||
 | 
			
		||||
        device=$(uci_get_state network "$network" ifname "$network")
 | 
			
		||||
        echo -e "\nphyint $device $direction ratelimit 0 threshold 1" >> /var/etc/igmpproxy.conf
 | 
			
		||||
 | 
			
		||||
        if [ -n "$altnets" ]; then
 | 
			
		||||
                local altnet
 | 
			
		||||
                for altnet in $altnets; do
 | 
			
		||||
                        echo -e "\taltnet $altnet" >> /var/etc/igmpproxy.conf
 | 
			
		||||
                done
 | 
			
		||||
        fi
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
start() {
 | 
			
		||||
	config_load igmpproxy
 | 
			
		||||
	config_foreach igmp_header igmpproxy
 | 
			
		||||
	config_foreach igmp_add_phyint phyint
 | 
			
		||||
	service_start /usr/sbin/igmpproxy $OPTIONS /etc/igmpproxy.conf
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
stop() {
 | 
			
		||||
	service_stop /usr/sbin/igmpproxy
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,79 @@
 | 
			
		||||
From fed8c3db10bc9d3a1e799a774924c00522595d0c Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Evgeny Yurchenko <evg.yurch@rogers.com>
 | 
			
		||||
Date: Mon, 4 Jan 2010 05:13:59 +0500
 | 
			
		||||
Subject: [PATCH] Send IGMP packets with IP Router Alert option [RFC 2113] included in IP header
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 src/igmp.c      |   17 ++++++++++++-----
 | 
			
		||||
 src/igmpproxy.h |    1 +
 | 
			
		||||
 2 files changed, 13 insertions(+), 5 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/src/igmp.c b/src/igmp.c
 | 
			
		||||
index a0cd27d..b547688 100644
 | 
			
		||||
--- a/src/igmp.c
 | 
			
		||||
+++ b/src/igmp.c
 | 
			
		||||
@@ -67,7 +67,7 @@ void initIgmp() {
 | 
			
		||||
      * - Checksum (let the kernel fill it in)
 | 
			
		||||
      */
 | 
			
		||||
     ip->ip_v   = IPVERSION;
 | 
			
		||||
-    ip->ip_hl  = sizeof(struct ip) >> 2;
 | 
			
		||||
+    ip->ip_hl  = (sizeof(struct ip) + 4) >> 2; /* +4 for Router Alert option */
 | 
			
		||||
     ip->ip_tos = 0xc0;      /* Internet Control */
 | 
			
		||||
     ip->ip_ttl = MAXTTL;    /* applies to unicasts only */
 | 
			
		||||
     ip->ip_p   = IPPROTO_IGMP;
 | 
			
		||||
@@ -213,7 +213,7 @@ void buildIgmp(uint32_t src, uint32_t dst, int type, int code, uint32_t group, i
 | 
			
		||||
     ip                      = (struct ip *)send_buf;
 | 
			
		||||
     ip->ip_src.s_addr       = src;
 | 
			
		||||
     ip->ip_dst.s_addr       = dst;
 | 
			
		||||
-    ip_set_len(ip, MIN_IP_HEADER_LEN + IGMP_MINLEN + datalen);
 | 
			
		||||
+    ip_set_len(ip, IP_HEADER_RAOPT_LEN + IGMP_MINLEN + datalen);
 | 
			
		||||
 
 | 
			
		||||
     if (IN_MULTICAST(ntohl(dst))) {
 | 
			
		||||
         ip->ip_ttl = curttl;
 | 
			
		||||
@@ -221,13 +221,20 @@ void buildIgmp(uint32_t src, uint32_t dst, int type, int code, uint32_t group, i
 | 
			
		||||
         ip->ip_ttl = MAXTTL;
 | 
			
		||||
     }
 | 
			
		||||
 
 | 
			
		||||
-    igmp                    = (struct igmp *)(send_buf + MIN_IP_HEADER_LEN);
 | 
			
		||||
+    /* Add Router Alert option */
 | 
			
		||||
+    ((u_char*)send_buf+MIN_IP_HEADER_LEN)[0] = IPOPT_RA;
 | 
			
		||||
+    ((u_char*)send_buf+MIN_IP_HEADER_LEN)[1] = 0x04;
 | 
			
		||||
+    ((u_char*)send_buf+MIN_IP_HEADER_LEN)[2] = 0x00;
 | 
			
		||||
+    ((u_char*)send_buf+MIN_IP_HEADER_LEN)[3] = 0x00;
 | 
			
		||||
+
 | 
			
		||||
+    igmp                    = (struct igmp *)(send_buf + IP_HEADER_RAOPT_LEN);
 | 
			
		||||
     igmp->igmp_type         = type;
 | 
			
		||||
     igmp->igmp_code         = code;
 | 
			
		||||
     igmp->igmp_group.s_addr = group;
 | 
			
		||||
     igmp->igmp_cksum        = 0;
 | 
			
		||||
     igmp->igmp_cksum        = inetChksum((u_short *)igmp,
 | 
			
		||||
-                                         IGMP_MINLEN + datalen);
 | 
			
		||||
+                                         IP_HEADER_RAOPT_LEN + datalen);
 | 
			
		||||
+
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 /* 
 | 
			
		||||
@@ -257,7 +264,7 @@ void sendIgmp(uint32_t src, uint32_t dst, int type, int code, uint32_t group, in
 | 
			
		||||
 #endif
 | 
			
		||||
     sdst.sin_addr.s_addr = dst;
 | 
			
		||||
     if (sendto(MRouterFD, send_buf,
 | 
			
		||||
-               MIN_IP_HEADER_LEN + IGMP_MINLEN + datalen, 0,
 | 
			
		||||
+               IP_HEADER_RAOPT_LEN + IGMP_MINLEN + datalen, 0,
 | 
			
		||||
                (struct sockaddr *)&sdst, sizeof(sdst)) < 0) {
 | 
			
		||||
         if (errno == ENETDOWN)
 | 
			
		||||
             my_log(LOG_ERR, errno, "Sender VIF was down.");
 | 
			
		||||
diff --git a/src/igmpproxy.h b/src/igmpproxy.h
 | 
			
		||||
index 0de7791..4df8a79 100644
 | 
			
		||||
--- a/src/igmpproxy.h
 | 
			
		||||
+++ b/src/igmpproxy.h
 | 
			
		||||
@@ -64,6 +64,7 @@
 | 
			
		||||
 #define MAX_IP_PACKET_LEN	576
 | 
			
		||||
 #define MIN_IP_HEADER_LEN	20
 | 
			
		||||
 #define MAX_IP_HEADER_LEN	60
 | 
			
		||||
+#define IP_HEADER_RAOPT_LEN	24
 | 
			
		||||
 
 | 
			
		||||
 #define MAX_MC_VIFS    32     // !!! check this const in the specific includes
 | 
			
		||||
 
 | 
			
		||||
-- 
 | 
			
		||||
1.7.2.5
 | 
			
		||||
 | 
			
		||||
@@ -0,0 +1,43 @@
 | 
			
		||||
From 85e240727305b156097ee7aa0f0c4473a136291f Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Constantin Baranov <const@mimas.ru>
 | 
			
		||||
Date: Tue, 23 Feb 2010 21:08:02 +0400
 | 
			
		||||
Subject: [PATCH] Change default interface state to disabled (wrt #2945877)
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 src/ifvc.c      |    2 +-
 | 
			
		||||
 src/igmpproxy.c |    6 ++++--
 | 
			
		||||
 2 files changed, 5 insertions(+), 3 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/src/ifvc.c b/src/ifvc.c
 | 
			
		||||
index 545b3b4..9d7ee97 100644
 | 
			
		||||
--- a/src/ifvc.c
 | 
			
		||||
+++ b/src/ifvc.c
 | 
			
		||||
@@ -139,7 +139,7 @@ void buildIfVc() {
 | 
			
		||||
             IfDescEp->allowednets->subnet_addr = subnet;
 | 
			
		||||
 
 | 
			
		||||
             // Set the default params for the IF...
 | 
			
		||||
-            IfDescEp->state         = IF_STATE_DOWNSTREAM;
 | 
			
		||||
+            IfDescEp->state         = IF_STATE_DISABLED;
 | 
			
		||||
             IfDescEp->robustness    = DEFAULT_ROBUSTNESS;
 | 
			
		||||
             IfDescEp->threshold     = DEFAULT_THRESHOLD;   /* ttl limit */
 | 
			
		||||
             IfDescEp->ratelimit     = DEFAULT_RATELIMIT; 
 | 
			
		||||
diff --git a/src/igmpproxy.c b/src/igmpproxy.c
 | 
			
		||||
index 1ece15a..35000c7 100644
 | 
			
		||||
--- a/src/igmpproxy.c
 | 
			
		||||
+++ b/src/igmpproxy.c
 | 
			
		||||
@@ -186,8 +186,10 @@ int igmpProxyInit() {
 | 
			
		||||
                     }
 | 
			
		||||
                 }
 | 
			
		||||
 
 | 
			
		||||
-                addVIF( Dp );
 | 
			
		||||
-                vifcount++;
 | 
			
		||||
+                if (Dp->state != IF_STATE_DISABLED) {
 | 
			
		||||
+                    addVIF( Dp );
 | 
			
		||||
+                    vifcount++;
 | 
			
		||||
+                }
 | 
			
		||||
             }
 | 
			
		||||
         }
 | 
			
		||||
 
 | 
			
		||||
-- 
 | 
			
		||||
1.7.2.5
 | 
			
		||||
 | 
			
		||||
@@ -0,0 +1,164 @@
 | 
			
		||||
From 65f777e7f66b55239d935c1cf81bb5abc0f6c89f Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Grinch <grinch79@users.sourceforge.net>
 | 
			
		||||
Date: Sun, 16 Aug 2009 19:58:26 +0500
 | 
			
		||||
Subject: [PATCH] Restrict igmp reports for downstream interfaces (wrt #2833339)
 | 
			
		||||
 | 
			
		||||
atm all igmp membership reports are forwarded to the upstream interface.
 | 
			
		||||
Unfortunately some ISP Providers restrict some multicast groups (esp. those
 | 
			
		||||
that are defined as local link groups and that are not supposed to be
 | 
			
		||||
forwarded to the wan, i.e 224.0.0.0/24). Therefore there should be some
 | 
			
		||||
kind of black oder whitelisting.
 | 
			
		||||
As whitelisting can be accomplished quite easy I wrote a litte patch, which
 | 
			
		||||
is attached to this request.
 | 
			
		||||
---
 | 
			
		||||
 doc/igmpproxy.conf.5.in |   19 +++++++++++++++++++
 | 
			
		||||
 src/config.c            |   23 ++++++++++++++++++++++-
 | 
			
		||||
 src/igmpproxy.h         |    1 +
 | 
			
		||||
 src/request.c           |   20 ++++++++++++++++----
 | 
			
		||||
 4 files changed, 58 insertions(+), 5 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/doc/igmpproxy.conf.5.in b/doc/igmpproxy.conf.5.in
 | 
			
		||||
index a4ea7d0..56efa22 100644
 | 
			
		||||
--- a/doc/igmpproxy.conf.5.in
 | 
			
		||||
+++ b/doc/igmpproxy.conf.5.in
 | 
			
		||||
@@ -116,6 +116,25 @@ This is especially useful for the upstream interface, since the source for multi
 | 
			
		||||
 traffic is often from a remote location. Any number of altnet parameters can be specified.
 | 
			
		||||
 .RE
 | 
			
		||||
 
 | 
			
		||||
+.B whitelist
 | 
			
		||||
+.I networkaddr
 | 
			
		||||
+.RS
 | 
			
		||||
+Defines a whitelist for multicast groups. The network address must be in the following
 | 
			
		||||
+format 'a.b.c.d/n'. If you want to allow one single group use a network mask of /32,
 | 
			
		||||
+i.e. 'a.b.c.d/32'. 
 | 
			
		||||
+
 | 
			
		||||
+By default all multicast groups are allowed on any downstream interface. If at least one
 | 
			
		||||
+whitelist entry is defined, all igmp membership reports for not explicitly whitelisted
 | 
			
		||||
+multicast groups will be ignored and therefore not be served by igmpproxy. This is especially
 | 
			
		||||
+useful, if your provider does only allow a predefined set of multicast groups. These whitelists
 | 
			
		||||
+are only obeyed by igmpproxy itself, they won't prevent any other igmp client running on the
 | 
			
		||||
+same machine as igmpproxy from requesting 'unallowed' multicast groups.
 | 
			
		||||
+
 | 
			
		||||
+You may specify as many whitelist entries as needed. Although you should keep it as simple as
 | 
			
		||||
+possible, as this list is parsed for every membership report and therefore this increases igmp
 | 
			
		||||
+response times. Often used or large groups should be defined first, as parsing ends as soon as
 | 
			
		||||
+a group matches an entry.
 | 
			
		||||
+.RE
 | 
			
		||||
 
 | 
			
		||||
 .SH EXAMPLE
 | 
			
		||||
 ## Enable quickleave
 | 
			
		||||
diff --git a/src/config.c b/src/config.c
 | 
			
		||||
index 5a96ce0..d72619f 100644
 | 
			
		||||
--- a/src/config.c
 | 
			
		||||
+++ b/src/config.c
 | 
			
		||||
@@ -46,6 +46,9 @@ struct vifconfig {
 | 
			
		||||
 
 | 
			
		||||
     // Keep allowed nets for VIF.
 | 
			
		||||
     struct SubnetList*  allowednets;
 | 
			
		||||
+
 | 
			
		||||
+    // Allowed Groups
 | 
			
		||||
+    struct SubnetList*  allowedgroups;
 | 
			
		||||
     
 | 
			
		||||
     // Next config in list...
 | 
			
		||||
     struct vifconfig*   next;
 | 
			
		||||
@@ -202,6 +205,8 @@ void configureVifs() {
 | 
			
		||||
                     // Insert the configured nets...
 | 
			
		||||
                     vifLast->next = confPtr->allowednets;
 | 
			
		||||
 
 | 
			
		||||
+		    Dp->allowedgroups = confPtr->allowedgroups;
 | 
			
		||||
+
 | 
			
		||||
                     break;
 | 
			
		||||
                 }
 | 
			
		||||
             }
 | 
			
		||||
@@ -215,7 +220,7 @@ void configureVifs() {
 | 
			
		||||
 */
 | 
			
		||||
 struct vifconfig *parsePhyintToken() {
 | 
			
		||||
     struct vifconfig  *tmpPtr;
 | 
			
		||||
-    struct SubnetList **anetPtr;
 | 
			
		||||
+    struct SubnetList **anetPtr, **agrpPtr;
 | 
			
		||||
     char *token;
 | 
			
		||||
     short parseError = 0;
 | 
			
		||||
 
 | 
			
		||||
@@ -239,6 +244,7 @@ struct vifconfig *parsePhyintToken() {
 | 
			
		||||
     tmpPtr->threshold = 1;
 | 
			
		||||
     tmpPtr->state = IF_STATE_DOWNSTREAM;
 | 
			
		||||
     tmpPtr->allowednets = NULL;
 | 
			
		||||
+    tmpPtr->allowedgroups = NULL;
 | 
			
		||||
 
 | 
			
		||||
     // Make a copy of the token to store the IF name
 | 
			
		||||
     tmpPtr->name = strdup( token );
 | 
			
		||||
@@ -248,6 +254,7 @@ struct vifconfig *parsePhyintToken() {
 | 
			
		||||
 
 | 
			
		||||
     // Set the altnet pointer to the allowednets pointer.
 | 
			
		||||
     anetPtr = &tmpPtr->allowednets;
 | 
			
		||||
+    agrpPtr = &tmpPtr->allowedgroups; 
 | 
			
		||||
 
 | 
			
		||||
     // Parse the rest of the config..
 | 
			
		||||
     token = nextConfigToken();
 | 
			
		||||
@@ -266,6 +273,20 @@ struct vifconfig *parsePhyintToken() {
 | 
			
		||||
                 anetPtr = &(*anetPtr)->next;
 | 
			
		||||
             }
 | 
			
		||||
         }
 | 
			
		||||
+	else if(strcmp("whitelist", token)==0) {
 | 
			
		||||
+	    // Whitelist
 | 
			
		||||
+	    token = nextConfigToken();
 | 
			
		||||
+	    my_log(LOG_DEBUG, 0, "Config: IF: Got whitelist token %s.", token);
 | 
			
		||||
+	
 | 
			
		||||
+	    *agrpPtr = parseSubnetAddress(token);
 | 
			
		||||
+	    if(*agrpPtr == NULL) {
 | 
			
		||||
+		parseError = 1;
 | 
			
		||||
+		my_log(LOG_WARNING, 0, "Unable to parse subnet address.");
 | 
			
		||||
+		break;
 | 
			
		||||
+	    } else {
 | 
			
		||||
+		agrpPtr = &(*agrpPtr)->next;
 | 
			
		||||
+	    }
 | 
			
		||||
+	}
 | 
			
		||||
         else if(strcmp("upstream", token)==0) {
 | 
			
		||||
             // Upstream
 | 
			
		||||
             my_log(LOG_DEBUG, 0, "Config: IF: Got upstream token.");
 | 
			
		||||
diff --git a/src/igmpproxy.h b/src/igmpproxy.h
 | 
			
		||||
index 4dabd1c..0de7791 100644
 | 
			
		||||
--- a/src/igmpproxy.h
 | 
			
		||||
+++ b/src/igmpproxy.h
 | 
			
		||||
@@ -145,6 +145,7 @@ struct IfDesc {
 | 
			
		||||
     short               Flags;
 | 
			
		||||
     short               state;
 | 
			
		||||
     struct SubnetList*  allowednets;
 | 
			
		||||
+    struct SubnetList*  allowedgroups;
 | 
			
		||||
     unsigned int        robustness;
 | 
			
		||||
     unsigned char       threshold;   /* ttl limit */
 | 
			
		||||
     unsigned int        ratelimit; 
 | 
			
		||||
diff --git a/src/request.c b/src/request.c
 | 
			
		||||
index e3589f6..89b91de 100644
 | 
			
		||||
--- a/src/request.c
 | 
			
		||||
+++ b/src/request.c
 | 
			
		||||
@@ -82,10 +82,22 @@ void acceptGroupReport(uint32_t src, uint32_t group, uint8_t type) {
 | 
			
		||||
         my_log(LOG_DEBUG, 0, "Should insert group %s (from: %s) to route table. Vif Ix : %d",
 | 
			
		||||
             inetFmt(group,s1), inetFmt(src,s2), sourceVif->index);
 | 
			
		||||
 
 | 
			
		||||
-        // The membership report was OK... Insert it into the route table..
 | 
			
		||||
-        insertRoute(group, sourceVif->index);
 | 
			
		||||
-
 | 
			
		||||
-
 | 
			
		||||
+	// If we don't have a whitelist we insertRoute and done
 | 
			
		||||
+	if(sourceVif->allowedgroups == NULL)
 | 
			
		||||
+	{
 | 
			
		||||
+	    insertRoute(group, sourceVif->index);
 | 
			
		||||
+	    return;
 | 
			
		||||
+	}
 | 
			
		||||
+	// Check if this Request is legit on this interface
 | 
			
		||||
+	struct SubnetList *sn;
 | 
			
		||||
+	for(sn = sourceVif->allowedgroups; sn != NULL; sn = sn->next)
 | 
			
		||||
+	    if((group & sn->subnet_mask) == sn->subnet_addr)
 | 
			
		||||
+	    {
 | 
			
		||||
+        	// The membership report was OK... Insert it into the route table..
 | 
			
		||||
+        	insertRoute(group, sourceVif->index);
 | 
			
		||||
+		return;
 | 
			
		||||
+	    }
 | 
			
		||||
+	my_log(LOG_INFO, 0, "The group address %s may not be requested from this interface. Ignoring.", inetFmt(group, s1));
 | 
			
		||||
     } else {
 | 
			
		||||
         // Log the state of the interface the report was recieved on.
 | 
			
		||||
         my_log(LOG_INFO, 0, "Mebership report was recieved on %s. Ignoring.",
 | 
			
		||||
-- 
 | 
			
		||||
1.7.2.5
 | 
			
		||||
 | 
			
		||||
@@ -0,0 +1,62 @@
 | 
			
		||||
From bcd7c648e86d97263c931de53a008c9629e7797e Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Stefan Becker <stefan.becker@nokia.com>
 | 
			
		||||
Date: Fri, 11 Dec 2009 21:08:57 +0200
 | 
			
		||||
Subject: [PATCH] Restrict igmp reports forwarding to upstream interface
 | 
			
		||||
 | 
			
		||||
Utilize the new "whitelist" keyword also on the upstream interface definition.
 | 
			
		||||
If specified then only whitelisted multicast groups will be forwarded upstream.
 | 
			
		||||
 | 
			
		||||
This can be used to avoid publishing private multicast groups to the world,
 | 
			
		||||
e.g. SSDP from a UPnP server on the internal network.
 | 
			
		||||
---
 | 
			
		||||
 doc/igmpproxy.conf.5.in |    5 +++++
 | 
			
		||||
 src/rttable.c           |   17 +++++++++++++++++
 | 
			
		||||
 2 files changed, 22 insertions(+), 0 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/doc/igmpproxy.conf.5.in b/doc/igmpproxy.conf.5.in
 | 
			
		||||
index 56efa22..d916f05 100644
 | 
			
		||||
--- a/doc/igmpproxy.conf.5.in
 | 
			
		||||
+++ b/doc/igmpproxy.conf.5.in
 | 
			
		||||
@@ -134,6 +134,11 @@ You may specify as many whitelist entries as needed. Although you should keep it
 | 
			
		||||
 possible, as this list is parsed for every membership report and therefore this increases igmp
 | 
			
		||||
 response times. Often used or large groups should be defined first, as parsing ends as soon as
 | 
			
		||||
 a group matches an entry.
 | 
			
		||||
+
 | 
			
		||||
+You may also specify whitelist entries for the upstream interface. Only igmp membership reports
 | 
			
		||||
+for explicitely whitelisted multicast groups will be sent out on the upstream interface. This
 | 
			
		||||
+is useful if you want to use multicast groups only between your downstream interfaces, like SSDP
 | 
			
		||||
+from a UPnP server.
 | 
			
		||||
 .RE
 | 
			
		||||
 
 | 
			
		||||
 .SH EXAMPLE
 | 
			
		||||
diff --git a/src/rttable.c b/src/rttable.c
 | 
			
		||||
index f0701a8..77dd791 100644
 | 
			
		||||
--- a/src/rttable.c
 | 
			
		||||
+++ b/src/rttable.c
 | 
			
		||||
@@ -117,6 +117,23 @@ void sendJoinLeaveUpstream(struct RouteTable* route, int join) {
 | 
			
		||||
         my_log(LOG_ERR, 0 ,"FATAL: Unable to get Upstream IF.");
 | 
			
		||||
     }
 | 
			
		||||
 
 | 
			
		||||
+    // Check if there is a white list for the upstram VIF
 | 
			
		||||
+    if (upstrIf->allowedgroups != NULL) {
 | 
			
		||||
+      uint32_t           group = route->group;
 | 
			
		||||
+        struct SubnetList* sn;
 | 
			
		||||
+
 | 
			
		||||
+        // Check if this Request is legit to be forwarded to upstream
 | 
			
		||||
+        for(sn = upstrIf->allowedgroups; sn != NULL; sn = sn->next)
 | 
			
		||||
+            if((group & sn->subnet_mask) == sn->subnet_addr)
 | 
			
		||||
+                // Forward is OK...
 | 
			
		||||
+                break;
 | 
			
		||||
+
 | 
			
		||||
+        if (sn == NULL) {
 | 
			
		||||
+	    my_log(LOG_INFO, 0, "The group address %s may not be forwarded upstream. Ignoring.", inetFmt(group, s1));
 | 
			
		||||
+            return;
 | 
			
		||||
+        }
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
     // Send join or leave request...
 | 
			
		||||
     if(join) {
 | 
			
		||||
 
 | 
			
		||||
-- 
 | 
			
		||||
1.7.2.5
 | 
			
		||||
 | 
			
		||||
@@ -0,0 +1,120 @@
 | 
			
		||||
From d0e66e0719ae8eb549f7cc220fdc66575d3db332 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Jonas Gorski <jonas.gorski@gmail.com>
 | 
			
		||||
Date: Thu, 29 Mar 2012 17:01:11 +0200
 | 
			
		||||
Subject: [PATCH 4/4] use monotic clock instead of time of day
 | 
			
		||||
 | 
			
		||||
The time of day might chance e.g. by daylight savings time during the
 | 
			
		||||
runtime, which causes timers to fire repeatedly for a long time.
 | 
			
		||||
 | 
			
		||||
Contributed by T-Labs, Deutsche Telekom Innovation Laboratories
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
 | 
			
		||||
---
 | 
			
		||||
 configure.ac    |    2 ++
 | 
			
		||||
 src/igmpproxy.c |   26 +++++++++++++-------------
 | 
			
		||||
 src/igmpproxy.h |    3 ++-
 | 
			
		||||
 3 files changed, 17 insertions(+), 14 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/configure.ac b/configure.ac
 | 
			
		||||
index 85beb08..bd84eba 100644
 | 
			
		||||
--- a/configure.ac
 | 
			
		||||
+++ b/configure.ac
 | 
			
		||||
@@ -25,6 +25,8 @@ AC_CHECK_MEMBERS([struct sockaddr_in.sin_len], [], [], [[
 | 
			
		||||
 #include <netinet/in.h>
 | 
			
		||||
 ]])
 | 
			
		||||
 
 | 
			
		||||
+AC_SEARCH_LIBS([clock_gettime],[rt])
 | 
			
		||||
+
 | 
			
		||||
 AC_CONFIG_FILES([
 | 
			
		||||
 	Makefile
 | 
			
		||||
 	doc/Makefile
 | 
			
		||||
diff --git a/src/igmpproxy.c b/src/igmpproxy.c
 | 
			
		||||
index 35000c7..3a9ccad 100644
 | 
			
		||||
--- a/src/igmpproxy.c
 | 
			
		||||
+++ b/src/igmpproxy.c
 | 
			
		||||
@@ -234,13 +234,13 @@ void igmpProxyRun() {
 | 
			
		||||
     int     MaxFD, Rt, secs;
 | 
			
		||||
     fd_set  ReadFDS;
 | 
			
		||||
     socklen_t dummy = 0;
 | 
			
		||||
-    struct  timeval  curtime, lasttime, difftime, tv; 
 | 
			
		||||
+    struct  timespec  curtime, lasttime, difftime, tv; 
 | 
			
		||||
     // The timeout is a pointer in order to set it to NULL if nessecary.
 | 
			
		||||
-    struct  timeval  *timeout = &tv;
 | 
			
		||||
+    struct  timespec  *timeout = &tv;
 | 
			
		||||
 
 | 
			
		||||
     // Initialize timer vars
 | 
			
		||||
-    difftime.tv_usec = 0;
 | 
			
		||||
-    gettimeofday(&curtime, NULL);
 | 
			
		||||
+    difftime.tv_nsec = 0;
 | 
			
		||||
+    clock_gettime(CLOCK_MONOTONIC, &curtime);
 | 
			
		||||
     lasttime = curtime;
 | 
			
		||||
 
 | 
			
		||||
     // First thing we send a membership query in downstream VIF's...
 | 
			
		||||
@@ -263,7 +263,7 @@ void igmpProxyRun() {
 | 
			
		||||
         if(secs == -1) {
 | 
			
		||||
             timeout = NULL;
 | 
			
		||||
         } else {
 | 
			
		||||
-            timeout->tv_usec = 0;
 | 
			
		||||
+            timeout->tv_nsec = 0;
 | 
			
		||||
             timeout->tv_sec = secs;
 | 
			
		||||
         }
 | 
			
		||||
 
 | 
			
		||||
@@ -274,7 +274,7 @@ void igmpProxyRun() {
 | 
			
		||||
         FD_SET( MRouterFD, &ReadFDS );
 | 
			
		||||
 
 | 
			
		||||
         // wait for input
 | 
			
		||||
-        Rt = select( MaxFD +1, &ReadFDS, NULL, NULL, timeout );
 | 
			
		||||
+        Rt = pselect( MaxFD +1, &ReadFDS, NULL, NULL, timeout, NULL );
 | 
			
		||||
 
 | 
			
		||||
         // log and ignore failures
 | 
			
		||||
         if( Rt < 0 ) {
 | 
			
		||||
@@ -307,20 +307,20 @@ void igmpProxyRun() {
 | 
			
		||||
              */
 | 
			
		||||
             if (Rt == 0) {
 | 
			
		||||
                 curtime.tv_sec = lasttime.tv_sec + secs;
 | 
			
		||||
-                curtime.tv_usec = lasttime.tv_usec;
 | 
			
		||||
+                curtime.tv_nsec = lasttime.tv_nsec;
 | 
			
		||||
                 Rt = -1; /* don't do this next time through the loop */
 | 
			
		||||
             } else {
 | 
			
		||||
-                gettimeofday(&curtime, NULL);
 | 
			
		||||
+                clock_gettime(CLOCK_MONOTONIC, &curtime);
 | 
			
		||||
             }
 | 
			
		||||
             difftime.tv_sec = curtime.tv_sec - lasttime.tv_sec;
 | 
			
		||||
-            difftime.tv_usec += curtime.tv_usec - lasttime.tv_usec;
 | 
			
		||||
-            while (difftime.tv_usec > 1000000) {
 | 
			
		||||
+            difftime.tv_nsec += curtime.tv_nsec - lasttime.tv_nsec;
 | 
			
		||||
+            while (difftime.tv_nsec > 1000000000) {
 | 
			
		||||
                 difftime.tv_sec++;
 | 
			
		||||
-                difftime.tv_usec -= 1000000;
 | 
			
		||||
+                difftime.tv_nsec -= 1000000000;
 | 
			
		||||
             }
 | 
			
		||||
-            if (difftime.tv_usec < 0) {
 | 
			
		||||
+            if (difftime.tv_nsec < 0) {
 | 
			
		||||
                 difftime.tv_sec--;
 | 
			
		||||
-                difftime.tv_usec += 1000000;
 | 
			
		||||
+                difftime.tv_nsec += 1000000000;
 | 
			
		||||
             }
 | 
			
		||||
             lasttime = curtime;
 | 
			
		||||
             if (secs == 0 || difftime.tv_sec > 0)
 | 
			
		||||
diff --git a/src/igmpproxy.h b/src/igmpproxy.h
 | 
			
		||||
index 4df8a79..36a4f04 100644
 | 
			
		||||
--- a/src/igmpproxy.h
 | 
			
		||||
+++ b/src/igmpproxy.h
 | 
			
		||||
@@ -44,12 +44,13 @@
 | 
			
		||||
 #include <string.h>
 | 
			
		||||
 #include <fcntl.h>
 | 
			
		||||
 #include <stdbool.h>
 | 
			
		||||
+#include <time.h>
 | 
			
		||||
 
 | 
			
		||||
 #include <sys/socket.h>
 | 
			
		||||
 #include <sys/un.h>
 | 
			
		||||
-#include <sys/time.h>
 | 
			
		||||
 #include <sys/ioctl.h>
 | 
			
		||||
 #include <sys/param.h>
 | 
			
		||||
+#include <sys/select.h>
 | 
			
		||||
 
 | 
			
		||||
 #include <net/if.h>
 | 
			
		||||
 #include <netinet/in.h>
 | 
			
		||||
-- 
 | 
			
		||||
1.7.2.5
 | 
			
		||||
 | 
			
		||||
@@ -0,0 +1,24 @@
 | 
			
		||||
--- a/src/config.c
 | 
			
		||||
+++ b/src/config.c
 | 
			
		||||
@@ -357,15 +357,18 @@ struct SubnetList *parseSubnetAddress(ch
 | 
			
		||||
     tmpStr = strtok(NULL, "/");
 | 
			
		||||
     if(tmpStr != NULL) {
 | 
			
		||||
         int bitcnt = atoi(tmpStr);
 | 
			
		||||
-        if(bitcnt <= 0 || bitcnt > 32) {
 | 
			
		||||
+        if(bitcnt < 0 || bitcnt > 32) {
 | 
			
		||||
             my_log(LOG_WARNING, 0, "The bits part of the address is invalid : %d.",tmpStr);
 | 
			
		||||
             return NULL;
 | 
			
		||||
         }
 | 
			
		||||
 
 | 
			
		||||
-        mask <<= (32 - bitcnt);
 | 
			
		||||
+		if (bitcnt == 0)
 | 
			
		||||
+			mask = 0;
 | 
			
		||||
+		else
 | 
			
		||||
+	        mask <<= (32 - bitcnt);
 | 
			
		||||
     }
 | 
			
		||||
 
 | 
			
		||||
-    if(addr == -1 || addr == 0) {
 | 
			
		||||
+    if(addr == -1) {
 | 
			
		||||
         my_log(LOG_WARNING, 0, "Unable to parse address token '%s'.", addrstr);
 | 
			
		||||
         return NULL;
 | 
			
		||||
     }
 | 
			
		||||
		Reference in New Issue
	
	Block a user