/*
 *  pcap-sita.c: Packet capture interface additions for SITA ACN devices
 *
 *  Copyright (c) 2007 Fulko Hew, SITA INC Canada, Inc <fulko.hew@sita.aero>
 *
 *  License: BSD
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *  1. Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in
 *     the documentation and/or other materials provided with the
 *     distribution.
 *  3. The names of the authors may not be used to endorse or promote
 *     products derived from this software without specific prior
 *     written permission.
 *
 *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 *  IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "pcap-int.h"

#include "pcap-sita.h"

	/* non-configureable manifests follow */

#define IOP_SNIFFER_PORT	49152			/* TCP port on the IOP used for 'distributed pcap' usage */
#define MAX_LINE_SIZE		255				/* max size of a buffer/line in /etc/hosts we allow */
#define MAX_CHASSIS			8				/* number of chassis in an ACN site */
#define MAX_GEOSLOT			8				/* max number of access units in an ACN site */

#define FIND			0
#define LIVE			1

typedef struct iface {
	struct iface	*next;		/* a pointer to the next interface */
	char		*name;		/* this interface's name */
	char		*IOPname;	/* this interface's name on an IOP */
	uint32_t	iftype;		/* the type of interface (DLT values) */
} iface_t;

typedef struct unit {
	char			*ip;		/* this unit's IP address (as extracted from /etc/hosts) */
	int			fd;		/* the connection to this unit (if it exists) */
	int			find_fd;	/* a big kludge to avoid my programming limitations since I could have this unit open for findalldevs purposes */
	int			first_time;	/* 0 = just opened via acn_open_live(),  ie. the first time, NZ = nth time */
	struct sockaddr_in	*serv_addr;	/* the address control block for comms to this unit */
	int			chassis;
	int			geoslot;
	iface_t			*iface;		/* a pointer to a linked list of interface structures */
	char			*imsg;		/* a pointer to an inbound message */
	int			len;		/* the current size of the inbound message */
} unit_t;

static unit_t		units[MAX_CHASSIS+1][MAX_GEOSLOT+1];	/* we use indexes of 1 through 8, but we reserve/waste index 0 */
static fd_set		readfds;				/* a place to store the file descriptors for the connections to the IOPs */
static int		max_fs;

pcap_if_t		*acn_if_list;		/* pcap's list of available interfaces */

static void dump_interface_list(void) {
	pcap_if_t		*iff;
	pcap_addr_t		*addr;
	int			longest_name_len = 0;
	char			*n, *d, *f;
	int			if_number = 0;

	iff = acn_if_list;
	while (iff) {
		if (iff->name && (strlen(iff->name) > longest_name_len)) longest_name_len = strlen(iff->name);
		iff = iff->next;
	}
	iff = acn_if_list;
	printf("Interface List:\n");
	while (iff) {
		n = (iff->name)							? iff->name			: "";
		d = (iff->description)					? iff->description	: "";
		f = (iff->flags == PCAP_IF_LOOPBACK)	? "L"				: "";
		printf("%3d: %*s %s '%s'\n", if_number++, longest_name_len, n, f, d);
		addr = iff->addresses;
		while (addr) {
			printf("%*s ", (5 + longest_name_len), "");		/* add some indentation */
			printf("%15s  ", (addr->addr)		? inet_ntoa(((struct sockaddr_in *)addr->addr)->sin_addr)		: "");
			printf("%15s  ", (addr->netmask)	? inet_ntoa(((struct sockaddr_in *)addr->netmask)->sin_addr)	: "");
			printf("%15s  ", (addr->broadaddr)	? inet_ntoa(((struct sockaddr_in *)addr->broadaddr)->sin_addr)	: "");
			printf("%15s  ", (addr->dstaddr)	? inet_ntoa(((struct sockaddr_in *)addr->dstaddr)->sin_addr)	: "");
			printf("\n");
			addr = addr->next;
		}
		iff = iff->next;
	}
}

static void dump(unsigned char *ptr, int i, int indent) {
	fprintf(stderr, "%*s", indent, " ");
	for (; i > 0; i--) {
		fprintf(stderr, "%2.2x ", *ptr++);
	}
	fprintf(stderr, "\n");
}

static void dump_interface_list_p(void) {
	pcap_if_t		*iff;
	pcap_addr_t		*addr;
	int				if_number = 0;

	iff = acn_if_list;
	printf("Interface Pointer @ %p is %p:\n", &acn_if_list, iff);
	while (iff) {
		printf("%3d: %p %p next: %p\n", if_number++, iff->name, iff->description, iff->next);
		dump((unsigned char *)iff, sizeof(pcap_if_t), 5);
		addr = iff->addresses;
		while (addr) {
			printf("          %p %p %p %p, next: %p\n", addr->addr, addr->netmask, addr->broadaddr, addr->dstaddr, addr->next);
			dump((unsigned char *)addr, sizeof(pcap_addr_t), 10);
			addr = addr->next;
		}
		iff = iff->next;
	}
}

