diff --git a/.clang-format b/.clang-format new file mode 100644 index 00000000..3e21b23e --- /dev/null +++ b/.clang-format @@ -0,0 +1,61 @@ +Language: Cpp + +IndentWidth: 4 +ContinuationIndentWidth: 8 + +ColumnLimit: 120 + +AlignAfterOpenBracket: false + +AlignConsecutiveAssignments: true + +# not supported in clang-format-3.7 +# supported in clang-format-3.8 and above +AlignConsecutiveDeclarations: true + +AlignTrailingComments: true + +AllowAllParametersOfDeclarationOnNextLine: true + +AllowShortBlocksOnASingleLine: false +AllowShortFunctionsOnASingleLine: false +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false + +# Control of individual brace wrapping cases +# not supported in clang-format-3.7 +# supported in clang-format-3.8 and above +BraceWrapping: { + AfterClass: 'true' + AfterControlStatement: 'false' + AfterEnum: 'true' + AfterFunction: 'true' + AfterNamespace: 'true' + AfterStruct: 'true' + AfterUnion: 'true' + BeforeCatch: 'true' + BeforeElse: 'false' + IndentBraces: 'false' +} + +BreakBeforeBraces: Stroustrup + +IndentCaseLabels: true + +KeepEmptyLinesAtTheStartOfBlocks: true + +MaxEmptyLinesToKeep: 2 + +# Pointer is aligned to right side +PointerAlignment: Right + +# High penalty to avoid line break just after return type +PenaltyReturnTypeOnItsOwnLine: 10000 + +SpaceAfterCStyleCast: true + +SpacesInParentheses: true +SpaceInEmptyParentheses: false +SpaceBeforeParens: ControlStatements + +UseTab: Never diff --git a/Makefile.am b/Makefile.am index b569f48e..4d9e991f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -8,3 +8,15 @@ ChangeLog: AUTHORS: ChangeLog ( echo "Authors and contributors, in alphabetical order: "; echo; \ sed -r "s/^Author: (.*)/\1/;t;d" $< | sort -u ) > $@ + +if HAVE_CLANG_FORMAT + +.PHONY: reformat + +reformat: + @echo "Reformatting header files..." + @CLANG_FORMAT@ -style=file -i `find . -name "*.h"` + @echo "Reformatting C files..." + @CLANG_FORMAT@ -style=file -i `find . -name "*.c"` + +endif diff --git a/configure.ac b/configure.ac index f8b577de..60b9199d 100644 --- a/configure.ac +++ b/configure.ac @@ -5,6 +5,12 @@ AC_CONFIG_SRCDIR([src/igmpproxy.c]) AC_CONFIG_HEADERS([config.h]) AC_PROG_CC_C99 +AC_CHECK_PROGS( + [CLANG_FORMAT], [clang-format clang-format-4.0 clang-format-3.9], + [AC_MSG_ERROR([clang-format was not not found during configure.])] +) +AM_CONDITIONAL([HAVE_CLANG_FORMAT], [test -n "$CLANG_FORMAT"]) + AC_CANONICAL_HOST case $host_os in linux*|uclinux*) os=linux;; diff --git a/src/callout.c b/src/callout.c index c49da6cf..c9650fac 100644 --- a/src/callout.c +++ b/src/callout.c @@ -32,79 +32,81 @@ ** */ - #include "igmpproxy.h" /* the code below implements a callout queue */ -static int id = 0; -static struct timeOutQueue *queue = 0; /* pointer to the beginning of timeout queue */ +static int id = 0; +static struct timeOutQueue *queue = 0; /* pointer to the beginning of timeout queue */ struct timeOutQueue { - struct timeOutQueue *next; // Next event in queue - int id; - timer_f func; // function to call - void *data; // Data for function - int time; // Time offset for next event + struct timeOutQueue *next; // Next event in queue + int id; + timer_f func; // function to call + void * data; // Data for function + int time; // Time offset for next event }; // Method for dumping the Queue to the log. -static void debugQueue(void); +static void debugQueue( void ); /** * Initializes the callout queue */ -void callout_init(void) { +void callout_init( void ) +{ queue = NULL; } /** * Clears all scheduled timeouts... */ -void free_all_callouts(void) { +void free_all_callouts( void ) +{ struct timeOutQueue *p; - while (queue) { - p = queue; + while ( queue ) { + p = queue; queue = queue->next; - free(p); + free( p ); } } - /** * elapsed_time seconds have passed; perform all the events that should * happen. */ -void age_callout_queue(int elapsed_time) { +void age_callout_queue( int elapsed_time ) +{ struct timeOutQueue *ptr; struct timeOutQueue *_queue = NULL; - struct timeOutQueue *last = NULL; - int i = 0; + struct timeOutQueue *last = NULL; + int i = 0; - for (ptr = queue; ptr; ptr = ptr->next) { - if (ptr->time > elapsed_time) { + for ( ptr = queue; ptr; ptr = ptr->next ) { + if ( ptr->time > elapsed_time ) { ptr->time -= elapsed_time; break; - } else { + } + else { elapsed_time -= ptr->time; - if (_queue == NULL) + if ( _queue == NULL ) _queue = ptr; - last = ptr; - } + last = ptr; + } } queue = ptr; - if (last) { + if ( last ) { last->next = NULL; } /* process existing events */ - for (ptr = _queue; ptr; ptr = _queue, i++) { + for ( ptr = _queue; ptr; ptr = _queue, i++ ) { _queue = _queue->next; - my_log(LOG_DEBUG, 0, "About to call timeout %d (#%d)", ptr->id, i); - if (ptr->func) - ptr->func(ptr->data); - free(ptr); + my_log( LOG_DEBUG, 0, "About to call timeout %d (#%d)", ptr->id, i ); + if ( ptr->func ) + ptr->func( ptr->data ); + free( ptr ); } } @@ -112,11 +114,11 @@ void age_callout_queue(int elapsed_time) { * Return in how many seconds age_callout_queue() would like to be called. * Return -1 if there are no events pending. */ -int timer_nextTimer(void) { - if (queue) { - if (queue->time < 0) { - my_log(LOG_WARNING, 0, "timer_nextTimer top of queue says %d", - queue->time); +int timer_nextTimer( void ) +{ + if ( queue ) { + if ( queue->time < 0 ) { + my_log( LOG_WARNING, 0, "timer_nextTimer top of queue says %d", queue->time ); return 0; } return queue->time; @@ -130,14 +132,15 @@ int timer_nextTimer(void) { * @param action - The function to call on timeout. * @param data - Pointer to the function data to supply... */ -int timer_setTimer(int delay, timer_f action, void *data) { - struct timeOutQueue *ptr, *node, *prev; - int i = 0; +int timer_setTimer( int delay, timer_f action, void *data ) +{ + struct timeOutQueue *ptr, *node, *prev; + int i = 0; /* create a node */ - node = (struct timeOutQueue *)malloc(sizeof(struct timeOutQueue)); - if (node == 0) { - my_log(LOG_WARNING, 0, "Malloc Failed in timer_settimer\n"); + node = (struct timeOutQueue *) malloc( sizeof( struct timeOutQueue ) ); + if ( node == 0 ) { + my_log( LOG_WARNING, 0, "Malloc Failed in timer_settimer\n" ); return -1; } node->func = action; @@ -151,39 +154,38 @@ int timer_setTimer(int delay, timer_f action, void *data) { /* insert node in the queue */ /* if the queue is empty, insert the node and return */ - if (!queue) { + if ( !queue ) { queue = node; } else { /* chase the pointer looking for the right place */ - while (ptr) { - if (delay < ptr->time) { + while ( ptr ) { + if ( delay < ptr->time ) { // We found the correct node node->next = ptr; - if (ptr == queue) { + if ( ptr == queue ) { queue = node; } else { prev->next = node; } ptr->time -= node->time; - my_log(LOG_DEBUG, 0, - "Created timeout %d (#%d) - delay %d secs", - node->id, i, node->time); + my_log( LOG_DEBUG, 0, "Created timeout %d (#%d) - delay %d secs", node->id, i, node->time ); debugQueue(); return node->id; - } else { + } + else { // Continur to check nodes. - delay -= ptr->time; node->time = delay; - prev = ptr; - ptr = ptr->next; + delay -= ptr->time; + node->time = delay; + prev = ptr; + ptr = ptr->next; } i++; } prev->next = node; } - my_log(LOG_DEBUG, 0, "Created timeout %d (#%d) - delay %d secs", - node->id, i, node->time); + my_log( LOG_DEBUG, 0, "Created timeout %d (#%d) - delay %d secs", node->id, i, node->time ); debugQueue(); return node->id; @@ -192,16 +194,17 @@ int timer_setTimer(int delay, timer_f action, void *data) { /** * returns the time until the timer is scheduled */ -int timer_leftTimer(int timer_id) { +int timer_leftTimer( int timer_id ) +{ struct timeOutQueue *ptr; - int left = 0; + int left = 0; - if (!timer_id) + if ( !timer_id ) return -1; - for (ptr = queue; ptr; ptr = ptr->next) { + for ( ptr = queue; ptr; ptr = ptr->next ) { left += ptr->time; - if (ptr->id == timer_id) { + if ( ptr->id == timer_id ) { return left; } } @@ -211,11 +214,12 @@ int timer_leftTimer(int timer_id) { /** * clears the associated timer. Returns 1 if succeeded. */ -int timer_clearTimer(int timer_id) { - struct timeOutQueue *ptr, *prev; - int i = 0; +int timer_clearTimer( int timer_id ) +{ + struct timeOutQueue *ptr, *prev; + int i = 0; - if (!timer_id) + if ( !timer_id ) return 0; prev = ptr = queue; @@ -226,33 +230,33 @@ int timer_clearTimer(int timer_id) { */ debugQueue(); - while (ptr) { - if (ptr->id == timer_id) { + while ( ptr ) { + if ( ptr->id == timer_id ) { /* got the right node */ /* unlink it from the queue */ - if (ptr == queue) + if ( ptr == queue ) queue = queue->next; else prev->next = ptr->next; /* increment next node if any */ - if (ptr->next != 0) - (ptr->next)->time += ptr->time; + if ( ptr->next != 0 ) + ( ptr->next )->time += ptr->time; - if (ptr->data) - free(ptr->data); - my_log(LOG_DEBUG, 0, "deleted timer %d (#%d)", ptr->id, i); - free(ptr); + if ( ptr->data ) + free( ptr->data ); + my_log( LOG_DEBUG, 0, "deleted timer %d (#%d)", ptr->id, i ); + free( ptr ); debugQueue(); return 1; } prev = ptr; - ptr = ptr->next; + ptr = ptr->next; i++; } // If we get here, the timer was not deleted. - my_log(LOG_DEBUG, 0, "failed to delete timer %d (#%d)", timer_id, i); + my_log( LOG_DEBUG, 0, "failed to delete timer %d (#%d)", timer_id, i ); debugQueue(); return 0; } @@ -260,10 +264,11 @@ int timer_clearTimer(int timer_id) { /** * debugging utility */ -static void debugQueue(void) { - struct timeOutQueue *ptr; +static void debugQueue( void ) +{ + struct timeOutQueue *ptr; - for (ptr = queue; ptr; ptr = ptr->next) { - my_log(LOG_DEBUG, 0, "(Id:%d, Time:%d) ", ptr->id, ptr->time); + for ( ptr = queue; ptr; ptr = ptr->next ) { + my_log( LOG_DEBUG, 0, "(Id:%d, Time:%d) ", ptr->id, ptr->time ); } } diff --git a/src/config.c b/src/config.c index 3732a1c9..9de76850 100644 --- a/src/config.c +++ b/src/config.c @@ -40,19 +40,19 @@ // Structure to keep configuration for VIFs... struct vifconfig { - char* name; - short state; - int ratelimit; - int threshold; + char *name; + short state; + int ratelimit; + int threshold; // Keep allowed nets for VIF. - struct SubnetList* allowednets; + struct SubnetList *allowednets; // Allowed Groups - struct SubnetList* allowedgroups; + struct SubnetList *allowedgroups; // Next config in list... - struct vifconfig* next; + struct vifconfig *next; }; // Structure to keep vif configuration @@ -62,20 +62,21 @@ struct vifconfig *vifconf; static struct Config commonConfig; // Prototypes... -struct vifconfig *parsePhyintToken(void); -struct SubnetList *parseSubnetAddress(char *addrstr); +struct vifconfig * parsePhyintToken( void ); +struct SubnetList *parseSubnetAddress( char *addrstr ); /** * Initializes common config.. */ -static void initCommonConfig(void) { - commonConfig.robustnessValue = DEFAULT_ROBUSTNESS; - commonConfig.queryInterval = INTERVAL_QUERY; +static void initCommonConfig( void ) +{ + commonConfig.robustnessValue = DEFAULT_ROBUSTNESS; + commonConfig.queryInterval = INTERVAL_QUERY; commonConfig.queryResponseInterval = INTERVAL_QUERY_RESPONSE; // The defaults are calculated from other settings. - commonConfig.startupQueryInterval = (unsigned int)(INTERVAL_QUERY / 4); - commonConfig.startupQueryCount = DEFAULT_ROBUSTNESS; + commonConfig.startupQueryInterval = (unsigned int) ( INTERVAL_QUERY / 4 ); + commonConfig.startupQueryCount = DEFAULT_ROBUSTNESS; // Default values for leave intervals... commonConfig.lastMemberQueryInterval = INTERVAL_QUERY_RESPONSE; @@ -86,13 +87,14 @@ static void initCommonConfig(void) { // aimwang: default value commonConfig.defaultInterfaceState = IF_STATE_DISABLED; - commonConfig.rescanVif = 0; + commonConfig.rescanVif = 0; } /** * Returns a pointer to the common config... */ -struct Config *getCommonConfig(void) { +struct Config *getCommonConfig( void ) +{ return &commonConfig; } @@ -100,81 +102,84 @@ struct Config *getCommonConfig(void) { * Loads the configuration from file, and stores the config in * respective holders... */ -int loadConfig(char *configFile) { - struct vifconfig *tmpPtr; - struct vifconfig **currPtr = &vifconf; - char *token; +int loadConfig( char *configFile ) +{ + struct vifconfig * tmpPtr; + struct vifconfig **currPtr = &vifconf; + char * token; // Initialize common config initCommonConfig(); // Test config file reader... - if(!openConfigFile(configFile)) { - my_log(LOG_ERR, 0, "Unable to open configfile from %s", configFile); + if ( !openConfigFile( configFile ) ) { + my_log( LOG_ERR, 0, "Unable to open configfile from %s", configFile ); } // Get first token... token = nextConfigToken(); - if(token == NULL) { - my_log(LOG_ERR, 0, "Config file was empty."); + if ( token == NULL ) { + my_log( LOG_ERR, 0, "Config file was empty." ); } // Loop until all configuration is read. while ( token != NULL ) { // Check token... - if(strcmp("phyint", token)==0) { + if ( strcmp( "phyint", token ) == 0 ) { // Got a phyint token... Call phyint parser - my_log(LOG_DEBUG, 0, "Config: Got a phyint token."); + my_log( LOG_DEBUG, 0, "Config: Got a phyint token." ); tmpPtr = parsePhyintToken(); - if(tmpPtr == NULL) { + if ( tmpPtr == NULL ) { // Unparsable token... Exit... closeConfigFile(); - my_log(LOG_WARNING, 0, "Unknown token '%s' in configfile", token); + my_log( LOG_WARNING, 0, "Unknown token '%s' in configfile", token ); return 0; - } else { + } + else { - my_log(LOG_DEBUG, 0, "IF name : %s", tmpPtr->name); - my_log(LOG_DEBUG, 0, "Next ptr : %x", tmpPtr->next); - my_log(LOG_DEBUG, 0, "Ratelimit : %d", tmpPtr->ratelimit); - my_log(LOG_DEBUG, 0, "Threshold : %d", tmpPtr->threshold); - my_log(LOG_DEBUG, 0, "State : %d", tmpPtr->state); - my_log(LOG_DEBUG, 0, "Allowednet ptr : %x", tmpPtr->allowednets); + my_log( LOG_DEBUG, 0, "IF name : %s", tmpPtr->name ); + my_log( LOG_DEBUG, 0, "Next ptr : %x", tmpPtr->next ); + my_log( LOG_DEBUG, 0, "Ratelimit : %d", tmpPtr->ratelimit ); + my_log( LOG_DEBUG, 0, "Threshold : %d", tmpPtr->threshold ); + my_log( LOG_DEBUG, 0, "State : %d", tmpPtr->state ); + my_log( LOG_DEBUG, 0, "Allowednet ptr : %x", tmpPtr->allowednets ); // Insert config, and move temppointer to next location... *currPtr = tmpPtr; - currPtr = &tmpPtr->next; + currPtr = &tmpPtr->next; } } - else if(strcmp("quickleave", token)==0) { + else if ( strcmp( "quickleave", token ) == 0 ) { // Got a quickleave token.... - my_log(LOG_DEBUG, 0, "Config: Quick leave mode enabled."); + my_log( LOG_DEBUG, 0, "Config: Quick leave mode enabled." ); commonConfig.fastUpstreamLeave = 1; // Read next token... token = nextConfigToken(); continue; } - else if(strcmp("defaultdown", token)==0) { + else if ( strcmp( "defaultdown", token ) == 0 ) { // Got a defaultdown token... - my_log(LOG_DEBUG, 0, "Config: interface Default as down stream."); + my_log( LOG_DEBUG, 0, "Config: interface Default as down stream." ); commonConfig.defaultInterfaceState = IF_STATE_DOWNSTREAM; // Read next token... token = nextConfigToken(); continue; } - else if(strcmp("rescanvif", token)==0) { + else if ( strcmp( "rescanvif", token ) == 0 ) { // Got a defaultdown token... - my_log(LOG_DEBUG, 0, "Config: Need detect new interace."); + my_log( LOG_DEBUG, 0, "Config: Need detect new interace." ); commonConfig.rescanVif = 1; // Read next token... token = nextConfigToken(); continue; - } else { + } + else { // Unparsable token... Exit... closeConfigFile(); - my_log(LOG_WARNING, 0, "Unknown token '%s' in configfile", token); + my_log( LOG_WARNING, 0, "Unknown token '%s' in configfile", token ); return 0; } // Get token that was not recognized by phyint parser. @@ -190,29 +195,29 @@ int loadConfig(char *configFile) { /** * Appends extra VIF configuration from config file. */ -void configureVifs(void) { - unsigned Ix; - struct IfDesc *Dp; +void configureVifs( void ) +{ + unsigned Ix; + struct IfDesc * Dp; struct vifconfig *confPtr; // If no config is available, just return... - if(vifconf == NULL) { + if ( vifconf == NULL ) { return; } // Loop through all VIFs... - for ( Ix = 0; (Dp = getIfByIx(Ix)); Ix++ ) { - if ( Dp->InAdr.s_addr && ! (Dp->Flags & IFF_LOOPBACK) ) { + for ( Ix = 0; ( Dp = getIfByIx( Ix ) ); Ix++ ) { + if ( Dp->InAdr.s_addr && !( Dp->Flags & IFF_LOOPBACK ) ) { // Now try to find a matching config... - for( confPtr = vifconf; confPtr; confPtr = confPtr->next) { + for ( confPtr = vifconf; confPtr; confPtr = confPtr->next ) { // I the VIF names match... - if(strcmp(Dp->Name, confPtr->name)==0) { + if ( strcmp( Dp->Name, confPtr->name ) == 0 ) { struct SubnetList *vifLast; - my_log(LOG_DEBUG, 0, "Found config for %s", Dp->Name); - + my_log( LOG_DEBUG, 0, "Found config for %s", Dp->Name ); // Set the VIF state Dp->state = confPtr->state; @@ -221,7 +226,8 @@ void configureVifs(void) { Dp->ratelimit = confPtr->ratelimit; // Go to last allowed net on VIF... - for(vifLast = Dp->allowednets; vifLast->next; vifLast = vifLast->next); + for ( vifLast = Dp->allowednets; vifLast->next; vifLast = vifLast->next ) + ; // Insert the configured nets... vifLast->next = confPtr->allowednets; @@ -235,42 +241,44 @@ void configureVifs(void) { } } - /** * Internal function to parse phyint config */ -struct vifconfig *parsePhyintToken(void) { - struct vifconfig *tmpPtr; +struct vifconfig *parsePhyintToken( void ) +{ + struct vifconfig * tmpPtr; struct SubnetList **anetPtr, **agrpPtr; - char *token; - short parseError = 0; + char * token; + short parseError = 0; // First token should be the interface name.... token = nextConfigToken(); // Sanitycheck the name... - if(token == NULL) return NULL; - if(strlen(token) >= IF_NAMESIZE) return NULL; - my_log(LOG_DEBUG, 0, "Config: IF: Config for interface %s.", token); + if ( token == NULL ) + return NULL; + if ( strlen( token ) >= IF_NAMESIZE ) + return NULL; + my_log( LOG_DEBUG, 0, "Config: IF: Config for interface %s.", token ); // Allocate memory for configuration... - tmpPtr = (struct vifconfig*)malloc(sizeof(struct vifconfig)); - if(tmpPtr == NULL) { - my_log(LOG_ERR, 0, "Out of memory."); + tmpPtr = (struct vifconfig *) malloc( sizeof( struct vifconfig ) ); + if ( tmpPtr == NULL ) { + my_log( LOG_ERR, 0, "Out of memory." ); } // Set default values... - tmpPtr->next = NULL; // Important to avoid seg fault... - tmpPtr->ratelimit = 0; - tmpPtr->threshold = 1; - tmpPtr->state = commonConfig.defaultInterfaceState; - tmpPtr->allowednets = NULL; + tmpPtr->next = NULL; // Important to avoid seg fault... + tmpPtr->ratelimit = 0; + tmpPtr->threshold = 1; + tmpPtr->state = commonConfig.defaultInterfaceState; + tmpPtr->allowednets = NULL; tmpPtr->allowedgroups = NULL; // Make a copy of the token to store the IF name tmpPtr->name = strdup( token ); - if(tmpPtr->name == NULL) { - my_log(LOG_ERR, 0, "Out of memory."); + if ( tmpPtr->name == NULL ) { + my_log( LOG_ERR, 0, "Out of memory." ); } // Set the altnet pointer to the allowednets pointer. @@ -279,68 +287,70 @@ struct vifconfig *parsePhyintToken(void) { // Parse the rest of the config.. token = nextConfigToken(); - while(token != NULL) { - if(strcmp("altnet", token)==0) { + while ( token != NULL ) { + if ( strcmp( "altnet", token ) == 0 ) { // Altnet... token = nextConfigToken(); - my_log(LOG_DEBUG, 0, "Config: IF: Got altnet token %s.",token); + my_log( LOG_DEBUG, 0, "Config: IF: Got altnet token %s.", token ); - *anetPtr = parseSubnetAddress(token); - if(*anetPtr == NULL) { + *anetPtr = parseSubnetAddress( token ); + if ( *anetPtr == NULL ) { parseError = 1; - my_log(LOG_WARNING, 0, "Unable to parse subnet address."); + my_log( LOG_WARNING, 0, "Unable to parse subnet address." ); break; - } else { - anetPtr = &(*anetPtr)->next; + } + else { + anetPtr = &( *anetPtr )->next; } } - else if(strcmp("whitelist", token)==0) { + else if ( strcmp( "whitelist", token ) == 0 ) { // Whitelist token = nextConfigToken(); - my_log(LOG_DEBUG, 0, "Config: IF: Got whitelist token %s.", token); + my_log( LOG_DEBUG, 0, "Config: IF: Got whitelist token %s.", token ); - *agrpPtr = parseSubnetAddress(token); - if(*agrpPtr == NULL) { + *agrpPtr = parseSubnetAddress( token ); + if ( *agrpPtr == NULL ) { parseError = 1; - my_log(LOG_WARNING, 0, "Unable to parse subnet address."); + my_log( LOG_WARNING, 0, "Unable to parse subnet address." ); break; - } else { - agrpPtr = &(*agrpPtr)->next; + } + else { + agrpPtr = &( *agrpPtr )->next; } } - else if(strcmp("upstream", token)==0) { + else if ( strcmp( "upstream", token ) == 0 ) { // Upstream - my_log(LOG_DEBUG, 0, "Config: IF: Got upstream token."); + my_log( LOG_DEBUG, 0, "Config: IF: Got upstream token." ); tmpPtr->state = IF_STATE_UPSTREAM; } - else if(strcmp("downstream", token)==0) { + else if ( strcmp( "downstream", token ) == 0 ) { // Downstream - my_log(LOG_DEBUG, 0, "Config: IF: Got downstream token."); + my_log( LOG_DEBUG, 0, "Config: IF: Got downstream token." ); tmpPtr->state = IF_STATE_DOWNSTREAM; } - else if(strcmp("disabled", token)==0) { + else if ( strcmp( "disabled", token ) == 0 ) { // Disabled - my_log(LOG_DEBUG, 0, "Config: IF: Got disabled token."); + my_log( LOG_DEBUG, 0, "Config: IF: Got disabled token." ); tmpPtr->state = IF_STATE_DISABLED; } - else if(strcmp("ratelimit", token)==0) { + else if ( strcmp( "ratelimit", token ) == 0 ) { // Ratelimit token = nextConfigToken(); - my_log(LOG_DEBUG, 0, "Config: IF: Got ratelimit token '%s'.", token); + my_log( LOG_DEBUG, 0, "Config: IF: Got ratelimit token '%s'.", token ); tmpPtr->ratelimit = atoi( token ); - if(tmpPtr->ratelimit < 0) { - my_log(LOG_WARNING, 0, "Ratelimit must be 0 or more."); + if ( tmpPtr->ratelimit < 0 ) { + my_log( LOG_WARNING, 0, "Ratelimit must be 0 or more." ); parseError = 1; break; } } - else if(strcmp("threshold", token)==0) { + else if ( strcmp( "threshold", token ) == 0 ) { // Threshold token = nextConfigToken(); - my_log(LOG_DEBUG, 0, "Config: IF: Got threshold token '%s'.", token); + my_log( LOG_DEBUG, 0, "Config: IF: Got threshold token '%s'.", token ); tmpPtr->threshold = atoi( token ); - if(tmpPtr->threshold <= 0 || tmpPtr->threshold > 255) { - my_log(LOG_WARNING, 0, "Threshold must be between 1 and 255."); + if ( tmpPtr->threshold <= 0 || tmpPtr->threshold > 255 ) { + my_log( LOG_WARNING, 0, "Threshold must be between 1 and 255." ); parseError = 1; break; } @@ -353,9 +363,9 @@ struct vifconfig *parsePhyintToken(void) { } // Clean up after a parseerror... - if(parseError) { - free(tmpPtr->name); - free(tmpPtr); + if ( parseError ) { + free( tmpPtr->name ); + free( tmpPtr ); tmpPtr = NULL; } @@ -366,42 +376,43 @@ struct vifconfig *parsePhyintToken(void) { * Parses a subnet address string on the format * a.b.c.d/n into a SubnetList entry. */ -struct SubnetList *parseSubnetAddress(char *addrstr) { - struct SubnetList *tmpSubnet; - char *tmpStr; - uint32_t addr = 0x00000000; - uint32_t mask = 0xFFFFFFFF; +struct SubnetList *parseSubnetAddress( char *addrstr ) +{ + struct SubnetList *tmpSubnet; + char * tmpStr; + uint32_t addr = 0x00000000; + uint32_t mask = 0xFFFFFFFF; // First get the network part of the address... - tmpStr = strtok(addrstr, "/"); - addr = inet_addr(tmpStr); - - tmpStr = strtok(NULL, "/"); - if(tmpStr != NULL) { - int bitcnt = atoi(tmpStr); - if(bitcnt < 0 || bitcnt > 32) { - my_log(LOG_WARNING, 0, "The bits part of the address is invalid : %d.",tmpStr); + tmpStr = strtok( addrstr, "/" ); + addr = inet_addr( tmpStr ); + + tmpStr = strtok( NULL, "/" ); + if ( tmpStr != NULL ) { + int bitcnt = atoi( tmpStr ); + if ( bitcnt < 0 || bitcnt > 32 ) { + my_log( LOG_WARNING, 0, "The bits part of the address is invalid : %d.", tmpStr ); return NULL; } - if (bitcnt == 0) + if ( bitcnt == 0 ) mask = 0; else - mask <<= (32 - bitcnt); + mask <<= ( 32 - bitcnt ); } - if(addr == -1) { - my_log(LOG_WARNING, 0, "Unable to parse address token '%s'.", addrstr); + if ( addr == -1 ) { + my_log( LOG_WARNING, 0, "Unable to parse address token '%s'.", addrstr ); return NULL; } - tmpSubnet = (struct SubnetList*) malloc(sizeof(struct SubnetList)); + tmpSubnet = (struct SubnetList *) malloc( sizeof( struct SubnetList ) ); tmpSubnet->subnet_addr = addr; - tmpSubnet->subnet_mask = ntohl(mask); - tmpSubnet->next = NULL; + tmpSubnet->subnet_mask = ntohl( mask ); + tmpSubnet->next = NULL; - my_log(LOG_DEBUG, 0, "Config: IF: Altnet: Parsed altnet to %s.", - inetFmts(tmpSubnet->subnet_addr, tmpSubnet->subnet_mask,s1)); + my_log( LOG_DEBUG, 0, "Config: IF: Altnet: Parsed altnet to %s.", + inetFmts( tmpSubnet->subnet_addr, tmpSubnet->subnet_mask, s1 ) ); return tmpSubnet; } diff --git a/src/confread.c b/src/confread.c index 22b69128..dcd2eaeb 100644 --- a/src/confread.c +++ b/src/confread.c @@ -45,45 +45,46 @@ #include "igmpproxy.h" -#define READ_BUFFER_SIZE 512 // Inputbuffer size... +#define READ_BUFFER_SIZE 512 // Inputbuffer size... #ifndef MAX_TOKEN_LENGTH - #define MAX_TOKEN_LENGTH 30 // Default max token length +#define MAX_TOKEN_LENGTH 30 // Default max token length #endif -FILE *confFilePtr; // File handle pointer -char *iBuffer; // Inputbuffer for reading... -unsigned int bufPtr; // Buffer position pointer. -unsigned int readSize; // Number of bytes in buffer after last read... -char cToken[MAX_TOKEN_LENGTH]; // Token buffer... -short validToken; +FILE * confFilePtr; // File handle pointer +char * iBuffer; // Inputbuffer for reading... +unsigned int bufPtr; // Buffer position pointer. +unsigned int readSize; // Number of bytes in buffer after last read... +char cToken[MAX_TOKEN_LENGTH]; // Token buffer... +short validToken; /** * Opens config file specified by filename. */ -int openConfigFile(char *filename) { +int openConfigFile( char *filename ) +{ // Set the buffer to null initially... iBuffer = NULL; // Open the file for reading... - confFilePtr = fopen(filename, "r"); + confFilePtr = fopen( filename, "r" ); // On error, return false - if(confFilePtr == NULL) { + if ( confFilePtr == NULL ) { return 0; } // Allocate memory for inputbuffer... - iBuffer = (char*) malloc( sizeof(char) * READ_BUFFER_SIZE ); + iBuffer = (char *) malloc( sizeof( char ) * READ_BUFFER_SIZE ); - if(iBuffer == NULL) { + if ( iBuffer == NULL ) { closeConfigFile(); return 0; } // Reset bufferpointer and readsize - bufPtr = 0; + bufPtr = 0; readSize = 0; return 1; @@ -92,14 +93,15 @@ int openConfigFile(char *filename) { /** * Closes the currently open config file. */ -void closeConfigFile(void) { +void closeConfigFile( void ) +{ // Close the file. - if(confFilePtr!=NULL) { - fclose(confFilePtr); + if ( confFilePtr != NULL ) { + fclose( confFilePtr ); } // Free input buffer memory... - if(iBuffer != NULL) { - free(iBuffer); + if ( iBuffer != NULL ) { + free( iBuffer ); } } @@ -107,30 +109,32 @@ void closeConfigFile(void) { * Returns the next token from the configfile. The function * return NULL if there are no more tokens in the file. */ -char *nextConfigToken(void) { +char *nextConfigToken( void ) +{ validToken = 0; // If no file or buffer, return NULL - if(confFilePtr == NULL || iBuffer == NULL) { + if ( confFilePtr == NULL || iBuffer == NULL ) { return NULL; } { - unsigned int tokenPtr = 0; + unsigned int tokenPtr = 0; unsigned short finished = 0; unsigned short commentFound = 0; // Outer buffer fill loop... while ( !finished ) { - // If readpointer is at the end of the buffer, we should read next chunk... - if(bufPtr == readSize) { + // If readpointer is at the end of the buffer, we should read next + // chunk... + if ( bufPtr == readSize ) { // Fill up the buffer... - readSize = fread (iBuffer, sizeof(char), READ_BUFFER_SIZE, confFilePtr); - bufPtr = 0; + readSize = fread( iBuffer, sizeof( char ), READ_BUFFER_SIZE, confFilePtr ); + bufPtr = 0; // If the readsize is 0, we should just return... - if(readSize == 0) { + if ( readSize == 0 ) { return NULL; } } @@ -138,63 +142,64 @@ char *nextConfigToken(void) { // Inner char loop... while ( bufPtr < readSize && !finished ) { - //printf("Char %s", iBuffer[bufPtr]); + // printf("Char %s", iBuffer[bufPtr]); // Break loop on \0 - if(iBuffer[bufPtr] == '\0') { + if ( iBuffer[bufPtr] == '\0' ) { break; } - if( commentFound ) { - if( iBuffer[bufPtr] == '\n' ) { + if ( commentFound ) { + if ( iBuffer[bufPtr] == '\n' ) { commentFound = 0; } - } else { + } + else { // Check current char... - switch(iBuffer[bufPtr]) { - case '#': - // Found a comment start... - commentFound = 1; - break; - - case '\n': - case '\r': - case '\t': - case ' ': - // Newline, CR, Tab and space are end of token, or ignored. - if(tokenPtr > 0) { - cToken[tokenPtr] = '\0'; // EOL - finished = 1; - } - break; - - default: - // Append char to token... - cToken[tokenPtr++] = iBuffer[bufPtr]; - break; + switch ( iBuffer[bufPtr] ) { + case '#': + // Found a comment start... + commentFound = 1; + break; + + case '\n': + case '\r': + case '\t': + case ' ': + // Newline, CR, Tab and space are end of token, or ignored. + if ( tokenPtr > 0 ) { + cToken[tokenPtr] = '\0'; // EOL + finished = 1; + } + break; + + default: + // Append char to token... + cToken[tokenPtr++] = iBuffer[bufPtr]; + break; } } // Check end of token buffer !!! - if(tokenPtr == MAX_TOKEN_LENGTH - 1) { + if ( tokenPtr == MAX_TOKEN_LENGTH - 1 ) { // Prevent buffer overrun... cToken[tokenPtr] = '\0'; - finished = 1; + finished = 1; } // Next char... bufPtr++; } // If the readsize is less than buffersize, we assume EOF. - if(readSize < READ_BUFFER_SIZE && bufPtr == readSize) { - if (tokenPtr > 0) + if ( readSize < READ_BUFFER_SIZE && bufPtr == readSize ) { + if ( tokenPtr > 0 ) finished = 1; else return NULL; } } - if(tokenPtr>0) { + if ( tokenPtr > 0 ) { validToken = 1; return cToken; } @@ -202,11 +207,11 @@ char *nextConfigToken(void) { return NULL; } - /** * Returns the currently active token, or null * if no tokens are available. */ -char *getCurrentConfigToken(void) { +char *getCurrentConfigToken( void ) +{ return validToken ? cToken : NULL; } diff --git a/src/ifvc.c b/src/ifvc.c index 2dce19c1..cc5694b3 100644 --- a/src/ifvc.c +++ b/src/ifvc.c @@ -34,113 +34,117 @@ #include "igmpproxy.h" -struct IfDesc IfDescVc[ MAX_IF ], *IfDescEp = IfDescVc; +struct IfDesc IfDescVc[MAX_IF], *IfDescEp = IfDescVc; /* aimwang: add for detect interface and rebuild IfVc record */ -/*************************************************** - * TODO: Only need run me when detect downstream changed. - * For example: /etc/ppp/ip-up & ip-down can touch a file /tmp/ppp_changed - * So I can check if the file exist then run me and delete the file. - ***************************************************/ -void rebuildIfVc () { - struct ifreq IfVc[ sizeof( IfDescVc ) / sizeof( IfDescVc[ 0 ] ) ]; - struct ifreq *IfEp; - struct ifconf IoCtlReq; +/******************************************************************************* + * TODO: + * Only need run me when detect downstream changed. + * + * For example: + * /etc/ppp/ip-up & ip-down can touch a file /tmp/ppp_changed + * + * So I can check if the file exist then run me and delete the file. + ******************************************************************************/ +void rebuildIfVc() +{ + struct ifreq IfVc[sizeof( IfDescVc ) / sizeof( IfDescVc[0] )]; + struct ifreq * IfEp; + struct ifconf IoCtlReq; struct IfDesc *Dp; - struct ifreq *IfPt, *IfNext; - uint32_t addr, subnet, mask; - int Sock, Ix; + struct ifreq * IfPt, *IfNext; + uint32_t addr, subnet, mask; + int Sock, Ix; // Get the config. struct Config *config = getCommonConfig(); - if ( (Sock = socket( AF_INET, SOCK_DGRAM, 0 )) < 0 ) + if ( ( Sock = socket( AF_INET, SOCK_DGRAM, 0 ) ) < 0 ) my_log( LOG_ERR, errno, "RAW socket open" ); // aimwang: set all downstream IF as lost, for check IF exist or gone. - for (Dp = IfDescVc; Dp < IfDescEp; Dp++) { - if (Dp->state == IF_STATE_DOWNSTREAM) { + for ( Dp = IfDescVc; Dp < IfDescEp; Dp++ ) { + if ( Dp->state == IF_STATE_DOWNSTREAM ) { Dp->state = IF_STATE_LOST; } } - IoCtlReq.ifc_buf = (void *)IfVc; + IoCtlReq.ifc_buf = (void *) IfVc; IoCtlReq.ifc_len = sizeof( IfVc ); if ( ioctl( Sock, SIOCGIFCONF, &IoCtlReq ) < 0 ) my_log( LOG_ERR, errno, "ioctl SIOCGIFCONF" ); - IfEp = (void *)((char *)IfVc + IoCtlReq.ifc_len); + IfEp = (void *) ( (char *) IfVc + IoCtlReq.ifc_len ); for ( IfPt = IfVc; IfPt < IfEp; IfPt = IfNext ) { struct ifreq IfReq; - char FmtBu[ 32 ]; + char FmtBu[32]; - IfNext = (struct ifreq *)((char *)&IfPt->ifr_addr + + IfNext = (struct ifreq *) ( (char *) &IfPt->ifr_addr + #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN - IfPt->ifr_addr.sa_len + IfPt->ifr_addr.sa_len #else - sizeof(struct sockaddr_in) + sizeof( struct sockaddr_in ) #endif - ); - if (IfNext < IfPt + 1) + ); + if ( IfNext < IfPt + 1 ) IfNext = IfPt + 1; - for (Dp = IfDescVc; Dp < IfDescEp; Dp++) { - if (0 == strcmp(Dp->Name, IfPt->ifr_name)) { + for ( Dp = IfDescVc; Dp < IfDescEp; Dp++ ) { + if ( 0 == strcmp( Dp->Name, IfPt->ifr_name ) ) { break; } } - if (Dp == IfDescEp) { + if ( Dp == IfDescEp ) { strncpy( Dp->Name, IfPt->ifr_name, sizeof( IfDescEp->Name ) ); } if ( IfPt->ifr_addr.sa_family != AF_INET ) { - if (Dp == IfDescEp) { + if ( Dp == IfDescEp ) { IfDescEp++; } - Dp->InAdr.s_addr = 0; /* mark as non-IP interface */ + Dp->InAdr.s_addr = 0; /* mark as non-IP interface */ continue; } // Get the interface adress... - Dp->InAdr = ((struct sockaddr_in *)&IfPt->ifr_addr)->sin_addr; - addr = Dp->InAdr.s_addr; + Dp->InAdr = ( (struct sockaddr_in *) &IfPt->ifr_addr )->sin_addr; + addr = Dp->InAdr.s_addr; memcpy( IfReq.ifr_name, Dp->Name, sizeof( IfReq.ifr_name ) ); - IfReq.ifr_addr.sa_family = AF_INET; - ((struct sockaddr_in *)&IfReq.ifr_addr)->sin_addr.s_addr = addr; + IfReq.ifr_addr.sa_family = AF_INET; + ( (struct sockaddr_in *) &IfReq.ifr_addr )->sin_addr.s_addr = addr; // Get the subnet mask... - if (ioctl(Sock, SIOCGIFNETMASK, &IfReq ) < 0) - my_log(LOG_ERR, errno, "ioctl SIOCGIFNETMASK for %s", IfReq.ifr_name); - mask = ((struct sockaddr_in *)&IfReq.ifr_addr)->sin_addr.s_addr; + if ( ioctl( Sock, SIOCGIFNETMASK, &IfReq ) < 0 ) + my_log( LOG_ERR, errno, "ioctl SIOCGIFNETMASK for %s", IfReq.ifr_name ); + mask = ( (struct sockaddr_in *) &IfReq.ifr_addr )->sin_addr.s_addr; subnet = addr & mask; if ( ioctl( Sock, SIOCGIFFLAGS, &IfReq ) < 0 ) my_log( LOG_ERR, errno, "ioctl SIOCGIFFLAGS" ); Dp->Flags = IfReq.ifr_flags; - if (0x10d1 == Dp->Flags) - { + if ( 0x10d1 == Dp->Flags ) { if ( ioctl( Sock, SIOCGIFDSTADDR, &IfReq ) < 0 ) - my_log(LOG_ERR, errno, "ioctl SIOCGIFDSTADDR for %s", IfReq.ifr_name); - addr = ((struct sockaddr_in *)&IfReq.ifr_dstaddr)->sin_addr.s_addr; + my_log( LOG_ERR, errno, "ioctl SIOCGIFDSTADDR for %s", IfReq.ifr_name ); + addr = ( (struct sockaddr_in *) &IfReq.ifr_dstaddr )->sin_addr.s_addr; subnet = addr & mask; } - if (Dp == IfDescEp) { + if ( Dp == IfDescEp ) { // Insert the verified subnet as an allowed net... - Dp->allowednets = (struct SubnetList *)malloc(sizeof(struct SubnetList)); - if(IfDescEp->allowednets == NULL) { - my_log(LOG_ERR, 0, "Out of memory !"); + Dp->allowednets = (struct SubnetList *) malloc( sizeof( struct SubnetList ) ); + if ( IfDescEp->allowednets == NULL ) { + my_log( LOG_ERR, 0, "Out of memory !" ); } Dp->allowednets->next = NULL; - Dp->state = IF_STATE_DOWNSTREAM; - Dp->robustness = DEFAULT_ROBUSTNESS; - Dp->threshold = DEFAULT_THRESHOLD; /* ttl limit */ - Dp->ratelimit = DEFAULT_RATELIMIT; + Dp->state = IF_STATE_DOWNSTREAM; + Dp->robustness = DEFAULT_ROBUSTNESS; + Dp->threshold = DEFAULT_THRESHOLD; /* ttl limit */ + Dp->ratelimit = DEFAULT_RATELIMIT; } // Set the network address for the IF.. @@ -148,42 +152,39 @@ void rebuildIfVc () { Dp->allowednets->subnet_addr = subnet; // Set the state for the IF... - if (Dp->state == IF_STATE_LOST) { - Dp->state = IF_STATE_DOWNSTREAM; + if ( Dp->state == IF_STATE_LOST ) { + Dp->state = IF_STATE_DOWNSTREAM; } // when IF become enabeld from downstream, addVIF to enable its VIF - if (Dp->state == IF_STATE_HIDDEN) { - my_log(LOG_NOTICE, 0, "%s [Hidden -> Downstream]", Dp->Name); + if ( Dp->state == IF_STATE_HIDDEN ) { + my_log( LOG_NOTICE, 0, "%s [Hidden -> Downstream]", Dp->Name ); Dp->state = IF_STATE_DOWNSTREAM; - addVIF(Dp); - joinMcGroup(getMcGroupSock(), Dp, allrouters_group); + addVIF( Dp ); + joinMcGroup( getMcGroupSock(), Dp, allrouters_group ); } // addVIF when found new IF - if (Dp == IfDescEp) { - my_log(LOG_NOTICE, 0, "%s [New]", Dp->Name); + if ( Dp == IfDescEp ) { + my_log( LOG_NOTICE, 0, "%s [New]", Dp->Name ); Dp->state = config->defaultInterfaceState; - addVIF(Dp); - joinMcGroup(getMcGroupSock(), Dp, allrouters_group); + addVIF( Dp ); + joinMcGroup( getMcGroupSock(), Dp, allrouters_group ); IfDescEp++; } // Debug log the result... - my_log( LOG_DEBUG, 0, "rebuildIfVc: Interface %s Addr: %s, Flags: 0x%04x, Network: %s", - Dp->Name, - fmtInAdr( FmtBu, Dp->InAdr ), - Dp->Flags, - inetFmts(subnet, mask, s1)); + my_log( LOG_DEBUG, 0, "rebuildIfVc: Interface %s Addr: %s, Flags: 0x%04x, Network: %s", Dp->Name, + fmtInAdr( FmtBu, Dp->InAdr ), Dp->Flags, inetFmts( subnet, mask, s1 ) ); } // aimwang: search not longer exist IF, set as hidden and call delVIF - for (Dp = IfDescVc; Dp < IfDescEp; Dp++) { - if (IF_STATE_LOST == Dp->state) { - my_log(LOG_NOTICE, 0, "%s [Downstream -> Hidden]", Dp->Name); + for ( Dp = IfDescVc; Dp < IfDescEp; Dp++ ) { + if ( IF_STATE_LOST == Dp->state ) { + my_log( LOG_NOTICE, 0, "%s [Downstream -> Hidden]", Dp->Name ); Dp->state = IF_STATE_HIDDEN; leaveMcGroup( getMcGroupSock(), Dp, allrouters_group ); - delVIF(Dp); + delVIF( Dp ); } } @@ -191,18 +192,20 @@ void rebuildIfVc () { } /* -** Builds up a vector with the interface of the machine. Calls to the other functions of +** Builds up a vector with the interface of the machine. Calls to the other +*functions of ** the module will fail if they are called before the vector is build. ** */ -void buildIfVc(void) { - struct ifreq IfVc[ sizeof( IfDescVc ) / sizeof( IfDescVc[ 0 ] ) ]; - struct ifreq *IfEp; +void buildIfVc( void ) +{ + struct ifreq IfVc[sizeof( IfDescVc ) / sizeof( IfDescVc[0] )]; + struct ifreq * IfEp; struct Config *config = getCommonConfig(); int Sock; - if ( (Sock = socket( AF_INET, SOCK_DGRAM, 0 )) < 0 ) + if ( ( Sock = socket( AF_INET, SOCK_DGRAM, 0 ) ) < 0 ) my_log( LOG_ERR, errno, "RAW socket open" ); /* get If vector @@ -210,41 +213,41 @@ void buildIfVc(void) { { struct ifconf IoCtlReq; - IoCtlReq.ifc_buf = (void *)IfVc; + IoCtlReq.ifc_buf = (void *) IfVc; IoCtlReq.ifc_len = sizeof( IfVc ); if ( ioctl( Sock, SIOCGIFCONF, &IoCtlReq ) < 0 ) my_log( LOG_ERR, errno, "ioctl SIOCGIFCONF" ); - IfEp = (void *)((char *)IfVc + IoCtlReq.ifc_len); + IfEp = (void *) ( (char *) IfVc + IoCtlReq.ifc_len ); } /* loop over interfaces and copy interface info to IfDescVc */ { - struct ifreq *IfPt, *IfNext; + struct ifreq *IfPt, *IfNext; // Temp keepers of interface params... uint32_t addr, subnet, mask; for ( IfPt = IfVc; IfPt < IfEp; IfPt = IfNext ) { struct ifreq IfReq; - char FmtBu[ 32 ]; + char FmtBu[32]; - IfNext = (struct ifreq *)((char *)&IfPt->ifr_addr + + IfNext = (struct ifreq *) ( (char *) &IfPt->ifr_addr + #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN - IfPt->ifr_addr.sa_len + IfPt->ifr_addr.sa_len #else - sizeof(struct sockaddr_in) + sizeof( struct sockaddr_in ) #endif - ); - if (IfNext < IfPt + 1) - IfNext = IfPt + 1; + ); + if ( IfNext < IfPt + 1 ) + IfNext = IfPt + 1; strncpy( IfDescEp->Name, IfPt->ifr_name, sizeof( IfDescEp->Name ) ); // Currently don't set any allowed nets... - //IfDescEp->allowednets = NULL; + // IfDescEp->allowednets = NULL; // Set the index to -1 by default. IfDescEp->index = -1; @@ -252,23 +255,23 @@ void buildIfVc(void) { /* don't retrieve more info for non-IP interfaces */ if ( IfPt->ifr_addr.sa_family != AF_INET ) { - IfDescEp->InAdr.s_addr = 0; /* mark as non-IP interface */ + IfDescEp->InAdr.s_addr = 0; /* mark as non-IP interface */ IfDescEp++; continue; } // Get the interface adress... - IfDescEp->InAdr = ((struct sockaddr_in *)&IfPt->ifr_addr)->sin_addr; - addr = IfDescEp->InAdr.s_addr; + IfDescEp->InAdr = ( (struct sockaddr_in *) &IfPt->ifr_addr )->sin_addr; + addr = IfDescEp->InAdr.s_addr; memcpy( IfReq.ifr_name, IfDescEp->Name, sizeof( IfReq.ifr_name ) ); - IfReq.ifr_addr.sa_family = AF_INET; - ((struct sockaddr_in *)&IfReq.ifr_addr)->sin_addr.s_addr = addr; + IfReq.ifr_addr.sa_family = AF_INET; + ( (struct sockaddr_in *) &IfReq.ifr_addr )->sin_addr.s_addr = addr; // Get the subnet mask... - if (ioctl(Sock, SIOCGIFNETMASK, &IfReq ) < 0) - my_log(LOG_ERR, errno, "ioctl SIOCGIFNETMASK for %s", IfReq.ifr_name); - mask = ((struct sockaddr_in *)&IfReq.ifr_addr)->sin_addr.s_addr; + if ( ioctl( Sock, SIOCGIFNETMASK, &IfReq ) < 0 ) + my_log( LOG_ERR, errno, "ioctl SIOCGIFNETMASK for %s", IfReq.ifr_name ); + mask = ( (struct sockaddr_in *) &IfReq.ifr_addr )->sin_addr.s_addr; subnet = addr & mask; /* get if flags @@ -286,35 +289,32 @@ void buildIfVc(void) { IfDescEp->Flags = IfReq.ifr_flags; // aimwang: when pppx get dstaddr for use - if (0x10d1 == IfDescEp->Flags) - { + if ( 0x10d1 == IfDescEp->Flags ) { if ( ioctl( Sock, SIOCGIFDSTADDR, &IfReq ) < 0 ) - my_log(LOG_ERR, errno, "ioctl SIOCGIFDSTADDR for %s", IfReq.ifr_name); - addr = ((struct sockaddr_in *)&IfReq.ifr_dstaddr)->sin_addr.s_addr; + my_log( LOG_ERR, errno, "ioctl SIOCGIFDSTADDR for %s", IfReq.ifr_name ); + addr = ( (struct sockaddr_in *) &IfReq.ifr_dstaddr )->sin_addr.s_addr; subnet = addr & mask; } // Insert the verified subnet as an allowed net... - IfDescEp->allowednets = (struct SubnetList *)malloc(sizeof(struct SubnetList)); - if(IfDescEp->allowednets == NULL) my_log(LOG_ERR, 0, "Out of memory !"); + IfDescEp->allowednets = (struct SubnetList *) malloc( sizeof( struct SubnetList ) ); + if ( IfDescEp->allowednets == NULL ) + my_log( LOG_ERR, 0, "Out of memory !" ); // Create the network address for the IF.. - IfDescEp->allowednets->next = NULL; + IfDescEp->allowednets->next = NULL; IfDescEp->allowednets->subnet_mask = mask; IfDescEp->allowednets->subnet_addr = subnet; // Set the default params for the IF... - IfDescEp->state = config->defaultInterfaceState; - IfDescEp->robustness = DEFAULT_ROBUSTNESS; - IfDescEp->threshold = DEFAULT_THRESHOLD; /* ttl limit */ - IfDescEp->ratelimit = DEFAULT_RATELIMIT; + IfDescEp->state = config->defaultInterfaceState; + IfDescEp->robustness = DEFAULT_ROBUSTNESS; + IfDescEp->threshold = DEFAULT_THRESHOLD; /* ttl limit */ + IfDescEp->ratelimit = DEFAULT_RATELIMIT; // Debug log the result... - my_log( LOG_DEBUG, 0, "buildIfVc: Interface %s Addr: %s, Flags: 0x%04x, Network: %s", - IfDescEp->Name, - fmtInAdr( FmtBu, IfDescEp->InAdr ), - IfDescEp->Flags, - inetFmts(subnet,mask, s1)); + my_log( LOG_DEBUG, 0, "buildIfVc: Interface %s Addr: %s, Flags: 0x%04x, Network: %s", IfDescEp->Name, + fmtInAdr( FmtBu, IfDescEp->InAdr ), IfDescEp->Flags, inetFmts( subnet, mask, s1 ) ); IfDescEp++; } @@ -330,11 +330,12 @@ void buildIfVc(void) { ** - NULL if no interface 'IfName' exists ** */ -struct IfDesc *getIfByName( const char *IfName ) { +struct IfDesc *getIfByName( const char *IfName ) +{ struct IfDesc *Dp; for ( Dp = IfDescVc; Dp < IfDescEp; Dp++ ) - if ( ! strcmp( IfName, Dp->Name ) ) + if ( !strcmp( IfName, Dp->Name ) ) return Dp; return NULL; @@ -347,8 +348,9 @@ struct IfDesc *getIfByName( const char *IfName ) { ** - NULL if no interface 'Ix' exists ** */ -struct IfDesc *getIfByIx( unsigned Ix ) { - struct IfDesc *Dp = &IfDescVc[ Ix ]; +struct IfDesc *getIfByIx( unsigned Ix ) +{ + struct IfDesc *Dp = &IfDescVc[Ix]; return Dp < IfDescEp ? Dp : NULL; } @@ -357,19 +359,21 @@ struct IfDesc *getIfByIx( unsigned Ix ) { * the supplied IP adress. The IP must match a interfaces * subnet, or any configured allowed subnet on a interface. */ -struct IfDesc *getIfByAddress( uint32_t ipaddr ) { +struct IfDesc *getIfByAddress( uint32_t ipaddr ) +{ - struct IfDesc *Dp; - struct SubnetList *currsubnet; - struct IfDesc *res = NULL; - uint32_t last_subnet_mask = 0; + struct IfDesc * Dp; + struct SubnetList *currsubnet; + struct IfDesc * res = NULL; + uint32_t last_subnet_mask = 0; for ( Dp = IfDescVc; Dp < IfDescEp; Dp++ ) { // Loop through all registered allowed nets of the VIF... - for(currsubnet = Dp->allowednets; currsubnet != NULL; currsubnet = currsubnet->next) { + for ( currsubnet = Dp->allowednets; currsubnet != NULL; currsubnet = currsubnet->next ) { // Check if the ip falls in under the subnet.... - if(currsubnet->subnet_mask > last_subnet_mask && (ipaddr & currsubnet->subnet_mask) == currsubnet->subnet_addr) { - res = Dp; + if ( currsubnet->subnet_mask > last_subnet_mask && + ( ipaddr & currsubnet->subnet_mask ) == currsubnet->subnet_addr ) { + res = Dp; last_subnet_mask = currsubnet->subnet_mask; } } @@ -377,17 +381,17 @@ struct IfDesc *getIfByAddress( uint32_t ipaddr ) { return res; } - /** * Returns a pointer to the IfDesc whose subnet matches * the supplied IP adress. The IP must match a interfaces * subnet, or any configured allowed subnet on a interface. */ -struct IfDesc *getIfByVifIndex( unsigned vifindex ) { - struct IfDesc *Dp; - if(vifindex>0) { +struct IfDesc *getIfByVifIndex( unsigned vifindex ) +{ + struct IfDesc *Dp; + if ( vifindex > 0 ) { for ( Dp = IfDescVc; Dp < IfDescEp; Dp++ ) { - if(Dp->index == vifindex) { + if ( Dp->index == vifindex ) { return Dp; } } @@ -395,22 +399,22 @@ struct IfDesc *getIfByVifIndex( unsigned vifindex ) { return NULL; } - /** * Function that checks if a given ipaddress is a valid * address for the supplied VIF. */ -int isAdressValidForIf( struct IfDesc* intrface, uint32_t ipaddr ) { - struct SubnetList *currsubnet; +int isAdressValidForIf( struct IfDesc *intrface, uint32_t ipaddr ) +{ + struct SubnetList *currsubnet; - if(intrface == NULL) { + if ( intrface == NULL ) { return 0; } // Loop through all registered allowed nets of the VIF... - for(currsubnet = intrface->allowednets; currsubnet != NULL; currsubnet = currsubnet->next) { + for ( currsubnet = intrface->allowednets; currsubnet != NULL; currsubnet = currsubnet->next ) { // Check if the ip falls in under the subnet.... - if((ipaddr & currsubnet->subnet_mask) == (currsubnet->subnet_addr& currsubnet->subnet_mask)) { + if ( ( ipaddr & currsubnet->subnet_mask ) == ( currsubnet->subnet_addr & currsubnet->subnet_mask ) ) { return 1; } } diff --git a/src/igmp.c b/src/igmp.c index c09f167f..a394090d 100644 --- a/src/igmp.c +++ b/src/igmp.c @@ -40,9 +40,9 @@ #include "igmpv3.h" // Globals -uint32_t allhosts_group; /* All hosts addr in net order */ -uint32_t allrouters_group; /* All hosts addr in net order */ -uint32_t alligmp3_group; /* IGMPv3 addr in net order */ +uint32_t allhosts_group; /* All hosts addr in net order */ +uint32_t allrouters_group; /* All hosts addr in net order */ +uint32_t alligmp3_group; /* IGMPv3 addr in net order */ extern int MRouterFD; @@ -50,19 +50,20 @@ extern int MRouterFD; * Open and initialize the igmp socket, and fill in the non-changing * IP header fields in the output packet buffer. */ -void initIgmp(void) { +void initIgmp( void ) +{ struct ip *ip; - recv_buf = malloc(RECV_BUF_SIZE); - send_buf = malloc(RECV_BUF_SIZE); + recv_buf = malloc( RECV_BUF_SIZE ); + send_buf = malloc( RECV_BUF_SIZE ); - k_hdr_include(true); /* include IP header when sending */ - k_set_rcvbuf(256*1024,48*1024); /* lots of input buffering */ - k_set_ttl(1); /* restrict multicasts to one hop */ - k_set_loop(false); /* disable multicast loopback */ + k_hdr_include( true ); /* include IP header when sending */ + k_set_rcvbuf( 256 * 1024, 48 * 1024 ); /* lots of input buffering */ + k_set_ttl( 1 ); /* restrict multicasts to one hop */ + k_set_loop( false ); /* disable multicast loopback */ - ip = (struct ip *)send_buf; - memset(ip, 0, sizeof(struct ip)); + ip = (struct ip *) send_buf; + memset( ip, 0, sizeof( struct ip ) ); /* * Fields zeroed that aren't filled in later: * - IP ID (let the kernel fill it in) @@ -70,32 +71,38 @@ void initIgmp(void) { * - Checksum (let the kernel fill it in) */ ip->ip_v = IPVERSION; - 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_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; - allhosts_group = htonl(INADDR_ALLHOSTS_GROUP); - allrouters_group = htonl(INADDR_ALLRTRS_GROUP); - alligmp3_group = htonl(INADDR_ALLIGMPV3_GROUP); + allhosts_group = htonl( INADDR_ALLHOSTS_GROUP ); + allrouters_group = htonl( INADDR_ALLRTRS_GROUP ); + alligmp3_group = htonl( INADDR_ALLIGMPV3_GROUP ); } /** * Finds the textual name of the supplied IGMP request. */ -static const char *igmpPacketKind(unsigned int type, unsigned int code) { +static const char *igmpPacketKind( unsigned int type, unsigned int code ) +{ static char unknown[20]; - switch (type) { - case IGMP_MEMBERSHIP_QUERY: return "Membership query "; - case IGMP_V1_MEMBERSHIP_REPORT: return "V1 member report "; - case IGMP_V2_MEMBERSHIP_REPORT: return "V2 member report "; - case IGMP_V3_MEMBERSHIP_REPORT: return "V3 member report "; - case IGMP_V2_LEAVE_GROUP: return "Leave message "; - - default: - sprintf(unknown, "unk: 0x%02x/0x%02x ", type, code); - return unknown; + switch ( type ) { + case IGMP_MEMBERSHIP_QUERY: + return "Membership query "; + case IGMP_V1_MEMBERSHIP_REPORT: + return "V1 member report "; + case IGMP_V2_MEMBERSHIP_REPORT: + return "V2 member report "; + case IGMP_V3_MEMBERSHIP_REPORT: + return "V3 member report "; + case IGMP_V2_LEAVE_GROUP: + return "Leave message "; + + default: + sprintf( unknown, "unk: 0x%02x/0x%02x ", type, code ); + return unknown; } } @@ -103,28 +110,27 @@ static const char *igmpPacketKind(unsigned int type, unsigned int code) { * Process a newly received IGMP packet that is sitting in the input * packet buffer. */ -void acceptIgmp(int recvlen) { - register uint32_t src, dst, group; - struct ip *ip; - struct igmp *igmp; +void acceptIgmp( int recvlen ) +{ + register uint32_t src, dst, group; + struct ip * ip; + struct igmp * igmp; struct igmpv3_report *igmpv3; - struct igmpv3_grec *grec; - int ipdatalen, iphdrlen, ngrec, nsrcs, i; + struct igmpv3_grec * grec; + int ipdatalen, iphdrlen, ngrec, nsrcs, i; - if (recvlen < sizeof(struct ip)) { - my_log(LOG_WARNING, 0, - "received packet too short (%u bytes) for IP header", recvlen); + if ( recvlen < sizeof( struct ip ) ) { + my_log( LOG_WARNING, 0, "received packet too short (%u bytes) for IP header", recvlen ); return; } - ip = (struct ip *)recv_buf; - src = ip->ip_src.s_addr; - dst = ip->ip_dst.s_addr; + ip = (struct ip *) recv_buf; + 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."); + if ( dst == htonl( 0xEFFFFFFA ) ) { + my_log( LOG_NOTICE, 0, "The IGMP message was local multicast. Ignoring." ); return; } @@ -133,46 +139,52 @@ void acceptIgmp(int recvlen) { * a new src grp pair message has arrived and so, it would be * necessary to install a route into the kernel for this. */ - if (ip->ip_p == 0) { - if (src == 0 || dst == 0) { - my_log(LOG_WARNING, 0, "kernel request not accurate"); + if ( ip->ip_p == 0 ) { + if ( src == 0 || dst == 0 ) { + my_log( LOG_WARNING, 0, "kernel request not accurate" ); } else { struct IfDesc *checkVIF; - for(i=0; iInAdr.s_addr) { - my_log(LOG_NOTICE, 0, "Route activation request from %s for %s is from myself. Ignoring.", - inetFmt(src, s1), inetFmt(dst, s2)); + else if ( src == checkVIF->InAdr.s_addr ) { + my_log( LOG_NOTICE, 0, "Route activation request from %s for %s is " + "from myself. Ignoring.", + inetFmt( src, s1 ), inetFmt( dst, s2 ) ); return; } - else if(!isAdressValidForIf(checkVIF, src)) { - struct IfDesc *downVIF = getIfByAddress(src); - if (downVIF && downVIF->state & IF_STATE_DOWNSTREAM) { - my_log(LOG_NOTICE, 0, "The source address %s for group %s is from downstream VIF[%d]. Ignoring.", - inetFmt(src, s1), inetFmt(dst, s2), i); - } else { - my_log(LOG_WARNING, 0, "The source address %s for group %s, is not in any valid net for upstream VIF[%d].", - inetFmt(src, s1), inetFmt(dst, s2), i); + else if ( !isAdressValidForIf( checkVIF, src ) ) { + struct IfDesc *downVIF = getIfByAddress( src ); + if ( downVIF && downVIF->state & IF_STATE_DOWNSTREAM ) { + my_log( LOG_NOTICE, 0, "The source address %s for group %s is " + "from downstream VIF[%d]. Ignoring.", + inetFmt( src, s1 ), inetFmt( dst, s2 ), i ); } - } else { + else { + my_log( LOG_WARNING, 0, "The source address %s for group %s, is " + "not in any valid net for upstream " + "VIF[%d].", + inetFmt( src, s1 ), inetFmt( dst, s2 ), i ); + } + } + else { // Activate the route. int vifindex = checkVIF->index; - my_log(LOG_DEBUG, 0, "Route activate request from %s to %s on VIF[%d]", - inetFmt(src,s1), inetFmt(dst,s2), vifindex); - activateRoute(dst, src, vifindex); + my_log( LOG_DEBUG, 0, "Route activate request from %s to %s on VIF[%d]", inetFmt( src, s1 ), + inetFmt( dst, s2 ), vifindex ); + activateRoute( dst, src, vifindex ); i = MAX_UPS_VIFS; } - } else { + } + else { i = MAX_UPS_VIFS; } } @@ -181,122 +193,114 @@ void acceptIgmp(int recvlen) { } iphdrlen = ip->ip_hl << 2; - ipdatalen = ip_data_len(ip); + ipdatalen = ip_data_len( ip ); - if (iphdrlen + ipdatalen != recvlen) { - my_log(LOG_WARNING, 0, - "received packet from %s shorter (%u bytes) than hdr+data length (%u+%u)", - inetFmt(src, s1), recvlen, iphdrlen, ipdatalen); + if ( iphdrlen + ipdatalen != recvlen ) { + my_log( LOG_WARNING, 0, "received packet from %s shorter (%u bytes) than " + "hdr+data length (%u+%u)", + inetFmt( src, s1 ), recvlen, iphdrlen, ipdatalen ); return; } - igmp = (struct igmp *)(recv_buf + iphdrlen); - if ((ipdatalen < IGMP_MINLEN) || - (igmp->igmp_type == IGMP_V3_MEMBERSHIP_REPORT && ipdatalen <= IGMPV3_MINLEN)) { - my_log(LOG_WARNING, 0, - "received IP data field too short (%u bytes) for IGMP, from %s", - ipdatalen, inetFmt(src, s1)); + igmp = (struct igmp *) ( recv_buf + iphdrlen ); + if ( ( ipdatalen < IGMP_MINLEN ) || + ( igmp->igmp_type == IGMP_V3_MEMBERSHIP_REPORT && ipdatalen <= IGMPV3_MINLEN ) ) { + my_log( LOG_WARNING, 0, "received IP data field too short (%u bytes) for IGMP, from %s", ipdatalen, + inetFmt( src, s1 ) ); return; } - my_log(LOG_NOTICE, 0, "RECV %s from %-15s to %s", - igmpPacketKind(igmp->igmp_type, igmp->igmp_code), - inetFmt(src, s1), inetFmt(dst, s2) ); - - switch (igmp->igmp_type) { - case IGMP_V1_MEMBERSHIP_REPORT: - case IGMP_V2_MEMBERSHIP_REPORT: - group = igmp->igmp_group.s_addr; - acceptGroupReport(src, group); - return; - - case IGMP_V3_MEMBERSHIP_REPORT: - igmpv3 = (struct igmpv3_report *)(recv_buf + iphdrlen); - grec = &igmpv3->igmp_grec[0]; - ngrec = ntohs(igmpv3->igmp_ngrec); - while (ngrec--) { - if ((uint8_t *)igmpv3 + ipdatalen < (uint8_t *)grec + sizeof(*grec)) - break; - group = grec->grec_mca.s_addr; - nsrcs = ntohs(grec->grec_nsrcs); - switch (grec->grec_type) { - case IGMPV3_MODE_IS_INCLUDE: - case IGMPV3_CHANGE_TO_INCLUDE: - if (nsrcs == 0) { - acceptLeaveMessage(src, group); + my_log( LOG_NOTICE, 0, "RECV %s from %-15s to %s", igmpPacketKind( igmp->igmp_type, igmp->igmp_code ), + inetFmt( src, s1 ), inetFmt( dst, s2 ) ); + + switch ( igmp->igmp_type ) { + case IGMP_V1_MEMBERSHIP_REPORT: + case IGMP_V2_MEMBERSHIP_REPORT: + group = igmp->igmp_group.s_addr; + acceptGroupReport( src, group ); + return; + + case IGMP_V3_MEMBERSHIP_REPORT: + igmpv3 = (struct igmpv3_report *) ( recv_buf + iphdrlen ); + grec = &igmpv3->igmp_grec[0]; + ngrec = ntohs( igmpv3->igmp_ngrec ); + while ( ngrec-- ) { + if ( (uint8_t *) igmpv3 + ipdatalen < (uint8_t *) grec + sizeof( *grec ) ) break; - } /* else fall through */ - case IGMPV3_MODE_IS_EXCLUDE: - case IGMPV3_CHANGE_TO_EXCLUDE: - case IGMPV3_ALLOW_NEW_SOURCES: - acceptGroupReport(src, group); - break; - case IGMPV3_BLOCK_OLD_SOURCES: - break; - default: - my_log(LOG_INFO, 0, - "ignoring unknown IGMPv3 group record type %x from %s to %s for %s", - grec->grec_type, inetFmt(src, s1), inetFmt(dst, s2), - inetFmt(group, s3)); - break; + group = grec->grec_mca.s_addr; + nsrcs = ntohs( grec->grec_nsrcs ); + switch ( grec->grec_type ) { + case IGMPV3_MODE_IS_INCLUDE: + case IGMPV3_CHANGE_TO_INCLUDE: + if ( nsrcs == 0 ) { + acceptLeaveMessage( src, group ); + break; + } /* else fall through */ + case IGMPV3_MODE_IS_EXCLUDE: + case IGMPV3_CHANGE_TO_EXCLUDE: + case IGMPV3_ALLOW_NEW_SOURCES: + acceptGroupReport( src, group ); + break; + case IGMPV3_BLOCK_OLD_SOURCES: + break; + default: + my_log( LOG_INFO, 0, "ignoring unknown IGMPv3 group record type %x from %s to %s for %s", + grec->grec_type, inetFmt( src, s1 ), inetFmt( dst, s2 ), inetFmt( group, s3 ) ); + break; + } + grec = (struct igmpv3_grec *) ( &grec->grec_src[nsrcs] + grec->grec_auxwords * 4 ); } - grec = (struct igmpv3_grec *) - (&grec->grec_src[nsrcs] + grec->grec_auxwords * 4); - } - return; + return; - case IGMP_V2_LEAVE_GROUP: - group = igmp->igmp_group.s_addr; - acceptLeaveMessage(src, group); - return; + case IGMP_V2_LEAVE_GROUP: + group = igmp->igmp_group.s_addr; + acceptLeaveMessage( src, group ); + return; - case IGMP_MEMBERSHIP_QUERY: - return; + case IGMP_MEMBERSHIP_QUERY: + return; - default: - my_log(LOG_INFO, 0, - "ignoring unknown IGMP message type %x from %s to %s", - igmp->igmp_type, inetFmt(src, s1), - inetFmt(dst, s2)); - return; + default: + my_log( LOG_INFO, 0, "ignoring unknown IGMP message type %x from %s to %s", igmp->igmp_type, + inetFmt( src, s1 ), inetFmt( dst, s2 ) ); + return; } } - /* * Construct an IGMP message in the output packet buffer. The caller may * have already placed data in that buffer, of length 'datalen'. */ -static void buildIgmp(uint32_t src, uint32_t dst, int type, int code, uint32_t group, int datalen) { - struct ip *ip; +static void buildIgmp( uint32_t src, uint32_t dst, int type, int code, uint32_t group, int datalen ) +{ + struct ip * ip; struct igmp *igmp; - extern int curttl; + extern int curttl; - ip = (struct ip *)send_buf; - ip->ip_src.s_addr = src; - ip->ip_dst.s_addr = dst; - ip_set_len(ip, IP_HEADER_RAOPT_LEN + IGMP_MINLEN + datalen); + ip = (struct ip *) send_buf; + ip->ip_src.s_addr = src; + ip->ip_dst.s_addr = dst; + ip_set_len( ip, IP_HEADER_RAOPT_LEN + IGMP_MINLEN + datalen ); - if (IN_MULTICAST(ntohl(dst))) { + if ( IN_MULTICAST( ntohl( dst ) ) ) { ip->ip_ttl = curttl; - } else { + } + else { ip->ip_ttl = MAXTTL; } /* Add Router Alert option */ - ((unsigned char*)send_buf+MIN_IP_HEADER_LEN)[0] = IPOPT_RA; - ((unsigned char*)send_buf+MIN_IP_HEADER_LEN)[1] = 0x04; - ((unsigned char*)send_buf+MIN_IP_HEADER_LEN)[2] = 0x00; - ((unsigned char*)send_buf+MIN_IP_HEADER_LEN)[3] = 0x00; + ( (unsigned char *) send_buf + MIN_IP_HEADER_LEN )[0] = IPOPT_RA; + ( (unsigned char *) send_buf + MIN_IP_HEADER_LEN )[1] = 0x04; + ( (unsigned char *) send_buf + MIN_IP_HEADER_LEN )[2] = 0x00; + ( (unsigned char *) send_buf + MIN_IP_HEADER_LEN )[3] = 0x00; - igmp = (struct igmp *)(send_buf + IP_HEADER_RAOPT_LEN); + 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((unsigned short *)igmp, - IP_HEADER_RAOPT_LEN + datalen); - + igmp->igmp_cksum = inetChksum( (unsigned short *) igmp, IP_HEADER_RAOPT_LEN + datalen ); } /* @@ -304,47 +308,44 @@ static void buildIgmp(uint32_t src, uint32_t dst, int type, int code, uint32_t g * Then send the message from the interface with IP address 'src' to * destination 'dst'. */ -void sendIgmp(uint32_t src, uint32_t dst, int type, int code, uint32_t group, int datalen) { +void sendIgmp( uint32_t src, uint32_t dst, int type, int code, uint32_t group, int datalen ) +{ struct sockaddr_in sdst; - int setloop = 0, setigmpsource = 0; + int setloop = 0, setigmpsource = 0; - buildIgmp(src, dst, type, code, group, datalen); + buildIgmp( src, dst, type, code, group, datalen ); - if (IN_MULTICAST(ntohl(dst))) { - k_set_if(src); + if ( IN_MULTICAST( ntohl( dst ) ) ) { + k_set_if( src ); setigmpsource = 1; - if (type != IGMP_DVMRP || dst == allhosts_group) { + if ( type != IGMP_DVMRP || dst == allhosts_group ) { setloop = 1; - k_set_loop(true); + k_set_loop( true ); } } - memset(&sdst, 0, sizeof(sdst)); + memset( &sdst, 0, sizeof( sdst ) ); sdst.sin_family = AF_INET; #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN - sdst.sin_len = sizeof(sdst); + sdst.sin_len = sizeof( sdst ); #endif sdst.sin_addr.s_addr = dst; - if (sendto(MRouterFD, send_buf, - 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."); + if ( sendto( MRouterFD, send_buf, 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." ); else - my_log(LOG_INFO, errno, - "sendto to %s on %s", - inetFmt(dst, s1), inetFmt(src, s2)); + my_log( LOG_INFO, errno, "sendto to %s on %s", inetFmt( dst, s1 ), inetFmt( src, s2 ) ); } - if(setigmpsource) { - if (setloop) { - k_set_loop(false); + if ( setigmpsource ) { + if ( setloop ) { + k_set_loop( false ); } // Restore original... - k_set_if(INADDR_ANY); + k_set_if( INADDR_ANY ); } - my_log(LOG_DEBUG, 0, "SENT %s from %-15s to %s", - igmpPacketKind(type, code), - src == INADDR_ANY ? "INADDR_ANY" : inetFmt(src, s1), inetFmt(dst, s2)); + my_log( LOG_DEBUG, 0, "SENT %s from %-15s to %s", igmpPacketKind( type, code ), + src == INADDR_ANY ? "INADDR_ANY" : inetFmt( src, s1 ), inetFmt( dst, s2 ) ); } diff --git a/src/igmpproxy.c b/src/igmpproxy.c index 45e4f387..a415ac71 100644 --- a/src/igmpproxy.c +++ b/src/igmpproxy.c @@ -39,104 +39,98 @@ #include "igmpproxy.h" -static const char Usage[] = -"Usage: igmpproxy [-h] [-d] [-v [-v]] \n" -"\n" -" -h Display this help screen\n" -" -d Run in debug mode. Output all messages on stderr\n" -" -v Be verbose. Give twice to see even debug messages.\n" -"\n" -PACKAGE_STRING "\n" -; +static const char Usage[] = "Usage: igmpproxy [-h] [-d] [-v [-v]] \n" + "\n" + " -h Display this help screen\n" + " -d Run in debug mode. Output all messages on stderr\n" + " -v Be verbose. Give twice to see even debug messages.\n" + "\n" PACKAGE_STRING "\n"; // Local function Prototypes -static void signalHandler(int); -int igmpProxyInit(void); -void igmpProxyCleanUp(void); -void igmpProxyRun(void); +static void signalHandler( int ); +int igmpProxyInit( void ); +void igmpProxyCleanUp( void ); +void igmpProxyRun( void ); // Global vars... static int sighandled = 0; -#define GOT_SIGINT 0x01 -#define GOT_SIGHUP 0x02 +#define GOT_SIGINT 0x01 +#define GOT_SIGHUP 0x02 #define GOT_SIGUSR1 0x04 #define GOT_SIGUSR2 0x08 // Holds the indeces of the upstream IF... -int upStreamIfIdx[MAX_UPS_VIFS]; +int upStreamIfIdx[MAX_UPS_VIFS]; /** * Program main method. Is invoked when the program is started * on commandline. The number of commandline arguments, and a * pointer to the arguments are received on the line... */ -int main( int ArgCn, char *ArgVc[] ) { +int main( int ArgCn, char *ArgVc[] ) +{ int c; // Parse the commandline options and setup basic settings.. - while ((c = getopt(ArgCn, ArgVc, "vdh")) != -1) { - switch (c) { - case 'd': - Log2Stderr = true; - break; - case 'v': - if (LogLevel == LOG_INFO) - LogLevel = LOG_DEBUG; - else - LogLevel = LOG_INFO; - break; - case 'h': - fputs(Usage, stderr); - exit(0); - break; - default: - exit(1); - break; + while ( ( c = getopt( ArgCn, ArgVc, "vdh" ) ) != -1 ) { + switch ( c ) { + case 'd': + Log2Stderr = true; + break; + case 'v': + LogLevel++; + break; + case 'h': + fputs( Usage, stderr ); + exit( 0 ); + break; + default: + exit( 1 ); + break; } } - if (optind != ArgCn - 1) { - fputs("You must specify the configuration file.\n", stderr); - exit(1); + if ( optind != ArgCn - 1 ) { + fputs( "You must specify the configuration file.\n", stderr ); + exit( 1 ); } char *configFilePath = ArgVc[optind]; // Chech that we are root - if (geteuid() != 0) { - fprintf(stderr, "igmpproxy: must be root\n"); - exit(1); + if ( geteuid() != 0 ) { + fprintf( stderr, "igmpproxy: must be root\n" ); + exit( 1 ); } - openlog("igmpproxy", LOG_PID, LOG_USER); + openlog( "igmpproxy", LOG_PID, LOG_USER ); // Write debug notice with file path... - my_log(LOG_DEBUG, 0, "Searching for config file at '%s'" , configFilePath); + my_log( LOG_DEBUG, 0, "Searching for config file at '%s'", configFilePath ); do { // Loads the config file... - if( ! loadConfig( configFilePath ) ) { - my_log(LOG_ERR, 0, "Unable to load config file..."); + if ( !loadConfig( configFilePath ) ) { + my_log( LOG_ERR, 0, "Unable to load config file..." ); break; } // Initializes the deamon. if ( !igmpProxyInit() ) { - my_log(LOG_ERR, 0, "Unable to initialize IGMPproxy."); + my_log( LOG_ERR, 0, "Unable to initialize IGMPproxy." ); break; } if ( !Log2Stderr ) { // Only daemon goes past this line... - if (fork()) exit(0); + if ( fork() ) + exit( 0 ); // Detach daemon from terminal - if ( close( 0 ) < 0 || close( 1 ) < 0 || close( 2 ) < 0 - || open( "/dev/null", 0 ) != 0 || dup2( 0, 1 ) < 0 || dup2( 0, 2 ) < 0 - || setpgid( 0, 0 ) < 0 - ) { + if ( close( 0 ) < 0 || close( 1 ) < 0 || close( 2 ) < 0 || open( "/dev/null", 0 ) != 0 || + dup2( 0, 1 ) < 0 || dup2( 0, 2 ) < 0 || setpgid( 0, 0 ) < 0 ) { my_log( LOG_ERR, errno, "failed to detach daemon" ); } } @@ -150,23 +144,24 @@ int main( int ArgCn, char *ArgVc[] ) { } while ( false ); // Inform that we are exiting. - my_log(LOG_INFO, 0, "Shutdown complete...."); + my_log( LOG_INFO, 0, "Shutdown complete...." ); - exit(0); + exit( 0 ); } /** * Handles the initial startup of the daemon. */ -int igmpProxyInit(void) { +int igmpProxyInit( void ) +{ struct sigaction sa; - int Err; + int Err; sa.sa_handler = signalHandler; - sa.sa_flags = 0; /* Interrupt system calls */ - sigemptyset(&sa.sa_mask); - sigaction(SIGTERM, &sa, NULL); - sigaction(SIGINT, &sa, NULL); + sa.sa_flags = 0; /* Interrupt system calls */ + sigemptyset( &sa.sa_mask ); + sigaction( SIGTERM, &sa, NULL ); + sigaction( SIGINT, &sa, NULL ); // Loads configuration for Physical interfaces... buildIfVc(); @@ -175,48 +170,51 @@ int igmpProxyInit(void) { configureVifs(); switch ( Err = enableMRouter() ) { - case 0: break; - case EADDRINUSE: my_log( LOG_ERR, EADDRINUSE, "MC-Router API already in use" ); break; - default: my_log( LOG_ERR, Err, "MRT_INIT failed" ); + case 0: + break; + case EADDRINUSE: + my_log( LOG_ERR, EADDRINUSE, "MC-Router API already in use" ); + break; + default: + my_log( LOG_ERR, Err, "MRT_INIT failed" ); } /* create VIFs for all IP, non-loop interfaces */ { - unsigned Ix; + unsigned Ix; struct IfDesc *Dp; - int vifcount = 0, upsvifcount = 0; + int vifcount = 0, upsvifcount = 0; // init array to "not set" - for ( Ix = 0; Ix < MAX_UPS_VIFS; Ix++) - { + for ( Ix = 0; Ix < MAX_UPS_VIFS; Ix++ ) { upStreamIfIdx[Ix] = -1; } - for ( Ix = 0; (Dp = getIfByIx(Ix)); Ix++ ) { + for ( Ix = 0; ( Dp = getIfByIx( Ix ) ); Ix++ ) { - if ( Dp->InAdr.s_addr && ! (Dp->Flags & IFF_LOOPBACK) ) { - if(Dp->state == IF_STATE_UPSTREAM) { - if (upsvifcount < MAX_UPS_VIFS -1) - { - my_log(LOG_DEBUG, 0, "Found upstrem IF #%d, will assing as upstream Vif %d", - upsvifcount, Ix); + if ( Dp->InAdr.s_addr && !( Dp->Flags & IFF_LOOPBACK ) ) { + if ( Dp->state == IF_STATE_UPSTREAM ) { + if ( upsvifcount < MAX_UPS_VIFS - 1 ) { + my_log( LOG_DEBUG, 0, "Found upstrem IF #%d, will assing as upstream Vif %d", upsvifcount, Ix ); upStreamIfIdx[upsvifcount++] = Ix; - } else { - my_log(LOG_ERR, 0, "Cannot set VIF #%d as upstream as well. Mac upstream Vif count is %d", - Ix, MAX_UPS_VIFS); + } + else { + my_log( LOG_ERR, 0, "Cannot set VIF #%d as upstream as well. Mac " + "upstream Vif count is %d", + Ix, MAX_UPS_VIFS ); } } - if (Dp->state != IF_STATE_DISABLED) { + if ( Dp->state != IF_STATE_DISABLED ) { addVIF( Dp ); vifcount++; } } } - if(0 == upsvifcount) { - my_log(LOG_ERR, 0, "There must be at least 1 Vif as upstream."); + if ( 0 == upsvifcount ) { + my_log( LOG_ERR, 0, "There must be at least 1 Vif as upstream." ); } } @@ -233,60 +231,63 @@ int igmpProxyInit(void) { /** * Clean up all on exit... */ -void igmpProxyCleanUp(void) { +void igmpProxyCleanUp( void ) +{ my_log( LOG_DEBUG, 0, "clean handler called" ); - free_all_callouts(); // No more timeouts. - clearAllRoutes(); // Remove all routes. - disableMRouter(); // Disable the multirout API + free_all_callouts(); // No more timeouts. + clearAllRoutes(); // Remove all routes. + disableMRouter(); // Disable the multirout API } /** * Main daemon loop. */ -void igmpProxyRun(void) { +void igmpProxyRun( void ) +{ // Get the config. struct Config *config = getCommonConfig(); // Set some needed values. - register int recvlen; - int MaxFD, Rt, secs; - fd_set ReadFDS; - socklen_t dummy = 0; - struct timespec curtime, lasttime, difftime, tv; + register int recvlen; + int MaxFD, Rt, secs; + fd_set ReadFDS; + socklen_t dummy = 0; + struct timespec curtime, lasttime, difftime, tv; // The timeout is a pointer in order to set it to NULL if nessecary. - struct timespec *timeout = &tv; + struct timespec *timeout = &tv; // Initialize timer vars difftime.tv_nsec = 0; - clock_gettime(CLOCK_MONOTONIC, &curtime); + clock_gettime( CLOCK_MONOTONIC, &curtime ); lasttime = curtime; // First thing we send a membership query in downstream VIF's... sendGeneralMembershipQuery(); // Loop until the end... - for (;;) { + for ( ;; ) { // Process signaling... - if (sighandled) { - if (sighandled & GOT_SIGINT) { + if ( sighandled ) { + if ( sighandled & GOT_SIGINT ) { sighandled &= ~GOT_SIGINT; - my_log(LOG_NOTICE, 0, "Got a interrupt signal. Exiting."); + my_log( LOG_NOTICE, 0, "Got a interrupt signal. Exiting." ); break; } } /* aimwang: call rebuildIfVc */ - if (config->rescanVif) + if ( config->rescanVif ) rebuildIfVc(); // Prepare timeout... secs = timer_nextTimer(); - if(secs == -1) { + if ( secs == -1 ) { timeout = NULL; - } else { + } + else { timeout->tv_nsec = 0; - timeout->tv_sec = (secs > 3) ? 3 : secs; // aimwang: set max timeout + timeout->tv_sec = ( secs > 3 ) ? 3 : secs; // aimwang: set max timeout } // Prepare for select. @@ -296,26 +297,26 @@ void igmpProxyRun(void) { FD_SET( MRouterFD, &ReadFDS ); // wait for input - Rt = pselect( MaxFD +1, &ReadFDS, NULL, NULL, timeout, NULL ); + Rt = pselect( MaxFD + 1, &ReadFDS, NULL, NULL, timeout, NULL ); // log and ignore failures - if( Rt < 0 ) { + if ( Rt < 0 ) { my_log( LOG_WARNING, errno, "select() failure" ); continue; } - else if( Rt > 0 ) { + else if ( Rt > 0 ) { // Read IGMP request, and handle it... - if( FD_ISSET( MRouterFD, &ReadFDS ) ) { + if ( FD_ISSET( MRouterFD, &ReadFDS ) ) { - recvlen = recvfrom(MRouterFD, recv_buf, RECV_BUF_SIZE, - 0, NULL, &dummy); - if (recvlen < 0) { - if (errno != EINTR) my_log(LOG_ERR, errno, "recvfrom"); + recvlen = recvfrom( MRouterFD, recv_buf, RECV_BUF_SIZE, 0, NULL, &dummy ); + if ( recvlen < 0 ) { + if ( errno != EINTR ) + my_log( LOG_ERR, errno, "recvfrom" ); continue; } - acceptIgmp(recvlen); + acceptIgmp( recvlen ); } } @@ -326,55 +327,55 @@ void igmpProxyRun(void) { * activity to account for and we don't need to * call gettimeofday. */ - if (Rt == 0) { - curtime.tv_sec = lasttime.tv_sec + secs; + if ( Rt == 0 ) { + curtime.tv_sec = lasttime.tv_sec + secs; curtime.tv_nsec = lasttime.tv_nsec; - Rt = -1; /* don't do this next time through the loop */ - } else { - clock_gettime(CLOCK_MONOTONIC, &curtime); + Rt = -1; /* don't do this next time through the loop */ + } + else { + clock_gettime( CLOCK_MONOTONIC, &curtime ); } difftime.tv_sec = curtime.tv_sec - lasttime.tv_sec; difftime.tv_nsec += curtime.tv_nsec - lasttime.tv_nsec; - while (difftime.tv_nsec > 1000000000) { + while ( difftime.tv_nsec > 1000000000 ) { difftime.tv_sec++; difftime.tv_nsec -= 1000000000; } - if (difftime.tv_nsec < 0) { + if ( difftime.tv_nsec < 0 ) { difftime.tv_sec--; difftime.tv_nsec += 1000000000; } lasttime = curtime; - if (secs == 0 || difftime.tv_sec > 0) - age_callout_queue(difftime.tv_sec); + if ( secs == 0 || difftime.tv_sec > 0 ) + age_callout_queue( difftime.tv_sec ); secs = -1; - } while (difftime.tv_sec > 0); - + } while ( difftime.tv_sec > 0 ); } - } /* * Signal handler. Take note of the fact that the signal arrived * so that the main loop can take care of it. */ -static void signalHandler(int sig) { - switch (sig) { - case SIGINT: - case SIGTERM: - sighandled |= GOT_SIGINT; - break; - /* XXX: Not in use. - case SIGHUP: - sighandled |= GOT_SIGHUP; +static void signalHandler( int sig ) +{ + switch ( sig ) { + case SIGINT: + case SIGTERM: + sighandled |= GOT_SIGINT; break; + /* XXX: Not in use. + case SIGHUP: + sighandled |= GOT_SIGHUP; + break; - case SIGUSR1: - sighandled |= GOT_SIGUSR1; - break; + case SIGUSR1: + sighandled |= GOT_SIGUSR1; + break; - case SIGUSR2: - sighandled |= GOT_SIGUSR2; - break; - */ + case SIGUSR2: + sighandled |= GOT_SIGUSR2; + break; + */ } } diff --git a/src/igmpproxy.h b/src/igmpproxy.h index 6980e35a..0b745578 100644 --- a/src/igmpproxy.h +++ b/src/igmpproxy.h @@ -36,51 +36,50 @@ */ #include +#include +#include #include +#include #include #include -#include -#include -#include #include -#include -#include +#include #include +#include -#include -#include #include #include #include +#include +#include +#include #include #include -#include -#include "os.h" #include "config.h" +#include "os.h" /* * Limit on length of route data */ -#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_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 -#define MAX_UPS_VIFS 8 +#define MAX_MC_VIFS 32 // !!! check this const in the specific includes +#define MAX_UPS_VIFS 8 // Useful macros.. -#define VCMC( Vc ) (sizeof( Vc ) / sizeof( (Vc)[ 0 ] )) -#define VCEP( Vc ) (&(Vc)[ VCMC( Vc ) ]) +#define VCMC( Vc ) ( sizeof( Vc ) / sizeof( ( Vc )[0] ) ) +#define VCEP( Vc ) ( &( Vc )[VCMC( Vc )] ) // Bit manipulation macros... -#define BIT_ZERO(X) ((X) = 0) -#define BIT_SET(X,n) ((X) |= 1 << (n)) -#define BIT_CLR(X,n) ((X) &= ~(1 << (n))) -#define BIT_TST(X,n) ((X) & 1 << (n)) - +#define BIT_ZERO( X ) ( ( X ) = 0 ) +#define BIT_SET( X, n ) ( ( X ) |= 1 << ( n ) ) +#define BIT_CLR( X, n ) ( ( X ) &= ~( 1 << ( n ) ) ) +#define BIT_TST( X, n ) ( (X) &1 << ( n ) ) //################################################################################# // Globals @@ -90,15 +89,13 @@ * External declarations for global variables and functions. */ #define RECV_BUF_SIZE 8192 -extern char *recv_buf; -extern char *send_buf; - -extern char s1[]; -extern char s2[]; -extern char s3[]; -extern char s4[]; - +extern char *recv_buf; +extern char *send_buf; +extern char s1[]; +extern char s2[]; +extern char s3[]; +extern char s4[]; //################################################################################# // Lib function prototypes. @@ -106,77 +103,97 @@ extern char s4[]; /* syslog.c */ -extern bool Log2Stderr; // Log to stderr instead of to syslog -extern int LogLevel; // Log threshold, LOG_WARNING .... LOG_DEBUG +#define LOG_TRACE ( LOG_DEBUG + 1 ) +#define LOG_INIT ( LOG_DEBUG + 2 ) + +extern bool Log2Stderr; // Log to stderr instead of to syslog +extern int LogLevel; // Log threshold, LOG_WARNING .... LOG_DEBUG, LOG_TRACE, LOG_INIT + +// uncomment for more details while logging +//#define DEVEL_LOGGING + +#ifdef DEVEL_LOGGING +#define _my_log( Severity, Errno, Fmt, args... ) \ + __my_log( ( Severity ), ( Errno ), __FUNCTION__, __LINE__, ( Fmt ), ##args ) +void __my_log( int Severity, int Errno, char *func, int line, char *FmtSt, ... ); +#else +void _my_log( int Severity, int Errno, char *FmtSt, ... ); +#endif + +// short circuit log level evaluation to avoid unnecessary function calls for argruments +#define my_log( Severity, Errno, Fmt, args... ) \ + do { \ + if ( LogLevel < ( Severity ) ) { \ + break; \ + } \ + _my_log( ( Severity ), ( Errno ), ( Fmt ), ##args ); \ + } while ( 0 ) -void my_log( int Serverity, int Errno, const char *FmtSt, ... ); /* ifvc.c */ -#define MAX_IF 40 // max. number of interfaces recognized +#define MAX_IF 40 // max. number of interfaces recognized // Interface states -#define IF_STATE_DISABLED 0 // Interface should be ignored. -#define IF_STATE_UPSTREAM 1 // Interface is the upstream interface -#define IF_STATE_DOWNSTREAM 2 // Interface is a downstream interface -#define IF_STATE_LOST 3 // aimwang: Temp from downstream to hidden -#define IF_STATE_HIDDEN 4 // aimwang: Interface is hidden +#define IF_STATE_DISABLED 0 // Interface should be ignored. +#define IF_STATE_UPSTREAM 1 // Interface is the upstream interface +#define IF_STATE_DOWNSTREAM 2 // Interface is a downstream interface +#define IF_STATE_LOST 3 // aimwang: Temp from downstream to hidden +#define IF_STATE_HIDDEN 4 // aimwang: Interface is hidden // Multicast default values... -#define DEFAULT_ROBUSTNESS 2 -#define DEFAULT_THRESHOLD 1 -#define DEFAULT_RATELIMIT 0 +#define DEFAULT_ROBUSTNESS 2 +#define DEFAULT_THRESHOLD 1 +#define DEFAULT_RATELIMIT 0 // Define timer constants (in seconds...) -#define INTERVAL_QUERY 125 -#define INTERVAL_QUERY_RESPONSE 10 +#define INTERVAL_QUERY 125 +#define INTERVAL_QUERY_RESPONSE 10 //#define INTERVAL_QUERY_RESPONSE 10 -#define ROUTESTATE_NOTJOINED 0 // The group corresponding to route is not joined -#define ROUTESTATE_JOINED 1 // The group corresponding to route is joined -#define ROUTESTATE_CHECK_LAST_MEMBER 2 // The router is checking for hosts - - +#define ROUTESTATE_NOTJOINED 0 // The group corresponding to route is not joined +#define ROUTESTATE_JOINED 1 // The group corresponding to route is joined +#define ROUTESTATE_CHECK_LAST_MEMBER 2 // The router is checking for hosts // Linked list of networks... struct SubnetList { - uint32_t subnet_addr; - uint32_t subnet_mask; - struct SubnetList *next; + uint32_t subnet_addr; + uint32_t subnet_mask; + struct SubnetList *next; }; struct IfDesc { - char Name[IF_NAMESIZE]; - struct in_addr InAdr; /* == 0 for non IP interfaces */ - short Flags; - short state; - struct SubnetList* allowednets; - struct SubnetList* allowedgroups; - unsigned int robustness; - unsigned char threshold; /* ttl limit */ - unsigned int ratelimit; - unsigned int index; + char Name[IF_NAMESIZE]; + struct in_addr InAdr; /* == 0 for non IP interfaces */ + short Flags; + short state; + struct SubnetList *allowednets; + struct SubnetList *allowedgroups; + unsigned int robustness; + unsigned char threshold; /* ttl limit */ + unsigned int ratelimit; + unsigned int index; }; // Keeps common configuration settings struct Config { - unsigned int robustnessValue; - unsigned int queryInterval; - unsigned int queryResponseInterval; + unsigned int robustnessValue; + unsigned int queryInterval; + unsigned int queryResponseInterval; // Used on startup.. - unsigned int startupQueryInterval; - unsigned int startupQueryCount; + unsigned int startupQueryInterval; + unsigned int startupQueryCount; // Last member probe... - unsigned int lastMemberQueryInterval; - unsigned int lastMemberQueryCount; + unsigned int lastMemberQueryInterval; + unsigned int lastMemberQueryCount; // Set if upstream leave messages should be sent instantly.. - unsigned short fastUpstreamLeave; + unsigned short fastUpstreamLeave; //~ aimwang added // Set if nneed to detect new interface. - unsigned short rescanVif; + unsigned short rescanVif; // Set if not detect new interface for down stream. - unsigned short defaultInterfaceState; // 0: disable, 2: downstream - //~ aimwang added done + unsigned short defaultInterfaceState; // 0: disable, 2: downstream + //~ aimwang added done }; // Holds the indeces of the upstream IF... @@ -184,63 +201,63 @@ extern int upStreamIfIdx[MAX_UPS_VIFS]; /* ifvc.c */ -void rebuildIfVc( void ); -void buildIfVc( void ); +void rebuildIfVc( void ); +void buildIfVc( void ); struct IfDesc *getIfByName( const char *IfName ); struct IfDesc *getIfByIx( unsigned Ix ); struct IfDesc *getIfByAddress( uint32_t Ix ); struct IfDesc *getIfByVifIndex( unsigned vifindex ); -int isAdressValidForIf(struct IfDesc* intrface, uint32_t ipaddr); +int isAdressValidForIf( struct IfDesc *intrface, uint32_t ipaddr ); /* mroute-api.c */ struct MRouteDesc { - struct in_addr OriginAdr, McAdr; - short InVif; - uint8_t TtlVc[ MAX_MC_VIFS ]; + struct in_addr OriginAdr, McAdr; + short InVif; + uint8_t TtlVc[MAX_MC_VIFS]; }; // IGMP socket as interface for the mrouted API // - receives the IGMP messages extern int MRouterFD; -int enableMRouter( void ); +int enableMRouter( void ); void disableMRouter( void ); void addVIF( struct IfDesc *Dp ); void delVIF( struct IfDesc *Dp ); -int addMRoute( struct MRouteDesc * Dp ); -int delMRoute( struct MRouteDesc * Dp ); +int addMRoute( struct MRouteDesc *Dp ); +int delMRoute( struct MRouteDesc *Dp ); int getVifIx( struct IfDesc *IfDp ); /* config.c */ -int loadConfig(char *configFile); -void configureVifs(void); -struct Config *getCommonConfig(void); +int loadConfig( char *configFile ); +void configureVifs( void ); +struct Config *getCommonConfig( void ); /* igmp.c */ extern uint32_t allhosts_group; extern uint32_t allrouters_group; extern uint32_t alligmp3_group; -void initIgmp(void); -void acceptIgmp(int); -void sendIgmp (uint32_t, uint32_t, int, int, uint32_t,int); +void initIgmp( void ); +void acceptIgmp( int ); +void sendIgmp( uint32_t, uint32_t, int, int, uint32_t, int ); /* lib.c */ -char *fmtInAdr( char *St, struct in_addr InAdr ); -char *inetFmt(uint32_t addr, char *s); -char *inetFmts(uint32_t addr, uint32_t mask, char *s); -uint16_t inetChksum(uint16_t *addr, int len); +char *fmtInAdr( char *St, struct in_addr InAdr ); +char *inetFmt( uint32_t addr, char *s ); +char *inetFmts( uint32_t addr, uint32_t mask, char *s ); +uint16_t inetChksum( uint16_t *addr, int len ); /* kern.c */ -void k_set_rcvbuf(int bufsize, int minsize); -void k_hdr_include(int hdrincl); -void k_set_ttl(int t); -void k_set_loop(int l); -void k_set_if(uint32_t ifa); +void k_set_rcvbuf( int bufsize, int minsize ); +void k_hdr_include( int hdrincl ); +void k_set_ttl( int t ); +void k_set_loop( int l ); +void k_set_if( uint32_t ifa ); /* void k_join(uint32_t grp, uint32_t ifa); void k_leave(uint32_t grp, uint32_t ifa); @@ -255,42 +272,41 @@ int openUdpSocket( uint32_t PeerInAdr, uint16_t PeerPort ); int joinMcGroup( int UdpSock, struct IfDesc *IfDp, uint32_t mcastaddr ); int leaveMcGroup( int UdpSock, struct IfDesc *IfDp, uint32_t mcastaddr ); - /* rttable.c */ -void initRouteTable(void); -void clearAllRoutes(void); -int insertRoute(uint32_t group, int ifx); -int activateRoute(uint32_t group, uint32_t originAddr, int upstrVif); -void ageActiveRoutes(void); -void setRouteLastMemberMode(uint32_t group); -int lastMemberGroupAge(uint32_t group); -int interfaceInRoute(int32_t group, int Ix); -int getMcGroupSock(void); +void initRouteTable( void ); +void clearAllRoutes( void ); +int insertRoute( uint32_t group, int ifx ); +int activateRoute( uint32_t group, uint32_t originAddr, int upstrVif ); +void ageActiveRoutes( void ); +void setRouteLastMemberMode( uint32_t group ); +int lastMemberGroupAge( uint32_t group ); +int interfaceInRoute( int32_t group, int Ix ); +int getMcGroupSock( void ); /* request.c */ -void acceptGroupReport(uint32_t src, uint32_t group); -void acceptLeaveMessage(uint32_t src, uint32_t group); -void sendGeneralMembershipQuery(void); +void acceptGroupReport( uint32_t src, uint32_t group ); +void acceptLeaveMessage( uint32_t src, uint32_t group ); +void sendGeneralMembershipQuery( void ); -/* callout.c +/* callout.c */ -typedef void (*timer_f)(void *); +typedef void ( *timer_f )( void * ); -void callout_init(void); -void free_all_callouts(void); -void age_callout_queue(int); -int timer_nextTimer(void); -int timer_setTimer(int, timer_f, void *); -int timer_clearTimer(int); -int timer_leftTimer(int); +void callout_init( void ); +void free_all_callouts( void ); +void age_callout_queue( int ); +int timer_nextTimer( void ); +int timer_setTimer( int, timer_f, void * ); +int timer_clearTimer( int ); +int timer_leftTimer( int ); /* confread.c */ -#define MAX_TOKEN_LENGTH 30 +#define MAX_TOKEN_LENGTH 30 -int openConfigFile(char *filename); -void closeConfigFile(void); -char* nextConfigToken(void); -char* getCurrentConfigToken(void); +int openConfigFile( char *filename ); +void closeConfigFile( void ); +char *nextConfigToken( void ); +char *getCurrentConfigToken( void ); diff --git a/src/igmpv3.h b/src/igmpv3.h index f8658237..11115521 100644 --- a/src/igmpv3.h +++ b/src/igmpv3.h @@ -22,24 +22,24 @@ */ struct igmpv3_grec { - u_int8_t grec_type; - u_int8_t grec_auxwords; - u_int16_t grec_nsrcs; + u_int8_t grec_type; + u_int8_t grec_auxwords; + u_int16_t grec_nsrcs; struct in_addr grec_mca; struct in_addr grec_src[0]; }; struct igmpv3_report { - u_int8_t igmp_type; - u_int8_t igmp_resv1; - u_int16_t igmp_cksum; - u_int16_t igmp_resv2; - u_int16_t igmp_ngrec; + u_int8_t igmp_type; + u_int8_t igmp_resv1; + u_int16_t igmp_cksum; + u_int16_t igmp_resv2; + u_int16_t igmp_ngrec; struct igmpv3_grec igmp_grec[0]; }; -#define IGMPV3_MODE_IS_INCLUDE 1 -#define IGMPV3_MODE_IS_EXCLUDE 2 +#define IGMPV3_MODE_IS_INCLUDE 1 +#define IGMPV3_MODE_IS_EXCLUDE 2 #define IGMPV3_CHANGE_TO_INCLUDE 3 #define IGMPV3_CHANGE_TO_EXCLUDE 4 #define IGMPV3_ALLOW_NEW_SOURCES 5 diff --git a/src/kern.c b/src/kern.c index 490ffd6d..549e7271 100644 --- a/src/kern.c +++ b/src/kern.c @@ -32,14 +32,14 @@ ** */ - #include "igmpproxy.h" int curttl = 0; -void k_set_rcvbuf(int bufsize, int minsize) { +void k_set_rcvbuf( int bufsize, int minsize ) +{ int delta = bufsize / 2; - int iter = 0; + int iter = 0; /* * Set the socket buffer. If we can't set it as large as we @@ -47,68 +47,64 @@ void k_set_rcvbuf(int bufsize, int minsize) { * value. The highest acceptable value being smaller than * minsize is a fatal error. */ - if (setsockopt(MRouterFD, SOL_SOCKET, SO_RCVBUF, - (char *)&bufsize, sizeof(bufsize)) < 0) { + if ( setsockopt( MRouterFD, SOL_SOCKET, SO_RCVBUF, (char *) &bufsize, sizeof( bufsize ) ) < 0 ) { bufsize -= delta; - while (1) { + while ( 1 ) { iter++; - if (delta > 1) + if ( delta > 1 ) delta /= 2; - if (setsockopt(MRouterFD, SOL_SOCKET, SO_RCVBUF, - (char *)&bufsize, sizeof(bufsize)) < 0) { + if ( setsockopt( MRouterFD, SOL_SOCKET, SO_RCVBUF, (char *) &bufsize, sizeof( bufsize ) ) < 0 ) { bufsize -= delta; - } else { - if (delta < 1024) + } + else { + if ( delta < 1024 ) break; bufsize += delta; } } - if (bufsize < minsize) { - my_log(LOG_ERR, 0, "OS-allowed buffer size %u < app min %u", - bufsize, minsize); + if ( bufsize < minsize ) { + my_log( LOG_ERR, 0, "OS-allowed buffer size %u < app min %u", bufsize, minsize ); /*NOTREACHED*/ } } - my_log(LOG_DEBUG, 0, "Got %d byte buffer size in %d iterations", bufsize, iter); + my_log( LOG_DEBUG, 0, "Got %d byte buffer size in %d iterations", bufsize, iter ); } -void k_hdr_include(int hdrincl) { - if (setsockopt(MRouterFD, IPPROTO_IP, IP_HDRINCL, - (char *)&hdrincl, sizeof(hdrincl)) < 0) - my_log(LOG_WARNING, errno, "setsockopt IP_HDRINCL %u", hdrincl); +void k_hdr_include( int hdrincl ) +{ + if ( setsockopt( MRouterFD, IPPROTO_IP, IP_HDRINCL, (char *) &hdrincl, sizeof( hdrincl ) ) < 0 ) + my_log( LOG_WARNING, errno, "setsockopt IP_HDRINCL %u", hdrincl ); } - -void k_set_ttl(int t) { +void k_set_ttl( int t ) +{ #ifndef RAW_OUTPUT_IS_RAW unsigned char ttl; ttl = t; - if (setsockopt(MRouterFD, IPPROTO_IP, IP_MULTICAST_TTL, - (char *)&ttl, sizeof(ttl)) < 0) - my_log(LOG_WARNING, errno, "setsockopt IP_MULTICAST_TTL %u", ttl); + if ( setsockopt( MRouterFD, IPPROTO_IP, IP_MULTICAST_TTL, (char *) &ttl, sizeof( ttl ) ) < 0 ) + my_log( LOG_WARNING, errno, "setsockopt IP_MULTICAST_TTL %u", ttl ); #endif curttl = t; } -void k_set_loop(int l) { +void k_set_loop( int l ) +{ unsigned char loop; loop = l; - if (setsockopt(MRouterFD, IPPROTO_IP, IP_MULTICAST_LOOP, - (char *)&loop, sizeof(loop)) < 0) - my_log(LOG_WARNING, errno, "setsockopt IP_MULTICAST_LOOP %u", loop); + if ( setsockopt( MRouterFD, IPPROTO_IP, IP_MULTICAST_LOOP, (char *) &loop, sizeof( loop ) ) < 0 ) + my_log( LOG_WARNING, errno, "setsockopt IP_MULTICAST_LOOP %u", loop ); } -void k_set_if(uint32_t ifa) { +void k_set_if( uint32_t ifa ) +{ struct in_addr adr; adr.s_addr = ifa; - if (setsockopt(MRouterFD, IPPROTO_IP, IP_MULTICAST_IF, - (char *)&adr, sizeof(adr)) < 0) - my_log(LOG_WARNING, errno, "setsockopt IP_MULTICAST_IF %s", - inetFmt(ifa, s1)); + if ( setsockopt( MRouterFD, IPPROTO_IP, IP_MULTICAST_IF, (char *) &adr, sizeof( adr ) ) < 0 ) + my_log( LOG_WARNING, errno, "setsockopt IP_MULTICAST_IF %s", inetFmt( ifa, s1 ) ); } /* diff --git a/src/lib.c b/src/lib.c index fd041444..c70eda2b 100644 --- a/src/lib.c +++ b/src/lib.c @@ -37,9 +37,9 @@ /* * Exported variables. */ -char s1[19]; /* buffers to hold the string representations */ -char s2[19]; /* of IP addresses, to be passed to inet_fmt() */ -char s3[19]; /* or inet_fmts(). */ +char s1[19]; /* buffers to hold the string representations */ +char s2[19]; /* of IP addresses, to be passed to inet_fmt() */ +char s3[19]; /* or inet_fmts(). */ char s4[19]; /* @@ -48,12 +48,10 @@ char s4[19]; ** returns: - pointer to 'St' ** */ -char *fmtInAdr( char *St, struct in_addr InAdr ) { - sprintf( St, "%u.%u.%u.%u", - ((uint8_t *)&InAdr.s_addr)[ 0 ], - ((uint8_t *)&InAdr.s_addr)[ 1 ], - ((uint8_t *)&InAdr.s_addr)[ 2 ], - ((uint8_t *)&InAdr.s_addr)[ 3 ] ); +char *fmtInAdr( char *St, struct in_addr InAdr ) +{ + sprintf( St, "%u.%u.%u.%u", ( (uint8_t *) &InAdr.s_addr )[0], ( (uint8_t *) &InAdr.s_addr )[1], + ( (uint8_t *) &InAdr.s_addr )[2], ( (uint8_t *) &InAdr.s_addr )[3] ); return St; } @@ -61,37 +59,42 @@ char *fmtInAdr( char *St, struct in_addr InAdr ) { /* * Convert an IP address in u_long (network) format into a printable string. */ -char *inetFmt(uint32_t addr, char *s) { +char *inetFmt( uint32_t addr, char *s ) +{ register unsigned char *a; - a = (unsigned char *)&addr; - sprintf(s, "%u.%u.%u.%u", a[0], a[1], a[2], a[3]); - return(s); + a = (unsigned char *) &addr; + sprintf( s, "%u.%u.%u.%u", a[0], a[1], a[2], a[3] ); + return ( s ); } /* * Convert an IP subnet number in u_long (network) format into a printable * string including the netmask as a number of bits. */ -char *inetFmts(uint32_t addr, uint32_t mask, char *s) { +char *inetFmts( uint32_t addr, uint32_t mask, char *s ) +{ register unsigned char *a, *m; - int bits; + int bits; - if ((addr == 0) && (mask == 0)) { - sprintf(s, "default"); - return(s); + if ( ( addr == 0 ) && ( mask == 0 ) ) { + sprintf( s, "default" ); + return ( s ); } - a = (unsigned char *)&addr; - m = (unsigned char *)&mask; - bits = 33 - ffs(ntohl(mask)); + a = (unsigned char *) &addr; + m = (unsigned char *) &mask; + bits = 33 - ffs( ntohl( mask ) ); - if (m[3] != 0) sprintf(s, "%u.%u.%u.%u/%d", a[0], a[1], a[2], a[3], - bits); - else if (m[2] != 0) sprintf(s, "%u.%u.%u/%d", a[0], a[1], a[2], bits); - else if (m[1] != 0) sprintf(s, "%u.%u/%d", a[0], a[1], bits); - else sprintf(s, "%u/%d", a[0], bits); + if ( m[3] != 0 ) + sprintf( s, "%u.%u.%u.%u/%d", a[0], a[1], a[2], a[3], bits ); + else if ( m[2] != 0 ) + sprintf( s, "%u.%u.%u/%d", a[0], a[1], a[2], bits ); + else if ( m[1] != 0 ) + sprintf( s, "%u.%u/%d", a[0], a[1], bits ); + else + sprintf( s, "%u/%d", a[0], bits ); - return(s); + return ( s ); } /* @@ -112,11 +115,12 @@ char *inetFmts(uint32_t addr, uint32_t mask, char *s) { * Checksum routine for Internet Protocol family headers (C Version) * */ -uint16_t inetChksum(uint16_t *addr, int len) { - register int nleft = len; - register uint16_t *w = addr; - uint16_t answer = 0; - register int32_t sum = 0; +uint16_t inetChksum( uint16_t *addr, int len ) +{ + register int nleft = len; + register uint16_t *w = addr; + uint16_t answer = 0; + register int32_t sum = 0; /* * Our algorithm is simple, using a 32 bit accumulator (sum), @@ -124,22 +128,22 @@ uint16_t inetChksum(uint16_t *addr, int len) { * back all the carry bits from the top 16 bits into the lower * 16 bits. */ - while (nleft > 1) { + while ( nleft > 1 ) { sum += *w++; nleft -= 2; } /* mop up an odd byte, if necessary */ - if (nleft == 1) { - *(uint8_t *) (&answer) = *(uint8_t *)w ; + if ( nleft == 1 ) { + *(uint8_t *) ( &answer ) = *(uint8_t *) w; sum += answer; } /* * add back carry outs from top 16 bits to low 16 bits */ - sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */ - sum += (sum >> 16); /* add carry */ - answer = ~sum; /* truncate to 16 bits */ - return(answer); + sum = ( sum >> 16 ) + ( sum & 0xffff ); /* add hi 16 to low 16 */ + sum += ( sum >> 16 ); /* add carry */ + answer = ~sum; /* truncate to 16 bits */ + return ( answer ); } diff --git a/src/mcgroup.c b/src/mcgroup.c index 1244c47d..1a6810c9 100644 --- a/src/mcgroup.c +++ b/src/mcgroup.c @@ -38,27 +38,24 @@ #include "igmpproxy.h" - /** * Common function for joining or leaving a MCast group. */ -static int joinleave( int Cmd, int UdpSock, struct IfDesc *IfDp, uint32_t mcastaddr ) { +static int joinleave( int Cmd, int UdpSock, struct IfDesc *IfDp, uint32_t mcastaddr ) +{ struct ip_mreq CtlReq; - const char *CmdSt = Cmd == 'j' ? "join" : "leave"; + const char * CmdSt = Cmd == 'j' ? "join" : "leave"; - memset(&CtlReq, 0, sizeof(CtlReq)); + memset( &CtlReq, 0, sizeof( CtlReq ) ); CtlReq.imr_multiaddr.s_addr = mcastaddr; CtlReq.imr_interface.s_addr = IfDp->InAdr.s_addr; { - my_log( LOG_NOTICE, 0, "%sMcGroup: %s on %s", CmdSt, - inetFmt( mcastaddr, s1 ), IfDp ? IfDp->Name : "" ); + my_log( LOG_NOTICE, 0, "%sMcGroup: %s on %s", CmdSt, inetFmt( mcastaddr, s1 ), IfDp ? IfDp->Name : "" ); } - if( setsockopt( UdpSock, IPPROTO_IP, - Cmd == 'j' ? IP_ADD_MEMBERSHIP : IP_DROP_MEMBERSHIP, - (void *)&CtlReq, sizeof( CtlReq ) ) ) - { + if ( setsockopt( UdpSock, IPPROTO_IP, Cmd == 'j' ? IP_ADD_MEMBERSHIP : IP_DROP_MEMBERSHIP, (void *) &CtlReq, + sizeof( CtlReq ) ) ) { my_log( LOG_WARNING, errno, "MRT_%s_MEMBERSHIP failed", Cmd == 'j' ? "ADD" : "DROP" ); return 1; } @@ -71,17 +68,21 @@ static int joinleave( int Cmd, int UdpSock, struct IfDesc *IfDp, uint32_t mcasta * The join is bound to the UDP socket 'UdpSock', so if this socket is * closed the membership is dropped. * -* @return 0 if the function succeeds, 1 if parameters are wrong or the join fails +* @return 0 if the function succeeds, 1 if parameters are wrong or the join +* fails */ -int joinMcGroup( int UdpSock, struct IfDesc *IfDp, uint32_t mcastaddr ) { +int joinMcGroup( int UdpSock, struct IfDesc *IfDp, uint32_t mcastaddr ) +{ return joinleave( 'j', UdpSock, IfDp, mcastaddr ); } /** * Leaves the MC group with the address 'McAdr' on the interface 'IfName'. * -* @return 0 if the function succeeds, 1 if parameters are wrong or the join fails +* @return 0 if the function succeeds, 1 if parameters are wrong or the join +* fails */ -int leaveMcGroup( int UdpSock, struct IfDesc *IfDp, uint32_t mcastaddr ) { +int leaveMcGroup( int UdpSock, struct IfDesc *IfDp, uint32_t mcastaddr ) +{ return joinleave( 'l', UdpSock, IfDp, mcastaddr ); } diff --git a/src/mroute-api.c b/src/mroute-api.c index d8912e61..54ec0b50 100644 --- a/src/mroute-api.c +++ b/src/mroute-api.c @@ -37,25 +37,23 @@ * This module contains the interface routines to the Linux mrouted API */ - #include "igmpproxy.h" // MAX_MC_VIFS from mclab.h must have same value as MAXVIFS from mroute.h #if MAX_MC_VIFS != MAXVIFS -# error "constants don't match, correct mclab.h" +#error "constants don't match, correct mclab.h" #endif // need an IGMP socket as interface for the mrouted API // - receives the IGMP messages -int MRouterFD; /* socket for all network I/O */ -char *recv_buf; /* input packet buffer */ -char *send_buf; /* output packet buffer */ - +int MRouterFD; /* socket for all network I/O */ +char *recv_buf; /* input packet buffer */ +char *send_buf; /* output packet buffer */ // my internal virtual interfaces descriptor vector static struct VifDesc { struct IfDesc *IfDp; -} VifDescVc[ MAXVIFS ]; +} VifDescVc[MAXVIFS]; /* ** Initialises the mrouted API and locks it by this exclusively. @@ -63,15 +61,14 @@ static struct VifDesc { ** returns: - 0 if the functions succeeds ** - the errno value for non-fatal failure condition */ -int enableMRouter(void) +int enableMRouter( void ) { int Va = 1; - if ( (MRouterFD = socket(AF_INET, SOCK_RAW, IPPROTO_IGMP)) < 0 ) + if ( ( MRouterFD = socket( AF_INET, SOCK_RAW, IPPROTO_IGMP ) ) < 0 ) my_log( LOG_ERR, errno, "IGMP socket open" ); - if ( setsockopt( MRouterFD, IPPROTO_IP, MRT_INIT, - (void *)&Va, sizeof( Va ) ) ) + if ( setsockopt( MRouterFD, IPPROTO_IP, MRT_INIT, (void *) &Va, sizeof( Va ) ) ) return errno; return 0; @@ -81,11 +78,9 @@ int enableMRouter(void) ** Diable the mrouted API and relases by this the lock. ** */ -void disableMRouter(void) +void disableMRouter( void ) { - if ( setsockopt( MRouterFD, IPPROTO_IP, MRT_DONE, NULL, 0 ) - || close( MRouterFD ) - ) { + if ( setsockopt( MRouterFD, IPPROTO_IP, MRT_DONE, NULL, 0 ) || close( MRouterFD ) ) { MRouterFD = 0; my_log( LOG_ERR, errno, "MRT_DONE/close" ); } @@ -100,16 +95,15 @@ void delVIF( struct IfDesc *IfDp ) { struct vifctl VifCtl; - if (-1 == IfDp->index) + if ( -1 == IfDp->index ) return; VifCtl.vifc_vifi = IfDp->index; - my_log( LOG_NOTICE, 0, "removing VIF, Ix %d Fl 0x%x IP 0x%08x %s, Threshold: %d, Ratelimit: %d", - IfDp->index, IfDp->Flags, IfDp->InAdr.s_addr, IfDp->Name, IfDp->threshold, IfDp->ratelimit); + my_log( LOG_NOTICE, 0, "removing VIF, Ix %d Fl 0x%x IP 0x%08x %s, Threshold: %d, Ratelimit: %d", IfDp->index, + IfDp->Flags, IfDp->InAdr.s_addr, IfDp->Name, IfDp->threshold, IfDp->ratelimit ); - if ( setsockopt( MRouterFD, IPPROTO_IP, MRT_DEL_VIF, - (char *)&VifCtl, sizeof( VifCtl ) ) ) + if ( setsockopt( MRouterFD, IPPROTO_IP, MRT_DEL_VIF, (char *) &VifCtl, sizeof( VifCtl ) ) ) my_log( LOG_WARNING, errno, "MRT_DEL_VIF" ); } @@ -119,13 +113,13 @@ void delVIF( struct IfDesc *IfDp ) */ void addVIF( struct IfDesc *IfDp ) { - struct vifctl VifCtl; + struct vifctl VifCtl; struct VifDesc *VifDp; /* search free (aimwang: or exist) VifDesc */ for ( VifDp = VifDescVc; VifDp < VCEP( VifDescVc ); VifDp++ ) { - if ( ! VifDp->IfDp || VifDp->IfDp == IfDp) + if ( !VifDp->IfDp || VifDp->IfDp == IfDp ) break; } @@ -136,10 +130,10 @@ void addVIF( struct IfDesc *IfDp ) VifDp->IfDp = IfDp; - VifCtl.vifc_vifi = VifDp - VifDescVc; - VifCtl.vifc_flags = 0; /* no tunnel, no source routing, register ? */ - VifCtl.vifc_threshold = VifDp->IfDp->threshold; // Packet TTL must be at least 1 to pass them - VifCtl.vifc_rate_limit = VifDp->IfDp->ratelimit; // Ratelimit + VifCtl.vifc_vifi = VifDp - VifDescVc; + VifCtl.vifc_flags = 0; /* no tunnel, no source routing, register ? */ + VifCtl.vifc_threshold = VifDp->IfDp->threshold; // Packet TTL must be at least 1 to pass them + VifCtl.vifc_rate_limit = VifDp->IfDp->ratelimit; // Ratelimit VifCtl.vifc_lcl_addr.s_addr = VifDp->IfDp->InAdr.s_addr; VifCtl.vifc_rmt_addr.s_addr = INADDR_ANY; @@ -147,21 +141,18 @@ void addVIF( struct IfDesc *IfDp ) // Set the index... VifDp->IfDp->index = VifCtl.vifc_vifi; - my_log( LOG_NOTICE, 0, "adding VIF, Ix %d Fl 0x%x IP 0x%08x %s, Threshold: %d, Ratelimit: %d", - VifCtl.vifc_vifi, VifCtl.vifc_flags, VifCtl.vifc_lcl_addr.s_addr, VifDp->IfDp->Name, - VifCtl.vifc_threshold, VifCtl.vifc_rate_limit); + my_log( LOG_NOTICE, 0, "adding VIF, Ix %d Fl 0x%x IP 0x%08x %s, Threshold: %d, Ratelimit: %d", VifCtl.vifc_vifi, + VifCtl.vifc_flags, VifCtl.vifc_lcl_addr.s_addr, VifDp->IfDp->Name, VifCtl.vifc_threshold, + VifCtl.vifc_rate_limit ); struct SubnetList *currSubnet; - for(currSubnet = IfDp->allowednets; currSubnet; currSubnet = currSubnet->next) { - my_log(LOG_DEBUG, 0, " Network for [%s] : %s", - IfDp->Name, - inetFmts(currSubnet->subnet_addr, currSubnet->subnet_mask, s1)); + for ( currSubnet = IfDp->allowednets; currSubnet; currSubnet = currSubnet->next ) { + my_log( LOG_DEBUG, 0, " Network for [%s] : %s", IfDp->Name, + inetFmts( currSubnet->subnet_addr, currSubnet->subnet_mask, s1 ) ); } - if ( setsockopt( MRouterFD, IPPROTO_IP, MRT_ADD_VIF, - (char *)&VifCtl, sizeof( VifCtl ) ) ) + if ( setsockopt( MRouterFD, IPPROTO_IP, MRT_ADD_VIF, (char *) &VifCtl, sizeof( VifCtl ) ) ) my_log( LOG_ERR, errno, "MRT_ADD_VIF" ); - } /* @@ -173,11 +164,11 @@ void addVIF( struct IfDesc *IfDp ) int addMRoute( struct MRouteDesc *Dp ) { struct mfcctl CtlReq; - int rc; + int rc; - CtlReq.mfcc_origin = Dp->OriginAdr; - CtlReq.mfcc_mcastgrp = Dp->McAdr; - CtlReq.mfcc_parent = Dp->InVif; + CtlReq.mfcc_origin = Dp->OriginAdr; + CtlReq.mfcc_mcastgrp = Dp->McAdr; + CtlReq.mfcc_parent = Dp->InVif; /* copy the TTL vector */ @@ -185,18 +176,14 @@ int addMRoute( struct MRouteDesc *Dp ) memcpy( CtlReq.mfcc_ttls, Dp->TtlVc, sizeof( CtlReq.mfcc_ttls ) ); { - char FmtBuO[ 32 ], FmtBuM[ 32 ]; + char FmtBuO[32], FmtBuM[32]; - my_log( LOG_NOTICE, 0, "Adding MFC: %s -> %s, InpVIf: %d", - fmtInAdr( FmtBuO, CtlReq.mfcc_origin ), - fmtInAdr( FmtBuM, CtlReq.mfcc_mcastgrp ), - (int)CtlReq.mfcc_parent - ); + my_log( LOG_NOTICE, 0, "Adding MFC: %s -> %s, InpVIf: %d", fmtInAdr( FmtBuO, CtlReq.mfcc_origin ), + fmtInAdr( FmtBuM, CtlReq.mfcc_mcastgrp ), (int) CtlReq.mfcc_parent ); } - rc = setsockopt( MRouterFD, IPPROTO_IP, MRT_ADD_MFC, - (void *)&CtlReq, sizeof( CtlReq ) ); - if (rc) + rc = setsockopt( MRouterFD, IPPROTO_IP, MRT_ADD_MFC, (void *) &CtlReq, sizeof( CtlReq ) ); + if ( rc ) my_log( LOG_WARNING, errno, "MRT_ADD_MFC" ); return rc; @@ -211,29 +198,25 @@ int addMRoute( struct MRouteDesc *Dp ) int delMRoute( struct MRouteDesc *Dp ) { struct mfcctl CtlReq; - int rc; + int rc; - CtlReq.mfcc_origin = Dp->OriginAdr; - CtlReq.mfcc_mcastgrp = Dp->McAdr; - CtlReq.mfcc_parent = Dp->InVif; + CtlReq.mfcc_origin = Dp->OriginAdr; + CtlReq.mfcc_mcastgrp = Dp->McAdr; + CtlReq.mfcc_parent = Dp->InVif; /* clear the TTL vector */ memset( CtlReq.mfcc_ttls, 0, sizeof( CtlReq.mfcc_ttls ) ); { - char FmtBuO[ 32 ], FmtBuM[ 32 ]; + char FmtBuO[32], FmtBuM[32]; - my_log( LOG_NOTICE, 0, "Removing MFC: %s -> %s, InpVIf: %d", - fmtInAdr( FmtBuO, CtlReq.mfcc_origin ), - fmtInAdr( FmtBuM, CtlReq.mfcc_mcastgrp ), - (int)CtlReq.mfcc_parent - ); + my_log( LOG_NOTICE, 0, "Removing MFC: %s -> %s, InpVIf: %d", fmtInAdr( FmtBuO, CtlReq.mfcc_origin ), + fmtInAdr( FmtBuM, CtlReq.mfcc_mcastgrp ), (int) CtlReq.mfcc_parent ); } - rc = setsockopt( MRouterFD, IPPROTO_IP, MRT_DEL_MFC, - (void *)&CtlReq, sizeof( CtlReq ) ); - if (rc) + rc = setsockopt( MRouterFD, IPPROTO_IP, MRT_DEL_MFC, (void *) &CtlReq, sizeof( CtlReq ) ); + if ( rc ) my_log( LOG_WARNING, errno, "MRT_DEL_MFC" ); return rc; diff --git a/src/os-dragonfly.h b/src/os-dragonfly.h index 5ac8cc7e..4b757279 100644 --- a/src/os-dragonfly.h +++ b/src/os-dragonfly.h @@ -1,18 +1,18 @@ -#include #include -#include +#include #include +#include #define IGMP_V3_MEMBERSHIP_REPORT 0x22 -#define INADDR_ALLIGMPV3_GROUP ((in_addr_t) 0xe0000016) +#define INADDR_ALLIGMPV3_GROUP ( (in_addr_t) 0xe0000016 ) -static inline unsigned short ip_data_len(const struct ip *ip) +static inline unsigned short ip_data_len( const struct ip *ip ) { return ip->ip_len; } -static inline void ip_set_len(struct ip *ip, unsigned short len) +static inline void ip_set_len( struct ip *ip, unsigned short len ) { ip->ip_len = len; } diff --git a/src/os-freebsd.h b/src/os-freebsd.h index 4edef92d..9d2b6a5c 100644 --- a/src/os-freebsd.h +++ b/src/os-freebsd.h @@ -1,11 +1,10 @@ #include +#include #include -#include #include -#include +#include -#if __FreeBSD_version >= 800069 && defined BURN_BRIDGES \ - || __FreeBSD_version >= 800098 +#if __FreeBSD_version >= 800069 && defined BURN_BRIDGES || __FreeBSD_version >= 800098 #define IGMP_MEMBERSHIP_QUERY IGMP_HOST_MEMBERSHIP_QUERY #define IGMP_V1_MEMBERSHIP_REPORT IGMP_v1_HOST_MEMBERSHIP_REPORT #define IGMP_V2_MEMBERSHIP_REPORT IGMP_v2_HOST_MEMBERSHIP_REPORT @@ -13,23 +12,23 @@ #endif #define IGMP_V3_MEMBERSHIP_REPORT 0x22 -#define INADDR_ALLIGMPV3_GROUP ((in_addr_t) 0xe0000016) +#define INADDR_ALLIGMPV3_GROUP ( (in_addr_t) 0xe0000016 ) -static inline unsigned short ip_data_len(const struct ip *ip) +static inline unsigned short ip_data_len( const struct ip *ip ) { #if __FreeBSD_version >= 1100030 - return ntohs(ip->ip_len) - (ip->ip_hl << 2); + return ntohs( ip->ip_len ) - ( ip->ip_hl << 2 ); #elif __FreeBSD_version >= 900044 - return ip->ip_len - (ip->ip_hl << 2); + return ip->ip_len - ( ip->ip_hl << 2 ); #else return ip->ip_len; #endif } -static inline void ip_set_len(struct ip *ip, unsigned short len) +static inline void ip_set_len( struct ip *ip, unsigned short len ) { #if __FreeBSD_version >= 1100030 - ip->ip_len = htons(len); + ip->ip_len = htons( len ); #else ip->ip_len = len; #endif diff --git a/src/os-linux.h b/src/os-linux.h index 180a0a0d..1b19ed63 100644 --- a/src/os-linux.h +++ b/src/os-linux.h @@ -1,20 +1,20 @@ #define _LINUX_IN_H -#include #include -#include +#include #include +#include #include #define IGMP_V3_MEMBERSHIP_REPORT 0x22 -#define INADDR_ALLIGMPV3_GROUP ((in_addr_t) 0xe0000016) +#define INADDR_ALLIGMPV3_GROUP ( (in_addr_t) 0xe0000016 ) -static inline unsigned short ip_data_len(const struct ip *ip) +static inline unsigned short ip_data_len( const struct ip *ip ) { - return ntohs(ip->ip_len) - (ip->ip_hl << 2); + return ntohs( ip->ip_len ) - ( ip->ip_hl << 2 ); } -static inline void ip_set_len(struct ip *ip, unsigned short len) +static inline void ip_set_len( struct ip *ip, unsigned short len ) { - ip->ip_len = htons(len); + ip->ip_len = htons( len ); } diff --git a/src/os-netbsd.h b/src/os-netbsd.h index 311d0658..57fadb99 100644 --- a/src/os-netbsd.h +++ b/src/os-netbsd.h @@ -1,7 +1,7 @@ +#include #include -#include #include -#include +#include #define IGMP_MEMBERSHIP_QUERY IGMP_HOST_MEMBERSHIP_QUERY #define IGMP_V1_MEMBERSHIP_REPORT IGMP_v1_HOST_MEMBERSHIP_REPORT @@ -9,14 +9,14 @@ #define IGMP_V3_MEMBERSHIP_REPORT 0x22 #define IGMP_V2_LEAVE_GROUP IGMP_HOST_LEAVE_MESSAGE -#define INADDR_ALLIGMPV3_GROUP ((in_addr_t) 0xe0000016) +#define INADDR_ALLIGMPV3_GROUP ( (in_addr_t) 0xe0000016 ) -static inline unsigned short ip_data_len(const struct ip *ip) +static inline unsigned short ip_data_len( const struct ip *ip ) { return ip->ip_len; } -static inline void ip_set_len(struct ip *ip, unsigned short len) +static inline void ip_set_len( struct ip *ip, unsigned short len ) { ip->ip_len = len; } diff --git a/src/os-openbsd.h b/src/os-openbsd.h index aeb36860..3e029b16 100644 --- a/src/os-openbsd.h +++ b/src/os-openbsd.h @@ -1,7 +1,7 @@ +#include #include -#include #include -#include +#include #define IGMP_MEMBERSHIP_QUERY IGMP_HOST_MEMBERSHIP_QUERY #define IGMP_V1_MEMBERSHIP_REPORT IGMP_v1_HOST_MEMBERSHIP_REPORT @@ -10,14 +10,14 @@ #define IGMP_V2_LEAVE_GROUP IGMP_HOST_LEAVE_MESSAGE #define INADDR_ALLRTRS_GROUP INADDR_ALLROUTERS_GROUP -#define INADDR_ALLIGMPV3_GROUP ((in_addr_t) 0xe0000016) +#define INADDR_ALLIGMPV3_GROUP ( (in_addr_t) 0xe0000016 ) -static inline unsigned short ip_data_len(const struct ip *ip) +static inline unsigned short ip_data_len( const struct ip *ip ) { - return ntohs(ip->ip_len) - (ip->ip_hl << 2); + return ntohs( ip->ip_len ) - ( ip->ip_hl << 2 ); } -static inline void ip_set_len(struct ip *ip, unsigned short len) +static inline void ip_set_len( struct ip *ip, unsigned short len ) { - ip->ip_len = htons(len); + ip->ip_len = htons( len ); } diff --git a/src/os-qnxnto.h b/src/os-qnxnto.h index 150067a6..1d88febd 100644 --- a/src/os-qnxnto.h +++ b/src/os-qnxnto.h @@ -1,21 +1,21 @@ +#include #include -#include #include -#include +#include #define IGMP_MEMBERSHIP_QUERY IGMP_HOST_MEMBERSHIP_QUERY #define IGMP_V1_MEMBERSHIP_REPORT IGMP_v1_HOST_MEMBERSHIP_REPORT #define IGMP_V2_MEMBERSHIP_REPORT IGMP_v2_HOST_MEMBERSHIP_REPORT #define IGMP_V2_LEAVE_GROUP IGMP_HOST_LEAVE_MESSAGE -#define IPOPT_RA 148 /* router alert */ +#define IPOPT_RA 148 /* router alert */ -static inline u_short ip_data_len(const struct ip *ip) +static inline u_short ip_data_len( const struct ip *ip ) { return ip->ip_len; } -static inline void ip_set_len(struct ip *ip, u_short len) +static inline void ip_set_len( struct ip *ip, u_short len ) { ip->ip_len = len; } diff --git a/src/request.c b/src/request.c index 2f4b71a5..34a1bde8 100644 --- a/src/request.c +++ b/src/request.c @@ -41,115 +41,112 @@ #include "igmpproxy.h" // Prototypes... -void sendGroupSpecificMemberQuery(void *argument); +void sendGroupSpecificMemberQuery( void *argument ); typedef struct { - uint32_t group; + uint32_t group; // uint32_t vifAddr; - short started; + short started; } GroupVifDesc; - /** * Handles incoming membership reports, and * appends them to the routing table. */ -void acceptGroupReport(uint32_t src, uint32_t group) { - struct IfDesc *sourceVif; +void acceptGroupReport( uint32_t src, uint32_t group ) +{ + struct IfDesc *sourceVif; // Sanitycheck the group adress... - if(!IN_MULTICAST( ntohl(group) )) { - my_log(LOG_WARNING, 0, "The group address %s is not a valid Multicast group.", - inetFmt(group, s1)); + if ( !IN_MULTICAST( ntohl( group ) ) ) { + my_log( LOG_WARNING, 0, "The group address %s is not a valid Multicast group.", inetFmt( group, s1 ) ); return; } // Find the interface on which the report was received. sourceVif = getIfByAddress( src ); - if(sourceVif == NULL) { - my_log(LOG_WARNING, 0, "No interfaces found for source %s", - inetFmt(src,s1)); + if ( sourceVif == NULL ) { + my_log( LOG_WARNING, 0, "No interfaces found for source %s", inetFmt( src, s1 ) ); return; } - if(sourceVif->InAdr.s_addr == src) { - my_log(LOG_NOTICE, 0, "The IGMP message was from myself. Ignoring."); + if ( sourceVif->InAdr.s_addr == src ) { + my_log( LOG_NOTICE, 0, "The IGMP message was from myself. Ignoring." ); return; } // We have a IF so check that it's an downstream IF. - if(sourceVif->state == IF_STATE_DOWNSTREAM) { + if ( sourceVif->state == IF_STATE_DOWNSTREAM ) { - 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); + 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(sourceVif->allowedgroups == NULL) - { - insertRoute(group, sourceVif->index); + 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) - { + 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); + 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 { + } + 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.", - sourceVif->state==IF_STATE_UPSTREAM?"the upstream interface":"a disabled interface"); + my_log( LOG_INFO, 0, "Mebership report was received on %s. Ignoring.", + sourceVif->state == IF_STATE_UPSTREAM ? "the upstream interface" : "a disabled interface" ); } } /** * Recieves and handles a group leave message. */ -void acceptLeaveMessage(uint32_t src, uint32_t group) { - struct IfDesc *sourceVif; +void acceptLeaveMessage( uint32_t src, uint32_t group ) +{ + struct IfDesc *sourceVif; - my_log(LOG_DEBUG, 0, - "Got leave message from %s to %s. Starting last member detection.", - inetFmt(src, s1), inetFmt(group, s2)); + my_log( LOG_DEBUG, 0, "Got leave message from %s to %s. Starting last member detection.", inetFmt( src, s1 ), + inetFmt( group, s2 ) ); // Sanitycheck the group adress... - if(!IN_MULTICAST( ntohl(group) )) { - my_log(LOG_WARNING, 0, "The group address %s is not a valid Multicast group.", - inetFmt(group, s1)); + if ( !IN_MULTICAST( ntohl( group ) ) ) { + my_log( LOG_WARNING, 0, "The group address %s is not a valid Multicast group.", inetFmt( group, s1 ) ); return; } // Find the interface on which the report was received. sourceVif = getIfByAddress( src ); - if(sourceVif == NULL) { - my_log(LOG_WARNING, 0, "No interfaces found for source %s", - inetFmt(src,s1)); + if ( sourceVif == NULL ) { + my_log( LOG_WARNING, 0, "No interfaces found for source %s", inetFmt( src, s1 ) ); return; } // We have a IF so check that it's an downstream IF. - if(sourceVif->state == IF_STATE_DOWNSTREAM) { + if ( sourceVif->state == IF_STATE_DOWNSTREAM ) { - GroupVifDesc *gvDesc; - gvDesc = (GroupVifDesc*) malloc(sizeof(GroupVifDesc)); + GroupVifDesc *gvDesc; + gvDesc = (GroupVifDesc *) malloc( sizeof( GroupVifDesc ) ); // Tell the route table that we are checking for remaining members... - setRouteLastMemberMode(group); + setRouteLastMemberMode( group ); // Call the group spesific membership querier... gvDesc->group = group; // gvDesc->vifAddr = sourceVif->InAdr.s_addr; gvDesc->started = 0; - sendGroupSpecificMemberQuery(gvDesc); - - } else { + sendGroupSpecificMemberQuery( gvDesc ); + } + else { // just ignore the leave request... - my_log(LOG_DEBUG, 0, "The found if for %s was not downstream. Ignoring leave request.", inetFmt(src, s1)); + my_log( LOG_DEBUG, 0, "The found if for %s was not downstream. Ignoring leave request.", inetFmt( src, s1 ) ); } } @@ -157,94 +154,93 @@ void acceptLeaveMessage(uint32_t src, uint32_t group) { * Sends a group specific member report query until the * group times out... */ -void sendGroupSpecificMemberQuery(void *argument) { - struct Config *conf = getCommonConfig(); - struct IfDesc *Dp; - struct RouteTable *croute; - int Ix; +void sendGroupSpecificMemberQuery( void *argument ) +{ + struct Config * conf = getCommonConfig(); + struct IfDesc * Dp; + struct RouteTable *croute; + int Ix; // Cast argument to correct type... - GroupVifDesc *gvDesc = (GroupVifDesc*) argument; + GroupVifDesc *gvDesc = (GroupVifDesc *) argument; - if(gvDesc->started) { + if ( gvDesc->started ) { // If aging returns false, we don't do any further action... - if(!lastMemberGroupAge(gvDesc->group)) { + if ( !lastMemberGroupAge( gvDesc->group ) ) { // FIXME: Should we free gvDesc here? return; } - } else { + } + else { gvDesc->started = 1; } /** - * FIXME: This loops through all interfaces the group is active on an sends queries. - * It might be better to send only a query on the interface the leave was accepted on and remove only that interface from the route. + * FIXME: This loops through all interfaces the group is active on an sends + * queries. + * It might be better to send only a query on the interface the leave + * was accepted on and remove only that + * interface from the route. */ // Loop through all downstream interfaces - for ( Ix = 0; (Dp = getIfByIx(Ix)); Ix++ ) { - if ( Dp->InAdr.s_addr && ! (Dp->Flags & IFF_LOOPBACK) ) { - if(Dp->state == IF_STATE_DOWNSTREAM) { + for ( Ix = 0; ( Dp = getIfByIx( Ix ) ); Ix++ ) { + if ( Dp->InAdr.s_addr && !( Dp->Flags & IFF_LOOPBACK ) ) { + if ( Dp->state == IF_STATE_DOWNSTREAM ) { // Is that interface used in the group? - if (interfaceInRoute(gvDesc->group ,Dp->index)) { + if ( interfaceInRoute( gvDesc->group, Dp->index ) ) { // Send a group specific membership query... - sendIgmp(Dp->InAdr.s_addr, gvDesc->group, - IGMP_MEMBERSHIP_QUERY, - conf->lastMemberQueryInterval * IGMP_TIMER_SCALE, - gvDesc->group, 0); - - my_log(LOG_DEBUG, 0, "Sent membership query from %s to %s. Delay: %d", - inetFmt(Dp->InAdr.s_addr,s1), inetFmt(gvDesc->group,s2), - conf->lastMemberQueryInterval); + sendIgmp( Dp->InAdr.s_addr, gvDesc->group, IGMP_MEMBERSHIP_QUERY, + conf->lastMemberQueryInterval * IGMP_TIMER_SCALE, gvDesc->group, 0 ); + + my_log( LOG_DEBUG, 0, "Sent membership query from %s to %s. Delay: %d", + inetFmt( Dp->InAdr.s_addr, s1 ), inetFmt( gvDesc->group, s2 ), + conf->lastMemberQueryInterval ); } } } } // Set timeout for next round... - timer_setTimer(conf->lastMemberQueryInterval, sendGroupSpecificMemberQuery, gvDesc); + timer_setTimer( conf->lastMemberQueryInterval, sendGroupSpecificMemberQuery, gvDesc ); } - /** * Sends a general membership query on downstream VIFs */ -void sendGeneralMembershipQuery(void) { - struct Config *conf = getCommonConfig(); - struct IfDesc *Dp; - int Ix; +void sendGeneralMembershipQuery( void ) +{ + struct Config *conf = getCommonConfig(); + struct IfDesc *Dp; + int Ix; // Loop through all downstream vifs... - for ( Ix = 0; (Dp = getIfByIx(Ix)); Ix++ ) { - if ( Dp->InAdr.s_addr && ! (Dp->Flags & IFF_LOOPBACK) ) { - if(Dp->state == IF_STATE_DOWNSTREAM) { + for ( Ix = 0; ( Dp = getIfByIx( Ix ) ); Ix++ ) { + if ( Dp->InAdr.s_addr && !( Dp->Flags & IFF_LOOPBACK ) ) { + if ( Dp->state == IF_STATE_DOWNSTREAM ) { // Send the membership query... - sendIgmp(Dp->InAdr.s_addr, allhosts_group, - IGMP_MEMBERSHIP_QUERY, - conf->queryResponseInterval * IGMP_TIMER_SCALE, 0, 0); - - my_log(LOG_DEBUG, 0, - "Sent membership query from %s to %s. Delay: %d", - inetFmt(Dp->InAdr.s_addr,s1), - inetFmt(allhosts_group,s2), - conf->queryResponseInterval); + sendIgmp( Dp->InAdr.s_addr, allhosts_group, IGMP_MEMBERSHIP_QUERY, + conf->queryResponseInterval * IGMP_TIMER_SCALE, 0, 0 ); + + my_log( LOG_DEBUG, 0, "Sent membership query from %s to %s. Delay: %d", inetFmt( Dp->InAdr.s_addr, s1 ), + inetFmt( allhosts_group, s2 ), conf->queryResponseInterval ); } } } // Install timer for aging active routes. - timer_setTimer(conf->queryResponseInterval, (timer_f)ageActiveRoutes, NULL); + timer_setTimer( conf->queryResponseInterval, (timer_f) ageActiveRoutes, NULL ); // Install timer for next general query... - if(conf->startupQueryCount>0) { + if ( conf->startupQueryCount > 0 ) { // Use quick timer... - timer_setTimer(conf->startupQueryInterval, (timer_f)sendGeneralMembershipQuery, NULL); + timer_setTimer( conf->startupQueryInterval, (timer_f) sendGeneralMembershipQuery, NULL ); // Decrease startup counter... conf->startupQueryCount--; } else { // Use slow timer... - timer_setTimer(conf->queryInterval, (timer_f)sendGeneralMembershipQuery, NULL); + timer_setTimer( conf->queryInterval, (timer_f) sendGeneralMembershipQuery, NULL ); } } diff --git a/src/rttable.c b/src/rttable.c index fb0fbc60..6312abcb 100644 --- a/src/rttable.c +++ b/src/rttable.c @@ -46,41 +46,43 @@ * Routing table structure definition. Double linked list... */ struct RouteTable { - struct RouteTable *nextroute; // Pointer to the next group in line. - struct RouteTable *prevroute; // Pointer to the previous group in line. - uint32_t group; // The group to route - uint32_t originAddrs[MAX_ORIGINS]; // The origin adresses (only set on activated routes) - uint32_t vifBits; // Bits representing recieving VIFs. + struct RouteTable *nextroute; // Pointer to the next group in line. + struct RouteTable *prevroute; // Pointer to the previous group in line. + uint32_t group; // The group to route + uint32_t originAddrs[MAX_ORIGINS]; // The origin adresses (only set on + // activated routes) + uint32_t vifBits; // Bits representing recieving VIFs. // Keeps the upstream membership state... - short upstrState; // Upstream membership state. - int upstrVif; // Upstream Vif Index. + short upstrState; // Upstream membership state. + int upstrVif; // Upstream Vif Index. // These parameters contain aging details. - uint32_t ageVifBits; // Bits representing aging VIFs. - int ageValue; // Downcounter for death. - int ageActivity; // Records any acitivity that notes there are still listeners. + uint32_t ageVifBits; // Bits representing aging VIFs. + int ageValue; // Downcounter for death. + int ageActivity; // Records any acitivity that notes there are still + // listeners. }; - // Keeper for the routing table... -static struct RouteTable *routing_table; +static struct RouteTable *routing_table; // Prototypes -void logRouteTable(const char *header); -int internAgeRoute(struct RouteTable *croute); -int internUpdateKernelRoute(struct RouteTable *route, int activate); +void logRouteTable( const char *header ); +int internAgeRoute( struct RouteTable *croute ); +int internUpdateKernelRoute( struct RouteTable *route, int activate ); // Socket for sending join or leave requests. int mcGroupSock = 0; - /** * Function for retrieving the Multicast Group socket. */ -int getMcGroupSock(void) { - if( ! mcGroupSock ) { - mcGroupSock = openUdpSocket( INADDR_ANY, 0 );; +int getMcGroupSock( void ) +{ + if ( !mcGroupSock ) { + mcGroupSock = openUdpSocket( INADDR_ANY, 0 ); + ; } return mcGroupSock; } @@ -88,25 +90,26 @@ int getMcGroupSock(void) { /** * Initializes the routing table. */ -void initRouteTable(void) { - unsigned Ix; +void initRouteTable( void ) +{ + unsigned Ix; struct IfDesc *Dp; // Clear routing table... routing_table = NULL; // Join the all routers group on downstream vifs... - for ( Ix = 0; (Dp = getIfByIx(Ix)); Ix++ ) { + for ( Ix = 0; ( Dp = getIfByIx( Ix ) ); Ix++ ) { // If this is a downstream vif, we should join the All routers group... - if( Dp->InAdr.s_addr && ! (Dp->Flags & IFF_LOOPBACK) && Dp->state == IF_STATE_DOWNSTREAM) { - my_log(LOG_DEBUG, 0, "Joining all-routers group %s on vif %s", - inetFmt(allrouters_group,s1),inetFmt(Dp->InAdr.s_addr,s2)); + if ( Dp->InAdr.s_addr && !( Dp->Flags & IFF_LOOPBACK ) && Dp->state == IF_STATE_DOWNSTREAM ) { + my_log( LOG_DEBUG, 0, "Joining all-routers group %s on vif %s", inetFmt( allrouters_group, s1 ), + inetFmt( Dp->InAdr.s_addr, s2 ) ); - //k_join(allrouters_group, Dp->InAdr.s_addr); + // k_join(allrouters_group, Dp->InAdr.s_addr); joinMcGroup( getMcGroupSock(), Dp, allrouters_group ); - my_log(LOG_DEBUG, 0, "Joining all igmpv3 multicast routers group %s on vif %s", - inetFmt(alligmp3_group,s1),inetFmt(Dp->InAdr.s_addr,s2)); + my_log( LOG_DEBUG, 0, "Joining all igmpv3 multicast routers group %s on vif %s", + inetFmt( alligmp3_group, s1 ), inetFmt( Dp->InAdr.s_addr, s2 ) ); joinMcGroup( getMcGroupSock(), Dp, alligmp3_group ); } } @@ -116,69 +119,68 @@ void initRouteTable(void) { * Internal function to send join or leave requests for * a specified route upstream... */ -static void sendJoinLeaveUpstream(struct RouteTable* route, int join) { - struct IfDesc* upstrIf; - int i; - - for(i=0; iallowedgroups != NULL) { - uint32_t group = route->group; - struct SubnetList* sn; + 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) + 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)); + 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) { + if ( join ) { // Only join a group if there are listeners downstream... - if(route->vifBits > 0) { - my_log(LOG_DEBUG, 0, "Joining group %s upstream on IF address %s", - inetFmt(route->group, s1), - inetFmt(upstrIf->InAdr.s_addr, s2)); + if ( route->vifBits > 0 ) { + my_log( LOG_DEBUG, 0, "Joining group %s upstream on IF address %s", inetFmt( route->group, s1 ), + inetFmt( upstrIf->InAdr.s_addr, s2 ) ); - //k_join(route->group, upstrIf->InAdr.s_addr); + // k_join(route->group, upstrIf->InAdr.s_addr); joinMcGroup( getMcGroupSock(), upstrIf, route->group ); route->upstrState = ROUTESTATE_JOINED; - } else { - my_log(LOG_DEBUG, 0, "No downstream listeners for group %s. No join sent.", - inetFmt(route->group, s1)); } - } else { + else { + my_log( LOG_DEBUG, 0, "No downstream listeners for group %s. No join sent.", + inetFmt( route->group, s1 ) ); + } + } + else { // Only leave if group is not left already... - if(route->upstrState != ROUTESTATE_NOTJOINED) { - my_log(LOG_DEBUG, 0, "Leaving group %s upstream on IF address %s", - inetFmt(route->group, s1), - inetFmt(upstrIf->InAdr.s_addr, s2)); + if ( route->upstrState != ROUTESTATE_NOTJOINED ) { + my_log( LOG_DEBUG, 0, "Leaving group %s upstream on IF address %s", inetFmt( route->group, s1 ), + inetFmt( upstrIf->InAdr.s_addr, s2 ) ); - //k_leave(route->group, upstrIf->InAdr.s_addr); + // k_leave(route->group, upstrIf->InAdr.s_addr); leaveMcGroup( getMcGroupSock(), upstrIf, route->group ); route->upstrState = ROUTESTATE_NOTJOINED; } } } - else - { + else { i = MAX_UPS_VIFS; } } @@ -187,44 +189,45 @@ static void sendJoinLeaveUpstream(struct RouteTable* route, int join) { /** * Clear all routes from routing table, and alerts Leaves upstream. */ -void clearAllRoutes(void) { - struct RouteTable *croute, *remainroute; +void clearAllRoutes( void ) +{ + struct RouteTable *croute, *remainroute; // Loop through all routes... - for(croute = routing_table; croute; croute = remainroute) { + for ( croute = routing_table; croute; croute = remainroute ) { remainroute = croute->nextroute; // Log the cleanup in debugmode... - my_log(LOG_DEBUG, 0, "Removing route entry for %s", - inetFmt(croute->group, s1)); + my_log( LOG_DEBUG, 0, "Removing route entry for %s", inetFmt( croute->group, s1 ) ); // Uninstall current route - if(!internUpdateKernelRoute(croute, 0)) { - my_log(LOG_WARNING, 0, "The removal from Kernel failed."); + if ( !internUpdateKernelRoute( croute, 0 ) ) { + my_log( LOG_WARNING, 0, "The removal from Kernel failed." ); } // Send Leave message upstream. - sendJoinLeaveUpstream(croute, 0); + sendJoinLeaveUpstream( croute, 0 ); // Clear memory, and set pointer to next route... - free(croute); + free( croute ); } routing_table = NULL; // Send a notice that the routing table is empty... - my_log(LOG_NOTICE, 0, "All routes removed. Routing table is empty."); + my_log( LOG_NOTICE, 0, "All routes removed. Routing table is empty." ); } /** * Private access function to find a route from a given * Route Descriptor. */ -static struct RouteTable *findRoute(uint32_t group) { - struct RouteTable* croute; +static struct RouteTable *findRoute( uint32_t group ) +{ + struct RouteTable *croute; - for(croute = routing_table; croute; croute = croute->nextroute) { - if(croute->group == group) { + for ( croute = routing_table; croute; croute = croute->nextroute ) { + if ( croute->group == group ) { return croute; } } @@ -237,42 +240,42 @@ static struct RouteTable *findRoute(uint32_t group) { * If the route already exists, the existing route * is updated... */ -int insertRoute(uint32_t group, int ifx) { +int insertRoute( uint32_t group, int ifx ) +{ - struct Config *conf = getCommonConfig(); - struct RouteTable* croute; + struct Config * conf = getCommonConfig(); + struct RouteTable *croute; // Sanitycheck the group adress... - if( ! IN_MULTICAST( ntohl(group) )) { - my_log(LOG_WARNING, 0, "The group address %s is not a valid Multicast group. Table insert failed.", - inetFmt(group, s1)); + if ( !IN_MULTICAST( ntohl( group ) ) ) { + my_log( LOG_WARNING, 0, "The group address %s is not a valid Multicast " + "group. Table insert failed.", + inetFmt( group, s1 ) ); return 0; } // Santiycheck the VIF index... - //if(ifx < 0 || ifx >= MAX_MC_VIFS) { - if(ifx >= MAX_MC_VIFS) { - my_log(LOG_WARNING, 0, "The VIF Ix %d is out of range (0-%d). Table insert failed.",ifx,MAX_MC_VIFS); + // if(ifx < 0 || ifx >= MAX_MC_VIFS) { + if ( ifx >= MAX_MC_VIFS ) { + my_log( LOG_WARNING, 0, "The VIF Ix %d is out of range (0-%d). Table insert failed.", ifx, MAX_MC_VIFS ); return 0; } // Try to find an existing route for this group... - croute = findRoute(group); - if(croute==NULL) { - struct RouteTable* newroute; - - my_log(LOG_DEBUG, 0, "No existing route for %s. Create new.", - inetFmt(group, s1)); + croute = findRoute( group ); + if ( croute == NULL ) { + struct RouteTable *newroute; + my_log( LOG_DEBUG, 0, "No existing route for %s. Create new.", inetFmt( group, s1 ) ); // Create and initialize the new route table entry.. - newroute = (struct RouteTable*)malloc(sizeof(struct RouteTable)); + newroute = (struct RouteTable *) malloc( sizeof( struct RouteTable ) ); // Insert the route desc and clear all pointers... - newroute->group = group; - memset(newroute->originAddrs, 0, MAX_ORIGINS * sizeof(newroute->originAddrs[0])); - newroute->nextroute = NULL; - newroute->prevroute = NULL; - newroute->upstrVif = -1; + newroute->group = group; + memset( newroute->originAddrs, 0, MAX_ORIGINS * sizeof( newroute->originAddrs[0] ) ); + newroute->nextroute = NULL; + newroute->prevroute = NULL; + newroute->upstrVif = -1; // The group is not joined initially. newroute->upstrState = ROUTESTATE_NOTJOINED; @@ -281,53 +284,54 @@ int insertRoute(uint32_t group, int ifx) { newroute->ageValue = conf->robustnessValue; newroute->ageActivity = 0; - BIT_ZERO(newroute->ageVifBits); // Initially we assume no listeners. + BIT_ZERO( newroute->ageVifBits ); // Initially we assume no listeners. // Set the listener flag... - BIT_ZERO(newroute->vifBits); // Initially no listeners... - if(ifx >= 0) { - BIT_SET(newroute->vifBits, ifx); + BIT_ZERO( newroute->vifBits ); // Initially no listeners... + if ( ifx >= 0 ) { + BIT_SET( newroute->vifBits, ifx ); } // Check if there is a table already.... - if(routing_table == NULL) { + if ( routing_table == NULL ) { // No location set, so insert in on the table top. routing_table = newroute; - my_log(LOG_DEBUG, 0, "No routes in table. Insert at beginning."); - } else { + my_log( LOG_DEBUG, 0, "No routes in table. Insert at beginning." ); + } + else { - my_log(LOG_DEBUG, 0, "Found existing routes. Find insert location."); + my_log( LOG_DEBUG, 0, "Found existing routes. Find insert location." ); // Check if the route could be inserted at the beginning... - if(routing_table->group > group) { - my_log(LOG_DEBUG, 0, "Inserting at beginning, before route %s",inetFmt(routing_table->group,s1)); + if ( routing_table->group > group ) { + my_log( LOG_DEBUG, 0, "Inserting at beginning, before route %s", inetFmt( routing_table->group, s1 ) ); // Insert at beginning... newroute->nextroute = routing_table; newroute->prevroute = NULL; - routing_table = newroute; + routing_table = newroute; // If the route has a next node, the previous pointer must be updated. - if(newroute->nextroute != NULL) { + if ( newroute->nextroute != NULL ) { newroute->nextroute->prevroute = newroute; } - - } else { + } + else { // Find the location which is closest to the route. - for( croute = routing_table; croute->nextroute != NULL; croute = croute->nextroute ) { + for ( croute = routing_table; croute->nextroute != NULL; croute = croute->nextroute ) { // Find insert position. - if(croute->nextroute->group > group) { + if ( croute->nextroute->group > group ) { break; } } - my_log(LOG_DEBUG, 0, "Inserting after route %s",inetFmt(croute->group,s1)); + my_log( LOG_DEBUG, 0, "Inserting after route %s", inetFmt( croute->group, s1 ) ); // Insert after current... newroute->nextroute = croute->nextroute; newroute->prevroute = croute; - if(croute->nextroute != NULL) { + if ( croute->nextroute != NULL ) { croute->nextroute->prevroute = newroute; } croute->nextroute = newroute; @@ -338,37 +342,35 @@ int insertRoute(uint32_t group, int ifx) { croute = newroute; // Log the cleanup in debugmode... - my_log(LOG_INFO, 0, "Inserted route table entry for %s on VIF #%d", - inetFmt(croute->group, s1),ifx); - - } else if(ifx >= 0) { + my_log( LOG_INFO, 0, "Inserted route table entry for %s on VIF #%d", inetFmt( croute->group, s1 ), ifx ); + } + else if ( ifx >= 0 ) { // The route exists already, so just update it. - BIT_SET(croute->vifBits, ifx); + BIT_SET( croute->vifBits, ifx ); // Register the VIF activity for the aging routine - BIT_SET(croute->ageVifBits, ifx); + BIT_SET( croute->ageVifBits, ifx ); // Log the cleanup in debugmode... - my_log(LOG_INFO, 0, "Updated route entry for %s on VIF #%d", - inetFmt(croute->group, s1), ifx); + my_log( LOG_INFO, 0, "Updated route entry for %s on VIF #%d", inetFmt( croute->group, s1 ), ifx ); // Update route in kernel... - if(!internUpdateKernelRoute(croute, 1)) { - my_log(LOG_WARNING, 0, "The insertion into Kernel failed."); + if ( !internUpdateKernelRoute( croute, 1 ) ) { + my_log( LOG_WARNING, 0, "The insertion into Kernel failed." ); return 0; } } // Send join message upstream, if the route has no joined flag... - if(croute->upstrState != ROUTESTATE_JOINED) { + if ( croute->upstrState != ROUTESTATE_JOINED ) { // Send Join request upstream - struct IfDesc* downstrIf; - downstrIf = getIfByIx(ifx); - sendJoinLeaveUpstream(croute, 1); + struct IfDesc *downstrIf; + downstrIf = getIfByIx( ifx ); + sendJoinLeaveUpstream( croute, 1 ); } - logRouteTable("Insert Route"); + logRouteTable( "Insert Route" ); return 1; } @@ -378,108 +380,108 @@ int insertRoute(uint32_t group, int ifx) { * activated, it's reinstalled in the kernel. If * the route is activated, no originAddr is needed. */ -int activateRoute(uint32_t group, uint32_t originAddr, int upstrVif) { - struct RouteTable* croute; - int result = 0; +int activateRoute( uint32_t group, uint32_t originAddr, int upstrVif ) +{ + struct RouteTable *croute; + int result = 0; // Find the requested route. - croute = findRoute(group); - if(croute == NULL) { - my_log(LOG_DEBUG, 0, - "No table entry for %s [From: %s]. Inserting route.", - inetFmt(group, s1),inetFmt(originAddr, s2)); + croute = findRoute( group ); + if ( croute == NULL ) { + my_log( LOG_DEBUG, 0, "No table entry for %s [From: %s]. Inserting route.", inetFmt( group, s1 ), + inetFmt( originAddr, s2 ) ); // Insert route, but no interfaces have yet requested it downstream. - insertRoute(group, -1); + insertRoute( group, -1 ); // Retrieve the route from table... - croute = findRoute(group); + croute = findRoute( group ); } - if(croute != NULL) { + if ( croute != NULL ) { // If the origin address is set, update the route data. - if(originAddr > 0) { + if ( originAddr > 0 ) { // find this origin, or an unused slot int i; - for (i = 0; i < MAX_ORIGINS; i++) { + for ( i = 0; i < MAX_ORIGINS; i++ ) { // unused slots are at the bottom, so we can't miss this origin - if (croute->originAddrs[i] == originAddr || croute->originAddrs[i] == 0) { + if ( croute->originAddrs[i] == originAddr || croute->originAddrs[i] == 0 ) { break; } } - if (i == MAX_ORIGINS) { + if ( i == MAX_ORIGINS ) { i = MAX_ORIGINS - 1; - my_log(LOG_WARNING, 0, "Too many origins for route %s; replacing %s with %s", - inetFmt(croute->group, s1), - inetFmt(croute->originAddrs[i], s2), - inetFmt(originAddr, s3)); + my_log( LOG_WARNING, 0, "Too many origins for route %s; replacing %s with %s", + inetFmt( croute->group, s1 ), inetFmt( croute->originAddrs[i], s2 ), + inetFmt( originAddr, s3 ) ); } // set origin croute->originAddrs[i] = originAddr; // move it to the top - while (i > 0) { - uint32_t t = croute->originAddrs[i - 1]; + while ( i > 0 ) { + uint32_t t = croute->originAddrs[i - 1]; croute->originAddrs[i - 1] = croute->originAddrs[i]; - croute->originAddrs[i] = t; + croute->originAddrs[i] = t; i--; } } croute->upstrVif = upstrVif; // Only update kernel table if there are listeners ! - if(croute->vifBits > 0) { - result = internUpdateKernelRoute(croute, 1); + if ( croute->vifBits > 0 ) { + result = internUpdateKernelRoute( croute, 1 ); } } - logRouteTable("Activate Route"); + logRouteTable( "Activate Route" ); return result; } - /** * This function loops through all routes, and updates the age * of any active routes. */ -void ageActiveRoutes(void) { - struct RouteTable *croute, *nroute; +void ageActiveRoutes( void ) +{ + struct RouteTable *croute, *nroute; - my_log(LOG_DEBUG, 0, "Aging routes in table."); + my_log( LOG_DEBUG, 0, "Aging routes in table." ); // Scan all routes... - for( croute = routing_table; croute != NULL; croute = nroute ) { + for ( croute = routing_table; croute != NULL; croute = nroute ) { // Keep the next route (since current route may be removed)... nroute = croute->nextroute; // Run the aging round algorithm. - if(croute->upstrState != ROUTESTATE_CHECK_LAST_MEMBER) { + if ( croute->upstrState != ROUTESTATE_CHECK_LAST_MEMBER ) { // Only age routes if Last member probe is not active... - internAgeRoute(croute); + internAgeRoute( croute ); } } - logRouteTable("Age active routes"); + logRouteTable( "Age active routes" ); } /** * Counts the number of interfaces a given route is active on */ -int numberOfInterfaces(struct RouteTable *croute) { - int Ix; +int numberOfInterfaces( struct RouteTable *croute ) +{ + int Ix; struct IfDesc *Dp; - int result = 0; + int result = 0; // Loop through all interfaces - for ( Ix = 0; (Dp = getIfByIx(Ix)); Ix++ ) { + for ( Ix = 0; ( Dp = getIfByIx( Ix ) ); Ix++ ) { // If the interface is used by the route, increase counter - if(BIT_TST(croute->vifBits, Dp->index)) { + if ( BIT_TST( croute->vifBits, Dp->index ) ) { result++; } } - my_log(LOG_DEBUG, 0, "counted %d interfaces", result); + my_log( LOG_DEBUG, 0, "counted %d interfaces", result ); return result; } @@ -487,18 +489,20 @@ int numberOfInterfaces(struct RouteTable *croute) { * Should be called when a leave message is received, to * mark a route for the last member probe state. */ -void setRouteLastMemberMode(uint32_t group) { - struct Config *conf = getCommonConfig(); - struct RouteTable *croute; +void setRouteLastMemberMode( uint32_t group ) +{ + struct Config * conf = getCommonConfig(); + struct RouteTable *croute; - croute = findRoute(group); - if(croute!=NULL) { + croute = findRoute( group ); + if ( croute != NULL ) { // Check for fast leave mode... - if(croute->upstrState == ROUTESTATE_JOINED && conf->fastUpstreamLeave) { - // Send a leave message right away only when the route has been active on only one interface - if (numberOfInterfaces(croute) <= 1) { - my_log(LOG_DEBUG, 0, "Leaving group %d now", group); - sendJoinLeaveUpstream(croute, 0); + if ( croute->upstrState == ROUTESTATE_JOINED && conf->fastUpstreamLeave ) { + // Send a leave message right away only when the route has been active on + // only one interface + if ( numberOfInterfaces( croute ) <= 1 ) { + my_log( LOG_DEBUG, 0, "Leaving group %d now", group ); + sendJoinLeaveUpstream( croute, 0 ); } } @@ -510,19 +514,20 @@ void setRouteLastMemberMode(uint32_t group) { } } - /** * Ages groups in the last member check state. If the * route is not found, or not in this state, 0 is returned. */ -int lastMemberGroupAge(uint32_t group) { - struct RouteTable *croute; - - croute = findRoute(group); - if(croute!=NULL) { - if(croute->upstrState == ROUTESTATE_CHECK_LAST_MEMBER) { - return !internAgeRoute(croute); - } else { +int lastMemberGroupAge( uint32_t group ) +{ + struct RouteTable *croute; + + croute = findRoute( group ); + if ( croute != NULL ) { + if ( croute->upstrState == ROUTESTATE_CHECK_LAST_MEMBER ) { + return !internAgeRoute( croute ); + } + else { return 0; } } @@ -533,76 +538,76 @@ int lastMemberGroupAge(uint32_t group) { * Remove a specified route. Returns 1 on success, * and 0 if route was not found. */ -static int removeRoute(struct RouteTable* croute) { - struct Config *conf = getCommonConfig(); - int result = 1; +static int removeRoute( struct RouteTable *croute ) +{ + struct Config *conf = getCommonConfig(); + int result = 1; // If croute is null, no routes was found. - if(croute==NULL) { + if ( croute == NULL ) { return 0; } // Log the cleanup in debugmode... - my_log(LOG_DEBUG, 0, "Removed route entry for %s from table.", - inetFmt(croute->group, s1)); + my_log( LOG_DEBUG, 0, "Removed route entry for %s from table.", inetFmt( croute->group, s1 ) ); - //BIT_ZERO(croute->vifBits); + // BIT_ZERO(croute->vifBits); // Uninstall current route from kernel - if(!internUpdateKernelRoute(croute, 0)) { - my_log(LOG_WARNING, 0, "The removal from Kernel failed."); + if ( !internUpdateKernelRoute( croute, 0 ) ) { + my_log( LOG_WARNING, 0, "The removal from Kernel failed." ); result = 0; } // Send Leave request upstream if group is joined - if(croute->upstrState == ROUTESTATE_JOINED || - (croute->upstrState == ROUTESTATE_CHECK_LAST_MEMBER && !conf->fastUpstreamLeave)) - { - sendJoinLeaveUpstream(croute, 0); + if ( croute->upstrState == ROUTESTATE_JOINED || + ( croute->upstrState == ROUTESTATE_CHECK_LAST_MEMBER && !conf->fastUpstreamLeave ) ) { + sendJoinLeaveUpstream( croute, 0 ); } // Update pointers... - if(croute->prevroute == NULL) { + if ( croute->prevroute == NULL ) { // Topmost node... - if(croute->nextroute != NULL) { + if ( croute->nextroute != NULL ) { croute->nextroute->prevroute = NULL; } routing_table = croute->nextroute; - - } else { + } + else { croute->prevroute->nextroute = croute->nextroute; - if(croute->nextroute != NULL) { + if ( croute->nextroute != NULL ) { croute->nextroute->prevroute = croute->prevroute; } } // Free the memory, and set the route to NULL... - free(croute); + free( croute ); croute = NULL; - logRouteTable("Remove route"); + logRouteTable( "Remove route" ); return result; } - /** * Ages a specific route */ -int internAgeRoute(struct RouteTable* croute) { - struct Config *conf = getCommonConfig(); - int result = 0; +int internAgeRoute( struct RouteTable *croute ) +{ + struct Config *conf = getCommonConfig(); + int result = 0; // Drop age by 1. croute->ageValue--; // Check if there has been any activity... - if( croute->ageVifBits > 0 && croute->ageActivity == 0 ) { + if ( croute->ageVifBits > 0 && croute->ageActivity == 0 ) { // There was some activity, check if all registered vifs responded. - if(croute->vifBits == croute->ageVifBits) { + if ( croute->vifBits == croute->ageVifBits ) { // Everything is in perfect order, so we just update the route age. croute->ageValue = conf->robustnessValue; - //croute->ageActivity = 0; - } else { + // croute->ageActivity = 0; + } + else { // One or more VIF has not gotten any response. croute->ageActivity++; @@ -611,10 +616,10 @@ int internAgeRoute(struct RouteTable* croute) { } } // Check if there have been activity in aging process... - else if( croute->ageActivity > 0 ) { + else if ( croute->ageActivity > 0 ) { // If the bits are different in this round, we must - if(croute->vifBits != croute->ageVifBits) { + if ( croute->vifBits != croute->ageVifBits ) { // Or the bits together to insure we don't lose any listeners. croute->vifBits |= croute->ageVifBits; @@ -624,33 +629,32 @@ int internAgeRoute(struct RouteTable* croute) { } // If the aging counter has reached zero, its time for updating... - if(croute->ageValue == 0) { + if ( croute->ageValue == 0 ) { // Check for activity in the aging process, - if(croute->ageActivity>0) { + if ( croute->ageActivity > 0 ) { - my_log(LOG_DEBUG, 0, "Updating route after aging : %s", - inetFmt(croute->group,s1)); + my_log( LOG_DEBUG, 0, "Updating route after aging : %s", inetFmt( croute->group, s1 ) ); // Just update the routing settings in kernel... - internUpdateKernelRoute(croute, 1); + internUpdateKernelRoute( croute, 1 ); // We append the activity counter to the age, and continue... - croute->ageValue = croute->ageActivity; + croute->ageValue = croute->ageActivity; croute->ageActivity = 0; - } else { + } + else { - my_log(LOG_DEBUG, 0, "Removing group %s. Died of old age.", - inetFmt(croute->group,s1)); + my_log( LOG_DEBUG, 0, "Removing group %s. Died of old age.", inetFmt( croute->group, s1 ) ); // No activity was registered within the timelimit, so remove the route. - removeRoute(croute); + removeRoute( croute ); } // Tell that the route was updated... result = 1; } // The aging vif bits must be reset for each round... - BIT_ZERO(croute->ageVifBits); + BIT_ZERO( croute->ageVifBits ); return result; } @@ -659,14 +663,15 @@ int internAgeRoute(struct RouteTable* croute) { * Updates the Kernel routing table. If activate is 1, the route * is (re-)activated. If activate is false, the route is removed. */ -int internUpdateKernelRoute(struct RouteTable *route, int activate) { - struct MRouteDesc mrDesc; - struct IfDesc *Dp; - unsigned Ix; - int i; - - for (int i = 0; i < MAX_ORIGINS; i++) { - if (route->originAddrs[i] == 0 || route->upstrVif == -1) { +int internUpdateKernelRoute( struct RouteTable *route, int activate ) +{ + struct MRouteDesc mrDesc; + struct IfDesc * Dp; + unsigned Ix; + int i; + + for ( int i = 0; i < MAX_ORIGINS; i++ ) { + if ( route->originAddrs[i] == 0 || route->upstrVif == -1 ) { continue; } @@ -678,26 +683,27 @@ int internUpdateKernelRoute(struct RouteTable *route, int activate) { // clear output interfaces memset( mrDesc.TtlVc, 0, sizeof( mrDesc.TtlVc ) ); - my_log(LOG_DEBUG, 0, "Vif bits : 0x%08x", route->vifBits); + my_log( LOG_DEBUG, 0, "Vif bits : 0x%08x", route->vifBits ); mrDesc.InVif = route->upstrVif; // Set the TTL's for the route descriptor... - for ( Ix = 0; (Dp = getIfByIx(Ix)); Ix++ ) { - if(Dp->state == IF_STATE_UPSTREAM) { + for ( Ix = 0; ( Dp = getIfByIx( Ix ) ); Ix++ ) { + if ( Dp->state == IF_STATE_UPSTREAM ) { continue; } - else if(BIT_TST(route->vifBits, Dp->index)) { - my_log(LOG_DEBUG, 0, "Setting TTL for Vif %d to %d", Dp->index, Dp->threshold); - mrDesc.TtlVc[ Dp->index ] = Dp->threshold; + else if ( BIT_TST( route->vifBits, Dp->index ) ) { + my_log( LOG_DEBUG, 0, "Setting TTL for Vif %d to %d", Dp->index, Dp->threshold ); + mrDesc.TtlVc[Dp->index] = Dp->threshold; } } // Do the actual Kernel route update... - if(activate) { + if ( activate ) { // Add route in kernel... addMRoute( &mrDesc ); - } else { + } + else { // Delete the route from Kernel... delMRoute( &mrDesc ); } @@ -710,53 +716,55 @@ int internUpdateKernelRoute(struct RouteTable *route, int activate) { * Debug function that writes the routing table entries * to the log. */ -void logRouteTable(const char *header) { - struct RouteTable *croute = routing_table; - unsigned rcount = 0; - - my_log(LOG_DEBUG, 0, ""); - my_log(LOG_DEBUG, 0, "Current routing table (%s):", header); - my_log(LOG_DEBUG, 0, "-----------------------------------------------------"); - if(croute==NULL) { - my_log(LOG_DEBUG, 0, "No routes in table..."); - } else { - do { - char st = 'I'; - char src[MAX_ORIGINS * 30 + 1]; - src[0] = '\0'; - - for (int i = 0; i < MAX_ORIGINS; i++) { - if (croute->originAddrs[i] == 0) { - continue; - } - st = 'A'; - sprintf(src + strlen(src), "Src%d: %s, ", i, inetFmt(croute->originAddrs[i], s1)); +void logRouteTable( const char *header ) +{ + struct RouteTable *croute = routing_table; + unsigned rcount = 0; + + my_log( LOG_DEBUG, 0, "" ); + my_log( LOG_DEBUG, 0, "Current routing table (%s):", header ); + my_log( LOG_DEBUG, 0, "-----------------------------------------------------" ); + if ( croute == NULL ) { + my_log( LOG_DEBUG, 0, "No routes in table..." ); + } + else { + do { + char st = 'I'; + char src[MAX_ORIGINS * 30 + 1]; + src[0] = '\0'; + + for ( int i = 0; i < MAX_ORIGINS; i++ ) { + if ( croute->originAddrs[i] == 0 ) { + continue; } + st = 'A'; + sprintf( src + strlen( src ), "Src%d: %s, ", i, inetFmt( croute->originAddrs[i], s1 ) ); + } - my_log(LOG_DEBUG, 0, "#%d: %sDst: %s, Age:%d, St: %c, OutVifs: 0x%08x", - rcount, src, inetFmt(croute->group, s2), - croute->ageValue, st, - croute->vifBits); + my_log( LOG_DEBUG, 0, "#%d: %sDst: %s, Age:%d, St: %c, OutVifs: 0x%08x", rcount, src, + inetFmt( croute->group, s2 ), croute->ageValue, st, croute->vifBits ); - croute = croute->nextroute; + croute = croute->nextroute; - rcount++; - } while ( croute != NULL ); - } + rcount++; + } while ( croute != NULL ); + } - my_log(LOG_DEBUG, 0, "-----------------------------------------------------"); + my_log( LOG_DEBUG, 0, "-----------------------------------------------------" ); } /** * Returns true when the given group belongs to the given interface */ -int interfaceInRoute(int32_t group, int Ix) { - struct RouteTable* croute; - croute = findRoute(group); - if (croute != NULL) { - my_log(LOG_DEBUG, 0, "Interface id %d is in group $d", Ix, group); - return BIT_TST(croute->vifBits, Ix); - } else { +int interfaceInRoute( int32_t group, int Ix ) +{ + struct RouteTable *croute; + croute = findRoute( group ); + if ( croute != NULL ) { + my_log( LOG_DEBUG, 0, "Interface id %d is in group $d", Ix, group ); + return BIT_TST( croute->vifBits, Ix ); + } + else { return 0; } } diff --git a/src/syslog.c b/src/syslog.c index 0c718f09..a20be5ee 100644 --- a/src/syslog.c +++ b/src/syslog.c @@ -33,31 +33,76 @@ */ #include "igmpproxy.h" +#include -int LogLevel = LOG_WARNING; +int LogLevel = LOG_WARNING; bool Log2Stderr = false; -void my_log( int Severity, int Errno, const char *FmtSt, ... ) +// Prototypes +#ifdef DEVEL_LOGGING +void print_log_prefix( int Severity, const char *func, int line ); +#else +void print_log_prefix( int Severity ); +#endif + +#ifdef DEVEL_LOGGING +void __my_log( int Severity, int Errno, char *func, int line, char *FmtSt, ... ) +#else +void _my_log( int Severity, int Errno, char *FmtSt, ... ) +#endif { - char LogMsg[ 128 ]; + char LogMsg[128]; - va_list ArgPt; + va_list ArgPt; unsigned Ln; va_start( ArgPt, FmtSt ); Ln = vsnprintf( LogMsg, sizeof( LogMsg ), FmtSt, ArgPt ); - if( Errno > 0 ) - snprintf( LogMsg + Ln, sizeof( LogMsg ) - Ln, - "; Errno(%d): %s", Errno, strerror(Errno) ); + if ( Errno > 0 ) + snprintf( LogMsg + Ln, sizeof( LogMsg ) - Ln, "; Errno(%d): %s", Errno, strerror( Errno ) ); va_end( ArgPt ); - if (Severity <= LogLevel) { - if (Log2Stderr) - fprintf(stderr, "%s\n", LogMsg); - else { - syslog(Severity, "%s", LogMsg); + if ( Severity <= LogLevel ) { + if ( Log2Stderr ) { + +#ifdef DEVEL_LOGGING + print_log_prefix( Severity, func, line ); +#else + print_log_prefix( Severity ); +#endif + fprintf( stderr, "%s\n", LogMsg ); + } + else if ( Severity <= LOG_DEBUG ) { + // we log only known severity levels to syslog + syslog( Severity, "%s", LogMsg ); } } - if( Severity <= LOG_ERR ) + if ( Severity <= LOG_ERR ) exit( -1 ); } + +#ifdef DEVEL_LOGGING +void print_log_prefix( int Severity, char *func, int line ) +#else +void print_log_prefix( int Severity ) +#endif +{ + const char SeverityVc[][6] = { + "EMERG", "ALERT", "CRITI", "ERROR", "Warn ", "Notic", "Info ", "Debug", "Trace", "Init "}; + + const char *SeverityPt = Severity < 0 || Severity >= (int) VCMC( SeverityVc ) ? "*****" : SeverityVc[Severity]; + + struct timeval curTime; + gettimeofday( &curTime, NULL ); + int milli = curTime.tv_usec / 1000; + char currentTime[84] = ""; + strftime( currentTime, 84, "%H:%M:%S", localtime( &curTime.tv_sec ) ); + + // now we have something like: + // [Trace] 14:37,628 + fprintf( stderr, "[%5s] %s,%03d ", SeverityPt, currentTime, milli ); +#ifdef DEVEL_LOGGING + // print function_name(): + fprintf( stderr, "%s():%d: ", func, line ); +#endif +} diff --git a/src/udpsock.c b/src/udpsock.c index 218319ea..0194bd2e 100644 --- a/src/udpsock.c +++ b/src/udpsock.c @@ -46,21 +46,21 @@ * @param PeerPort - The port to connect to * */ -int openUdpSocket( uint32_t PeerInAdr, uint16_t PeerPort ) { - int Sock; +int openUdpSocket( uint32_t PeerInAdr, uint16_t PeerPort ) +{ + int Sock; struct sockaddr_in SockAdr; - if( (Sock = socket( AF_INET, SOCK_RAW, IPPROTO_IGMP )) < 0 ) + if ( ( Sock = socket( AF_INET, SOCK_RAW, IPPROTO_IGMP ) ) < 0 ) my_log( LOG_ERR, errno, "UDP socket open" ); memset( &SockAdr, 0, sizeof( SockAdr ) ); SockAdr.sin_family = AF_INET; - SockAdr.sin_port = htons(PeerPort); - SockAdr.sin_addr.s_addr = htonl(PeerInAdr); + SockAdr.sin_port = htons( PeerPort ); + SockAdr.sin_addr.s_addr = htonl( PeerInAdr ); - if( bind( Sock, (struct sockaddr *)&SockAdr, sizeof( SockAdr ) ) ) + if ( bind( Sock, (struct sockaddr *) &SockAdr, sizeof( SockAdr ) ) ) my_log( LOG_ERR, errno, "UDP socket bind" ); return Sock; } -