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; }
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; }