Logo Search packages:      
Sourcecode: netdiag version File versions  Download package

table.c

/*
 * $Id: table.c,v 1.3 1997/08/13 21:55:21 begemot Exp begemot $
 * $Log: table.c,v $
 * Revision 1.3  1997/08/13 21:55:21  begemot
 * debug messages removed.
 *
 * Revision 1.2  1997/08/12 19:17:13  begemot
 * New modes, new options (show speed, sort).
 *
 * Revision 1.1  1997/08/12 16:37:50  begemot
 * Initial revision
 *
 * Revision 1.17  1995/02/26  19:21:02  begemot
 * Some improvements (?) in hash management.
 *
 * Revision 1.16  1995/02/26  18:59:25  begemot
 * Added RCS Id & Log entries into the all source files.
 *
 */

/*
 * Copyright (C) 1994-1996 D.Gorodchanin. See COPYING for more info.
 */

#include "trafshow.h"

#define HASH_BITS 8
#define HASH_SIZE (1 << HASH_BITS)
#define TABLE_SIZE (CHANNELS_COUNT + 1)
#define HASH(saddr,daddr,sport,dport,proto) \
      ((((saddr) ^ (daddr) ^ (sport) ^ (dport) ^ ((proto) << 8)) >> 8) \
      & (HASH_SIZE - 1))

static struct channel_entry table[TABLE_SIZE];
static unsigned int hash_table[HASH_SIZE];

static int intervals[SPEED_COUNT] = SPEED_INTRVLS; 

void calc_speed(double array[], int size, struct timeval * last)
{
      double t,o;
      int i;

      gettimeofday(&now, NULL);

      array[0] += size;

      t  = (now.tv_sec - last->tv_sec) * 1000000;
      t += now.tv_usec - last->tv_usec;

#ifdef CALC_DEBUG
      fprintf(stderr, "now %ld %ld last %ld %ld t = %f\n",
            now.tv_sec,now.tv_usec,last->tv_sec,last->tv_usec,t);
#endif

      for (i = 1; i <= SPEED_COUNT; i++) {
            if (t > (double)intervals[i-1]*1000000) {
                  o = 0;
            } else if (t < 0) {
                  o = (double)intervals[i-1]*1000000;
            } else {
                  o = (double)intervals[i-1]*1000000 - t;
            }
#ifdef CALC_DEBUG
            fprintf(stderr,"array[%d] = %f, t/i = %f",
                  i, array[i], o/intervals[i-1]/1000000);
#endif
            array[i] *= o / intervals[i-1] / 1000000;
            array[i] += (double) size / intervals[i-1];
#ifdef CALC_DEBUG
            fprintf(stderr,"size/int = %f, array[%d] = %f\n",
                  (double)size/intervals[i-1],i,array[i]);
#endif
      }
}

static int get_free_slot()
{
      unsigned int i, hash;
      unsigned long t = now.tv_sec + 1;
      unsigned int minno = 0;
      
      for (i = 1; i < TABLE_SIZE; i++) {
            if (table[i].tm.tv_sec < t)  {
                  minno = i;
                  if (!(t = table[i].tm.tv_sec))  {
                        return minno;
                  }
            }
      }
      
      hash = HASH(table[minno].saddr, table[minno].daddr,
                table[minno].sport, table[minno].dport, table[minno].proto);
      
      i = hash_table[hash];
      
      if (i == minno)  {
            hash_table[hash] = table[minno].next;
      } else  {
            while (table[i].next != minno)  {
                  i = table[i].next;
            }
            table[i].next = table[minno].next;
      }
      return minno;
}

void update_channels (unsigned long const saddr,
               unsigned long const daddr,
               unsigned short const sport,
               unsigned short const dport,
               unsigned char const proto,
               int const size,
               unsigned char const * const ifname)
{
      unsigned int h, hash;
      
      hash = HASH(saddr,daddr,sport,dport,proto);
      h = hash_table[hash];
      
      while ( h )  {
            if  (saddr == table[h].saddr &&
                 daddr == table[h].daddr &&
                 sport == table[h].sport &&
                 dport == table[h].dport &&
                 proto == table[h].proto)  {
                       if (now.tv_sec - table[h].tm.tv_sec 
                         < forget_interval) {
                             if (strcmp(table[h].ifname, ifname)) 
                                   return;
                       } else { 
                             memset(table[h].ispeed, 0,
                                  sizeof(table[h].ospeed));
                             memset(table[h].ospeed, 0,
                                  sizeof(table[h].ispeed));
                             strcpy(table[h].ifname, ifname);
                       }
                       calc_speed(table[h].ispeed,size,&table[h].tm);
                       calc_speed(table[h].ospeed,0,&table[h].tm);
                       table[h].tm = now;
                       return;
            } else if (saddr == table[h].daddr &&
                       daddr == table[h].saddr &&
                     sport == table[h].dport &&
                     dport == table[h].sport &&
                     proto == table[h].proto)  {
                       if (now.tv_sec - table[h].tm.tv_sec 
                         < forget_interval) {
                             if (strcmp(table[h].ifname, ifname))
                                   return;
                       } else { 
                             memset(table[h].ispeed, 0,
                                  sizeof(table[h].ispeed));
                             memset(table[h].ospeed, 0,
                                  sizeof(table[h].ispeed));
                             strcpy(table[h].ifname, ifname);
                       }
                       calc_speed(table[h].ospeed,size,&table[h].tm);
                       calc_speed(table[h].ispeed,0,&table[h].tm);
                       table[h].tm = now;
                       return;
            }
            h = table[h].next;
      }
      
      h = get_free_slot();

      memset(&table[h], 0, sizeof(table[h]));
      if (ntohs(sport) <= ntohs(dport))  {
            table[h].saddr = saddr;
            table[h].daddr = daddr;
            table[h].sport = sport;
            table[h].dport = dport;
            calc_speed(table[h].ispeed,size,&table[h].tm);
      } else  {
            table[h].saddr = daddr;
            table[h].daddr = saddr;
            table[h].sport = dport;
            table[h].dport = sport;
            calc_speed(table[h].ospeed,size,&table[h].tm);
      }
      table[h].proto = proto;
      table[h].tm = now;
      table[h].next = hash_table[hash];
      strcpy(table[h].ifname, ifname);
      hash_table[hash] = h;
}

int get_channels_list(struct channel_entry * * const list,
                  int const size)
{
      unsigned int i = 0, last_i, j;
      long up_mark; 
      long low_mark;
      
      up_mark = now.tv_sec + 1;
      
      while (i < size)  {
            low_mark = 0;
            last_i   = i;
            for (j = 1; j < TABLE_SIZE; j++)  {
                  if (table[j].tm.tv_sec >= low_mark 
                      && table[j].tm.tv_sec < up_mark) {
                        if (table[j].tm.tv_sec != low_mark)  {
                              i = last_i;
                              low_mark = table[j].tm.tv_sec;
                        }
                        if (i < size)  {
                              list[i++] = &table[j];
                        }
                  }
            }
            if (last_i == i || !(up_mark = low_mark) || 
                now.tv_sec - list[last_i]->tm.tv_sec >= remove_interval)  {
                  return last_i;
            }
      }
      return i;
}


void init_channels_table( void )
{
}

Generated by  Doxygen 1.6.0   Back to index