#include "../include/traffic.h"

void invalid_class() {
    printf("Invalid network class !\n");
    exit(1);
}

/* Function which return unit modifier */
float get_unit(char *s) {
	if (cmp(s, "B"))
		return 1;
	else if (cmp(s, "KB"))
		return (1.0/1024);
	else if (cmp(s, "MB"))
		return (1.0/(1024*1024));
	else if (cmp(s, "GB"))
		return (1.0/(1024*1024*1024));
	else if (cmp(s, "Bit"))
		return 8;
	else if (cmp(s, "kBit"))
		return (8.0/1024);
	else if (cmp(s, "mBit"))
		return (8.0/(1024*1024));
	else if (cmp(s, "gBit"))
		return (8.0/(1024*1024*1024));
	else
		return 0; 
} 

void usage() {
	printf("Available options:\n\
\t-f <filename>\n\
\t-i <interface>\n\
\t-u <unit>\n\
\t-U <unit>\n\
\t-r <refresh>\n\
\t-l <logfile>\n\
\t-c <class> (xxx.xxx.xxx.xxx/xx)\n\
\t-s <column>\n\
\t-R (reverse sorting)\n\
\t-t (enable summarize line)\n\
\t-C <columns list>\n\
\t-e <filename>\n\
\t-E <host or network>\n\
\t-x <filename>\n\
\t-X <host or network>\n\
\t-d (daemon mode)\n\
\t-D (discovery mode)\n\
\t-P (private mode)\n\
\t-T <timeout>\n\
\t-H (enable revdns)\n\
\t-v (print version)\n");
	exit(0);
}

/* Add column */
void add_column(short col)
{
	extern struct options 	opt;
	
	int i;

	for(i=0; i < MAX_COL; i++) {
		if (opt.columns[i] ==  col)
			return;
		if (opt.columns[i] == 0)
			{
			opt.columns[i] = col;
			break;
			}
	}

}

/* Delete column */
void del_column(short col)
{
	extern struct options 	opt;
	
	int i;
	int j;

	for(i=0; i < MAX_COL; i++)
		if (opt.columns[i] == col) {
			for(j=i; j < (MAX_COL - 1); j++)
				opt.columns[j] = opt.columns[j+1];
			opt.columns[MAX_COL] = 0;
			}
}

/* Daemonize */
void daemonize()
{
	if (daemon(0, 0) != 0) {
		perror("Error during daemonizing");
		exit(-1);
	}
}

/* Read config and initialize opt */
void read_config() 
{
	extern struct options	opt;

	FILE	*fp;

	if ( (fp = fopen(opt.config, "r")) != NULL ) {
		
	}
}

/* Add host */
int addhost(struct in_addr h)
{
	struct	hostent		*host;

    /* Check exluded hosts list */
    {
        int a;

        for(a=0; a < eh_num; a++)
                if (inclass(h, ehosts[a]))
					return 0;
    }

	h_num++;

	/* Try to alloc new memory */
	if ((hosts = realloc(hosts, host_len * h_num)) == NULL) {
		perror("adding host\n");
		return(-1);
	}
						
	/* Reset structure */
	bzero(&hosts[h_num - 1], host_len);
				
	/* Initialize data with addr of new host */
	hosts[h_num - 1].ip.s_addr = h.s_addr;

	/* Get hostname */
	if (opt.revdns == 1) {
		host = gethostbyaddr((char *)&h, sizeof(h), AF_INET);
		if (host != NULL)
			strncpy(hosts[h_num - 1].hostname, host->h_name, strlen(host->h_name));
		else
			strcpy(hosts[h_num - 1].hostname, "Couldn't resolve");
	}

	return 0;
}

/* Convert bin MAC to string */
char *mac2str(u_char * mac)
{
	static char buf[17];

	snprintf(buf,17,"%x:%x:%x:%x:%x:%x",mac[0],mac[1],mac[2],mac[3],mac[4],mac[5]);

	return buf;
}

/* Add exluded host or network to list */
int addehost(char *h)
{
	u_short	ip[4];
	u_short	netmask;
	
	char	buf[16];

	bzero(ip, sizeof(ip));
	netmask = 32;

	/* Retrieve host or network adress and netmask */
	if (sscanf(h, "%d/%d", &ip[0], &netmask) == 2);
	else if (sscanf(h, "%d.%d/%d", &ip[0], &ip[1], &netmask) == 3);
	else if (sscanf(h, "%d.%d.%d/%d", &ip[0], &ip[1], &ip[2], &netmask) == 4);
	else if (sscanf(h, "%d.%d.%d.%d/%d", &ip[0], &ip[1], &ip[2], &ip[3], &netmask) == 5);
	else if (sscanf(h, "%d.%d.%d.%d", &ip[0], &ip[1], &ip[2], &ip[3]) == 4);
	else return 1;

	/* Check validity of netmask */
	if ((netmask < 1) || (netmask > 32))
		return 1;

	/* Compose IP address */
	bzero(buf, sizeof(buf));
	snprintf(buf, sizeof(buf), "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);

	/* Alloc space for new ehost entry */
	if (( ehosts = realloc(ehosts, sizeof(host_len * eh_num))) == NULL) {
		perror("adding ehost\n");
		exit(-1);
	}

	bzero(&ehosts[eh_num - 1], host_len);
                    
	/* Initialize new entry in ehosts array */
	if ((ehosts[eh_num - 1].ip.s_addr = inet_addr(buf)) == INADDR_ANY) {
		perror(buf);
		exit(1);
	} else { ehosts[eh_num -1].netmask = netmask; }

	return 0;
}

/* Add exluded host or network to list */
int addxhost(char *h)
{
	u_short	ip[4];
	u_short	netmask;
	
	char	buf[16];

	bzero(ip, sizeof(ip));
	netmask = 32;

	/* Retrieve host or network adress and netmask */
	if (sscanf(h, "%d/%d", &ip[0], &netmask) == 2);
	else if (sscanf(h, "%d.%d/%d", &ip[0], &ip[1], &netmask) == 3);
	else if (sscanf(h, "%d.%d.%d/%d", &ip[0], &ip[1], &ip[2], &netmask) == 4);
	else if (sscanf(h, "%d.%d.%d.%d/%d", &ip[0], &ip[1], &ip[2], &ip[3], &netmask) == 5);
	else if (sscanf(h, "%d.%d.%d.%d", &ip[0], &ip[1], &ip[2], &ip[3]) == 4);
	else return 1;

	/* Check validity of netmask */
	if ((netmask < 1) || (netmask > 32))
		return 1;

	/* Compose IP address */
	bzero(buf, sizeof(buf));
	snprintf(buf, sizeof(buf), "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);

	/* Alloc space for new ehost entry */
	if (( xhosts = realloc(xhosts, sizeof(host_len * xh_num))) == NULL) {
		perror("adding ehost\n");
		exit(-1);
	}

	bzero(&xhosts[xh_num - 1], host_len);
                    
	/* Initialize new entry in ehosts array */
	if ((xhosts[xh_num - 1].ip.s_addr = inet_addr(buf)) == INADDR_ANY) {
		perror(buf);
		exit(1);
	} else { xhosts[xh_num -1].netmask = netmask; }

	return 0;
}


/* Check presence of host in specified network */
int inclass(struct in_addr host, struct ehost net)
{
	if ((ntohl(net.ip.s_addr) ^ (ntohl(net.ip.s_addr) & ntohl(host.s_addr))) == 0)
		return 1;
	else return 0;
}


syntax highlighted by Code2HTML, v. 0.9.1