Logo Search packages:      
Sourcecode: net-acct version File versions  Download package

config.c

/* 
 * Network accounting
 * config.c - configuration module
 * (C) 1994 Ulrich Callmeier
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "netacct.h"

char *rcs_revision_config_c = "$Revision: 1.14 $";

/* 
 * This routine reads all the configuration from the file fname.
 * On success it returns a non-NULL pointer to a struct config.
 * The parser is kind of a hack but it works.
 */

struct config *read_config(char *fname)
{
    char buff[1024];
    FILE *f;
    int line=0;
    struct config *cfg = malloc(sizeof(struct config));
    if(cfg == NULL) return cfg;

    cfg -> filename = NULL;
    cfg -> dumpname = NULL;
    cfg -> debugname = NULL;
    cfg -> flush = DEFAULT_FLUSH;
    cfg -> ignoremask = inet_addr(DEFAULT_IGNOREMASK);
    cfg -> err_delay = DEFAULT_ERR_DELAY;
    cfg -> ignorenet = NULL;
    cfg -> dontignore = NULL;
    cfg -> promisc = NULL;
    cfg -> notdev = NULL;
    cfg -> fdelay = DEFAULT_FDELAY;
    cfg -> disabled = 0;
    cfg -> dynamicip = NULL;
    cfg -> excludenamelookup = NULL;
    cfg -> headers = NULL;
    cfg -> hostlist = NULL;
    cfg -> iflist = NULL;
#ifdef REMAP_MASQUERADE
    cfg -> masqif = 0;
#endif

    debug_level = 0;
    dev2line = NULL;

    f=fopen(fname,"r");
    if(f == NULL) return NULL;

