2
* Copyright (C) 1998-2001 Luca Deri <deri@ntop.org>
3
* Portions by Stefano Suin <stefano@ntop.org>
7
* This program is free software; you can redistribute it and/or modify
8
* it under the terms of the GNU General Public License as published by
9
* the Free Software Foundation; either version 2 of the License, or
10
* (at your option) any later version.
12
* This program is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
* GNU General Public License for more details.
17
* You should have received a copy of the GNU General Public License
18
* along with this program; if not, write to the Free Software
19
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25
/* ******************************* */
27
static void updateThptStats(int deviceToUpdate,
28
u_int topSentIdx, u_int secondSentIdx, u_int thirdSentIdx,
29
u_int topHourSentIdx, u_int secondHourSentIdx,
30
u_int thirdHourSentIdx,
31
u_int topRcvdIdx, u_int secondRcvdIdx, u_int thirdRcvdIdx,
32
u_int topHourRcvdIdx, u_int secondHourRcvdIdx,
33
u_int thirdHourRcvdIdx) {
37
traceEvent(TRACE_INFO, "updateThptStats(%d, %d, %d, %d, %d, %d)\n",
38
topSentIdx, secondSentIdx, thirdSentIdx,
39
topHourSentIdx, secondHourSentIdx,
43
/* We never check enough... */
44
if(topSentIdx == NO_PEER)
47
if(topRcvdIdx == NO_PEER)
50
if(secondSentIdx == NO_PEER)
53
if(thirdSentIdx == NO_PEER)
56
if(secondRcvdIdx == NO_PEER)
59
if(thirdRcvdIdx == NO_PEER)
63
memcpy(&device[deviceToUpdate].last60MinutesThpt[i+1],
64
&device[deviceToUpdate].last60MinutesThpt[i], sizeof(ThptEntry));
66
device[deviceToUpdate].last60MinutesThpt[0].trafficValue = device[deviceToUpdate].lastMinThpt;
69
traceEvent(TRACE_INFO, "LastMinThpt: %s", formatThroughput(device[deviceToUpdate].lastMinThpt));
72
device[deviceToUpdate].last60MinutesThpt[0].topHostSentIdx = topSentIdx,
73
device[deviceToUpdate].last60MinutesThpt[0].topSentTraffic =
74
device[deviceToUpdate].hash_hostTraffic[topSentIdx]->actualSentThpt;
75
device[deviceToUpdate].last60MinutesThpt[0].secondHostSentIdx = secondSentIdx,
76
device[deviceToUpdate].last60MinutesThpt[0].secondSentTraffic =
77
device[deviceToUpdate].hash_hostTraffic[secondSentIdx]->actualSentThpt;
78
device[deviceToUpdate].last60MinutesThpt[0].thirdHostSentIdx = thirdSentIdx,
79
device[deviceToUpdate].last60MinutesThpt[0].thirdSentTraffic =
80
device[deviceToUpdate].hash_hostTraffic[thirdSentIdx]->actualSentThpt;
82
device[deviceToUpdate].last60MinutesThpt[0].topHostRcvdIdx = topRcvdIdx,
83
device[deviceToUpdate].last60MinutesThpt[0].topRcvdTraffic =
84
device[deviceToUpdate].hash_hostTraffic[topRcvdIdx]->actualRcvdThpt;
85
device[deviceToUpdate].last60MinutesThpt[0].secondHostRcvdIdx = secondRcvdIdx,
86
device[deviceToUpdate].last60MinutesThpt[0].secondRcvdTraffic =
87
device[deviceToUpdate].hash_hostTraffic[secondRcvdIdx]->actualRcvdThpt;
88
device[deviceToUpdate].last60MinutesThpt[0].thirdHostRcvdIdx = thirdRcvdIdx,
89
device[deviceToUpdate].last60MinutesThpt[0].thirdRcvdTraffic =
90
device[deviceToUpdate].hash_hostTraffic[thirdRcvdIdx]->actualRcvdThpt;
92
device[deviceToUpdate].last60MinutesThptIdx = (device[deviceToUpdate].last60MinutesThptIdx+1) % 60;
94
if(topHourSentIdx != NO_PEER) { /* It wrapped -> 1 hour is over */
98
if(topHourSentIdx == NO_PEER) return;
99
if(topHourRcvdIdx == NO_PEER) return;
100
if(secondHourSentIdx == NO_PEER) secondHourSentIdx = 0;
101
if(thirdHourSentIdx == NO_PEER) thirdHourSentIdx = 0;
102
if(secondHourRcvdIdx == NO_PEER) secondHourRcvdIdx = 0;
103
if(thirdHourRcvdIdx == NO_PEER) thirdHourRcvdIdx = 0;
105
for(i=0; i<60; i++) {
106
average += device[deviceToUpdate].last60MinutesThpt[i].trafficValue;
112
memcpy(&device[deviceToUpdate].last24HoursThpt[i+1],
113
&device[deviceToUpdate].last24HoursThpt[i], sizeof(ThptEntry));
115
device[deviceToUpdate].last24HoursThpt[0].trafficValue = average;
117
device[deviceToUpdate].last24HoursThpt[0].topHostSentIdx = topHourSentIdx,
118
device[deviceToUpdate].last24HoursThpt[0].topSentTraffic =
119
device[deviceToUpdate].hash_hostTraffic[topHourSentIdx]->lastHourSentThpt;
120
device[deviceToUpdate].last24HoursThpt[0].secondHostSentIdx = secondHourSentIdx,
121
device[deviceToUpdate].last24HoursThpt[0].secondSentTraffic =
122
device[deviceToUpdate].hash_hostTraffic[secondHourSentIdx]->lastHourSentThpt;
123
device[deviceToUpdate].last24HoursThpt[0].thirdHostSentIdx = thirdHourSentIdx,
124
device[deviceToUpdate].last24HoursThpt[0].thirdSentTraffic =
125
device[deviceToUpdate].hash_hostTraffic[thirdHourSentIdx]->lastHourSentThpt;
127
device[deviceToUpdate].last24HoursThpt[0].topHostRcvdIdx = topHourRcvdIdx,
128
device[deviceToUpdate].last24HoursThpt[0].topRcvdTraffic =
129
device[deviceToUpdate].hash_hostTraffic[topHourRcvdIdx]->lastHourRcvdThpt;
130
device[deviceToUpdate].last24HoursThpt[0].secondHostRcvdIdx = secondHourRcvdIdx,
131
device[deviceToUpdate].last24HoursThpt[0].secondRcvdTraffic =
132
device[deviceToUpdate].hash_hostTraffic[secondHourRcvdIdx]->lastHourRcvdThpt;
133
device[deviceToUpdate].last24HoursThpt[0].thirdHostRcvdIdx = thirdHourRcvdIdx,
134
device[deviceToUpdate].last24HoursThpt[0].thirdRcvdTraffic =
135
device[deviceToUpdate].hash_hostTraffic[thirdHourRcvdIdx]->lastHourRcvdThpt;
137
device[deviceToUpdate].last24HoursThptIdx =
138
(device[deviceToUpdate].last24HoursThptIdx + 1) % 24;
140
if(device[deviceToUpdate].last24HoursThptIdx == 0) {
143
for(i=0; i<24; i++) {
144
average += device[deviceToUpdate].last24HoursThpt[i].trafficValue;
149
for(i=28; i>=0; i--) {
150
device[deviceToUpdate].last30daysThpt[i+1] =
151
device[deviceToUpdate].last30daysThpt[i];
154
device[deviceToUpdate].last30daysThpt[0] = average;
155
device[deviceToUpdate].last30daysThptIdx =
156
(device[deviceToUpdate].last30daysThptIdx + 1) % 30;
160
device[deviceToUpdate].numThptSamples++;
163
traceEvent(TRACE_INFO, "updateThptStats() completed.\n");
167
/* ******************************* */
169
static void updateDeviceThpt(int deviceToUpdate) {
170
time_t timeDiff, timeMinDiff, timeHourDiff=0, totalTime;
174
timeDiff = actTime-device[deviceToUpdate].lastThptUpdate;
176
if(timeDiff > 10 /* secs */) {
177
u_int topSentIdx=NO_PEER, secondSentIdx=NO_PEER, thirdSentIdx=NO_PEER;
178
u_int topHourSentIdx=NO_PEER, secondHourSentIdx=NO_PEER, thirdHourSentIdx=NO_PEER;
179
u_int topRcvdIdx=NO_PEER, secondRcvdIdx=NO_PEER, thirdRcvdIdx=NO_PEER;
180
u_int topHourRcvdIdx=NO_PEER, secondHourRcvdIdx=NO_PEER, thirdHourRcvdIdx=NO_PEER;
181
short updateMinThpt, updateHourThpt;
183
totalTime = actTime-initialSniffTime;
188
if((timeMinDiff = actTime-device[deviceToUpdate].lastMinThptUpdate) >= 60 /* 1 minute */) {
190
device[deviceToUpdate].lastMinThptUpdate = actTime;
191
if((timeHourDiff = actTime-device[deviceToUpdate].lastHourThptUpdate) >= 60*60 /* 1 hour */) {
193
device[deviceToUpdate].lastHourThptUpdate = actTime;
197
for(idx=1; idx<device[deviceToUpdate].actualHashSize; idx++) {
198
if((el = device[deviceToUpdate].hash_hostTraffic[idx]) != NULL) {
200
if(broadcastHost(el))
203
el->actualRcvdThpt = (float)(el->bytesReceived-el->lastBytesReceived)/timeDiff;
204
if(el->peakRcvdThpt < el->actualRcvdThpt) el->peakRcvdThpt = el->actualRcvdThpt;
205
if(el->peakSentThpt < el->actualSentThpt) el->peakSentThpt = el->actualSentThpt;
206
el->actualSentThpt = (float)(el->bytesSent-el->lastBytesSent)/timeDiff;
207
el->lastBytesSent = el->bytesSent;
208
el->lastBytesReceived = el->bytesReceived;
210
/* ******************************** */
212
el->actualRcvdPktThpt = (float)(el->pktReceived-el->lastPktReceived)/timeDiff;
213
if(el->peakRcvdPktThpt < el->actualRcvdPktThpt) el->peakRcvdPktThpt = el->actualRcvdPktThpt;
214
if(el->peakSentPktThpt < el->actualSentPktThpt) el->peakSentPktThpt = el->actualSentPktThpt;
215
el->actualSentPktThpt = (float)(el->pktSent-el->lastPktSent)/timeDiff;
216
el->lastPktSent = el->pktSent;
217
el->lastPktReceived = el->pktReceived;
219
/* ******************************** */
222
el->averageRcvdThpt = ((float)el->bytesReceived)/totalTime;
223
el->averageSentThpt = ((float)el->bytesSent)/totalTime;
224
el->averageRcvdPktThpt = ((float)el->pktReceived)/totalTime;
225
el->averageSentPktThpt = ((float)el->pktSent)/totalTime;
227
if(topSentIdx == NO_PEER) {
230
if(el->actualSentThpt > device[deviceToUpdate].hash_hostTraffic[topSentIdx]->actualSentThpt) {
231
secondSentIdx = topSentIdx;
234
if(secondSentIdx == NO_PEER)
237
if(el->actualSentThpt > device[deviceToUpdate].hash_hostTraffic[secondSentIdx]->actualSentThpt) {
238
thirdSentIdx = secondSentIdx;
241
if(thirdSentIdx == NO_PEER)
244
if(el->actualSentThpt > device[deviceToUpdate].hash_hostTraffic[thirdSentIdx]->actualSentThpt) {
253
if(topRcvdIdx == NO_PEER) {
256
if(el->actualRcvdThpt > device[deviceToUpdate].hash_hostTraffic[topRcvdIdx]->actualRcvdThpt) {
257
secondRcvdIdx = topRcvdIdx;
260
if(secondRcvdIdx == NO_PEER)
263
if(el->actualRcvdThpt > device[deviceToUpdate].hash_hostTraffic[secondRcvdIdx]->actualRcvdThpt) {
264
thirdRcvdIdx = secondRcvdIdx;
267
if(thirdRcvdIdx == NO_PEER)
270
if(el->actualRcvdThpt > device[deviceToUpdate].
271
hash_hostTraffic[thirdRcvdIdx]->actualRcvdThpt) {
281
el->lastHourRcvdThpt = (float)(el->bytesReceived-el->lastHourBytesReceived)/timeHourDiff;
282
el->lastHourSentThpt = (float)(el->bytesSent-el->lastHourBytesSent)/timeHourDiff;
283
el->lastHourBytesReceived = el->bytesReceived;
284
el->lastHourBytesSent = el->bytesSent;
286
if(topHourSentIdx == NO_PEER) {
287
topHourSentIdx = idx;
289
if(el->lastHourSentThpt > device[deviceToUpdate].
290
hash_hostTraffic[topHourSentIdx]->lastHourSentThpt) {
291
secondHourSentIdx = topHourSentIdx;
292
topHourSentIdx = idx;
294
if(secondHourSentIdx == NO_PEER)
295
secondHourSentIdx = idx;
297
if(el->lastHourSentThpt > device[deviceToUpdate].
298
hash_hostTraffic[secondHourSentIdx]->lastHourSentThpt) {
299
thirdHourSentIdx = secondHourSentIdx;
300
secondHourSentIdx = idx;
302
if(thirdHourSentIdx == NO_PEER)
303
thirdHourSentIdx = idx;
305
if(el->lastHourSentThpt > device[deviceToUpdate].
306
hash_hostTraffic[thirdHourSentIdx]->lastHourSentThpt) {
307
thirdHourSentIdx = idx;
315
if(topHourRcvdIdx == NO_PEER) {
316
topHourRcvdIdx = idx;
318
if(el->lastHourRcvdThpt > device[deviceToUpdate].
319
hash_hostTraffic[topHourRcvdIdx]->lastHourRcvdThpt) {
320
secondHourRcvdIdx = topHourRcvdIdx;
321
topHourRcvdIdx = idx;
323
if(secondHourRcvdIdx == NO_PEER)
324
secondHourRcvdIdx = idx;
326
if(el->lastHourRcvdThpt > device[deviceToUpdate].
327
hash_hostTraffic[secondHourRcvdIdx]->lastHourRcvdThpt) {
328
thirdHourRcvdIdx = secondHourRcvdIdx;
329
secondHourRcvdIdx = idx;
331
if(thirdHourRcvdIdx == NO_PEER)
332
thirdHourRcvdIdx = idx;
334
if(el->lastHourRcvdThpt > device[deviceToUpdate].
335
hash_hostTraffic[thirdHourRcvdIdx]->lastHourRcvdThpt) {
336
thirdHourRcvdIdx = idx;
348
/* ******************************** */
350
device[deviceToUpdate].throughput =
351
device[deviceToUpdate].ethernetBytes-device[deviceToUpdate].throughput;
352
device[deviceToUpdate].packetThroughput = device[deviceToUpdate].ethernetPkts-
353
device[deviceToUpdate].lastNumEthernetPkts;
354
device[deviceToUpdate].lastNumEthernetPkts = device[deviceToUpdate].ethernetPkts;
357
device[deviceToUpdate].actualThpt = (float)device[deviceToUpdate].throughput/(float)timeDiff;
358
device[deviceToUpdate].actualPktsThpt =
359
(float)device[deviceToUpdate].packetThroughput/(float)timeDiff;
361
if(device[deviceToUpdate].actualThpt > device[deviceToUpdate].peakThroughput)
362
device[deviceToUpdate].peakThroughput = device[deviceToUpdate].actualThpt;
364
if(device[deviceToUpdate].actualPktsThpt > device[deviceToUpdate].peakPacketThroughput)
365
device[deviceToUpdate].peakPacketThroughput = device[deviceToUpdate].actualPktsThpt;
367
device[deviceToUpdate].throughput = device[deviceToUpdate].ethernetBytes;
368
device[deviceToUpdate].packetThroughput = device[deviceToUpdate].ethernetPkts;
371
device[deviceToUpdate].lastMinEthernetBytes = device[deviceToUpdate].ethernetBytes-
372
device[deviceToUpdate].lastMinEthernetBytes;
373
device[deviceToUpdate].lastMinThpt =
374
(float)(device[deviceToUpdate].lastMinEthernetBytes)/(float)timeMinDiff;
375
device[deviceToUpdate].lastMinEthernetBytes = device[deviceToUpdate].ethernetBytes;
376
/* ******************* */
377
device[deviceToUpdate].lastMinEthernetPkts = device[deviceToUpdate].ethernetPkts-
378
device[deviceToUpdate].lastMinEthernetPkts;
379
device[deviceToUpdate].lastMinPktsThpt =
380
(float)device[deviceToUpdate].lastMinEthernetPkts/(float)timeMinDiff;
381
device[deviceToUpdate].lastMinEthernetPkts = device[deviceToUpdate].ethernetPkts;
382
device[deviceToUpdate].lastMinThptUpdate = actTime;
385
if((timeMinDiff = actTime-device[deviceToUpdate].lastFiveMinsThptUpdate) > 300 /* 5 minutes */) {
386
device[deviceToUpdate].lastFiveMinsEthernetBytes =
387
device[deviceToUpdate].ethernetBytes - device[deviceToUpdate].lastFiveMinsEthernetBytes;
388
device[deviceToUpdate].lastFiveMinsThptUpdate = timeMinDiff;
389
device[deviceToUpdate].lastFiveMinsThpt =
390
(float)device[deviceToUpdate].lastFiveMinsEthernetBytes/(float)device[deviceToUpdate].lastFiveMinsThptUpdate;
391
device[deviceToUpdate].lastFiveMinsEthernetBytes = device[deviceToUpdate].ethernetBytes;
392
/* ******************* */
393
device[deviceToUpdate].lastFiveMinsEthernetPkts =
394
device[deviceToUpdate].ethernetPkts - device[deviceToUpdate].lastFiveMinsEthernetPkts;
395
device[deviceToUpdate].lastFiveMinsPktsThpt =
396
(float)device[deviceToUpdate].lastFiveMinsEthernetPkts/(float)device[deviceToUpdate].lastFiveMinsThptUpdate;
397
device[deviceToUpdate].lastFiveMinsEthernetPkts = device[deviceToUpdate].ethernetPkts;
398
device[deviceToUpdate].lastFiveMinsThptUpdate = actTime;
401
if((updateMinThpt || updateHourThpt)
402
&& ((topSentIdx != NO_PEER)
403
|| (topHourSentIdx != NO_PEER)
404
|| (topRcvdIdx != NO_PEER)
405
|| (topHourRcvdIdx != NO_PEER)))
406
updateThptStats(deviceToUpdate,
407
topSentIdx, secondSentIdx, thirdSentIdx,
408
topHourSentIdx, secondHourSentIdx, thirdHourSentIdx,
409
topRcvdIdx, secondRcvdIdx, thirdRcvdIdx,
410
topHourRcvdIdx, secondHourRcvdIdx, thirdHourRcvdIdx);
412
device[deviceToUpdate].lastThptUpdate = actTime;
416
/* ******************************* */
418
void updateThpt(void) {
424
for(i=0; i<numDevices; i++)
429
/* ******************************* */
431
static void updateHostThpt(HostTraffic *el, int hourId) {
433
if(broadcastHost(el))
436
el->lastCounterBytesSent = el->bytesSent;
437
el->lastCounterBytesRcvd = el->bytesReceived;
440
el->lastDayBytesSent = el->bytesSent;
441
el->lastDayBytesRcvd = el->bytesReceived;
445
/* ******************************* */
447
static void updateHostsDeviceThpt(int deviceToUpdate, int hourId) {
451
for(idx=1; idx<device[deviceToUpdate].actualHashSize; idx++) {
452
if((el = device[deviceToUpdate].hash_hostTraffic[idx]) != NULL) {
453
updateHostThpt(el, hourId);
458
/* ******************************* */
460
void updateHostTrafficStatsThpt(int hourId) {
464
updateHostsDeviceThpt(0, hourId);
466
for(i=0; i<numDevices; i++)
467
updateHostsDeviceThpt(i, hourId);
471
/* ******************************* */
473
void updateTrafficMatrix(HostTraffic *srcHost,
474
HostTraffic *dstHost,
475
TrafficCounter length) {
476
if(subnetLocalHost(srcHost) && subnetLocalHost(dstHost)) {
477
unsigned long a, b, id;
479
a = (unsigned long)(srcHost->hostIpAddress.s_addr) % device[actualDeviceId].numHosts;
480
b = (unsigned long)(dstHost->hostIpAddress.s_addr) % device[actualDeviceId].numHosts;
482
device[actualDeviceId].ipTrafficMatrixHosts[a] = srcHost,
483
device[actualDeviceId].ipTrafficMatrixHosts[b] = dstHost;
485
id = a*device[actualDeviceId].numHosts+b;
486
if(device[actualDeviceId].ipTrafficMatrix[id] == NULL)
487
device[actualDeviceId].ipTrafficMatrix[id] = (TrafficEntry*)calloc(1, sizeof(TrafficEntry));
488
device[actualDeviceId].ipTrafficMatrix[id]->bytesSent += length;
490
id = b*device[actualDeviceId].numHosts+a;
491
if(device[actualDeviceId].ipTrafficMatrix[id] == NULL)
492
device[actualDeviceId].ipTrafficMatrix[id] = (TrafficEntry*)calloc(1, sizeof(TrafficEntry));
493
device[actualDeviceId].ipTrafficMatrix[id]->bytesReceived += length;
497
/* *********************************** */
499
void updateDbHostsTraffic(int deviceToUpdate) {
504
traceEvent(TRACE_INFO, "updateDbHostsTraffic(device=%d)", deviceToUpdate);
507
for(i=0; i<device[deviceToUpdate].actualHashSize; i++) {
508
el = device[deviceToUpdate].hash_hostTraffic[i]; /* (**) */
511
&& (!broadcastHost(el))
512
&& (el->nextDBupdate < actTime)) {
516
if(el->nextDBupdate == 0) {
517
/* traceEvent(TRACE_INFO, "1"); */
518
notifyHostCreation(el);
520
mySQLnotifyHostCreation(el);
522
/* traceEvent(TRACE_INFO, "2"); */
523
} else if(el->nextDBupdate < actTime) {
524
/* traceEvent(TRACE_INFO, "3"); */
525
updateHostTraffic(el);
526
/* traceEvent(TRACE_INFO, "4"); */
528
mySQLupdateHostTraffic(el);
530
/* traceEvent(TRACE_INFO, "5"); */
531
if(el->osName == NULL) {
532
/* traceEvent(TRACE_INFO, "6"); */
534
/* traceEvent(TRACE_INFO, "7"); */
538
el->nextDBupdate = actTime + DB_TIMEOUT_REFRESH_TIME;
544
/* ************************ */
546
int isInitialHttpData(char* packetData) {
548
if((strncmp(packetData, "GET ", 4) == 0) /* HTTP/1.0 */
549
|| (strncmp(packetData, "HEAD ", 5) == 0)
550
|| (strncmp(packetData, "LINK ", 5) == 0)
551
|| (strncmp(packetData, "POST ", 5) == 0)
552
|| (strncmp(packetData, "OPTIONS ", 8) == 0) /* HTTP/1.1 */
553
|| (strncmp(packetData, "PUT ", 4) == 0)
554
|| (strncmp(packetData, "DELETE ", 7) == 0)
555
|| (strncmp(packetData, "TRACE ", 6) == 0)
556
|| (strncmp(packetData, "PROPFIND", 8) == 0) /* RFC 2518 */
563
/* ************************ */
565
int isInitialSshData(char* packetData) {
566
/* SSH-1.99-OpenSSH_2.1.1 */
567
if(strncmp(packetData, "SSH-", 4) == 0)
573
/* ************************ */
575
int isInitialFtpData(char* packetData) {
576
/* 220 linux.local FTP server (Version 6.4/OpenBSD/Linux-ftpd-0.16) ready. */
577
if((strncmp(packetData, "220 ", 4) == 0)
578
|| (strncmp(packetData, "530", 3) == 0))