static void dump_unit_table(void) {
	int		chassis, geoslot;
	iface_t	*p;

	printf("%c:%c %s %s\n", 'C', 'S', "fd", "IP Address");
	for (chassis = 0; chassis <= MAX_CHASSIS; chassis++) {
		for (geoslot = 0; geoslot <= MAX_GEOSLOT; geoslot++) {
			if (units[chassis][geoslot].ip != NULL)
				printf("%d:%d %2d %s\n", chassis, geoslot, units[chassis][geoslot].fd, units[chassis][geoslot].ip);
			p = units[chassis][geoslot].iface;
			while (p) {
				char *n = (p->name)			? p->name			: "";
				char *i = (p->IOPname)		? p->IOPname		: "";
				p = p->next;
				printf("   %12s    -> %12s\n", i, n);
			}
		}
	}
}

static int find_unit_by_fd(int fd, int *chassis, int *geoslot, unit_t **unit_ptr) {
	int		c, s;

	for (c = 0; c <= MAX_CHASSIS; c++) {
		for (s = 0; s <= MAX_GEOSLOT; s++) {
			if (units[c][s].fd == fd || units[c][s].find_fd == fd) {
				if (chassis)	*chassis = c;
				if (geoslot)	*geoslot = s;
				if (unit_ptr)	*unit_ptr = &units[c][s];
				return 1;
			}
		}
	}
	return 0;
}

static int read_client_nbytes(int fd, int count, unsigned char *buf) {
	unit_t			*u;
	int				chassis, geoslot;
	int				len;

	find_unit_by_fd(fd, &chassis, &geoslot, &u);
	while (count) {
		if ((len = recv(fd, buf, count, 0)) <= 0)	return -1;	/* read in whatever data was sent to us */
		count -= len;	
		buf += len;
	}															/* till we have everything we are looking for */
	return 0;
}

static void empty_unit_iface(unit_t *u) {
	iface_t	*p, *cur;

	cur = u->iface;
	while (cur) {											/* loop over all the interface entries */
		if (cur->name)			free(cur->name);			/* throwing away the contents if they exist */
		if (cur->IOPname)		free(cur->IOPname);
		p = cur->next;
		free(cur);											/* then throw away the structure itself */
		cur = p;
	}
	u->iface = 0;											/* and finally remember that there are no remaining structure */
}

