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.
23
* Copyright (c) 1994, 1996
24
* The Regents of the University of California. All rights reserved.
26
* Redistribution and use in source and binary forms, with or without
27
* modification, are permitted provided that: (1) source code distributions
28
* retain the above copyright notice and this paragraph in its entirety, (2)
29
* distributions including binary code include the above copyright notice and
30
* this paragraph in its entirety in the documentation or other materials
31
* provided with the distribution, and (3) all advertising materials mentioning
32
* features or use of this software display the following acknowledgement:
33
* ``This product includes software developed by the University of California,
34
* Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
35
* the University nor the names of its contributors may be used to endorse
36
* or promote products derived from this software without specific prior
38
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
39
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
40
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
57
/* #define MEMORY_DEBUG */
59
#define MAX_DEVICE_NAME_LEN 64
66
#define MAX_NUM_NETWORKS 32
70
#define INVALIDNETMASK -1
72
#define NUM_SESSION_INFO 128
73
#define MAX_NUM_SESSION_INFO 2*NUM_SESSION_INFO /* Not yet used */
75
#define PASSIVE_SESSION_PURGE_TIMEOUT 60 /* seconds */
77
static SessionInfo *passiveSessions;
78
static u_short numLocalNets=0, passiveSessionsLen;
80
/* [0]=network, [1]=mask, [2]=broadcast */
81
static u_int32_t networks[MAX_NUM_NETWORKS][3];
84
* secure popen by Thomas Biege <thomas@suse.de>
86
* Fixes by Andreas Pfaller <a.pfaller@pop.gun.de>
88
#define __SEC_POPEN_TOKEN " "
92
FILE *sec_popen(char *cmd, const char *type) {
96
int rpipe = 0, wpipe = 0, i;
97
char **argv, *ptr, *cmdcpy=NULL, *strtokState;
98
if(cmd == NULL || cmd == "")
101
if(strcmp(type, "r") && strcmp(type, "w"))
104
if((cmdcpy = strdup(cmd)) == NULL)
108
if((ptr = strtok_r(cmdcpy, __SEC_POPEN_TOKEN, &strtokState)) == NULL) {
114
if((argv = (char **)realloc(argv, (i+1) * sizeof(char*))) == NULL) {
119
if((*(argv+i) = (char*)malloc((strlen(ptr)+1) * sizeof(char))) == NULL) {
124
strcpy(argv[i], ptr);
126
if((ptr = strtok_r(NULL, __SEC_POPEN_TOKEN, &strtokState)) == NULL) {
127
if((argv = (char **) realloc(argv, (i+2) * sizeof(char*))) == NULL) {
146
if((pid = fork()) < 0) {
154
if((pid = fork()) < 0) {
162
exit(0); /* child nr. 1 exits */
166
close(pfd[0]); /* close reading end, we don't need it */
167
if(pfd[1] != STDOUT_FILENO)
168
dup2(pfd[1], STDOUT_FILENO); /* redirect stdout to writing end of pipe */
169
dup2(STDOUT_FILENO, STDERR_FILENO);
171
close(pfd[1]); /* close writing end, we don't need it */
173
if(pfd[0] != STDIN_FILENO)
174
dup2(pfd[0], STDOUT_FILENO); /* redirect stdin to reading end of pipe */
177
if(strchr(argv[0], '/') == NULL)
178
execvp(argv[0], argv); /* search in $PATH */
180
execv(argv[0], argv);
184
return(NULL); /* exec failed.. ooops! */
188
waitpid(pid, NULL, 0); /* wait for child nr. 1 */
192
return(fdopen(pfd[0], "r"));
195
return(fdopen(pfd[1], "r"));
199
#endif /* SEC_POPEN */
203
/* ************************************ */
205
u_int findHostIdxByNumIP(struct in_addr hostIpAddress) {
208
for(idx=1; idx<device[actualDeviceId].actualHashSize; idx++)
209
if((device[actualDeviceId].hash_hostTraffic[idx] != NULL)
210
&& (device[actualDeviceId].hash_hostTraffic[idx]->hostNumIpAddress != NULL)
211
&& (device[actualDeviceId].hash_hostTraffic[idx]->hostIpAddress.s_addr == hostIpAddress.s_addr))
217
/* ************************************ */
219
HostTraffic* findHostByNumIP(char* numIPaddr) {
222
for(idx=1; idx<device[actualDeviceId].actualHashSize; idx++)
223
if((device[actualDeviceId].hash_hostTraffic[idx] != NULL)
224
&& (device[actualDeviceId].hash_hostTraffic[idx]->hostNumIpAddress != NULL)
225
&& (!strcmp(device[actualDeviceId].hash_hostTraffic[idx]->hostNumIpAddress, numIPaddr)))
226
return(device[actualDeviceId].hash_hostTraffic[idx]);
231
/* ************************************ */
233
HostTraffic* findHostByMAC(char* macAddr) {
236
for(idx=1; idx<device[actualDeviceId].actualHashSize; idx++)
237
if(device[actualDeviceId].hash_hostTraffic[idx]
238
&& device[actualDeviceId].hash_hostTraffic[idx]->hostNumIpAddress
239
&& (!strcmp(device[actualDeviceId].hash_hostTraffic[idx]->ethAddressString, macAddr)))
240
return(device[actualDeviceId].hash_hostTraffic[idx]);
245
/* ************************************ */
248
* Copy arg vector into a new buffer, concatenating arguments with spaces.
250
char* copy_argv(register char **argv) {
252
register u_int len = 0;
261
len += strlen(*p++) + 1;
263
buf = (char*)malloc(len);
265
traceEvent(TRACE_INFO, "copy_argv: malloc");
271
while ((src = *p++) != NULL) {
272
while ((*dst++ = *src++) != '\0')
281
/* ********************************* */
283
unsigned short isBroadcastAddress(struct in_addr *addr) {
288
else if(addr->s_addr == 0x0)
289
return 0; /* IP-less device (is it trying to boot via DHCP/BOOTP ?) */
291
for(i=0; i<numDevices; i++)
292
if(device[i].netmask.s_addr == 0xFFFFFFFF) /* PPP */
294
else if(((addr->s_addr | device[i].netmask.s_addr) == addr->s_addr)
295
|| ((addr->s_addr & 0x000000FF) == 0x000000FF)
296
|| ((addr->s_addr & 0x000000FF) == 0x00000000) /* Network address */
299
traceEvent(TRACE_INFO, "%s is a broadcast address", intoa(*addr));
304
return(isPseudoBroadcastAddress(addr));
308
/* ********************************* */
310
unsigned short isMulticastAddress(struct in_addr *addr) {
311
if((addr->s_addr & MULTICAST_MASK) == MULTICAST_MASK) {
313
traceEvent(TRACE_INFO, "%s is multicast [%X/%X]\n",
315
((unsigned long)(addr->s_addr) & MULTICAST_MASK),
324
/* ********************************* */
326
unsigned short isLocalAddress(struct in_addr *addr) {
329
for(i=0; i<numDevices; i++)
330
if((addr->s_addr & device[i].netmask.s_addr) == device[i].network.s_addr) {
332
traceEvent(TRACE_INFO, "%s is local\n", intoa(*addr));
338
traceEvent(TRACE_INFO, "%s is %s\n", intoa(*addr),
339
isLocalAddress (addr) ? "pseudolocal" : "remote");
341
/* Broadcast is considered a local address */
342
return(isBroadcastAddress(addr));
345
/* ********************************* */
347
unsigned short isPrivateAddress(struct in_addr *addr) {
349
/* See http://www.isi.edu/in-notes/rfc1918.txt */
351
/* Fixes below courtesy of Wies-Software <wies@wiessoft.de> */
352
if(((addr->s_addr & 0xFF000000) == 0x0A000000) /* 10/8 */
353
|| ((addr->s_addr & 0xFFF00000) == 0xAC100000) /* 172.16/12 */
354
|| ((addr->s_addr & 0xFFFF0000) == 0xC0A80000) /* 192.168/16 */
361
/* **********************************************
365
* It converts an integer in the range
366
* from 0 to 255 in number of bits
367
* useful for netmask calculation.
368
* The conversion is valid if there
369
* is an uninterrupted sequence of
370
* bits set to 1 at the most signi-
371
* ficant positions. Example:
374
* 1110 1000 -> invalid
377
* 0 - 8 (number of subsequent
379
* -1 (INVALIDNETMASK)
382
* Courtesy of Antonello Maiorca <marty@tai.it>
384
*********************************************** */
386
static int int2bits(int number) {
390
if((number > 255) || (number < 0))
393
traceEvent(TRACE_ERROR, "int2bits (%3d) = %d\n", number, INVALIDNETMASK);
395
return(INVALIDNETMASK);
399
test = ~number & 0xff;
405
if(number != ((~(0xff >> bits)) & 0xff))
408
traceEvent(TRACE_ERROR, "int2bits (%3d) = %d\n", number, INVALIDNETMASK);
410
return(INVALIDNETMASK);
415
traceEvent(TRACE_ERROR, "int2bits (%3d) = %d\n", number, bits);
422
/* ***********************************************
426
* Converts a dotted quad notation
427
* netmask specification to the
428
* equivalent number of bits.
429
* from 0 to 255 in number of bits
430
* useful for netmask calculation.
431
* The converion is valid if there
432
* is an uninterrupted sequence of
433
* bits set to 1 at the most signi-
434
* ficant positions. Example:
437
* 1110 1000 -> invalid
440
* 0 - 32 (number of subsequent
442
* -1 (INVALIDNETMASK)
445
* Courtesy of Antonello Maiorca <marty@tai.it>
447
*********************************************** */
449
int dotted2bits(char *mask) {
451
int fields_num, field_bits;
455
fields_num = sscanf(mask, "%d.%d.%d.%d",
456
&fields[0], &fields[1], &fields[2], &fields[3]);
457
if((fields_num == 1) && (fields[0] <= 32) && (fields[0] >= 0))
460
traceEvent(TRACE_ERROR, "dotted2bits (%s) = %d\n", mask, fields[0]);
464
for (i=0; i < fields_num; i++)
466
/* We are in a dotted quad notation. */
467
field_bits = int2bits (fields[i]);
471
return(INVALIDNETMASK);
474
/* whenever a 0 bits field is reached there are no more */
477
traceEvent(TRACE_ERROR, "dotted2bits (%15s) = %d\n", mask, bits);
479
/* In this case we are in a bits (not dotted quad) notation */
480
return(bits /* fields[0] - L.Deri 08/2001 */);
487
traceEvent(TRACE_ERROR, "dotted2bits (%15s) = %d\n", mask, bits);
492
/* ********************************* */
494
/* Example: "131.114.0.0/16,193.43.104.0/255.255.255.0" */
496
void handleLocalAddresses(char* addresses) {
497
char *strtokState, *address = strtok_r(addresses, ",", &strtokState);
500
while(address != NULL) {
501
char *mask = strchr(address, '/');
504
traceEvent(TRACE_INFO, "Unknown network '%s' (empty mask!). It has been ignored.\n",
507
u_int32_t network, networkMask, broadcast;
508
int bits, a, b, c, d;
512
bits = dotted2bits (mask);
514
if(sscanf(address, "%d.%d.%d.%d", &a, &b, &c, &d) != 4) {
515
traceEvent(TRACE_ERROR, "Unknown network '%s' .. skipping. Check network numbers.\n",
517
address = strtok_r(NULL, ",", &strtokState);
521
if(bits == INVALIDNETMASK) {
522
/* malformed netmask specification */
523
traceEvent(TRACE_ERROR,
524
"The specified netmask %s is not valid. Skipping it..\n",
526
address = strtok_r(NULL, ",", &strtokState);
530
network = ((a & 0xff) << 24) + ((b & 0xff) << 16) + ((c & 0xff) << 8) + (d & 0xff);
531
networkMask = 0xffffffff >> bits;
532
networkMask = ~networkMask;
535
traceEvent(TRACE_INFO, "Nw=%08X - Mask: %08X [%08X]\n",
536
network, networkMask, (network & networkMask));
539
if((networkMask >= 0xFFFFFF00) /* Courtesy of Roy-Magne Mo <romo@interpost.no> */
540
&& ((network & networkMask) != network)) {
541
/* malformed network specification */
542
traceEvent(TRACE_ERROR, "WARNING: %d.%d.%d.%d/%d is not a valid network number\n",
545
/* correcting network numbers as specified in the netmask */
546
network &= networkMask;
548
a = (int) ((network >> 24) & 0xff);
549
b = (int) ((network >> 16) & 0xff);
550
c = (int) ((network >> 8) & 0xff);
551
d = (int) ((network >> 0) & 0xff);
553
traceEvent(TRACE_ERROR, "Assuming %d.%d.%d.%d/%d [0x%08x/0x%08x]\n\n",
554
a, b, c, d, bits, network, networkMask);
557
traceEvent(TRACE_INFO, "%d.%d.%d.%d/%d [0x%08x/0x%08x]\n",
558
a, b, c, d, bits, network, networkMask);
561
broadcast = network | (~networkMask);
564
a = (int) ((broadcast >> 24) & 0xff);
565
b = (int) ((broadcast >> 16) & 0xff);
566
c = (int) ((broadcast >> 8) & 0xff);
567
d = (int) ((broadcast >> 0) & 0xff);
569
traceEvent(TRACE_INFO, "Broadcast: [net=0x%08x] [broadcast=%d.%d.%d.%d]\n",
570
network, a, b, c, d);
573
if(numLocalNets < MAX_NUM_NETWORKS) {
576
for(i=0; i<numDevices; i++)
577
if((network == device[i].network.s_addr)
578
&& (device[i].netmask.s_addr == networkMask)) {
579
a = (int) ((network >> 24) & 0xff);
580
b = (int) ((network >> 16) & 0xff);
581
c = (int) ((network >> 8) & 0xff);
582
d = (int) ((network >> 0) & 0xff);
584
traceEvent(TRACE_WARNING, "WARNING: Discarded network %d.%d.%d.%d/%d: "
585
"this is the local network.\n",
591
networks[numLocalNets][NETWORK] = network;
592
networks[numLocalNets][NETMASK] = networkMask;
593
networks[numLocalNets][BROADCAST] = broadcast;
597
traceEvent(TRACE_WARNING, "Unable to handle network (too many entries!).\n");
600
address = strtok_r(NULL, ",", &strtokState);
604
/* ********************************* */
606
/* This function returns true when a host is considered local
607
as specified using the 'm' flag */
608
unsigned short isPseudoLocalAddress(struct in_addr *addr) {
611
i = isLocalAddress(addr);
614
return 1; /* This is a real local address */
616
for(i=0; i<numLocalNets; i++) {
618
char buf[32], buf1[32], buf2[32];
619
struct in_addr addr1, addr2;
621
addr1.s_addr = networks[i][NETWORK];
622
addr2.s_addr = networks[i][NETMASK];
624
traceEvent(TRACE_INFO, "%s comparing [%s/%s]\n",
625
_intoa(*addr, buf, sizeof(buf)),
626
_intoa(addr1, buf1, sizeof(buf1)),
627
_intoa(addr2, buf2, sizeof(buf2)));
629
if((addr->s_addr & networks[i][NETMASK]) == networks[i][NETWORK]) {
631
traceEvent(TRACE_WARNING, "%s is pseudolocal\n", intoa(*addr));
636
traceEvent(TRACE_WARNING, "%s is NOT pseudolocal\n", intoa(*addr));
642
We don't check for broadcast as this check has been
643
performed already by isLocalAddress() just called
648
/* ********************************* */
650
/* This function returns true when an address is the broadcast
651
for the specified (-m flag subnets */
653
unsigned short isPseudoBroadcastAddress(struct in_addr *addr) {
657
traceEvent(TRACE_WARNING, "Checking %8X (pseudo broadcast)\n", addr->s_addr);
660
for(i=0; i<numLocalNets; i++) {
661
if(addr->s_addr == networks[i][BROADCAST]) {
663
traceEvent(TRACE_WARNING, "--> %8X is pseudo broadcast\n", addr->s_addr);
669
traceEvent(TRACE_WARNING, "%8X/%8X is NOT pseudo broadcast\n", addr->s_addr, networks[i][BROADCAST]);
676
/* ********************************* */
679
* Returns the difference between gmt and local time in seconds.
680
* Use gmtime() and localtime() to keep things simple.
681
* [Borrowed from tcpdump]
683
int32_t gmt2local(time_t t) {
685
struct tm *gmt, *myloc;
692
myloc = localtime_r(&t, &loc);
694
dt = (myloc->tm_hour - gmt->tm_hour)*60*60+(myloc->tm_min - gmt->tm_min)*60;
697
* If the year or julian day is different, we span 00:00 GMT
698
* and must add or subtract a day. Check the year first to
699
* avoid problems when the julian day wraps.
701
dir = myloc->tm_year - gmt->tm_year;
703
dir = myloc->tm_yday - gmt->tm_yday;
704
dt += dir * 24 * 60 * 60;
709
/* ********************************* */
711
/* Example: "flow1='host jake',flow2='dst host born2run'" */
712
void handleFlowsSpecs(char* flows) {
713
FILE *fd = fopen(flows, "rb");
714
char *flow, *buffer=NULL, *strtokState;;
717
flow = strtok_r(flows, ",", &strtokState);
722
if(stat(flows, &buf) != 0) {
723
traceEvent(TRACE_INFO, "Error while stat() of %s\n", flows);
727
buffer = (char*)malloc(buf.st_size+8) /* just to be safe */;
729
for(i=0;i<buf.st_size;) {
730
len = fread(&buffer[i], sizeof(char), buf.st_size-i, fd);
737
/* remove trailing carriage return */
738
if(buffer[strlen(buffer)-1] == '\n')
739
buffer[strlen(buffer)-1] = 0;
741
flow = strtok_r(buffer, ",", &strtokState);
744
while(flow != NULL) {
745
char *flowSpec = strchr(flow, '=');
748
traceEvent(TRACE_INFO, "Missing flow spec '%s'. It has been ignored.\n", flow);
750
struct bpf_program fcode;
752
char *flowName = flow;
756
/* flowSpec should now point to 'host jake' */
757
len = strlen(flowSpec);
760
|| (flowSpec[0] != '\'')
761
|| (flowSpec[len-1] != '\''))
762
traceEvent(TRACE_WARNING, "Wrong flow specification \"%s\" (missing \'). "
763
"It has been ignored.\n", flowSpec);
765
flowSpec[len-1] = '\0';
768
rc = pcap_compile(device[0].pcapPtr, &fcode, flowSpec, 1, device[0].netmask.s_addr);
771
traceEvent(TRACE_INFO, "Wrong flow specification \"%s\" (syntax error). "
772
"It has been ignored.\n", flowSpec);
774
FlowFilterList *newFlow;
776
newFlow = (FlowFilterList*)calloc(1, sizeof(FlowFilterList));
778
if(newFlow == NULL) {
779
traceEvent(TRACE_INFO, "Fatal error: not enough memory. Bye!\n");
780
if(buffer != NULL) free(buffer);
785
newFlow->fcode = (struct bpf_program*)calloc(numDevices, sizeof(struct bpf_program));
787
for(i=0; i<numDevices; i++) {
788
rc = pcap_compile(device[i].pcapPtr, &newFlow->fcode[i],
789
flowSpec, 1, device[i].netmask.s_addr);
792
traceEvent(TRACE_WARNING, "Wrong flow specification \"%s\" (syntax error). "
793
"It has been ignored.\n", flowSpec);
799
newFlow->flowName = strdup(flowName);
800
newFlow->pluginStatus.activePlugin = 1;
801
newFlow->pluginStatus.pluginPtr = NULL; /* Added by Jacques Le Rest <jlerest@ifremer.fr> */
802
newFlow->next = flowsList;
809
flow = strtok_r(NULL, ",", &strtokState);
816
/* ********************************* */
818
int getLocalHostAddress(struct in_addr *hostAddress, char* device) {
821
hostAddress->s_addr = GetHostIPAddr();
825
register struct sockaddr_in *sin;
831
fd = socket(AF_INET, SOCK_DGRAM, 0);
833
traceEvent(TRACE_INFO, "socket error: %d", errno);
837
memset(&ifr, 0, sizeof(ifr));
840
/* XXX Work around Linux kernel bug */
841
ifr.ifr_addr.sa_family = AF_INET;
843
strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
844
if(ioctl(fd, SIOCGIFADDR, (char*)&ifr) < 0) {
846
traceEvent(TRACE_INFO, "SIOCGIFADDR error: %s/errno=%d", device, errno);
850
sin = (struct sockaddr_in *)&ifr.ifr_addr;
852
if((hostAddress->s_addr = ntohl(sin->sin_addr.s_addr)) == 0)
857
traceEvent(TRACE_INFO, "Local address is: %s\n", intoa(*hostAddress));
860
/* ******************************* */
866
if(ioctl(fd, SIOCGIFNETMASK, (char*)&ifr) >= 0) {
867
sin = (struct sockaddr_in *)&ifr.ifr_broadaddr;
868
numHosts = 0xFFFFFFFF - ntohl(sin->sin_addr.s_addr)+1;
870
numHosts = 256; /* default C class */
872
traceEvent(TRACE_INFO, "Num subnet hosts: %d\n", numHosts);
876
/* ******************************* */
884
/* ********************************* */
889
/* *********** MULTITHREAD STUFF *********** */
891
int createThread(pthread_t *threadId,
892
void *(*__start_routine) (void *),
896
rc = pthread_create(threadId, NULL, __start_routine, userParm);
901
/* ************************************ */
903
void killThread(pthread_t *threadId) {
904
pthread_detach(*threadId);
908
/* ************************************ */
910
int _createMutex(PthreadMutex *mutexId, char* fileName, int fileLine) {
913
memset(mutexId, 0, sizeof(PthreadMutex));
915
rc = pthread_mutex_init(&(mutexId->mutex), NULL);
917
#ifdef PTHREAD_MUTEX_ERRORCHECK_NP
919
/* *************************************************
920
There seems to be some problem with mutexes and some
923
http://sdb.suse.de/sdb/de/html/aj_pthread7.0.html
925
(in German but an english version is probably available on their
926
international web site). Suggested workaround is either to use
928
pthread_mutexattr_settype (&mutattr, PTHREAD_MUTEX_ERRORCHECK_NP);
930
as checked mutexes dont have the error or use a corrected
931
glibc (Suse offers a patched version for their system).
933
Andreas Pfaeller <a.pfaller@pop.gun.de>
935
************************************************* */
937
pthread_mutexattr_settype (&(mutexId->mutex),
938
PTHREAD_MUTEX_ERRORCHECK_NP);
940
#endif /* PTHREAD_MUTEX_ERRORCHECK_NP */
942
mutexId->isInitialized = 1;
947
/* ************************************ */
949
void _deleteMutex(PthreadMutex *mutexId, char* fileName, int fileLine) {
951
if(!mutexId->isInitialized) {
952
traceEvent(TRACE_ERROR,
953
"ERROR: deleteMutex() call with a NULL mutex [%s:%d]\n",
958
pthread_mutex_unlock(&(mutexId->mutex));
959
pthread_mutex_destroy(&(mutexId->mutex));
961
memset(mutexId, 0, sizeof(PthreadMutex));
964
/* ************************************ */
966
int _accessMutex(PthreadMutex *mutexId, char* where,
967
char* fileName, int fileLine) {
970
if(!mutexId->isInitialized) {
971
traceEvent(TRACE_ERROR,
972
"ERROR: accessMutex() call with a NULL mutex [%s:%d]\n",
977
#ifdef SEMAPHORE_DEBUG
978
traceEvent(TRACE_INFO, "Locking 0x%X @ %s [%s:%d]\n",
979
&(mutexId->mutex), where, fileName, fileLine);
981
rc = pthread_mutex_lock(&(mutexId->mutex));
984
traceEvent(TRACE_ERROR, "ERROR: lock failed 0x%X [%s:%d] (rc=%d)\n",
985
(void*)&(mutexId->mutex), fileName, fileLine, rc);
987
/* traceEvent(TRACE_ERROR, "LOCKED 0x%X", &(mutexId->mutex)); */
989
mutexId->isLocked = 1;
990
mutexId->lockTime = time(NULL);
991
if(fileName != NULL) {
992
strcpy(mutexId->lockFile, fileName);
993
mutexId->lockLine = fileLine;
997
#ifdef SEMAPHORE_DEBUG
998
traceEvent(TRACE_INFO, "Locked 0x%X @ %s [%s:%d]\n",
999
&(mutexId->mutex), where, fileName, fileLine);
1004
/* ************************************ */
1006
int _tryLockMutex(PthreadMutex *mutexId, char* where,
1007
char* fileName, int fileLine) {
1010
if(!mutexId->isInitialized) {
1011
traceEvent(TRACE_ERROR,
1012
"ERROR: tryLockMutex() call with a NULL mutex [%s:%d]\n",
1013
fileName, fileLine);
1017
#ifdef SEMAPHORE_DEBUG
1018
traceEvent(TRACE_INFO, "Try to Lock 0x%X @ %s [%s:%d]\n",
1019
mutexId, where, fileName, fileLine);
1026
EBUSY (mutex already locked)
1028
rc = pthread_mutex_trylock(&(mutexId->mutex));
1031
traceEvent(TRACE_ERROR, "ERROR: tryLockMutex failed 0x%X [%s:%d] (rc=%d)\n",
1032
(void*)&(mutexId->mutex), fileName, fileLine, rc);
1034
/* traceEvent(TRACE_ERROR, "LOCKED 0x%X", &(mutexId->mutex)); */
1035
mutexId->isLocked = 1;
1036
mutexId->lockTime = time(NULL);
1037
if(fileName != NULL) {
1038
strcpy(mutexId->lockFile, fileName);
1039
mutexId->lockLine = fileLine;
1046
/* ************************************ */
1048
int _isMutexLocked(PthreadMutex *mutexId, char* fileName, int fileLine) {
1051
if(!mutexId->isInitialized) {
1052
traceEvent(TRACE_ERROR,
1053
"ERROR: isMutexLocked() call with a NULL mutex [%s:%d]\n",
1054
fileName, fileLine);
1058
#ifdef SEMAPHORE_DEBUG
1059
traceEvent(TRACE_INFO, "Checking whether 0x%X is locked [%s:%d]\n",
1060
&(mutexId->mutex), fileName, fileLine);
1063
rc = pthread_mutex_trylock(&(mutexId->mutex));
1069
EBUSY (mutex already locked)
1073
pthread_mutex_unlock(&(mutexId->mutex));
1079
/* ************************************ */
1081
int _releaseMutex(PthreadMutex *mutexId,
1082
char* fileName, int fileLine) {
1085
if(!mutexId->isInitialized) {
1086
traceEvent(TRACE_ERROR,
1087
"ERROR: releaseMutex() call with a NULL mutex [%s:%d]\n",
1088
fileName, fileLine);
1092
#ifdef SEMAPHORE_DEBUG
1093
traceEvent(TRACE_INFO, "Unlocking 0x%X [%s:%d]\n",
1094
&(mutexId->mutex), fileName, fileLine);
1096
rc = pthread_mutex_unlock(&(mutexId->mutex));
1099
traceEvent(TRACE_ERROR, "ERROR: unlock failed 0x%X [%s:%d]\n",
1100
(void*)&(mutexId->mutex), fileName, fileLine);
1102
time_t lockDuration = time(NULL) - mutexId->lockTime;
1104
if((mutexId->maxLockedDuration < lockDuration)
1105
|| (mutexId->maxLockedDurationUnlockLine == 0 /* Never set */)) {
1106
mutexId->maxLockedDuration = lockDuration;
1108
if(fileName != NULL) {
1109
strcpy(mutexId->maxLockedDurationUnlockFile, fileName);
1110
mutexId->maxLockedDurationUnlockLine = fileLine;
1114
if(mutexId->maxLockedDuration > 0) {
1115
traceEvent(TRACE_INFO, "INFO: semaphore 0x%X [%s:%d] locked for %d secs\n",
1116
(void*)&(mutexId->mutex), fileName, fileLine,
1117
mutexId->maxLockedDuration);
1122
/* traceEvent(TRACE_ERROR, "UNLOCKED 0x%X", &(mutexId->mutex)); */
1123
mutexId->isLocked = 0;
1124
mutexId->numReleases++;
1125
if(fileName != NULL) {
1126
strcpy(mutexId->unlockFile, fileName);
1127
mutexId->unlockLine = fileLine;
1131
#ifdef SEMAPHORE_DEBUG
1132
traceEvent(TRACE_INFO, "Unlocked 0x%X [%s:%d]\n",
1133
&(mutexId->mutex), fileName, fileLine);
1138
/* ************************************ */
1140
int createCondvar(ConditionalVariable *condvarId) {
1143
rc = pthread_mutex_init(&condvarId->mutex, NULL);
1144
rc = pthread_cond_init(&condvarId->condvar, NULL);
1145
condvarId->predicate = 0;
1150
/* ************************************ */
1152
void deleteCondvar(ConditionalVariable *condvarId) {
1153
pthread_mutex_destroy(&condvarId->mutex);
1154
pthread_cond_destroy(&condvarId->condvar);
1157
/* ************************************ */
1159
int waitCondvar(ConditionalVariable *condvarId) {
1162
if((rc = pthread_mutex_lock(&condvarId->mutex)) != 0)
1165
while(condvarId->predicate <= 0) {
1166
rc = pthread_cond_wait(&condvarId->condvar, &condvarId->mutex);
1169
condvarId->predicate--;
1171
rc = pthread_mutex_unlock(&condvarId->mutex);
1176
/* ************************************ */
1178
int signalCondvar(ConditionalVariable *condvarId) {
1181
rc = pthread_mutex_lock(&condvarId->mutex);
1183
condvarId->predicate++;
1185
rc = pthread_mutex_unlock(&condvarId->mutex);
1186
rc = pthread_cond_signal(&condvarId->condvar);
1191
/* ************************************ */
1193
#ifdef HAVE_SEMAPHORE_H
1195
int createSem(sem_t *semId, int initialValue) {
1198
rc = sem_init(semId, 0, initialValue);
1202
/* ************************************ */
1204
void waitSem(sem_t *semId) {
1208
/* ************************************ */
1210
int incrementSem(sem_t *semId) {
1211
return(sem_post(semId));
1214
/* ************************************ */
1216
int decrementSem(sem_t *semId) {
1217
return(sem_trywait(semId));
1220
/* ************************************ */
1222
int deleteSem(sem_t *semId) {
1223
return(sem_destroy(semId));
1227
#endif /* MULTITHREADED */
1230
/* ************************************ */
1232
int checkCommand(char* commandName) {
1236
FILE* fd = sec_popen(commandName, "r");
1252
/* ************************************ */
1256
#define USE_LSOF_DUMP
1259
void readLsofInfo(void) {
1265
int i, j, found, portNumber, idx, processesIdx;
1266
int numLines, processSize, numRetries;
1267
unsigned int fdFileno;
1268
ProcessInfoList *listElement;
1269
ProcessInfo **tmpProcesses;
1271
struct timeval wait_time;
1272
char fileName[NAME_MAX] = "/tmp/lsof-XXXXXX";
1274
time_t startTime = time(NULL);
1276
fd1 = getNewRandomFile(fileName, NAME_MAX);
1279
/* The warning message is returned by getNewRandomFile() */
1283
fd = sec_popen("lsof -i -n -w", "r");
1291
numRetries = numLines = 0;
1292
fdFileno = fileno(fd);
1293
wait_time.tv_sec = 30, wait_time.tv_usec = 0;
1297
FD_SET(fdFileno, &mask);
1299
if((i = select(fdFileno+1, &mask, 0, 0, &wait_time)) == 1) {
1300
if(fgets(line, 383, fd) != NULL) {
1302
fprintf(fd1, "%s", line);
1307
if((errno == 4 /* Interrupted system call */)
1308
&& (numRetries < 3) /* Avoid to loop */) {
1311
traceEvent(TRACE_WARNING,
1312
"WARNING: lsof() timeout (select=%d)(errno=%d: %s)",
1313
i, errno, strerror(errno));
1328
return; /* No processes */
1330
fd = fopen(fileName, "r");
1332
traceEvent(TRACE_WARNING, "WARNING: unable to read lsof dump file");
1337
/* ****************************************** */
1339
#ifdef MULTITHREADED
1340
accessMutex(&lsofMutex, "readLsofInfo");
1343
for(i=0; i<numProcesses; i++)
1344
processes[i]->marker = 0;
1346
for(idx=0; idx<TOP_IP_PORT; idx++) {
1347
while(localPorts[idx] != NULL) {
1348
listElement = localPorts[idx]->next;
1349
free(localPorts[idx]);
1350
localPorts[idx] = listElement;
1354
memset(localPorts, 0, sizeof(localPorts)); /* Just to be sure... */
1356
fgets(line, 383, fd); /* Ignore 1st line */
1358
while(fgets(line, 383, fd) != NULL) {
1360
char command[32], user[32], *portNr;
1361
char *trailer, *thePort, *strtokState;
1363
/*traceEvent(TRACE_INFO, "%s\n", line); */
1365
/* Fix below courtesy of Andreas Pfaller <a.pfaller@pop.gun.de> */
1366
if(3 != sscanf(line, "%31[^ \t] %d %31[^ \t]", command, &pid, user))
1369
if(strcmp(command, "lsof") == 0)
1372
/* Either UDP or TCP */
1373
for(i=10; (line[i] != '\0'); i++)
1374
if((line[i] == 'P') && (line[i+1] == ' '))
1380
trailer = &line[i+2];
1382
portNr = (char*)strtok_r(trailer, ":", &strtokState);
1384
if(portNr[0] == '*')
1385
portNr = &portNr[2];
1387
portNr = (char*)strtok_r(NULL, "-", &strtokState);
1389
if((portNr == NULL) || (portNr[0] == '*'))
1392
for(i=0, found = 0; i<numProcesses; i++) {
1393
if(processes[i]->pid == pid) {
1395
processes[i]->marker = 1;
1400
thePort = strtok_r(portNr, " ", &strtokState);
1402
for(j=0; portNr[j] != '\0'; j++)
1403
if(!isalnum(portNr[j]) && portNr[j]!='-') {
1408
if(isdigit(portNr[0])) {
1409
portNumber = atoi(thePort);
1411
portNumber = getAllPortByName(thePort);
1415
traceEvent(TRACE_INFO, "%s - %s - %s (%s/%d)\n",
1416
command, user, thePort, portNr, portNumber);
1419
if(portNumber == -1)
1425
if(numProcesses < MAX_NUM_PROCESSES) {
1426
ProcessInfo **swapProcesses;
1428
swapProcesses = (ProcessInfo**)malloc((numProcesses+1)*sizeof(ProcessInfo*));
1429
if(numProcesses > 0)
1430
memcpy(swapProcesses, processes, numProcesses*sizeof(ProcessInfo*));
1431
if(processes != NULL) free(processes);
1432
processes = swapProcesses;
1435
traceEvent(TRACE_INFO, "%3d) %s %s %s/%d\n",
1436
numProcesses, command, user, portNr, portNumber);
1438
processes[numProcesses] = (ProcessInfo*)malloc(sizeof(ProcessInfo));
1439
processes[numProcesses]->command = strdup(command);
1440
processes[numProcesses]->user = strdup(user);
1441
processes[numProcesses]->pid = pid;
1442
processes[numProcesses]->firstSeen = actTime;
1443
processes[numProcesses]->lastSeen = actTime;
1444
processes[numProcesses]->marker = 1;
1445
processes[numProcesses]->bytesSent = 0;
1446
processes[numProcesses]->bytesReceived = 0;
1447
processes[numProcesses]->contactedIpPeersIdx = 0;
1449
for(floater=0; floater<MAX_NUM_CONTACTED_PEERS; floater++)
1450
processes[numProcesses]->contactedIpPeersIndexes[floater] = NO_PEER;
1458
listElement = (ProcessInfoList*)malloc(sizeof(ProcessInfoList));
1459
listElement->element = processes[idx];
1460
listElement->next = localPorts[portNumber];
1461
localPorts[portNumber] = listElement;
1467
processSize = sizeof(ProcessInfo*)*numProcesses;
1468
tmpProcesses = (ProcessInfo**)malloc(processSize);
1470
memcpy(tmpProcesses, processes, processSize);
1471
memset(processes, 0, processSize);
1473
for(i=0, processesIdx=0; i<numProcesses; i++) {
1474
if(tmpProcesses[i]->marker == 0) {
1475
/* Free the process */
1476
free(tmpProcesses[i]->command);
1477
free(tmpProcesses[i]->user);
1478
free(tmpProcesses[i]);
1480
processes[processesIdx++] = tmpProcesses[i];
1484
numProcesses = processesIdx;
1488
#ifdef MULTITHREADED
1489
releaseMutex(&lsofMutex);
1493
traceEvent(TRACE_INFO, "readLsofInfo completed (%d sec).", (int)(time(NULL)-startTime));
1499
* An os independent signal() with BSD semantics, e.g. the signal
1500
* catcher is restored following service of the signal.
1502
* When sigset() is available, signal() has SYSV semantics and sigset()
1503
* has BSD semantics and call interface. Unfortunately, Linux does not
1504
* have sigset() so we use the more complicated sigaction() interface
1507
* Did I mention that signals suck?
1509
RETSIGTYPE (*setsignal (int sig, RETSIGTYPE (*func)(int)))(int)
1511
#ifdef HAVE_SIGACTION
1512
struct sigaction old, new;
1514
memset(&new, 0, sizeof(new));
1515
new.sa_handler = func;
1517
new.sa_flags |= SA_RESTART;
1519
if(sigaction(sig, &new, &old) < 0)
1521
return(old.sa_handler);
1524
return(signal(sig, func));
1529
/* ************************************ */
1531
char* decodeNBstring(char* theString, char *theBuffer) {
1532
int i=0, j = 0, len=strlen(theString);
1534
while((i<len) && (theString[i] != '\0')) {
1535
char encodedChar, decodedChar;
1537
encodedChar = theString[i++];
1538
if((encodedChar < 'A') || (encodedChar > 'Z')) break; /* Wrong character */
1541
decodedChar = encodedChar << 4;
1543
encodedChar = theString[i++];
1544
if((encodedChar < 'A') || (encodedChar > 'Z')) break; /* Wrong character */
1547
decodedChar |= encodedChar;
1549
theBuffer[j++] = decodedChar;
1552
theBuffer[j] = '\0';
1555
theBuffer[i] = (char)tolower(theBuffer[i]);
1560
/* ************************************ */
1562
char* getHostOS(char* ipAddr, int port _UNUSED_, char* additionalInfo) {
1567
char line[384], *operatingSystem=NULL;
1568
static char staticOsName[96];
1569
int len, found=0, sockFd;
1571
struct timeval wait_time;
1573
if((!isNmapPresent) || (ipAddr[0] == '\0')) {
1578
traceEvent(TRACE_INFO, "getHostOS(%s:%d)\n", ipAddr, port);
1579
traceEvent(TRACE_INFO, "Guessing OS of %s...\n", ipAddr);
1582
/* 548 is the AFP (Apple Filing Protocol) */
1583
if(snprintf(line, sizeof(line), "nmap -p 23,21,80,138,139,548 -O %s", ipAddr) < 0)
1584
traceEvent(TRACE_ERROR, "Buffer overflow!");
1586
fd = sec_popen(line, "r");
1588
#define OS_GUESS "Remote operating system guess: "
1589
#define OS_GUESS_1 "Remote OS guesses: "
1590
#define OS_GUESS_2 "OS: "
1596
sockFd = fileno(fd);
1598
if(additionalInfo != NULL) additionalInfo[0]='\0';
1602
FD_SET(sockFd, &mask);
1603
wait_time.tv_sec = PIPE_READ_TIMEOUT, wait_time.tv_usec = 0;
1605
if(select(sockFd+1, &mask, 0, 0, &wait_time) == 0) {
1606
break; /* Timeout */
1609
if((operatingSystem = fgets(line, sizeof(line)-1, fd)) == NULL)
1612
len = strlen(operatingSystem);
1613
if ((operatingSystem[len-1] == '\n') || (operatingSystem[len-1] == '\r'))
1614
operatingSystem[len-1] = '\0'; /* strip NL or CR from end-of-line */
1617
traceEvent(TRACE_INFO, "'%s'\n", line);
1620
if(strncmp(operatingSystem, OS_GUESS, strlen(OS_GUESS)) == 0) {
1621
operatingSystem = &operatingSystem[strlen(OS_GUESS)];
1626
/* Patches below courtesy of
1627
Valeri V. Parchine <valeri@com-con.com> */
1630
(strncmp(operatingSystem, OS_GUESS_1, strlen(OS_GUESS_1)) == 0)) {
1631
operatingSystem = &operatingSystem[strlen(OS_GUESS_1)];
1637
(strncmp(operatingSystem, OS_GUESS_2, strlen(OS_GUESS_2)) == 0)) {
1638
operatingSystem = &operatingSystem[strlen(OS_GUESS_2)];
1643
if(additionalInfo != NULL) {
1644
if(isdigit(operatingSystem[0])) {
1645
strcat(additionalInfo, operatingSystem);
1646
strcat(additionalInfo, "<BR>\n");
1649
/*traceEvent(TRACE_INFO, "> %s\n", operatingSystem); */
1653
memset(staticOsName, 0, sizeof(staticOsName));
1657
traceEvent(TRACE_INFO, "OS is: '%s'\n", operatingSystem);
1659
len = strlen(operatingSystem);
1660
strncpy(staticOsName, operatingSystem, len-1);
1663
memset(staticOsName, 0, sizeof(staticOsName));
1665
len = strlen(operatingSystem);
1666
strncpy(staticOsName, operatingSystem, len);
1667
staticOsName[sizeof(staticOsName)-1] = '\0';
1669
traceEvent(TRACE_INFO, "OS is: '%s'\n", operatingSystem);
1673
/* Read remaining data (if any) */
1676
FD_SET(sockFd, &mask);
1677
wait_time.tv_sec = PIPE_READ_TIMEOUT; wait_time.tv_usec = 0;
1679
if(select(sockFd+1, &mask, 0, 0, &wait_time) == 0) {
1680
break; /* Timeout */
1683
if(fgets(line, sizeof(line)-1, fd) == NULL)
1686
else printf("Garbage: '%s'\n", line);
1691
return(staticOsName);
1695
/* ************************************* */
1697
void closeNwSocket(int *sockId) {
1699
traceEvent(TRACE_INFO, "Closing socket %d...\n", *sockId);
1702
if(*sockId == DUMMY_SOCKET_VALUE)
1707
term_ssl_connection(-(*sockId));
1709
closesocket(*sockId);
1711
closesocket(*sockId);
1714
*sockId = DUMMY_SOCKET_VALUE;
1717
/* ************************************ */
1719
char* savestr(const char *str)
1723
static char *strptr = NULL;
1724
static u_int strsize = 0;
1726
size = strlen(str) + 1;
1727
if(size > strsize) {
1731
strptr = (char*)malloc(strsize);
1732
if(strptr == NULL) {
1733
fprintf(stderr, "savestr: malloc\n");
1737
(void)strncpy(strptr, str, strsize);
1745
/* ************************************ */
1747
/* The function below has been inherited by tcpdump */
1750
int name_interpret(char *in, char *out, int numBytes) {
1755
traceEvent(TRACE_WARNING, "WARNING: name_interpret error (numBytes=%d)", numBytes);
1763
if(len > 30 || len < 1) {
1764
traceEvent(TRACE_WARNING, "WARNING: name_interpret error (numBytes=%d)", numBytes);
1769
if(in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
1774
*out = ((in[0]-'A')<<4) + (in[1]-'A');
1781
/* Courtesy of Roberto F. De Luca <deluca@tandar.cnea.gov.ar> */
1782
/* Trim trailing whitespace from the returned string */
1783
for(out--; out>=b && *out==' '; out--) *out = '\0';
1789
/* ******************************* */
1791
char* getNwInterfaceType(int i) {
1792
switch(device[i].datalink) {
1793
case DLT_NULL: return("No link-layer encapsulation");
1794
case DLT_EN10MB: return("Ethernet");
1795
case DLT_EN3MB: return("Experimental Ethernet (3Mb)");
1796
case DLT_AX25: return("Amateur Radio AX.25");
1797
case DLT_PRONET: return("Proteon ProNET Token Ring");
1798
case DLT_CHAOS: return("Chaos");
1799
case DLT_IEEE802: return("IEEE 802 Networks");
1800
case DLT_ARCNET: return("ARCNET");
1801
case DLT_SLIP: return("SLIP");
1802
case DLT_PPP: return("PPP");
1803
case DLT_FDDI: return("FDDI");
1804
case DLT_ATM_RFC1483: return("LLC/SNAP encapsulated ATM");
1805
case DLT_RAW: return("Raw IP");
1806
case DLT_SLIP_BSDOS: return("BSD/OS SLIP");
1807
case DLT_PPP_BSDOS: return("BSD/OS PPP");
1810
return(""); /* NOTREACHED (I hope) */
1813
/* ************************************ */
1815
char* formatTime(time_t *theTime, short encodeString) {
1817
static char outStr[2][TIME_LEN];
1818
static short timeBufIdx=0;
1820
struct tm myLocTime;
1822
locTime = localtime_r(theTime, &myLocTime);
1824
timeBufIdx = (timeBufIdx+1)%2;
1827
strftime(outStr[timeBufIdx], TIME_LEN, "%x %X", locTime);
1829
strftime(outStr[timeBufIdx], TIME_LEN, "%x %X", locTime);
1831
return(outStr[timeBufIdx]);
1835
/* ************************************ */
1837
int getActualInterface(void) {
1844
/* ************************************ */
1846
void storeHostTrafficInstance(HostTraffic *el) {
1852
if(broadcastHost(el))
1855
if(el->ethAddressString[0] == '\0')
1856
key = el->hostNumIpAddress;
1858
key = el->ethAddressString;
1860
#ifdef STORAGE_DEBUG
1861
traceEvent(TRACE_INFO, "storeHostTrafficInstance(%s)\n", key);
1865
Before to store the instance all the pointers need
1866
to be deleted (i.e. set to NULL)
1868
resetHostsVariables(el);
1870
key_data.dptr = key;
1871
key_data.dsize = strlen(key_data.dptr);
1872
data_data.dptr = (void*)el;
1873
data_data.dsize = sizeof(HostTraffic);
1875
#ifdef MULTITHREADED
1876
accessMutex(&gdbmMutex, "storeHostTrafficInstance");
1879
if(gdbm_store(hostsInfoFile, key_data, data_data, GDBM_REPLACE) == 0) {
1880
#ifdef STORAGE_DEBUG
1881
traceEvent(TRACE_INFO, "Stored instance: '%s'\n", key);
1883
fprintf(stdout, "+"); fflush(stdout);
1886
#ifdef MULTITHREADED
1887
releaseMutex(&gdbmMutex);
1895
/* ************************************ */
1897
void resetHostsVariables(HostTraffic* el) {
1899
FD_ZERO(&(el->flags));
1900
resetUsageCounter(&el->contactedSentPeers);
1901
resetUsageCounter(&el->contactedRcvdPeers);
1902
resetUsageCounter(&el->contactedRouters);
1904
el->fullDomainName = NULL;
1905
el->dotDomainName = NULL;
1906
el->hostSymIpAddress[0] = '\0';
1908
el->nbHostName = NULL;
1909
el->nbDomainName = NULL;
1910
el->nbDescr = NULL; /* Fix courtesy of Francis Pintos <francis@arhl.com.hk> */
1911
el->atNodeName = NULL;
1912
memset(el->atNodeType, 0, sizeof(el->atNodeType));
1913
el->routedTraffic = NULL;
1914
el->ipxHostName = NULL;
1915
el->numIpxNodeTypes = 0;
1916
el->portsUsage = NULL;
1917
el->protoIPTrafficInfos = NULL;
1918
el->tcpSessionList = NULL;
1919
el->udpSessionList = NULL;
1920
el->nextDBupdate = 0;
1921
el->icmpInfo = NULL;
1922
el->dnsStats = NULL;
1923
el->httpStats = NULL;
1924
#ifdef ENABLE_NAPSTER
1925
el->napsterStats = NULL;
1927
el->dhcpStats = NULL;
1929
resetUsageCounter(&el->contactedSentPeers);
1930
resetUsageCounter(&el->contactedRcvdPeers);
1931
resetUsageCounter(&el->contactedRouters);
1933
el->securityHostPkts = NULL;
1936
/* ************************************ */
1938
HostTraffic* resurrectHostTrafficInstance(char *key) {
1943
key_data.dptr = key;
1944
key_data.dsize = strlen(key_data.dptr);
1946
#ifdef MULTITHREADED
1947
accessMutex(&gdbmMutex, "resurrectHostTrafficInstance");
1949
data_data = gdbm_fetch(hostsInfoFile, key_data);
1951
if(data_data.dptr != NULL) {
1954
if(data_data.dsize != sizeof(HostTraffic)) {
1955
#ifdef STORAGE_DEBUG
1956
traceEvent(TRACE_INFO,
1957
"Wrong size for '%s'[size=%d, expected=%d]. Deleted.\n",
1958
key, data_data.dsize, sizeof(HostTraffic));
1960
gdbm_delete(hostsInfoFile, key_data);
1961
free(data_data.dptr);
1962
#ifdef MULTITHREADED
1963
releaseMutex(&gdbmMutex);
1968
#ifdef MULTITHREADED
1969
releaseMutex(&gdbmMutex);
1973
el = (HostTraffic*)malloc(sizeof(HostTraffic));
1974
memcpy(el, data_data.dptr, sizeof(HostTraffic));
1975
free(data_data.dptr);
1977
el = (HostTraffic*)data_data.dptr;
1980
if(broadcastHost(el)) {
1982
Broadcast entries should
1983
NOT be stored on disk
1988
resetHostsVariables(el);
1990
#ifdef STORAGE_DEBUG
1991
traceEvent(TRACE_INFO, "\nResurrected instance: '%s/%s'\n",
1992
el->ethAddressString, el->hostNumIpAddress);
1994
fprintf(stdout, "*"); fflush(stdout);
1997
#ifdef STORAGE_DEBUG
1998
traceEvent(TRACE_INFO, "Unable to find '%s'\n", key);
2000
#ifdef MULTITHREADED
2001
releaseMutex(&gdbmMutex);
2010
/* ************************************
2012
* [Borrowed from tcpdump]
2015
u_short in_cksum(const u_short *addr, int len, u_short csum) {
2017
const u_short *w = addr;
2022
* Our algorithm is simple, using a 32 bit accumulator (sum),
2023
* we add sequential 16 bit words to it, and at the end, fold
2024
* back all the carry bits from the top 16 bits into the lower
2032
sum += htons(*(u_char *)w<<8);
2035
* add back carry outs from top 16 bits to low 16 bits
2037
sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
2038
sum += (sum >> 16); /* add carry */
2039
answer = ~sum; /* truncate to 16 bits */
2043
/* ****************** */
2045
void addTimeMapping(u_int16_t transactionId,
2046
struct timeval theTime) {
2048
u_int idx = transactionId % NUM_TRANSACTION_ENTRIES;
2052
traceEvent(TRACE_INFO, "addTimeMapping(0x%X)\n", transactionId);
2054
for(i=0; i<NUM_TRANSACTION_ENTRIES; i++) {
2055
if(transTimeHash[idx].transactionId == 0) {
2056
transTimeHash[idx].transactionId = transactionId;
2057
transTimeHash[idx].theTime = theTime;
2059
} else if(transTimeHash[idx].transactionId == transactionId) {
2060
transTimeHash[idx].theTime = theTime;
2064
idx = (idx+1) % NUM_TRANSACTION_ENTRIES;
2068
/* ****************** */
2071
* The time difference in microseconds
2073
long delta_time (struct timeval * now,
2074
struct timeval * before) {
2075
time_t delta_seconds;
2076
time_t delta_microseconds;
2079
* compute delta in second, 1/10's and 1/1000's second units
2081
delta_seconds = now -> tv_sec - before -> tv_sec;
2082
delta_microseconds = now -> tv_usec - before -> tv_usec;
2084
if(delta_microseconds < 0) {
2085
/* manually carry a one from the seconds field */
2086
delta_microseconds += 1000000; /* 1e6 */
2090
return((delta_seconds * 1000000) + delta_microseconds);
2093
/* ****************** */
2095
time_t getTimeMapping(u_int16_t transactionId,
2096
struct timeval theTime) {
2098
u_int idx = transactionId % NUM_TRANSACTION_ENTRIES;
2102
traceEvent(TRACE_INFO, "getTimeMapping(0x%X)\n", transactionId);
2105
/* ****************************************
2107
As Andreas Pfaller <a.pfaller@pop.gun.de>
2108
pointed out, the hash code needs to be optimised.
2109
Actually the hash is scanned completely
2110
if (unlikely but possible) the searched entry
2111
is not present into the table.
2113
**************************************** */
2115
for(i=0; i<NUM_TRANSACTION_ENTRIES; i++) {
2116
if(transTimeHash[idx].transactionId == transactionId) {
2117
time_t msDiff = (time_t)delta_time(&theTime, &transTimeHash[idx].theTime);
2118
transTimeHash[idx].transactionId = 0; /* Free bucket */
2120
traceEvent(TRACE_INFO, "getTimeMapping(0x%X) [diff=%d]\n",
2121
transactionId, (unsigned long)msDiff);
2126
idx = (idx+1) % NUM_TRANSACTION_ENTRIES;
2130
traceEvent(TRACE_INFO, "getTimeMapping(0x%X) [not found]\n", transactionId);
2132
return(0); /* Not found */
2135
/* ********************************** */
2137
void traceEvent(int eventTraceLevel, char* file,
2138
int line, char * format, ...) {
2140
va_start (va_ap, format);
2142
if(eventTraceLevel <= traceLevel) {
2145
time_t theTime = time(NULL);
2148
if(traceLevel >= DEFAULT_TRACE_LEVEL) {
2151
openlog("ntop", LOG_PID, LOG_DAEMON);
2155
strftime(theDate, 32, "%d/%b/%Y %H:%M:%S", localtime_r(&theTime, &t));
2157
if(traceLevel == DETAIL_TRACE_LEVEL) {
2158
printf("%s [%s:%d] ", theDate, file, line);
2160
printf("%s ", theDate);
2164
memset(buf, 0, BUF_SIZE);
2166
/* Windows lacks of vsnprintf */
2167
vsprintf(buf, format, va_ap);
2169
vsnprintf(buf, BUF_SIZE-1, format, va_ap);
2174
if(format[strlen(format)-1] != '\n')
2180
switch(traceLevel) {
2182
syslog(LOG_ERR, buf);
2185
syslog(LOG_WARNING, buf);
2188
syslog(LOG_NOTICE, buf);
2191
syslog(LOG_INFO, buf);
2195
syslog(LOG_ERR, buf);
2211
/* ******************************************** */
2213
char* _strncpy(char *dest, const char *src, size_t n) {
2214
size_t len = strlen(src);
2219
memcpy(dest, src, len);
2224
/* ******************************************** */
2226
/* Courtesy of Andreas Pfaller <a.pfaller@pop.gun.de> */
2227
#ifndef HAVE_STRTOK_R
2228
/* Reentrant string tokenizer. Generic version.
2230
Slightly modified from: glibc 2.1.3
2232
Copyright (C) 1991, 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
2233
This file is part of the GNU C Library.
2235
The GNU C Library is free software; you can redistribute it and/or
2236
modify it under the terms of the GNU Library General Public License as
2237
published by the Free Software Foundation; either version 2 of the
2238
License, or (at your option) any later version.
2240
The GNU C Library is distributed in the hope that it will be useful,
2241
but WITHOUT ANY WARRANTY; without even the implied warranty of
2242
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2243
Library General Public License for more details.
2245
You should have received a copy of the GNU Library General Public
2246
License along with the GNU C Library; see the file COPYING.LIB. If not,
2247
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
2248
Boston, MA 02111-1307, USA. */
2250
char *strtok_r(char *s, const char *delim, char **save_ptr) {
2256
/* Scan leading delimiters. */
2257
s += strspn (s, delim);
2261
/* Find the end of the token. */
2263
s = strpbrk (token, delim);
2265
/* This token finishes the string. */
2268
/* Terminate the token and make *SAVE_PTR point past it. */
2277
/* ********************************** */
2279
/* Courtesy of Andreas Pfaller <a.pfaller@pop.gun.de> */
2281
int getSniffedDNSName(char *hostNumIpAddress,
2282
char *name, int maxNameLen) {
2288
if((hostNumIpAddress[0] != '\0') && gdbm_file) {
2292
key.dptr = hostNumIpAddress;
2293
key.dsize = strlen(key.dptr)+1;
2295
#ifdef MULTITHREADED
2296
accessMutex(&gdbmMutex, "getSniffedDNSName");
2298
data = gdbm_fetch(gdbm_file, key);
2299
#ifdef MULTITHREADED
2300
releaseMutex(&gdbmMutex);
2306
strncpy(name, data.dptr, maxNameLen-1);
2307
name[maxNameLen-1] = 0;
2309
if((maxNameLen > 5) &&
2310
(strcmp(&name[strlen(name)-5], ".arpa") == 0))
2311
return(0); /* Do not return XXXX.in-addr.arpa */
2313
for(i=0; i<maxNameLen; i++)
2314
name[i] = tolower(name[i]);
2324
/* *************************************** */
2326
int strOnlyDigits(const char *s) {
2331
while ((*s) != '\0') {
2340
/* ****************************************************** */
2342
FILE* getNewRandomFile(char* fileName, int len) {
2349
/* Patch courtesy of Thomas Biege <thomas@suse.de> */
2350
if(((tmpfd = mkstemp(fileName)) < 0)
2351
|| (fchmod(tmpfd, 0600) < 0)
2352
|| ((fd = fdopen(tmpfd, "wb")) == NULL))
2355
char tmpFileName[NAME_MAX];
2357
strcpy(tmpFileName, fileName);
2358
sprintf(fileName, "%s-%lu", tmpFileName, numHandledHTTPrequests);
2359
fd = fopen(fileName, "wb");
2363
fd = fopen(fileName, "wb");
2367
traceEvent(TRACE_WARNING, "Unable to create temp. file (%s). ", fileName);
2372
/* ****************************************************** */
2375
Function added in order to catch invalid
2376
strings passed on the command line.
2378
Thanks to Bailleux Christophe <cb@grolier.fr> for
2379
pointing out the finger at the problem.
2382
void stringSanityCheck(char* string) {
2385
if(string == NULL) {
2386
traceEvent(TRACE_ERROR, "FATAL ERROR: Invalid string specified.");
2390
for(i=0, j=1; i<strlen(string); i++) {
2400
traceEvent(TRACE_ERROR, "FATAL ERROR: Invalid string '%s' specified.",
2406
/* ****************************************************** */
2409
Function added in order to catch invalid (too long)
2410
device names specified on the command line.
2412
Thanks to Bailleux Christophe <cb@grolier.fr> for
2413
pointing out the finger at the problem.
2416
void deviceSanityCheck(char* string) {
2419
if(strlen(string) > MAX_DEVICE_NAME_LEN)
2422
for(i=0, j=1; i<strlen(string); i++) {
2433
traceEvent(TRACE_ERROR, "FATAL ERROR: Invalid device specified.");
2438
/* ****************************************************** */
2440
#ifndef HAVE_SNPRINTF
2441
int snprintf(char *string, size_t maxlen, const char *format, ...) {
2445
va_start(args, format);
2446
vsprintf(string,format,args);
2452
/* ************************ */
2454
void fillDomainName(HostTraffic *el) {
2457
if(theDomainHasBeenComputed(el)
2458
|| (el->hostSymIpAddress == NULL))
2461
#ifdef MULTITHREADED
2462
accessMutex(&addressResolutionMutex, "fillDomainName");
2465
if((el->hostSymIpAddress[0] == '*')
2466
|| (el->hostNumIpAddress[0] == '\0')
2467
|| (isdigit(el->hostSymIpAddress[strlen(el->hostSymIpAddress)-1]) &&
2468
isdigit(el->hostSymIpAddress[0]))) {
2469
/* NOTE: theDomainHasBeenComputed(el) = 0 */
2470
el->fullDomainName = el->dotDomainName = "";
2471
#ifdef MULTITHREADED
2472
releaseMutex(&addressResolutionMutex);
2477
FD_SET(THE_DOMAIN_HAS_BEEN_COMPUTED_FLAG, &el->flags);
2478
el->fullDomainName = el->dotDomainName = ""; /* Reset values... */
2480
i = strlen(el->hostSymIpAddress)-1;
2483
if(el->hostSymIpAddress[i] == '.')
2489
&& strcmp(el->hostSymIpAddress, el->hostNumIpAddress)
2490
&& (strlen(el->hostSymIpAddress) > (i+1)))
2491
el->dotDomainName = &el->hostSymIpAddress[i+1];
2493
/* Let's use the local domain name */
2495
traceEvent(TRACE_INFO, "'%s' [%s/%s]\n",
2496
el->hostSymIpAddress, domainName, shortDomainName);
2498
if((domainName[0] != '\0')
2499
&& (strcmp(el->hostSymIpAddress, el->hostNumIpAddress))) {
2500
int len = strlen(el->hostSymIpAddress);
2501
int len1 = strlen(domainName);
2503
/* traceEvent(TRACE_INFO, "%s [%s]\n",
2504
el->hostSymIpAddress, &el->hostSymIpAddress[len-len1]); */
2507
&& (strcmp(&el->hostSymIpAddress[len-len1-1], domainName) == 0))
2508
el->hostSymIpAddress[len-len1-1] = '\0';
2510
el->fullDomainName = domainName;
2511
el->dotDomainName = shortDomainName;
2513
el->fullDomainName = el->dotDomainName = "";
2516
#ifdef MULTITHREADED
2517
releaseMutex(&addressResolutionMutex);
2522
for(i=0; el->hostSymIpAddress[i] != '\0'; i++)
2523
el->hostSymIpAddress[i] = tolower(el->hostSymIpAddress[i]);
2526
while(el->hostSymIpAddress[i] != '\0')
2527
if(el->hostSymIpAddress[i] == '.')
2532
if((el->hostSymIpAddress[i] == '.')
2533
&& (strlen(el->hostSymIpAddress) > (i+1)))
2534
el->fullDomainName = &el->hostSymIpAddress[i+1];
2536
/* traceEvent(TRACE_INFO, "'%s'\n", el->domainName); */
2538
#ifdef MULTITHREADED
2539
releaseMutex(&addressResolutionMutex);
2543
/* ********************************* */
2545
/* similar to Java.String.trim() */
2546
void trimString(char* str) {
2547
int len = strlen(str), i, idx;
2548
char *out = (char *) malloc(sizeof(char) * (len+1));
2555
for(i=0, idx=0; i<len; i++)
2562
&& (out[idx-1] != ' ')
2563
&& (out[idx-1] != '\t'))
2564
out[idx++] = str[i];
2567
out[idx++] = str[i];
2573
strncpy(str, out, len);
2577
/* ****************************** */
2579
void setNBnodeNameType(HostTraffic *theHost,
2580
char nodeType, char* nbName) {
2583
if((nbName == NULL) || (strlen(nbName) == 0))
2586
if(strlen(nbName) >= (MAX_HOST_SYM_NAME_LEN-1)) /* (**) */
2587
nbName[MAX_HOST_SYM_NAME_LEN-2] = '\0';
2589
theHost->nbNodeType = (char)nodeType;
2590
/* Courtesy of Roberto F. De Luca <deluca@tandar.cnea.gov.ar> */
2592
theHost->nbNodeType = (char)nodeType;
2595
case 0x0: /* Workstation */
2596
case 0x20: /* Server */
2597
if(theHost->nbHostName == NULL) {
2598
theHost->nbHostName = strdup(nbName);
2599
updateHostName(theHost);
2601
if(theHost->hostSymIpAddress[0] == '\0')
2602
strcpy(theHost->hostSymIpAddress, nbName); /* See up (**) */
2605
printf("nbHostName=%s [0x%X]\n", nbName, nodeType);
2609
case 0x1C: /* Domain Controller */
2610
case 0x1E: /* Domain */
2611
case 0x1D: /* Workgroup (I think) */
2612
if(theHost->nbDomainName == NULL) {
2613
if(strcmp(nbName, "__MSBROWSE__") && strncmp(&nbName[2], "__", 2)) {
2614
theHost->nbDomainName = strdup(nbName);
2621
case 0x0: /* Workstation */
2622
FD_SET(HOST_TYPE_WORKSTATION, &theHost->flags);
2623
case 0x20: /* Server */
2624
FD_SET(HOST_TYPE_SERVER, &theHost->flags);
2625
case 0x1B: /* Master Browser */
2626
FD_SET(HOST_TYPE_MASTER_BROWSER, &theHost->flags);
2630
/* ******************************************* */
2634
void addPassiveSessionInfo(u_long theHost, u_short thePort) {
2636
time_t timeoutTime = actTime - PASSIVE_SESSION_PURGE_TIMEOUT;
2639
traceEvent(TRACE_INFO, "Adding %ld:%d", theHost, thePort);
2642
for(i=0; i<passiveSessionsLen; i++) {
2643
if((passiveSessions[i].sessionPort == 0)
2644
|| (passiveSessions[i].creationTime < timeoutTime)) {
2645
passiveSessions[i].sessionHost.s_addr = theHost,
2646
passiveSessions[i].sessionPort = thePort,
2647
passiveSessions[i].creationTime = actTime;
2652
if(i == passiveSessionsLen) {
2653
/* Slot Not found */
2654
traceEvent(TRACE_INFO, "Info: passiveSessions[size=%d] is full", passiveSessionsLen);
2656
/* Shift table entries */
2657
for(i=1; i<passiveSessionsLen; i++) {
2658
passiveSessions[i-1].sessionHost = passiveSessions[i].sessionHost,
2659
passiveSessions[i-1].sessionPort = passiveSessions[i].sessionPort;
2661
passiveSessions[passiveSessionsLen-1].sessionHost.s_addr = theHost,
2662
passiveSessions[passiveSessionsLen-1].sessionPort = thePort;
2666
/* ******************************************* */
2668
int isPassiveSession(u_long theHost, u_short thePort) {
2672
traceEvent(TRACE_INFO, "Searching for %ld:%d",
2676
for(i=0; i<passiveSessionsLen; i++) {
2677
if((passiveSessions[i].sessionHost.s_addr == theHost)
2678
&& (passiveSessions[i].sessionPort == thePort)) {
2679
passiveSessions[i].sessionHost.s_addr = 0,
2680
passiveSessions[i].sessionPort = 0,
2681
passiveSessions[i].creationTime = 0;
2683
traceEvent(TRACE_INFO, "Found passive FTP session");
2692
/* ******************************************* */
2694
void initPassiveSessions() {
2697
len = sizeof(SessionInfo)*NUM_SESSION_INFO;
2698
passiveSessions = (SessionInfo*)malloc(len);
2699
memset(passiveSessions, 0, len);
2700
passiveSessionsLen = NUM_SESSION_INFO;
2703
/* ******************************* */
2705
void termPassiveSessions() {
2706
free(passiveSessions);
2709
/* ******************************* */
2711
int getPortByName(ServiceEntry **theSvc, char* portName) {
2714
for(idx=0; idx<numActServices; idx++) {
2717
if(theSvc[idx] != NULL)
2718
traceEvent(TRACE_INFO, "%d/%s [%s]\n",
2720
theSvc[idx]->name, portName);
2723
if((theSvc[idx] != NULL)
2724
&& (strcmp(theSvc[idx]->name, portName) == 0))
2725
return(theSvc[idx]->port);
2731
/* ******************************* */
2733
char* getPortByNumber(ServiceEntry **theSvc, int port) {
2734
int idx = port % numActServices;
2740
if((scan != NULL) && (scan->port == port))
2742
else if(scan == NULL)
2745
idx = (idx+1) % numActServices;
2749
/* ******************************* */
2751
char* getPortByNum(int port, int type) {
2754
if(type == IPPROTO_TCP) {
2755
rsp = getPortByNumber(tcpSvc, port);
2757
rsp = getPortByNumber(udpSvc, port);
2763
/* ******************************* */
2765
char* getAllPortByNum(int port) {
2767
static char staticBuffer[2][16];
2768
static short portBufIdx=0;
2770
rsp = getPortByNumber(tcpSvc, port); /* Try TCP first... */
2772
rsp = getPortByNumber(udpSvc, port); /* ...then UDP */
2777
portBufIdx = (short)((portBufIdx+1)%2);
2778
if(snprintf(staticBuffer[portBufIdx], 16, "%d", port) < 0)
2779
traceEvent(TRACE_ERROR, "Buffer overflow!");
2780
return(staticBuffer[portBufIdx]);
2784
/* ******************************* */
2786
int getAllPortByName(char* portName) {
2789
rsp = getPortByName(tcpSvc, portName); /* Try TCP first... */
2791
rsp = getPortByName(udpSvc, portName); /* ...then UDP */
2797
/* ******************************* */
2799
void addPortHashEntry(ServiceEntry **theSvc, int port, char* name) {
2800
int idx = port % numActServices;
2807
theSvc[idx] = (ServiceEntry*)malloc(sizeof(ServiceEntry));
2808
theSvc[idx]->port = (u_short)port;
2809
theSvc[idx]->name = strdup(name);
2812
idx = (idx+1) % numActServices;
2816
/* ******************************* */
2818
void resetUsageCounter(UsageCounter *counter) {
2821
memset(counter, 0, sizeof(UsageCounter));
2823
for(i=0; i<MAX_NUM_CONTACTED_PEERS; i++)
2824
counter->peersIndexes[i] = NO_PEER;
2827
/* ************************************ */
2830
This function has to be used to reset (i.e. initialize to
2831
empty values in the correct range) HostTraffic
2835
void resetSecurityHostTraffic(HostTraffic *el) {
2837
if(el->securityHostPkts == NULL) return;
2839
resetUsageCounter(&el->securityHostPkts->synPktsSent);
2840
resetUsageCounter(&el->securityHostPkts->rstPktsSent);
2841
resetUsageCounter(&el->securityHostPkts->rstAckPktsSent);
2842
resetUsageCounter(&el->securityHostPkts->synFinPktsSent);
2843
resetUsageCounter(&el->securityHostPkts->finPushUrgPktsSent);
2844
resetUsageCounter(&el->securityHostPkts->nullPktsSent);
2845
resetUsageCounter(&el->securityHostPkts->ackScanSent);
2846
resetUsageCounter(&el->securityHostPkts->xmasScanSent);
2847
resetUsageCounter(&el->securityHostPkts->finScanSent);
2848
resetUsageCounter(&el->securityHostPkts->nullScanSent);
2849
resetUsageCounter(&el->securityHostPkts->rejectedTCPConnSent);
2850
resetUsageCounter(&el->securityHostPkts->establishedTCPConnSent);
2851
resetUsageCounter(&el->securityHostPkts->udpToClosedPortSent);
2852
resetUsageCounter(&el->securityHostPkts->udpToDiagnosticPortSent);
2853
resetUsageCounter(&el->securityHostPkts->tcpToDiagnosticPortSent);
2854
resetUsageCounter(&el->securityHostPkts->tinyFragmentSent);
2855
resetUsageCounter(&el->securityHostPkts->icmpFragmentSent);
2856
resetUsageCounter(&el->securityHostPkts->overlappingFragmentSent);
2857
resetUsageCounter(&el->securityHostPkts->closedEmptyTCPConnSent);
2858
resetUsageCounter(&el->securityHostPkts->icmpPortUnreachSent);
2859
resetUsageCounter(&el->securityHostPkts->icmpHostNetUnreachSent);
2860
resetUsageCounter(&el->securityHostPkts->icmpProtocolUnreachSent);
2861
resetUsageCounter(&el->securityHostPkts->icmpAdminProhibitedSent);
2862
resetUsageCounter(&el->securityHostPkts->malformedPktsSent);
2866
resetUsageCounter(&el->contactedRcvdPeers);
2868
resetUsageCounter(&el->securityHostPkts->synPktsRcvd);
2869
resetUsageCounter(&el->securityHostPkts->rstPktsRcvd);
2870
resetUsageCounter(&el->securityHostPkts->rstAckPktsRcvd);
2871
resetUsageCounter(&el->securityHostPkts->synFinPktsRcvd);
2872
resetUsageCounter(&el->securityHostPkts->finPushUrgPktsRcvd);
2873
resetUsageCounter(&el->securityHostPkts->nullPktsRcvd);
2874
resetUsageCounter(&el->securityHostPkts->ackScanRcvd);
2875
resetUsageCounter(&el->securityHostPkts->xmasScanRcvd);
2876
resetUsageCounter(&el->securityHostPkts->finScanRcvd);
2877
resetUsageCounter(&el->securityHostPkts->nullScanRcvd);
2878
resetUsageCounter(&el->securityHostPkts->rejectedTCPConnRcvd);
2879
resetUsageCounter(&el->securityHostPkts->establishedTCPConnRcvd);
2880
resetUsageCounter(&el->securityHostPkts->udpToClosedPortRcvd);
2881
resetUsageCounter(&el->securityHostPkts->udpToDiagnosticPortRcvd);
2882
resetUsageCounter(&el->securityHostPkts->tcpToDiagnosticPortRcvd);
2883
resetUsageCounter(&el->securityHostPkts->tinyFragmentRcvd);
2884
resetUsageCounter(&el->securityHostPkts->icmpFragmentRcvd);
2885
resetUsageCounter(&el->securityHostPkts->overlappingFragmentRcvd);
2886
resetUsageCounter(&el->securityHostPkts->closedEmptyTCPConnRcvd);
2887
resetUsageCounter(&el->securityHostPkts->icmpPortUnreachRcvd);
2888
resetUsageCounter(&el->securityHostPkts->icmpHostNetUnreachRcvd);
2889
resetUsageCounter(&el->securityHostPkts->icmpProtocolUnreachRcvd);
2890
resetUsageCounter(&el->securityHostPkts->icmpAdminProhibitedRcvd);
2891
resetUsageCounter(&el->securityHostPkts->malformedPktsRcvd);
2893
resetUsageCounter(&el->contactedSentPeers);
2894
resetUsageCounter(&el->contactedRcvdPeers);
2895
resetUsageCounter(&el->contactedRouters);
2898
/* ********************************************* */
2900
char* mapIcmpType(int icmpType) {
2901
static char icmpString[4];
2903
icmpType %= ICMP_MAXTYPE; /* Just to be safe... */
2906
case 0: return("ECHOREPLY");
2907
case 3: return("UNREACH");
2908
case 4: return("SOURCEQUENCH");
2909
case 5: return("REDIRECT");
2910
case 8: return("ECHO");
2911
case 9: return("ROUTERADVERT");
2912
case 10: return("ROUTERSOLICI");
2913
case 11: return("TIMXCEED");
2914
case 12: return("PARAMPROB");
2915
case 13: return("TIMESTAMP");
2916
case 14: return("TIMESTAMPREPLY");
2917
case 15: return("INFOREQ");
2918
case 16: return("INFOREQREPLY");
2919
case 17: return("MASKREQ");
2920
case 18: return("MASKREPLY");
2922
sprintf(icmpString, "%d", icmpType);
2927
/* ******************************** */
2929
#ifndef HAVE_LOCALTIME_R
2932
#ifdef MULTITHREADED
2933
static PthreadMutex localtimeMutex;
2934
static char localtimeMutexInitialized = 0;
2937
struct tm *localtime_r(const time_t *t, struct tm *tp) {
2940
#if defined(MULTITHREADED)
2941
if(!localtimeMutexInitialized) {
2942
createMutex(&localtimeMutex);
2943
localtimeMutexInitialized = 1;
2945
accessMutex(&localtimeMutex, "localtime_r");
2948
theTime = localtime(t);
2951
memcpy(tp, theTime, sizeof(struct tm));
2953
memset(tp, 0, sizeof(struct tm)); /* What shall I do ? */
2955
#if defined(MULTITHREADED)
2956
releaseMutex(&localtimeMutex);