<HTML ><HEAD ><TITLE >Bandwidth meter</TITLE ><META NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.76b+ "><LINK REL="HOME" TITLE="Querying libiptc HOWTO" HREF="index.html"><LINK REL="PREVIOUS" TITLE="Functions to modify firewalling rules and statistics" HREF="mfunction.html"><LINK REL="NEXT" TITLE="Controlling flows" HREF="cflows.html"></HEAD ><BODY CLASS="SECT1" BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#840084" ALINK="#0000FF" ><DIV CLASS="NAVHEADER" ><TABLE SUMMARY="Header navigation table" WIDTH="100%" BORDER="0" CELLPADDING="0" CELLSPACING="0" ><TR ><TH COLSPAN="3" ALIGN="center" >Querying libiptc HOWTO</TH ></TR ><TR ><TD WIDTH="10%" ALIGN="left" VALIGN="bottom" ><A HREF="mfunction.html" ACCESSKEY="P" >Prev</A ></TD ><TD WIDTH="80%" ALIGN="center" VALIGN="bottom" ></TD ><TD WIDTH="10%" ALIGN="right" VALIGN="bottom" ><A HREF="cflows.html" ACCESSKEY="N" >Next</A ></TD ></TR ></TABLE ><HR ALIGN="LEFT" WIDTH="100%"></DIV ><DIV CLASS="SECT1" ><H1 CLASS="SECT1" ><A NAME="BMETER">13. Bandwidth meter</H1 ><P >In this chapter I am going to develop a simple bandwidth meter using the following functions from <EM >libiptc</EM >:</P ><P ></P ><UL ><LI ><P >To initialize the system: <EM >iptc_handle_t iptc_init(const char *tablename)</EM >.</P ></LI ><LI ><P > To catch from errors: <EM >const char *iptc_strerror(int err)</EM >.</P ></LI ><LI ><P > To iterate through the chains of the table: <EM >const char *iptc_first_chain(iptc_handle_t *handle)</EM > and <EM >const char *iptc_next_chain(iptc_handle_t *handle)</EM >.</P ></LI ><LI ><P > To read packet and byte counters for a specific rule: <EM >struct ipt_counters *iptc_read_counter(const ipt_chainlabel chain, unsigned int rulenum, iptc_handle_t *handle)</EM >.</P ></LI ></UL ><P >Also the function <EM >gettimeofday</EM > will be used to measure elapsed time and the function <EM >getopt</EM > to get options from the command line.</P ><P >I don't know really if the term <EM >bandwidth meter</EM > is well used here. I interpret <EM >bandwidth</EM > as a reference to a flow capacity; perhaps a better term could be <EM >flow meter</EM >.</P ><P >Here is the <EM >bandwidth meter</EM > <TT CLASS="FILENAME" >bw.c</TT >. It's well commented to be easy followed by everyone:</P ><TABLE BORDER="1" BGCOLOR="#E0E0E0" WIDTH="100%" ><TR ><TD ><FONT COLOR="#000000" ><PRE CLASS="SCREEN" >/* * How to use libiptc- program #4 * /usr/local/src/bw.c * By Leonardo Balliache - 04.09.2002 * e-mail: leonardo@opalsoft.net * --WELL COMMENTED-- to be easy followed by everyone. */ /* include files required */ #include <getopt.h> #include <sys/errno.h> #include <sys/time.h> #include <stdio.h> #include <fcntl.h> #include <stdlib.h> #include <string.h> #include <dlfcn.h> #include <time.h> #include <unistd.h> #include "libiptc/libiptc.h" #include "iptables.h" /* colors to differentiate chains measures */ #define RED "\033[41m\033[37m" #define GREEN "\033[42m\033[30m" #define ORANGE "\033[43m\033[30m" #define BLUE "\033[44m\033[37m" #define MAGENTA "\033[45m\033[37m" #define CYAN "\033[46m\033[30m" #define WHITE "\033[47m\033[30m" #define BLACK "\033[40m\033[37m" #define RESET "\033[00m" /* maximum number of chains to be processed */ #define MAXUSERCHAINS 7 /* time between measures in seconds; adjust as you like */ #define SLEEPTIME 1 /* structure to count bytes per chain */ struct bwcnt { int start; /* the chain was initialized */ u_int64_t icnt; /* bytes through; previous measure */ u_int64_t ocnt; /* bytes through; current measure */ double bw; /* bandwitdh (flow) on this chain */ }; /* function to calculate differences of time in seconds. * micro-seconds precision. */ double delta(struct timeval a, struct timeval b) { if (a.tv_usec & b.tv_usec) { a.tv_sec--; a.tv_usec += 1000000; } return a.tv_sec-b.tv_sec + (a.tv_usec-b.tv_usec)/1000000.0; } /* main function */ int main(int argc, char *argv[]) { int i, j, ok; double totbw; iptc_handle_t h; int c, act_bw = 0; const char *chain = NULL; const char *tablename = "filter"; struct timeval ti, to; struct bwcnt bw[MAXUSERCHAINS]; struct ipt_counters *counters; char *col[9] = { RED,GREEN,ORANGE,BLUE,MAGENTA,CYAN,WHITE,BLACK,RESET }; program_name = "bw"; program_version = NETFILTER_VERSION; /* check options * we have 2 options: * -c = display current flow (each SLEEPTIME). * -a = display average flow (from start); default option. */ while ((c = getopt (argc, argv, "ac")) != -1) switch (c) { case 'a': act_bw = 0; break; case 'c': act_bw = 1; break; case '?': if (isprint(optopt)) fprintf (stderr, "Unknown option `-%c'.\n", optopt); else fprintf (stderr,"Unknown option character `\\x%x'.\n",optopt); exit(1); default: abort(); } /* initialize array of chains */ memset(&bw, 0, MAXUSERCHAINS * sizeof(struct bwcnt)); /* get time to start meter on variable ti */ gettimeofday(&ti, NULL); /* fire meter loop */ if ( act_bw ) printf("Displaying current flow values ...\n"); else printf("Displaying average flow values ...\n"); /* forever loop; abort the program with ^C */ while ( 1 ) { /* you have to initialize for each measure to be done */ if ( !(h = iptc_init(tablename)) ) { printf("Error initializing: %s\n", iptc_strerror(errno)); exit(errno); } ok = 0; /* we start a new loop */ gettimeofday(&to, NULL); /* have a time shoot */ /* iterate through each chain of the table */ for (chain = iptc_first_chain(&h), i = 0; chain; chain = iptc_next_chain(&h)) { if ( iptc_builtin(chain, h) ) continue; /* if it is a built-in chain, ignore it */ /* ok, read the counters of this chain */ if ( !(counters = iptc_read_counter(chain, 0, &h)) ) { printf("Error reading %s: %s\n", chain, iptc_strerror(errno)); exit(errno); } /* check that we do not have more chains than we can process */ if ( i >= MAXUSERCHAINS ) { printf("Maximum of %d user chains exceeded!!\n", MAXUSERCHAINS); exit(1); } /* this chain counter has not been initialized; initialize it */ if ( bw[i].start == 0 ) { bw[i].icnt = counters->bcnt; bw[i].start = 1; } /* this chain has a previous measure; take the current one */ else { bw[i].ocnt = counters->bcnt; if ( bw[i].ocnt == bw[i].icnt ) /* no new bytes flowing? */ bw[i].bw = 0; /* flow is zero */ else /* flow in this chain is: * current bytes count (bw[i].octn) *minus* * previous bytes count (bw[i].icnt) *divided by* * 128.0 to convert bytes to kbits *and divided by* * difference in times in seconds *to get* * flow in kbits/sec that is what we want. */ bw[i].bw = (bw[i].ocnt - bw[i].icnt) / (128.0 * delta(to, ti)); /* do you want current flow of this chain? initialize previous * bytes count to current bytes count; we get the flow in last * SLEEPTIME elapsed time. */ if ( act_bw ) bw[i].icnt = bw[i].ocnt; ok = 1; /* ok, we have some measure to show */ } ++i; /* next chain, please */ } /* we iterate and i == 0; we do not have user chains at all */ if ( i == 0 ) { printf("No user chains to meter!!\n"); exit(1); } /* do you want to measure current flow? initialize previous time * to actual time; we get the time elapsed in last SLEEPTIME. */ if ( act_bw ) ti = to; /* do we have something to show? ok, display it */ if ( ok ) { totbw = 0; for ( j = 0; j < i; ++j ) { totbw = totbw + bw[j].bw; /* calculate total flow */ } printf("%s%6.1fk:%s ", col[7], totbw, col[8]); /* display total */ for ( j = 0; j < i; ++j ) { /* display flow of each chain in color */ printf("%s%6.1fk%s ", col[j], bw[j].bw, col[8]); } printf("\n"); } sleep(SLEEPTIME); /* rest a little; you go too fast */ } /* give us enough time in order to let some bytes flow */ exit(0); /* bye, we have our measures!! */ } /* main */</PRE ></FONT ></TD ></TR ></TABLE ><P >Write your program and compile as before:</P ><TABLE BORDER="1" BGCOLOR="#E0E0E0" WIDTH="100%" ><TR ><TD ><FONT COLOR="#000000" ><PRE CLASS="SCREEN" >bash# <B CLASS="COMMAND" >./ipt-cc bw</B ></PRE ></FONT ></TD ></TR ></TABLE ><P >Before using the meter we need to set our environment.</P ><P >First, we have to have at least 2 PCs connected in a network. This is our diagram configuration:</P ><TABLE BORDER="1" BGCOLOR="#E0E0E0" WIDTH="100%" ><TR ><TD ><FONT COLOR="#000000" ><PRE CLASS="SCREEN" >+--------+ eth0 eth0 +--------+ | PC #1 +-----------------+ PC #2 | +--------+ +--------+ eth0=192.168.1.1 eth0=192.168.1.2</PRE ></FONT ></TD ></TR ></TABLE ><P >Second, we need to install a very nice and useful package called <EM >netcat</EM > written by Hobbit. This <EM >excellent</EM > package will help us to inject and receive a flow of bytes between 2 NICs. If you don't have the package in your system, download it from <A HREF="http://rr.sans.org/audit/netcat.php" TARGET="_top" >http://rr.sans.org/audit/netcat.php</A >.</P ><P >The version that I use is <EM >1.10-277</EM >. To install it follow these instructions:</P ><TABLE BORDER="1" BGCOLOR="#E0E0E0" WIDTH="100%" ><TR ><TD ><FONT COLOR="#000000" ><PRE CLASS="SCREEN" >bash# <B CLASS="COMMAND" >cp netcat-1.10.tar.gz /usr/local/src</B > bash# <B CLASS="COMMAND" >tar xzvf netcat-1.10.tar.gz</B > bash# <B CLASS="COMMAND" >cd netcat-1.10</B ></PRE ></FONT ></TD ></TR ></TABLE ><P >My version requires to make a patch first; check yours if you have a file with a <EM >.dif</EM > extension and apply it too:</P ><TABLE BORDER="1" BGCOLOR="#E0E0E0" WIDTH="100%" ><TR ><TD ><FONT COLOR="#000000" ><PRE CLASS="SCREEN" >bash# <B CLASS="COMMAND" >patch -p0 -i netcat-1.10.dif</B ></PRE ></FONT ></TD ></TR ></TABLE ><P >Next compile the package using <EM >make</EM >:</P ><TABLE BORDER="1" BGCOLOR="#E0E0E0" WIDTH="100%" ><TR ><TD ><FONT COLOR="#000000" ><PRE CLASS="SCREEN" >bash# <B CLASS="COMMAND" >make linux</B ></PRE ></FONT ></TD ></TR ></TABLE ><P >Copy the binary <EM >nc</EM > to your user bin directory:</P ><TABLE BORDER="1" BGCOLOR="#E0E0E0" WIDTH="100%" ><TR ><TD ><FONT COLOR="#000000" ><PRE CLASS="SCREEN" >bash# <B CLASS="COMMAND" >cp nc /usr/bin</B ></PRE ></FONT ></TD ></TR ></TABLE ><P >And also to the second PC in your network:</P ><TABLE BORDER="1" BGCOLOR="#E0E0E0" WIDTH="100%" ><TR ><TD ><FONT COLOR="#000000" ><PRE CLASS="SCREEN" >bash# <B CLASS="COMMAND" >scp nc 192.168.1.2:/usr/bin</B ></PRE ></FONT ></TD ></TR ></TABLE ><P >We are going to use <EM >netcat</EM > to <SPAN CLASS="QUOTE" >"listen"</SPAN > to a flow of bytes from PC #2 and to <SPAN CLASS="QUOTE" >"talk"</SPAN > from PC #1. Using tty1 to tty4 consoles on PC #2 let's start <EM >netcat</EM > to listen from this PC. Go to PC #2 and in tty1 type:</P ><TABLE BORDER="1" BGCOLOR="#E0E0E0" WIDTH="100%" ><TR ><TD ><FONT COLOR="#000000" ><PRE CLASS="SCREEN" >bash# <B CLASS="COMMAND" >nc -n -v -l -s 192.168.1.2 -p 1001 >/dev/null</B ></PRE ></FONT ></TD ></TR ></TABLE ><P ><EM >netcat</EM > must respond with:</P ><TABLE BORDER="1" BGCOLOR="#E0E0E0" WIDTH="100%" ><TR ><TD ><FONT COLOR="#000000" ><PRE CLASS="SCREEN" >listening on [192.168.1.2] 1001 ...</PRE ></FONT ></TD ></TR ></TABLE ><P >This command started <EM >netcat</EM > to listen from address <EM >192.168.1.2</EM > using port number <EM >1001</EM >. Arguments are: <EM >-n</EM > = use numeric address identification; <EM >-v</EM > = verbose; <EM >-l</EM > = listen. All the flow that <EM >netcat</EM > receives in <EM >192.168.1.2:1001</EM > will be redirected to the <SPAN CLASS="QUOTE" >"black hole"</SPAN > in <TT CLASS="FILENAME" >/dev/null</TT >.</P ><P >Repeat the command in tty2, tty3 and tty4; change to tty2 using <B CLASS="KEYCAP" >ALT-F2</B > and after logging in write:</P ><TABLE BORDER="1" BGCOLOR="#E0E0E0" WIDTH="100%" ><TR ><TD ><FONT COLOR="#000000" ><PRE CLASS="SCREEN" >bash# <B CLASS="COMMAND" >nc -n -v -l -s 192.168.1.2 -p 1002 >/dev/null</B ></PRE ></FONT ></TD ></TR ></TABLE ><P >Now we are <SPAN CLASS="QUOTE" >"listening"</SPAN > to the same address but port number <EM >1002</EM >.</P ><P >Go on now with tty3:</P ><TABLE BORDER="1" BGCOLOR="#E0E0E0" WIDTH="100%" ><TR ><TD ><FONT COLOR="#000000" ><PRE CLASS="SCREEN" >bash# <B CLASS="COMMAND" >nc -n -v -l -s 192.168.1.2 -p 1003 >/dev/null</B ></PRE ></FONT ></TD ></TR ></TABLE ><P >And tty4:</P ><TABLE BORDER="1" BGCOLOR="#E0E0E0" WIDTH="100%" ><TR ><TD ><FONT COLOR="#000000" ><PRE CLASS="SCREEN" >bash# <B CLASS="COMMAND" >nc -n -v -l -s 192.168.1.2 -p 1004 >/dev/null</B ></PRE ></FONT ></TD ></TR ></TABLE ><P >Now we are listening in PC #2, address <EM >192.168.1.2</EM > in ports <EM >1001</EM >, <EM >1002</EM >, <EM >1003</EM > and <EM >1004</EM >.</P ><P >Come back to PC #1 and let's set the environment to allow <EM >iptables</EM > to help us to complete our tests:</P ><P >On PC #1, type the into tty1 as follows:</P ><TABLE BORDER="1" BGCOLOR="#E0E0E0" WIDTH="100%" ><TR ><TD ><FONT COLOR="#000000" ><PRE CLASS="SCREEN" >bash# <B CLASS="COMMAND" >iptables -F</B > bash# <B CLASS="COMMAND" >iptables -X</B > bash# <B CLASS="COMMAND" >iptables -N chn_1</B > bash# <B CLASS="COMMAND" >iptables -N chn_2</B > bash# <B CLASS="COMMAND" >iptables -N chn_3</B > bash# <B CLASS="COMMAND" >iptables -N chn_4</B > bash# <B CLASS="COMMAND" >iptables -A chn_1 -j ACCEPT</B > bash# <B CLASS="COMMAND" >iptables -A chn_2 -j ACCEPT</B > bash# <B CLASS="COMMAND" >iptables -A chn_3 -j ACCEPT</B > bash# <B CLASS="COMMAND" >iptables -A chn_4 -j ACCEPT</B > bash# <B CLASS="COMMAND" >iptables -A OUTPUT -o eth0 -p tcp --dport 1001 -j chn_1</B > bash# <B CLASS="COMMAND" >iptables -A OUTPUT -o eth0 -p tcp --dport 1002 -j chn_2</B > bash# <B CLASS="COMMAND" >iptables -A OUTPUT -o eth0 -p tcp --dport 1003 -j chn_3</B > bash# <B CLASS="COMMAND" >iptables -A OUTPUT -o eth0 -p tcp --dport 1004 -j chn_4</B ></PRE ></FONT ></TD ></TR ></TABLE ><P >These commands will:</P ><P ></P ><UL ><LI ><P >Flush all chains in table <EM >filter</EM >.</P ></LI ><LI ><P > Delete all user chains in table <EM >filter</EM >.</P ></LI ><LI ><P > Create user chains <EM >chn_1</EM >, <EM >chn_2</EM >, <EM >chn_3</EM > and <EM >chn_4</EM >.</P ></LI ><LI ><P > Establish a target <EM >ACCEPT</EM > in each user chain.</P ></LI ><LI ><P > Create 4 rules in chain <EM >OUTPUT</EM > that matches port numbers <EM >1001</EM > to <EM >1004</EM > and target it to user chains <EM >chn_1</EM > to <EM >chn_4</EM >.</P ></LI ></UL ><P >Now start the <EM >bw</EM > meter using current values:</P ><TABLE BORDER="1" BGCOLOR="#E0E0E0" WIDTH="100%" ><TR ><TD ><FONT COLOR="#000000" ><PRE CLASS="SCREEN" >bash# <B CLASS="COMMAND" >./bw -c</B ></PRE ></FONT ></TD ></TR ></TABLE ><P >It must respond with:</P ><TABLE BORDER="1" BGCOLOR="#E0E0E0" WIDTH="100%" ><TR ><TD ><FONT COLOR="#000000" ><PRE CLASS="SCREEN" >Displaying current flow values ... 0.0k: 0.0k 0.0k 0.0k 0.0k 0.0k: 0.0k 0.0k 0.0k 0.0k 0.0k: 0.0k 0.0k 0.0k 0.0k 0.0k: 0.0k 0.0k 0.0k 0.0k</PRE ></FONT ></TD ></TR ></TABLE ><P >It informs that measures are current flows. Every line is a measure taken each <EM >SLEEPTIME</EM > lapse (1 second in our program). First column (in black) are total flow, next columns (in red, green, orange and blue) are flows in chains <EM >chn_1</EM >, <EM >chn_2</EM >, <EM >chn_3</EM > and <EM >chn_4</EM > respectively. Of course we do not have any flow now. However let <EM >bw</EM > run and continue reading.</P ><P >Let's start now one of our byte flows; go to tty2 in PC #1 with <B CLASS="KEYCAP" >ALT-F2</B > and after logging in, type:</P ><TABLE BORDER="1" BGCOLOR="#E0E0E0" WIDTH="100%" ><TR ><TD ><FONT COLOR="#000000" ><PRE CLASS="SCREEN" >bash# <B CLASS="COMMAND" >yes 000000000000000000 | nc -n -v -s 192.168.1.1 -p 2001 192.168.1.2 1001</B ></PRE ></FONT ></TD ></TR ></TABLE ><P ><EM >netcat</EM > responds with:</P ><TABLE BORDER="1" BGCOLOR="#E0E0E0" WIDTH="100%" ><TR ><TD ><FONT COLOR="#000000" ><PRE CLASS="SCREEN" >(UNKNOWN) [192.168.1.2] 1000 (?) open</PRE ></FONT ></TD ></TR ></TABLE ><P >Now we have a flow of bytes from PC #1 to PC #2. <EM >yes</EM > generates a constant flow of zeroes; this flow is piped to <EM >netcat</EM > through address <EM >192.168.1.1</EM >, port <EM >2001</EM > and sends it to PC #2, address <EM >192.168.1.2</EM >, port <EM >1001</EM > (where PC #2 is listening).</P ><P >Check now the display of <EM >bw</EM > in tty1:</P ><TABLE BORDER="1" BGCOLOR="#E0E0E0" WIDTH="100%" ><TR ><TD ><FONT COLOR="#000000" ><PRE CLASS="SCREEN" >7653.2k: 7653.2k 0.0k 0.0k 0.0k 7829.5k: 7829.5k 0.0k 0.0k 0.0k 7786.7k: 7786.7k 0.0k 0.0k 0.0k 7892.1k: 7982.1k 0.0k 0.0k 0.0k</PRE ></FONT ></TD ></TR ></TABLE ><P >Your mileage can vary depending of the physical characteristics of your system. In mine I have a flow of aproximately 7700 kbits/sec in the first chain <EM >chn_1</EM > which corresponds to port number <EM >1001</EM > in PC #2.</P ><P >Let's start now the second bytes flow; go to tty3 in PC #1 with <B CLASS="KEYCAP" >ALT-F3</B > and after logging in, type:</P ><TABLE BORDER="1" BGCOLOR="#E0E0E0" WIDTH="100%" ><TR ><TD ><FONT COLOR="#000000" ><PRE CLASS="SCREEN" >bash# <B CLASS="COMMAND" >yes 000000000000000000 | nc -n -v -s 192.168.1.1 -p 2002 192.168.1.2 1002</B ></PRE ></FONT ></TD ></TR ></TABLE ><P ><EM >netcat</EM > responds with:</P ><TABLE BORDER="1" BGCOLOR="#E0E0E0" WIDTH="100%" ><TR ><TD ><FONT COLOR="#000000" ><PRE CLASS="SCREEN" >(UNKNOWN) [192.168.1.2] 1002 (?) open</PRE ></FONT ></TD ></TR ></TABLE ><P >Now we have 2 flows of bytes from PC #1 to PC #2; one from <EM >192.168.1.1:2001</EM > to <EM >192.168.1.2:1001</EM > and another from <EM >192.168.1.1:2002</EM > to <EM >192.168.1.2:1002</EM >.</P ><P >Now check the display of <EM >bw</EM > in tty1:</P ><TABLE BORDER="1" BGCOLOR="#E0E0E0" WIDTH="100%" ><TR ><TD ><FONT COLOR="#000000" ><PRE CLASS="SCREEN" >7819.6k: 4144.2k 3675.4k 0.0k 0.0k 8090.5k: 3923.9k 4166.6k 0.0k 0.0k 7794.7k: 3920.8k 3873.9k 0.0k 0.0k 7988.3k: 3754.6k 4233.7k 0.0k 0.0k</PRE ></FONT ></TD ></TR ></TABLE ><P >Now we have 2 flows; each of them is more or less 50% of the total flow going out of the computer. The Linux kernel tries to balance the bandwidth available between the 2 channels of output.</P ><P >To continue, start the 2 aditional flows through channels <EM >192.168.1.1:2003-192.168.1.2:1003</EM > and <EM >192.168.1.1:2004-192.168.1.2:1004</EM >.</P ><P >In tty4 type:</P ><TABLE BORDER="1" BGCOLOR="#E0E0E0" WIDTH="100%" ><TR ><TD ><FONT COLOR="#000000" ><PRE CLASS="SCREEN" >bash# <B CLASS="COMMAND" >yes 000000000000000000 | nc -n -v -s 192.168.1.1 -p 2003 192.168.1.2 1003</B ></PRE ></FONT ></TD ></TR ></TABLE ><P >In tty5 type:</P ><TABLE BORDER="1" BGCOLOR="#E0E0E0" WIDTH="100%" ><TR ><TD ><FONT COLOR="#000000" ><PRE CLASS="SCREEN" >bash# <B CLASS="COMMAND" >yes 000000000000000000 | nc -n -v -s 192.168.1.1 -p 2004 192.168.1.2 1004</B ></PRE ></FONT ></TD ></TR ></TABLE ><P >The display of <EM >bw</EM > in tty1 will be something like:</P ><TABLE BORDER="1" BGCOLOR="#E0E0E0" WIDTH="100%" ><TR ><TD ><FONT COLOR="#000000" ><PRE CLASS="SCREEN" >8120.6k: 1705.3k 2354.9k 1898.6k 2161.8k 7765.3k: 1634.2k 2560.2k 2011.4k 1559.5k 7911.9k: 1699.8k 2090.3k 1768.0k 2353.8k 8309.4k: 1734.5k 1999.7k 1999.9k 2575.3k</PRE ></FONT ></TD ></TR ></TABLE ><P >Total bandwidth is distributed between the 4 channels of flow.</P ></DIV ><DIV CLASS="NAVFOOTER" ><HR ALIGN="LEFT" WIDTH="100%"><TABLE SUMMARY="Footer navigation table" WIDTH="100%" BORDER="0" CELLPADDING="0" CELLSPACING="0" ><TR ><TD WIDTH="33%" ALIGN="left" VALIGN="top" ><A HREF="mfunction.html" ACCESSKEY="P" >Prev</A ></TD ><TD WIDTH="34%" ALIGN="center" VALIGN="top" ><A HREF="index.html" ACCESSKEY="H" >Home</A ></TD ><TD WIDTH="33%" ALIGN="right" VALIGN="top" ><A HREF="cflows.html" ACCESSKEY="N" >Next</A ></TD ></TR ><TR ><TD WIDTH="33%" ALIGN="left" VALIGN="top" >Functions to modify firewalling rules and statistics</TD ><TD WIDTH="34%" ALIGN="center" VALIGN="top" > </TD ><TD WIDTH="33%" ALIGN="right" VALIGN="top" >Controlling flows</TD ></TR ></TABLE ></DIV ></BODY ></HTML >