From 3c0b2f6a5df9d9d391b9f810abcd98f6bd2fc4d7 Mon Sep 17 00:00:00 2001 From: Peter Popovec Date: Thu, 22 Feb 2007 14:25:29 +0100 Subject: [PATCH] Initial commit --- FWcnt2rrd | 31 +++++ Makefile | 30 +++++ README | 279 ++++++++++++++++++++++++++++++++++++++++++++ README.old | 68 +++++++++++ TODO | 3 + clean_FWcnt | 10 ++ cnt2rrd.c | 309 +++++++++++++++++++++++++++++++++++++++++++++++++ cron.d | 1 + fw2rrd | Bin 0 -> 12037 bytes fw2rrd.c | 276 +++++++++++++++++++++++++++++++++++++++++++ generate | 119 +++++++++++++++++++ get_FWcnt | 33 ++++++ init_FWcnt | 94 +++++++++++++++ wrapper/w0.cgi | 11 ++ wrapper/w1.cgi | 54 +++++++++ wrapper/w2.cgi | 48 ++++++++ wrapper/w3.cgi | 45 +++++++ wrapper/w4.cgi | 51 ++++++++ 18 files changed, 1462 insertions(+) create mode 100755 FWcnt2rrd create mode 100644 Makefile create mode 100644 README create mode 100644 README.old create mode 100644 TODO create mode 100755 clean_FWcnt create mode 100644 cnt2rrd.c create mode 100644 cron.d create mode 100755 fw2rrd create mode 100644 fw2rrd.c create mode 100755 generate create mode 100755 get_FWcnt create mode 100755 init_FWcnt create mode 100755 wrapper/w0.cgi create mode 100755 wrapper/w1.cgi create mode 100755 wrapper/w2.cgi create mode 100755 wrapper/w3.cgi create mode 100755 wrapper/w4.cgi diff --git a/FWcnt2rrd b/FWcnt2rrd new file mode 100755 index 0000000..06a940d --- /dev/null +++ b/FWcnt2rrd @@ -0,0 +1,31 @@ +#!/bin/bash + +/usr/lib/FWcnt/fw2rrd + +awk 'BEGIN{ + while(getline <"/proc/net/dev"){ + if(2==split($0,X,":")){ + split(X[1],xx," ") + eth[xx[1]]=X[2] + } + } +} +{ + if($1 == "cntLINK"){ + if($2 in eth){ + split(eth[$2],data) + C="test -f "$2"-p.rrd||rrdtool create "$2"-p.rrd --step 300 DS:ds0:DERIVE:600:0:U DS:ds1:DERIVE:600:0:U RRA:AVERAGE:0.5:1:800 RRA:AVERAGE:0.5:6:800 RRA:AVERAGE:0.5:24:800 RRA:AVERAGE:0.5:288:800 RRA:MAX:0.5:1:800 RRA:MAX:0.5:6:800 RRA:MAX:0.5:24:800 RRA:MAX:0.5:288:800" + system(C) + close(C) + C="test -f "$2"-b.rrd||rrdtool create "$2"-b.rrd --step 300 DS:ds0:DERIVE:600:0:U DS:ds1:DERIVE:600:0:U RRA:AVERAGE:0.5:1:800 RRA:AVERAGE:0.5:6:800 RRA:AVERAGE:0.5:24:800 RRA:AVERAGE:0.5:288:800 RRA:MAX:0.5:1:800 RRA:MAX:0.5:6:800 RRA:MAX:0.5:24:800 RRA:MAX:0.5:288:800" + system(C) + close(C) + C="rrdtool update "$2"-b.rrd N:"data[1]":"data[9] + system(C) + close(C) + C="rrdtool update "$2"-p.rrd N:"data[2]":"data[10] + system(C) + close(C) + } + } +}' /var/lib/FWcnt/etc/config 2>/dev/null diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..7b45f2d --- /dev/null +++ b/Makefile @@ -0,0 +1,30 @@ +fw2rrd: fw2rrd.c + cc fw2rrd.c -Wall -Wshadow -Wbad-function-cast \ + -pedantic -Wno-long-long -Wstrict-prototypes \ + -o fw2rrd -lrrd -O2 + +install: fw2rrd + mkdir /usr/lib/FWcnt;true + cp fw2rrd /usr/lib/FWcnt/ + cp init_FWcnt /usr/lib/FWcnt/ + cp clean_FWcnt /usr/lib/FWcnt/ + cp get_FWcnt /usr/lib/FWcnt/ + cp generate /usr/lib/FWcnt/ + cp FWcnt2rrd /usr/lib/FWcnt/ + mkdir /var/www/mrtg-rrd;true + chown www-data /var/www/mrtg-rrd + mkdir /var/lib/FWcnt;true + mkdir /var/lib/FWcnt/etc;true + mkdir /var/lib/FWcnt/FW_rrd_database;true + mkdir /var/lib/FWcnt/run_conf;true + touch /var/lib/FWcnt/etc/config + chown Debian-ippl -R /var/lib/FWcnt/FW_rrd_database + cp cron.d /etc/cron.d/FWcnt + cat mrtg-rrd.wrapper.cgi >/usr/lib/cgi-bin/mrtg-rrd.wrapper.cgi + +depends: + dpkg -l gawk mrtg-rrd ippl mrtg iptables cron bash librrd2-dev + +clean: + rm -f fw2rrd + diff --git a/README b/README new file mode 100644 index 0000000..1dc77f3 --- /dev/null +++ b/README @@ -0,0 +1,279 @@ +Version 0.3pre1 +--------------- + +Detailed measuring system for wide range of IPs +----------------------------------------------- + +"fast" setup +------------ + +1. copy this sample in /var/lib/FWcnt/etc/config (replace 192.168.0.0 with your +IP) +---------------- cut ---------------- +cntLINK eth0 +cntNET 192.168.0.0 +---------------- cut ---------------- + +2. run /usr/lib/FWcnt/init_FWcnt + +3. run /usr/lib/FWcnt/generate + +4. show http://YOUR_WEB/cgi-bin/mrtg-rrd.wrapper.cgi + + + + +Part 1: +******* + +Kernel counters in iptables is used for counting paket and byte count od +each measurments. + +Specification & features +------------------------- + +1. each IP has own In and Out counter +2. each subnet of 8,16,32,64,128,256 IP has own In and Out counter +3. paket traverse only minimum rules in firewall + max rules = 1(C range)+2(Ip/25)+4(Ip/26)+8(Ip/27)+ + 16(subchains = Ip/28)+2(Ip/29)+16 = 49 rules one direction + For reverse direction one more rule must be added. + Full C bidirectional counting is counted by max 50 rules + For each C class one rule more must be traversed for one direction + + +for each C range exists this structure: + +match +full ---+ rule subnet 0-127 +C + rule subnet 128-255 +range + rule subnet 0 - 63 + + rule subnet 64-127 + + rule subnet 128-191 + + rule subnet 192-255 + + rule subnet 0-31 + + rule subnet 32-63 + + . + + . + + rule subnet 224-255 + + subchain 0-15 ----+ rule subnet 0-7 + | + rule subnet 8-15 + | + rule 0 + | + rule 1 + | + . + | + . + | + rule 15 + + subchain 16-32 ----+ rule subnet 16-23 + | + rule subnet 24-31 + | + rule 16 + | + rule 17 + | + . + | + . + | + rule 31 + . + . + + subchain 240-255 ----+ rule subnet 240-247 + + rule subnet 248-255 + + rule 240 + + rule 241 + + . + + . + + rule 255 + + + +Chain FWcnt is managed by programs init_FWcnt, get_FWcnt and clean_FWcnt. + +clean_FWcnt erase all rules and subchains in FWcnt chain +get_FWcnt read counters from rules in FWcnt chain +init_FWcnt set up rules for one C ranges of IPs for measurments + +Example: to set up measurments for one C range 192.168.0.0 + +init_FWcnt 192.168.0 + +Without argumet this command read configuration file and set up counters for +all nets defined by keywork "cntNET" in config file (see below). + + +Initialization in FW: + +iptables -N FWcnt #base chain for measurments +iptables -I INPUT -j FWcnt #count input +iptables -I OUTPUT -j FWcnt #count output +iptables -I FORWARD -j FWcnt #count forward + + +getting counters: + +get_FWcnt + +return 4 values per line .. paket count, bytes count, source IP destination IP + + +Part 2 +****** + +counter database +---------------- + +Text database used by mrtg is slow. RRD database is used for each counter +rule. + +cron job read all counters in FWcnt chain by calling "get_FWcnt". +Output of "get_FWcnt" is passed to binary fw2rrd (from source fw2rrd.c) +For each counter from FWcnt chain reverse counter is searched. If database +file does not exist, then fw2rrd create one for each counter. fw2rrd must be +running in working directory. Only iptables command must run with root +privileges, database can be run by different user. + +example cron job: + + +0-55/5 * * * * root if [ -x /usr/lib/FWcnt/get_FWcnt ]; then \ + (env LANG=C /usr/lib/FWcnt/get_FWcnt |su --shell=/bin/bash \ + -c '(cd /var/lib/FWcnt/FW_rrd_database/; \ + /usr/lib/FWcnt/fw2rrd' Debian-ippl);fi + + +Counter name is derived vrom IP number. +For each counter pair exists two rrd files, one for bytes count and one for +pakets count. Name convencion: + +IP1.IP2.IP3.IP4_NM-b.rrd bytes for net IP1.IP2.IP3.IP4_NM +IP1.IP2.IP3.IP4_NM-p.rrd pakets for net IP1.IP2.IP3.IP4_NM + +IP1..IP4 number 0..255 +NM netmask bits (0 ..32) +-p.rrd fixed part of name for pakets counter +-b.rrd fixed part of name for bytes counter + +"Target" name of counter is filename without .rrd suffix + +Warning, "_NM" is optional, for measuring one IP "_NM" can be "_32" or this +part of name absent. + +example: + +192.168.0.1-b.rrd byte counter for one IP 192.168.0.1 +192.168.0.1_32-b.rrd byte counter for one IP 192.168.0.1 but !!WARNING!! + this counters is different from previous + +192.168.0.0_16-p.rrd pakets counter for "B" class net 192.168.0.0 + + + +Part3 +***** + +ethernet device measurment +-------------------------- + +data for each ethernet device can be found in /proc/net/dev. Not all devices +is "counted". Only devices found in config file is used for measurment. + +FWcnt2rrd first run fw2rrd, next check configuration file and for each +device create/update counter file. + +example config file (onli part for devices) +--------------- cut -------------- +cntLINK eth0 +cntLINK vlan2 +--------------- cut -------------- + +counter files with names: +eth0-p.rrd +eth0-b.rrd +vlan2-p.rrd +vlan2-b.rrd + + + + +Visualization of counters by mrtg. +---------------------------------- + +mrtg-rrd is used to visualize rrd files. Original mrtg-rrd does not use +multiple config files, wrapper is created for adapt mrtg-rrd to count C +class networks. + +All needed config files for mrtg-rrd is automaticali generated by +"generate" command. + +"generate" first creates one page with graphs for ethernet devices (based on +config file) and next graph for summary of one C class. + +below graph for C class is subsummary graphs for /28 subnets (default) or +subnets of C class defined in config file by directive "mrtgNET". +Both variant of netmask can be used. + +Example config: + +---------------------------- cut ------------------------- +#eth interfaces +cntLINK eth2 +cntLINK eth0 +# firewall counters for C class nets +cntNET 192.168.40 +cntNET 192.168.42.0 +# +mrtgNET 192.168.40.0 24 +mrtgNET 192.168.42.0 25 +mrtgNET 192.168.42.128 28 +mrtgNET 192.168.42.144 29 +mrtgNET 192.168.42.152 29 +mrtgNET 192.168.42.160 27 +mrtgNET 192.168.42.195 255.255.255.192 +---------------------------- cut ------------------------- + + +Keywork "cntNET" is used for definition of counter for "init_FWcnt" command. + + + + + + + + + + + + +obsollete files from previous development. +------------------------------------------ +cnt2rrd [filename] + +read filename or stdin if no filename is specified. Format of input file is +designed for iptables -L output but target must be RETURN. +Example input file: + +----------------------- cut --------------------------- +Chain CNTin (1 references) + pkts bytes target prot opt in out source destination + 302978 50655932 RETURN all -- * * 0.0.0.0/0 62.168.101.165 +Chain CNTout (1 references) + pkts bytes target prot opt in out source destination + 2 211 RETURN all -- * * 62.168.101.165 0.0.0.0/0 + +----------------------- cut --------------------------- + + +more chains can be concatenated in input and chains may consist of couple of +rules for input and output. As "download" must be source set to +0.0.0.0/0. for upload must be destination set to 0.0.0.0/0. Protocol must be +"all", opt must be "--" and in and out must be "-". + +For each couple of rule (one for down and one for upload) two rrd files are +updated. Name od rrd file is derived from IP (or ip and netmask). For IP +62.168.101.165 for example is output rrd filename 62.168.101.165a.rrd and +62.168.101.165b.rrd. First file is updated by bytes counters from chain and +seconf from pakets counter. + +If IP if rule match subnet (etc 172.26.0.0/24) file is named +172.26.0.0_24a.rrd (all "/" is replaced by "_"). + +Special IP ranges etc may cause problems.. + +WARNING ! rrd files creation is done in working directory. + diff --git a/README.old b/README.old new file mode 100644 index 0000000..3e087bd --- /dev/null +++ b/README.old @@ -0,0 +1,68 @@ +cnt2rrd [filename] + +read filename or stdin if no filename is specified. Format of input file is +designed for iptables -L output but target must be RETURN. +Example input file: + +----------------------- cut --------------------------- +Chain CNTin (1 references) + pkts bytes target prot opt in out source destination + 302978 50655932 RETURN all -- * * 0.0.0.0/0 62.168.101.165 +Chain CNTout (1 references) + pkts bytes target prot opt in out source destination + 2 211 RETURN all -- * * 62.168.101.165 0.0.0.0/0 + +----------------------- cut --------------------------- + + +more chains can be concatenated in input and chains may consist of couple of +rules for input and output. As "download" must be source set to +0.0.0.0/0. for upload must be destination set to 0.0.0.0/0. Protocol must be +"all", opt must be "--" and in and out must be "-". + +For each couple of rule (one for down and one for upload) two rrd files are +updated. Name od rrd file is derived from IP (or ip and netmask). For IP +62.168.101.165 for example is output rrd filename 62.168.101.165a.rrd and +62.168.101.165b.rrd. First file is updated by bytes counters from chain and +seconf from pakets counter. + +If IP if rule match subnet (etc 172.26.0.0/24) file is named +172.26.0.0_24a.rrd (all "/" is replaced by "_"). + +Special IP ranges etc may cause problems.. + +WARNING ! rrd files creation is done in working directory. + + + + + +directory structure: + +$ ls -lRa /var/lib/cnt-mrtg/ +/var/lib/cnt-mrtg/: +total 16 +drwxr-xr-x 4 root root 4096 May 11 13:56 . +drwxr-xr-x 30 root root 4096 May 11 13:55 .. +drwxr-xr-x 2 root root 4096 May 11 13:53 bin +drwxr-xr-x 2 arpwatch www-data 4096 May 11 13:56 rrd-database + +/var/lib/cnt-mrtg/bin: +total 16 +drwxr-xr-x 2 root root 4096 May 11 13:53 . +drwxr-xr-x 4 root root 4096 May 11 13:56 .. +-rwxr-xr-x 1 root root 7408 May 11 13:53 cnt2rrd + +/var/lib/cnt-mrtg/rrd-database: +total 8 +drwxr-xr-x 2 arpwatch www-data 4096 May 11 13:56 . +drwxr-xr-x 4 root root 4096 May 11 13:56 .. + +$ ls -lRa /var/log/cnt-mrtg/ +/var/log/cnt-mrtg/: +total 8 +drwxr-xr-x 2 arpwatch adm 4096 May 11 13:58 . +drwxr-xr-x 12 root root 4096 May 11 13:58 .. + + + diff --git a/TODO b/TODO new file mode 100644 index 0000000..150d474 --- /dev/null +++ b/TODO @@ -0,0 +1,3 @@ +* get name for IP/net + +* iptables counter setting (start/stop) from /etc/network/intrfaces diff --git a/clean_FWcnt b/clean_FWcnt new file mode 100755 index 0000000..c39c657 --- /dev/null +++ b/clean_FWcnt @@ -0,0 +1,10 @@ +#!/bin/bash + +for i in `iptables -L FWcnt -n|awk '{if($0 ~ "^FWcnt"){if(NR>2)print $1}}';iptables -F FWcnt` ;do + for j in `iptables -L ${i} -n |awk '{if($0 ~ "^FWcnt"){if(NR>2)print $1}}';iptables -F ${i}` ;do + iptables -F ${j} + iptables -X ${j} + done + iptables -X ${i} +done + diff --git a/cnt2rrd.c b/cnt2rrd.c new file mode 100644 index 0000000..6b15a2f --- /dev/null +++ b/cnt2rrd.c @@ -0,0 +1,309 @@ +/* for version of rrdtool before 2005-05-01 10:23 must be +optind initioalized before callinf any of rrd_*. +Please uncoment #define DO_GETOPT_RESET for old version of rrd +or comment out for new versions +*/ +#define DO_GETOPT_RESET +#define _GNU_SOURCE + +#define IPLIMIT 20 +#define HASHMAX 100 +#define BUFF_SIZE 2000 +#include +#include +#include +#include +#include +#ifdef DO_GETOPT_RESET +#include +#endif + +/* create new array */ +int +newRRD (char *name) +{ + char *timebuff; + char *r_create[] = { + "create", + NULL, + "--start", + NULL, + "--step", + "300", + "DS:ds0:DERIVE:600:0:U", + "DS:ds1:DERIVE:600:0:U", + "RRA:AVERAGE:0.5:1:800", + "RRA:AVERAGE:0.5:6:800", + "RRA:AVERAGE:0.5:24:800", + "RRA:AVERAGE:0.5:288:800", + "RRA:MAX:0.5:1:800", + "RRA:MAX:0.5:6:800", + "RRA:MAX:0.5:24:800", + "RRA:MAX:0.5:288:800" + }; + asprintf (&timebuff, "%ld", time (NULL) - 10); + r_create[1] = name; + r_create[3] = timebuff; + +#ifdef DO_GETOPT_RESET + optind = 0; + opterr = 0; +#endif + rrd_create (16, r_create); + if (rrd_test_error ()) + { + fprintf (stderr, "Unable to create %s,%s\n", name, rrd_get_error ()); + rrd_clear_error (); + return (1); + } + free (timebuff); + return (0); +} + + + + +int +updateRRD (char *key, unsigned long long inPkts, unsigned long long outPkts, + unsigned long long inBytes, unsigned long long outBytes) +{ + FILE *rrdfile; + char *r_buf, *name; + int i; + char *r_update[3] = { "update", NULL, NULL }; + + asprintf (&name, "%sa.rrd", key); + i = strlen (name); + while (i > 0) + { + if (name[i] == '/') + name[i] = '_'; + i--; + } + if (NULL == (rrdfile = fopen (name, "r"))) + newRRD (name); + else + fclose (rrdfile); + asprintf (&r_buf, "N:%lld:%lld", inBytes, outBytes); + r_update[1] = name; + r_update[2] = r_buf; +#ifdef DO_GETOPT_RESET + optind = 0; + opterr = 0; +#endif + rrd_update (3, r_update); + if (rrd_test_error ()) + { + fprintf (stderr, "Unable to update %s\n", name); + rrd_clear_error (); + } + free (r_buf); + free (name); + asprintf (&name, "%sb.rrd", key); + i = strlen (name); + while (i > 0) + { + if (name[i] == '/') + name[i] = '_'; + i--; + } + if (NULL == (rrdfile = fopen (name, "r"))) + newRRD (name); + else + fclose (rrdfile); + asprintf (&r_buf, "N:%lld:%lld", inPkts, outPkts); + r_update[1] = name; + r_update[2] = r_buf; +#ifdef DO_GETOPT_RESET + optind = 0; + opterr = 0; +#endif + rrd_update (3, r_update); + if (rrd_test_error ()) + { + fprintf (stderr, "Unable to update %s\n", name); + rrd_clear_error (); + } + free (r_buf); + free (name); + return (0); +} + + + +struct CNT +{ + char *key; + unsigned long long inBytes; + unsigned long long outBytes; + unsigned long long inPkts; + unsigned long long outPkts; + int count; + struct CNT *next; +}; + +struct CNT *CNThash[HASHMAX]; +int +add_to_hash (unsigned int h, char *key, unsigned long long bytes, + unsigned long long pakets, int direction) +{ + struct CNT *newCNT, *actual; + int hash; + hash = h % HASHMAX; + actual = CNThash[hash]; + while (actual != NULL) /* search */ + { + if (0 == strcmp (key, actual->key)) /* found */ + { + if (direction == 1) + { + actual->inBytes = bytes; + actual->inPkts = pakets; + } + else + { + actual->outBytes = bytes; + actual->outPkts = pakets; + } + if (actual->count == 1) + updateRRD (actual->key, actual->inPkts, actual->outPkts, + actual->inBytes, actual->outBytes); + else + { + fprintf (stderr, "Warning: count for key %s = %d\n", + actual->key, actual->count); + (actual->count)++; + } + + return (0); /* key found, do return */ + } + actual = actual->next; + } + if (NULL == (newCNT = malloc (sizeof (struct CNT)))) + { + fprintf (stderr, "Error, unable to alocate memory\n"); + exit (2); + } + newCNT->key = strdup (key); + if (direction == 1) + { + newCNT->inBytes = bytes; + newCNT->inPkts = pakets; + newCNT->outBytes = 0; + newCNT->outPkts = 0; + } + else + { + newCNT->outBytes = bytes; + newCNT->outPkts = pakets; + newCNT->inBytes = 0; + newCNT->inPkts = 0; + } + newCNT->count = 1; + newCNT->next = CNThash[hash]; + CNThash[hash] = newCNT; + return (0); +} + + + +int +main (int argc, char **argv) +{ + FILE *data; + int i, j; + unsigned int h; + char buffer[BUFF_SIZE], *ptr, ipbuff[IPLIMIT]; + unsigned long long tmppakets, tmpbytes; + + for (i = 0; i < HASHMAX; i++) + CNThash[i] = NULL; + + if (argc == 2) + { + if (NULL == (data = fopen (argv[1], "r"))) + { + fprintf (stderr, "Unable to open input file\n"); + return (1); + } + } + else + data = stdin; + + while (fgets (buffer, BUFF_SIZE - 1, data)) + { + ptr = buffer; + tmppakets = strtoull (ptr, &ptr, 10); + tmpbytes = strtoull (ptr, &ptr, 10); +/* skip RETURN */ + while (*ptr == ' ') + ptr++; + if (0 != memcmp (ptr, "RETURN", 6)) + continue; + ptr += 6; +/* skip all */ + while (*ptr == ' ') + ptr++; + if (0 != memcmp (ptr, "all", 3)) + continue; + ptr += 3; +/* skip -- */ + while (*ptr == ' ') + ptr++; + if (*ptr != '-') + continue; + ptr++; + if (*ptr != '-') + continue; + ptr++; +/*skip * */ + while (*ptr == ' ') + ptr++; + if (*ptr != '*') + continue; + ptr++; +/*skip * */ + while (*ptr == ' ') + ptr++; + if (*ptr != '*') + continue; + ptr++; +/*find IP */ + while (*ptr == ' ') + ptr++; + if (0 == memcmp (ptr, "0.0.0.0/0", 9)) /* download */ + { + /* skip IP */ + while (*ptr == ' ') + ptr++; + while (*ptr != ' ') + ptr++; + while (*ptr == ' ') + ptr++; + for (h = 0, i = 0, j = 0; + i < (IPLIMIT - 1) && *ptr != ' ' && *ptr != '\n'; i++, ptr++) + { + h *= 10; /* hash key */ + h += *ptr - '0'; + ipbuff[i] = *ptr; + } + ipbuff[i] = 0; + add_to_hash (h, ipbuff, tmpbytes, tmppakets, 1); + } + else + { + for (h = 0, i = 0, j = 0; + i < (IPLIMIT - 1) && *ptr != ' ' && *ptr != '\n'; i++, ptr++) + { + h *= 10; /* hash key */ + h += *ptr - '0'; + ipbuff[i] = *ptr; + } + ipbuff[i] = 0; + add_to_hash (h, ipbuff, tmpbytes, tmppakets, 0); + } + } + if (data != stdin) + fclose (data); + return (0); +} diff --git a/cron.d b/cron.d new file mode 100644 index 0000000..9518d65 --- /dev/null +++ b/cron.d @@ -0,0 +1 @@ +0-55/5 * * * * root if [ -x /usr/lib/FWcnt/get_FWcnt ]; then (env LANG=C /usr/lib/FWcnt/get_FWcnt |su --shell=/bin/bash -c '(cd /var/lib/FWcnt/FW_rrd_database/;/usr/lib/FWcnt/FWcnt2rrd)' Debian-ippl);fi diff --git a/fw2rrd b/fw2rrd new file mode 100755 index 0000000000000000000000000000000000000000..0938d6ca5675f7d9b057d7975c5135a7187d1681 GIT binary patch literal 12037 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 +#include +#include +#include +#include +#ifdef DO_GETOPT_RESET +#include +#endif + +/* create new array */ +int +newRRD (char *name) +{ + char *timebuff; + char *r_create[] = { + "create", + NULL, + "--start", + NULL, + "--step", + "300", + "DS:ds0:DERIVE:600:0:U", + "DS:ds1:DERIVE:600:0:U", + "RRA:AVERAGE:0.5:1:800", + "RRA:AVERAGE:0.5:6:800", + "RRA:AVERAGE:0.5:24:800", + "RRA:AVERAGE:0.5:288:800", + "RRA:MAX:0.5:1:800", + "RRA:MAX:0.5:6:800", + "RRA:MAX:0.5:24:800", + "RRA:MAX:0.5:288:800" + }; + asprintf (&timebuff, "%ld", time (NULL) - 10); + r_create[1] = name; + r_create[3] = timebuff; + +#ifdef DO_GETOPT_RESET + optind = 0; + opterr = 0; +#endif + rrd_create (16, r_create); + if (rrd_test_error ()) + { + fprintf (stderr, "Unable to create %s,%s\n", name, rrd_get_error ()); + rrd_clear_error (); + return (1); + } + free (timebuff); + return (0); +} + + + + +int +updateRRD (char *key, unsigned long long inPkts, unsigned long long outPkts, + unsigned long long inBytes, unsigned long long outBytes) +{ + FILE *rrdfile; + char *r_buf, *name; + int i; + char *r_update[3] = { "update", NULL, NULL }; + + asprintf (&name, "%s-b.rrd", key); + i = strlen (name); + while (i > 0) + { + if (name[i] == '/') + name[i] = '_'; + i--; + } + if (NULL == (rrdfile = fopen (name, "r"))) + newRRD (name); + else + fclose (rrdfile); + asprintf (&r_buf, "N:%lld:%lld", inBytes, outBytes); + r_update[1] = name; + r_update[2] = r_buf; +#ifdef DO_GETOPT_RESET + optind = 0; + opterr = 0; +#endif + rrd_update (3, r_update); + if (rrd_test_error ()) + { + fprintf (stderr, "Unable to update %s\n", name); + rrd_clear_error (); + } + free (r_buf); + free (name); + asprintf (&name, "%s-p.rrd", key); + i = strlen (name); + while (i > 0) + { + if (name[i] == '/') + name[i] = '_'; + i--; + } + if (NULL == (rrdfile = fopen (name, "r"))) + newRRD (name); + else + fclose (rrdfile); + asprintf (&r_buf, "N:%lld:%lld", inPkts, outPkts); + r_update[1] = name; + r_update[2] = r_buf; +#ifdef DO_GETOPT_RESET + optind = 0; + opterr = 0; +#endif + rrd_update (3, r_update); + if (rrd_test_error ()) + { + fprintf (stderr, "Unable to update %s\n", name); + rrd_clear_error (); + } + free (r_buf); + free (name); + return (0); +} + + + +struct CNT +{ + char *key; + unsigned long long inBytes; + unsigned long long outBytes; + unsigned long long inPkts; + unsigned long long outPkts; + int count; + struct CNT *next; +}; + +struct CNT *CNThash[HASHMAX]; +int +add_to_hash (unsigned int h, char *key, unsigned long long bytes, + unsigned long long pakets, int direction) +{ + struct CNT *newCNT, *actual; + int hash; + hash = h % HASHMAX; + actual = CNThash[hash]; + while (actual != NULL) /* search */ + { + if (0 == strcmp (key, actual->key)) /* found */ + { + if (direction == 1) + { + actual->inBytes = bytes; + actual->inPkts = pakets; + } + else + { + actual->outBytes = bytes; + actual->outPkts = pakets; + } + if (actual->count == 1) + updateRRD (actual->key, actual->inPkts, actual->outPkts, + actual->inBytes, actual->outBytes); + else + { + fprintf (stderr, "Warning: count for key %s = %d\n", + actual->key, actual->count); + (actual->count)++; + } + + return (0); /* key found, do return */ + } + actual = actual->next; + } + if (NULL == (newCNT = malloc (sizeof (struct CNT)))) + { + fprintf (stderr, "Error, unable to alocate memory\n"); + exit (2); + } + newCNT->key = strdup (key); + if (direction == 1) + { + newCNT->inBytes = bytes; + newCNT->inPkts = pakets; + newCNT->outBytes = 0; + newCNT->outPkts = 0; + } + else + { + newCNT->outBytes = bytes; + newCNT->outPkts = pakets; + newCNT->inBytes = 0; + newCNT->inPkts = 0; + } + newCNT->count = 1; + newCNT->next = CNThash[hash]; + CNThash[hash] = newCNT; + return (0); +} + + + +int +main (int argc, char **argv) +{ + FILE *data; + int i, j; + unsigned int h; + char buffer[BUFF_SIZE], *ptr, ipbuff[IPLIMIT]; + unsigned long long tmppakets, tmpbytes; + + for (i = 0; i < HASHMAX; i++) + CNThash[i] = NULL; + + if (argc == 2) + { + if (NULL == (data = fopen (argv[1], "r"))) + { + fprintf (stderr, "Unable to open input file\n"); + return (1); + } + } + else + data = stdin; + + while (fgets (buffer, BUFF_SIZE - 1, data)) + { + ptr = buffer; + tmppakets = strtoull (ptr, &ptr, 10); + tmpbytes = strtoull (ptr, &ptr, 10); +/*find IP */ + while (*ptr == ' ') + ptr++; + if (0 == memcmp (ptr, "0.0.0.0/0", 9)) /* download */ + { + /* skip IP */ + while (*ptr == ' ') + ptr++; + while (*ptr != ' ') + ptr++; + while (*ptr == ' ') + ptr++; + for (h = 0, i = 0, j = 0; + i < (IPLIMIT - 1) && *ptr != ' ' && *ptr != '\n'; i++, ptr++) + { + h *= 10; /* hash key */ + h += *ptr - '0'; + ipbuff[i] = *ptr; + } + ipbuff[i] = 0; + add_to_hash (h, ipbuff, tmpbytes, tmppakets, 1); + } + else + { + for (h = 0, i = 0, j = 0; + i < (IPLIMIT - 1) && *ptr != ' ' && *ptr != '\n'; i++, ptr++) + { + h *= 10; /* hash key */ + h += *ptr - '0'; + ipbuff[i] = *ptr; + } + ipbuff[i] = 0; + add_to_hash (h, ipbuff, tmpbytes, tmppakets, 0); + } + } + if (data != stdin) + fclose (data); + return (0); +} diff --git a/generate b/generate new file mode 100755 index 0000000..3fb1181 --- /dev/null +++ b/generate @@ -0,0 +1,119 @@ +#!/bin/bash +iptables -L FWcnt -n|gawk -v CONVFMT="%d" '{if($1 ~ "^FWcntIN"){split ($NF,N,"/");print N[1]}}'|sort -u -n -t . -k1,1 -k2,2 -k3,3 -k4,4| + +gawk -v CONVFMT="%d" ' + +function print_header(Ofile){ +OUT="/var/lib/FWcnt/run_conf/"Ofile".conf" +OUTf="/var/lib/FWcnt/run_conf/"Ofile".cfg" +print OUT > OUTf +print "######################################################################" >OUT +print "# Automaticaly generated (/var/www/mrtg/gener)" >>OUT +print "# !!!!!!! not for use with real mrtg !!!!!!" >>OUT +print "# automaticaly generated. " >>OUT +print "######################################################################" >>OUT +print "Htmldir: /var/www/mrtg-rrd" >>OUT +print "Imagedir: /var/www/mrtg-rrd" >>OUT +print "Logdir: /var/lib/FWcnt/FW_rrd_database" >>OUT +print "" >>OUT +print "WriteExpires: Yes" >>OUT +print "LogFormat: rrdtool" >>OUT +print "" >>OUT +print "Title[^]: Traffic Analysis for " >>OUT +print "" >>OUT +} + +function print_target(IP,TARGET,NAME,Ofile,HREF){ + OUT="/var/lib/FWcnt/run_conf/"Ofile".conf" + gsub("/","_",TARGET) + printf("Target[%s-b]: none\n",TARGET) >> OUT + printf("MaxBytes[%s-b]: %s\n",TARGET,10000*128) >> OUT + printf("AbsMax[%s-b]: %s\n",TARGET,3280000) >> OUT + if(HREF==""){ + printf("Title[%s-b]:  bytes %s\n",TARGET,IP) >> OUT + } + else{ + printf("Title[%s-b]:  bytes %s \n",TARGET,IP,HREF) >> OUT + } + printf("Options[%s-b]: bits\n",TARGET)>>OUT + printf("PageTop[%s-b]:

