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

port_db.c

/* darkstat: a network traffic analyzer
 * (c) 2001-2003, Emil Mikulic.
 */

/* Port database */
#include "port_db.h"
#include <sys/types.h>
#include <netdb.h>
#include <string.h>


/* Global database */
db port_db;
service *services;
int num_services = 0;



static void services_init(void)
{
      int i;
      struct servent *se;

      setservent(1);
      while ((se = getservent()))
            if (!strcasecmp(se->s_proto, "tcp")) num_services++;
      endservent();
      services = (service*)malloc(sizeof(service) * num_services);

      setservent(1);
      i = 0;
      while ((se = getservent()))
            if (!strcasecmp(se->s_proto, "tcp"))
            {
                  services[i].number = ntohs(se->s_port);
                  services[i].name = (char*)strdup(se->s_name);
                  i++;
            }
      endservent();
}

const char *service_name(word port)
{
      int i;

      if (port == webport) return "darkstat";

      for (i=0; i<num_services; i++)
            if (services[i].number == port)
                  return services[i].name;

      return NULL;
}



void port_db_init(void)
{
      services_init();
      db_init(&port_db);
}

void port_db_free(void)
{
      unsigned int i;

      for (i=0; i<port_db.used; i++)
            free(port_db.records[i]);

      db_free(&port_db);
}



/* port_record needs to be deallocated when it's no longer needed */
inline port_record *port_make(const word port)
{
      port_record *p = (port_record*)malloc(sizeof(port_record));

      p->port = port;
      SET64(p->data_in, 0,0);
      SET64(p->data_out, 0,0);

      return p;
}



/* update transfer amount */
inline void port_update_in(port_record *p, const dword in)
{
      i64add32(p->data_in, in);
}

inline void port_update_out(port_record *p, const dword out)
{
      i64add32(p->data_out, out);
}



/* find a port */
inline port_record *port_find(const word port)
{
      dword i;

      if (port_db.used == 0)
            return NULL;

      for (i=0; i<port_db.used; i++)
      {
            port_record *tmp = (port_record*)db_get(port_db,i);
            assert(tmp != NULL);
            if (tmp->port == port) return tmp;
      }

      return NULL;
}



/* add or update a port, depending on whether it exists in the db or not */
inline port_record *port_from_num(const word port)
{
      port_record *p;

      p = port_find(port);

      if (p == NULL)
      {
            p = port_make(port);
            if (!db_add(&port_db, p))
                  freakout("couldn't add to port_db in port_from_num()");
      }

      return p;
}



/* sorting juju */
void port_qs_swap(port_record **list, int64 *amount, int a, int b)
{
      int64 t64;
      port_record *tpr;

      t64 = amount[a];
      amount[a] = amount[b];
      amount[b] = t64;

      tpr = list[a];
      list[a] = list[b];
      list[b] = tpr;
}



void port_quicksort(port_record **list, int64 *amount, int left, int right)
{
      int i, j;
      int64 v;

      if(right > left) {
            v = amount[right];
            i = left - 1;
            j = right;
            for(;;) {
                  do {
                        i++;
                        if (i >= j) break;
                  } while (i64smaller(amount[i], v));

                  do {
                        j--;
                        if (i >= j) break;
                  } while (i64bigger(amount[j], v));

                  if (i >= j) break;
                  port_qs_swap(list, amount, i, j);
            }
            port_qs_swap(list, amount, i, right);
            port_quicksort(list, amount, left, i - 1);
            port_quicksort(list, amount, i + 1, right);
      }
}



inline port_record **port_db_sort(sort_type st)
{
      port_record **list;
      int64 *amount;
      dword i;

      list = (port_record**)malloc(port_db.used * sizeof(port_record*));
      amount = (int64*)malloc(port_db.used * sizeof(int64));

      for (i=0; i<port_db.used; i++)
      {
            /* initialize port record */
            list[i] = (port_record*)db_get(port_db, i);

            /* initialize amount */
            switch(st)
            {
            case MAIN:
                  SET64(amount[i], 0, -(list[i]->port));
                  break;
            case TOTAL:
                  amount[i] = list[i]->data_in;
                  i64add64(amount[i], list[i]->data_out);
                  break;
            case IN:
                  amount[i] = list[i]->data_in;
                  break;
            case OUT:
                  amount[i] = list[i]->data_out;
                  break;
            default:
                  freakout("invalid sort_type passed to port_db_sort()");
            }
      }

      port_quicksort(list, amount, 0, port_db.used-1);

      free(amount);
      return list;
}



void port_db_save(FILE *fp)
{
      dword i;

      fwrite(&(port_db.used), sizeof(port_db.used), 1, fp);

      for (i=0; i<port_db.used; i++)
      {
            port_record *p = (port_record*)db_get(port_db, i);

            fwrite(&(p->port), sizeof(p->port), 1, fp);
            fwrite64(p->data_in, fp);
            fwrite64(p->data_out, fp);
      }
}



int port_db_load(FILE *fp)
{
      dword used, i;
      int read;

      read = fread(&used, sizeof(used), 1, fp);
      if (!read) return 0;

      for (i=0; i<used; i++)
      {
            port_record *p;
            word port;

            read = fread(&port, sizeof(port), 1, fp);
            if (!read) return 0;

            p = port_make(port);

            fread64(p->data_in, fp, read);
            if (!read) return 0;

            fread64(p->data_out, fp, read);
            if (!read) return 0;

            if (!db_add(&port_db, p)) return 0;
      }

      return 1;
}




Generated by  Doxygen 1.6.0   Back to index