📄 netwolf.c
字号:
void StoreIPDataInCDF(struct IPData IncData[]) { struct IPData *IPData; unsigned int counter; FILE *cdf; struct Statistics *Stats; char IPBuffer[50]; char logfile[] = "log.1.0.cdf"; logfile[4] = config.tag; cdf = fopen(logfile, "at"); for (counter=0; counter < IpCount; counter++) { IPData = &IncData[counter]; HostIp2CharIp(IPData->ip, IPBuffer); fprintf(cdf, "%s,%lu,", IPBuffer, IPData->timestamp); Stats = &(IPData->Send); fprintf(cdf, "%llu,%llu,%llu,%llu,%llu,%llu,%llu,", Stats->total, Stats->icmp, Stats->udp, Stats->tcp, Stats->ftp, Stats->http, Stats->p2p); Stats = &(IPData->Receive); fprintf(cdf, "%llu,%llu,%llu,%llu,%llu,%llu,%llu\n", Stats->total, Stats->icmp, Stats->udp, Stats->tcp, Stats->ftp, Stats->http, Stats->p2p); } fclose(cdf); }void _StoreIPDataInRam(struct IPData *IPData) { struct IPDataStore *DataStore; struct DataStoreBlock *DataStoreBlock; if (!IPDataStore) // we need to create the first entry { // Allocate Datastore for this IP IPDataStore = malloc(sizeof(struct IPDataStore)); IPDataStore->ip = IPData->ip; IPDataStore->Next = NULL; // Allocate it's first block of storage IPDataStore->FirstBlock = malloc(sizeof(struct DataStoreBlock)); IPDataStore->FirstBlock->LatestTimestamp = 0; IPDataStore->FirstBlock->NumEntries = 0; IPDataStore->FirstBlock->Data = calloc(IPDATAALLOCCHUNKS, sizeof(struct IPData)); IPDataStore->FirstBlock->Next = NULL; if (!IPDataStore->FirstBlock || ! IPDataStore->FirstBlock->Data) { syslog(LOG_ERR, "Could not allocate datastore! Exiting!"); exit(1); } } DataStore = IPDataStore; // Take care of first case while (DataStore) // Is not null { if (DataStore->ip == IPData->ip) // then we have the right store { DataStoreBlock = DataStore->FirstBlock; while(DataStoreBlock) // is not null { if (DataStoreBlock->NumEntries < IPDATAALLOCCHUNKS) // We have a free spot { memcpy(&DataStoreBlock->Data[DataStoreBlock->NumEntries++], IPData, sizeof(struct IPData)); DataStoreBlock->LatestTimestamp = IPData->timestamp; return; } else { if (!DataStoreBlock->Next) // there isn't another block, add one { DataStoreBlock->Next = malloc(sizeof(struct DataStoreBlock)); DataStoreBlock->Next->LatestTimestamp = 0; DataStoreBlock->Next->NumEntries = 0; DataStoreBlock->Next->Data = calloc(IPDATAALLOCCHUNKS, sizeof(struct IPData)); DataStoreBlock->Next->Next = NULL; } DataStoreBlock = DataStoreBlock->Next; } } return; } else { if (!DataStore->Next) // there is no entry for this ip, so lets make one. { // Allocate Datastore for this IP DataStore->Next = malloc(sizeof(struct IPDataStore)); DataStore->Next->ip = IPData->ip; DataStore->Next->Next = NULL; // Allocate it's first block of storage DataStore->Next->FirstBlock = malloc(sizeof(struct DataStoreBlock)); DataStore->Next->FirstBlock->LatestTimestamp = 0; DataStore->Next->FirstBlock->NumEntries = 0; DataStore->Next->FirstBlock->Data = calloc(IPDATAALLOCCHUNKS, sizeof(struct IPData)); DataStore->Next->FirstBlock->Next = NULL; } DataStore = DataStore->Next; } } }void StoreIPDataInRam(struct IPData IncData[]) { unsigned int counter; for (counter=0; counter < IpCount; counter++) _StoreIPDataInRam(&IncData[counter]); }void CommitData(time_t timestamp) { static int MayGraph = TRUE; unsigned int counter; struct stat StatBuf; char logname1[] = "log.1.5.cdf"; char logname2[] = "log.1.4.cdf"; // Set the timestamps for (counter=0; counter < IpCount; counter++) IpTable[counter].timestamp = timestamp; // Output modules // Only call this from first thread if (config.output_database && config.tag == '1') StoreIPDataInDatabase(IpTable); if (config.output_cdf) { // TODO: This needs to be moved into the forked section, but I don't want to // deal with that right now (Heavy disk io may make us drop packets) StoreIPDataInCDF(IpTable); if (RotateLogs >= config.range/RANGE1) // We set this++ on HUP { logname1[4] = config.tag; logname2[4] = config.tag; logname2[6] = '5'; if (!stat(logname2, &StatBuf)) // File exists unlink(logname2); logname1[6] = '4'; if (!stat(logname1, &StatBuf)) // File exists rename(logname1, logname2); logname1[6] = '3'; logname2[6] = '4'; if (!stat(logname1, &StatBuf)) // File exists rename(logname1, logname2); logname1[6] = '2'; logname2[6] = '3'; if (!stat(logname1, &StatBuf)) // File exists rename(logname1, logname2); logname1[6] = '1'; logname2[6] = '2'; if (!stat(logname1, &StatBuf)) // File exists rename(logname1, logname2); logname1[6] = '0'; logname2[6] = '1'; if (!stat(logname1, &StatBuf)) // File exists rename(logname1, logname2); fclose(fopen(logname1, "at")); // Touch file RotateLogs = FALSE; } } if (config.graph) { StoreIPDataInRam(IpTable); // Reap a couple zombies if (waitpid(-1, NULL, WNOHANG)) // A child was reaped MayGraph = TRUE; if (GraphIntervalCount%config.skip_intervals == 0 && MayGraph) { MayGraph = FALSE; /* If WriteOutWebpages fails, reenable graphing since there won't * be any children to reap. */ if (WriteOutWebpages(timestamp)) MayGraph = TRUE; } else if (GraphIntervalCount%config.skip_intervals == 0) syslog(LOG_INFO, "Previouse graphing run not complete... Skipping current run"); DropOldData(timestamp); } }int RCDF_Test(char *filename) { // Determine if the first date in the file is before the cutoff // return FALSE on error FILE *cdf; char ipaddrBuffer[16]; time_t timestamp; if (!(cdf = fopen(filename, "rt"))) return FALSE; fseek(cdf, 10, SEEK_END); // fseek to near end of file while (fgetc(cdf) != '\n') // rewind to last newline { if (fseek(cdf, -2, SEEK_CUR) == -1) break; } if(fscanf(cdf, " %15[0-9.],%lu,", ipaddrBuffer, ×tamp) != 2) { syslog(LOG_ERR, "%s is corrupted, skipping", filename); return FALSE; } fclose(cdf); if (timestamp < time(NULL) - config.range) return FALSE; // There is no data in this file from before cutoff else return TRUE; // This file has data from before cutoff }void RCDF_PositionStream(FILE *cdf) { time_t timestamp; time_t current_timestamp; char ipaddrBuffer[16]; current_timestamp = time(NULL); fseek(cdf, 0, SEEK_END); timestamp = current_timestamp; while (timestamp > current_timestamp - config.range) { // What happenes if we seek past the beginning of the file? if (fseek(cdf, -IP_NUM*75*(config.range/config.interval)/20,SEEK_CUR)) { // fseek returned error, just seek to beginning fseek(cdf, 0, SEEK_SET); return; } while (fgetc(cdf) != '\n' && !feof(cdf)); // Read to next line ungetc('\n', cdf); // Just so the fscanf mask stays identical if(fscanf(cdf, " %15[0-9.],%lu,", ipaddrBuffer, ×tamp) != 2) { syslog(LOG_ERR, "Unknown error while scanning for beginning of data...\n"); return; } } while (fgetc(cdf) != '\n' && !feof(cdf)); ungetc('\n', cdf); }void RCDF_Load(FILE *cdf) { time_t timestamp; time_t current_timestamp = 0; struct in_addr ipaddr; struct IPData *ip=NULL; char ipaddrBuffer[16]; unsigned long int Counter = 0; unsigned long int IntervalsRead = 0; for(Counter = 0; !feof(cdf) && !ferror(cdf); Counter++) { if(fscanf(cdf, " %15[0-9.],%lu,", ipaddrBuffer, ×tamp) != 2) goto End_RecoverDataFromCdf; if (!timestamp) // First run through loop current_timestamp = timestamp; if (timestamp != current_timestamp) { // Dump to datastore StoreIPDataInRam(IpTable); IpCount = 0; // Reset Traffic Counters current_timestamp = timestamp; IntervalsRead++; } inet_aton(ipaddrBuffer, &ipaddr); ip = FindIp(ntohl(ipaddr.s_addr)); ip->timestamp = timestamp; if (fscanf(cdf, "%llu,%llu,%llu,%llu,%llu,%llu,%llu,", &ip->Send.total, &ip->Send.icmp, &ip->Send.udp, &ip->Send.tcp, &ip->Send.ftp, &ip->Send.http, &ip->Send.p2p) != 7 || fscanf(cdf, "%llu,%llu,%llu,%llu,%llu,%llu,%llu", &ip->Receive.total, &ip->Receive.icmp, &ip->Receive.udp, &ip->Receive.tcp, &ip->Receive.ftp, &ip->Receive.http, &ip->Receive.p2p) != 7) goto End_RecoverDataFromCdf; }End_RecoverDataFromCdf: StoreIPDataInRam(IpTable); syslog(LOG_INFO, "Finished recovering %lu records", Counter); DropOldData(time(NULL)); // Dump the extra data if(!feof(cdf)) syslog(LOG_ERR, "Failed to parse part of log file. Giving up on the file"); IpCount = 0; // Reset traffic counters fclose(cdf); }void RecoverDataFromCDF(void) { FILE *cdf; char index[] = "012345"; char logname1[] = "log.1.0.cdf"; char logname2[] = "log.1.1.cdf"; int Counter; int First = FALSE; logname1[4] = config.tag; logname2[4] = config.tag; for (Counter = 5; Counter >= 0; Counter--) { logname1[6] = index[Counter]; if (RCDF_Test(logname1)) break; } First = TRUE; for (; Counter >= 0; Counter--) { logname1[6] = index[Counter]; if ((cdf = fopen(logname1, "rt"))) { syslog(LOG_INFO, "Recovering from %s", logname1); if (First) { RCDF_PositionStream(cdf); First = FALSE; } RCDF_Load(cdf); } } }// ****** FindIp **********// ****** Returns or allocates an Ip's data structureinline struct IPData *FindIp(uint32_t ipaddr) { unsigned int counter; for (counter=0; counter < IpCount; counter++) if (IpTable[counter].ip == ipaddr) return (&IpTable[counter]); if (IpCount >= IP_NUM) { syslog(LOG_ERR, "IP_NUM is too low, dropping ip...."); return(NULL); } memset(&IpTable[IpCount], 0, sizeof(struct IPData)); IpTable[IpCount].ip = ipaddr; return (&IpTable[IpCount++]); }size_t ICGrandTotalDataPoints = 0;char inline *HostIp2CharIp(unsigned long ipaddr, char *buffer) { struct in_addr in_addr; char *s; in_addr.s_addr = htonl(ipaddr); s = inet_ntoa(in_addr); strncpy(buffer, s, 16); buffer[15] = '\0'; return(buffer);/* uint32_t ip = *(uint32_t *)ipaddr; sprintf(buffer, "%d.%d.%d.%d", (ip << 24) >> 24, (ip << 16) >> 24, (ip << 8) >> 24, (ip << 0) >> 24);*/ }// Add better error checkingint fork2() { pid_t pid; if (!(pid = fork())) { setsid(); if (!fork()) {#ifdef PROFILE // Got this incantation from a message board. Don't forget to set // GMON_OUT_PREFIX in the shell extern void _start(void), etext(void); syslog(LOG_INFO, "Calling profiler startup..."); monstartup((u_long) &_start, (u_long) &etext);#endif return(0); } _exit(0); } waitpid(pid, NULL, 0); return(1); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -