From 9303f7308241707634897003655b01bb04e1d7f3 Mon Sep 17 00:00:00 2001 From: Peter Popovec Date: Fri, 14 Dec 2007 12:03:35 +0100 Subject: [PATCH] import debian version fwcnt-0.6 --- FWcnt2rrd | 133 +++++++++++++-- Makefile | 18 +- README | 251 ++++++++++++---------------- TODO | 5 - clean_FWcnt | 113 +++++++------ cnt2rrd.c | 309 ----------------------------------- cron.d | 2 +- debian/changelog | 7 + debian/control | 7 +- debian/docs | 1 - debian/postinst | 15 +- debian/preinst | 42 +++++ debian/prerm | 1 + fw2rrd.c | 344 --------------------------------------- generate | 125 -------------- get_FWcnt | 33 ---- init_FWcnt | 119 +++++++------- install_FWcnt | 181 +++++++++++++++++--- ipfm_FWcnt | 34 ++++ merge | 149 +++++++++++++++++ mergeLINK | 16 ++ mergeNET | 30 ++++ mrtg-rrd.fwcnt.cgi.patch | 63 +++++++ mrtg-rrd.wrapper.cgi | 2 +- 24 files changed, 881 insertions(+), 1119 deletions(-) delete mode 100644 TODO delete mode 100644 cnt2rrd.c create mode 100644 debian/preinst delete mode 100644 fw2rrd.c delete mode 100755 generate delete mode 100755 get_FWcnt create mode 100755 ipfm_FWcnt create mode 100755 merge create mode 100755 mergeLINK create mode 100755 mergeNET create mode 100644 mrtg-rrd.fwcnt.cgi.patch diff --git a/FWcnt2rrd b/FWcnt2rrd index ec180d1..3b1d3f6 100755 --- a/FWcnt2rrd +++ b/FWcnt2rrd @@ -1,9 +1,122 @@ #!/bin/bash -/usr/lib/FWcnt/fw2rrd >/var/log/fwcnt/fwcnt-global.tmp -mv /var/log/fwcnt/fwcnt-global.tmp /var/log/fwcnt/ipfm-global-`date +%Y-%m-%d`.log +#from stdin get output from iptables-save -c, update rrd files +awk ' +BEGIN{ +I[2]=32-1 +I[4]=32-2 +I[8]=32-3 +I[16]=32-4 +I[32]=32-5 +I[64]=32-6 +I[128]=32-7 +I[0]=32-8 +I[256]=32-8 +} +{ +if($2!="-A")next +if($3 !~ "^FWcntIN" && $3 !~ "^FWcntOUT")next + +split(substr($1,2,length($1)-2),Nx,":") + +#printf("%s %s",Nx[1],Nx[2]) +if(NF==7){ + mask="" + if(2==split($(NF-2),N,"/")){ + split(N[2],M,".") + mask=sprintf("/%d",I[256-M[4]]) + } + split(N[1],IP,".") + C[IP[1]"."IP[2]"."IP[3]]=1 + if($(NF-3)=="-d") { + IPbi[N[1]""mask]=Nx[2] + IPpi[N[1]""mask]=Nx[1] + }else{ + IPbo[N[1]""mask]=Nx[2] + IPpo[N[1]""mask]=Nx[1] + } +} +if(NF==5){ + split($NF,N,"/") + split(N[2],M,".") + mask=I[256-M[4]] + split(N[1],IP,".") + C[IP[1]"."IP[2]"."IP[3]]=1 + if($(NF-1)=="-d"){ + IPbi[N[1]"/"mask]=Nx[2] + IPpi[N[1]"/"mask]=Nx[1] + }else{ + IPbo[N[1]"/"mask]=Nx[2] + IPpo[N[1]"/"mask]=Nx[1] + } +} +}END{ +CCMD="test -f /var/lib/FWcnt/FW_rrd_database/upgrade_needed" +j=system(CCMD) +close(CCMD) +if(j==1){ +for(i in C){ + CCMD= "test -f "i".rrd || rrdtool create "i".rrd " + CMD= "rrdtool update "i".rrd N" + k=8 + while(k>=0){ + if(k==2) k=0 + j=0 + while(j<256){ + mask="" + mmask="" + if(k!=0){ + mask="/"32-k + mmask="_"32-k + } + #print i"."j""mask + if( i"."j""mask in IPbi) + CMD=CMD ":"IPbi[i"."j""mask] + else + CMD=CMD ":U" + if( i"."j""mask in IPbo) + CMD=CMD ":"IPbo[i"."j""mask] + else + CMD=CMD ":U" + if( i"."j""mask in IPpi) + CMD=CMD ":"IPpi[i"."j""mask] + else + CMD=CMD ":U" + if( i"."j""mask in IPpo) + CMD=CMD ":"IPpo[i"."j""mask] + else + CMD=CMD ":U" + CCMD=CCMD "DS:IPbi"j""mmask":DERIVE:600:0:U " + CCMD=CCMD "DS:IPbo"j""mmask":DERIVE:600:0:U " + CCMD=CCMD "DS:IPpi"j""mmask":DERIVE:600:0:U " + CCMD=CCMD "DS:IPpo"j""mmask":DERIVE:600:0:U " + j+=2^k + } + k-- + } + CCMD=CCMD "RRA:AVERAGE:0.5:1:800 " + CCMD=CCMD "RRA:AVERAGE:0.5:6:800 " + CCMD=CCMD "RRA:AVERAGE:0.5:24:800 " + CCMD=CCMD "RRA:AVERAGE:0.5:288:800 " + CCMD=CCMD "RRA:MAX:0.5:1:800 " + CCMD=CCMD "RRA:MAX:0.5:6:800 " + CCMD=CCMD "RRA:MAX:0.5:24:800 " + CCMD=CCMD "RRA:MAX:0.5:288:800" + #check if rrdfile need to be created, if needed, create it + system(CCMD) + close(CCMD) + #update rrd file + system(CMD) + close(CMD) +} +} +}' +if [ -f /var/lib/FWcnt/FW_rrd_database/upgrade_needed ]; then + exit 0 +fi +#update rrd files for ethernet interfaces awk 'BEGIN{ while(getline <"/proc/net/dev"){ if(2==split($0,X,":")){ @@ -16,18 +129,16 @@ awk 'BEGIN{ 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] + match($2,"(.*)([[:digit:]]+)$",a) + C="test -f iface."a[1]"."a[2]".rrd||rrdtool create iface."a[1]"."a[2]".rrd --step 300 DS:IPbi:DERIVE:600:0:U DS:IPbo:DERIVE:600:0:U DS:IPpi:DERIVE:600:0:U DS:IPpo: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"-p.rrd N:"data[2]":"data[10] + C="rrdtool update iface."a[1]"."a[2]".rrd N:"data[1]":"data[9]":"data[2]":"data[10] system(C) close(C) } } -}' /var/lib/FWcnt/etc/config 2>/dev/null +}' /var/lib/FWcnt/etc/config + +#update ipfm like log +/usr/lib/FWcnt/ipfm_FWcnt diff --git a/Makefile b/Makefile index 25ca9d2..3d9dc22 100644 --- a/Makefile +++ b/Makefile @@ -1,17 +1,17 @@ -fw2rrd: fw2rrd.c - cc fw2rrd.c -std=c99 -Wall -Wshadow -Wbad-function-cast \ - -pedantic -Wno-long-long -Wstrict-prototypes \ - -o fw2rrd -lrrd -lm -O2 +all: + @echo "make install" -install: fw2rrd +install: install -d $(DESTDIR)/usr/lib/FWcnt - install -m 755 fw2rrd $(DESTDIR)/usr/lib/FWcnt/fw2rrd install -m 755 init_FWcnt $(DESTDIR)/usr/lib/FWcnt/init_FWcnt install -m 755 clean_FWcnt $(DESTDIR)/usr/lib/FWcnt/clean_FWcnt - install -m 755 get_FWcnt $(DESTDIR)/usr/lib/FWcnt/get_FWcnt - install -m 755 generate $(DESTDIR)/usr/lib/FWcnt/generate install -m 755 FWcnt2rrd $(DESTDIR)/usr/lib/FWcnt/FWcnt2rrd install -m 755 install_FWcnt $(DESTDIR)/usr/lib/FWcnt/install_FWcnt + install -m 644 mrtg-rrd.fwcnt.cgi.patch $(DESTDIR)/usr/lib/FWcnt/mrtg-rrd.fwcnt.cgi.patch + install -m 755 merge $(DESTDIR)/usr/lib/FWcnt/merge + install -m 755 mergeNET $(DESTDIR)/usr/lib/FWcnt/mergeNET + install -m 755 mergeLINK $(DESTDIR)/usr/lib/FWcnt/mergeLINK + install -m 755 ipfm_FWcnt $(DESTDIR)/usr/lib/FWcnt/ipfm_FWcnt install -d $(DESTDIR)/var/www/mrtg-rrd touch $(DESTDIR)/var/www/mrtg-rrd/.placeholder install -d $(DESTDIR)/var/lib/FWcnt;true @@ -25,6 +25,7 @@ install: fw2rrd install -d $(DESTDIR)/var/log/fwcnt touch $(DESTDIR)/var/log/.placeholder cp /dev/null $(DESTDIR)/etc/fwcnt.conf + cp /dev/null $(DESTDIR)/usr/lib/cgi-bin/mrtg-rrd.fwcnt.cgi #chown -R FWcnt $(DESTDIR)/var/lib/FWcnt/FW_rrd_database #chown -R FWcnt $(DESTDIR)/var/log/fwcnt #chown -R www-data $(DESTDIR)/var/www/mrtg-rrd @@ -32,6 +33,5 @@ install: fw2rrd #/var/log/fwcnt/ clean: - rm -f fw2rrd rm -f *~ diff --git a/README b/README index 97aec4c..fb8f54f 100644 --- a/README +++ b/README @@ -1,11 +1,39 @@ Detailed measuring system for wide range of IPs ----------------------------------------------- +Upgrading from < 0.6 +--------------------- + +Before 0.6 one rrd file per IP was used for in/out packets and one for in/out +bytes. For one C range 2 x 638 files was used. Starting version 0.6 one file +per C IP range is used. No automatic conversion is supported by installation +scripts. Before upgrading from version < 0.6 you can manually convert old +style rrd files to new by running: + +# /usr/lib/FWcnt/mergeLINK +# /usr/lib/FWcnt/mergeNET + +Next, check file permissions in /var/lib/FWcnt/FW_rrd_database/ files .. + +WARNING !!! Data collection can be damaged during conversion time, therefore +stop cron job before conversion. + +Debian users: + +If Debian preinst detects upgrade form 0.4 or 0.5 (before 0.4 no debian +version was released), automatic database conversion is prepared. Next, +postinst script runs automatic upgrade. Warning, this can take some time +(etc. 2 - 15 min per C range, depends on CPU). No data collection is runing +during conversion time. This automatic conversion is scheduled for removal in +fwcnt version >= 1.0. + + + "fast" install -------------- -for non debian users: -create FWcnt user, -uncommnent install rules +for non debian users: +create FWcnt user (by adduser or useradd), +uncomment install rules in Makefile #chown -R FWcnt $(DESTDIR)/var/lib/FWcnt/FW_rrd_database #chown -R www-data $(DESTDIR)/var/www/mrtg-rrd #cp cron.d $(DESTDIR)/etc/cron.d/FWcnt @@ -23,11 +51,13 @@ use "debuild" and create .deb package .. or get binary .deb package "fast" setup ------------ Debian users: all this is in postinst script, sample working config is -created automaticaly. +created automatically. -If You customize /etc/fwcnt.conf then run +If you have customized /etc/fwcnt.conf then run: /usr/lib/FWcnt/install_FWcnt -show http://YOUR_WEB/cgi-bin/mrtg-rrd.wrapper.cgi +for updating firewall counters chains and mrtg system configs + +check http://YOUR_WEB/cgi-bin/mrtg-rrd.wrapper.cgi non debian users: 1. copy this sample in /var/lib/FWcnt/etc/config (replace 192.168.0.0 with your @@ -39,31 +69,35 @@ cntNET 192.168.0.0 2. run /usr/lib/FWcnt/install_FWcnt -3. run /usr/lib/FWcnt/generate - -4. insert FWcnt chain in FORWARD chain (and if needed INPUT and OUTPUT chain) +3. insert FWcnt chain in FORWARD chain (and if needed INPUT and OUTPUT + chains) iptables -I FORWARD -j FWcnt -5. show http://YOUR_WEB/cgi-bin/mrtg-rrd.wrapper.cgi +4. check http://YOUR_WEB/cgi-bin/mrtg-rrd.wrapper.cgi + +"fast" config manual (config file directives): +---------------------------------------------- -"fast" config manual: ---------------------- One line per interface for "counting" interface statistics like this: + cntLINK eth0 one line per "C-class" net for counting all IP in this IP range: + cntNET 192.168.0.0 -(last number not needed .. etc cntNET 192.168.0 work fine) +(last number not needed .. etc cntNET 192.168.0 works fine) one line per sub "C-class" range for personalized view: + mrtgNET 192.168.42.128 25 create one page with 128 IPs from 192.168.42.128 to 192.168.42.255 default is 16 sub "C-class" - +NOIPFM +if present in config file, no ipfm like log is generated INTERNALS @@ -72,23 +106,23 @@ INTERNALS Part 1: ******* -Kernel counters in iptables is used for counting paket and byte count od -each measurments. +Kernel counters in iptables is used for counting packet and byte count. 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 +3. packet traverses 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 + 16(subchains = Ip/28)+2(Ip/29)+16 = 49 rules in one direction + + For reverse direction one more rule must be added. + Full C range bidirectional counting is counted by max 50 rules. + For each C class one more rule must be traversed for one direction. -for each C range exists this structure: +The following structure is created for each C range: match full ---+ rule subnet 0-127 @@ -128,33 +162,23 @@ range + rule subnet 0 - 63 -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). +Chain FWcnt is managed by init_FWcnt and clean_FWcnt programs. +clean_FWcnt erase all rules and subchains in FWcnt chain. +init_FWcnt set up rules for one C ranges of IPs for measurements. -Initialization in FW: +iptables-save -c is used for getting counters from FWcnt chains (check +FWcnt2rrd file for details of parsing) -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 +Example: to set up measurements for one C range 192.168.0.0 +init_FWcnt 192.168.0 -getting counters: - -get_FWcnt +Without argument this command reads configuration file and sets up counters +for all nets defined by keyword "cntNET" in config file (see below). -return 4 values per line .. paket count, bytes count, source IP destination IP +clean_FWcnt can be run with "force" option to clean all FWcnt rules from +firewall. Part 2 @@ -163,76 +187,52 @@ Part 2 counter database ---------------- -Text database used by mrtg is slow. RRD database is used for each counter -rule. +Text database used by mrtg is slow. FWcnt uses RRD database for each counter +rule. For minimizing files, all C range counters was moved into one rrd +file. -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. +Cron job reads all counters in FWcnt chain by calling "iptables-save -c". +Output of "iptables-save -c" is passed to FWcnt2rrd script. Output from +FWcnt counters is grouped to C ranges. For each C range rrd file is +updated. If database file does not exist, then FWcnt2rrd creates rrd file. +FWcnt2rrd must be run in working directory. Only iptables-save 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' someuser);fi +0-55/5 * * * * root if [ -x /usr/lib/FWcnt/FWcnt2rrd ]; then \ + (env LANG=C /sbin/iptables-save -c |su --shell=/bin/bash \ + -c '(cd /var/lib/FWcnt/FW_rrd_database/;\ + /usr/lib/FWcnt/FWcnt2rrd)' FWcnt );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 +In each C range rrd file 1276 data sources exists. For each IP in, out data +and packets is counted (256 IP * 4 = 1024 data sources). For each 8 IP +ranges, 16IP ranges ... 256IP range 4 more data sources exists. +Naming conversion: +192.168.0.rrd all counters for net 192.168.0/24 Part3 ***** -ethernet device measurment +ethernet device measurement -------------------------- 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. +are "counted". Only devices found in config file is used for measurement. -FWcnt2rrd first run fw2rrd, next check configuration file and for each -device create/update counter file. -example config file (onli part for devices) +example config file (device section only) --------------- cut -------------- cntLINK eth0 cntLINK vlan2 --------------- cut -------------- counter files with names: -eth0-p.rrd -eth0-b.rrd -vlan2-p.rrd -vlan2-b.rrd +iface.eth.0.rrd -counters for eth0 (packets and bytes) @@ -243,15 +243,16 @@ 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. +All needed config files for mrtg-rrd are automatically generated by +"install_FWcnt" command. -"generate" first creates one page with graphs for ethernet devices (based on -config file) and next graph for summary of one C class. +"install_FWcnt" first creates config for one page with graphs for ethernet +devices (based on config file) and next the graphs 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. +Below each graph for C class is subsummary graphs for /28 subnets (default) +or subnets of C class defined in config file by directive "mrtgNET". Both +variants of netmask can be used. Example config: @@ -273,59 +274,15 @@ mrtgNET 192.168.42.195 255.255.255.192 ---------------------------- cut ------------------------- -Keywork "cntNET" is used for definition of counter for "init_FWcnt" command. - - - - - - -SPECIAL -------- -fetching data from RRD: -summary for eth0 bytes: - -rrdtool fetch eth0-b.rrd AVERAGE -s $[`date +%s` - 86400 ] -e $[`date +%s` - -300 ]|awk '{A+=$2;B+=$3}END{print A" "B}' - - - - - -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 "-". +Keyword "cntNET" is used for definition of counter for "init_FWcnt" command. -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 "_"). +Contrib +------- -Special IP ranges etc may cause problems.. +FWcnt generates ipfm like log in /var/log/fwcnt directory. To disable this +feature insert "NOIPFM" directive to config file. To show ipfm log in +graphics, search internet for scr_ipfm (only change scr_ipfm log directory +to /var/log/fwcnt). -WARNING ! rrd files creation is done in working directory. diff --git a/TODO b/TODO deleted file mode 100644 index bd27e5f..0000000 --- a/TODO +++ /dev/null @@ -1,5 +0,0 @@ -* get name for IP/net - -* iptables counter setting (start/stop) from /etc/network/interfaces - (or other method .. ) - diff --git a/clean_FWcnt b/clean_FWcnt index ac77e5b..3e7ff7a 100755 --- a/clean_FWcnt +++ b/clean_FWcnt @@ -1,63 +1,78 @@ #!/bin/bash -iptables-save |gawk 'BEGIN{ +if [ ! -f /var/lib/FWcnt/etc/config ]; then + exit 0 +fi +iptables-save |gawk -v F=$1 'BEGIN{ while(getline <"/var/lib/FWcnt/etc/config"){ if($1 ~ "^cntNET") { split($2,IP,".") - Nd=sprintf("%d.%d.%d",IP[1],IP[2],IP[3]) Nx=sprintf("%02X%02X%02X",IP[1],IP[2],IP[3]) - NETx[Nx]=Nd - NETd[Nd]=Nx + if(F != "force") + hnets[Nx]=Nx } } } { - if($1 != "-A")next - if($2 != "FWcnt")next - i=1; - while(i0){ + hnetx=substr(hnet[2],1,6) + if(hnetx in hnets){ +# print "ignoring net "hnetx + }else{ + DEL[substr($1,2)]=1 + } + } +}END{ + CMD="iptables-restore -n" + print "*filter" | CMD + for (i in DEL){ + print ":"i" - [0:0]"|CMD } - else{ - print "Deleting "NN[1]"_"NN[2]"..." - C="iptables -D" - j=2 - while(j<=NF){ - C=C" "$j - j++ - } - if(system(C))print C - close(C) - C=sprintf("iptables -F %s_%s",NN[1],NN[2]) - if(system(C))print C - close(C) - C=sprintf("iptables -X %s_%s",NN[1],NN[2]) - if(system(C))print C - close(C) - k=0 - while(k<16){ - C=sprintf("iptables -F %s_%s%X",NN[1],NN[2],k) - if(system(C))print C - close(C) - C=sprintf("iptables -X %s_%s%X",NN[1],NN[2],k) - if(system(C))print C - close(C) - k++ - } + print "COMMIT"|CMD + close (CMD) + + + if(F=="force"){ + CMD="iptables -D FORWARD -j FWcnt 2>/dev/null" + system(CMD) + close(CMD) + CMD="iptables -D INPUT -j FWcnt 2>/dev/null" + system(CMD) + close(CMD) + CMD="iptables -D OUTPUT -j FWcnt 2>/dev/null " + system(CMD) + close(CMD) + CMD="iptables -F FWcnt 2>/dev/null" + system(CMD) + close(CMD) + CMD="iptables -F FWcntIN 2>/dev/null" + system(CMD) + close(CMD) + CMD="iptables -F FWcntOUT 2>/dev/null" + system(CMD) + close(CMD) + CMD="iptables -X FWcnt 2>/dev/null" + system(CMD) + close(CMD) + CMD="iptables -X FWcntIN 2>/dev/null" + system(CMD) + close(CMD) + CMD="iptables -X FWcntOUT 2>/dev/null" + system(CMD) + close(CMD) + } + for (i in DEL){ + CMD="iptables -X "i + system(CMD) + close(CMD) } + }' -if [ $# == 1 ]; then - if [ $1 == "force" ]; then - for i in `iptables-save |awk '{if($2 ~ "^FWcnt")print $2}'|sort -u`;do iptables -F $i ;done - iptables -D FORWARD -j FWcnt 2>/dev/null;true - iptables -D INPUT -j FWcnt 2>/dev/null;true - iptables -D OUTPUT -j FWcnt 2>/dev/null;true - for i in `iptables-save |awk '{if($1 ~ "^:FWcnt"){split($1,A,":");print A[2]}}'|sort -u`;do iptables -X $i ;done - fi -fi diff --git a/cnt2rrd.c b/cnt2rrd.c deleted file mode 100644 index 6b15a2f..0000000 --- a/cnt2rrd.c +++ /dev/null @@ -1,309 +0,0 @@ -/* 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 index afa6e3a..e0aaab7 100644 --- a/cron.d +++ b/cron.d @@ -1 +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)' FWcnt );fi +0-55/5 * * * * root if [ -x /usr/lib/FWcnt/FWcnt2rrd ]; then (env LANG=C /sbin/iptables-save -c |su --shell=/bin/bash -c '(cd /var/lib/FWcnt/FW_rrd_database/;/usr/lib/FWcnt/FWcnt2rrd)' FWcnt );fi diff --git a/debian/changelog b/debian/changelog index 95f0796..65440b8 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +fwcnt (0.6) unstable; urgency=low + + * one rrd file per C range + * getting counters by iptables-save + + -- Peter Popovec Tue, 4 Dec 2007 09:35:28 +0100 + fwcnt (0.5) unstable; urgency=low * added ipfm like log output from counters diff --git a/debian/control b/debian/control index 6cdd68d..c588db4 100644 --- a/debian/control +++ b/debian/control @@ -2,12 +2,13 @@ Source: fwcnt Section: unknown Priority: extra Maintainer: Peter Popovec -Build-Depends: debhelper (>= 5),librrd2-dev +Build-Depends: debhelper (>= 5) Standards-Version: 3.7.2 Package: fwcnt -Architecture: any -Depends: ${shlibs:Depends} ,gawk, mrtg-rrd, mrtg, iptables, cron, rrdtool +Architecture: all +Pre-Depends: mrtg-rrd, patch +Depends: gawk, iptables, cron, rrdtool Description: Firewall counter Detailed measuring system for wide range of IPs based on firewall rules (counters) and mrtg with rrd backend database. diff --git a/debian/docs b/debian/docs index 724e084..e845566 100644 --- a/debian/docs +++ b/debian/docs @@ -1,2 +1 @@ README -TODO diff --git a/debian/postinst b/debian/postinst index 2cc9ca3..1666aa5 100644 --- a/debian/postinst +++ b/debian/postinst @@ -20,12 +20,12 @@ set -e case "$1" in configure) + cp /usr/lib/cgi-bin/mrtg-rrd.cgi /usr/lib/cgi-bin/mrtg-rrd.fwcnt.cgi + patch /usr/lib/cgi-bin/mrtg-rrd.fwcnt.cgi /usr/lib/FWcnt/mrtg-rrd.fwcnt.cgi.patch + chmod 755 /usr/lib/cgi-bin/mrtg-rrd.fwcnt.cgi if ! getent group FWcnt > /dev/null; then - # echo Adding system group: mserv. addgroup --system --force-badname FWcnt fi - - # create mserv user if necessary. if ! getent passwd FWcnt > /dev/null; then adduser --system --force-badname --home /var/lib/FWcnt/FW_rrd_database/ --no-create-home --ingroup FWcnt FWcnt fi @@ -35,13 +35,18 @@ case "$1" in if [ ! -s /etc/fwcnt.conf ]; then echo "Creating initial /etc/fwcnt.conf" echo "# This is initial automatic generated file" >/etc/fwcnt.conf + echo "# after editing this file run /usr/lib/FWcnt/install_FWcnt" >>/etc/fwcnt.conf echo "# " >>/etc/fwcnt.conf route -n|awk -F'.' '{if(NR<3)next;if($0 ~ "^0.0.0.0")next;if($0 ~ "^127.0.0")next;print "cntNET "$1"."$2"."$3}'|sort -u >>/etc/fwcnt.conf - awk -F':' '{if($0 ~ ":")print "cntLINK "$1}' /proc/net/dev >>/etc/fwcnt.conf + awk -F':' '{if($0 ~ ":"){if($1 !~ "[:space:]*lo$")print "cntLINK "$1}}' /proc/net/dev >>/etc/fwcnt.conf fi ln -sf /etc/fwcnt.conf /var/lib/FWcnt/etc/config /usr/lib/FWcnt/install_FWcnt - /usr/lib/FWcnt/generate + if [ -e /var/lib/FWcnt/FW_rrd_database/upgrade_needed ]; then + echo "doing database upgrade... please wait" + su --shell=/bin/bash -c '(/usr/lib/FWcnt/mergeLINK;/usr/lib/FWcnt/mergeNET)' FWcnt + rm -f /var/lib/FWcnt/FW_rrd_database/upgrade_needed + fi ;; abort-upgrade|abort-remove|abort-deconfigure) ;; diff --git a/debian/preinst b/debian/preinst new file mode 100644 index 0000000..e70c9fd --- /dev/null +++ b/debian/preinst @@ -0,0 +1,42 @@ +#!/bin/sh +# preinst script for fwcnt +# +# see: dh_installdeb(1) + +set -e + +# summary of how this script can be called: +# * `install' +# * `install' +# * `upgrade' +# * `abort-upgrade' +# for details, see http://www.debian.org/doc/debian-policy/ or +# the debian-policy package + + +case "$1" in + install) + ;; + upgrade) + case "$2" in + "0.5"|"0.4") + touch /var/lib/FWcnt/FW_rrd_database/upgrade_needed + ;; + esac + ;; + + abort-upgrade) + ;; + + *) + echo "preinst called with unknown argument \`$1'" >&2 + exit 1 + ;; +esac + +# dh_installdeb will replace this with shell code automatically +# generated by other debhelper scripts. + +#DEBHELPER# + +exit 0 diff --git a/debian/prerm b/debian/prerm index 80af0bb..e7763ce 100644 --- a/debian/prerm +++ b/debian/prerm @@ -20,6 +20,7 @@ set -e case "$1" in remove) /usr/lib/FWcnt/clean_FWcnt force + rm -f /usr/lib/cgi-bin/mrtg-rrd.fwcnt.cgi ;; upgrade|deconfigure) ;; diff --git a/fw2rrd.c b/fw2rrd.c deleted file mode 100644 index 38d6592..0000000 --- a/fw2rrd.c +++ /dev/null @@ -1,344 +0,0 @@ -/* 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 -#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; - unsigned long i; - char *r_update[3] = { "update", NULL, NULL }; - int net = 0; - asprintf (&name, "%s-b.rrd", key); - i = strlen (name); - while (i > 0) - { - if (name[i] == '/') - { - net = 1; - 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); - if (!net) - { - time_t start, end, ti; - unsigned long step, ds_cnt; -/* unsigned long ii;*/ - rrd_value_t *data, *datai; - double inD = 0, outD = 0; - char **ds_namv; - char *r_fetch[5] = { "fetch", "--start", NULL, NULL, "AVERAGE" }; - asprintf (&r_buf, "%ld", (unsigned long) (time (NULL) / 86400) * 86400); - r_fetch[2] = r_buf; - r_fetch[3] = name; - if (rrd_fetch - (5, r_fetch, &start, &end, &step, &ds_cnt, &ds_namv, &data) != -1) - { - datai = data; - if (ds_cnt == 2) - { -/* printf (" "); - for (i = 0; i < ds_cnt; i++) - printf ("%20s", ds_namv[i]); - printf ("\n\n"); -*/ - for (ti = start + step; ti <= end; ti += step) - { -/* printf ("%10lu:", ti); - for (ii = 0; ii < ds_cnt; ii++) - printf (" %0.10e", *(datai++)); - printf ("\n"); -*/ - if (isfinite (*(datai))) - inD += *(datai) * 300; /* 300 seconds */ - datai++; - if (isfinite (*(datai))) - outD += *(datai) * 300; - datai++; - } - if ((inD + outD) > 1) - printf ("%-35s%15lld%15lld%15lld\n", key, - (unsigned long long) inD, (unsigned long long) outD, - (unsigned long long) (inD + outD)); - } - for (i = 0; i < ds_cnt; i++) - free (ds_namv[i]); - free (ds_namv); - free (data); - 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; - char outstr[200]; - time_t t; - struct tm *tmp; - t = time (NULL); - tmp = localtime (&t); - - - for (i = 0; i < HASHMAX; i++) - CNThash[i] = NULL; - data = stdin; - if (argc == 2) - { - if (NULL == (data = fopen (argv[1], "r"))) - { - fprintf (stderr, "Unable to open input file\n"); - return (1); - } - } - - strftime (outstr, sizeof (outstr), "%Y/%m/%d %H:%M:00", tmp); - - printf - ("# fwcnt 0.5 %s (local time) -- dump every 0d00:05:00 -- generated from iptables counters\n", - outstr); - printf ("# %-33s%15s%15s%15s\n", "Host", "In (bytes)", "Out (bytes)", - "Total (bytes)"); - - - 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); - } - } - printf ("# end of dump %s\n", outstr); - if (data != stdin) - fclose (data); - return (0); -} diff --git a/generate b/generate deleted file mode 100755 index 0334598..0000000 --- a/generate +++ /dev/null @@ -1,125 +0,0 @@ -#!/bin/bash -if [ $# -ge 1 ]; then - MAINT=$1 -else - MAINT="FWcnt" -fi -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:%s
\n\n",MAINT) >> 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:%s
\n\n",MAINT) >> 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 - } -}' MAINT=$MAINT - diff --git a/get_FWcnt b/get_FWcnt deleted file mode 100755 index 79ffeba..0000000 --- a/get_FWcnt +++ /dev/null @@ -1,33 +0,0 @@ -#!/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 index 2d216d0..656e3d1 100755 --- a/init_FWcnt +++ b/init_FWcnt @@ -16,86 +16,91 @@ fi if [ ${NET_C} -gt 255 ]; then NET_C=255 fi -iptables -N FWcnt 2>/dev/null NET_Ah=`printf "%02X" ${NET_A}` NET_Bh=`printf "%02X" ${NET_B}` NET_Ch=`printf "%02X" ${NET_C}` +( +echo "*filter" +#create chains for C range: +echo ":FWcntIN_${NET_Ah}${NET_Bh}${NET_Ch} - [0:0]" +echo ":FWcntOUT_${NET_Ah}${NET_Bh}${NET_Ch} - [0:0]" -iptables -L FWcntIN_${NET_Ah}${NET_Bh}${NET_Ch} -n 2>/dev/null >/dev/null -if [ $? == 0 ]; then - echo "Counters for already net ${NET_A}.${NET_B}.${NET_C}.0/24 exists...." -else -echo -n "${NET_A}.${NET_B}.${NET_C}:" -iptables -N FWcntIN_${NET_Ah}${NET_Bh}${NET_Ch} -iptables -N FWcntOUT_${NET_Ah}${NET_Bh}${NET_Ch} -echo -n "." +#create subchains for counters (/28) +i=0 +while [ $i -lt 16 ]; do + ih=`printf "%X" $i` + j=$[$i * 16 ] + echo ":FWcntIN_${NET_Ah}${NET_Bh}${NET_Ch}${ih} - [0:0]" + echo ":FWcntOUT_${NET_Ah}${NET_Bh}${NET_Ch}${ih} - [0:0]" + i=$[$i + 1 ] +done #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 -echo -n "." +echo "-A FWcntIN_${NET_Ah}${NET_Bh}${NET_Ch} -d ${NET_A}.${NET_B}.${NET_C}.0/255.255.255.128" +echo "-A FWcntIN_${NET_Ah}${NET_Bh}${NET_Ch} -d ${NET_A}.${NET_B}.${NET_C}.128/255.255.255.128" +echo "-A FWcntOUT_${NET_Ah}${NET_Bh}${NET_Ch} -s ${NET_A}.${NET_B}.${NET_C}.0/255.255.255.128" +echo "-A FWcntOUT_${NET_Ah}${NET_Bh}${NET_Ch} -s ${NET_A}.${NET_B}.${NET_C}.128/255.255.255.128" #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 -echo -n "." +echo "-A FWcntIN_${NET_Ah}${NET_Bh}${NET_Ch} -d ${NET_A}.${NET_B}.${NET_C}.0/255.255.255.192" +echo "-A FWcntIN_${NET_Ah}${NET_Bh}${NET_Ch} -d ${NET_A}.${NET_B}.${NET_C}.64/255.255.255.192" +echo "-A FWcntIN_${NET_Ah}${NET_Bh}${NET_Ch} -d ${NET_A}.${NET_B}.${NET_C}.128/255.255.255.192" +echo "-A FWcntIN_${NET_Ah}${NET_Bh}${NET_Ch} -d ${NET_A}.${NET_B}.${NET_C}.192/255.255.255.192" +echo "-A FWcntOUT_${NET_Ah}${NET_Bh}${NET_Ch} -s ${NET_A}.${NET_B}.${NET_C}.0/255.255.255.192" +echo "-A FWcntOUT_${NET_Ah}${NET_Bh}${NET_Ch} -s ${NET_A}.${NET_B}.${NET_C}.64/255.255.255.192" +echo "-A FWcntOUT_${NET_Ah}${NET_Bh}${NET_Ch} -s ${NET_A}.${NET_B}.${NET_C}.128/255.255.255.192" +echo "-A FWcntOUT_${NET_Ah}${NET_Bh}${NET_Ch} -s ${NET_A}.${NET_B}.${NET_C}.192/255.255.255.192" #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 -echo -n "." +echo "-A FWcntIN_${NET_Ah}${NET_Bh}${NET_Ch} -d ${NET_A}.${NET_B}.${NET_C}.0/255.255.255.224" +echo "-A FWcntIN_${NET_Ah}${NET_Bh}${NET_Ch} -d ${NET_A}.${NET_B}.${NET_C}.32/255.255.255.224" +echo "-A FWcntIN_${NET_Ah}${NET_Bh}${NET_Ch} -d ${NET_A}.${NET_B}.${NET_C}.64/255.255.255.224" +echo "-A FWcntIN_${NET_Ah}${NET_Bh}${NET_Ch} -d ${NET_A}.${NET_B}.${NET_C}.96/255.255.255.224" +echo "-A FWcntIN_${NET_Ah}${NET_Bh}${NET_Ch} -d ${NET_A}.${NET_B}.${NET_C}.128/255.255.255.224" +echo "-A FWcntIN_${NET_Ah}${NET_Bh}${NET_Ch} -d ${NET_A}.${NET_B}.${NET_C}.160/255.255.255.224" +echo "-A FWcntIN_${NET_Ah}${NET_Bh}${NET_Ch} -d ${NET_A}.${NET_B}.${NET_C}.192/255.255.255.224" +echo "-A FWcntIN_${NET_Ah}${NET_Bh}${NET_Ch} -d ${NET_A}.${NET_B}.${NET_C}.224/255.255.255.224" +echo "-A FWcntOUT_${NET_Ah}${NET_Bh}${NET_Ch} -s ${NET_A}.${NET_B}.${NET_C}.0/255.255.255.224" +echo "-A FWcntOUT_${NET_Ah}${NET_Bh}${NET_Ch} -s ${NET_A}.${NET_B}.${NET_C}.32/255.255.255.224" +echo "-A FWcntOUT_${NET_Ah}${NET_Bh}${NET_Ch} -s ${NET_A}.${NET_B}.${NET_C}.64/255.255.255.224" +echo "-A FWcntOUT_${NET_Ah}${NET_Bh}${NET_Ch} -s ${NET_A}.${NET_B}.${NET_C}.96/255.255.255.224" +echo "-A FWcntOUT_${NET_Ah}${NET_Bh}${NET_Ch} -s ${NET_A}.${NET_B}.${NET_C}.128/255.255.255.224" +echo "-A FWcntOUT_${NET_Ah}${NET_Bh}${NET_Ch} -s ${NET_A}.${NET_B}.${NET_C}.160/255.255.255.224" +echo "-A FWcntOUT_${NET_Ah}${NET_Bh}${NET_Ch} -s ${NET_A}.${NET_B}.${NET_C}.192/255.255.255.224" +echo "-A FWcntOUT_${NET_Ah}${NET_Bh}${NET_Ch} -s ${NET_A}.${NET_B}.${NET_C}.224/255.255.255.224" #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} + #cretae "goto" for /28 + echo "-A FWcntIN_${NET_Ah}${NET_Bh}${NET_Ch} -d ${NET_A}.${NET_B}.${NET_C}.${j}/255.255.255.240 -g FWcntIN_${NET_Ah}${NET_Bh}${NET_Ch}${ih}" + echo "-A FWcntOUT_${NET_Ah}${NET_Bh}${NET_Ch} -s ${NET_A}.${NET_B}.${NET_C}.${j}/255.255.255.240 -g FWcntOUT_${NET_Ah}${NET_Bh}${NET_Ch}${ih}" + i=$[$i + 1 ] +done + +i=0 +while [ $i -lt 16 ]; do + ih=`printf "%X" $i` + j=$[$i * 16 ] #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 + echo "-A FWcntIN_${NET_Ah}${NET_Bh}${NET_Ch}${ih} -d ${NET_A}.${NET_B}.${NET_C}.${j}/255.255.255.248" + echo "-A FWcntIN_${NET_Ah}${NET_Bh}${NET_Ch}${ih} -d ${NET_A}.${NET_B}.${NET_C}.$[${j} + 8 ]/255.255.255.248" + echo "-A FWcntOUT_${NET_Ah}${NET_Bh}${NET_Ch}${ih} -s ${NET_A}.${NET_B}.${NET_C}.${j}/255.255.255.248" + echo "-A FWcntOUT_${NET_Ah}${NET_Bh}${NET_Ch}${ih} -s ${NET_A}.${NET_B}.${NET_C}.$[${j} + 8 ]/255.255.255.248" #create counters for chunk 16 IP - echo -n "." 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 + echo "-A FWcntIN_${NET_Ah}${NET_Bh}${NET_Ch}${ih} -d ${NET_A}.${NET_B}.${NET_C}.$[ ${k} + ${j} ] -j RETURN" + echo "-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 -echo "" -fi +#add to parent +echo "-A FWcntIN -g FWcntIN_${NET_Ah}${NET_Bh}${NET_Ch} -d ${NET_A}.${NET_B}.${NET_C}.0/255.255.255.0" +echo "-A FWcntOUT -g FWcntOUT_${NET_Ah}${NET_Bh}${NET_Ch} -s ${NET_A}.${NET_B}.${NET_C}.0/255.255.255.0" +echo "COMMIT")|iptables-restore -n done - diff --git a/install_FWcnt b/install_FWcnt index 65194c2..ab71f5b 100755 --- a/install_FWcnt +++ b/install_FWcnt @@ -1,30 +1,173 @@ #!/bin/bash -/usr/lib/FWcnt/init_FWcnt -/usr/lib/FWcnt/clean_FWcnt +#regenerate mrtg configs +if [ $# -ge 1 ]; then + MAINT=$1 +else + MAINT="FWcnt" +fi +awk '{if($1=="cntNET"){split ($2,A,".");print A[1]"."A[2]"."A[3]".0"}}' 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:%s
\n\n",MAINT) >> 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:%s
\n\n",MAINT) >> 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"){ + match($2,"(.*)([[:digit:]]+)$",a) + print_target($2,"iface."a[1]"."a[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 + } +}' MAINT=$MAINT + +#create and flush initial firewall chains, create initial "goto" +iptables-restore -n <1){ + CMD="iptables -D "i" -j FWcnt" + print "deleting duplicate in "i" chain" + system(CMD) + close(CMD) + C[i]-- + } +} }' + +#Clear not needed chains +/usr/lib/FWcnt/clean_FWcnt diff --git a/ipfm_FWcnt b/ipfm_FWcnt new file mode 100755 index 0000000..31cac2d --- /dev/null +++ b/ipfm_FWcnt @@ -0,0 +1,34 @@ +#!/bin/bash +awk 'BEGIN{ +printf ("# fwcnt 0.6 %s (local time) -- dump every 0d00:05:00 -- generated from iptables counters\n", + strftime("%Y/%m/%d %H:%M:00")); + +printf ("# %-33s%15s%15s%15s\n", "Host", "In (bytes)", "Out (bytes)", "Total (bytes)"); +}' >/var/log/fwcnt/fwcnt-global.tmp + +while read tag value; do +if [ $tag == "cntNET" ]; then +rrdtool fetch /var/lib/FWcnt/FW_rrd_database/${value}.rrd AVERAGE --start `date +%s -d '0:0'`| +awk -v net=$value '{ +if(NR<3)next +i=NF-256*4+1 +j=0 +while(i<=NF){ + bi[j]+=300*strtonum($i) + bo[j]+=300*strtonum($(i+1)) + i+=4 + j++ +} +} +END{ +j=0; +while(j<256){ + if(bi[j]+bo[j]>0){ + printf ("%-35s%15d%15d%15d\n",net"."j,bi[j],bo[j],bi[j]+bo[j]) + } + j++ +} +}' +fi +done >/var/log/fwcnt/fwcnt-global.tmp +mv /var/log/fwcnt/fwcnt-global.tmp /var/log/fwcnt/ipfm-global-`date +%Y-%m-%d`.log diff --git a/merge b/merge new file mode 100755 index 0000000..ceeca8c --- /dev/null +++ b/merge @@ -0,0 +1,149 @@ +#!/bin/bash +awk 'BEGIN{ +file=0 +} +{ +split ($0,x,".") +fs[file]=x[4] +f[file++]="rrdtool dump /var/lib/FWcnt/FW_rrd_database/"$0"-b.rrd" +fs[file]=x[4] +f[file++]="rrdtool dump /var/lib/FWcnt/FW_rrd_database/"$0"-p.rrd" + +}END{ + f[0]|getline + print $0 + f[0]|getline + print $0 + f[0]|getline + print $0 + i=1 + while(i\n\t\t IP%si%s \n",and(i,1)? "p":"b",fs[i] + f[i]|getline ;print $0 + f[i]|getline ;print $0 + f[i]|getline ;print $0 + f[i]|getline ;print $0 + f[i]|getline ;print $0 + f[i]|getline ;print $0 + f[i]|getline ;print $0 + f[i]|getline ;print $0 + f[i]|getline ;print $0 + f[i]|getline ;print $0 + f[i]|getline ;print $0 + f[i]|getline + f[i]|getline + printf "\t\n\t\t IP%so%s \n",and(i,1)? "p":"b",fs[i] + f[i]|getline ;print $0 + f[i]|getline ;print $0 + f[i]|getline ;print $0 + f[i]|getline ;print $0 + f[i]|getline ;print $0 + f[i]|getline ;print $0 + f[i]|getline ;print $0 + f[i]|getline ;print $0 + f[i]|getline ;print $0 + f[i]|getline ;print $0 + f[i]|getline ;print $0 + i++ + } +printf "" +k=0 +#only first 8 RRAs +while(k<8){ +#CDP + i=0 + f[i]|getline ;printf "\t%s\n",$NF + f[i]|getline ;print $0 + f[i]|getline ;print $0 + f[i]|getline ;print $0 + f[i]|getline ;print $0 + f[i]|getline ;print $0 + f[i]|getline ;print $0 + f[i]|getline ;print $0 + + i=1 + while(i %s %s ",$1,$2,$3,$4,$5,$6,$7,$9,$11 + i=1 + while(i %s %s ",$9,$11 + i++ + } + printf "\n" + j++ +}#RRA database end + print $0 + f[0]|getline ;print $0 + i=1 + while(i /var/lib/FWcnt/FW_rrd_database/iface.$Name.$Num.rrd.xml + rrdtool restore /var/lib/FWcnt/FW_rrd_database/iface.$Name.$Num.rrd.xml /var/lib/FWcnt/FW_rrd_database/iface.$Name.$Num.rrd + rm /var/lib/FWcnt/FW_rrd_database/iface.$Name.$Num.rrd.xml + fi + fi +done < /var/lib/FWcnt/etc/config + diff --git a/mergeNET b/mergeNET new file mode 100755 index 0000000..b16c2b2 --- /dev/null +++ b/mergeNET @@ -0,0 +1,30 @@ +#!/bin/bash +while read tag value ; do + if [ $tag == "cntNET" ]; then + C=$value + if [ ! -f /var/lib/FWcnt/FW_rrd_database/$value.rrd ]; then + echo "Converting C range: $value" + (i=0 + k=8 + while [ $k -ge 0 ]; do + if [ $k -eq 2 ]; then + k=0 + fi + j=0 + while [ $j -lt 256 ]; do + mask="" + if [ $k -ne 0 ]; then + mask=`echo "_"$[ 32 - $k ]` + fi + xtarget=${j}""$mask + echo $C"."$xtarget + i=$[$i + 4 ] + j=$[$j + $[ 2 ** $k ]] + done + k=$[$k - 1 ] + done)|/usr/lib/FWcnt/merge > /var/lib/FWcnt/FW_rrd_database/$value.rrd.xml + rrdtool restore /var/lib/FWcnt/FW_rrd_database/$value.rrd.xml /var/lib/FWcnt/FW_rrd_database/$value.rrd + rm /var/lib/FWcnt/FW_rrd_database/$value.rrd.xml + fi + fi +done < /var/lib/FWcnt/etc/config diff --git a/mrtg-rrd.fwcnt.cgi.patch b/mrtg-rrd.fwcnt.cgi.patch new file mode 100644 index 0000000..9b5e2fb --- /dev/null +++ b/mrtg-rrd.fwcnt.cgi.patch @@ -0,0 +1,63 @@ +--- /usr/lib/cgi-bin/mrtg-rrd.cgi 2005-09-28 21:13:08.000000000 +0200 ++++ /usr/lib/cgi-bin/mrtg-rrd.fwcnt.cgi 2007-12-06 14:50:00.000000000 +0100 +@@ -518,7 +518,8 @@ + $dir = $cfg->{logdir} + if defined $cfg->{logdir}; + +- $target->{rrd} = $dir . '/' . $tdir . $name . '.rrd'; ++ my @namex = split(/\./, $name, -1); ++ $target->{rrd} = $dir . '/' . $tdir . $namex[0] . '.' . $namex[1] . '.' .$namex[2] . '.rrd'; + + %{$target->{options}} = () + unless defined %{$target->{options}}; +@@ -621,23 +622,24 @@ + unless defined $target->{shortlegend}; + } + ++ my @namey = split(/-/, $namex[3], -1); + if ($scale > 1) { +- push @args, "DEF:in0=$target->{rrd}:ds0:AVERAGE", ++ push @args, "DEF:in0=$target->{rrd}:IP". $namey[1] . "i" . $namey[0] . ":AVERAGE", + "CDEF:in=in0,$scale,*", +- "DEF:maxin0=$target->{rrd}:ds0:MAX", ++ "DEF:maxin0=$target->{rrd}:IP". $namey[1] . "i" . $namey[0] . ":MAX", + "CDEF:maxin=maxin0,$scale,*" + unless $noi; +- push @args, "DEF:out0=$target->{rrd}:ds1:AVERAGE", ++ push @args, "DEF:out0=$target->{rrd}:IP". $namey[1] . "o" . $namey[0] . ":AVERAGE", + "CDEF:out=out0,$scale,*", +- "DEF:maxout0=$target->{rrd}:ds1:MAX", ++ "DEF:maxout0=$target->{rrd}:IP". $namey[1] . "o" . $namey[0] . ":MAX", + "CDEF:maxout=maxout0,$scale,*" + unless $noo; + } else { +- push @args, "DEF:in=$target->{rrd}:ds0:AVERAGE", +- "DEF:maxin=$target->{rrd}:ds0:MAX" ++ push @args, "DEF:in=$target->{rrd}:IP". $namey[1] . "i" . $namey[0] . ":AVERAGE", ++ "DEF:maxin=$target->{rrd}:IP". $namey[1] . "i" . $namey[0] . ":MAX" + unless $noi; +- push @args, "DEF:out=$target->{rrd}:ds1:AVERAGE", +- "DEF:maxout=$target->{rrd}:ds1:MAX" ++ push @args, "DEF:out=$target->{rrd}:IP". $namey[1] . "o" . $namey[0] . ":AVERAGE", ++ "DEF:maxout=$target->{rrd}:IP". $namey[1] . "o" . $namey[0] . ":MAX" + unless $noo; + } + +@@ -731,7 +733,7 @@ + my $cfgref = { + refresh => 300, + interval => 5, +- icondir => $prefix ++ icondir => "/mrtg/" + }; + + read_mrtg_config($cfgfile, \%defaults, $cfgref, \$order); +@@ -992,6 +994,8 @@ +
<kas\@fi.muni.cz> + + ++patched for fwcnt-0.6 by ++Peter Popovec + + EOF + print '', "\n"; diff --git a/mrtg-rrd.wrapper.cgi b/mrtg-rrd.wrapper.cgi index 3564713..8e71817 100755 --- a/mrtg-rrd.wrapper.cgi +++ b/mrtg-rrd.wrapper.cgi @@ -29,7 +29,7 @@ END{ printf("no CFG %s\n",CFG); } else{ - C="MRTGRRDCONF="CFG" PATH_INFO="PATH_INFO" /usr/lib/cgi-bin/mrtg-rrd.cgi" + C="MRTGRRDCONF="CFG" PATH_INFO="PATH_INFO" /usr/lib/cgi-bin/mrtg-rrd.fwcnt.cgi" system(C) close(C) } -- 2.47.3