static void empty_unit(int chassis, int geoslot) {
	unit_t	*u = &units[chassis][geoslot];

	empty_unit_iface(u);
	if (u->imsg) {											/* then if an inbound message buffer exists */
		u->imsg = (char *)realloc(u->imsg, 1);				/* and re-allocate the old large buffer into a new small one */
		if (u->imsg == NULL) {	/* oops, realloc call failed */
			fprintf(stderr, "Warning...call to realloc() failed, value of errno is %d\n", errno);
		
	}
}

static void empty_unit_table(void) {
	int		chassis, geoslot;

	for (chassis = 0; chassis <= MAX_CHASSIS; chassis++) {
		for (geoslot = 0; geoslot <= MAX_GEOSLOT; geoslot++) {
			if (units[chassis][geoslot].ip != NULL) {
				free(units[chassis][geoslot].ip);			/* get rid of the malloc'ed space that holds the IP address */
				units[chassis][geoslot].ip = 0;				/* then set the pointer to NULL */
			}
			empty_unit(chassis, geoslot);
		}
	}
}

static char *find_nth_interface_name(int n) {
	int		chassis, geoslot;
	iface_t	*p;
	char	*last_name = 0;

	if (n < 0) n = 0;												/* ensure we are working with a valid number */
	for (chassis = 0; chassis <= MAX_CHASSIS; chassis++) {			/* scan the table... */
		for (geoslot = 0; geoslot <= MAX_GEOSLOT; geoslot++) {
			if (units[chassis][geoslot].ip != NULL) {
				p = units[chassis][geoslot].iface;
				while (p) {											/* and all interfaces... */
					if (p->IOPname) last_name = p->name;			/* remembering the last name found */
					if (n-- == 0) return last_name;					/* and if we hit the instance requested */
					p = p->next;
				}
			}
		}
	}
											/* if we couldn't fine the selected entry */
	if (last_name)	return last_name;		/* ... but we did have at least one entry... return the last entry found */
	return "";								/* ... but if there wasn't any entry... return an empty string instead */
}

int acn_parse_hosts_file(char *errbuf) {				/* returns: -1 = error, 0 = OK */
	FILE	*fp;
	char	buf[MAX_LINE_SIZE];
	char	*ptr, *ptr2;
	int		pos;
	int		chassis, geoslot;
	unit_t	*u;

	empty_unit_table();
	if ((fp = fopen("/etc/hosts", "r")) == NULL) {										/* try to open the hosts file and if it fails */
		snprintf(errbuf, PCAP_ERRBUF_SIZE, "Cannot open '/etc/hosts' for reading.");	/* return the nohostsfile error response */
		return -1;
	}
	while (fgets(buf, MAX_LINE_SIZE-1, fp)) {			/* while looping over the file */

		pos = strcspn(buf, "#\n\r");					/* find the first comment character or EOL */
		*(buf + pos) = '\0';							/* and clobber it and anything that follows it */

		pos = strspn(buf, " \t");						/* then find the first non-white space */
		if (pos == strlen(buf))							/* if there is nothing but white space on the line */
			continue;									/* ignore that empty line */
		ptr = buf + pos;								/* and skip over any of that leading whitespace */

		if ((ptr2 = strstr(ptr, "_I_")) == NULL)		/* skip any lines that don't have names that look like they belong to IOPs */
			continue;
		if (*(ptr2 + 4) != '_')							/* and skip other lines that have names that don't look like ACN components */
			continue;
		*(ptr + strcspn(ptr, " \t")) = '\0';			/* null terminate the IP address so its a standalone string */

		chassis = *(ptr2 + 3) - '0';					/* extract the chassis number */
		geoslot = *(ptr2 + 5) - '0';					/* and geo-slot number */
		if (chassis < 1 || chassis > MAX_CHASSIS ||
			geoslot < 1 || geoslot > MAX_GEOSLOT) {		/* if the chassis and/or slot numbers appear to be bad... */
			snprintf(errbuf, PCAP_ERRBUF_SIZE, "Invalid ACN name in '/etc/hosts'.");	/* warn the user */
			continue;																	/* and ignore the entry */
		}
		if ((ptr2 = (char *)malloc(strlen(ptr) + 1)) == NULL) {
			snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
			continue;
		}
		strcpy(ptr2, ptr);								/* copy the IP address into our malloc'ed memory */
		u = &units[chassis][geoslot];
		u->ip = ptr2;									/* and remember the whole shebang */
		u->chassis = chassis;
		u->geoslot = geoslot;
	}
	fclose(fp);
	if (*errbuf)	return -1;
	else			return 0;
}

static int open_with_IOP(unit_t  *u, int flag) {
	int					sockfd;
	char				*ip;

	if (u->serv_addr == NULL) {
		u->serv_addr = malloc(sizeof(struct sockaddr_in));

		/* since we called malloc(), lets check to see if we actually got the memory	*/
		if (u->serv_addr == NULL) {	/* oops, we didn't get the memory requested	*/
			fprintf(stderr, "malloc() request for u->serv_addr failed, value of errno is: %d\n", errno);
			return 0;
		}

	}
	ip = u->ip;
	/* bzero() is deprecated, replaced with memset()	*/
	memset((char *)u->serv_addr, 0, sizeof(struct sockaddr_in));
	u->serv_addr->sin_family		= AF_INET;
	u->serv_addr->sin_addr.s_addr	= inet_addr(ip);
	u->serv_addr->sin_port			= htons(IOP_SNIFFER_PORT);

	if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
		fprintf(stderr, "pcap can't open a socket for connecting to IOP at %s\n", ip);
		return 0;
	}
	if (connect(sockfd, (struct sockaddr *)u->serv_addr, sizeof(struct sockaddr_in)) < 0) {
		fprintf(stderr, "pcap can't connect to IOP at %s\n", ip);
		return 0;
	}
	if (flag == LIVE)	u->fd = sockfd;
	else				u->find_fd = sockfd;
	u->first_time = 0;
	return sockfd;			/* return the non-zero file descriptor as a 'success' indicator */
}

static void close_with_IOP(int chassis, int geoslot, int flag) {
	int		*id;

	if (flag == LIVE)	id = &units[chassis][geoslot].fd;
	else				id = &units[chassis][geoslot].find_fd;

	if (*id) {										/* this was the last time, so... if we are connected... */
		close(*id);									/* disconnect us */
		*id = 0;									/* and forget that the descriptor exists because we are not open */
	}
}

static void pcap_cleanup_acn(pcap_t *handle) {
	int		chassis, geoslot;
	unit_t	*u;

	if (find_unit_by_fd(handle->fd, &chassis, &geoslot, &u) == 0)
		return;
	close_with_IOP(chassis, geoslot, LIVE);
	if (u)
		u->first_time = 0;
	pcap_cleanup_live_common(handle);
}

static void send_to_fd(int fd, int len, unsigned char *str) {
	int		nwritten;
	int		chassis, geoslot;

	while (len > 0) {
		if ((nwritten = write(fd, str, len)) <= 0) {
			find_unit_by_fd(fd, &chassis, &geoslot, NULL);
			if (units[chassis][geoslot].fd == fd)			close_with_IOP(chassis, geoslot, LIVE);
			else if (units[chassis][geoslot].find_fd == fd)	close_with_IOP(chassis, geoslot, FIND);
			empty_unit(chassis, geoslot);
			return;
		}
		len -= nwritten;
		str += nwritten;
	}
}

static void acn_freealldevs(void) {

	pcap_if_t	*iff, *next_iff;
	pcap_addr_t	*addr, *next_addr;

	for (iff = acn_if_list; iff != NULL; iff = next_iff) {
		next_iff = iff->next;
		for (addr = iff->addresses; addr != NULL; addr = next_addr) {
			next_addr = addr->next;
			if (addr->addr)			free(addr->addr);
			if (addr->netmask)		free(addr->netmask);
			if (addr->broadaddr)	free(addr->broadaddr);
			if (addr->dstaddr)		free(addr->dstaddr);
			free(addr);
		}
		if (iff->name)			free(iff->name);
		if (iff->description)	free(iff->description);
		free(iff);
	}
}

