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