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

graph.c

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

/* Network [ab]use graph */

#include "graph.h"
#include <assert.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
#include <time.h>

pthread_mutex_t graph_mutex;

/* circular buffers */
int64 graph_sec_in[GRAPH_SECS], graph_sec_out[GRAPH_SECS];
int64 graph_min_in[GRAPH_MINS], graph_min_out[GRAPH_MINS];
int64 graph_hr_in[GRAPH_HRS], graph_hr_out[GRAPH_HRS];
int64 graph_day_in[GRAPH_DAYS], graph_day_out[GRAPH_DAYS];

/* graph's idea of current time (may lag behind real time) */
time_t graph_time;

/* graph's time broken down */
byte g_secs, g_mins, g_hrs, g_days; /* g_days is mday-1 */



inline void graph_breakdown_time(void)
{
      time_t tmp = graph_time;
      struct tm *tm = localtime(&tmp);

      /* % protects from localtime() weirdness like leap seconds */
      g_secs = tm->tm_sec % GRAPH_SECS;
      g_mins = tm->tm_min % GRAPH_MINS;
      g_hrs = tm->tm_hour % GRAPH_HRS; 
      g_days = tm->tm_mday-1 % GRAPH_DAYS;
}



inline int yesterday_mday(void)
{
      time_t tmp = graph_time - 86400;
      struct tm *tm = localtime(&tmp);
      return tm->tm_mday;
}



void init_graph(void)
{
      int i;
      int64 zero;

      SET64(zero, 0,0);

      for (i=0; i<GRAPH_SECS; i++)
            graph_sec_in[i] = graph_sec_out[i] = zero;
      for (i=0; i<GRAPH_MINS; i++)
            graph_min_in[i] = graph_min_out[i] = zero;
      for (i=0; i<GRAPH_HRS; i++)
            graph_hr_in[i] = graph_hr_out[i] = zero;
      for (i=0; i<GRAPH_DAYS; i++)
            graph_day_in[i] = graph_day_out[i] = zero;

      /* intialize indices to current time */
      graph_time = time(NULL);
      graph_breakdown_time();
      printf("GRAPH: Starting at %d secs, %d mins, %d hrs, %d days.\n",
            g_secs, g_mins, g_hrs, g_days+1);
}



inline void graph_add_in(const dword amount)
{
      i64add32(graph_sec_in[g_secs], amount);
      i64add32(graph_min_in[g_mins], amount);
      i64add32(graph_hr_in[g_hrs], amount);
      i64add32(graph_day_in[g_days], amount);
}

inline void graph_add_out(const dword amount)
{
      i64add32(graph_sec_out[g_secs], amount);
      i64add32(graph_min_out[g_mins], amount);
      i64add32(graph_hr_out[g_hrs], amount);
      i64add32(graph_day_out[g_days], amount);
}



int daylog_enabled = 1;

inline void graph_pushone(void) /* rotate by one second */
{
      int64 zero;
      SET64(zero, 0,0);

      graph_time++;
      graph_breakdown_time();

      graph_sec_in[g_secs] = graph_sec_out[g_secs] = zero;
      if (g_secs == 0)
      {
            graph_min_in[g_mins] = graph_min_out[g_mins] = zero;

            if (g_mins == 0)
            {
                  graph_hr_in[g_hrs] = graph_hr_out[g_hrs] = zero;

                  if (g_hrs == 0)
                  {
                        time_t now = graph_time;
                        struct tm *tm = localtime(&now);

                        graph_day_in[g_days] =
                        graph_day_out[g_days] = zero;

      if (daylog_enabled)
      {
            FILE *fp = fopen(daylog_file, "a");

#ifdef HAVE_64PRINT
            fprintf(fp, "%d/%d/%d|"
                  "%" LONGLONG_FORMAT "u|"
                  "%" LONGLONG_FORMAT "u\n",
                        tm->tm_year+1900, tm->tm_mon+1,
                        yesterday_mday(),
                        graph_day_in[yesterday_mday()-1],
                        graph_day_out[yesterday_mday()-1]);
#else
            {
                  char *t1, *t2;
                  
                  fprintf(fp, "%d/%d/%d|%s|%s\n",
                        tm->tm_year+1900, tm->tm_mon+1,
                        yesterday_mday(),
                        t1=strint64(graph_day_in[yesterday_mday()-1]),
                        t2=strint64(graph_day_out[yesterday_mday()-1])
                         );

                  free(t1);
                  free(t2);
            }
#endif
            fclose(fp);
      }

                        if (yesterday_mday()-1 > g_days)
                        {
                              /* we've circled around */
                              int i;
                              for (i=yesterday_mday();
                                    i<GRAPH_DAYS; i++)
                              {
                                    graph_day_in[i] = zero;
                                    graph_day_out[i] = zero;
                              }
                        }
                  }
            }
      }
}



void graph_rotate(const time_t now)
{
      while (graph_time < now) graph_pushone();
}



/* rotate until graph_time matches real time */
void graph_calibrate_to_clock(void)
{
      graph_rotate(time(NULL));
}



inline void graph_save_one(const byte GRAPH_SIZE,
            const int64 graph_in[], const int64 graph_out[],
            FILE *fp)
{
      int i;

      for (i=0; i<GRAPH_SIZE; i++)
      {
            fwrite64(graph_in[i], fp);
            fwrite64(graph_out[i], fp);
      }
}



void graph_save(FILE *fp)
{
      graph_save_one(GRAPH_SECS,
                  graph_sec_in, graph_sec_out, fp);

      graph_save_one(GRAPH_MINS,
                  graph_min_in, graph_min_out, fp);

      graph_save_one(GRAPH_HRS,
                  graph_hr_in , graph_hr_out , fp);

      graph_save_one(GRAPH_DAYS,
                  graph_day_in, graph_day_out, fp);

      /* store last graph time */
      fwrite(&graph_time, sizeof(graph_time), 1, fp);
}



inline int graph_load_one(byte GRAPH_SIZE,
            int64 graph_in[], int64 graph_out[], FILE *fp)
{
      int numread, i;

      for (i=0; i<GRAPH_SIZE; i++)
      {
            fread64(graph_in[i], fp, numread);
            if (!numread) return 0;

            fread64(graph_out[i], fp, numread);
            if (!numread) return 0;
      }

      return 1;
}



int graph_load(FILE *fp)
{
      if (!graph_load_one(GRAPH_SECS,
                  graph_sec_in, graph_sec_out, fp)) return 0;

      if (!graph_load_one(GRAPH_MINS,
                  graph_min_in, graph_min_out, fp)) return 0;

      if (!graph_load_one(GRAPH_HRS,
                  graph_hr_in , graph_hr_out , fp)) return 0;

      if (!graph_load_one(GRAPH_DAYS,
                  graph_day_in, graph_day_out, fp)) return 0;

      /* load last time and rotate the graphs accordingly */
      if (!fread(&graph_time, sizeof(graph_time), 1, fp)) return 0;
      daylog_enabled = 0;
      graph_calibrate_to_clock();
      daylog_enabled = 1;

      return 1;
}

Generated by  Doxygen 1.6.0   Back to index