static void nonUnified_IOP_port_name(char *buf, size_t bufsize, const char *proto, unit_t *u) {

	snprintf(buf, bufsize, "%s_%d_%d", proto, u->chassis, u->geoslot);
}

static void unified_IOP_port_name(char *buf, size_t bufsize, const char *proto, unit_t *u, int IOPportnum) {
	int			portnum;

	portnum = ((u->chassis - 1) * 64) + ((u->geoslot - 1) * 8) + IOPportnum + 1;
	snprintf(buf, bufsize, "%s_%d", proto, portnum);
}

static char *translate_IOP_to_pcap_name(unit_t *u, char *IOPname, bpf_u_int32 iftype) {
	iface_t		*iface_ptr, *iface;
	char		*name;
	char		buf[32];
	char		*proto;
	char		*port;
	int			IOPportnum = 0;

	iface = malloc(sizeof(iface_t));		/* get memory for a structure */
	if (iface == NULL) {	/* oops, we didn't get the memory requested	*/
		fprintf(stderr, "Error...couldn't allocate memory for interface structure...value of errno is: %d\n", errno);
		return NULL;
	}
	memset((char *)iface, 0, sizeof(iface_t));	/* bzero is deprecated(), replaced with memset() */

	iface->iftype = iftype;					/* remember the interface type of this interface */

	name = malloc(strlen(IOPname) + 1);		/* get memory for the IOP's name */
        if (name == NULL) {    /* oops, we didn't get the memory requested     */
                fprintf(stderr, "Error...couldn't allocate memory for IOPname...value of errno is: %d\n", errno);
                return NULL;
        }

	strcpy(name, IOPname);					/* and copy it in */
	iface->IOPname = name;					/* and stick it into the structure */

	if (strncmp(IOPname, "lo", 2) == 0) {
		IOPportnum = atoi(&IOPname[2]);
		switch (iftype) {
			case DLT_EN10MB:
				nonUnified_IOP_port_name(buf, sizeof buf, "lo", u);
				break;
			default:
				unified_IOP_port_name(buf, sizeof buf, "???", u, IOPportnum);
				break;
		}
	} else if (strncmp(IOPname, "eth", 3) == 0) {
		IOPportnum = atoi(&IOPname[3]);
		switch (iftype) {
			case DLT_EN10MB:
				nonUnified_IOP_port_name(buf, sizeof buf, "eth", u);
				break;
			default:
				unified_IOP_port_name(buf, sizeof buf, "???", u, IOPportnum);
				break;
		}
	} else if (strncmp(IOPname, "wan", 3) == 0) {
		IOPportnum = atoi(&IOPname[3]);
		switch (iftype) {
			case DLT_SITA:
				unified_IOP_port_name(buf, sizeof buf, "wan", u, IOPportnum);
				break;
			default:
				unified_IOP_port_name(buf, sizeof buf, "???", u, IOPportnum);
				break;
		}
	} else {
		fprintf(stderr, "Error... invalid IOP name %s\n", IOPname);
		return NULL;
	}

	name = malloc(strlen(buf) + 1);			/* get memory for that name */
        if (name == NULL) {    /* oops, we didn't get the memory requested     */
                fprintf(stderr, "Error...couldn't allocate memory for IOP port name...value of errno is: %d\n", errno);
                return NULL;
        }

	strcpy(name, buf);						/* and copy it in */
	iface->name = name;						/* and stick it into the structure */

	if (u->iface == 0) {					/* if this is the first name */
		u->iface = iface;					/* stick this entry at the head of the list */
	} else {
		iface_ptr = u->iface;
		while (iface_ptr->next) {			/* othewise scan the list */
			iface_ptr = iface_ptr->next;	/* till we're at the last entry */
		}
		iface_ptr->next = iface;			/* then tack this entry on the end of the list */
	}
	return iface->name;
}

static int if_sort(char *s1, char *s2) {
	char	*s1_p2, *s2_p2;
	char	str1[MAX_LINE_SIZE], str2[MAX_LINE_SIZE];
	int		s1_p1_len, s2_p1_len;
	int		retval;

	if ((s1_p2 = strchr(s1, '_'))) {	/* if an underscore is found... */
		s1_p1_len = s1_p2 - s1;			/* the prefix length is the difference in pointers */
		s1_p2++;						/* the suffix actually starts _after_ the underscore */
	} else {							/* otherwise... */
		s1_p1_len = strlen(s1);			/* the prefix length is the length of the string itself */
		s1_p2 = 0;						/* and there is no suffix */
	}
	if ((s2_p2 = strchr(s2, '_'))) {	/* now do the same for the second string */
		s2_p1_len = s2_p2 - s2;
		s2_p2++;
	} else {
		s2_p1_len = strlen(s2);
		s2_p2 = 0;
	}
	strncpy(str1, s1, (s1_p1_len > sizeof(str1)) ? s1_p1_len : sizeof(str1));   *(str1 + s1_p1_len) = 0;
	strncpy(str2, s2, (s2_p1_len > sizeof(str2)) ? s2_p1_len : sizeof(str2));   *(str2 + s2_p1_len) = 0;
	retval = strcmp(str1, str2);
	if (retval != 0) return retval;		/* if they are not identical, then we can quit now and return the indication */
	return strcmp(s1_p2, s2_p2);		/* otherwise we return the result of comparing the 2nd half of the string */
}