Bytes to/from %s (%s)\n",TARGET,IP,IP) >> OUT + printf(" %s

\n \n \n",IP) >> OUT + printf(" \n
System:router
Maintainer:krak3n
\n\n") >> OUT + + printf("Target[%s-p]: none\n",TARGET) >> OUT + printf("MaxBytes[%s-p]: %s\n",TARGET,65000) >> OUT + printf("AbsMax[%s-p]: %s\n",TARGET,1280000) >> OUT + printf("ShortLegend[%s-p]: pps\n",TARGET) >> OUT + printf("Options[%s-p]: nopercent,unknaszero\n",TARGET) >> OUT + printf("Title[%s-p]:  pkts %s\n",TARGET,IP) >> OUT + printf("YLegend[%s-p]: Pkts per Second\n",TARGET) >> OUT + printf("PageTop[%s-p]:

Pkts to/from %s\n",TARGET,IP) >> OUT + printf("

\n \n \n") >> OUT + printf(" \n
System:router
Maintainer:krak3n
\n\n") >> OUT +} + +BEGIN{ + OUTx="/var/lib/FWcnt/run_conf/target.parent" + printf("")>OUTx + print_header("default") + while(getline < "/var/lib/FWcnt/etc/config" ){ + if($1 ~ "^mrtgNET"){ + split($2,N,".") + C=16 + if(split($3,NM,".")==4){ + if(NM[1]==255 && NM[2]==255 && NM[3]==255) C=256-NM[4] + } + else C=2^(32-$3) + if(C>128 || C<8)C=16 + N[4]=and(N[4],xor(255,(C-1))) + NL[N[1]"."N[2]"."N[3]"."N[4]]=C +# print("Net "N[1]"."N[2]"."N[3]"."N[4]" "C) + } + if($1 ~ "^cntLINK"){ + print_target($2"",$2"",$2"","default","") + printf("default %s\n",$2) >>OUTx + } + } + close("/var/lib/FWcnt/etc/config"); +} +{ +TP="default" +IP=$1 "/24" +TARGET=$1."/24" +NAME=$1"/24" +HREF=$1"_24" +print_target(IP,TARGET,NAME,"default",HREF) +printf("%s %s\n",TP,TARGET) >>OUTx + +split(IP,IPn,"."); +netC=IPn[1]"."IPn[2]"."IPn[3] + + TP=$1"_24" + print_header(TP) + i=0 + while(i<256){ + j=16 + if(netC"."i in NL) j=NL[netC"."i] + jx=32-int(log(j)*1.5) +# print "j="j" jx="jx + IP=netC"."i"/"jx + TARGET=IP + NAME=IP + HREF=netC"."i"_"jx + print_target(IP,TARGET,NAME,TP,HREF) + printf("%s %s\n",TP,TARGET) >>OUTx + k=0 + TPx=netC"."i"_"jx + HREF="" + print_header(TPx) + while(k>OUTx + k++ + } + i+=j + } +}' diff --git a/get_FWcnt b/get_FWcnt new file mode 100755 index 0000000..2be34b9 --- /dev/null +++ b/get_FWcnt @@ -0,0 +1,33 @@ +#!/bin/bash +PATH=/bin:/sbin:/usr/bin:/usr/sbin +iptables -L FWcnt -n -x -v 2>/dev/null|awk '{ + if(NR<3)next; + if(NF==9) { + printf "%s %s %s %s\n",$1,$2,$8,$9 + C1="iptables -L "$3" -n -x -v" + C1|getline + C1|getline + while(C1|getline){ + if(NF==9) { + printf "%s %s %s %s\n",$1,$2,$8,$9 + C2="iptables -L "$3" -n -x -v" + C2|getline + C2|getline + while(C2|getline){ + if(NF==9) { + printf "%s %s %s %s\n",$1,$2,$8,$9 + } + if(NF==8) { + printf "%s %s %s %s\n",$1,$2,$7,$8 + } + } + close(C2) + } + if(NF==8) { + printf "%s %s %s %s\n",$1,$2,$7,$8 + } + } + close(C1) + } +}' + diff --git a/init_FWcnt b/init_FWcnt new file mode 100755 index 0000000..3404e99 --- /dev/null +++ b/init_FWcnt @@ -0,0 +1,94 @@ +#!/bin/bash +(if [ $# -ne 1 ]; then + awk '{if($1=="cntNET") print $2}' /var/lib/FWcnt/etc/config +else + echo "$1" +fi)|while read IP;do +NET_A=`echo $IP|awk -F. '{printf "%d",$1}'` +NET_B=`echo $IP|awk -F. '{printf "%d",$2}'` +NET_C=`echo $IP|awk -F. '{printf "%d",$3}'` +if [ ${NET_A} -gt 255 ]; then + NET_A=255 +fi +if [ ${NET_B} -gt 255 ]; then + NET_B=255 +fi +if [ ${NET_C} -gt 255 ]; then + NET_C=255 +fi +iptables -N FWcnt 2>/dev/null + +NET_Ah=`printf "%X" ${NET_A}` +NET_Bh=`printf "%X" ${NET_B}` +NET_Ch=`printf "%X" ${NET_C}` + +iptables -L FWcntIN_${NET_Ah}${NET_Bh}${NET_Ch} -n 2>/dev/null >/dev/null +if [ $? == 0 ]; then + echo "Warning, counters for net ${NET_A}.${NET_B}.${NET_C}.0/24 exists...." +else + +iptables -N FWcntIN_${NET_Ah}${NET_Bh}${NET_Ch} +iptables -N FWcntOUT_${NET_Ah}${NET_Bh}${NET_Ch} + +#create counters for nets /25 +iptables -A FWcntIN_${NET_Ah}${NET_Bh}${NET_Ch} -d ${NET_A}.${NET_B}.${NET_C}.0/25 +iptables -A FWcntIN_${NET_Ah}${NET_Bh}${NET_Ch} -d ${NET_A}.${NET_B}.${NET_C}.128/25 +iptables -A FWcntOUT_${NET_Ah}${NET_Bh}${NET_Ch} -s ${NET_A}.${NET_B}.${NET_C}.0/25 +iptables -A FWcntOUT_${NET_Ah}${NET_Bh}${NET_Ch} -s ${NET_A}.${NET_B}.${NET_C}.128/25 + +#create counters for nets /26 +iptables -A FWcntIN_${NET_Ah}${NET_Bh}${NET_Ch} -d ${NET_A}.${NET_B}.${NET_C}.0/26 +iptables -A FWcntIN_${NET_Ah}${NET_Bh}${NET_Ch} -d ${NET_A}.${NET_B}.${NET_C}.64/26 +iptables -A FWcntIN_${NET_Ah}${NET_Bh}${NET_Ch} -d ${NET_A}.${NET_B}.${NET_C}.128/26 +iptables -A FWcntIN_${NET_Ah}${NET_Bh}${NET_Ch} -d ${NET_A}.${NET_B}.${NET_C}.192/26 +iptables -A FWcntOUT_${NET_Ah}${NET_Bh}${NET_Ch} -s ${NET_A}.${NET_B}.${NET_C}.0/26 +iptables -A FWcntOUT_${NET_Ah}${NET_Bh}${NET_Ch} -s ${NET_A}.${NET_B}.${NET_C}.64/26 +iptables -A FWcntOUT_${NET_Ah}${NET_Bh}${NET_Ch} -s ${NET_A}.${NET_B}.${NET_C}.128/26 +iptables -A FWcntOUT_${NET_Ah}${NET_Bh}${NET_Ch} -s ${NET_A}.${NET_B}.${NET_C}.192/26 + +#create counters for nets /27 +iptables -A FWcntIN_${NET_Ah}${NET_Bh}${NET_Ch} -d ${NET_A}.${NET_B}.${NET_C}.0/27 +iptables -A FWcntIN_${NET_Ah}${NET_Bh}${NET_Ch} -d ${NET_A}.${NET_B}.${NET_C}.32/27 +iptables -A FWcntIN_${NET_Ah}${NET_Bh}${NET_Ch} -d ${NET_A}.${NET_B}.${NET_C}.64/27 +iptables -A FWcntIN_${NET_Ah}${NET_Bh}${NET_Ch} -d ${NET_A}.${NET_B}.${NET_C}.96/27 +iptables -A FWcntIN_${NET_Ah}${NET_Bh}${NET_Ch} -d ${NET_A}.${NET_B}.${NET_C}.128/27 +iptables -A FWcntIN_${NET_Ah}${NET_Bh}${NET_Ch} -d ${NET_A}.${NET_B}.${NET_C}.160/27 +iptables -A FWcntIN_${NET_Ah}${NET_Bh}${NET_Ch} -d ${NET_A}.${NET_B}.${NET_C}.192/27 +iptables -A FWcntIN_${NET_Ah}${NET_Bh}${NET_Ch} -d ${NET_A}.${NET_B}.${NET_C}.224/27 +iptables -A FWcntOUT_${NET_Ah}${NET_Bh}${NET_Ch} -s ${NET_A}.${NET_B}.${NET_C}.0/27 +iptables -A FWcntOUT_${NET_Ah}${NET_Bh}${NET_Ch} -s ${NET_A}.${NET_B}.${NET_C}.32/27 +iptables -A FWcntOUT_${NET_Ah}${NET_Bh}${NET_Ch} -s ${NET_A}.${NET_B}.${NET_C}.64/27 +iptables -A FWcntOUT_${NET_Ah}${NET_Bh}${NET_Ch} -s ${NET_A}.${NET_B}.${NET_C}.96/27 +iptables -A FWcntOUT_${NET_Ah}${NET_Bh}${NET_Ch} -s ${NET_A}.${NET_B}.${NET_C}.128/27 +iptables -A FWcntOUT_${NET_Ah}${NET_Bh}${NET_Ch} -s ${NET_A}.${NET_B}.${NET_C}.160/27 +iptables -A FWcntOUT_${NET_Ah}${NET_Bh}${NET_Ch} -s ${NET_A}.${NET_B}.${NET_C}.192/27 +iptables -A FWcntOUT_${NET_Ah}${NET_Bh}${NET_Ch} -s ${NET_A}.${NET_B}.${NET_C}.224/27 + +#create subchains for counters (/28) +i=0 +while [ $i -lt 16 ]; do + ih=`printf "%X" $i` + j=$[$i * 16 ] + iptables -N FWcntIN_${NET_Ah}${NET_Bh}${NET_Ch}${ih} + iptables -N FWcntOUT_${NET_Ah}${NET_Bh}${NET_Ch}${ih} + #create counters for /29 + iptables -A FWcntIN_${NET_Ah}${NET_Bh}${NET_Ch}${ih} -d ${NET_A}.${NET_B}.${NET_C}.${j}/29 + iptables -A FWcntIN_${NET_Ah}${NET_Bh}${NET_Ch}${ih} -d ${NET_A}.${NET_B}.${NET_C}.$[${j} + 8 ]/29 + iptables -A FWcntOUT_${NET_Ah}${NET_Bh}${NET_Ch}${ih} -s ${NET_A}.${NET_B}.${NET_C}.${j}/29 + iptables -A FWcntOUT_${NET_Ah}${NET_Bh}${NET_Ch}${ih} -s ${NET_A}.${NET_B}.${NET_C}.$[${j} + 8 ]/29 + #create counters for chunk 16 IP + k=0 + while [ $k -lt 16 ]; do + iptables -A FWcntIN_${NET_Ah}${NET_Bh}${NET_Ch}${ih} -d ${NET_A}.${NET_B}.${NET_C}.$[ ${k} + ${j} ] -j RETURN + iptables -A FWcntOUT_${NET_Ah}${NET_Bh}${NET_Ch}${ih} -s ${NET_A}.${NET_B}.${NET_C}.$[ ${k} + ${j} ] -j RETURN + k=$[$k + 1 ] + done + iptables -A FWcntIN_${NET_Ah}${NET_Bh}${NET_Ch} -d ${NET_A}.${NET_B}.${NET_C}.${j}/28 -j FWcntIN_${NET_Ah}${NET_Bh}${NET_Ch}${ih} + iptables -A FWcntOUT_${NET_Ah}${NET_Bh}${NET_Ch} -s ${NET_A}.${NET_B}.${NET_C}.${j}/28 -j FWcntOUT_${NET_Ah}${NET_Bh}${NET_Ch}${ih} + i=$[$i + 1 ] +done + +iptables -A FWcnt -j FWcntIN_${NET_Ah}${NET_Bh}${NET_Ch} -d ${NET_A}.${NET_B}.${NET_C}.0/24 +iptables -A FWcnt -j FWcntOUT_${NET_Ah}${NET_Bh}${NET_Ch} -s ${NET_A}.${NET_B}.${NET_C}.0/24 +fi +done diff --git a/wrapper/w0.cgi b/wrapper/w0.cgi new file mode 100755 index 0000000..6aab91b --- /dev/null +++ b/wrapper/w0.cgi @@ -0,0 +1,11 @@ +#!/bin/bash +C="default.cfg" +if [ $# -eq 1 ]; then + C=`echo $1|awk '{print $1".cfg"}'` +fi +CFG=/var/lib/FWcnt/etc/${C} +if [ -e ${CFG} ]; then + export MRTGRRDCONF=${CFG} +fi +exec /usr/lib/cgi-bin/mrtg-rrd.cgi + diff --git a/wrapper/w1.cgi b/wrapper/w1.cgi new file mode 100755 index 0000000..59e65a4 --- /dev/null +++ b/wrapper/w1.cgi @@ -0,0 +1,54 @@ +#!/bin/bash +IPI=${PATH_INFO} +Cxx=`echo "${PATH_INFO}"|awk 'BEGIN{ +while (getline <"/var/lib/FWcnt/etc/target.parent"){ + gsub("/","_") + TP[$2]=$1 + } +close("/var/lib/FWcnt/etc/target.parent") +FS="-" +} +{ +gsub("/","") +if (length($1)>4){ +split($1,IP,".") +split($1,N,"_") +X=strtonum(IP[4]) +IP[4]=X +NX=strtonum(N[2]) +if(NX!=0){ +X=sprintf ("%d.%d.%d.%d_%d",IP[1],IP[2],IP[3],IP[4],NX) +} +else{ +X=sprintf ("%d.%d.%d.%d",IP[1],IP[2],IP[3],IP[4]) +} +#print(TP[X]) +if(ENVIRON["PATH_INFO"] ~ ".png$") {print(TP[X]);exit 0} +if(ENVIRON["PATH_INFO"] ~ ".html$") {print(TP[X]);exit 0} +print X +exit 1 +} +else { + printf("default\n"); + } +}'` +if [ $? == 1 ]; then + export PATH_INFO="/" +fi + +CFG=/var/lib/FWcnt/etc/${Cxx}.cfg +echo $CFG >> /var/lib/FWcnt/etc/debug +echo "incoming PATH_INFO: "$IPI >>/var/lib/FWcnt/etc/debug +echo "PATH_INFO: $PATH_INFO" >>/var/lib/FWcnt/etc/debug +echo $Cxx >>/var/lib/FWcnt/etc/debug + +if [ -e ${CFG} ]; then + echo "OK" >> /var/lib/FWcnt/etc/debug + export MRTGRRDCONF=${CFG} + exec /usr/lib/cgi-bin/mrtg-rrd.cgi +else + echo "Content-type: text/html" + echo "X-Powered-By: shell" + echo "" + echo "no CFG "$CFG +fi diff --git a/wrapper/w2.cgi b/wrapper/w2.cgi new file mode 100755 index 0000000..7021ab5 --- /dev/null +++ b/wrapper/w2.cgi @@ -0,0 +1,48 @@ +#!/bin/bash +Cxx=`echo "${PATH_INFO}"|awk 'BEGIN{ +while (getline <"/var/lib/FWcnt/etc/target.parent"){ + gsub("/","_") + TP[$2]=$1 + } +close("/var/lib/FWcnt/etc/target.parent") +FS="-" +} +{ +gsub("/","") +if (length($1)>4){ +split($1,IP,".") +split($1,N,"_") +X=strtonum(IP[4]) +IP[4]=X +NX=strtonum(N[2]) +if(NX!=0){ +X=sprintf ("%d.%d.%d.%d_%d",IP[1],IP[2],IP[3],IP[4],NX) +} +else{ +X=sprintf ("%d.%d.%d.%d",IP[1],IP[2],IP[3],IP[4]) +} +#print(TP[X]) +if(ENVIRON["PATH_INFO"] ~ ".png$") {print(TP[X]);exit 0} +if(ENVIRON["PATH_INFO"] ~ ".html$") {print(TP[X]);exit 0} +print X +exit 1 +} +else { + printf("default\n"); + } +}'` +if [ $? == 1 ]; then + export PATH_INFO="/" +fi + +CFG=/var/lib/FWcnt/etc/${Cxx}.cfg + +if [ -e ${CFG} ]; then + export MRTGRRDCONF=${CFG} + exec /usr/lib/cgi-bin/mrtg-rrd.cgi +else + echo "Content-type: text/html" + echo "X-Powered-By: shell" + echo "" + echo "no CFG "$CFG +fi diff --git a/wrapper/w3.cgi b/wrapper/w3.cgi new file mode 100755 index 0000000..0de1580 --- /dev/null +++ b/wrapper/w3.cgi @@ -0,0 +1,45 @@ +#!/bin/bash +awk 'BEGIN{ + while (getline <"/var/lib/FWcnt/run_conf/target.parent"){ + gsub("/","_") + TP[$2]=$1 + } + close("/var/lib/FWcnt/run_conf/target.parent") + FS="-" + INP=ENVIRON["PATH_INFO"] + PATH_INFO=INP + gsub("/","",INP) + if (length(INP)>4){ + split(INP,IP,".") + split(INP,N,"_") + X=strtonum(IP[4]) + IP[4]=X + NX=strtonum(N[2]) + if(NX!=0){ + X=sprintf ("%d.%d.%d.%d_%d",IP[1],IP[2],IP[3],IP[4],NX) + } + else{ + X=sprintf ("%d.%d.%d.%d",IP[1],IP[2],IP[3],IP[4]) + } + if(ENVIRON["PATH_INFO"] ~ ".png$") {OUTX=TP[X];exit 0} + if(ENVIRON["PATH_INFO"] ~ ".html$") {OUTX=TP[X];exit 0} + OUTX=X + PATH_INFO="/" + } + else OUTX="default" +} +{#BLANK BODY +} +END{ + CFG="/var/lib/FWcnt/run_conf/"OUTX".cfg" + if((getline 2){ + split(INP,IP,".") + split(INP,N,"_") + X=strtonum(IP[4]) + IP[4]=X + NX=strtonum(N[2]) + if(NX!=0){ + X=sprintf ("%d.%d.%d.%d_%d",IP[1],IP[2],IP[3],IP[4],NX) + } + else{ + X=sprintf ("%d.%d.%d.%d",IP[1],IP[2],IP[3],IP[4]) + } + if(X in TP){ + OUTX=TP[X] + } + else{ + OUTX="default" + } + if(ENVIRON["PATH_INFO"] ~ ".png$") {exit 0} + if(ENVIRON["PATH_INFO"] ~ ".html$") {exit 0} + OUTX=X + PATH_INFO="/" + } + else OUTX="default" +} +{#BLANK BODY +} +END{ + CFG="/var/lib/FWcnt/run_conf/"OUTX".cfg" + if((getline