/*
     net logger - network traffic logging library
     Copyright (C) 1993 Douglas Lee Schales, David K. Hess, David R. Safford

     Please see the file `COPYING' for the complete copyright notice.

nit.c - 03/20/93

*/

#ifdef SUNOS4

#include <stdio.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/stream.h>
#include <sys/stropts.h>
#include <sys/file.h>
#include <sys/ioctl.h>
#include <net/nit.h>
#include <net/nit_pf.h>
#include <net/nit_buf.h>
#include <sys/socket.h>
#include <net/if.h>
#include <net/nit_if.h>
#include <fcntl.h>

#define BUFSIZE 32768

int
opennit(char *eif, int promisc, void (*filter)(int))
{
     int fd;
     int bufsize = BUFSIZE;

     struct strioctl si;
     struct ifreq ifr;
     struct timeval timeout;
     unsigned long flags;
     
     fd = open("/dev/nit", O_RDONLY);
     ioctl(fd, I_SRDOPT, (char *)RMSGD);

     if(ioctl(fd, I_PUSH, "pf") == -1)
	  perror("pf push");

     /* Push filter */
     (*filter)(fd);

     ioctl(fd, I_PUSH, "nbuf");

     /* One second timeout */
     timeout.tv_sec = 1;
     timeout.tv_usec = 0;
     si.ic_timout = INFTIM;
     si.ic_cmd = NIOCSTIME;
     si.ic_len = sizeof (timeout);
     si.ic_dp = (char *)&timeout;
     ioctl(fd, I_STR, (char *)&si);


     /* 32k buffer */
     si.ic_cmd = NIOCSCHUNK;
     si.ic_len = sizeof(bufsize);
     si.ic_dp = (char *)&bufsize;
     ioctl(fd, I_STR, (char *)&si);

     /* Select which interface */
     strncpy(ifr.ifr_name, eif, sizeof(ifr.ifr_name));
     ifr.ifr_name[sizeof(ifr.ifr_name)-1] = 0;
     si.ic_cmd = NIOCBIND;
     si.ic_len = sizeof(ifr);
     si.ic_dp = (char *)&ifr;
     if(ioctl(fd, I_STR, (char *)&si) == -1){
	  perror(eif);
	  exit(1);
     }

     /* Set promiscuous mode & timestamp flags */
     flags = NI_TIMESTAMP;
     if(promisc)
	  flags |= NI_PROMISC;
     ioctl(fd, NIOCSFLAGS, &flags);

     /* Flush any packets that came in before we finished configuring */
     ioctl(fd, I_FLUSH, (char *)FLUSHR);

     return fd;
}

void
procpkts(int fd, void (*handler)())
{
     int n;
     char buf[BUFSIZE];

     while((n = read(fd, buf, BUFSIZE)) >= 0){
	  char *bp = buf;
	  char *bufend = buf+n;

	  while(bp < bufend){
	       register char *cp = bp;
	       struct nit_bufhdr *bufhdrp;
	       struct nit_iftime *hdrtime;
	       struct timeval *tvp = NULL;
	       unsigned long drops = 0;
	       unsigned long pktlen;
	       struct nit_iftime *ntp;
	       
	       bufhdrp = (struct nit_bufhdr *)cp;
	       cp += sizeof(struct nit_bufhdr);

	       hdrtime = (struct nit_iftime *)cp;
	       cp += sizeof(struct nit_iftime);

	       (*handler)(cp, bufhdrp->nhb_totlen, *hdrtime);

	       bp += bufhdrp->nhb_totlen;
	  }
     }
}

#endif