static void sort_if_table(void) {
	pcap_if_t	*p1, *p2, *prev, *temp;
	int			has_swapped;

	if (!acn_if_list) return;				/* nothing to do if the list is empty */

	while (1) {
		p1 = acn_if_list;					/* start at the head of the list */
		prev = 0;
		has_swapped = 0;
		while ((p2 = p1->next)) {
			if (if_sort(p1->name, p2->name) > 0) {
				if (prev) {					/* we are swapping things that are _not_ at the head of the list */
					temp = p2->next;
					prev->next = p2;
					p2->next = p1;
					p1->next = temp;
				} else {					/* special treatment if we are swapping with the head of the list */
					temp = p2->next;
					acn_if_list= p2;
					p2->next = p1;
					p1->next = temp;
				}
				p1 = p2;
				prev = p1;
				has_swapped = 1;
			}
			prev = p1;
			p1 = p1->next;
		}
		if (has_swapped == 0)
			return;
	}	
	return;
}
	
static int process_client_data (char *errbuf) {								/* returns: -1 = error, 0 = OK */
	int					chassis, geoslot;
	unit_t				*u;
	pcap_if_t			*iff, *prev_iff;
	pcap_addr_t			*addr, *prev_addr;
	char				*ptr;
	int					address_count;
	struct sockaddr_in	*s;
	char				*newname;
	bpf_u_int32				interfaceType;
	unsigned char		flags;

	prev_iff = 0;
	for (chassis = 0; chassis <= MAX_CHASSIS; chassis++) {
		for (geoslot = 0; geoslot <= MAX_GEOSLOT; geoslot++) {				/* now loop over all the devices */
			u = &units[chassis][geoslot];
			empty_unit_iface(u);
			ptr = u->imsg;													/* point to the start of the msg for this IOP */
			while (ptr < (u->imsg + u->len)) {
				if ((iff = malloc(sizeof(pcap_if_t))) == NULL) {
					snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
					return -1;
				}
				memset((char *)iff, 0, sizeof(pcap_if_t)); /* bzero() is deprecated, replaced with memset() */
				if (acn_if_list == 0)	acn_if_list = iff;					/* remember the head of the list */
				if (prev_iff)			prev_iff->next = iff;				/* insert a forward link */

				if (*ptr) {													/* if there is a count for the name */
					if ((iff->name = malloc(*ptr + 1)) == NULL) {			/* get that amount of space */
						snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
						return -1;
					}
					memcpy(iff->name, (ptr + 1), *ptr);						/* copy the name into the malloc'ed space */
					*(iff->name + *ptr) = 0;								/* and null terminate the string */
					ptr += *ptr;											/* now move the pointer forwards by the length of the count plus the length of the string */
				}
				ptr++;

				if (*ptr) {													/* if there is a count for the description */
					if ((iff->description = malloc(*ptr + 1)) == NULL) {	/* get that amount of space */
						snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
						return -1;
					}
					memcpy(iff->description, (ptr + 1), *ptr);				/* copy the name into the malloc'ed space */
					*(iff->description + *ptr) = 0;							/* and null terminate the string */
					ptr += *ptr;											/* now move the pointer forwards by the length of the count plus the length of the string */
				}
				ptr++;

				interfaceType = ntohl(*(bpf_u_int32 *)ptr);
				ptr += 4;													/* skip over the interface type */

				flags = *ptr++;
				if (flags) iff->flags = PCAP_IF_LOOPBACK;					/* if this is a loopback style interface, lets mark it as such */

				address_count = *ptr++;

				prev_addr = 0;
				while (address_count--) {
					if ((addr = malloc(sizeof(pcap_addr_t))) == NULL) {
						snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
						return -1;
					}
+					memset((char *)addr, 0, sizeof(pcap_addr_t)); /* bzero() is deprecated, replaced with memset() */
					if (iff->addresses == 0) iff->addresses = addr;
					if (prev_addr) prev_addr->next = addr;							/* insert a forward link */
					if (*ptr) {														/* if there is a count for the address */
						if ((s = malloc(sizeof(struct sockaddr_in))) == NULL) {		/* get that amount of space */
							snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
							return -1;
						}
						memset((char *)s, 0, sizeof(struct sockaddr_in)); /* bzero() is deprecated, replaced with memset() */
						addr->addr = (struct sockaddr *)s;
						s->sin_family		= AF_INET;
						s->sin_addr.s_addr	= *(bpf_u_int32 *)(ptr + 1);			/* copy the address in */
						ptr += *ptr;										/* now move the pointer forwards according to the specified length of the address */
					}
					ptr++;													/* then forwards one more for the 'length of the address' field */
					if (*ptr) {												/* process any netmask */
						if ((s = malloc(sizeof(struct sockaddr_in))) == NULL) {
							snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
							return -1;
						}
						/* bzero() is deprecated, replaced with memset() */
						memset((char *)s, 0, sizeof(struct sockaddr_in));

						addr->netmask = (struct sockaddr *)s;
						s->sin_family		= AF_INET;
						s->sin_addr.s_addr	= *(bpf_u_int32*)(ptr + 1);
						ptr += *ptr;
					}
					ptr++;
					if (*ptr) {												/* process any broadcast address */
						if ((s = malloc(sizeof(struct sockaddr_in))) == NULL) {
							snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
							return -1;
						}
						/* bzero() is deprecated, replaced with memset() */
						memset((char *)s, 0, sizeof(struct sockaddr_in));

						addr->broadaddr = (struct sockaddr *)s;
						s->sin_family		= AF_INET;
						s->sin_addr.s_addr	= *(bpf_u_int32*)(ptr + 1);
						ptr += *ptr;
					}
					ptr++;
					if (*ptr) {												/* process any destination address */
						if ((s = malloc(sizeof(struct sockaddr_in))) == NULL) {
							snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
							return -1;
						}
						/* bzero() is deprecated, replaced with memset() */
						memset((char *)s, 0, sizeof(struct sockaddr_in));

						addr->dstaddr = (struct sockaddr *)s;
						s->sin_family		= AF_INET;
						s->sin_addr.s_addr	= *(bpf_u_int32*)(ptr + 1);
						ptr += *ptr;
					}
					ptr++;
					prev_addr = addr;
				}
				prev_iff = iff;

				newname = translate_IOP_to_pcap_name(u, iff->name, interfaceType);		/* add a translation entry and get a point to the mangled name */
				if ((iff->name = realloc(iff->name, strlen(newname) + 1)) == NULL) {	/* we now re-write the name stored in the interface list */
					snprintf(errbuf, PCAP_ERRBUF_SIZE, "realloc: %s", pcap_strerror(errno));
					return -1;
				}
				strcpy(iff->name, newname);												/* to this new name */
			}
		}
	}
	return 0;
}

