Skip to content

Commit

Permalink
Complement phyint whitelist with blacklist
Browse files Browse the repository at this point in the history
Fixes: #54

Implement new phyint configuration option (blacklist), which enables
blocking of specific traffic.
  • Loading branch information
bket committed Jul 11, 2021
1 parent 0e7186b commit cfad330
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 25 deletions.
20 changes: 20 additions & 0 deletions doc/igmpproxy.conf.5.in
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,26 @@ You may also specify whitelist entries for the upstream interface. Only igmp mem
for explicitly 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.

This option can be combined with
.B blacklist
for fine-grained control.
.RE

.B blacklist
.I networkaddr
.RS
Defines a blacklist for multicast groups. Similar to
.B whitelist
except that if a blacklist entry is defined, all igmp membership reports for
that multicast group will be ignored and therefore not be served by igmpproxy.

Each time a multicast group is forwarded or requested, whitelist and blacklist
entries are evaluated in sequential order, from first to last. The last matching
entry decides what action is taken; if no entry matches the multicast group, the
default action is to serve. Note that, if at least one whitelist entry is
defined before any blacklist entry, all igmp membership reports for not
explicitly whitelisted multicast groups will be ignored.
.RE

.SH EXAMPLE
Expand Down
22 changes: 19 additions & 3 deletions src/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -351,10 +351,26 @@ struct vifconfig *parsePhyintToken(void) {

*agrpPtr = parseSubnetAddress(token);
if(*agrpPtr == NULL) {
parseError = 1;
my_log(LOG_WARNING, 0, "Unable to parse subnet address.");
break;
free(tmpPtr->name);
free(tmpPtr);
my_log(LOG_ERR, 0, "Unable to parse subnet address.");
} else {
(*agrpPtr)->allow = true;
agrpPtr = &(*agrpPtr)->next;
}
}
else if(strcmp("blacklist", token)==0) {
// Blacklist
token = nextConfigToken();
my_log(LOG_DEBUG, 0, "Config: IF: Got blacklist token %s.", token);

*agrpPtr = parseSubnetAddress(token);
if(*agrpPtr == NULL) {
free(tmpPtr->name);
free(tmpPtr);
my_log(LOG_ERR, 0, "Unable to parse subnet address.");
} else {
(*agrpPtr)->allow = false;
agrpPtr = &(*agrpPtr)->next;
}
}
Expand Down
7 changes: 0 additions & 7 deletions src/igmp.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,13 +121,6 @@ void acceptIgmp(int recvlen) {
src = ip->ip_src.s_addr;
dst = ip->ip_dst.s_addr;

/* filter local multicast 239.255.255.250 */
if (dst == htonl(0xEFFFFFFA))
{
my_log(LOG_NOTICE, 0, "The IGMP message was local multicast. Ignoring.");
return;
}

/*
* this is most likely a message from the kernel indicating that
* a new src grp pair message has arrived and so, it would be
Expand Down
1 change: 1 addition & 0 deletions src/igmpproxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ struct SubnetList {
uint32_t subnet_addr;
uint32_t subnet_mask;
struct SubnetList *next;
bool allow;
};

struct IfDesc {
Expand Down
27 changes: 19 additions & 8 deletions src/request.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,22 +83,33 @@ void acceptGroupReport(uint32_t src, uint32_t group) {
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);

// If we don't have a whitelist we insertRoute and done
// If we don't have a black- and whitelist we insertRoute and done
if(sourceVif->allowedgroups == NULL)
{
insertRoute(group, sourceVif->index, src);
return;
}

// Check if this Request is legit on this interface
struct SubnetList *sn;
for(sn = sourceVif->allowedgroups; sn != NULL; sn = sn->next)
bool allow_list = false;
struct SubnetList *match = NULL;
struct SubnetList *sn;

for(sn = sourceVif->allowedgroups; sn != NULL; sn = sn->next) {
// Check if there is a whitelist
if (sn->allow)
allow_list = true;
if((group & sn->subnet_mask) == sn->subnet_addr)
{
// The membership report was OK... Insert it into the route table..
insertRoute(group, sourceVif->index, src);
return;
match = sn;
}

if((!allow_list && match == NULL) ||
(allow_list && match != NULL && match->allow)) {
// The membership report was OK... Insert it into the route table..
insertRoute(group, sourceVif->index, src);
return;
}
my_log(LOG_INFO, 0, "The group address %s may not be requested from this interface. Ignoring.", inetFmt(group, s1));
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 received on.
my_log(LOG_INFO, 0, "Mebership report was received on %s. Ignoring.",
Expand Down
21 changes: 14 additions & 7 deletions src/rttable.c
Original file line number Diff line number Diff line change
Expand Up @@ -157,18 +157,25 @@ static 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
// Check if there is a black- or whitelist for the upstram VIF
if (upstrIf->allowedgroups != NULL) {
uint32_t group = route->group;
struct SubnetList* sn;
bool allow_list = false;
struct SubnetList *match = NULL;
struct SubnetList *sn;
uint32_t group = route->group;

// Check if this Request is legit to be forwarded to upstream
for(sn = upstrIf->allowedgroups; sn != NULL; sn = sn->next)
for(sn = upstrIf->allowedgroups; sn != NULL; sn = sn->next) {
// Check if there is a whitelist
if (sn->allow)
allow_list = true;
if((group & sn->subnet_mask) == sn->subnet_addr)
// Forward is OK...
break;
match = sn;
}

if (sn == NULL) {
// Keep in sync with request.c, note the negation
if(!((!allow_list && match == NULL) ||
(allow_list && match != NULL && match->allow))) {
my_log(LOG_INFO, 0, "The group address %s may not be forwarded upstream. Ignoring.", inetFmt(group, s1));
return;
}
Expand Down

0 comments on commit cfad330

Please sign in to comment.