/*
 *  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);
}