static int read_client_data (int fd) {
	unsigned char	buf[256];
	int				chassis, geoslot;
	unit_t			*u;
	int				len;

	find_unit_by_fd(fd, &chassis, &geoslot, &u);

	if ((len = recv(fd, buf, sizeof(buf), 0)) <= 0)	return 0;	/* read in whatever data was sent to us */

	if ((u->imsg = realloc(u->imsg, (u->len + len))) == NULL)	/* extend the buffer for the new data */
		return 0;
	memcpy((u->imsg + u->len), buf, len);						/* append the new data */
	u->len += len;
	return 1;
}

static void wait_for_all_answers(void) {
	int		retval;
	struct	timeval tv;
	int		fd;
	int		chassis, geoslot;

	tv.tv_sec = 2;
	tv.tv_usec = 0;

	while (1) {
		int flag = 0;
		fd_set working_set;

		for (fd = 0; fd <= max_fs; fd++) {								/* scan the list of descriptors we may be listening to */
			if (FD_ISSET(fd, &readfds)) flag = 1;						/* and see if there are any still set */
		}
		if (flag == 0) return;											/* we are done, when they are all gone */

		memcpy(&working_set, &readfds, sizeof(readfds));				/* otherwise, we still have to listen for more stuff, till we timeout */
		retval = select(max_fs + 1, &working_set, NULL, NULL, &tv);
		if (retval == -1) {												/* an error occured !!!!! */
			return;
		} else if (retval == 0) {										/* timeout occured, so process what we've got sofar and return */
			printf("timeout\n");
			return;
		} else {
			for (fd = 0; fd <= max_fs; fd++) {							/* scan the list of things to do, and do them */
				if (FD_ISSET(fd, &working_set)) {
					if (read_client_data(fd) == 0) {					/* if the socket has closed */
						FD_CLR(fd, &readfds);							/* and descriptors we listen to for errors */
						find_unit_by_fd(fd, &chassis, &geoslot, NULL);
						close_with_IOP(chassis, geoslot, FIND);			/* and close out connection to him */
					}
				}
			}
		}
	}
}

static char *get_error_response(int fd, char *errbuf) {		/* return a pointer on error, NULL on no error */
	char	byte;
	int		len = 0;

	while (1) {
		recv(fd, &byte, 1, 0);							/* read another byte in */
		if (errbuf && (len++ < PCAP_ERRBUF_SIZE)) {		/* and if there is still room in the buffer */
			*errbuf++ = byte;							/* stick it in */
			*errbuf = '\0';								/* ensure the string is null terminated just in case we might exceed the buffer's size */
		}
		if (byte == '\0') {
			if (len > 1)	{ return errbuf;	}
			else			{ return NULL;		}
		}
	}
}

