/*
     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.

hosts.c - 03/20/93

*/
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <netdb.h>
#include <signal.h>

extern char *inet_ntoa(struct in_addr);

struct hncache {
     struct in_addr ha;
     char *hn;
};

struct hncache hostcache[2048];
static int hnc_init = 0;
static unsigned long hit = 0, miss = 0, coll = 0;

sigusr1()
{
     printf("Hit/Miss: %lu/%lu, Collisions: %lu\n",
	    hit, miss,coll);
}

char *
cgethostbyaddr(struct in_addr ipha)
{
     unsigned int hash;
     struct hostent *he;
     unsigned long ha;
     char *name;

     ha = htonl(ipha.s_addr);
     hash = ha & 0x7ff;

     if(!hnc_init){
	  int i;
	  for(i=0;i<2048;i++){
	       hostcache[i].hn = (char *)0;
	       memset(&hostcache[i].ha, 0, 4);
	  }
	  hnc_init = 1;
	  signal(SIGUSR1, sigusr1);
     }
     
     if((memcmp(&hostcache[hash].ha, &ha, 4) == 0) &&
	hostcache[hash].hn){
	  name = hostcache[hash].hn;
	  hit++;
     }
     else {
	  miss++;
	  if(he = gethostbyaddr((char *)&ha, 4, AF_INET))
	       name = he->h_name;
	  else
	       name =  inet_ntoa(ipha);

	  memcpy(&hostcache[hash].ha, &ha, 4);
	  if(hostcache[hash].hn){
	       free(hostcache[hash].hn);
	       coll++;
	  }
	  hostcache[hash].hn = (char *)malloc(strlen(name)+1);
	  strcpy(hostcache[hash].hn, name);
     }
     return name;
}

void
outhost(struct in_addr ha)
{
     printf(" %s", cgethostbyaddr(ha));
}
