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 @@
//#include "../../mapi.h"
#include <mapi.h>
#include "cgi_headers.h"
// TOP includes
#include <sys/socket.h>
#include <netinet/in.h>
......@@ -24,11 +26,6 @@
//#include "../../stdlib/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
......@@ -36,7 +33,6 @@ static void terminate();
void my_rrd_create(char *filename, int num);
void my_rrd_update(char *, char *);
int create_cgi();
int create_form();
void *commthread(void *threadid);
void create_flows(char *scope);
void *process();
......@@ -57,6 +53,9 @@ static char *progname;
int verbose;
int refresh_time;
int anonymize;
char *MonitorName = "Monitor";
int main(int argc, char **argv) {
......@@ -67,7 +66,9 @@ int main(int argc, char **argv) {
void sig_chld(int);
verbose = 0;
anonymize = 0;
refresh_time = 10;
signal(SIGINT, terminate);
signal(SIGQUIT, terminate);
signal(SIGTERM, terminate);
......@@ -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)
{
......@@ -90,6 +91,12 @@ int main(int argc, char **argv) {
case 'i':
refresh_time = atoi(optarg);
break;
case 'n':
MonitorName = optarg;
break;
case 'a':
anonymize = 1;
break;
case 'v':
verbose = 1;
break;
......@@ -136,8 +143,8 @@ void create_flows(char *scope) {
int i;
char *remote_net;
char tmpstr_in[512];
char tmpstr_out[512];
char tmpstr_in[2048];
char tmpstr_out[2048];
char tmpstr[100];
if (user_net_defined)
......@@ -184,18 +191,18 @@ void create_flows(char *scope) {
if ((filter[i].type == F_BPF) &&(filter[i].f != NULL)) { // second check needed for "other"
/* 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);
/* 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);
}
else {
/* 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);
/* 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);
}
......@@ -224,20 +231,12 @@ void create_flows(char *scope) {
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[] = "\
<html>\n<head>\n\
<META Http-Equiv=\"Cache-Control\" Content=\"no-cache\">\n\
<META Http-Equiv=\"Pragma\" Content=\"no-cache\">\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";
struct top_clients_t {
......@@ -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);
}
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() {
struct stats_t {
......@@ -417,8 +434,8 @@ void *process() {
fprintf(fp, "<tr >\n");
struct in_addr 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=center bgcolor=\"%s\"> %s </td>\n",colors[in_top_clients[i].tracker_no],in_top_clients[i].tracker_name);
fprintf(fp, "<td align=left>%s</td>\n", anonimize_ip(ip));
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, "</tr>\n");
}
......@@ -435,8 +452,8 @@ void *process() {
fprintf(fp, "<tr >\n");
struct in_addr 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=center bgcolor=\"%s\"> %s </td>\n",colors[out_top_clients[i].tracker_no],out_top_clients[i].tracker_name);
fprintf(fp, "<td align=left>%s</td>\n", anonimize_ip(ip));
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, "</tr>\n");
......@@ -456,12 +473,12 @@ void *process() {
struct in_addr ip;
// IN
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);
// OUT
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, "</tr>\n");
......@@ -478,98 +495,55 @@ void *process() {
return 0;
}
static char form1[] = "\
<html>\n<head>\n\
<title>CGI-C Test Form</title>\n\
<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";
void print_common(FILE *fp, char *cwd)
{
int i = 0;
static char form2[] = "\
<p><input name=\"update\" type=\"submit\" id=\"update\" value=\"update\">\n\
</form>\n\
</body>\n\
</html>\n";
if (user_net_defined)
fprintf(fp, "--title \"Traffic Breakdown: %s <-> %s \"\n", local_net, user_net);
else
fprintf(fp, "--title \"Traffic Breakdown: %s\"\n", local_net);
int create_form() {
int i;
FILE *fp;
char cwd[512];
char temp[1024];
for(i=0; i<NUMFILTERS; ++i) {
if (filter[i].state == INACTIVE)
continue;
fprintf(fp, " DEF:flow%d_in=%s/%s:flow%d_in:AVERAGE\n", i, cwd, RRD_FILENAME, i);
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){
printf("\n---> ERROR: Can't create form file\n\n");
return -1;
/* in */
if (filter[0].state == ACTIVE) {
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);
getcwd(cwd, 512); //FIXME
fprintf(fp, " LINE:0\n");
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, "<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,"</center>\n</BODY>\n</HTML>\n");
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() {
FILE *fp;
char cwd[512];
char temp[4092];
int i;
// HOUR
if((fp = fopen(CGI_FILENAME,"w")) == NULL){
printf("\n---> ERROR: Can't create output file\n\n");
return -1;
......@@ -577,63 +551,89 @@ int create_cgi() {
chmod(CGI_FILENAME, S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);
getcwd(cwd, 512); //FIXME
sprintf(temp, cgi1, refresh_time * 1000);
sprintf(temp, cgiHour, MonitorName);
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);
print_common(fp, cwd);
fclose(fp);
if (user_net_defined)
fprintf(fp, "--title \"Traffic Breakdown: %s <-> %s \"\n", local_net, user_net);
else
fprintf(fp, "--title \"Traffic Breakdown: %s\"\n", local_net);
// 1 DAY
if((fp = fopen("appmon24.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
for(i=0; i<NUMFILTERS; ++i) {
if (filter[i].state == INACTIVE)
continue;
fprintf(fp, " DEF:flow%d_in=%s/%s:flow%d_in:AVERAGE\n", i, cwd, RRD_FILENAME, i);
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 );
// fprintf(fp, " VDEF:f%d_out=flow%d_out,LAST\n",i , i);
sprintf(temp, cgiDay, MonitorName);
fprintf(fp, "%s", temp);
print_common(fp, cwd);
fclose(fp);
// 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 */
if (filter[0].state == ACTIVE) {
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);
}
fprintf(fp, " LINE:0\n");
for (i=1; i<NUMFILTERS; ++i)
if (filter[i].state == ACTIVE)
fprintf(fp, " AREA:flow%d_in#%s:\"%s\":STACK\n", i, colors[i], 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, colors[0]);
fprintf(fp, "%s", temp);
print_common(fp, cwd);
fclose(fp);
// 1 MONTH
if((fp = fopen("appmonMonth.cgi","w")) == NULL){
printf("\n---> ERROR: Can't create output file\n\n");
return -1;
}
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, colors[i]);
chmod(CGI_FILENAME, S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);
getcwd(cwd, 512); //FIXME
sprintf(temp, cgiMonth, MonitorName);
fprintf(fp, " LINE:0#000000\n");
fprintf(fp, "%s", temp);
print_common(fp, cwd);
/* if(filter[0].state == ACTIVE) {
fprintf(fp, " COMMENT:\"Incoming Total Traffic = \"\n");
fprintf(fp, " GPRINT:f0_in:\"%%6.2lf %%sbps\\n\"\n");
fprintf(fp, " COMMENT:\"Outgoing Total Traffic = \"\n");
fprintf(fp, " GPRINT:f0_out:\"%%6.2lf %%sbps\\n\"\n");
fclose(fp);
// 1 YEAR
if((fp = fopen("appmonYear.cgi","w")) == NULL){
printf("\n---> ERROR: Can't create output file\n\n");
return -1;
}
*/
fprintf(fp, ">\n</P>\n");
chmod(CGI_FILENAME, S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);
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);
return 0;
}
......@@ -717,8 +717,9 @@ void terminate() {
static char usgtxt[] = "\
%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\
-a anonymize IP addresses in TOP IPs frame\
-i time (in seconds) for reading the results\n\
-v verbose\n\
";
......
......@@ -11,26 +11,27 @@ struct filter_t {
enum {F_BPF, F_TRACKER} type;
char *f;
enum {ACTIVE, INACTIVE} state;
char *color;
};
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, "HTTP", F_BPF, "(port 80 or port 443)", 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},
{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, "DNS", F_BPF, "port 53", ACTIVE},
{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, "RTSP", F_BPF, "(port 554 or port 8554 or port 322)", ACTIVE},
{0,0,0,0,0,0, "ICMP", F_BPF, "icmp", ACTIVE},
{0,0,0,0,0,0, "OpenVPN", F_BPF, "port 1194", ACTIVE},
{0,0,0,0,0,0, "WoW", F_BPF, "port 3724", ACTIVE},
{0,0,0,0,0,0, "FTP", F_TRACKER, "TRACK_FTP", ACTIVE},
{0,0,0,0,0,0, "Gnutella", F_TRACKER, "TRACK_GNUTELLA", ACTIVE},
{0,0,0,0,0,0, "BitTorrent", F_TRACKER, "TRACK_TORRENT", ACTIVE},
{0,0,0,0,0,0, "eDonkey", F_TRACKER, "TRACK_EDONKEY", ACTIVE},
{0,0,0,0,0,0, "DC++", F_TRACKER, "TRACK_DC", ACTIVE},
{0,0,0,0,0,0, "IP-in-IP", F_BPF, "ip[9] == 4", ACTIVE},
// {0,0,0,0,0,0, "IP-in-IP", F_TRACKER, "TRACK_IPOVERIP", ACTIVE},
{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, "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, "B800B8"},
{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, "CC9900"},
{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, "FF0000"},
{0,0,0,0,0,0, "ICMP", F_BPF, "icmp", ACTIVE, "FF00EE"},
{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, "336666"},
{0,0,0,0,0,0, "FTP", F_TRACKER, "TRACK_FTP", ACTIVE, "99CC00"},
{0,0,0,0,0,0, "Gnutella", F_TRACKER, "TRACK_GNUTELLA", ACTIVE, "FF0000"},
{0,0,0,0,0,0, "BitTorrent", F_TRACKER, "TRACK_TORRENT", ACTIVE, "9933FF"},
{0,0,0,0,0,0, "eDonkey", F_TRACKER, "TRACK_EDONKEY", ACTIVE, "33CCFF"},
{0,0,0,0,0,0, "DC++", F_TRACKER, "TRACK_DC", ACTIVE, "CCFFCC"},
{0,0,0,0,0,0, "IP-in-IP", F_BPF, "ip[9] == 4", ACTIVE, "3300CC"},
{0,0,0,0,0,0, "MAPI", F_BPF, "tcp and port == 2233", ACTIVE, "CCFF99"},
};
#define NUMFILTERS (int)(sizeof(filter)/sizeof(filter[0]))
#ifndef __CGI_HEADERS_H__
#define __CGI_HEADERS_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"
static char cgiHour[] = "\
#!/usr/bin/rrdcgi\n\
<HTML>\n<HEAD>\n\
<META HTTP-EQUIV=\"Pragma\" CONTENT=\"no-cache\">\n\
<META Http-Equiv=\"Expires\" Content=\"10\">\n\
<META Http-Equiv=\"Refresh\" Content=\"10;url=./appmon.cgi\">\
<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>\n<center>\n\
<h2>LOBSTER P2P Monitoring: traffic from/to %s (1 hour) </h2>\
<h3> (10 second average) </h3>\
<table align=\"center\"><hr>\
<hd><a href=\"appmon.cgi\">1 hour</a></hd> \
<hd><a href=\"appmon3.cgi\">3 hour</a></hd> \
<hd><a href=\"appmon24.cgi\">1 day</a></hd> \
<hd><a href=\"appmonWeek.cgi\">1 Week</a></hd> \
<hd><a href=\"appmonMonth.cgi\">1 Month</a></hd> \
<hd><a href=\"appmonYear.cgi\">1 Year</a></hd> \
</hr></table>\
<P>\n<RRD::GRAPH\n\
../appmon.png\n\
--width 500 --height 300\n\
--imginfo '<IMG SRC=../%s WIDTH=%lu HEIGHT=%lu >'\n\
--end now --start end-3600s --lazy\n\
--slope-mode --interlaced --vertical-label \"outbound Mbit/s inbound\"\n";
static char cgiThree[] = "\
#!/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()',10000)\">\n<center>\n\
<h2>LOBSTER P2P Monitoring: traffic from/to %s (3 hours)</h2>\
<h3> (1 minute average) </h3>\
<table align=\"center\"><hr>\
<table align=\"center\"><hr>\
<hd><a href=\"appmon.cgi\">1 hour</a></hd> \
<hd><a href=\"appmon3.cgi\">3 hour</a></hd> \
<hd><a href=\"appmon24.cgi\">1 day</a></hd> \
<hd><a href=\"appmonWeek.cgi\">1 Week</a></hd> \
<hd><a href=\"appmonMonth.cgi\">1 Month</a></hd> \
<hd><a href=\"appmonYear.cgi\">1 Year</a></hd> \
</hr></table>\
<P>\n<RRD::GRAPH\n\
../appmon3hours.png\n\
--width 500 --height 300\n\
--imginfo '<IMG SRC=../%s WIDTH=%lu HEIGHT=%lu >'\n\
--end now --start end-3h --lazy\n\
--slope-mode --interlaced --vertical-label \"outbound Mbit/s inbound\"\n";
static char cgiDay[] = "\
#!/usr/bin/rrdcgi\n\
<HTML>\n<HEAD>\n\
<META HTTP-EQUIV=\"Pragma\" CONTENT=\"no-cache\">\n\
<script language=\"JavaScript\">\n\
<!--var time = null\n\
function move() {\n\
window.location = '"CGI_FILENAME"';\n\
} //-->\n\
</script>\n\