Annotation of embedaddon/igmpproxy/src/config.c, revision 1.1
1.1 ! misho 1: /*
! 2: ** igmpproxy - IGMP proxy based multicast router
! 3: ** Copyright (C) 2005 Johnny Egeland <johnny@rlo.org>
! 4: **
! 5: ** This program is free software; you can redistribute it and/or modify
! 6: ** it under the terms of the GNU General Public License as published by
! 7: ** the Free Software Foundation; either version 2 of the License, or
! 8: ** (at your option) any later version.
! 9: **
! 10: ** This program is distributed in the hope that it will be useful,
! 11: ** but WITHOUT ANY WARRANTY; without even the implied warranty of
! 12: ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
! 13: ** GNU General Public License for more details.
! 14: **
! 15: ** You should have received a copy of the GNU General Public License
! 16: ** along with this program; if not, write to the Free Software
! 17: ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
! 18: **
! 19: **----------------------------------------------------------------------------
! 20: **
! 21: ** This software is derived work from the following software. The original
! 22: ** source code has been modified from it's original state by the author
! 23: ** of igmpproxy.
! 24: **
! 25: ** smcroute 0.92 - Copyright (C) 2001 Carsten Schill <carsten@cschill.de>
! 26: ** - Licensed under the GNU General Public License, version 2
! 27: **
! 28: ** mrouted 3.9-beta3 - COPYRIGHT 1989 by The Board of Trustees of
! 29: ** Leland Stanford Junior University.
! 30: ** - Original license can be found in the Stanford.txt file.
! 31: **
! 32: */
! 33: /**
! 34: * config.c - Contains functions to load and parse config
! 35: * file, and functions to configure the daemon.
! 36: */
! 37:
! 38: #include "igmpproxy.h"
! 39:
! 40: // Structure to keep configuration for VIFs...
! 41: struct vifconfig {
! 42: char* name;
! 43: short state;
! 44: int ratelimit;
! 45: int threshold;
! 46:
! 47: // Keep allowed nets for VIF.
! 48: struct SubnetList* allowednets;
! 49:
! 50: // Next config in list...
! 51: struct vifconfig* next;
! 52: };
! 53:
! 54: // Structure to keep vif configuration
! 55: struct vifconfig* vifconf;
! 56:
! 57: // Keeps common settings...
! 58: static struct Config commonConfig;
! 59:
! 60: // Prototypes...
! 61: struct vifconfig *parsePhyintToken();
! 62: struct SubnetList *parseSubnetAddress(char *addrstr);
! 63:
! 64:
! 65: /**
! 66: * Initializes common config..
! 67: */
! 68: void initCommonConfig() {
! 69: commonConfig.robustnessValue = DEFAULT_ROBUSTNESS;
! 70: commonConfig.queryInterval = INTERVAL_QUERY;
! 71: commonConfig.queryResponseInterval = INTERVAL_QUERY_RESPONSE;
! 72:
! 73: // The defaults are calculated from other settings.
! 74: commonConfig.startupQueryInterval = (unsigned int)(INTERVAL_QUERY / 4);
! 75: commonConfig.startupQueryCount = DEFAULT_ROBUSTNESS;
! 76:
! 77: // Default values for leave intervals...
! 78: commonConfig.lastMemberQueryInterval = INTERVAL_QUERY_RESPONSE;
! 79: commonConfig.lastMemberQueryCount = DEFAULT_ROBUSTNESS;
! 80:
! 81: // If 1, a leave message is sent upstream on leave messages from downstream.
! 82: commonConfig.fastUpstreamLeave = 0;
! 83:
! 84: }
! 85:
! 86: /**
! 87: * Returns a pointer to the common config...
! 88: */
! 89: struct Config *getCommonConfig() {
! 90: return &commonConfig;
! 91: }
! 92:
! 93: /**
! 94: * Loads the configuration from file, and stores the config in
! 95: * respective holders...
! 96: */
! 97: int loadConfig(char *configFile) {
! 98: struct vifconfig *tmpPtr;
! 99: struct vifconfig **currPtr = &vifconf;
! 100: char *token;
! 101:
! 102: // Initialize common config
! 103: initCommonConfig();
! 104:
! 105: // Test config file reader...
! 106: if(!openConfigFile(configFile)) {
! 107: my_log(LOG_ERR, 0, "Unable to open configfile from %s", configFile);
! 108: }
! 109:
! 110: // Get first token...
! 111: token = nextConfigToken();
! 112: if(token == NULL) {
! 113: my_log(LOG_ERR, 0, "Config file was empty.");
! 114: }
! 115:
! 116: // Loop until all configuration is read.
! 117: while ( token != NULL ) {
! 118: // Check token...
! 119: if(strcmp("phyint", token)==0) {
! 120: // Got a phyint token... Call phyint parser
! 121: my_log(LOG_DEBUG, 0, "Config: Got a phyint token.");
! 122: tmpPtr = parsePhyintToken();
! 123: if(tmpPtr == NULL) {
! 124: // Unparsable token... Exit...
! 125: closeConfigFile();
! 126: my_log(LOG_WARNING, 0, "Unknown token '%s' in configfile", token);
! 127: return 0;
! 128: } else {
! 129:
! 130: my_log(LOG_DEBUG, 0, "IF name : %s", tmpPtr->name);
! 131: my_log(LOG_DEBUG, 0, "Next ptr : %x", tmpPtr->next);
! 132: my_log(LOG_DEBUG, 0, "Ratelimit : %d", tmpPtr->ratelimit);
! 133: my_log(LOG_DEBUG, 0, "Threshold : %d", tmpPtr->threshold);
! 134: my_log(LOG_DEBUG, 0, "State : %d", tmpPtr->state);
! 135: my_log(LOG_DEBUG, 0, "Allowednet ptr : %x", tmpPtr->allowednets);
! 136:
! 137: // Insert config, and move temppointer to next location...
! 138: *currPtr = tmpPtr;
! 139: currPtr = &tmpPtr->next;
! 140: }
! 141: }
! 142: else if(strcmp("quickleave", token)==0) {
! 143: // Got a quickleave token....
! 144: my_log(LOG_DEBUG, 0, "Config: Quick leave mode enabled.");
! 145: commonConfig.fastUpstreamLeave = 1;
! 146:
! 147: // Read next token...
! 148: token = nextConfigToken();
! 149: continue;
! 150: } else {
! 151: // Unparsable token... Exit...
! 152: closeConfigFile();
! 153: my_log(LOG_WARNING, 0, "Unknown token '%s' in configfile", token);
! 154: return 0;
! 155: }
! 156: // Get token that was not recognized by phyint parser.
! 157: token = getCurrentConfigToken();
! 158: }
! 159:
! 160: // Close the configfile...
! 161: closeConfigFile();
! 162:
! 163: return 1;
! 164: }
! 165:
! 166: /**
! 167: * Appends extra VIF configuration from config file.
! 168: */
! 169: void configureVifs() {
! 170: unsigned Ix;
! 171: struct IfDesc *Dp;
! 172: struct vifconfig *confPtr;
! 173:
! 174: // If no config is availible, just return...
! 175: if(vifconf == NULL) {
! 176: return;
! 177: }
! 178:
! 179: // Loop through all VIFs...
! 180: for ( Ix = 0; (Dp = getIfByIx(Ix)); Ix++ ) {
! 181: if ( Dp->InAdr.s_addr && ! (Dp->Flags & IFF_LOOPBACK) ) {
! 182:
! 183: // Now try to find a matching config...
! 184: for( confPtr = vifconf; confPtr; confPtr = confPtr->next) {
! 185:
! 186: // I the VIF names match...
! 187: if(strcmp(Dp->Name, confPtr->name)==0) {
! 188: struct SubnetList *vifLast;
! 189:
! 190: my_log(LOG_DEBUG, 0, "Found config for %s", Dp->Name);
! 191:
! 192:
! 193: // Set the VIF state
! 194: Dp->state = confPtr->state;
! 195:
! 196: Dp->threshold = confPtr->threshold;
! 197: Dp->ratelimit = confPtr->ratelimit;
! 198:
! 199: // Go to last allowed net on VIF...
! 200: for(vifLast = Dp->allowednets; vifLast->next; vifLast = vifLast->next);
! 201:
! 202: // Insert the configured nets...
! 203: vifLast->next = confPtr->allowednets;
! 204:
! 205: break;
! 206: }
! 207: }
! 208: }
! 209: }
! 210: }
! 211:
! 212:
! 213: /**
! 214: * Internal function to parse phyint config
! 215: */
! 216: struct vifconfig *parsePhyintToken() {
! 217: struct vifconfig *tmpPtr;
! 218: struct SubnetList **anetPtr;
! 219: char *token;
! 220: short parseError = 0;
! 221:
! 222: // First token should be the interface name....
! 223: token = nextConfigToken();
! 224:
! 225: // Sanitycheck the name...
! 226: if(token == NULL) return NULL;
! 227: if(strlen(token) >= IF_NAMESIZE) return NULL;
! 228: my_log(LOG_DEBUG, 0, "Config: IF: Config for interface %s.", token);
! 229:
! 230: // Allocate memory for configuration...
! 231: tmpPtr = (struct vifconfig*)malloc(sizeof(struct vifconfig));
! 232: if(tmpPtr == NULL) {
! 233: my_log(LOG_ERR, 0, "Out of memory.");
! 234: }
! 235:
! 236: // Set default values...
! 237: tmpPtr->next = NULL; // Important to avoid seg fault...
! 238: tmpPtr->ratelimit = 0;
! 239: tmpPtr->threshold = 1;
! 240: tmpPtr->state = IF_STATE_DOWNSTREAM;
! 241: tmpPtr->allowednets = NULL;
! 242:
! 243: // Make a copy of the token to store the IF name
! 244: tmpPtr->name = strdup( token );
! 245: if(tmpPtr->name == NULL) {
! 246: my_log(LOG_ERR, 0, "Out of memory.");
! 247: }
! 248:
! 249: // Set the altnet pointer to the allowednets pointer.
! 250: anetPtr = &tmpPtr->allowednets;
! 251:
! 252: // Parse the rest of the config..
! 253: token = nextConfigToken();
! 254: while(token != NULL) {
! 255: if(strcmp("altnet", token)==0) {
! 256: // Altnet...
! 257: token = nextConfigToken();
! 258: my_log(LOG_DEBUG, 0, "Config: IF: Got altnet token %s.",token);
! 259:
! 260: *anetPtr = parseSubnetAddress(token);
! 261: if(*anetPtr == NULL) {
! 262: parseError = 1;
! 263: my_log(LOG_WARNING, 0, "Unable to parse subnet address.");
! 264: break;
! 265: } else {
! 266: anetPtr = &(*anetPtr)->next;
! 267: }
! 268: }
! 269: else if(strcmp("upstream", token)==0) {
! 270: // Upstream
! 271: my_log(LOG_DEBUG, 0, "Config: IF: Got upstream token.");
! 272: tmpPtr->state = IF_STATE_UPSTREAM;
! 273: }
! 274: else if(strcmp("downstream", token)==0) {
! 275: // Downstream
! 276: my_log(LOG_DEBUG, 0, "Config: IF: Got downstream token.");
! 277: tmpPtr->state = IF_STATE_DOWNSTREAM;
! 278: }
! 279: else if(strcmp("disabled", token)==0) {
! 280: // Disabled
! 281: my_log(LOG_DEBUG, 0, "Config: IF: Got disabled token.");
! 282: tmpPtr->state = IF_STATE_DISABLED;
! 283: }
! 284: else if(strcmp("ratelimit", token)==0) {
! 285: // Ratelimit
! 286: token = nextConfigToken();
! 287: my_log(LOG_DEBUG, 0, "Config: IF: Got ratelimit token '%s'.", token);
! 288: tmpPtr->ratelimit = atoi( token );
! 289: if(tmpPtr->ratelimit < 0) {
! 290: my_log(LOG_WARNING, 0, "Ratelimit must be 0 or more.");
! 291: parseError = 1;
! 292: break;
! 293: }
! 294: }
! 295: else if(strcmp("threshold", token)==0) {
! 296: // Threshold
! 297: token = nextConfigToken();
! 298: my_log(LOG_DEBUG, 0, "Config: IF: Got threshold token '%s'.", token);
! 299: tmpPtr->threshold = atoi( token );
! 300: if(tmpPtr->threshold <= 0 || tmpPtr->threshold > 255) {
! 301: my_log(LOG_WARNING, 0, "Threshold must be between 1 and 255.");
! 302: parseError = 1;
! 303: break;
! 304: }
! 305: }
! 306: else {
! 307: // Unknown token. Break...
! 308: break;
! 309: }
! 310: token = nextConfigToken();
! 311: }
! 312:
! 313: // Clean up after a parseerror...
! 314: if(parseError) {
! 315: free(tmpPtr);
! 316: tmpPtr = NULL;
! 317: }
! 318:
! 319: return tmpPtr;
! 320: }
! 321:
! 322: /**
! 323: * Parses a subnet address string on the format
! 324: * a.b.c.d/n into a SubnetList entry.
! 325: */
! 326: struct SubnetList *parseSubnetAddress(char *addrstr) {
! 327: struct SubnetList *tmpSubnet;
! 328: char *tmpStr;
! 329: uint32_t addr = 0x00000000;
! 330: uint32_t mask = 0xFFFFFFFF;
! 331:
! 332: // First get the network part of the address...
! 333: tmpStr = strtok(addrstr, "/");
! 334: addr = inet_addr(tmpStr);
! 335:
! 336: tmpStr = strtok(NULL, "/");
! 337: if(tmpStr != NULL) {
! 338: int bitcnt = atoi(tmpStr);
! 339: if(bitcnt <= 0 || bitcnt > 32) {
! 340: my_log(LOG_WARNING, 0, "The bits part of the address is invalid : %d.",tmpStr);
! 341: return NULL;
! 342: }
! 343:
! 344: mask <<= (32 - bitcnt);
! 345: }
! 346:
! 347: if(addr == -1 || addr == 0) {
! 348: my_log(LOG_WARNING, 0, "Unable to parse address token '%s'.", addrstr);
! 349: return NULL;
! 350: }
! 351:
! 352: tmpSubnet = (struct SubnetList*) malloc(sizeof(struct SubnetList));
! 353: tmpSubnet->subnet_addr = addr;
! 354: tmpSubnet->subnet_mask = ntohl(mask);
! 355: tmpSubnet->next = NULL;
! 356:
! 357: my_log(LOG_DEBUG, 0, "Config: IF: Altnet: Parsed altnet to %s.",
! 358: inetFmts(tmpSubnet->subnet_addr, tmpSubnet->subnet_mask,s1));
! 359:
! 360: return tmpSubnet;
! 361: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>