/*
	**
	** htmlfe.c 
	**
	** HTML report frontend to network traffic visualiser
	**
	** Copyright 1998 Damien Miller <dmiller@ilogic.com.au>
	**
	** This software is licensed under the terms of the GNU General 
	** Public License (GPL). Please see the file COPYING for details.
	** 
	** $Id: htmlfe.c,v 1.3 1998/12/01 01:02:00 dmiller Exp $
	**
 */

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <signal.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include "htmlfe.h"
#include "util.h"
#include "summary-sort.h"

/* Prototypes */
static void print_host(host_t *host, GHashTable *peers, unsigned int max_peers, int peer_sort_mode, int peer_reverse);
static void print_peers(GHashTable *peers, u_int64_t *peer_keys, unsigned int num_peers, unsigned int max_peers, int peer_sort_mode, int peer_reverse);
static void format_hostname(host_t *host, char *s, size_t s_len);
static const char *format_time(time_t t);

/* Displays summary of network traffic */
void html_display_summary(summary_t *p, unsigned int max_hosts, int host_sort_mode, int host_reverse, unsigned int max_peers, int peer_sort_mode, int peer_reverse)
{
	host_list_t		*sorted_hosts;
	host_list_t		*last_sh;
	
	setlinebuf(stdout);
	
	sorted_hosts = sort_hosts(p->hosts, max_hosts, host_sort_mode, host_reverse);

	printf("
<HTML>
	<HEAD>
		<TITLE>traffic-vis report</TITLE>
		<STYLE TYPE=\"text/css\"><!--
			BODY { font-family: helvetica, arial, sans-serif; }
			TD, TH { font-family: helvetica, arial, sans-serif; }
			H { font-family: helvetica, arial, sans-serif; }
		--></STYLE>
	</HEAD>
	<BODY BGCOLOR=\"#FFFFFF\">
		<TABLE WIDTH=\"90%%\" ALIGN=\"CENTER\">
			<TR>
				<TD ALIGN=\"LEFT\">
					<H1>traffic-vis report</H1>
");					
	printf("					<BIG><B>Collection started at %s</B></BIG><BR>\n", format_time(p->summary_start));
	printf("					<BIG><B>Collection concluded at %s</B></BIG><BR><BR>", format_time(p->summary_finish));
	printf("					
					<TABLE>
						<TR>
							<TD>
								<B>Number of active hosts:</B>
							</TD>
							<TD>
								%u
							</TD>
						</TR>
						<TR>
							<TD>
								<B>Total bytes transferred:</B>
							</TD>
							<TD>
								%Lu
							</TD>
						</TR>
						<TR>
							<TD>
								<B>Total packets recorded:</B>
							</TD>
							<TD>
								%Lu
							</TD>
						</TR>
						<TR>
							<TD>
								<B>Total TCP connection requests:</B>
							</TD>
							<TD>
								%Lu
							</TD>
						</TR>
					</TABLE>
				<BR>
", p->active_hosts, p->total_bytes, p->total_packets, p->total_connections);

	while(sorted_hosts != NULL)
	{
		last_sh = sorted_hosts;
		print_host(sorted_hosts->host, p->peers, max_peers, peer_sort_mode, peer_reverse);
		sorted_hosts = sorted_hosts->next;
		free(last_sh);
	}

	printf("
				</TD>
			</TR>
		</TABLE>
	</BODY>
</HTML>
");
}

static void print_host(host_t *host, GHashTable *peers, unsigned int max_peers, int peer_sort_mode, int peer_reverse)
{
	struct in_addr i;

	i.s_addr = htonl(host->ip_addr);

	printf("
					<TABLE BORDER=1 WIDTH=\"100%%\" CELLSPACING=0>
						<TR>
							<TD BGCOLOR=\"#000000\" ALIGN=\"LEFT\">
								<FONT COLOR=\"#FFFFFF\">
									<B>%s (%s)</B>
								</FONT>
							</TD>
						</TR>
", (host->hostname == NULL)?"Unknown":host->hostname, inet_ntoa(i));

	printf("
						<TR>
							<TD ALIGN=\"LEFT\">
");
	if (host->n_peers != 0)
		print_peers(peers, host->peer_keys, host->n_peers, max_peers, 
						peer_sort_mode, peer_reverse);
	
	printf("
								<BR>
								<TABLE WIDTH=\"100%%\" CELLSPACING=0 BORDER=0>
									<TR BGCOLOR=\"#E0E0E0\">
										<TD>&nbsp</TD>
										<TD ALIGN=\"RIGHT\"><B>Sent</B></TD>
										<TD ALIGN=\"RIGHT\"><B>Received</B></TD>
									</TR>
");

	printf("
									<TR>
										<TD>
											<B>Total Bytes</B>
										</TD>
										<TD ALIGN=\"RIGHT\">
											%Lu
										</TD>
										<TD ALIGN=\"RIGHT\">
											%Lu
										</TD>
									</TR>
", host->bytes_sent, host->bytes_received);

	printf("
									<TR>
										<TD>
											<B>Total Packets</B>
										</TD>
										<TD ALIGN=\"RIGHT\">
											%Lu
										</TD>
										<TD ALIGN=\"RIGHT\">
											%Lu
										</TD>
									</TR>
", host->packets_sent, host->packets_received);

	printf("
									<TR>
										<TD>
											<B>Total Connect requests</B>
										</TD>
										<TD ALIGN=\"RIGHT\">
											%Lu
										</TD>
										<TD ALIGN=\"RIGHT\">
											%Lu
										</TD>
									</TR>
", host->connections_sent, host->connections_received);

	printf("
									<TR>
										<TD COLSPAN=\"3\">&nbsp;</TD>
									</TR>
									<TR>
										<TD ALIGN=\"LEFT\"><B>First traffic recorded at:</B></TD>
										<TD ALIGN=\"LEFT\" COLSPAN=\"2\">%s</TD>
									</TR>
									<TR>
										<TD ALIGN=\"LEFT\"><B>Last traffic recorded at:</B></TD>
										<TD ALIGN=\"LEFT\" COLSPAN=\"2\">%s</TD>
									</TR>
								</TABLE>
								
", format_time(host->first_seen), format_time(host->last_seen));

	printf("
							</TD>
						</TR>
					</TABLE>
");
	printf("<BR>\n");
}

static void print_peers(GHashTable *peers, u_int64_t *peer_keys, unsigned int num_peers, unsigned int max_peers, int peer_sort_mode, int peer_reverse)
{
	peer_list_t	*peer_list;
	peer_list_t	*last_pl;
	char			src_hostname[1024];
	char			dst_hostname[1024];
	
	peer_list = sort_peers(peer_keys, num_peers, peers, max_peers, 
								  peer_sort_mode, peer_reverse);

	printf("
								<TABLE WIDTH=\"100%%\" BORDER=0 CELLSPACING=0>
									<TR BGCOLOR=\"#E0E0E0\">
										<TD><B>Source host</B></TD>
										<TD><B>Destination host</B></TD>
										<TD ALIGN=\"RIGHT\"><B>Bytes sent</B></TD>
										<TD ALIGN=\"RIGHT\"><B>Packets sent</B></TD>
									</TR>
");

	while(peer_list != NULL)
	{
		format_hostname(peer_list->peer->host1, src_hostname, sizeof(src_hostname));
		format_hostname(peer_list->peer->host2, dst_hostname, sizeof(dst_hostname));
		
		printf("
									<TR>
										<TD>%s</TD>
										<TD>%s</TD>
										<TD ALIGN=\"RIGHT\">%Lu</TD>
										<TD ALIGN=\"RIGHT\">%Lu</TD>
									</TR>
", src_hostname, dst_hostname, peer_list->peer->bytes_sent_1_to_2, peer_list->peer->packets_sent_1_to_2);
		
		last_pl = peer_list;
		peer_list = peer_list->next;
		free(last_pl->peer);
		free(last_pl);
	}

	printf("
								</TABLE>
");
}

static void format_hostname(host_t *host, char *s, size_t s_len)
{
	static struct	in_addr i;

	i.s_addr = htonl(host->ip_addr);
	
	if (host->hostname != NULL)
		snprintf(s, s_len, "%s", host->hostname);
	else	
		snprintf(s, s_len, "Unknown (%s)", inet_ntoa(i));
}

static const char *format_time(time_t t)
{
	static char	ts[128];
	struct tm	*tm;
	
	tm = localtime(&t);
	
	strftime(ts, sizeof(ts), "%a, %d %b %Y %H:%M:%S %Z", tm);
	
	return(ts);
}