int acn_findalldevs(char *errbuf) {								/* returns: -1 = error, 0 = OK */
	int		chassis, geoslot;
	unit_t	*u;

	FD_ZERO(&readfds);
	max_fs = 0;
	for (chassis = 0; chassis <= MAX_CHASSIS; chassis++) {
		for (geoslot = 0; geoslot <= MAX_GEOSLOT; geoslot++) {
			u = &units[chassis][geoslot];
			if (u->ip && (open_with_IOP(u, FIND))) {			/* connect to the remote IOP */
				send_to_fd(u->find_fd, 1, (unsigned char *)"\0");
				if (get_error_response(u->find_fd, errbuf))
					close_with_IOP(chassis, geoslot, FIND);
				else {
					if (u->find_fd > max_fs)
						max_fs = u->find_fd;								/* remember the highest number currently in use */
					FD_SET(u->find_fd, &readfds);						/* we are going to want to read this guy's response to */
					u->len = 0;
					send_to_fd(u->find_fd, 1, (unsigned char *)"Q");		/* this interface query request */
				}
			}
		}
	}
	wait_for_all_answers();
	if (process_client_data(errbuf))
		return -1;
	sort_if_table();
	return 0;
}

static int pcap_stats_acn(pcap_t *handle, struct pcap_stat *ps) {
	unsigned char	buf[12];

	send_to_fd(handle->fd, 1, (unsigned char *)"S");						/* send the get_stats command to the IOP */

	if (read_client_nbytes(handle->fd, sizeof(buf), buf) == -1) return -1;	/* try reading the required bytes */

	ps->ps_recv		= ntohl(*(uint32_t *)&buf[0]);							/* break the buffer into its three 32 bit components */
	ps->ps_drop		= ntohl(*(uint32_t *)&buf[4]);
	ps->ps_ifdrop	= ntohl(*(uint32_t *)&buf[8]);

	return 0;
}

static int acn_open_live(const char *name, char *errbuf, int *linktype) {		/* returns 0 on error, else returns the file descriptor */
	int			chassis, geoslot;
	unit_t		*u;
	iface_t		*p;
	pcap_if_t	*alldevsp;

	pcap_findalldevs_interfaces(&alldevsp, errbuf);
	for (chassis = 0; chassis <= MAX_CHASSIS; chassis++) {										/* scan the table... */
		for (geoslot = 0; geoslot <= MAX_GEOSLOT; geoslot++) {
			u = &units[chassis][geoslot];
			if (u->ip != NULL) {
				p = u->iface;
				while (p) {																		/* and all interfaces... */
					if (p->IOPname && p->name && (strcmp(p->name, name) == 0)) {				/* and if we found the interface we want... */
						*linktype = p->iftype;
						open_with_IOP(u, LIVE);													/* start a connection with that IOP */
						send_to_fd(u->fd, strlen(p->IOPname)+1, (unsigned char *)p->IOPname);	/* send the IOP's interface name, and a terminating null */
						if (get_error_response(u->fd, errbuf)) {
							return -1;
						}
						return u->fd;															/* and return that open descriptor */
					}
					p = p->next;
				}
			}
		}
	}
	return -1;																				/* if the interface wasn't found, return an error */
}

static void acn_start_monitor(int fd, int snaplen, int timeout, int promiscuous, int direction) {
	unsigned char	buf[8];
	unit_t			*u;

	//printf("acn_start_monitor()\n");				// fulko
	find_unit_by_fd(fd, NULL, NULL, &u);
	if (u->first_time == 0) {
		buf[0]					= 'M';
		*(uint32_t *)&buf[1]	= htonl(snaplen);
		buf[5]					= timeout;
		buf[6]					= promiscuous;
		buf[7]					= direction;
	//printf("acn_start_monitor() first time\n");				// fulko
		send_to_fd(fd, 8, buf);								/* send the start monitor command with its parameters to the IOP */
		u->first_time = 1;
	}
	//printf("acn_start_monitor() complete\n");				// fulko
}

static int pcap_inject_acn(pcap_t *p, const void *buf _U_, size_t size _U_) {
	strlcpy(p->errbuf, "Sending packets isn't supported on ACN adapters",
	    PCAP_ERRBUF_SIZE);
	return (-1);
}

static int pcap_setfilter_acn(pcap_t *handle, struct bpf_program *bpf) {
	int				fd = handle->fd;
	int				count;
	struct bpf_insn	*p;
	uint16_t		shortInt;
	uint32_t		longInt;

	send_to_fd(fd, 1, (unsigned char *)"F");			/* BPF filter follows command */
	count = bpf->bf_len;
	longInt = htonl(count);
	send_to_fd(fd, 4, (unsigned char *)&longInt);		/* send the instruction sequence count */
	p = bpf->bf_insns;
	while (count--) {									/* followed by the list of instructions */
		shortInt = htons(p->code);
		longInt = htonl(p->k);
		send_to_fd(fd, 2, (unsigned char *)&shortInt);
		send_to_fd(fd, 1, (unsigned char *)&p->jt);
		send_to_fd(fd, 1, (unsigned char *)&p->jf);
		send_to_fd(fd, 4, (unsigned char *)&longInt);
		p++;
	}
	if (get_error_response(fd, NULL))
		return -1;
	return 0;
}

