diff -Nur ipfm-0.12.0pre1/source/data.c ipfm-0.12.0pre1-highbw/source/data.c --- ipfm-0.12.0pre1/source/data.c 2002-10-06 20:00:03.000000000 +0200 +++ ipfm-0.12.0pre1-highbw/source/data.c 2003-10-21 21:29:05.000000000 +0200 @@ -11,6 +11,11 @@ 200010 : tibob : optional append to logfile 200210 : tibob : fix for Solaris + 200310 : Maik Broemme + Speed optimizations at the expense of memory usage. + Also you need to reorganize the flowchart file after + writing, for example with a small perl script. + */ /* @@ -29,6 +34,16 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +/* + * Change the two values below to fit your wishes. + * Note: If you set the PACKET_LIMIT > 1500000 + * you will get experienced problems and many + * segfaults. + */ + +#define DEBUG 1 +#define PACKET_LIMIT 1000000 + #include #include #include @@ -42,6 +57,7 @@ #include #include #include +#include #include "config.h" #include "data.h" @@ -54,63 +70,258 @@ extern char *device; extern ipfm_timezone tz; -void data_add(struct AllLogsType *pLog, u_int32_t ip, int in, int out) { - struct ipfm_data *p_datatmp; +#ifdef DEBUG +char* data_time_internal(struct tm * tp) { + static char time[128]; + char *s_cpy; + if (tp == NULL) { + return NULL; + } else { + strftime(time, sizeof(time), "%Y-%m-%d %H:%M:%S", tp); + s_cpy = xstrdup(time); + } + return (s_cpy); +} - if (NULL == pLog->Data || pLog->Data->ip > ip) { - /* p_datatmp = p_data; */ - p_datatmp = xmalloc(sizeof(struct ipfm_data)); - p_datatmp->prev = NULL; - p_datatmp->next = pLog->Data; - p_datatmp->ip = ip; - p_datatmp->in = in; - p_datatmp->out = out; - if (pLog->Data != NULL) { - pLog->Data->prev = p_datatmp; - } - pLog->Data = p_datatmp; - pLog->DataSize++; - } else { - for (p_datatmp = pLog->Data; - (NULL != p_datatmp->next) && (p_datatmp->ip < ip); - p_datatmp = p_datatmp->next); - - if (p_datatmp->ip == ip) { - p_datatmp->in += in; - p_datatmp->out += out; - } else if (NULL == p_datatmp->next && p_datatmp->ip < ip) { - p_datatmp->next = xmalloc(sizeof(struct ipfm_data)); - p_datatmp->next->prev = p_datatmp; - p_datatmp->next->next = NULL; - p_datatmp->next->ip = ip; - p_datatmp->next->in = in; - p_datatmp->next->out = out; - pLog->DataSize++; - } else { - /* if (NULL == p_datatmp->next && p_datatmp->ip > ip) { - or p_datatmp->ip > ip && NULL != p_datatmp) */ - p_datatmp->prev->next = xmalloc(sizeof(struct ipfm_data)); - p_datatmp->prev->next->prev = p_datatmp->prev; - p_datatmp->prev->next->next = p_datatmp; - p_datatmp->prev->next->ip = ip; - p_datatmp->prev->next->in = in; - p_datatmp->prev->next->out = out; - p_datatmp->prev = p_datatmp->prev->next; - pLog->DataSize++; - } - } +char* data_time(void) { + time_t tval; + struct tm tpt; + tval = time (NULL); + tpt = * localtime (&tval); + return data_time_internal(&tpt); +} +#endif + +int compare_ips(const void *a, const void *b) { + const u_int32_t *aa = a; + const u_int32_t *bb = b; + return(*aa - *bb); +} + +int data_tmp(struct AllLogsType *pLog, struct AllLogsType **pLogtmp) { +#ifdef DEBUG + char *time; +#endif + struct ipfm_data *p_datatmp_final; + struct ipfm_data *p_datatmp; + int i = 0; + int j = 0; + u_int32_t ip_array[pLog->DataSize]; + u_int32_t ip_final[pLog->DataSize]; + +#ifdef DEBUG + time = data_time(); + fprintf(stderr, "%s - data_tmp() entered\n", time); + fprintf(stderr, "%s - data_tmp() ip packets recieved %i\n", time, pLog->DataSize); +#endif + + p_datatmp = xmalloc(sizeof(struct ipfm_data)); + *pLogtmp = xmalloc(sizeof(struct AllLogsType)); + + memset(ip_array, 0, sizeof(ip_array)); + memset(ip_final, 0, sizeof(ip_final)); + + (*pLogtmp)->DumpInterval = pLog->DumpInterval; + (*pLogtmp)->Append = pLog->Append; + (*pLogtmp)->ReverseLookup = pLog->ReverseLookup; + (*pLogtmp)->LogFile = pLog->LogFile; + (*pLogtmp)->NextDump = pLog->NextDump; + (*pLogtmp)->Data = NULL; + (*pLogtmp)->DataSize = 0; + + for (p_datatmp = pLog->Data; NULL != p_datatmp; p_datatmp = p_datatmp->next) { + ip_array[i] = p_datatmp->ip; + i++; + } + +#ifdef DEBUG + time = data_time(); + fprintf(stderr, "%s - data_tmp() sorting ips with quicksort for comparison\n", time); +#endif + + qsort(ip_array, pLog->DataSize - 1, sizeof(u_int32_t), compare_ips); + + i = 0; + j = 0; + for (p_datatmp = pLog->Data; NULL != p_datatmp; p_datatmp = p_datatmp->next) { + if (i == 0) { + ip_final[j] = ip_array[i]; + j++; + } + if ((i > 0) && (ip_array[i] != ip_array[i - 1])) { + ip_final[j] = ip_array[i]; + j++; + } + i++; + } + +#ifdef DEBUG + time = data_time(); + fprintf(stderr, "%s - data_tmp() non duplicated ips %i\n", time, j); + fprintf(stderr, "%s - data_tmp() preparing traffic stack\n", time); +#endif + + unsigned long ip_in[j]; + unsigned long ip_out[j]; + memset(ip_in, 0, sizeof(ip_in)); + memset(ip_out, 0, sizeof(ip_out)); + +#ifdef DEBUG + time = data_time(); + fprintf(stderr, "%s - data_tmp() count traffic for non duplicated ips\n", time); +#endif + + for (p_datatmp = pLog->Data; NULL != p_datatmp; p_datatmp = p_datatmp->next) { + for (i = 0; i < (j - 1); i++) { + if (p_datatmp->ip == ip_final[i]) { + ip_in[i] += p_datatmp->in; + ip_out[i] += p_datatmp->out; + } + } + } + +#ifdef DEBUG + time = data_time(); + fprintf(stderr, "%s - data_tmp() try to free stack pointer\n", time); +#endif + + if (p_datatmp != NULL) { + xfree(p_datatmp); + } else { + +#ifdef DEBUG + time = data_time(); + fprintf(stderr, "%s - data_tmp() free stack pointer failed - you could safely ignore this\n", time); +#endif + + } + +#ifdef DEBUG + time = data_time(); + fprintf(stderr, "%s - data_tmp() create new pLog structure with non duplicated ips and their traffic\n", time); +#endif + + for (i = 0; i <= j; i++) { + if (i < j) { + if ((*pLogtmp)->Data == NULL) { + p_datatmp_final = xmalloc(sizeof(struct ipfm_data)); + p_datatmp_final->prev = NULL; + p_datatmp_final->next = (*pLogtmp)->Data; + p_datatmp_final->ip = ip_final[i]; + p_datatmp_final->in = ip_in[i]; + p_datatmp_final->out = ip_out[i]; + if ((*pLogtmp)->Data != NULL) { + (*pLogtmp)->Data->prev = p_datatmp_final; + } + (*pLogtmp)->Data = p_datatmp_final; + (*pLogtmp)->DataSize++; + } + if ((*pLogtmp)->Data != NULL) { + p_datatmp_final = xmalloc(sizeof(struct ipfm_data)); + p_datatmp_final->next = (*pLogtmp)->Data; + p_datatmp_final->ip = ip_final[i]; + p_datatmp_final->in = ip_in[i]; + p_datatmp_final->out = ip_out[i]; + if ((*pLogtmp)->Data != NULL) { + (*pLogtmp)->Data->prev = p_datatmp_final; + } + (*pLogtmp)->Data = p_datatmp_final; + (*pLogtmp)->DataSize++; + } + } + if (i == j) { + p_datatmp_final = xmalloc(sizeof(struct ipfm_data)); + p_datatmp_final->next = NULL; + (*pLogtmp)->Data->prev = p_datatmp_final; + } + } + +#ifdef DEBUG + time = data_time(); + fprintf(stderr, "%s - data_tmp() pLog structure creation finished\n", time); + fprintf(stderr, "%s - data_tmp() finished\n", time); +#endif + return 0; +} + +void data_add(struct AllLogsType *pLog, u_int32_t ip, int in, int out) { +#ifdef DEBUG + char *time; +#endif + struct ipfm_data *p_datatmp; + struct AllLogsType *pLogtmp; + + if (pLog->Data == NULL || pLog->Data->ip > ip) { + p_datatmp = xmalloc(sizeof(struct ipfm_data)); + p_datatmp->prev = NULL; + p_datatmp->next = pLog->Data; + p_datatmp->ip = ip; + p_datatmp->in = in; + p_datatmp->out = out; + if (pLog->Data != NULL) { + pLog->Data->prev = p_datatmp; + } + pLog->Data = p_datatmp; + pLog->DataSize++; + } + if (pLog->Data != NULL) { + p_datatmp = xmalloc(sizeof(struct ipfm_data)); + p_datatmp->next = pLog->Data; + p_datatmp->ip = ip; + p_datatmp->in = in; + p_datatmp->out = out; + if (pLog->Data != NULL) { + pLog->Data->prev = p_datatmp; + } + pLog->Data = p_datatmp; + pLog->DataSize++; + } + if (pLog->DataSize > PACKET_LIMIT) { + +#ifdef DEBUG + time = data_time(); + fprintf(stderr, "%s - data_add() ip packet limit reached\n", time); +#endif + + data_tmp(pLog, &pLogtmp); + +#ifdef DEBUG + time = data_time(); + fprintf(stderr, "%s - data_add() non duplicated ips in pLogtmp %i\n", time, pLogtmp->DataSize); +#endif + + data_dump(pLogtmp); + data_clear(pLog); + } } void data_dump(struct AllLogsType *pLog) { + +#ifdef DEBUG + char *time; +#endif + pid_t pid; char *FileName; FileName = timefile(pLog->LogFile, pLog->NextDump); /* Avoid stdout conflicts between son and father */ fflush(stdout); + +#ifdef DEBUG + time = data_time(); + fprintf(stderr, "%s - data_dump() try to fork\n", time); +#endif + pid = fork(); + if (-1 == pid) { - fprintf(stderr, "couldn't fork\n"); + +#ifdef DEBUG + time = data_time(); + fprintf(stderr, "%s - data_dump() fork failed\n", time); +#endif + xfree(FileName); return; } else if (0 == pid) { @@ -119,14 +330,17 @@ char *stringTime; char *timezonestring; +#ifdef DEBUG + time = data_time(); + fprintf(stderr, "%s - data_dump() fork successful\n", time); +#endif + if (tz == local) { timezonestring = "local time"; } else { timezonestring = "UTC"; } - DataSort(pLog); - if (1 == pLog->Append) { /* append to file */ logfile = fopen(FileName, "a"); @@ -173,6 +387,7 @@ "In (bytes)", "Out (bytes)", "Total (bytes)"); + while (NULL != pLog->Data) { DataFormat(pLog, pLog->Data, DataToFile, MAX_DATA_SIZE); fprintf(logfile, "%s", DataToFile); @@ -205,6 +420,14 @@ } void data_clear(struct AllLogsType *pLog) { + +#ifdef DEBUG + char *time; + time = data_time(); + fprintf(stderr, "%s - data_clear() entered\n", time); + fprintf(stderr, "%s - data_clear() ips and packets to clear %i\n", time, pLog->DataSize); +#endif + while (NULL != pLog->Data) { if (NULL != pLog->Data->next) { @@ -217,42 +440,12 @@ } } pLog->DataSize = 0; -} -void DataSort(struct AllLogsType *pLog) { - if (pLog->Sort) { - int j; - int DataSize = pLog->DataSize; - struct ipfm_data *pTempData; - struct ipfm_data **pDataArray; - - pDataArray = xmalloc (DataSize * sizeof(struct ipfm_data *)); - - j = 0; - for (pTempData = pLog->Data; - NULL != pTempData; - pTempData = pTempData->next) - pDataArray[j++] = pTempData; - - if (DataSize) { - qsort(pDataArray, DataSize, sizeof(struct ipfm_data *), pLog->SortFunc); - - for (j = 1; j < DataSize-1; j++) { - pDataArray[j]->next = pDataArray[j+1]; - pDataArray[j]->prev = pDataArray[j-1]; - } +#ifdef DEBUG + time = data_time(); + fprintf(stderr, "%s - data_clear() finished\n", time); +#endif - if (1 < DataSize) { - pDataArray[0]->next = pDataArray[1]; - pDataArray[DataSize-1]->prev = pDataArray[DataSize-2]; - } - pDataArray[0]->prev = NULL; - pDataArray[DataSize-1]->next = NULL; - - pLog->Data = pDataArray[0]; - xfree(pDataArray); - } - } } int DataCompareOut(const void *ptr1, const void *ptr2) { diff -Nur ipfm-0.12.0pre1/source/data.h ipfm-0.12.0pre1-highbw/source/data.h --- ipfm-0.12.0pre1/source/data.h 2001-12-26 17:14:52.000000000 +0100 +++ ipfm-0.12.0pre1-highbw/source/data.h 2003-10-21 21:06:46.000000000 +0200 @@ -43,7 +43,6 @@ void data_add(struct AllLogsType *pLog, u_int32_t ip, int in, int out); void data_dump(struct AllLogsType *pLog); void data_clear(struct AllLogsType *pLog); -void DataSort(struct AllLogsType *pLog); int DataCompareOut(const void *ptr1, const void *ptr2); int DataCompareIn(const void *ptr1, const void *ptr2); int DataCompareTotal(const void *ptr1, const void *ptr2); diff -Nur ipfm-0.12.0pre1/source/filter.h ipfm-0.12.0pre1-highbw/source/filter.h --- ipfm-0.12.0pre1/source/filter.h 2001-12-26 17:14:52.000000000 +0100 +++ ipfm-0.12.0pre1-highbw/source/filter.h 2003-10-21 21:06:46.000000000 +0200 @@ -62,7 +62,7 @@ struct ipfm_data *Data; char *LogFile; - int DataSize; + unsigned long long DataSize; int Sort; int (*SortFunc)(const void *, const void *); int ReverseLookup;