#ifndef lint
static  char rcsid[] =
    "@(#)$Header: pcap-linux.c,v 0.12 93/12/29 17:13:24 slouken Exp $ (LBL)";
#endif

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <linux/if.h>
#include <signal.h>
#include <stdio.h>

#include <net/bpf.h>

#include "interface.h"

void
readloop(cnt, if_fd, fp, printit)
	int cnt;
	int if_fd;
	struct bpf_program *fp;
	void (*printit)();
{
	u_char buf[4096];
	struct bpf_insn *fcode;
	struct sockaddr dest;
	int cc, i, dlen;
	unsigned long now;

	fcode = fp->bf_insns;
	i = 0;

	while ((cc = recvfrom(if_fd, (char *)buf, sizeof(buf), 0, &dest, &dlen)) > 0) {
		register u_char *bp, *bstop;
		register u_char *sp;
		register struct nit_hdr *nh;
		register int datalen = 0;
		int caplen;
		
		/*
		 * Loop through each packet.  The increment expression
		 * rounds up to the next int boundary past the end of
		 * the previous packet.
		 */
		bstop = buf + cc;
		for (bp = buf; bp < bstop; ++bp )
			/* Do Nothing */ ;
		(void) time(&now);
		sp=buf;
		caplen=cc;

		if (bpf_filter(fcode, sp, cc, caplen)) {
			(*printit)(sp, &now, cc, caplen);
			if (cflag && ++i >= cnt) {
				wrapup(if_fd);
				return;
			}
		}
	}
	perror("read");
	exit(-1);
}


wrapup(fd)
	int fd;
{
	close(fd);
}

int
initdevice(device, pflag, linktype)
	char *device;
	int pflag;
	int *linktype;
{
#define PROTO htons(0x0800)   /* Ethernet code for IP protocol */

	int if_fd=0;
	struct ifreq ifr;

	if ( (if_fd=socket(AF_INET,SOCK_PACKET,PROTO)) < 0 ) {
		perror("Can't get socket");
		exit(2);
	}

	strcpy(ifr.ifr_name, device);       /* interface we're gonna use */
	if( ioctl(if_fd, SIOCGIFFLAGS, &ifr) < 0 ) {    /* get flags */
		close(if_fd);
		perror("Can't get flags");
		exit(2);
	}
	if ( pflag )
		ifr.ifr_flags |= IFF_PROMISC;         /* set promiscuous mode */

	if( ioctl(if_fd, SIOCSIFFLAGS, &ifr) < 0 ) {    /* set flags */
		close(if_fd);
		perror("Can't set flags");
		exit(2);
	}
	if ( strncmp(device, "sl", 2) == 0 )
		*linktype = DLT_SLIP;
	else /* Assume ethernet */
		*linktype = DLT_EN10MB;

	return if_fd;
}
