/*
 * 
 * trafficsqueezer.c -- Traffic Squeezer main program
 *
 * Author: Kiran K(Sathya Ravi Kiran Kumar Raja. K) 2006-2008
 *         kiran_cyberpro at yahoo dot com
 *
 *
 * Traffic Squeezer is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2, or (at your option) any
 * later version.
 *
 * Traffic Squeezer is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Zebra; see the file COPYING.  If not, write to the Free
 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 * 02111-1307, USA.
 */

#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <malloc.h>
#include <net/ethernet.h>
#include <netpacket/packet.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <string.h>
#include <sys/types.h>
#include <signal.h>
#include <linux/ipc.h>
#include <linux/msg.h>
#include <swill/swill.h>
#include <stdlib.h>
#include <unistd.h>

#include "socket.h"
#include "common.h"
#include "cli_parser.h"
#include "message.h"
#include "bucket.h"
#include "ingress_thread.h"
#include "egress_thread.h"
#include "web.h"

int stats_msgQ_id = ZERO;

char ingress_port[10];
char egress_port[10];

BYTE ingress_port_mac[MAC_ADDR_LEN];
BYTE egress_port_mac[MAC_ADDR_LEN];

BYTE ingress_port_dest_mac[MAC_ADDR_LEN];
BYTE egress_port_dest_mac[MAC_ADDR_LEN];

BYTE br_mac_addr[MAC_ADDR_LEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };

int ingress_port_sock_fd  = 0;
int egress_port_sock_fd = 0;


pthread_t ingress_thread;
pthread_t egress_thread;
pthread_t stats_thread;
pthread_t web_thread;


BYTEx2 bucket_size = MAX_BUCKET_PDU_SIZE;
int compress_enabled = FALSE;
int coalescing_enabled = FALSE;
int qos_enabled = FALSE;


ts_bucket_t ingress_bucket;

/*-b----------SWILL----------*/
/* Define this to the port where you want to listen: */
#define SIMPLE_PORT 8080

/* Define this to the number of iterations you want the server to run: */
#define SIMPLE_TOP 0

/* Define this to 1 if you wish to dump the raw request to stderr: */
#define SIMPLE_DUMP 0

/* Users can use the command line to define this to 1 to use SSL (https): */
static int use_ssl = 0;


static void dump_request(FILE* out)
{
#if defined(SIMPLE_DUMP) && (SIMPLE_DUMP > 0)
   fprintf(out,
           "Raw request:\n---------\n%s\n---------\n",
           swill_getrequest());
#endif
}

/* A function to return a password for the SSL certificate file */
int pwd_getter(char* buf, int maxlen)
{
   strcpy(buf, "password");
   return strlen(buf);
}


