Commit e49ef8d3 authored by 's avatar
Browse files

Updates to appmon application (history, cleanup).

Tracker functions are now coloring packets



git-svn-id: file:///home/svn/mapi/trunk@831 8d5bb341-7cf1-0310-8cf6-ba355fef3186
parent 07cc5249
...@@ -17,6 +17,8 @@ ...@@ -17,6 +17,8 @@
//#include "../../mapi.h" //#include "../../mapi.h"
#include <mapi.h> #include <mapi.h>
#include "cgi_headers.h"
// TOP includes // TOP includes
#include <sys/socket.h> #include <sys/socket.h>
#include <netinet/in.h> #include <netinet/in.h>
...@@ -24,11 +26,6 @@ ...@@ -24,11 +26,6 @@
//#include "../../stdlib/topx.h" //#include "../../stdlib/topx.h"
#include <mapi/topx.h> #include <mapi/topx.h>
#define BASENAME "appmon" //change only this one
#define RRD_FILENAME BASENAME".rrd"
#define CGI_FILENAME BASENAME".cgi"
#define FORM_FILENAME BASENAME"_form.html"
#define TOP_FILENAME BASENAME"_top.html"
#define TOP_RESET_TIME 100 #define TOP_RESET_TIME 100
...@@ -36,7 +33,6 @@ static void terminate(); ...@@ -36,7 +33,6 @@ static void terminate();
void my_rrd_create(char *filename, int num); void my_rrd_create(char *filename, int num);
void my_rrd_update(char *, char *); void my_rrd_update(char *, char *);
int create_cgi(); int create_cgi();
int create_form();
void *commthread(void *threadid); void *commthread(void *threadid);
void create_flows(char *scope); void create_flows(char *scope);
void *process(); void *process();
...@@ -57,6 +53,9 @@ static char *progname; ...@@ -57,6 +53,9 @@ static char *progname;
int verbose; int verbose;
int refresh_time; int refresh_time;
int anonymize;
char *MonitorName = "Monitor";
int main(int argc, char **argv) { int main(int argc, char **argv) {
...@@ -67,7 +66,9 @@ int main(int argc, char **argv) { ...@@ -67,7 +66,9 @@ int main(int argc, char **argv) {
void sig_chld(int); void sig_chld(int);
verbose = 0; verbose = 0;
anonymize = 0;
refresh_time = 10; refresh_time = 10;
signal(SIGINT, terminate); signal(SIGINT, terminate);
signal(SIGQUIT, terminate); signal(SIGQUIT, terminate);
signal(SIGTERM, terminate); signal(SIGTERM, terminate);
...@@ -80,7 +81,7 @@ int main(int argc, char **argv) { ...@@ -80,7 +81,7 @@ int main(int argc, char **argv) {
} }
while((opt = getopt(argc, argv, "hv:i:")) != EOF) while((opt = getopt(argc, argv, "hva:i:n:")) != EOF)
{ {
switch(opt) switch(opt)
{ {
...@@ -90,6 +91,12 @@ int main(int argc, char **argv) { ...@@ -90,6 +91,12 @@ int main(int argc, char **argv) {
case 'i': case 'i':
refresh_time = atoi(optarg); refresh_time = atoi(optarg);
break; break;
case 'n':
MonitorName = optarg;
break;
case 'a':
anonymize = 1;
break;
case 'v': case 'v':
verbose = 1; verbose = 1;
break; break;
...@@ -136,8 +143,8 @@ void create_flows(char *scope) { ...@@ -136,8 +143,8 @@ void create_flows(char *scope) {
int i; int i;
char *remote_net; char *remote_net;
char tmpstr_in[512]; char tmpstr_in[2048];
char tmpstr_out[512]; char tmpstr_out[2048];
char tmpstr[100]; char tmpstr[100];
if (user_net_defined) if (user_net_defined)
...@@ -184,18 +191,18 @@ void create_flows(char *scope) { ...@@ -184,18 +191,18 @@ void create_flows(char *scope) {
if ((filter[i].type == F_BPF) &&(filter[i].f != NULL)) { // second check needed for "other" if ((filter[i].type == F_BPF) &&(filter[i].f != NULL)) { // second check needed for "other"
/* incoming traffic: remote -> local */ /* incoming traffic: remote -> local */
snprintf(tmpstr_in, 512, "(ip and src net %s and dst net %s and %s) or (vlan and src net %s and dst net %s and %s)", snprintf(tmpstr_in, 2048, "(ip and src net %s and dst net %s and %s) or (vlan and src net %s and dst net %s and %s)",
remote_net, local_net, filter[i].f, remote_net, local_net, filter[i].f); remote_net, local_net, filter[i].f, remote_net, local_net, filter[i].f);
/* outgoing traffic: local -> remote */ /* outgoing traffic: local -> remote */
snprintf(tmpstr_out, 512, "(ip and src net %s and dst net %s and %s) or (vlan and src net %s and dst net %s and %s)", snprintf(tmpstr_out, 2048, "(ip and src net %s and dst net %s and %s) or (vlan and src net %s and dst net %s and %s)",
local_net, remote_net, filter[i].f, local_net, remote_net, filter[i].f); local_net, remote_net, filter[i].f, local_net, remote_net, filter[i].f);
} }
else { else {
/* incoming traffic: remote -> local */ /* incoming traffic: remote -> local */
snprintf(tmpstr_in, 512, "(ip and src net %s and dst net %s) or (vlan and src net %s and dst net %s)", snprintf(tmpstr_in, 2048, "(ip and src net %s and dst net %s) or (vlan and src net %s and dst net %s)",
remote_net, local_net, remote_net, local_net); remote_net, local_net, remote_net, local_net);
/* outgoing traffic: local -> remote */ /* outgoing traffic: local -> remote */
snprintf(tmpstr_out, 512, "(ip and src net %s and dst net %s) or (vlan and src net %s and dst net %s)", snprintf(tmpstr_out, 2048, "(ip and src net %s and dst net %s) or (vlan and src net %s and dst net %s)",
local_net, remote_net, local_net, remote_net); local_net, remote_net, local_net, remote_net);
} }
...@@ -224,20 +231,12 @@ void create_flows(char *scope) { ...@@ -224,20 +231,12 @@ void create_flows(char *scope) {
free(remote_net); free(remote_net);
} }
static char *colors[] = {
"666666",
"00F500", "B800B8", "FFFF00", "CC9900",
"FF8000", "FF0000", "FF00EE", "0000FF",
"336666", "99CC00", "FF0000",
"9933FF", "33CCFF", "CCFFCC", "3300CC",
};
static char top_page[] = "\ static char top_page[] = "\
<html>\n<head>\n\ <html>\n<head>\n\
<META Http-Equiv=\"Cache-Control\" Content=\"no-cache\">\n\ <META Http-Equiv=\"Cache-Control\" Content=\"no-cache\">\n\
<META Http-Equiv=\"Pragma\" Content=\"no-cache\">\n\ <META Http-Equiv=\"Pragma\" Content=\"no-cache\">\n\
<META Http-Equiv=\"Expires\" Content=\"0\">\n\ <META Http-Equiv=\"Expires\" Content=\"0\">\n\
<META Http-Equiv=\"Refresh\" Content=\"1;url=./%s\">\ <META Http-Equiv=\"Refresh\" Content=\"10;url=./%s\">\
</head>\n<body>\n"; </head>\n<body>\n";
struct top_clients_t { struct top_clients_t {
...@@ -264,7 +263,25 @@ void sort_top(struct top_clients_t *top_res, unsigned int total) ...@@ -264,7 +263,25 @@ void sort_top(struct top_clients_t *top_res, unsigned int total)
qsort(top_res, total, sizeof(struct top_clients_t), compare); qsort(top_res, total, sizeof(struct top_clients_t), compare);
} }
char *anonimize_ip(struct in_addr ip)
{
char *ipc = inet_ntoa(ip);
char *temp = NULL;
if(anonymize == 1) {
temp = strrchr(ipc, '.');
temp++;
while(*temp != '\0') {
*temp = 'X';
temp++;
}
}
return ipc;
}
void *process() { void *process() {
struct stats_t { struct stats_t {
...@@ -417,8 +434,8 @@ void *process() { ...@@ -417,8 +434,8 @@ void *process() {
fprintf(fp, "<tr >\n"); fprintf(fp, "<tr >\n");
struct in_addr ip; struct in_addr ip;
ip.s_addr = (unsigned long int)in_top_clients[i].ip; ip.s_addr = (unsigned long int)in_top_clients[i].ip;
fprintf(fp, "<td align=left>%s</td>\n", inet_ntoa(ip)); fprintf(fp, "<td align=left>%s</td>\n", anonimize_ip(ip));
fprintf(fp, "<td align=center bgcolor=\"%s\"> %s </td>\n",colors[in_top_clients[i].tracker_no],in_top_clients[i].tracker_name); fprintf(fp, "<td align=center bgcolor=\"%s\"> %s </td>\n",filter[in_top_clients[i].tracker_no].color,in_top_clients[i].tracker_name);
fprintf(fp, "<td align=right>%.2lf Kbps</td>\n", in_top_clients[i].speed); fprintf(fp, "<td align=right>%.2lf Kbps</td>\n", in_top_clients[i].speed);
fprintf(fp, "</tr>\n"); fprintf(fp, "</tr>\n");
} }
...@@ -435,8 +452,8 @@ void *process() { ...@@ -435,8 +452,8 @@ void *process() {
fprintf(fp, "<tr >\n"); fprintf(fp, "<tr >\n");
struct in_addr ip; struct in_addr ip;
ip.s_addr = (unsigned long int)out_top_clients[i].ip; ip.s_addr = (unsigned long int)out_top_clients[i].ip;
fprintf(fp, "<td align=left>%s</td>\n", inet_ntoa(ip)); fprintf(fp, "<td align=left>%s</td>\n", anonimize_ip(ip));
fprintf(fp, "<td align=center bgcolor=\"%s\"> %s </td>\n",colors[out_top_clients[i].tracker_no],out_top_clients[i].tracker_name); fprintf(fp, "<td align=center bgcolor=\"%s\"> %s </td>\n", filter[out_top_clients[i].tracker_no].color,out_top_clients[i].tracker_name);
fprintf(fp, "<td align=right>%.2lf Kbps</td>\n", out_top_clients[i].speed); fprintf(fp, "<td align=right>%.2lf Kbps</td>\n", out_top_clients[i].speed);
fprintf(fp, "</tr>\n"); fprintf(fp, "</tr>\n");
...@@ -456,12 +473,12 @@ void *process() { ...@@ -456,12 +473,12 @@ void *process() {
struct in_addr ip; struct in_addr ip;
// IN // IN
ip.s_addr = (unsigned long int)ip_in_top_clients[i].ip; ip.s_addr = (unsigned long int)ip_in_top_clients[i].ip;
fprintf(fp, "<td align=left>%s</td>\n", inet_ntoa(ip)); fprintf(fp, "<td align=left>%s</td>\n", anonimize_ip(ip));
fprintf(fp, "<td align=right>%.2lf Kbps</td>\n", ip_in_top_clients[i].speed); fprintf(fp, "<td align=right>%.2lf Kbps</td>\n", ip_in_top_clients[i].speed);
// OUT // OUT
ip.s_addr = (unsigned long int)ip_out_top_clients[i].ip; ip.s_addr = (unsigned long int)ip_out_top_clients[i].ip;
fprintf(fp, "<td align=left>%s</td>\n", inet_ntoa(ip)); fprintf(fp, "<td align=left>%s</td>\n", anonimize_ip(ip));
fprintf(fp, "<td align=right>%.2lf Kbps</td>\n", ip_out_top_clients[i].speed); fprintf(fp, "<td align=right>%.2lf Kbps</td>\n", ip_out_top_clients[i].speed);
fprintf(fp, "</tr>\n"); fprintf(fp, "</tr>\n");
...@@ -478,98 +495,55 @@ void *process() { ...@@ -478,98 +495,55 @@ void *process() {
return 0; return 0;
} }
static char form1[] = "\ void print_common(FILE *fp, char *cwd)
<html>\n<head>\n\ {
<title>CGI-C Test Form</title>\n\ int i = 0;
<META Http-Equiv=\"Cache-Control\" Content=\"no-cache\">\n\
<META Http-Equiv=\"Pragma\" Content=\"no-cache\">\n\
<META Http-Equiv=\"Expires\" Content=\"%d\">\n\
</head>\n<body>\n";
static char form2[] = "\ if (user_net_defined)
<p><input name=\"update\" type=\"submit\" id=\"update\" value=\"update\">\n\ fprintf(fp, "--title \"Traffic Breakdown: %s <-> %s \"\n", local_net, user_net);
</form>\n\ else
</body>\n\ fprintf(fp, "--title \"Traffic Breakdown: %s\"\n", local_net);
</html>\n";
int create_form() { for(i=0; i<NUMFILTERS; ++i) {
int i; if (filter[i].state == INACTIVE)
FILE *fp; continue;
char cwd[512]; fprintf(fp, " DEF:flow%d_in=%s/%s:flow%d_in:AVERAGE\n", i, cwd, RRD_FILENAME, i);
char temp[1024]; fprintf(fp, " DEF:flow%d_out=%s/%s:flow%d_out:AVERAGE\n", i, cwd, RRD_FILENAME, i);
}
if((fp = fopen(FORM_FILENAME,"w")) == NULL){ /* in */
printf("\n---> ERROR: Can't create form file\n\n"); if (filter[0].state == ACTIVE) {
return -1; fprintf(fp, " AREA:flow%d_in#%s::\n", 0, "EEEEEE");
fprintf(fp, " LINE:flow%d_in#%s:\"%s\":\n", 0, filter[0].color, filter[0].name);
} }
chmod(FORM_FILENAME, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); fprintf(fp, " LINE:0\n");
getcwd(cwd, 512); //FIXME for (i=1; i<NUMFILTERS; ++i)
if (filter[i].state == ACTIVE)
fprintf(fp, " AREA:flow%d_in#%s:\"%s\":STACK\n", i, filter[i].color, filter[i].name);
/* out */
if (filter[0].state == ACTIVE) {
fprintf(fp, " AREA:flow%d_out#%s::\n", 0, "EEEEEE");
fprintf(fp, " LINE:flow%d_out#%s::\n", 0, filter[0].color);
}
fprintf(fp, " LINE:0\n");
for (i=1; i<NUMFILTERS; ++i)
if (filter[i].state == ACTIVE)
fprintf(fp, " AREA:flow%d_out#%s::STACK\n", i, filter[i].color);
fprintf(fp, " LINE:0#000000\n");
sprintf(temp, form1, refresh_time); fprintf(fp, ">\n</P>\n");
fprintf(fp, "%s", temp); fprintf(fp,"</center>\n</BODY>\n</HTML>\n");
fprintf(fp, "<h2>LOBSTER P2P Monitoring: ");
if (user_net_defined)
fprintf(fp, "traffic between %s and %s</h2>\n", local_net, user_net);
else
fprintf(fp, "traffic from/to %s </h2>\n", local_net);
fprintf(fp, "<form method=\"POST\" action=\"cgi-bin/appform.cgi\">\n");
if (user_net_defined)
fprintf(fp, "<p>subnet: <input type=\"text\" name=\"subnet\" value=\"%s\">\n", user_net);
else
fprintf(fp, "<p>subnet: <input type=\"text\" name=\"subnet\">\n");
fprintf(fp, "<p>filters: ");
for (i=0; i<NUMFILTERS; i++)
fprintf(fp, "<input type=\"checkbox\" name=\"filters\" value=\"%s\" %s>%s \n",
filter[i].name, (filter[i].state == ACTIVE) ? "checked" : " ", filter[i].name);
fprintf(fp, "%s", form2);
fclose(fp);
return 0;
} }
/*
<!-- <META HTTP-EQUIV=\"Refresh\" CONTENT=1> -->\n\
*/
// --width 600 --height 300 --lower-limit 0\n
static char cgi1[] = "\
#!/usr/bin/rrdcgi\n\
<HTML>\n<HEAD>\n\
<META HTTP-EQUIV=\"Pragma\" CONTENT=\"no-cache\">\n\
<META HTTP-EQUIV=\"Expires\" CONTENT=\"-1\">\n\
<script language=\"JavaScript\">\n\
<!--var time = null\n\
function move() {\n\
window.location = '"CGI_FILENAME"';\n\
} //-->\n\
</script>\n\
<style type=\"text/css\">\n\
<!-- body { background-color: #cccccc; } -->\n\
</style>\n\n\
</HEAD>\n<BODY onload=\"timer=setTimeout('move()',%d)\">\n<center>\n\
";
static char cgi2[] ="\
<h2>LOBSTER P2P Monitoring: traffic from/to 147.52 </h2>\
<P>\n<RRD::GRAPH\n\
../appmon.png\n\
--width 500 --height 300\n\
--imginfo '<IMG SRC=../%s WIDTH=%lu HEIGHT=%lu >'\n\
";
static char cgi3[] = "\
--end now --start end-%ds --lazy\n\
--slope-mode --interlaced --vertical-label \"outbound Mbit/s inbound\"\n";
/*
--font UNIT:10:/usr/share/fonts/truetype/msttcorefonts/Verdana.ttf\n\
--font TITLE:11:/usr/share/fonts/truetype/msttcorefonts/Verdana_Bold.ttf\n\
*/
int create_cgi() { int create_cgi() {
FILE *fp; FILE *fp;
char cwd[512]; char cwd[512];
char temp[4092]; char temp[4092];
int i; // HOUR
if((fp = fopen(CGI_FILENAME,"w")) == NULL){ if((fp = fopen(CGI_FILENAME,"w")) == NULL){
printf("\n---> ERROR: Can't create output file\n\n"); printf("\n---> ERROR: Can't create output file\n\n");
return -1; return -1;
...@@ -577,63 +551,89 @@ int create_cgi() { ...@@ -577,63 +551,89 @@ int create_cgi() {
chmod(CGI_FILENAME, S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH); chmod(CGI_FILENAME, S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);
getcwd(cwd, 512); //FIXME getcwd(cwd, 512); //FIXME
sprintf(temp, cgi1, refresh_time * 1000); sprintf(temp, cgiHour, MonitorName);
fprintf(fp, "%s", temp); fprintf(fp, "%s", temp);
fprintf(fp, "%s", cgi2); print_common(fp, cwd);
fclose(fp);
sprintf(temp, cgi3, refresh_time * 360); // 3 HOURs
if((fp = fopen("appmon3.cgi","w")) == NULL){
printf("\n---> ERROR: Can't create output file\n\n");
return -1;
}
chmod(CGI_FILENAME, S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);
getcwd(cwd, 512); //FIXME
sprintf(temp, cgiThree, MonitorName);
fprintf(fp, "%s", temp); fprintf(fp, "%s", temp);
print_common(fp, cwd);
fclose(fp);
if (user_net_defined) // 1 DAY
fprintf(fp, "--title \"Traffic Breakdown: %s <-> %s \"\n", local_net, user_net); if((fp = fopen("appmon24.cgi","w")) == NULL){
else printf("\n---> ERROR: Can't create output file\n\n");
fprintf(fp, "--title \"Traffic Breakdown: %s\"\n", local_net); return -1;
}
chmod(CGI_FILENAME, S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);
getcwd(cwd, 512); //FIXME
for(i=0; i<NUMFILTERS; ++i) { sprintf(temp, cgiDay, MonitorName);
if (filter[i].state == INACTIVE)
continue; fprintf(fp, "%s", temp);
fprintf(fp, " DEF:flow%d_in=%s/%s:flow%d_in:AVERAGE\n", i, cwd, RRD_FILENAME, i); print_common(fp, cwd);
fprintf(fp, " DEF:flow%d_out=%s/%s:flow%d_out:AVERAGE\n", i, cwd, RRD_FILENAME, i);
// fprintf(fp, " VDEF:f%d_in=flow%d_in,LAST\n", i, i ); fclose(fp);
// fprintf(fp, " VDEF:f%d_out=flow%d_out,LAST\n",i , i);
// 1 WEEK
if((fp = fopen("appmonWeek.cgi","w")) == NULL){
printf("\n---> ERROR: Can't create output file\n\n");
return -1;
} }
chmod(CGI_FILENAME, S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);
getcwd(cwd, 512); //FIXME
sprintf(temp, cgiWeek, MonitorName);
/* in */ fprintf(fp, "%s", temp);
if (filter[0].state == ACTIVE) { print_common(fp, cwd);
fprintf(fp, " AREA:flow%d_in#%s::\n", 0, "EEEEEE");
fprintf(fp, " LINE:flow%d_in#%s:\"%s\":\n", 0, colors[0], filter[0].name); fclose(fp);
}
fprintf(fp, " LINE:0\n"); // 1 MONTH
for (i=1; i<NUMFILTERS; ++i) if((fp = fopen("appmonMonth.cgi","w")) == NULL){
if (filter[i].state == ACTIVE) printf("\n---> ERROR: Can't create output file\n\n");
fprintf(fp, " AREA:flow%d_in#%s:\"%s\":STACK\n", i, colors[i], filter[i].name); return -1;
/* out */
if (filter[0].state == ACTIVE) {
fprintf(fp, " AREA:flow%d_out#%s::\n", 0, "EEEEEE");
fprintf(fp, " LINE:flow%d_out#%s::\n", 0, colors[0]);
} }
fprintf(fp, " LINE:0\n"); chmod(CGI_FILENAME, S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);
for (i=1; i<NUMFILTERS; ++i) getcwd(cwd, 512); //FIXME
if (filter[i].state == ACTIVE)
fprintf(fp, " AREA:flow%d_out#%s::STACK\n", i, colors[i]); sprintf(temp, cgiMonth, MonitorName);
fprintf(fp, " LINE:0#000000\n"); fprintf(fp, "%s", temp);
print_common(fp, cwd);
/* if(filter[0].state == ACTIVE) { fclose(fp);
fprintf(fp, " COMMENT:\"Incoming Total Traffic = \"\n");
fprintf(fp, " GPRINT:f0_in:\"%%6.2lf %%sbps\\n\"\n"); // 1 YEAR
fprintf(fp, " COMMENT:\"Outgoing Total Traffic = \"\n"); if((fp = fopen("appmonYear.cgi","w")) == NULL){
fprintf(fp, " GPRINT:f0_out:\"%%6.2lf %%sbps\\n\"\n"); printf("\n---> ERROR: Can't create output file\n\n");
return -1;
} }
*/ chmod(CGI_FILENAME, S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);
fprintf(fp, ">\n</P>\n"); getcwd(cwd, 512); //FIXME
sprintf(temp, cgiYear, MonitorName);
fprintf(fp, "%s", temp);
print_common(fp, cwd);
fprintf(fp,"</center>\n</BODY>\n</HTML>\n");
fclose(fp); fclose(fp);
return 0; return 0;
} }
...@@ -717,8 +717,9 @@ void terminate() { ...@@ -717,8 +717,9 @@ void terminate() {
static char usgtxt[] = "\ static char usgtxt[] = "\
%s: appmon: Network Traffic Classification tool using MAPI.\n\ %s: appmon: Network Traffic Classification tool using MAPI.\n\
Usage: %s [-h] localnet host:interface [-i time] [-v]\n\ Usage: %s [-h] [-a] localnet host:interface [-i time] [-v]\n\
-h this page\n\ -h this page\n\
-a anonymize IP addresses in TOP IPs frame\
-i time (in seconds) for reading the results\n\ -i time (in seconds) for reading the results\n\
-v verbose\n\ -v verbose\n\
"; ";
......
...@@ -11,26 +11,27 @@ struct filter_t { ...@@ -11,26 +11,27 @@ struct filter_t {
enum {F_BPF, F_TRACKER} type; enum {F_BPF, F_TRACKER} type;
char *f; char *f;
enum {ACTIVE, INACTIVE} state; enum {ACTIVE, INACTIVE} state;
char *color;
}; };
struct filter_t filter[] = { struct filter_t filter[] = {
{0,0,0,0,0,0, "Total", F_BPF, NULL, ACTIVE}, // this should always be first {0,0,0,0,0,0, "Total", F_BPF, NULL, ACTIVE, "666666"}, // this should always be first
{0,0,0,0,0,0, "HTTP", F_BPF, "(port 80 or port 443)", ACTIVE}, {0,0,0,0,0,0, "HTTP", F_BPF, "(port 80 or port 443)", ACTIVE, "00F500"},
{0,0,0,0,0,0, "SSH", F_BPF, "(port 22 or port 23 or port 107 or port 614 or port 992)", ACTIVE}, {0,0,0,0,0,0, "SSH", F_BPF, "(port 22 or port 23 or port 107 or port 614 or port 992)", ACTIVE, "B800B8"},
{0,0,0,0,0,0, "SMTP", F_BPF, "((tcp and port 25) or (udp and port 995))", ACTIVE}, {0,0,0,0,0,0, "SMTP", F_BPF, "((tcp and port 25) or (udp and port 995))", ACTIVE, "FFFF00"},
{0,0,0,0,0,0, "DNS", F_BPF, "port 53", ACTIVE}, {0,0,0,0,0,0, "DNS", F_BPF, "port 53", ACTIVE, "CC9900"},
{0,0,0,0,0,0, "NETBIOS", F_BPF, "(port 137 or port 138 or port 139 or port 445)", ACTIVE}, {0,0,0,0,0,0, "NETBIOS", F_BPF, "(port 137 or port 138 or port 139 or port 445)", ACTIVE, "FF8000"},
{0,0,0,0,0,0, "RTSP", F_BPF, "(port 554 or port 8554 or port 322)", ACTIVE}, {0,0,0,0,0,0, "RTSP", F_BPF, "(port 554 or port 8554 or port 322)", ACTIVE, "FF0000"},
{0,0,0,0,0,0, "ICMP", F_BPF, "icmp", ACTIVE}, {0,0,0,0,0,0, "ICMP", F_BPF, "icmp", ACTIVE, "FF00EE"},
{0,0,0,0,0,0, "OpenVPN", F_BPF, "port 1194", ACTIVE}, {0,0,0,0,0,0, "OpenVPN", F_BPF, "port 1194", ACTIVE, "0000FF"},
{0,0,0,0,0,0, "WoW", F_BPF, "port 3724", ACTIVE},