/*
 * Stanford Enetfilter subroutines for tcpdump
 *
 * Based on the MERIT NNstat etherifrt.c and the Ultrix pcap-pf.c
 * subroutines.
 *
 * Rayan Zachariassen, CA*Net
 */

#include <config.h>

#include <sys/types.h>
#include <sys/time.h>
#include <sys/file.h>
#include <sys/ioctl.h>
#include <sys/socket.h>

#include <net/if.h>
#include <pcap/bpf.h>
#include <net/enet.h>

#include <netinet/in.h>
#include <netinet/if_ether.h>

#include <stdio.h>
#include <errno.h>

#include "interface.h"

struct packet_header {
#ifdef	IBMRTPC
	struct LengthWords	length;
	struct tap_header	tap;
#endif	/* IBMRTPC */
	u_char			packet[8]
};

extern int errno;

#define BUFSPACE (4*1024)

/* Forwards */
static void efReadError(int, char *);

void
readloop(int cnt, int if_fd, struct bpf_program *fp, printfunc printit)
{
#ifdef	IBMRTPC
	register struct packet_header *ph;
	register u_char *bp;
	register int inc;
#else	/* !IBMRTPC */
	static struct timeval tv = { 0 };
#endif	/* IBMRTPC */
	register int cc, caplen;
	register struct bpf_insn *fcode = fp->bf_insns;
	union {
		struct packet_header hdr;
		u_char	p[BUFSPACE];
		u_short	s;
	} buf;

	while (1) {
		if ((cc = read(if_fd, (char *)buf.p, sizeof(buf))) < 0)
			efReadError(if_fd, "reader");

#ifdef	IBMRTPC
		/*
		 * Loop through each packet.
		 */
		bp = buf.p;
		while (cc > 0) {
			ph = (struct packet_header *)bp;
			caplen = ph->tap.th_wirelen > snaplen ? snaplen : ph->tap
.th_wirelen ;
			if (pcapint_filter(fcode, (char *)ph->packet,
						ph->tap.th_wirelen, caplen)) {
				if (cnt >= 0 && --cnt < 0)
					goto out;
				(*printit)((char *)ph->packet,
					(struct timeval *)ph->tap.th_timestamp,
					ph->tap.th_wirelen, caplen);
			}
			inc = ph->length.PacketOffset;
			cc -= inc;
			bp += inc;
		}
#else	/* !IBMRTPC */
		caplen = cc > snaplen ? snaplen : cc ;
		if (pcapint_filter(fcode, buf.hdr.packet, cc, caplen)) {
			if (cnt >= 0 && --cnt < 0)
				goto out;
			(*printit)(buf.hdr.packet, &tv, cc, caplen);
		}
#endif	/* IBMRTPC */
	}
 out:
	wrapup(if_fd);
}

/* Call ONLY if read() has returned an error on packet filter */
static void
efReadError(int fid, char *msg)
{
	if (errno == EINVAL) {	/* read MAXINT bytes already! */
		if (lseek(fid, 0, 0) < 0) {
			perror("tcpdump: efReadError/lseek");
			exit(-1);
		}
		else
			return;
	}
	else {
		(void) fprintf(stderr, "tcpdump: ");
		perror(msg);
		exit(-1);
	}
}

void
wrapup(int fd)
{
#ifdef	IBMRTPC
	struct enstats es;

	if (ioctl(fd, EIOSTATS, &es) == -1) {
		perror("tcpdump: enet ioctl EIOSTATS error");
		exit(-1);
	}

	fprintf(stderr, "%d packets queued", es.enStat_Rcnt);
	if (es.enStat_Rdrops > 0)
		fprintf(stderr, ", %d dropped", es.enStat_Rdrops);
	if (es.enStat_Reads > 0)
		fprintf(stderr, ", %d tcpdump %s", es.enStat_Reads,
				es.enStat_Reads > 1 ? "reads" : "read");
	if (es.enStat_MaxRead > 1)
		fprintf(stderr, ", %d packets in largest read",
			es.enStat_MaxRead);
	putc('\n', stderr);
#endif	/* IBMRTPC */
	close(fd);
}

int
initdevice(char *device, int pflag, int *linktype)
{
	struct eniocb ctl;
	struct enfilter filter;
	u_int maxwaiting;
	int if_fd;

#ifdef	IBMRTPC
	GETENETDEVICE(0, O_RDONLY, &if_fd);
#else	/* !IBMRTPC */
	if_fd = open("/dev/enet", O_RDONLY, 0);
#endif	/* IBMRTPC */

	if (if_fd == -1) {
		perror("tcpdump: enet open error");
		error(
"your system may not be properly configured; see \"man enet(4)\"");
		exit(-1);
	}

	/*  Get operating parameters. */

	if (ioctl(if_fd, EIOCGETP, (char *)&ctl) == -1) {
		perror("tcpdump: enet ioctl EIOCGETP error");
		exit(-1);
	}

	/*  Set operating parameters. */

#ifdef	IBMRTPC
	ctl.en_rtout = 1 * ctl.en_hz;
	ctl.en_tr_etherhead = 1;
	ctl.en_tap_network = 1;
	ctl.en_multi_packet = 1;
	ctl.en_maxlen = BUFSPACE;
#else	/* !IBMRTPC */
	ctl.en_rtout = 64;	/* randomly picked value for HZ */
#endif	/* IBMRTPC */
	if (ioctl(if_fd, EIOCSETP, &ctl) == -1) {
		perror("tcpdump: enet ioctl EIOCSETP error");
		exit(-1);
	}

	/*  Flush the receive queue, since we've changed
	    the operating parameters and we otherwise might
	    receive data without headers. */

	if (ioctl(if_fd, EIOCFLUSH) == -1) {
		perror("tcpdump: enet ioctl EIOCFLUSH error");
		exit(-1);
	}

	/*  Set the receive queue depth to its maximum. */

	maxwaiting = ctl.en_maxwaiting;
	if (ioctl(if_fd, EIOCSETW, &maxwaiting) == -1) {
		perror("tcpdump: enet ioctl EIOCSETW error");
		exit(-1);
	}

#ifdef	IBMRTPC
	/*  Clear statistics. */

	if (ioctl(if_fd, EIOCLRSTAT, 0) == -1) {
		perror("tcpdump: enet ioctl EIOCLRSTAT error");
		exit(-1);
	}
#endif	/* IBMRTPC */

	/*  Set the filter (accept all packets). */

	filter.enf_Priority = 3;
	filter.enf_FilterLen = 0;
	if (ioctl(if_fd, EIOCSETF, &filter) == -1) {
		perror("tcpdump: enet ioctl EIOCSETF error");
		exit(-1);
	}
	/*
	 * "enetfilter" supports only ethernets.
	 */
	*linktype = DLT_EN10MB;

	return(if_fd);
}
