Exemplo n.º 1
0
int main (int argc, char ** argv)
{
   char * ptr;
   char * str;
   FILE * f    = NULL;
   char   c;
   int    i, i2;

   hostspec_t  hostspec;


/*
    TODO:
 s   1. Redefine default filter source file (/etc/ipf.rules)
 t   2. Redefine default filter target file (/var/bee/ipf.rules.effecive)
 d   3. Redefine destination host (any)
 i   4. Redefine target interface (tun0)
 r   5. Redefine resource name (inet)
 f   6. Redefine allowed filename (/var/bee/allowed.inet)
 P   7. Redefine dest_s (NULL)
 p   8. Redefine host_s (NULL)
 m   9. Redefine filter file rsmark (#<beerules>)
 S  10. Redefine rule_s (NULL)
 R  11. Reverse in & out
 l  12. Redefine log mark(NULL)
 o  13. One rule only (to destination)
*/   

#define OPTS "s:t:d:i:r:f:P:p:m:S:Rl:oT:"

   while ((c = getopt(argc, argv, OPTS)) != -1)
   {  switch (c)
      {
      case 's':
         srcrules = optarg;
         break;
      case 't':
         dstrules = optarg;
         break;
      case 'r':
         snprintf(namebuf, sizeof(namebuf),"/var/bee/allowed.%s", optarg); 
         srchosts = namebuf;    
         break;	 
      case 'f':
         srchosts = optarg;
         break;	 
      default:
         usage(-1);
      }
   }

// 1. Load current acl

   if (strcmp(srcrules, "-") != 0)
   {  f=fopen(srcrules, "r");
      if (f==NULL)
      {  syslog(LOG_ERR, "fopen(%s): %m", srcrules);
         exit (-1);
      }
   }
   else f = stdin;

   while(fgets(buf, sizeof(buf), f) != NULL)
   {
      ptr = buf;

      memset(&hostspec, 0, sizeof(hostspec));

//      printf("%s", ptr);

      // rule check
      str = next_token(&ptr, " \t\n");   
      if (str == NULL) continue;
      if (strcmp(str, "permit") != 0) continue;

//      printf("got '%s' (permit)\n", str);

      str = next_token(&ptr, " \t\n");
      if (str == NULL) continue;
      if (strcmp(str, "ip") != 0) continue;
      
//      printf("got '%s' (ip)\n", str);

      // host/net specification
      str = next_token(&ptr, " \t\n");
      if (str == NULL) continue;
      if (strcmp(str, "host") == 0)
      {

//         printf("got '%s' (host)\n", str);

         // set host mask /32
         hostspec.bmask = 0xffffffff;
         str = next_token(&ptr, " \t\n");
         if (str == NULL) continue;
      }
      
      if (inet_pton(AF_INET, str, &(hostspec.bhost)) == 0) continue;

//      printf("got '%s' (ipaddr)\n", str);
    
      if (hostspec.bmask != 0xffffffff)
      {  
         // parse net wildcard
         str = next_token(&ptr, " \t\n");
         if (str == NULL) continue;
         if (inet_pton(AF_INET, str, &(hostspec.bmask)) == 0) continue;
         hostspec.bmask = ~hostspec.bmask;

//         printf("got '%s' (ipmask)\n", str);
      }

// attach host spec to list
      da_ins(&cnt_current, &itm_current, sizeof(*itm_current), (-1), &hostspec);
   }

   if (f != stdin) fclose(f);

// 2. Load allowed list

   if (strcmp(srchosts, "-") != 0)
   {  f=fopen(srchosts, "r");
      if (f==NULL)
      {  syslog(LOG_ERR, "open(%s): %m", srchosts);
         exit (-1);
      }
   }
   else f = stdin;

   while(fgets(buf, sizeof(buf), f) != NULL)
   {
      ptr = buf;

      memset(&hostspec, 0, sizeof(hostspec));

      str = next_token(&ptr, " \t\n");
      if (str == NULL) continue;

      if (make_addrandmask(str, &hostspec.bhost, &hostspec.bmask) < 0) continue;

// attach host spec to list
      da_ins(&cnt_allow, &itm_allow, sizeof(*itm_allow), (-1), &hostspec);
   }

   if (f != stdin) fclose(f);

// 3. Sort current acl

   da_bsort(&cnt_current, &itm_current, sizeof(*itm_current), ip_compare);

// 4. Sort allowed list

   da_bsort(&cnt_allow, &itm_allow, sizeof(*itm_allow), ip_compare);

// 5. Remove equal items


   i  = 0;
   i2 = 0;

   while(i < cnt_current && i2 < cnt_allow)
   {
      if (itm_current[i].bhost == itm_allow[i2].bhost &&
          itm_current[i].bmask == itm_allow[i2].bmask)
      {
          da_rm(&cnt_current, &itm_current, sizeof(*itm_current), i,  NULL);
          da_rm(&cnt_allow,   &itm_allow,   sizeof(*itm_allow),   i2, NULL);
          continue;   
      }

      if (ip_compare(itm_current+i, itm_allow+i2)) i2++;
      else i++;
   }


// 6. Generate additon commands from allow list remains
   
   if (strcmp(dstrules, "-") != 0)
   {  f = fopen(dstrules, "w");
      if (f == NULL)
      {  syslog(LOG_ERR, "fopen(%s): %m", dstrules);
         exit (-1);
      }
   }
   else f = stdout;

   for (i=0; i < cnt_allow; i++)
   {
      hostspec = itm_allow[i];
      hostspec.bmask = ~hostspec.bmask;

      fprintf(f, " %s %s %s%s\n",
	head_add,
        inet_ntop(AF_INET, &hostspec.bhost, addrbuf1, sizeof(addrbuf1)),
        inet_ntop(AF_INET, &hostspec.bmask, addrbuf2, sizeof(addrbuf2)),
        tail_add ? tail_add : "" );
   }

// 7. Generate removal commands from current list remains

   for (i=0; i < cnt_current; i++)
   {
      hostspec = itm_current[i];
      hostspec.bmask = ~hostspec.bmask;

      fprintf(f, " %s %s %s%s\n",
	head_rm,
        inet_ntop(AF_INET, &hostspec.bhost, addrbuf1, sizeof(addrbuf1)),
        inet_ntop(AF_INET, &hostspec.bmask, addrbuf2, sizeof(addrbuf2)),
        tail_rm ? tail_rm : "" );
   }

   if (f != stdout) fclose(f);

   return 0; 
}
Exemplo n.º 2
0
int main(int argc, char ** argv)
{
   FILE      * f  = stdin;
#ifdef SQLSTAT_HACK
   FILE      * of = NULL;
#endif /* SQLSTAT_HACK */
   char      * str;
   char      * p;
   char      * p2;
   char      * msg;
   u_int       from;
   u_int       to;
   u_int       count;
   int         fromport;
   int         toport;
   int         proto;
   char        c;
//   int         n;
   int         i;
   int         rc;
   int         flag_from;
   int         flag_to;

   exclitem_t  exclusion;
   accsum_t    statitem;

   time_t      curtime;
   struct tm   stm;

/*
 r  1. Redefine resource name
 a  2. Redefine daemon address
 A  3. Redefine daemon port
 u  4. Send update command to billing switch
 n  5. Exclude dest address
 N  6. Include dest address
 l  7. Lock database (undesirable)
*/

// Prepare timestampt for output file
   curtime = time(NULL) - 300;
   localtime_r(&curtime, &stm);

// Load bee config
   rc = conf_load(NULL);
   if (rc < 0)
   {  fprintf(stderr, "ERROR - Configuration loading failure\n");
      exit(-1);
   }
   host = conf_coreaddr;
   port = conf_coreport;

   while ((c = getopt(argc, argv, OPTS)) != -1)
   {  switch (c)
      {  case 'r':            // resorce name
            resname = optarg;
            break;

         case 'a':            // core address
            host = optarg;
            break;

         case 'A':            // core tcp port
            port = strtol(optarg, NULL, 10);
            break;

         case 'u':            // send update command flag
            fUpdate = 1;
            break;

         case 'n':
         case 'N':
	    if (cnt_exclist < EXCLUSIONS) 
            {  bzero(&exclusion, sizeof(exclusion));

               rc = make_addrandmask (optarg, &(exclusion.addr), &(exclusion.mask));
               if (rc < 0)
               {  fprintf(stderr, "ERROR - Exclusion \"-%c %s\" parse error\n", 
                          c, optarg);
                  break;
               }

               if (c == 'N') exclusion.flag = ITMF_COUNT;

               rc = da_ins(&cnt_exclist, &itm_exclist, sizeof(*itm_exclist), (-1), &exclusion);
               if (rc < 0)
               {  fprintf(stderr, "ERROR - Exclusion \"-%c %s\" system error\n",
                          c, optarg);
               }
            }
            else
            {  fprintf(stderr, "ERROR - Overflow, exclusion \"-%c %s\" skipped\n",
                       c, optarg);
               break;
            }
            break;

         case 'l':
            fLock = 1;
            break;

         case 'f':
            filename = optarg;
            break;

         case 'o':
            outfile = optarg;
            break;

         case 'c':
            fCnupm = !fCnupm;
            break;

         default:
            usage(-1);
      }
   }

#ifdef SQLSTAT_HACK
// Open output file if any given (ignore error)
   if (outfile != NULL) of = fopen(outfile, "a");
#endif /* SQLSTAT_HACK */



/*
// Load gates
   rc = reslinks_load (LOCK_SH);
   if (rc < 0)
   {  fprintf(stderr, "ERROR - Gates loading failure\n");
      exit(-1);  
   }
*/

// Open input file (if any)
   if (filename != NULL)
   {  f = fopen(filename, "r");
      if (f == NULL)
      {  fprintf(stderr, "ERROR - Unable to open input \"%s\"\n", filename);
         exit(-1);  
      }
   }

// Insert single stats item
   statitem.addr = 0;
   statitem.in   = 0;
   statitem.out  = 0;

   da_ins(&cnt_statlist, &itm_statlist, sizeof(*itm_statlist), (-1), &statitem);

// Input parse cycle
   while (fgets(buf, sizeof(buf), f))
   {

#ifdef DUMP_JOB
      fprintf(stderr, "STR: %s", buf);
#endif

      if (!(p = strchr(buf, '\n')))     // long line
      {
#ifdef DUMP_JOB
         fprintf(stderr, "\n");         // appending "\n"
#endif
         fprintf(stderr, "line too long: %s\n", buf);
         continue; 
      }

      if (*buf > '9' || *buf < '0')     // if first char is not digit
      {
#ifdef DUMP_JOB
         fprintf(stderr, "SKIPPED - header\n");
#endif
         continue;  // skip header lines
      }

      str = buf;

      if (fCnupm != 0)
      {  p = next_token(&str, IPFSTAT_DELIM);  // start date (skip)
         if (p == NULL) continue;
         p = next_token(&str, IPFSTAT_DELIM);  // start time (skip)
         if (p == NULL) continue;
      }

      p = next_token(&str, IPFSTAT_DELIM);     // from addr
      if (p == NULL) continue;
      p2 = next_token(&p, ":");
      if (p2 == NULL) continue;      
      rc = inet_pton(AF_INET, p2, &from); 
      if (rc < 0) continue;

      fromport = (-1);
      if (fCnupm)                         // from port (cnupm only)
      {  p2 = next_token(&p, ":");
         if (p2 != NULL)
         {  fromport = strtol(p2, NULL, 10);
         } 
      }

      p = next_token(&str, IPFSTAT_DELIM);     // to addr
      if (p == NULL) continue;
      p2 = next_token(&p, ":");
      if (p2 == NULL) continue;
      rc = inet_pton(AF_INET, p2, &to);
      if (rc < 0) continue;

      toport = (-1);
      if (fCnupm)                         // to port (cnupm only)
      {  p2 = next_token(&p, ":");
         if (p2 != NULL)
         {  toport = strtol(p2, NULL, 10);
         }
      }

      proto = (-1);
      p = next_token(&str, IPFSTAT_DELIM);     // packets/proto
      if (p == NULL) continue;
      if (fCnupm != 0)
      {  proto = strtol(p, NULL, 10);
      }

      p = next_token(&str, IPFSTAT_DELIM);     // bytes
      if (p == NULL) continue;
      count = strtoul(p, NULL, 10);

      if (count == 0) continue;

// Filter excluded traffic (i.e. excluded to excluded)

      flag_to   = 1;   // i.e. global by default
      flag_from = 1;

      for (i=0; i < cnt_exclist; i++)
      {  if ((to   & itm_exclist[i].mask) == itm_exclist[i].addr)
            flag_to   = (itm_exclist[i].flag & ITMF_COUNT) != 0;
         if ((from & itm_exclist[i].mask) == itm_exclist[i].addr)
            flag_from = (itm_exclist[i].flag & ITMF_COUNT) != 0;
      }
      if (flag_to == flag_from)
      {
#ifdef DUMP_JOB
         fprintf(stderr, "LOCAL -  %s -> %s\n", 
             inet_ntop(AF_INET, &from, addrbuf, sizeof(addrbuf)),
             inet_ntop(AF_INET, &to, addrbuf2, sizeof(addrbuf2)));
#endif
         continue;
      }

// Fill stat item
      if (flag_from == 0)
      {  statitem.addr = from;
         statitem.in   = 0;
         statitem.out  = count;
      }
      else
      {  statitem.addr = to;
         statitem.in   = count;
         statitem.out  = 0;
      }

#ifdef SQLSTAT_HACK
// Write filtered data to output file
      if (of != NULL)
      {  fprintf(of, "SELECT add_traffstat('%04d-%02d-%02d %02d:00:00', ", 
                     stm.tm_year + 1900,
                     stm.tm_mon + 1,
                     stm.tm_mday,
                     stm.tm_hour);
         fprintf(of, "'%s', ", inet_ntop(AF_INET, (flag_from ? &from : &to), addrbuf, sizeof(addrbuf)));
         fprintf(of, "'%s', ", inet_ntop(AF_INET, (flag_from ? &to : &from), addrbuf, sizeof(addrbuf)));
         if (flag_from) 
            fprintf(of, "0, %ld);\n", count);
         else
            fprintf(of, "%ld, 0);\n", count);    
      }
#endif /* SQLSTAT_HACK */

// Append to stats
         itm_statlist[0].in  += statitem.in;
         itm_statlist[0].out += statitem.out;
#ifdef DUMP_JOB
         fprintf(stderr, "APPENDED\n");
#endif
   } // Input parse cycle
   
// Send counts onto core   

#ifdef DUMP_JOB
   fprintf(stderr, "NEW SESSION\n");
#endif

   rc = link_request(&lnk, host, port);
   if (rc == -1)
   {  fprintf(stderr, "Can't connect to billing service (%s:%d): %s", host, port,
                 strerror(errno));
      exit(-1);
   }
#ifdef DUMP_JOB
   fprintf(stderr, "CONNECTING BEE\n");
#endif

   rc = answait(&lnk, RET_SUCCESS, linbuf, sizeof(linbuf), &msg);

#ifdef DUMP_JOB
   fprintf(stderr, "BEE: %03d\n", rc);
#endif

   if (rc != RET_SUCCESS)
   {  if (rc == LINK_DOWN) fprintf(stderr, "Unexpected link down\n");
      if (rc == LINK_ERROR) perror("Link error");
      if (rc >= 400) fprintf(stderr, "Billing error : %s\n", msg);
      exit(-1);
   }

#ifdef DUMP_JOB
   fprintf(stderr, "machine\n");
#endif

   link_puts(&lnk, "machine");
   rc = answait(&lnk, RET_SUCCESS, linbuf, sizeof(linbuf), &msg);

#ifdef DUMP_JOB
   fprintf(stderr, "BEE: %03d\n", rc);
#endif

   if (rc != RET_SUCCESS)
   {  if (rc == LINK_DOWN) fprintf(stderr, "Unexpected link down\n");
      if (rc == LINK_ERROR) perror("Link error");
      if (rc >= 400) fprintf(stderr, "Billing error : %s\n", msg);
      exit(-1);
   }

   if (fLock)
   {
#ifdef DUMP_JOB
      fprintf(stderr, "lock\n");
#endif

      link_puts(&lnk, "lock");
      rc = answait(&lnk, RET_SUCCESS, linbuf, sizeof(linbuf), &msg);

#ifdef DUMP_JOB
      fprintf(stderr, "BEE: %03d\n", rc);
#endif

      if (rc != RET_SUCCESS)
      {  if (rc == LINK_DOWN) fprintf(stderr, "Unexpected link down\n");
         if (rc == LINK_ERROR) perror("Link error");
         if (rc >= 400) fprintf(stderr, "Billing error : %s\n", msg);
         exit(-1);
      }
   }

   for (i=0; i < cnt_statlist; i++)
   {  
      inet_ntop(AF_INET, &(itm_statlist[i].addr), addrbuf, sizeof(addrbuf));

#ifdef DUMP_JOB
      fprintf(stderr, "ITEM: %s in:%d out:%d\n", addrbuf,
              itm_statlist[i].in, itm_statlist[i].out);
#endif

      if (itm_statlist[i].in  != 0)
      {  snprintf(buf, sizeof(buf), "res %s %s %u %u %s", resname,
                   addrbuf, itm_statlist[i].in, 0, addrbuf);  
#ifdef DUMP_JOB
         fprintf(stderr, "CMD: %s\n", buf);
#endif
         link_puts(&lnk, "%s", buf);

         rc = answait(&lnk, RET_SUCCESS, linbuf, sizeof(linbuf), &msg);
#ifdef DUMP_JOB
         fprintf(stderr, "BEE: %03d\n", rc);
#endif
         if (rc != RET_SUCCESS)
         {  if (rc == LINK_DOWN)
            {  fprintf(stderr, "Unexpected link down\n");
               exit(-1);
            }
            if (rc == LINK_ERROR) perror("Link error");
            if (rc >= 400) fprintf(stderr, "Billing error (%d): %s "
                                           "(%s)\n",
                                           rc, msg, addrbuf);
         }
      }

      if (itm_statlist[i].out != 0)
      {  snprintf(buf, sizeof(buf), "res %s %s %u %u %s", resname,
                   addrbuf, itm_statlist[i].out, 0x80000000, addrbuf);  
#ifdef DUMP_JOB
         fprintf(stderr, "CMD: %s\n", buf);
#endif
         link_puts(&lnk, "%s", buf);

         rc = answait(&lnk, RET_SUCCESS, linbuf, sizeof(linbuf), &msg);
#ifdef DUMP_JOB
         fprintf(stderr, "BEE: %03d\n", rc);
#endif
         if (rc != RET_SUCCESS)
         {  if (rc == LINK_DOWN)
            {  fprintf(stderr, "Unexpected link down\n");
               exit(-1);
            }
            if (rc == LINK_ERROR) perror("Link error");
            if (rc >= 400) fprintf(stderr, "Billing error (%d): %s "
                                           "(%s)\n",
                                           rc, msg, addrbuf);
         }
      }
   }

#ifdef DUMP_JOB
fprintf(stderr, "TERMINATING\n");
#endif
   if (fUpdate)
   {  link_puts(&lnk, "update");
      rc=answait(&lnk, RET_SUCCESS, linbuf, sizeof(linbuf), &msg);
      if (rc != RET_SUCCESS)
      {  if (rc == LINK_DOWN) fprintf(stderr, "Unexpected link down\n");
         if (rc == LINK_ERROR) perror("Link error");
         if (rc >= 400) fprintf(stderr, "Billing error : %s\n", msg);
         exit(-1);
      }
   }

   link_puts (&lnk, "exit");
   link_close(&lnk);

   return 0;
}