static int pcap_setdirection_acn(pcap_t *handle, pcap_direction_t d) {
	snprintf(handle->errbuf, sizeof(handle->errbuf),
	    "Setting direction is not supported on ACN adapters");
	return -1;
}

static int acn_read_n_bytes_with_timeout(pcap_t *handle, int count) {
	struct		timeval tv;
	int			retval, fd;
	fd_set		r_fds;
	fd_set		w_fds;
	u_char		*bp;
	int			len = 0;
	int			offset = 0;

	tv.tv_sec = 5;
	tv.tv_usec = 0;

	fd = handle->fd;
	FD_ZERO(&r_fds);
	FD_SET(fd, &r_fds);
	memcpy(&w_fds, &r_fds, sizeof(r_fds));
	bp = handle->bp;
	while (count) {
		retval = select(fd + 1, &w_fds, NULL, NULL, &tv);
		if (retval == -1) {											/* an error occured !!!!! */
//			fprintf(stderr, "error during packet data read\n");
			return -1;												/* but we need to return a good indication to prevent unneccessary popups */
		} else if (retval == 0) {									/* timeout occured, so process what we've got sofar and return */
//			fprintf(stderr, "timeout during packet data read\n");
			return -1;
		} else {
			if ((len = recv(fd, (bp + offset), count, 0)) <= 0) {
//				fprintf(stderr, "premature exit during packet data rx\n");
				return -1;
			}
			count -= len;
			offset += len;
		}
	}
	return 0;
}

static int pcap_read_acn(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user) {
	#define HEADER_SIZE (4 * 4)
	unsigned char		packet_header[HEADER_SIZE];
	struct pcap_pkthdr	pcap_header;

	//printf("pcap_read_acn()\n");			// fulko
	acn_start_monitor(handle->fd, handle->snapshot, handle->opt.timeout, handle->opt.promisc, handle->direction);	/* maybe tell him to start monitoring */
	//printf("pcap_read_acn() after start monitor\n");			// fulko

	handle->bp = packet_header;
	if (acn_read_n_bytes_with_timeout(handle, HEADER_SIZE) == -1) return 0;			/* try to read a packet header in so we can get the sizeof the packet data */

	pcap_header.ts.tv_sec	= ntohl(*(uint32_t *)&packet_header[0]);				/* tv_sec */
	pcap_header.ts.tv_usec	= ntohl(*(uint32_t *)&packet_header[4]);				/* tv_usec */
	pcap_header.caplen		= ntohl(*(uint32_t *)&packet_header[8]);				/* caplen */
	pcap_header.len			= ntohl(*(uint32_t *)&packet_header[12]);				/* len */

	handle->bp = handle->buffer + handle->offset;									/* start off the receive pointer at the right spot */
	if (acn_read_n_bytes_with_timeout(handle, pcap_header.caplen) == -1) return 0;	/* then try to read in the rest of the data */

	callback(user, &pcap_header, handle->bp);										/* call the user supplied callback function */
	return 1;
}

static int pcap_activate_sita(pcap_t *handle) {
	int		fd;

	if (handle->opt.rfmon) {
		/*
		 * No monitor mode on SITA devices (they're not Wi-Fi
		 * devices).
		 */
		return PCAP_ERROR_RFMON_NOTSUP;
	}

	/* Initialize some components of the pcap structure. */

	handle->inject_op = pcap_inject_acn;
	handle->setfilter_op = pcap_setfilter_acn;
	handle->setdirection_op = pcap_setdirection_acn;
	handle->set_datalink_op = NULL;	/* can't change data link type */
	handle->getnonblock_op = pcap_getnonblock_fd;
	handle->setnonblock_op = pcap_setnonblock_fd;
	handle->cleanup_op = pcap_cleanup_acn;
	handle->read_op = pcap_read_acn;
	handle->stats_op = pcap_stats_acn;

	fd = acn_open_live(handle->opt.source, handle->errbuf,
	    &handle->linktype);
	if (fd == -1)
		return PCAP_ERROR;
	handle->fd = fd;
	handle->bufsize = handle->snapshot;

	/* Allocate the buffer */

	handle->buffer	 = malloc(handle->bufsize + handle->offset);
	if (!handle->buffer) {
	        snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
			 "malloc: %s", pcap_strerror(errno));
		pcap_cleanup_acn(handle);
		return PCAP_ERROR;
	}

	/*
	 * "handle->fd" is a socket, so "select()" and "poll()"
	 * should work on it.
	 */
	handle->selectable_fd = handle->fd;

	return 0;
}

pcap_t *pcap_create_interface(const char *device, char *ebuf) {
	pcap_t *p;

	p = pcap_create_common(device, ebuf, 0);
	if (p == NULL)
		return (NULL);

	p->activate_op = pcap_activate_sita;
	return (p);
}
