123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164 |
- 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
|