void print_html_intro(FILE *f)
{
   dump_request(stderr);
   web_get_intro_title(f);


   fprintf(f, "<font size=\"+1\" face=\"Verdana\" color=AA5088>\
                <center><u><b>Traffic Squeezer - Home</b></u></center></font><br>\n");

   fprintf(f, "<table border=0 cellpadding=0 cellspacing=0 style=\"font-family:verdana;font-size:90%\">");
   fprintf(f, "<tr><td><b>Settings:<b></td></tr>");
   fprintf(f, "<tr><td>Ingress Port</td><td align=left>%s %s</td></tr> \
               <tr><td>Egress Port</td><td align=left>%s %s</td></tr>", HTTP_TAB, ingress_port, HTTP_TAB, egress_port);
	
   fprintf(f, "<tr><td>Ingress Port MAC</td><td align=left>%s %02x:%02x:%02x:%02x:%02x:%02x</td></tr>\n", \
		HTTP_TAB, ingress_port_mac[0], \
		ingress_port_mac[1], ingress_port_mac[2], ingress_port_mac[3], \
		ingress_port_mac[4], ingress_port_mac[5]);

   fprintf(f, "<tr><td>Egress Port MAC</td><td align=left>%s %02x:%02x:%02x:%02x:%02x:%02x</td></tr>\n", \
		HTTP_TAB, egress_port_mac[0], \
        	egress_port_mac[1], egress_port_mac[2], egress_port_mac[3], \
        	egress_port_mac[4], egress_port_mac[5]);

   fprintf(f, "<tr><td>Compression</td><td aligh=left>%s", HTTP_TAB);
   if(compress_enabled)
	fprintf(f, " Enabled</td></tr>");
   else
	fprintf(f, " Disabled</td></tr>");

   fprintf(f, "<tr><td>Coalescing</td><td aligh=left>%s", HTTP_TAB);
   if(coalescing_enabled)
        fprintf(f, " Enabled</td></tr>");
   else
        fprintf(f, " Disabled</td></tr>");

   fprintf(f, "<tr><td><font color=gray>QoS</font></td><td aligh=left>%s", HTTP_TAB);
   if(qos_enabled)
        fprintf(f, "<font color=gray> Enabled (not supported yet)</font></td></tr>");
   else
        fprintf(f, "<font color=gray> Disabled (not supported yet)</font></td></tr>");

   fprintf(f, "</table><br>\n");
    
   fprintf(f, "<br><br><br><br><br><br><br><hr>\n");

   { //Mem info. & CPU load
	FILE  *mfp, *cfp;
	
	char tot_phy_mem[20];
        char used_phy_mem[20];
	char tot_swap_mem[20];
	char used_swap_mem[20];
	float tot_phy_mem_n = 0;
	float used_phy_mem_n = 0;
	float tot_swap_mem_n = 0;
        float used_swap_mem_n = 0;
	char line[120];
	float cpu_load = 0;

	mfp =  fopen("/proc/meminfo", "r");
	fgets(line, 120, mfp);
	fscanf(mfp, "%s", line);
	fscanf(mfp, "%s", tot_phy_mem);
	fscanf(mfp, "%s", used_phy_mem);
	fgets(line, 120, mfp);
	fscanf(mfp, "%s", line);
        fscanf(mfp, "%s", tot_swap_mem);
        fscanf(mfp, "%s", used_swap_mem);
	fclose(mfp);

	cfp = fopen("/proc/loadavg", "r");
	fscanf(cfp, "%s", line);
	cpu_load = atof(line) * 100; /* also convert into % */
	fclose(cfp);

	tot_phy_mem_n = atof(tot_phy_mem);
	used_phy_mem_n = atof(used_phy_mem);
	tot_swap_mem_n = atof(tot_swap_mem);
        used_swap_mem_n = atof(used_swap_mem);


	fprintf(f, "<table align=right><tr><td><table style=\"font-family:verdana;font-size:60%\"> <tr>\
                        <td border=0 width=120 height=10 cellspacing=0 cellpadding=0>CPU Load </td> \
                        <td><table border=2 cellspacing=0 cellpadding=0><tr> \
                                <td width=%f height=10 bgcolor=FF0033></td> \
                                <td width=%f height=10 bgcolor=DDDDDD></td> \
                            </tr> </table></td>\
                        <td border=0> %s[%0.1f%] Available</td></tr></table> \
			</td></tr>\n", \
			(cpu_load)/2, \
			(100-cpu_load)/2, \
			HTTP_TAB, (100-cpu_load));

        fprintf(f, "<tr><td><table style=\"font-family:verdana;font-size:60%\"> <tr>\
                        <td border=0 width=120 height=10 cellspacing=0 cellpadding=0>Physical Memory (%0.1f Mb)</td> \
                        <td><table border=2 cellspacing=0 cellpadding=0><tr> \
                                <td width=%f height=10 bgcolor=6600FF></td> \
                                <td width=%f height=10 bgcolor=DDDDDD></td> \
                            </tr> </table></td>\
                        <td border=0> %s[%0.1f%] Available</td></tr></table> \
                        </td></tr>\n", ((tot_phy_mem_n/1024)/1024), \
                        ((used_phy_mem_n/tot_phy_mem_n)*100)/2, \
                        ((tot_phy_mem_n-used_phy_mem_n)/tot_phy_mem_n*100)/2, \
                        HTTP_TAB, ((tot_phy_mem_n-used_phy_mem_n)/tot_phy_mem_n*100));
	
	fprintf(f, "<tr><td><table style=\"font-family:verdana;font-size:60%\"> <tr>\
                        <td border=0 width=120 height=10 cellspacing=0 cellpadding=0>Swap Memory (%0.1f Mb)</td> \
                        <td><table border=2 cellspacing=0 cellpadding=0><tr> \
                                <td width=%f height=10 bgcolor=006600></td> \
                                <td width=%f height=10 bgcolor=DDDDDD></td> \
                            </tr> </table></td>\
                        <td border=0> %s[%0.1f%] Available</td></tr></table> \
                        </td></tr></table>\n", ((tot_swap_mem_n/1024)/1024), \
                        ((used_swap_mem_n/tot_swap_mem_n)*100)/2, \
                        ((tot_swap_mem_n-used_swap_mem_n)/tot_swap_mem_n*100)/2, \
                        HTTP_TAB, ((tot_swap_mem_n-used_swap_mem_n)/tot_swap_mem_n*100));

   }
   fprintf(f, "<table border=0> \
                <tr> \
                        <td><center><img border=0 src=\"home.png\"></img></center></td> \
			<td><center><a href=\"settings.html\"><img border=0 src=\"configure.png\"></img></a></center></td> \
                        <td><center><a href=\"main_stats.html\"><img border=0 src=\"stats.png\"></img></a></center></td> \
                        <td><center><a href=\"help.html\"><img border=0 src=\"help.png\"></img></a></center></td> \
                </tr> \
                <tr> \
                        <td bgcolor=FF9933><center><b>Home</b></center></td> \
			<td><center>Settings</center></td> \
                        <td><center>Statistics</center></td> \
                        <td><center>Help</center></td> \
                </tr> \
                </table><br>");
   fprintf(f, "</body></html>\n");
}




