1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257
|
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <unistd.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <signal.h>
#include <net/if.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/udp.h>
#include <netinet/tcp.h>
#include <stdio.h>
#include <pcap.h>
#include <signal.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <dirent.h>
#if HAVE_INTTYPES_H
#include <inttypes.h>
#endif
#ifdef TYPEDEF_UINT32
typedef u_int32_t uint32_t;
#endif
#ifdef TYPEDEF_UINT16
typedef u_int16_t uint16_t;
#endif
#ifdef HAVE_GD_H
#include <gd.h>
#else
#ifdef HAVE_GD_GD_H
#include <gd/gd.h>
#endif
#endif
#ifdef HAVE_GDFONTS_H
#include <gdfonts.h>
#else
#ifdef HAVE_GD_GDFONTS_H
#include <gd/gdfonts.h>
#endif
#endif
#include <netdb.h>
#include <time.h>
#include <syslog.h>
#define BUILD 17
#define IP_NUM 10000 // TODO: Do this dynamicly to save ram and/or scale bigger
#define SUBNET_NUM 100
#define XWIDTH 900
#define YHEIGHT 256L
#define XOFFSET 90L
#define YOFFSET 45L
#define NR_WORKER_CHILDS 3
#define RANGE1 172800.0 // 2 days
#define RANGE2 604800.0 // 7 days
#define RANGE3 3024000.0 // 35 days
#define RANGE4 35640000.0 // 412.5ish days
#define INTERVAL1 200L // 150 -60 (213 is the perfect interval?)
#define INTERVAL2 600L // 10 minutes
#define INTERVAL3 3600L // 1 hour
#define INTERVAL4 43200L // 12 hours
#define CONFIG_GRAPHINTERVALS 1 // 2 -5 Number of Intervals to wait before redrawing the graphs
#define CONFIG_GRAPHCUTOFF 1024*1024 // If total data transfered doesn't reach at least this number we don't graph the ip
#define LEAD .05 // % Of time to lead the graph
#define TRUE 1
#define FALSE 0
#define CONFIG_METAREFRESH 150
#define PERMIS 1
#define MAX_FILENAME 1024
#define DB_PGSQL 1
// No mysql support yet
#define DB_MYSQL 2
struct config
{
char *dev;
char *filter;
unsigned int skip_intervals;
unsigned long long graph_cutoff;
int promisc;
int extensions;
int output_cdf;
int recover_cdf;
int graph;
double range;
unsigned long long interval;
char tag;
unsigned int meta_refresh;
int output_database;
char *db_connect_string;
char *sensor_name;
char *log_dir;
char *htdocs_dir;
char *description;
char *management_url;
};
struct SubnetData
{
uint32_t ip;
uint32_t mask;
} SubnetTable[SUBNET_NUM];
struct Statistics
{
unsigned long long packet_count;
unsigned long long total;
unsigned long long icmp;
unsigned long long udp;
unsigned long long tcp;
unsigned long long ftp;
unsigned long long http;
unsigned long long p2p;
};
struct IPData
{
time_t timestamp;
uint32_t ip; // Host byte order
struct Statistics Send;
struct Statistics Receive;
} IpTable[IP_NUM];
struct SummaryData
{
uint32_t IP;
int Graph; // TRUE or FALSE, Did we write out a graph for this ip
unsigned long long Total;
unsigned long long TotalSent;
unsigned long long TotalReceived;
unsigned long long ICMP;
unsigned long long UDP;
unsigned long long TCP;
unsigned long long FTP;
unsigned long long HTTP;
unsigned long long P2P;
};
struct IPDataStore
{
uint32_t ip;
struct DataStoreBlock *FirstBlock; // This is structure is allocated at the same time, so it always exists.
struct IPDataStore *Next;
};
#define IPDATAALLOCCHUNKS 100
struct DataStoreBlock
{
time_t LatestTimestamp;
int NumEntries; // Is the index of the first unused entry in IPData
struct IPData *Data; // These are allocated at creation, and thus always exist
struct DataStoreBlock *Next;
};
struct Broadcast
{
char *sensor_name;
char *interface;
time_t received;
struct Broadcast *next;
};
struct extensions {
char *name;
char *value;
struct extensions *next;
};
// ****************************************************************************************
// ** Function Prototypes
// ****************************************************************************************
// ************ A fork that orphans the child
int fork2();
// ************ The function that gets called with each packet
void PacketCallback(u_char *user, const struct pcap_pkthdr *h, const u_char *p);
// ************ Reads a CDF file from a previous run
void RecoverDataFromCDF(void);
// ************ Adds subnets to the list of subnets that are monitored
void MonitorSubnet(unsigned int ip, unsigned int mask);
// ************ This function converts and IP to a char string
char inline *HostIp2CharIp(unsigned long ipaddr, char *buffer);
// ************ This function converts the numbers for each quad into an IP
inline uint32_t IpAddr(unsigned char q1, unsigned char q2, unsigned char q3, unsigned char q4);
// ************ This function adds the packet's size to the proper entries in the data structure
inline void Credit(struct Statistics *Stats, const struct ip *ip);
// ************ Finds an IP in our IPTable
inline struct IPData *FindIp(uint32_t ipaddr);
// ************ Writes our IPTable to Disk or to the Ram cache
void CommitData(time_t timestamp);
// ************ Creates our Graphs
void GraphIp(struct IPDataStore *DataStore, struct SummaryData *SummaryData, time_t timestamp);
void PrepareXAxis(gdImagePtr im, time_t timestamp);
void PrepareYAxis(gdImagePtr im, unsigned long long int YMax);
unsigned long long GraphData(gdImagePtr im, gdImagePtr im2, struct IPDataStore *DataStore, time_t timestamp, struct SummaryData *SummaryData);
// ************ Misc
inline void DstCredit(uint32_t ipaddr, unsigned int psize);
void MakeIndexPages(int NumGraphs, struct SummaryData *SummaryData[]);
// ************ Pgsql
void pgsqlStoreIPData(struct IPData IncData[], struct extensions *);
// ************ Extensions
struct extensions *execute_extensions(void);
void destroy_extension_data(struct extensions *ext);
|