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.
27
#include "ntddndis.h" // This defines the IOCTL constants.
31
extern char* intoa(struct in_addr addr);
33
extern char domainName[];
39
extern unsigned int localnet, netmask;
42
char* getNwBoardMacAddress(char *deviceName); /* forward */
44
ULONG GetHostIPAddr(); /* forward declaration */
49
TCHAR AdapterName[64];
50
FRAMEETH ethernetFrame;
51
ULONG NameLength=64, FrameLength;
55
/* ************************************************** */
57
typedef PVOID NDIS_HANDLE, *PNDIS_HANDLE;
62
datalink = DLT_EN10MB;
64
/* ****************** */
66
PacketGetAdapterNames(AdapterName, &NameLength);
68
Adapter = PacketOpenAdapter(AdapterName);
70
traceEvent(TRACE_ERROR, "FATAL ERROR: please install MS NDIS 3.0 driver. Bye...");
73
PacketSetFilter(Adapter, NDIS_PACKET_TYPE_PROMISCUOUS);
74
Packet = PacketAllocatePacket();
75
PacketInitPacket(Packet, (PVOID)(ðernetFrame), sizeof(FRAMEETH));
79
/* ******************************************** */
81
void terminateSniffer() {
82
PacketCloseAdapter(Adapter);
85
/* ********************************** */
87
void sniffSinglePacket(void(*pbuf_process)(u_char *unused,
88
const struct pcap_pkthdr *h,
91
struct pcap_pkthdr hdr;
92
static int numPkts = 0;
94
PacketReceivePacket(Adapter, Packet, TRUE, &FrameLength);
95
hdr.caplen = (u_int32)FrameLength;
96
hdr.len = (u_int32)FrameLength;
99
if(numPkts < MAX_NUM_PACKETS)
101
pbuf_process(NULL, &hdr, (u_char*)ðernetFrame);
106
#endif /* ORIGINAL_NTOP */
108
/* ************************************************** */
112
DWORD dwWindowsMajorVersion;
114
dwVersion=GetVersion();
115
dwWindowsMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
116
if(!(dwVersion >= 0x80000000 && dwWindowsMajorVersion >= 4))
122
/* ************************************************** */
124
void initWinsock32() {
125
WORD wVersionRequested;
129
wVersionRequested = MAKEWORD(2, 0);
130
err = WSAStartup( wVersionRequested, &wsaData );
132
/* Tell the user that we could not find a usable */
134
traceEvent(TRACE_ERROR, "FATAL ERROR: unable to initialise Winsock 2.x.");
139
author = "Luca Deri <deri@ntop.org>";
140
buildDate = "27/12/2001";
143
osName = "WinNT/2K/XP";
145
osName = "Win95/98/ME";
148
traceEvent(TRACE_INFO, "\n-----------------------------------------------------------");
149
traceEvent(TRACE_INFO, "WARNING: this application is a limited ntop version able to");
150
traceEvent(TRACE_INFO, "capture up to %d packets. If you are interested", MAX_NUM_PACKETS);
151
traceEvent(TRACE_INFO, "in the full version please have a look at the ntop");
152
traceEvent(TRACE_INFO, "home page http://www.ntop.org/.");
153
traceEvent(TRACE_INFO, "-----------------------------------------------------------\n");
157
/* ************************************************** */
159
void termWinsock32() {
161
//terminateSniffer();
163
/* ************************************************** */
166
ULONG GetHostIPAddr () {
168
LPHOSTENT lpstHostent;
169
SOCKADDR_IN stLclAddr;
170
SOCKADDR_IN stRmtAddr;
171
int nAddrSize = sizeof(SOCKADDR);
175
/* Init local address (to zero) */
176
stLclAddr.sin_addr.s_addr = INADDR_ANY;
178
/* Get the local hostname */
179
nRet = gethostname(szLclHost, 64);
180
if(nRet != SOCKET_ERROR) {
181
/* Resolve hostname for local address */
182
lpstHostent = gethostbyname((LPSTR)szLclHost);
186
stLclAddr.sin_addr.s_addr = *((u_long FAR*) (lpstHostent->h_addr));
188
hp = (struct hostent*)gethostbyaddr((char*)&stLclAddr.sin_addr.s_addr, 4, AF_INET);
190
if(hp && (hp->h_name)) {
191
char *dotp = (char*)hp->h_name;
194
for(i=0; (dotp[i] != '\0') && (dotp[i] != '.'); i++)
197
if(dotp[i] == '.') strncpy(domainName, &dotp[i+1], sizeof(domainName));
202
/* If still not resolved, then try second strategy */
203
if(stLclAddr.sin_addr.s_addr == INADDR_ANY) {
204
/* Get a UDP socket */
205
hSock = socket(AF_INET, SOCK_DGRAM, 0);
206
if(hSock != INVALID_SOCKET) {
207
/* Connect to arbitrary port and address (NOT loopback) */
208
stRmtAddr.sin_family = AF_INET;
209
stRmtAddr.sin_port = htons(IPPORT_ECHO);
210
stRmtAddr.sin_addr.s_addr = inet_addr("128.127.50.1");
211
nRet = connect(hSock,
212
(LPSOCKADDR)&stRmtAddr,
214
if(nRet != SOCKET_ERROR)
215
/* Get local address */
217
(LPSOCKADDR)&stLclAddr,
218
(int FAR*)&nAddrSize);
220
closesocket(hSock); /* we're done with the socket */
224
/* Little/big endian crap... */
225
stLclAddr.sin_addr.s_addr = ntohl(stLclAddr.sin_addr.s_addr);
227
return (stLclAddr.sin_addr.s_addr);
230
/* **************************************
232
WIN32 MULTITHREAD STUFF
234
************************************** */
236
int createThread(pthread_t *threadId,
237
void *(*__start_routine) (void *), char* userParm) {
238
DWORD dwThreadId, dwThrdParam = 1;
240
(*threadId) = CreateThread(NULL, /* no security attributes */
241
0, /* use default stack size */
242
(LPTHREAD_START_ROUTINE)__start_routine, /* thread function */
243
userParm, /* argument to thread function */
244
0, /* use default creation flags */
245
&dwThreadId); /* returns the thread identifier */
247
if(*threadId != NULL)
253
/* ************************************ */
255
void killThread(pthread_t *threadId) {
256
CloseHandle((HANDLE)*threadId);
259
/* ************************************ */
261
int _createMutex(PthreadMutex *mutexId, char* fileName, int fileLine) {
263
memset(mutexId, 0, sizeof(PthreadMutex));
265
mutexId->mutex = CreateMutex(NULL, FALSE, NULL);
266
mutexId->isInitialized = 1;
270
traceEvent(TRACE_INFO,
271
"INFO: createMutex() call with %x mutex [%s:%d]", mutexId,
278
/* ************************************ */
280
void _deleteMutex(PthreadMutex *mutexId, char* fileName, int fileLine) {
284
traceEvent(TRACE_INFO,
285
"INFO: deleteMutex() call with %x(%c,%x) mutex [%s:%d]",
286
mutexId, (mutexId && mutexId->isInitialized) ? 'i' : '-',
287
mutexId ? mutexId->mutex : 0, fileName, fileLine);
290
if(!mutexId->isInitialized) {
291
traceEvent(TRACE_ERROR,
292
"ERROR: deleteMutex() call with a NULL mutex [%s:%d]",
297
ReleaseMutex(mutexId->mutex);
298
CloseHandle(mutexId->mutex);
300
memset(mutexId, 0, sizeof(PthreadMutex));
303
/* ************************************ */
305
int _accessMutex(PthreadMutex *mutexId, char* where,
306
char* fileName, int fileLine) {
308
traceEvent(TRACE_INFO, "Locking 0x%X @ %s [%s:%d]",
309
mutexId->mutex, where, fileName, fileLine);
312
WaitForSingleObject(mutexId->mutex, INFINITE);
315
mutexId->isLocked = 1;
316
mutexId->lockTime = time(NULL);
318
if(fileName != NULL) {
319
strcpy(mutexId->lockFile, fileName);
320
mutexId->lockLine = fileLine;
326
/* ************************************ */
328
int _tryLockMutex(PthreadMutex *mutexId, char* where,
329
char* fileName, int fileLine) {
331
traceEvent(TRACE_INFO, "Try to Lock 0x%X @ %s [%s:%d]",
332
mutexId->mutex, where, fileName, fileLine);
336
if(WaitForSingleObject(mutexId->mutex, 0) == WAIT_FAILED)
340
mutexId->isLocked = 1;
341
mutexId->lockTime = time(NULL);
343
if(fileName != NULL) {
344
strcpy(mutexId->lockFile, fileName);
345
mutexId->lockLine = fileLine;
352
/* ************************************ */
354
int _releaseMutex(PthreadMutex *mutexId,
355
char* fileName, int fileLine) {
361
traceEvent(TRACE_INFO, "Unlocking 0x%X [%s:%d]",
362
mutexId->mutex, fileName, fileLine);
364
rc = ReleaseMutex(mutexId->mutex);
366
if((rc == 0) && (fileName)) {
367
traceEvent(TRACE_ERROR, "ERROR while unlocking 0x%X [%s:%d] (LastError=%d)",
368
mutexId->mutex, fileName, fileLine, GetLastError());
371
lockDuration = time(NULL) - mutexId->lockTime;
373
if((mutexId->maxLockedDuration < lockDuration)
374
|| (mutexId->maxLockedDurationUnlockLine == 0 /* Never set */)) {
375
mutexId->maxLockedDuration = lockDuration;
377
if(fileName != NULL) {
378
strcpy(mutexId->maxLockedDurationUnlockFile, fileName);
379
mutexId->maxLockedDurationUnlockLine = fileLine;
383
traceEvent(TRACE_INFO, "INFO: semaphore 0x%X [%s:%d] locked for %d secs",
384
&(mutexId->mutex), fileName, fileLine,
385
mutexId->maxLockedDuration);
389
mutexId->isLocked = 0;
390
mutexId->numReleases++;
391
if(fileName != NULL) {
392
strcpy(mutexId->unlockFile, fileName);
393
mutexId->unlockLine = fileLine;
399
/* ************************************ */
401
int createCondvar(ConditionalVariable *condvarId) {
402
condvarId->condVar = CreateEvent(NULL, /* no security */
403
TRUE , /* auto-reset event (FALSE = single event, TRUE = broadcast) */
404
FALSE, /* non-signaled initially */
406
InitializeCriticalSection(&condvarId->criticalSection);
410
/* ************************************ */
412
void deleteCondvar(ConditionalVariable *condvarId) {
413
CloseHandle(condvarId->condVar);
414
DeleteCriticalSection(&condvarId->criticalSection);
417
/* ************************************ */
419
int waitCondvar(ConditionalVariable *condvarId) {
422
traceEvent(TRACE_INFO, "Wait (%x)...", condvarId->condVar);
424
EnterCriticalSection(&condvarId->criticalSection);
425
rc = WaitForSingleObject(condvarId->condVar, INFINITE);
426
LeaveCriticalSection(&condvarId->criticalSection);
429
traceEvent(TRACE_INFO, "Got signal (%d)...", rc);
435
/* ************************************ */
437
int signalCondvar(ConditionalVariable *condvarId) {
439
traceEvent(TRACE_INFO, "Signaling (%x)...", condvarId->condVar);
441
return((int)PulseEvent(condvarId->condVar));
444
/* ************************************ */
447
void printAvailableInterfaces() {
448
ULONG nameLength = 128;
449
WCHAR adaptersName[128];
451
PacketGetAdapterNames (adaptersName, &nameLength);
455
static char tmpString[128];
458
for(j=0, i=0; !((adaptersName[i] == 0) && (adaptersName[i+1] == 0)); i++) {
459
if(adaptersName[i] != 0)
460
tmpString[j++] = adaptersName[i];
464
memcpy(adaptersName, tmpString, 128);
467
traceEvent(TRACE_INFO, "Available interfaces:\n%s", (char*)adaptersName);
471
/* ************************************ */
473
#define _PATH_NETWORKS "networks"
475
#define MAXALIASES 35
477
static char NETDB[] = _PATH_NETWORKS;
478
static FILE *netf = NULL;
479
static char line[BUFSIZ+1];
480
static struct netent net;
481
static char *net_aliases[MAXALIASES];
482
static char *any(char *, char *);
491
netf = fopen(NETDB, "r" );
512
register char *mp, c;
515
for (mp = match; *mp; mp++)
524
inet_network(const char *cp)
526
register u_long val, base, n;
528
u_long parts[4], *pp = parts;
533
* Collect number up to ``.''.
534
* Values are specified as for C:
535
* 0x=hex, 0=octal, other=decimal.
539
* The 4.4BSD version of this file also accepts 'x__' as a hexa
540
* number. I don't think this is correct. -- Uli
543
if(*++cp == 'x' || *cp == 'X')
550
val = (val * base) + (c - '0');
554
if(base == 16 && isxdigit(c)) {
555
val = (val << 4) + (c + 10 - (islower(c) ? 'a' : 'A'));
563
return (INADDR_NONE);
567
if(*cp && !isspace(*cp))
568
return (INADDR_NONE);
572
return (INADDR_NONE);
573
for (val = 0, i = 0; i < (int)n; i++) {
575
val |= parts[i] & 0xff;
584
register char *cp, **q;
586
if(netf == NULL && (netf = fopen(NETDB, "r" )) == NULL)
589
p = fgets(line, BUFSIZ, netf);
603
while (*cp == ' ' || *cp == '\t')
608
net.n_net = inet_network(cp);
609
net.n_addrtype = AF_INET;
610
q = net.n_aliases = net_aliases;
614
if(*cp == ' ' || *cp == '\t') {
618
if(q < &net_aliases[MAXALIASES - 1])
628
struct netent *getnetbyname(const char *name)
630
register struct netent *p;
633
setnetent(_net_stayopen);
634
while (p = getnetent()) {
635
if(strcmp(p->n_name, name) == 0)
637
for (cp = p->n_aliases; *cp != 0; cp++)
638
if(strcmp(*cp, name) == 0)
648
/* Find the first bit set in I. */
651
static const unsigned char table[] =
653
0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
654
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
655
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
656
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
657
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
658
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
659
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
660
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8
663
unsigned long int x = i & -i;
665
a = x <= 0xffff ? (x <= 0xff ? 0 : 8) : (x <= 0xffffff ? 16 : 24);
667
return table[x >> a] + a;
670
/* ****************************************************** */
672
#if defined(WIN32) && defined(__GNUC__)
673
/* on mingw, struct timezone isn't defined so s/struct timezone/void/ - Scott Renfro <scott@renfro.org> */
674
int gettimeofday(struct timeval *tv, void *notUsed) {
676
int gettimeofday(struct timeval *tv, struct timezone *notUsed) {
678
tv->tv_sec = time(NULL);
683
/* ****************************************************** */
685
/* Courtesy of Wies-Software <wies@wiessoft.de> */
686
unsigned long waitForNextEvent(unsigned long ulDelay /* ms */) {
687
unsigned long ulSlice = 1000L; // 1 Second
689
while (capturePackets && (ulDelay > 0L)) {
690
if (ulDelay < ulSlice)