    while(fgets(buff,sizeof(buff),f))
      {
          /* remove trailing newline */
          char *cmt = strchr(buff,'\n');
          if(cmt) *cmt = '\0';

          line++;
          
          /* remove comments */
          cmt = strchr(buff,'#');
          if(cmt) *cmt = '\0';
          
          /* remove leading whitespace */
          while(isspace(*buff))
            {
                memmove(buff,buff+1,strlen(buff));
            }

          /* remove trailing whitespace */
          cmt = strchr(buff,'\0');
          cmt --;
          while(isspace(*cmt))
            {
                *cmt = '\0';
                cmt --;
            }

          /* process nonempty lines */
          if(*buff)
            {
                char *kwd = buff;
                char *value = buff + strcspn(buff," \t");
                *value++ = '\0';
                while(isspace(*value)) value++;

#if DBG               
                printf("key: \"%s\" value: \"%s\" \n",kwd, value);
#endif
                
                if(strcasecmp(kwd, "flush")==0)
                  {
                      cfg->flush = atoi(value);
                      syslog(LOG_DEBUG,"config: set flushing to %d\n",cfg->flush);
                  }
                else if(strcasecmp(kwd, "fdelay")==0)
                  {
                      cfg->fdelay = atoi(value);
                      syslog(LOG_DEBUG,"config: set fdelay to %d\n",cfg->fdelay);
                  }
                else if(strcasecmp(kwd, "file")==0)
                  {
                      cfg->filename = strdup(value);
                      syslog(LOG_DEBUG,"config: set filename to %s\n",cfg->filename);
                  }
                else if(strcasecmp(kwd, "dumpfile")==0)
                  {
                      cfg->dumpname = strdup(value);
                      syslog(LOG_DEBUG,"config: set dumpfile to %s\n",cfg->dumpname);
                  }
                else if(strcasecmp(kwd, "debugfile")==0)
                  {
                      cfg->debugname = strdup(value);
                      syslog(LOG_DEBUG,"config: set debugfile to %s\n",cfg->debugname);
                  }
                else if(strcasecmp(kwd, "dynamicip")==0)
                  {
                    if(value[strlen(value)-1]=='/') value[strlen(value)-1]='\0';
                    cfg->dynamicip = strdup(value);
                    syslog(LOG_DEBUG,"config: set dynamicip to %s\n",cfg->dynamicip);
                  }
                else if(strcasecmp(kwd, "ignoremask")==0)
                  {
                      cfg->ignoremask = inet_addr(value);
                      syslog(LOG_DEBUG,"config: set ignoremask to %s\n",intoa(cfg->ignoremask));
                  }
                else if(strcasecmp(kwd, "debug")==0)
                  {
                      debug_level = atoi(value);
                      syslog(LOG_DEBUG,"config: set debugging level to %d\n",debug_level);
                  }
                else if(strcasecmp(kwd, "disable")==0)
                  {
                    int field;
                    field = atoi(value);
                    if((field < MIN_DISABLE) || (field > MAX_DISABLE))
                      {
                        syslog(LOG_ERR, "config file: invalid disable statement\n");
                        return NULL;
                      }
                    else
                      {
                        cfg->disabled |= BITMASK(field);
                        syslog(LOG_DEBUG,"config: disabled field %d\n",field);
                      }
                  }
                else if(strcasecmp(kwd, "ignorenet")==0)
                  {
                      struct ipnetwork *tmp;
                      char *mask;

                      mask  = value + strcspn(value," \t");
                      *mask++ = '\0';
                      while(isspace(*mask)) mask++;

                      tmp = malloc(sizeof(struct ipnetwork));
                      
                      if(tmp != NULL)
                        {
                            tmp -> netnumber = inet_addr(value);
                            tmp -> netmask = inet_addr(mask);
                            tmp -> next = cfg -> ignorenet;
                            cfg -> ignorenet = tmp;
                            syslog(LOG_DEBUG,
                                 "config: added ignore network (netnumber %s)\n",
                                 intoa(cfg -> ignorenet -> netnumber));
                            syslog(LOG_DEBUG,
                                 "config: added ignore network (netmask %s)\n",
                                 intoa(cfg -> ignorenet -> netmask));
                        }
                  }
                else if(strcasecmp(kwd, "exclude-name-lookup")==0)
                  {
                      struct ipnetwork *tmp;
                      char *mask;

                      mask  = value + strcspn(value," \t");
                      *mask++ = '\0';
                      while(isspace(*mask)) mask++;

                      tmp = malloc(sizeof(struct ipnetwork));
                      
                      if(tmp != NULL)
                        {
                            tmp -> netnumber = inet_addr(value);
                            tmp -> netmask = inet_addr(mask);
                            tmp -> next = cfg -> excludenamelookup;
                            cfg -> excludenamelookup = tmp;
                            syslog(LOG_DEBUG,
                                 "config: added exclude-name-lookup network (netnumber %s)\n",
                                 intoa(cfg -> excludenamelookup -> netnumber));
                            syslog(LOG_DEBUG,
                                 "config: added exclude-name-lookup network (netmask %s)\n",
                                 intoa(cfg -> excludenamelookup -> netmask));
                        }
                  }
                else if(strcasecmp(kwd, "dynamicnet")==0)
                  {
                      char *mask;

                      mask  = value + strcspn(value," \t");
                      *mask++ = '\0';
                      while(isspace(*mask)) mask++;

                      cfg -> dynamicnet.netnumber = inet_addr(value);
                      cfg -> dynamicnet.netmask = inet_addr(mask);
                      syslog(LOG_DEBUG,
                           "config: set dynamic network (netnumber %s)\n",
                           intoa(cfg -> dynamicnet.netnumber));
                      syslog(LOG_DEBUG,
                           "config: set dynamic network (netmask %s)\n",
                           intoa(cfg -> dynamicnet.netmask));
                  }
                else if(strcasecmp(kwd, "dontignore")==0)
                  {
                      struct ipnetwork *tmp;
                      char *mask;

                      mask  = value + strcspn(value," \t");
                      *mask++ = '\0';
                      while(isspace(*mask)) mask++;

                      tmp = malloc(sizeof(struct ipnetwork));
                      
                      if(tmp != NULL)
                        {
                            tmp -> netnumber = inet_addr(value);
                            tmp -> netmask = inet_addr(mask);
                            tmp -> next = cfg -> dontignore;
                            cfg -> dontignore = tmp;
                            syslog(LOG_DEBUG,
                                 "config: added dontignore network (netnumber %s)\n",
                                 intoa(cfg -> dontignore -> netnumber));
                            syslog(LOG_DEBUG,
                                 "config: added dontignore network (netmask %s)\n",
                                 intoa(cfg -> dontignore -> netmask));
                        }
                  }
                else if(strcasecmp(kwd, "headers")==0)
                  {
                      char *offset;
                      char *type;
                      struct headerdat *tmp;

                      offset  = value + strcspn(value," \t");
                      *offset++ = '\0';
                      while(isspace(*offset)) offset++;

                      type  = offset + strcspn(offset," \t");
                      *type++ = '\0';
                      while(isspace(*type)) type++;

                      tmp = malloc(sizeof(struct headerdat));
                      
                      if(tmp != NULL)
                        {
                        tmp -> name = strdup(value);
                        tmp -> l = strlen(value);
                        tmp -> offset = atoi(offset);
                        tmp -> type = atoi(type);
                        
                        tmp -> next = cfg -> headers;
                        cfg -> headers = tmp;

                        syslog(LOG_DEBUG,
                               "config: added headerinfo (%s:%d:%d)\n",
                               tmp -> name, tmp -> offset, tmp -> type);
                        }
                  }
                else if(strcasecmp(kwd, "device")==0)
                  {
                      struct promisc_device *tmp;

                      tmp = malloc(sizeof(struct promisc_device));
                  
                      if(tmp != NULL)
                        {
                            tmp -> name  = strdup(value);
                            tmp -> reset = 0;
                            tmp -> next = cfg -> promisc;
                            cfg -> promisc = tmp;
                            syslog(LOG_DEBUG,"config: added promiscous device %s\n",
                                 cfg->promisc->name);
                        }
                  }
                else if(strcasecmp(kwd, "notdev")==0)
                  {
                      struct promisc_device *tmp;

                      tmp = malloc(sizeof(struct promisc_device));
                  
                      if(tmp != NULL)
                        {
                            tmp -> name  = strdup(value);
                            tmp -> next = cfg -> notdev;
                            cfg -> notdev = tmp;
                            syslog(LOG_DEBUG,"config: added notdevice %s\n",
                                 cfg->notdev->name);
                        }
                  }
                else if(strcasecmp(kwd, "errdelay")==0)
                  {
                      cfg->err_delay = atoi(value);
                      syslog(LOG_DEBUG,"config: set delay on error to %d\n",cfg->err_delay);
                  }
                else if(strcasecmp(kwd, "line")==0)
                  {
                      struct dev2line *tmp;
                      char *line;

                      tmp = malloc(sizeof(struct dev2line));

                      line  = value + strcspn(value," \t");
                      *line++ = '\0';
                      while(isspace(*line)) line++;

                      tmp -> netinterface = strdup(value);
                      tmp -> line = strdup(line);
                      tmp -> next = dev2line;
                      dev2line = tmp;
                      
                      syslog(LOG_DEBUG,"config: [dev2line:] %s -> %s\n",dev2line->netinterface, dev2line->line);
                  }
                else if(strcasecmp(kwd, "hostlimit")==0) {
                      unsigned char c1,c2,c3,c4;
                      unsigned long ipaddr;
                      struct mon_host_struct *tmp;
                      c1 = strtol(strtok(value,"."),0,0);
                      c2 = strtol(strtok(NULL,"."),0,0);
                      c3 = strtol(strtok(NULL,"."),0,0);
                      c4 = strtol(strtok(NULL,"."),0,0);
                      ipaddr = htonl((c1 << 24) | (c2 << 16) | (c3 << 8) | c4);
                      tmp = malloc(sizeof(struct mon_host_struct));
                      if(tmp != NULL) {
                        tmp->ipaddr = ipaddr;
                        tmp->next = cfg->hostlist;
                        cfg->hostlist = tmp;
                        syslog(LOG_DEBUG,"config: added hostlimit %s\n",intoa(cfg->hostlist->ipaddr));
                      }
                }
                else if(strcasecmp(kwd, "iflimit")==0)
                  {
                      struct promisc_device *tmp;

                      tmp = malloc(sizeof(struct promisc_device));
                  
                      if(tmp != NULL)
                        {
                            tmp -> name  = strdup(value);
                            tmp -> next = cfg -> iflist;
                            cfg -> iflist = tmp;
                            syslog(LOG_DEBUG,"config: added iflist %s\n",
                                 cfg->iflist->name);
                        }
                  }
#ifdef REMAP_MASQUERADE
                else if(strcasecmp(kwd, "masqif") == 0) {
                      cfg->masqif = inet_addr(value);
                      syslog(LOG_DEBUG, "config: set masqif to %s\n",intoa(cfg->masqif));
                    }
#endif
                else
                  {
                      syslog(LOG_ERR, "config file: unknown keyword %s in line %d\n",kwd,line);
                      return NULL;
                  }
            }
      }

    if(cfg->filename == NULL)
      {
          syslog(LOG_ERR, "config file: no filename given\n");
          return NULL;
      }

    if(cfg->dumpname == NULL)
      {
          syslog(LOG_ERR, "config file: no dumpfile given\n");
          return NULL;
      }
#ifdef linux

    if(cfg->headers == NULL)
      {
          syslog(LOG_ERR, "config file: no header information given\n");
          return NULL;
      }
#endif

    if(cfg->debugname == NULL)
      {
      syslog(LOG_INFO, "config file: no debugfile given, using /dev/null\n");
      cfg->debugname = strdup("/dev/null");
      }
    
    fclose(f);
    return cfg;
}
          

Generated by  Doxygen 1.6.0   Back to index