/*--e---------SWILL----------*/




int main(int argc, char **argv)
{

    if(!init_file_parser())
	return FALSE;

    if(!parse(argc, argv))
	return FALSE;

    system("clear");
    show_intro();
    printf("\n Ingress Port : %s\n Egress Port  : %s\n", ingress_port, egress_port);

    memset(ingress_port_mac, 0x00, MAC_ADDR_LEN);
    memset(egress_port_mac, 0x00, MAC_ADDR_LEN);


    if(!create_sockets( &ingress_port_sock_fd, &egress_port_sock_fd, \
		ingress_port, egress_port, ingress_port_mac, egress_port_mac))
    {
	printf(" ERR: Sockets Creation.\n");
	return FALSE;
    }
    else
	printf("\n\a Sockets Creation Success!\n\n");


    printf(" Ingress Port MAC: ");   print_mac(ingress_port_mac); //printf("\n");
    printf(" Egress Port MAC : ");  print_mac(egress_port_mac);printf("\n\n");

    { //Initialize Swill
        use_ssl = 0;
        if (swill_init_ssl(SIMPLE_PORT, use_ssl, 0)) {
        printf("Traffic Squeezer listening on port %d, %susing SSL\n",\
             SIMPLE_PORT, use_ssl ? "" : "not ");

        /* If using SSL, we inform about our server certificate files. */
	/*if (use_ssl)
                swill_ssl_set_certfile(SIMPLE_BASE "server.crt",
                                SIMPLE_BASE "server.key",
                                &pwd_getter);
        } else {
                printf("Couldn't initialize the server.\n");
        exit(1);
	*/
        }

    }
    
    /* Set a default title for the pages. */
    swill_title("Traffic Squeezer");
    /* Serve files out of a directory */
    swill_directory("/usr/share/trafficsqueezer/web");

    /* Set a bunch of handlers. */
    swill_handle("intro.html", print_html_intro, 0);
    swill_handle("settings.html", print_html_settings, 0);
    swill_handle("comp_stats.html", print_html_comp_stats, 0);
    swill_handle("coal_stats.html", print_html_coal_stats, 0);
    swill_handle("qos_stats.html", print_html_qos_stats, 0);
    swill_handle("main_stats.html", print_html_main_stats, 0);
    swill_handle("help.html", print_html_help, 0);
    swill_handle("conf_coal.html", print_html_conf_coal, 0);




    pthread_create( &ingress_thread, NULL, ingress_thread_start, NULL);
    pthread_create( &egress_thread, NULL, egress_thread_start, NULL);
    pthread_create( &stats_thread, NULL, stats_thread_start, NULL);
    pthread_create( &web_thread, NULL, web_thread_start, NULL);
	
    pthread_join(ingress_thread);
  
    printf("\n");
    return TRUE;
}




