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.
44
#include "globals-report.h"
46
#if defined(WIN32) && defined(__GNUC__) /* mingw compiler */
47
/* we're using the winpcap getopt() implementation
48
* which has the globals inside the dll, so a simple
49
* extern declaration is insufficient on win32
51
* Scott Renfro <scott@renfro.org>
54
extern __attribute__((dllimport)) char *optarg;
59
#if defined(NEED_INET_ATON)
61
* Minimal implementation of inet_aton.
62
* Cannot distinguish between failure and a local broadcast address.
66
#define INADDR_NONE 0xffffffff
70
static int inet_aton(const char *cp, struct in_addr *addr)
72
addr->s_addr = inet_addr(cp);
73
return (addr->s_addr == INADDR_NONE) ? 0 : 1;
79
int main(int argc, char *argv[]) {
84
int userId=0, groupId=0;
86
int op, mergeInterfaces=1;
87
int enableDBsupport=0;
89
int enableIdleHosts=1;
90
char *cp, *localAddresses=NULL, *webAddr=NULL, *devices, *sslAddr=NULL;
91
char *flowSpecs, *protoSpecs, rulesFile[128], ifStr[196], *theOpts;
94
printf("Wait please: ntop is coming up...\n");
100
if (freopen("/dev/null", "w", stderr) == NULL) {
101
traceEvent(TRACE_WARNING,
102
"ntop: unable to replace stderr with /dev/null: %s\n",
111
webPort = NTOP_DEFAULT_WEB_PORT;
113
sslPort = 0; /* Disabled: it can enabled using -W <SSL port> */
116
enableSuspiciousPacketDump = 0;
117
usePersistentStorage = 0;
119
enableNetFlowSupport = 0;
121
/* Initialization of local variables */
122
isLsofPresent = isNmapPresent = filterExpressionInExtraFrame = 0;
130
tcpChain = NULL, udpChain = NULL, icmpChain = NULL;
132
daemonMode = pflag = numericFlag = debugMode = 0;
140
maxHashSize = MAX_HASH_SIZE;
141
traceLevel = DEFAULT_TRACE_LEVEL;
142
accuracyLevel = HIGH_ACCURACY_LEVEL;
143
domainName[0] = '\0';
145
If you need a good mapper look at this
146
http://jake.ntop.org/cgi-bin/mapper.pl
150
actTime = time(NULL);
151
strncpy(dbPath, DBFILE_DIR, sizeof(dbPath));
153
if ((cp = strrchr(argv[0], '/')) != NULL)
154
program_name = cp + 1;
156
program_name = argv[0];
158
if(strcmp(program_name, "ntopd") == 0) {
163
theOpts = "ce:f:F:hr:p:i:nw:m:b:B:D:s:P:R:S:g:t:a:W:12l:qU:kA:";
165
theOpts = "cIdEe:f:F:hr:i:p:nNw:m:b:v:D:s:P:R:MS:g:t:a:u:W:12l:qU:kKLA:";
168
while((op = getopt(argc, argv, theOpts)) != EOF) {
170
/* Courtesy of Ralf Amandi <Ralf.Amandi@accordata.net> */
172
case 'c': /* Sticky hosts = hosts that are not purged
177
case 'P': /* DB-Path */
178
stringSanityCheck(optarg);
179
strncpy(dbPath, optarg, sizeof(dbPath)-1)[sizeof(dbPath)-1] = '\0';
182
case 'a': /* ntop access log path */
183
stringSanityCheck(optarg);
184
strncpy(accessLogPath, optarg,
185
sizeof(accessLogPath)-1)[sizeof(accessLogPath)-1] = '\0';
193
case 'I': /* Interactive mode */
194
printf("intop provides you curses support. "
195
"ntop -I is no longer used.\n");
199
case 'q': /* allow ntop to save suspicious packets
200
in a file in pcap (tcpdump) format */
201
enableSuspiciousPacketDump=1;
204
case '1': /* disable throughput update */
208
case '2': /* disable purging of idle hosts */
213
stringSanityCheck(optarg);
217
case 'b': /* host:port */
218
stringSanityCheck(optarg);
219
handleDbSupport(optarg, &enableDBsupport);
222
case 'g': /* host:port */
223
stringSanityCheck(optarg);
224
handleNetFlowSupport(optarg);
228
case 'v': /* username:password:dbname:host */
229
stringSanityCheck(optarg);
230
handlemySQLSupport(optarg, &enableDBsupport);
234
case 'D': /* domain */
235
stringSanityCheck(optarg);
236
strncpy(domainName, optarg,
237
sizeof(domainName)-1)[sizeof(domainName)-1] = '\0';
241
isLsofPresent = 0; /* Don't make debugging too complex */
246
if(!isdigit(optarg[0])) {
247
printf("FATAL ERROR: flag -r expects a numeric argument.\n");
250
refreshRate = atoi(optarg);
255
maxNumLines = atoi(optarg);
260
isLsofPresent = checkCommand("lsof");
261
isNmapPresent = checkCommand("nmap");
265
maxHashSize = atoi(optarg);
266
if(maxHashSize < 64) {
268
traceEvent(TRACE_INFO, "Max hash size set to 64 (minimum hash size)");
273
stringSanityCheck(optarg);
278
stringSanityCheck(optarg);
279
len = strlen(optarg);
280
if(len > 2048) len = 2048;
281
protoSpecs = (char*)malloc(len+1);
282
memset(protoSpecs, 0, len+1);
283
strncpy(protoSpecs, optarg, len);
287
stringSanityCheck(optarg);
288
len = strlen(optarg);
289
if(len > 2048) len = 2048;
290
flowSpecs = (char*)malloc(len+1);
291
memset(flowSpecs, 0, len+1);
292
strncpy(flowSpecs, optarg, len);
296
stringSanityCheck(optarg);
297
localAddresses = strdup(optarg);
309
stringSanityCheck(optarg);
310
if(!isdigit(optarg[0])) {
311
printf("FATAL ERROR: flag -w expects a numeric argument.\n");
315
/* Courtesy of Daniel Savard <daniel.savard@gespro.com> */
316
if ((webAddr = strchr(optarg,':'))) {
317
/* DS: Search for : to find xxx.xxx.xxx.xxx:port */
318
/* This code is to be able to bind to a particular interface */
320
webPort = atoi(webAddr+1);
323
webPort = atoi(optarg);
329
stringSanityCheck(optarg);
330
if(!isdigit(optarg[0])) {
331
printf("FATAL ERROR: flag -W expects a numeric argument.\n");
336
lets swipe the same address binding code from -w above
337
Curtis Doty <Curtis@GreenKey.net>
339
if((sslAddr = strchr(optarg,':'))) {
341
sslPort = atoi(sslAddr+1);
344
sslPort = atoi(optarg);
351
stringSanityCheck(optarg);
352
strncpy(rulesFile, optarg,
353
sizeof(rulesFile)-1)[sizeof(rulesFile)-1] = '\0';
362
Persitent storage only for 'local' machines
363
Courtesy of Joel Crisp <jcrisp@dyn21-126.trilogy.com>
367
2 = store only local hosts
369
usePersistentStorage = atoi(optarg);
370
if((usePersistentStorage > 2)
371
|| (usePersistentStorage < 0)){
372
printf("FATAL ERROR: -S flag accepts value in the 0-2 range.\n");
378
/* Trace Level Initialization */
379
traceLevel = atoi(optarg);
380
if(traceLevel > DETAIL_TRACE_LEVEL)
381
traceLevel = DETAIL_TRACE_LEVEL;
386
accuracyLevel = atoi(optarg);
387
if(accuracyLevel > HIGH_ACCURACY_LEVEL)
388
accuracyLevel = HIGH_ACCURACY_LEVEL;
393
stringSanityCheck(optarg);
394
if(strOnlyDigits(optarg))
395
userId = atoi(optarg);
398
pw = getpwnam(optarg);
400
printf("FATAL ERROR: Unknown user %s.\n", optarg);
404
groupId = pw->pw_gid;
410
case 'U': /* host:port */
411
if(strlen(optarg) >= (sizeof(mapperURL)-1)) {
412
strncpy(mapperURL, optarg, sizeof(mapperURL)-2);
413
mapperURL[sizeof(mapperURL)-1] = '\0';
415
strcpy(mapperURL, optarg);
419
/* update info of used kernel filter expression in extra frame */
420
filterExpressionInExtraFrame=1;
443
traceEvent(TRACE_ERROR,
444
"FATAL ERROR: both -W and -w can't be set to 0.\n");
448
traceEvent(TRACE_ERROR,
449
"FATAL ERROR: -w can't be set to 0.\n");
454
/* ***************************** */
458
traceEvent(TRACE_INFO, "SSL is present but https is disabled: "
459
"use -W <https port> for enabling it\n");
464
snprintf(accessLogPath, sizeof(accessLogPath), "%s/%s",
465
dbPath, DETAIL_ACCESS_LOG_FILE_PATH);
467
initLogger(); /* Do not call this function before dbPath
473
reportValues(&lastTime);
474
#endif /* MICRO_NTOP */
475
postCommandLineArgumentsInitialization(&lastTime);
478
initDevices(devices);
480
traceEvent(TRACE_INFO, "ntop v.%s %s [%s] (%s build)",
481
version, THREAD_MODE, osName, buildDate);
484
if(rFileName != NULL)
485
strncpy(ifStr, PCAP_NW_INTERFACE, sizeof(ifStr));
487
for(i=0; i<numDevices; i++) {
491
if(snprintf(tmpBuf, sizeof(tmpBuf), ",%s", device[i].name) < 0)
492
traceEvent(TRACE_ERROR, "Buffer overflow!");
494
if(snprintf(tmpBuf, sizeof(tmpBuf), "%s", device[i].name) < 0)
495
traceEvent(TRACE_ERROR, "Buffer overflow!");
497
strncat(ifStr, tmpBuf, sizeof(ifStr)-strlen(ifStr)-1)[sizeof(ifStr)-1] = '\0';
500
traceEvent(TRACE_INFO, "Listening on [%s]", ifStr);
501
traceEvent(TRACE_INFO, "Copyright 1998-2001 by %s\n", author);
502
traceEvent(TRACE_INFO, "Get the freshest ntop from http://www.ntop.org/\n");
503
traceEvent(TRACE_INFO, "Initializing...\n");
505
initLibpcap(rulesFile, numDevices);
511
Code fragment below courtesy of
512
Andreas Pfaller <a.pfaller@pop.gun.de>
516
if((getuid() != geteuid()) || (getgid() != getegid())) {
517
/* setuid binary, drop privileges */
518
if (setgid(getgid())!=0 || setuid(getuid())!=0) {
519
traceEvent(TRACE_ERROR,
520
"FATAL ERROR: Unable to drop privileges.\n");
525
if((userId != 0) || (groupId != 0)){
526
/* user id specified on commandline */
527
if ((setgid(groupId) != 0) || (setuid(userId) != 0)) {
528
traceEvent(TRACE_ERROR, "FATAL ERROR: Unable to change user ID.\n");
533
if((geteuid() == 0) || (getegid() == 0)) {
534
traceEvent(TRACE_INFO, "WARNING: For security reasons it is STRONGLY recommended to");
535
traceEvent(TRACE_INFO, "WARNING: run ntop as unprivileged user by using the -u option!");
539
if(localAddresses != NULL) {
540
handleLocalAddresses(localAddresses);
541
free(localAddresses);
542
localAddresses = NULL;
545
initDeviceDatalink();
546
parseTrafficFilter(argv, optind);
548
/* Handle flows (if any) */
549
if(flowSpecs != NULL) {
550
if(flowSpecs[0] != '\0')
551
handleFlowsSpecs(flowSpecs);
555
/* Patch courtesy of Burton M. Strauss III <BStrauss3@attbi.com> */
556
if(protoSpecs != NULL) {
557
if(protoSpecs[0] != '\0')
558
handleProtocols(protoSpecs);
562
initCounters(mergeInterfaces);
566
initThreads(enableThUpdate, enableIdleHosts, enableDBsupport);
570
initWeb(webPort, webAddr, sslAddr);
572
traceEvent(TRACE_INFO, "Sniffying...\n");
579
In multithread mode, a separate thread handles
582
#ifndef MULTITHREADED
583
packetCaptureLoop(&lastTime, refreshRate);