#!/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,":")){
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
-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
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
#/var/log/fwcnt/
clean:
- rm -f fw2rrd
rm -f *~
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
"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
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
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
-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
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)
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:
---------------------------- 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.
+++ /dev/null
-* get name for IP/net
-
-* iptables counter setting (start/stop) from /etc/network/interfaces
- (or other method .. )
-
#!/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(i<NR){
- if($i=="-j")
- split($(i+1),NN,"_")
- i++
- }
- if(NN[2] in NETx){
- #print "Net "NETx[NN[2]]
+ delete hnet
+ if($0 ~ "^:FWcntIN_"){
+ split($1,hnet,"_")
+ }
+ if($0 ~ "^:FWcntOUT_"){
+ split($1,hnet,"_")
+ }
+ if(length(hnet[2])>0){
+ 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
+++ /dev/null
-/* 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 <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <rrd.h>
-#ifdef DO_GETOPT_RESET
-#include <unistd.h>
-#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);
-}
-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
+fwcnt (0.6) unstable; urgency=low
+
+ * one rrd file per C range
+ * getting counters by iptables-save
+
+ -- Peter Popovec <popovec@fei.tuke.sk> Tue, 4 Dec 2007 09:35:28 +0100
+
fwcnt (0.5) unstable; urgency=low
* added ipfm like log output from counters
Section: unknown
Priority: extra
Maintainer: Peter Popovec <popovec@fei.tuke.sk>
-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.
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
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)
;;
--- /dev/null
+#!/bin/sh
+# preinst script for fwcnt
+#
+# see: dh_installdeb(1)
+
+set -e
+
+# summary of how this script can be called:
+# * <new-preinst> `install'
+# * <new-preinst> `install' <old-version>
+# * <new-preinst> `upgrade' <old-version>
+# * <old-preinst> `abort-upgrade' <new-version>
+# 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
case "$1" in
remove)
/usr/lib/FWcnt/clean_FWcnt force
+ rm -f /usr/lib/cgi-bin/mrtg-rrd.fwcnt.cgi
;;
upgrade|deconfigure)
;;
+++ /dev/null
-/* 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 <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <rrd.h>
-#include <math.h>
-#ifdef DO_GETOPT_RESET
-#include <unistd.h>
-#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);
-}
+++ /dev/null
-#!/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 </A><A HREF=\"%s\">\n",TARGET,IP,HREF) >> OUT
- }
- printf("Options[%s-b]: bits\n",TARGET)>>OUT
- printf("PageTop[%s-b]: <H1> Bytes to/from %s (%s)\n",TARGET,IP,IP) >> OUT
- printf(" %s</H1>\n <TABLE>\n <TR><TD>System:</TD><TD>router</TD></TR>\n",IP) >> OUT
- printf(" <TR><TD>Maintainer:</TD><TD>%s</TD></TR>\n </TABLE>\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]: <H1> Pkts to/from %s\n",TARGET,IP) >> OUT
- printf(" </H1>\n <TABLE>\n <TR><TD>System:</TD><TD>router</TD></TR>\n") >> OUT
- printf(" <TR><TD>Maintainer:</TD><TD>%s</TD></TR>\n </TABLE>\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<j){
- IP=netC"."k+i
- TARGET=IP
- NAME=IP
- print_target(IP,TARGET,NAME,TPx,HREF)
- printf("%s %s\n",TPx,TARGET) >>OUTx
- k++
- }
- i+=j
- }
-}' MAINT=$MAINT
-
+++ /dev/null
-#!/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)
- }
-}'
-
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
-
#!/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"}}'</var/lib/FWcnt/etc/config|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 </A><A HREF=\"%s\">\n",TARGET,IP,HREF) >> OUT
+ }
+ printf("Options[%s-b]: bits\n",TARGET)>>OUT
+ printf("PageTop[%s-b]: <H1> Bytes to/from %s (%s)\n",TARGET,IP,IP) >> OUT
+ printf(" %s</H1>\n <TABLE>\n <TR><TD>System:</TD><TD>router</TD></TR>\n",IP) >> OUT
+ printf(" <TR><TD>Maintainer:</TD><TD>%s</TD></TR>\n </TABLE>\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]: <H1> Pkts to/from %s\n",TARGET,IP) >> OUT
+ printf(" </H1>\n <TABLE>\n <TR><TD>System:</TD><TD>router</TD></TR>\n") >> OUT
+ printf(" <TR><TD>Maintainer:</TD><TD>%s</TD></TR>\n </TABLE>\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<j){
+ IP=netC"."k+i
+ TARGET=IP
+ NAME=IP
+ print_target(IP,TARGET,NAME,TPx,HREF)
+ printf("%s %s\n",TPx,TARGET) >>OUTx
+ k++
+ }
+ i+=j
+ }
+}' MAINT=$MAINT
+
+#create and flush initial firewall chains, create initial "goto"
+iptables-restore -n <<EOP
+*filter
+:FWcnt - [0:0]
+:FWcntIN - [0:0]
+:FWcntOUT - [0:0]
+-A FWcnt -j FWcntOUT
+-A FWcnt -j FWcntIN
+COMMIT
+EOP
+
+#install all C ranges
+/usr/lib/FWcnt/init_FWcnt
+
+#check INPUT OUTPUT and FORWARD chain for jump to FWcnt chain
iptables-save|awk 'BEGIN{
-C["FORWARD"]="iptables -I FORWARD -j FWcnt"
-C["INPUT"]="iptables -I INPUT -j FWcnt"
-C["OUTPUT"]="iptables -I OUTPUT -j FWcnt"
+C["FORWARD"]=0
+C["INPUT"]=0
+C["OUTPUT"]=0
}
{
if($1 != "-A")next
- if($0 ~ "FWcnt..?._")next
- if($0 !~ "FWcnt")next
- i=1;
- while(i<NR){
- if($i=="-j"){
- if($(i+1)=="FWcnt"){
- delete C[$2]
- }
- }
- i++
- }
+ if($2 != "INPUT" && $2 != "OUTPUT" && $2 != "FORWARD") next
+ if($NF != "FWcnt")next
+ #count rules
+ C[$2]++
}
END{
for( i in C ){
- system(C[i])
- close(C[i])
- }
+ if(C[i]<1){
+ CMD="iptables -I "i" -j FWcnt"
+ print "adding jump to "i" chain"
+ system(CMD)
+ close(CMD)
+ }
+ while(C[i]>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
--- /dev/null
+#!/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/lib/FWcnt/etc/config >>/var/log/fwcnt/fwcnt-global.tmp
+mv /var/log/fwcnt/fwcnt-global.tmp /var/log/fwcnt/ipfm-global-`date +%Y-%m-%d`.log
--- /dev/null
+#!/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<file){
+ f[i]|getline
+ f[i]|getline
+ f[i]|getline
+ i++
+ }
+ print""
+#skip
+ i=0
+ while(i<file){
+ f[i]|getline
+ f[i]|getline
+ f[i]|getline
+ i++
+ }
+#dumping data sources
+ i=0
+ while(i<file){
+ printf "\t<ds>\n\t\t<name> IP%si%s </name>\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<ds>\n\t\t<name> IP%so%s </name>\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 "<!-- Round Robin Archives -->"
+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<file){
+ f[i]|getline
+ f[i]|getline
+ f[i]|getline
+ f[i]|getline
+ f[i]|getline
+ f[i]|getline
+ f[i]|getline
+ f[i]|getline
+ i++
+ }
+ i=0
+ while(i<file){
+ 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 ;print $0
+ i++
+ }
+ i=0
+ f[i]|getline ;print $0
+ f[i]|getline ;print $0
+ i=1
+ while(i<file){
+ f[i]|getline
+ f[i]|getline
+ i++
+ }
+#RRA (max 900 lines)
+j=0
+while(j<900){
+ f[0]|getline
+ if($0 ~ "/database"){
+ i=1
+ while(i<file)
+ f[i++]|getline
+ break
+ }
+ printf "%s %s %s %s %s %s %s <row><v> %s </v><v> %s </v>",$1,$2,$3,$4,$5,$6,$7,$9,$11
+ i=1
+ while(i<file){
+ f[i]|getline
+ printf "<v> %s </v><v> %s </v>",$9,$11
+ i++
+ }
+ printf "</row>\n"
+ j++
+}#RRA database end
+ print $0
+ f[0]|getline ;print $0
+ i=1
+ while(i<file){
+ f[i]|getline
+ i++
+ }
+k++
+}#CDP+RRA
+f[0]|getline ;print $0
+
+}'
--- /dev/null
+#!/bin/bash
+while read tag value ; do
+ if [ $tag == "cntLINK" ]; then
+ #extract numeric part from device name
+ Num=`echo $value|awk '{match($0,"(.*)([[:digit:]]+)$",a);print a[2]}'`
+ #part before device number
+ Name=`echo $value|awk '{match($0,"(.*)([[:digit:]]+)$",a);print a[1]}'`
+ if [ ! -f /var/lib/FWcnt/FW_rrd_database/iface.$Name.$Num.rrd ]; then
+ echo "Converting interface: $value"
+ echo $value|/usr/lib/FWcnt/merge > /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
+
--- /dev/null
+#!/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
--- /dev/null
+--- /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 @@
+ <A HREF="mailto:kas\@fi.muni.cz"><kas\@fi.muni.cz></A>
+ </font></td>
+ </tr>
++<tr><td></td><td ALIGN=RIGHT><font FACE="Arial,Helvetica" SIZE=2>patched for <A HREF="http://zub.fei.tuke.sk/fwcnt/">fwcnt-0.6</A> by</font></td></tr>
++<tr><td></td><td ALIGN=RIGHT><font FACE="Arial,Helvetica" SIZE=2>Peter Popovec </font></td></tr>
+ </table>
+ EOF
+ print '<!--$Id: mrtg-rrd.cgi,v 1.35 2003/08/18 15:58:57 kas Exp $-->', "\n";
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)
}