]>
Commit | Line | Data |
---|---|---|
4bc434b8 JL |
1 | From 65f777e7f66b55239d935c1cf81bb5abc0f6c89f Mon Sep 17 00:00:00 2001 |
2 | From: Grinch <grinch79@users.sourceforge.net> | |
3 | Date: Sun, 16 Aug 2009 19:58:26 +0500 | |
4 | Subject: [PATCH] Restrict igmp reports for downstream interfaces (wrt #2833339) | |
5 | ||
6 | atm all igmp membership reports are forwarded to the upstream interface. | |
7 | Unfortunately some ISP Providers restrict some multicast groups (esp. those | |
8 | that are defined as local link groups and that are not supposed to be | |
9 | forwarded to the wan, i.e 224.0.0.0/24). Therefore there should be some | |
10 | kind of black oder whitelisting. | |
11 | As whitelisting can be accomplished quite easy I wrote a litte patch, which | |
12 | is attached to this request. | |
13 | --- | |
14 | doc/igmpproxy.conf.5.in | 19 +++++++++++++++++++ | |
15 | src/config.c | 23 ++++++++++++++++++++++- | |
16 | src/igmpproxy.h | 1 + | |
17 | src/request.c | 20 ++++++++++++++++---- | |
18 | 4 files changed, 58 insertions(+), 5 deletions(-) | |
19 | ||
20 | diff --git a/doc/igmpproxy.conf.5.in b/doc/igmpproxy.conf.5.in | |
21 | index a4ea7d0..56efa22 100644 | |
22 | --- a/doc/igmpproxy.conf.5.in | |
23 | +++ b/doc/igmpproxy.conf.5.in | |
24 | @@ -116,6 +116,25 @@ This is especially useful for the upstream interface, since the source for multi | |
25 | traffic is often from a remote location. Any number of altnet parameters can be specified. | |
26 | .RE | |
27 | ||
28 | +.B whitelist | |
29 | +.I networkaddr | |
30 | +.RS | |
31 | +Defines a whitelist for multicast groups. The network address must be in the following | |
32 | +format 'a.b.c.d/n'. If you want to allow one single group use a network mask of /32, | |
33 | +i.e. 'a.b.c.d/32'. | |
34 | + | |
35 | +By default all multicast groups are allowed on any downstream interface. If at least one | |
36 | +whitelist entry is defined, all igmp membership reports for not explicitly whitelisted | |
37 | +multicast groups will be ignored and therefore not be served by igmpproxy. This is especially | |
38 | +useful, if your provider does only allow a predefined set of multicast groups. These whitelists | |
39 | +are only obeyed by igmpproxy itself, they won't prevent any other igmp client running on the | |
40 | +same machine as igmpproxy from requesting 'unallowed' multicast groups. | |
41 | + | |
42 | +You may specify as many whitelist entries as needed. Although you should keep it as simple as | |
43 | +possible, as this list is parsed for every membership report and therefore this increases igmp | |
44 | +response times. Often used or large groups should be defined first, as parsing ends as soon as | |
45 | +a group matches an entry. | |
46 | +.RE | |
47 | ||
48 | .SH EXAMPLE | |
49 | ## Enable quickleave | |
50 | diff --git a/src/config.c b/src/config.c | |
51 | index 5a96ce0..d72619f 100644 | |
52 | --- a/src/config.c | |
53 | +++ b/src/config.c | |
54 | @@ -46,6 +46,9 @@ struct vifconfig { | |
55 | ||
56 | // Keep allowed nets for VIF. | |
57 | struct SubnetList* allowednets; | |
58 | + | |
59 | + // Allowed Groups | |
60 | + struct SubnetList* allowedgroups; | |
61 | ||
62 | // Next config in list... | |
63 | struct vifconfig* next; | |
64 | @@ -202,6 +205,8 @@ void configureVifs() { | |
65 | // Insert the configured nets... | |
66 | vifLast->next = confPtr->allowednets; | |
67 | ||
68 | + Dp->allowedgroups = confPtr->allowedgroups; | |
69 | + | |
70 | break; | |
71 | } | |
72 | } | |
73 | @@ -215,7 +220,7 @@ void configureVifs() { | |
74 | */ | |
75 | struct vifconfig *parsePhyintToken() { | |
76 | struct vifconfig *tmpPtr; | |
77 | - struct SubnetList **anetPtr; | |
78 | + struct SubnetList **anetPtr, **agrpPtr; | |
79 | char *token; | |
80 | short parseError = 0; | |
81 | ||
82 | @@ -239,6 +244,7 @@ struct vifconfig *parsePhyintToken() { | |
83 | tmpPtr->threshold = 1; | |
84 | tmpPtr->state = IF_STATE_DOWNSTREAM; | |
85 | tmpPtr->allowednets = NULL; | |
86 | + tmpPtr->allowedgroups = NULL; | |
87 | ||
88 | // Make a copy of the token to store the IF name | |
89 | tmpPtr->name = strdup( token ); | |
90 | @@ -248,6 +254,7 @@ struct vifconfig *parsePhyintToken() { | |
91 | ||
92 | // Set the altnet pointer to the allowednets pointer. | |
93 | anetPtr = &tmpPtr->allowednets; | |
94 | + agrpPtr = &tmpPtr->allowedgroups; | |
95 | ||
96 | // Parse the rest of the config.. | |
97 | token = nextConfigToken(); | |
98 | @@ -266,6 +273,20 @@ struct vifconfig *parsePhyintToken() { | |
99 | anetPtr = &(*anetPtr)->next; | |
100 | } | |
101 | } | |
102 | + else if(strcmp("whitelist", token)==0) { | |
103 | + // Whitelist | |
104 | + token = nextConfigToken(); | |
105 | + my_log(LOG_DEBUG, 0, "Config: IF: Got whitelist token %s.", token); | |
106 | + | |
107 | + *agrpPtr = parseSubnetAddress(token); | |
108 | + if(*agrpPtr == NULL) { | |
109 | + parseError = 1; | |
110 | + my_log(LOG_WARNING, 0, "Unable to parse subnet address."); | |
111 | + break; | |
112 | + } else { | |
113 | + agrpPtr = &(*agrpPtr)->next; | |
114 | + } | |
115 | + } | |
116 | else if(strcmp("upstream", token)==0) { | |
117 | // Upstream | |
118 | my_log(LOG_DEBUG, 0, "Config: IF: Got upstream token."); | |
119 | diff --git a/src/igmpproxy.h b/src/igmpproxy.h | |
120 | index 4dabd1c..0de7791 100644 | |
121 | --- a/src/igmpproxy.h | |
122 | +++ b/src/igmpproxy.h | |
123 | @@ -145,6 +145,7 @@ struct IfDesc { | |
124 | short Flags; | |
125 | short state; | |
126 | struct SubnetList* allowednets; | |
127 | + struct SubnetList* allowedgroups; | |
128 | unsigned int robustness; | |
129 | unsigned char threshold; /* ttl limit */ | |
130 | unsigned int ratelimit; | |
131 | diff --git a/src/request.c b/src/request.c | |
132 | index e3589f6..89b91de 100644 | |
133 | --- a/src/request.c | |
134 | +++ b/src/request.c | |
135 | @@ -82,10 +82,22 @@ void acceptGroupReport(uint32_t src, uint32_t group, uint8_t type) { | |
136 | my_log(LOG_DEBUG, 0, "Should insert group %s (from: %s) to route table. Vif Ix : %d", | |
137 | inetFmt(group,s1), inetFmt(src,s2), sourceVif->index); | |
138 | ||
139 | - // The membership report was OK... Insert it into the route table.. | |
140 | - insertRoute(group, sourceVif->index); | |
141 | - | |
142 | - | |
143 | + // If we don't have a whitelist we insertRoute and done | |
144 | + if(sourceVif->allowedgroups == NULL) | |
145 | + { | |
146 | + insertRoute(group, sourceVif->index); | |
147 | + return; | |
148 | + } | |
149 | + // Check if this Request is legit on this interface | |
150 | + struct SubnetList *sn; | |
151 | + for(sn = sourceVif->allowedgroups; sn != NULL; sn = sn->next) | |
152 | + if((group & sn->subnet_mask) == sn->subnet_addr) | |
153 | + { | |
154 | + // The membership report was OK... Insert it into the route table.. | |
155 | + insertRoute(group, sourceVif->index); | |
156 | + return; | |
157 | + } | |
158 | + my_log(LOG_INFO, 0, "The group address %s may not be requested from this interface. Ignoring.", inetFmt(group, s1)); | |
159 | } else { | |
160 | // Log the state of the interface the report was recieved on. | |
161 | my_log(LOG_INFO, 0, "Mebership report was recieved on %s. Ignoring.", | |
162 | -- | |
163 | 1.7.2.5 | |
164 |