~ubuntu-branches/ubuntu/wily/ntop/wily-proposed

« back to all changes in this revision

Viewing changes to ntop/webInterface.c

  • Committer: Bazaar Package Importer
  • Author(s): Dennis Schoen
  • Date: 2002-04-12 11:38:47 UTC
  • Revision ID: james.westby@ubuntu.com-20020412113847-4k4yydw0pzybc6g8
Tags: upstream-2.0.0
ImportĀ upstreamĀ versionĀ 2.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  Copyright (C) 1998-2001 Luca Deri <deri@ntop.org>
 
3
 *                          Portions by Stefano Suin <stefano@ntop.org>
 
4
 *
 
5
 *                          http://www.ntop.org/
 
6
 *
 
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.
 
11
 *
 
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.
 
16
 *
 
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.
 
20
 */
 
21
 
 
22
#include "ntop.h"
 
23
#include "globals-report.h"
 
24
 
 
25
#ifndef WIN32
 
26
#include <pwd.h>
 
27
#endif
 
28
#ifdef HAVE_UCD_SNMP_UCD_SNMP_AGENT_INCLUDES_H
 
29
#include <ucd-snmp/version.h>
 
30
#endif
 
31
 
 
32
#ifdef USE_COLOR
 
33
static short alternateColor=0;
 
34
#endif
 
35
 
 
36
/* Forward */
 
37
void handleSingleWebConnection(fd_set *fdmask);
 
38
 
 
39
#ifndef MICRO_NTOP
 
40
 
 
41
/* ************************************* */
 
42
 
 
43
#ifndef WIN32
 
44
#ifdef  USE_CGI
 
45
void execCGI(char* cgiName) {
 
46
  char* userName = "nobody", line[384], buf[256];
 
47
  struct passwd * newUser = NULL;
 
48
  FILE *fd;
 
49
  int num, i;
 
50
 
 
51
  if(!(newUser = getpwnam(userName))) {
 
52
    traceEvent(TRACE_WARNING, "WARNING: unable to find user %s\n", userName);
 
53
    return;
 
54
  } else {
 
55
    setgid(newUser->pw_gid);
 
56
    setuid(newUser->pw_uid);
 
57
  }
 
58
 
 
59
  for(num=0, i=0; cgiName[i] != '\0'; i++)
 
60
    if(cgiName[i] == '?') {
 
61
      cgiName[i] = '\0';
 
62
      if(snprintf(buf, sizeof(buf), "QUERY_STRING=%s", &cgiName[i+1]) < 0)
 
63
        traceEvent(TRACE_ERROR, "Buffer overflow!");
 
64
      putenv(buf);
 
65
      num = 1;
 
66
      break;
 
67
    }
 
68
 
 
69
  if(num == 0) putenv("QUERY_STRING=");
 
70
 
 
71
  if(snprintf(line, sizeof(line), "%s/cgi/%s", getenv("PWD"), cgiName) < 0)
 
72
    traceEvent(TRACE_ERROR, "Buffer overflow!");
 
73
 
 
74
  if((fd = sec_popen(line, "r")) == NULL) {
 
75
    traceEvent(TRACE_WARNING, "WARNING: unable to exec %s\n", cgiName);
 
76
    return;
 
77
  } else {
 
78
    while(!feof(fd)) {
 
79
      num = fread(line, 1, 383, fd);
 
80
      if(num > 0)
 
81
        sendStringLen(line, num);
 
82
    }
 
83
    pclose(fd);
 
84
  }
 
85
}
 
86
#endif /* USE_CGI */
 
87
#endif
 
88
 
 
89
/* **************************************** */
 
90
 
 
91
#if (defined(HAVE_DIRENT_H) && defined(HAVE_DLFCN_H)) || defined(WIN32) || defined(HPUX) || defined(AIX) || defined(DARWIN)
 
92
void showPluginsList(char* pluginName) {
 
93
  FlowFilterList *flows = flowsList;
 
94
  short printHeader = 0;
 
95
  char tmpBuf[BUF_SIZE], *thePlugin;
 
96
  int newPluginStatus = 0;
 
97
   
 
98
  if(pluginName[0] != '\0') {
 
99
    int i;
 
100
    
 
101
    thePlugin = pluginName;
 
102
    
 
103
    for(i=0; pluginName[i] != '\0'; i++)
 
104
      if(pluginName[i] == '=') {
 
105
        pluginName[i] = '\0';
 
106
        newPluginStatus = atoi(&pluginName[i+1]);
 
107
        break;
 
108
      }
 
109
  } else
 
110
    thePlugin = NULL;
 
111
 
 
112
  while(flows != NULL) {
 
113
    if((flows->pluginStatus.pluginPtr != NULL)
 
114
       && (flows->pluginStatus.pluginPtr->pluginURLname != NULL)) {
 
115
 
 
116
      if(thePlugin
 
117
         && (strcmp(flows->pluginStatus.pluginPtr->pluginURLname, thePlugin) == 0))
 
118
        flows->pluginStatus.activePlugin = newPluginStatus;
 
119
 
 
120
      if(!printHeader) {
 
121
        /* printHTTPheader(); */
 
122
        printHTMLheader("Available Plugins", 0);
 
123
        sendString("<CENTER>\n"
 
124
                   ""TABLE_ON"<TABLE BORDER=1><TR>\n"
 
125
                   "<TR><TH "TH_BG">Name</TH><TH>Description</TH>"
 
126
                   "<TH "TH_BG">Version</TH>"
 
127
                   "<TH "TH_BG">Author</TH>"
 
128
                   "<TH "TH_BG">Active</TH>"
 
129
                   "</TR>\n");
 
130
        printHeader = 1;
 
131
      }
 
132
 
 
133
      if(snprintf(tmpBuf, sizeof(tmpBuf), "<TR %s><TH "TH_BG" ALIGN=LEFT><A HREF=/plugins/%s>%s</TH>"
 
134
                  "<TD "TD_BG" ALIGN=LEFT>%s</TD>"
 
135
                  "<TD "TD_BG" ALIGN=CENTER>%s</TD>"
 
136
                  "<TD "TD_BG" ALIGN=LEFT>%s</TD>"
 
137
                  "<TD "TD_BG" ALIGN=CENTER><A HREF="STR_SHOW_PLUGINS"?%s=%d>%s</A></TD>"
 
138
                  "</TR>\n",
 
139
                  getRowColor(),
 
140
                  flows->pluginStatus.pluginPtr->pluginURLname,
 
141
                  flows->pluginStatus.pluginPtr->pluginURLname,
 
142
                  flows->pluginStatus.pluginPtr->pluginDescr,
 
143
                  flows->pluginStatus.pluginPtr->pluginVersion,
 
144
                  flows->pluginStatus.pluginPtr->pluginAuthor,
 
145
                  flows->pluginStatus.pluginPtr->pluginURLname,
 
146
                  flows->pluginStatus.activePlugin ? 0: 1,
 
147
                  flows->pluginStatus.activePlugin ? 
 
148
                  "Yes" : "<FONT COLOR=#FF0000>No</FONT>")  < 0) 
 
149
        traceEvent(TRACE_ERROR, "Buffer overflow!");
 
150
      sendString(tmpBuf);
 
151
    }
 
152
 
 
153
    flows = flows->next;
 
154
  }
 
155
 
 
156
  if(!printHeader) {
 
157
    printHTMLheader("No Plugins available", 0);
 
158
  } else {
 
159
    sendString("</TABLE>"TABLE_OFF"<p>\n");
 
160
    sendString("</CENTER>\n");
 
161
  }
 
162
}
 
163
 
 
164
#else /* defined(HAVE_DIRENT_H) && defined(HAVE_DLFCN_H) */
 
165
 
 
166
void showPluginsList(char* pluginName) {
 
167
  ;
 
168
}
 
169
 
 
170
void loadPlugins(void) {
 
171
  ;
 
172
}
 
173
 
 
174
void unloadPlugins(void) {
 
175
  ;
 
176
}
 
177
 
 
178
#endif /* defined(HAVE_DIRENT_H) && defined(HAVE_DLFCN_H) */
 
179
 
 
180
/* ******************************* */
 
181
 
 
182
char* makeHostLink(HostTraffic *el, short mode,
 
183
                   short cutName, short addCountryFlag) {
 
184
  static char buf[5][BUF_SIZE];
 
185
  char symIp[256], *tmpStr, linkName[256], flag[128];
 
186
  char *blinkOn, *blinkOff, *dynIp;
 
187
  char *multihomed, *gwStr, *dnsStr, *printStr, *smtpStr, *healthStr = "";
 
188
  short specialMacAddress = 0;
 
189
  static short bufIdx=0;
 
190
  short usedEthAddress=0;
 
191
 
 
192
  if(el == NULL)
 
193
    return("&nbsp;");
 
194
 
 
195
  if(broadcastHost(el) 
 
196
     || ((el->hostIpAddress.s_addr == 0) && (el->ethAddressString[0] == '\0'))) {
 
197
    if(mode == LONG_FORMAT)
 
198
      return("<TH "TH_BG" ALIGN=LEFT>&lt;broadcast&gt;</TH>");
 
199
    else
 
200
      return("&lt;broadcast&gt;");
 
201
  }
 
202
 
 
203
  blinkOn = "", blinkOff = "";
 
204
 
 
205
  bufIdx = (bufIdx+1)%5;
 
206
 
 
207
#ifdef MULTITHREADED
 
208
  accessMutex(&addressResolutionMutex, "makeHostLink");
 
209
#endif
 
210
 
 
211
  tmpStr = el->hostSymIpAddress;
 
212
  
 
213
  if((tmpStr == NULL) || (tmpStr[0] == '\0')) {
 
214
    /* The DNS is still getting the entry name */
 
215
    if(el->hostNumIpAddress[0] != '\0')
 
216
      strncpy(symIp, el->hostNumIpAddress, sizeof(symIp));
 
217
    else {
 
218
      strncpy(symIp, el->ethAddressString, sizeof(symIp)); 
 
219
      usedEthAddress = 1;
 
220
    }
 
221
  } else if(tmpStr[0] != '\0') {
 
222
    strncpy(symIp, tmpStr, sizeof(symIp));
 
223
    if(tmpStr[strlen(tmpStr)-1] == ']') /* "... [MAC]" */ {
 
224
      usedEthAddress = 1;
 
225
      specialMacAddress = 1;
 
226
    } else {
 
227
        if(cutName && (symIp[0] != '*') 
 
228
           && strcmp(symIp, el->hostNumIpAddress)) {
 
229
          int i;
 
230
          
 
231
          for(i=0; symIp[i] != '\0'; i++)
 
232
            if(symIp[i] == '.') {
 
233
              symIp[i] = '\0';
 
234
              break;
 
235
            }
 
236
        }
 
237
    }      
 
238
  } else {
 
239
    strncpy(symIp, el->ethAddressString, sizeof(symIp)); 
 
240
    usedEthAddress = 1;
 
241
  }
 
242
 
 
243
#ifdef MULTITHREADED
 
244
  releaseMutex(&addressResolutionMutex);
 
245
#endif
 
246
 
 
247
  if(specialMacAddress) {
 
248
    tmpStr = el->ethAddressString;
 
249
#ifdef DEBUG
 
250
    traceEvent(TRACE_INFO, "->'%s/%s'\n", symIp, el->ethAddressString);
 
251
#endif
 
252
  } else {
 
253
 
 
254
    if (usedEthAddress) {
 
255
      if(el->nbHostName != NULL) {
 
256
        strncpy(symIp, el->nbHostName, sizeof(linkName));
 
257
      } else if(el->ipxHostName != NULL) {
 
258
        strncpy(symIp, el->ipxHostName, sizeof(linkName));
 
259
      } 
 
260
    }
 
261
 
 
262
    if(el->hostNumIpAddress[0] != '\0') {
 
263
      tmpStr = el->hostNumIpAddress;
 
264
    } else {
 
265
      tmpStr = el->ethAddressString;
 
266
      /* tmpStr = symIp; */
 
267
    }
 
268
  }
 
269
 
 
270
  strncpy(linkName, tmpStr, sizeof(linkName));
 
271
 
 
272
  if(usedEthAddress) {
 
273
    /* Patch for ethernet addresses and MS Explorer */
 
274
    int i;    
 
275
    char tmpStr[256], *vendorInfo;
 
276
 
 
277
    if(el->nbHostName != NULL) {
 
278
      strncpy(symIp, el->nbHostName, sizeof(linkName));
 
279
    } else if(el->ipxHostName != NULL) {
 
280
      strncpy(symIp, el->ipxHostName, sizeof(linkName));      
 
281
    } else {
 
282
      vendorInfo = getVendorInfo(el->ethAddress, 0);
 
283
      if(vendorInfo[0] != '\0') {
 
284
        sprintf(tmpStr, "%s%s", vendorInfo, &linkName[8]);    
 
285
        strcpy(symIp, tmpStr); 
 
286
      }
 
287
      
 
288
      for(i=0; linkName[i] != '\0'; i++)
 
289
        if(linkName[i] == ':')
 
290
          linkName[i] = '_';
 
291
    }
 
292
  }
 
293
 
 
294
  if(addCountryFlag == 0)
 
295
    flag[0] = '\0';
 
296
  else {
 
297
    if(snprintf(flag, sizeof(flag), "<TD "TD_BG" ALIGN=CENTER>%s</TD>",
 
298
                getHostCountryIconURL(el)) < 0) 
 
299
      traceEvent(TRACE_ERROR, "Buffer overflow!");
 
300
  }
 
301
 
 
302
  if(isDHCPClient(el))
 
303
    dynIp = "&nbsp;<IMG ALT=\"DHCP Client\" SRC=/bulb.gif BORDER=0>&nbsp;"; 
 
304
  else { 
 
305
    if(isDHCPServer(el))
 
306
      dynIp = "&nbsp;<IMG ALT=\"DHCP Server\" SRC=/wheel.gif BORDER=0>&nbsp;"; 
 
307
    else
 
308
      dynIp = ""; 
 
309
  }
 
310
  
 
311
  if(isMultihomed(el))   multihomed = "&nbsp;<IMG ALT=\"Multihomed host\" SRC=/multihomed.gif BORDER=0>&nbsp;"; else multihomed = "";
 
312
  if(gatewayHost(el))    gwStr = "&nbsp;<IMG ALT=Router SRC=/router.gif BORDER=0>&nbsp;"; else gwStr = "";
 
313
  if(nameServerHost(el)) dnsStr = "&nbsp;<IMG ALT=\"DNS Server\" SRC=/dns.gif BORDER=0>&nbsp;"; else dnsStr = "";
 
314
  if(isPrinter(el))      printStr = "&nbsp;<IMG ALT=Printer SRC=/printer.gif BORDER=0>&nbsp;"; else printStr = "";
 
315
  if(isSMTPhost(el))     smtpStr = "&nbsp;<IMG ALT=\"Mail Server (SMTP)\" SRC=/mail.gif BORDER=0>&nbsp;"; else smtpStr = "";
 
316
  
 
317
  switch(isHostHealthy(el)) {
 
318
  case 0: /* OK */
 
319
    healthStr = "";
 
320
    break;
 
321
  case 1: /* Warning */
 
322
    healthStr = "<IMG ALT=\"Medium Risk\" SRC=/Risk_medium.gif BORDER=0>";
 
323
    break;
 
324
  case 2: /* Error */
 
325
    healthStr = "<IMG ALT=\"High Risk\" SRC=/Risk_high.gif BORDER=0>";
 
326
    break;
 
327
  }  
 
328
 
 
329
  if(mode == LONG_FORMAT) {
 
330
    if(snprintf(buf[bufIdx], BUF_SIZE, "<TH "TH_BG" ALIGN=LEFT NOWRAP>%s"
 
331
                "<A HREF=\"/%s.html\">%s</A>%s%s%s%s%s%s%s%s</TH>%s",
 
332
                blinkOn, linkName, symIp, dynIp, 
 
333
                multihomed, gwStr, dnsStr, printStr, smtpStr, healthStr,
 
334
                blinkOff, flag) < 0) 
 
335
      traceEvent(TRACE_ERROR, "Buffer overflow!");
 
336
  } else {
 
337
    if(snprintf(buf[bufIdx], BUF_SIZE, "%s<A HREF=\"/%s.html\" NOWRAP>%s</A>%s%s%s%s%s%s%s%s%s",
 
338
                blinkOn, linkName, symIp, 
 
339
                multihomed, gwStr, dnsStr, printStr, smtpStr, healthStr,
 
340
                dynIp, blinkOff, flag) < 0) 
 
341
      traceEvent(TRACE_ERROR, "Buffer overflow!");
 
342
  }
 
343
  
 
344
  return(buf[bufIdx]);
 
345
}
 
346
 
 
347
/* ******************************* */
 
348
 
 
349
char* getHostName(HostTraffic *el, short cutName) {
 
350
  static char buf[5][80];
 
351
  char *tmpStr;
 
352
  static short bufIdx=0;
 
353
 
 
354
  if(broadcastHost(el))
 
355
    return("broadcast");
 
356
 
 
357
  bufIdx = (bufIdx+1)%5;
 
358
 
 
359
#ifdef MULTITHREADED
 
360
  accessMutex(&addressResolutionMutex, "getHostName");
 
361
#endif
 
362
 
 
363
  tmpStr = el->hostSymIpAddress;
 
364
  
 
365
  if(tmpStr == NULL) {
 
366
    /* The DNS is still getting the entry name */
 
367
    if(el->hostNumIpAddress[0] == '\0')
 
368
      strncpy(buf[bufIdx], el->hostNumIpAddress, 80);
 
369
    else
 
370
      strncpy(buf[bufIdx], el->ethAddressString, 80);
 
371
  } else if(tmpStr[0] != '\0') {
 
372
    strncpy(buf[bufIdx], tmpStr, 80);
 
373
    if(cutName) {
 
374
      int i;
 
375
      
 
376
      for(i=0; buf[bufIdx][i] != '\0'; i++)
 
377
        if((buf[bufIdx][i] == '.')
 
378
           && (!(isdigit(buf[bufIdx][i-1])
 
379
                 && isdigit(buf[bufIdx][i+1]))
 
380
               )) {
 
381
          buf[bufIdx][i] = '\0';
 
382
          break;
 
383
        }
 
384
    }
 
385
  } else
 
386
    strncpy(buf[bufIdx], el->ethAddressString, 80);
 
387
  
 
388
#ifdef MULTITHREADED
 
389
  releaseMutex(&addressResolutionMutex);
 
390
#endif
 
391
 
 
392
  return(buf[bufIdx]);
 
393
}
 
394
 
 
395
/* ********************************** */
 
396
 
 
397
char* calculateCellColor(TrafficCounter actualValue,
 
398
                         TrafficCounter avgTrafficLow,
 
399
                         TrafficCounter avgTrafficHigh) {
 
400
 
 
401
  if(actualValue < avgTrafficLow)
 
402
    return("BGCOLOR=#AAAAAAFF"); /* light blue */
 
403
  else if(actualValue < avgTrafficHigh)
 
404
    return("BGCOLOR=#00FF75"); /* light green */
 
405
  else
 
406
    return("BGCOLOR=#FF7777"); /* light red */
 
407
}
 
408
 
 
409
 
 
410
/* ************************ */
 
411
 
 
412
char* getCountryIconURL(char* domainName) {
 
413
  if((domainName == NULL) || (domainName[0] == '\0')) {
 
414
    /* Courtesy of Roberto De Luca <deluca@tandar.cnea.gov.ar> */
 
415
    return("&nbsp;");
 
416
  } else {
 
417
    static char flagBuf[384];
 
418
    char path[256];
 
419
    struct stat buf;
 
420
 
 
421
    if(snprintf(path, sizeof(path), "./html/statsicons/flags/%s.gif", 
 
422
                domainName) < 0) 
 
423
      traceEvent(TRACE_ERROR, "Buffer overflow!");
 
424
 
 
425
    if(stat(path, &buf) != 0) {
 
426
      if(snprintf(path, sizeof(path), "%s/html/statsicons/flags/%s.gif", 
 
427
                  DATAFILE_DIR, domainName) < 0) 
 
428
        traceEvent(TRACE_ERROR, "Buffer overflow!");
 
429
 
 
430
      if(stat(path, &buf) != 0)
 
431
        return("&nbsp;");
 
432
    }
 
433
    
 
434
    if(snprintf(flagBuf, sizeof(flagBuf), 
 
435
                "<IMG ALT=\"Flag for domain %s\"  ALIGN=MIDDLE SRC=/statsicons/flags/%s.gif BORDER=0>",
 
436
                domainName, domainName) < 0) traceEvent(TRACE_ERROR, "Buffer overflow!");
 
437
 
 
438
    return(flagBuf);
 
439
  }
 
440
}
 
441
 
 
442
/* ************************ */
 
443
 
 
444
char* getHostCountryIconURL(HostTraffic *el) {
 
445
  char path[128], *ret;
 
446
  struct stat buf;
 
447
 
 
448
  fillDomainName(el);
 
449
 
 
450
  if(snprintf(path, sizeof(path), "%s/html/statsicons/flags/%s.gif", 
 
451
              DATAFILE_DIR, el->fullDomainName) < 0) 
 
452
    traceEvent(TRACE_ERROR, "Buffer overflow!");
 
453
 
 
454
  if(stat(path, &buf) == 0)
 
455
    ret = getCountryIconURL(el->fullDomainName);
 
456
  else
 
457
    ret = getCountryIconURL(el->dotDomainName);
 
458
 
 
459
  if(ret == NULL)
 
460
    ret = "&nbsp;";
 
461
 
 
462
  return(ret);
 
463
}
 
464
 
 
465
/* ******************************* */
 
466
 
 
467
char* getRowColor(void) {
 
468
  /* #define USE_COLOR */
 
469
 
 
470
#ifdef USE_COLOR
 
471
  if(alternateColor == 0) {
 
472
    alternateColor = 1;
 
473
    return("BGCOLOR=#C3C9D9"); /* EFEFEF */ 
 
474
  } else {
 
475
    alternateColor = 0;
 
476
    return("");
 
477
  }
 
478
#else
 
479
  return("");
 
480
#endif
 
481
}
 
482
 
 
483
/* ******************************* */
 
484
 
 
485
char* getActualRowColor(void) {
 
486
  /* #define USE_COLOR */
 
487
 
 
488
#ifdef USE_COLOR
 
489
  if(alternateColor == 1) {
 
490
    return("BGCOLOR=#EFEFEF");
 
491
  } else
 
492
    return("");
 
493
#else
 
494
  return("");
 
495
#endif
 
496
}
 
497
 
 
498
 
 
499
/* ******************************* */
 
500
 
 
501
void switchNwInterface(int _interface) {
 
502
  int i, mwInterface=_interface-1;
 
503
  char buf[BUF_SIZE], *selected;
 
504
 
 
505
  printHTMLheader("Network Interface Switch", HTML_FLAG_NO_REFRESH); 
 
506
  sendString("<HR>\n<P>\n<FONT FACE=\"Helvetica, Arial, Sans Serif\"><B>\n");
 
507
 
 
508
  if(mergeInterfaces) {
 
509
    if(snprintf(buf, sizeof(buf), "You can't switch among different inferfaces if the -M "
 
510
                "command line switch is not used. Sorry.\n") < 0) 
 
511
      traceEvent(TRACE_ERROR, "Buffer overflow!");
 
512
    sendString(buf);
 
513
  } else if((mwInterface != -1) &&
 
514
            ((mwInterface >= numDevices) || device[mwInterface].virtualDevice)) {
 
515
    if(snprintf(buf, sizeof(buf), "Invalid interface selected. Sorry.\n") < 0) 
 
516
      traceEvent(TRACE_ERROR, "Buffer overflow!");
 
517
    sendString(buf);
 
518
  } else if(numDevices == 1) {
 
519
    if(snprintf(buf, sizeof(buf), "You're currently capturing traffic from one "
 
520
                "interface [%s]. The interface switch feature is active only when "
 
521
                "you active ntop with multiple interfaces (-i command line switch). "
 
522
                "Sorry.\n", device[actualReportDeviceId].name) < 0) 
 
523
      traceEvent(TRACE_ERROR, "Buffer overflow!");
 
524
    sendString(buf);
 
525
  } else if(mwInterface >= 0) {
 
526
    actualReportDeviceId = (mwInterface)%numDevices;
 
527
    if(snprintf(buf, sizeof(buf), "The current interface is now [%s].\n", 
 
528
                device[actualReportDeviceId].name) < 0) 
 
529
      traceEvent(TRACE_ERROR, "Buffer overflow!");
 
530
    sendString(buf);
 
531
  } else {
 
532
    sendString("Available Network Interfaces:</B><P>\n<FORM ACTION="SWITCH_NIC_HTML">\n");
 
533
 
 
534
    for(i=0; i<numDevices; i++) 
 
535
      if(!device[i].virtualDevice) {
 
536
        if(actualReportDeviceId == i)
 
537
          selected="CHECKED";
 
538
        else
 
539
          selected = "";
 
540
 
 
541
        if(snprintf(buf, sizeof(buf), "<INPUT TYPE=radio NAME=interface VALUE=%d %s>&nbsp;%s<br>\n",
 
542
                    i+1, selected, device[i].name) < 0) traceEvent(TRACE_ERROR, "Buffer overflow!");
 
543
 
 
544
        sendString(buf);
 
545
      }
 
546
 
 
547
    sendString("<p><INPUT TYPE=submit>&nbsp;<INPUT TYPE=reset>\n</FORM>\n");
 
548
    sendString("<B>");
 
549
  }
 
550
 
 
551
  sendString("</B>");
 
552
  sendString("</font><p>\n");
 
553
}
 
554
 
 
555
/* **************************************** */
 
556
 
 
557
void shutdownNtop(void) {
 
558
  printHTMLheader("ntop is shutting down...", HTML_FLAG_NO_REFRESH);
 
559
  closeNwSocket(&newSock);
 
560
  termAccessLog();
 
561
  cleanup(0);
 
562
}
 
563
 
 
564
/* ******************************** */
 
565
 
 
566
static void printFeatureConfigInfo(char* feature, char* status) {
 
567
  sendString("<TR><TH "TH_BG" ALIGN=left>");
 
568
  sendString(feature);
 
569
  sendString("</TH><TD "TD_BG" ALIGN=right>");
 
570
  sendString(status);
 
571
  sendString("</TD></TR>\n");
 
572
}
 
573
 
 
574
/* ******************************** */
 
575
 
 
576
#ifdef MULTITHREADED
 
577
static void printMutexStatus(PthreadMutex *mutexId, char *mutexName) {  
 
578
  char buf[BUF_SIZE];
 
579
 
 
580
  if(mutexId->lockLine == 0) /* Mutex never used */
 
581
    return;
 
582
 
 
583
  if(snprintf(buf, sizeof(buf), 
 
584
              "<TR><TH "TH_BG" ALIGN=left>%s</TH><TD ALIGN=CENTER>%s</TD>"
 
585
              "<TD ALIGN=RIGHT>%s:%d</TD>"
 
586
              "<TD ALIGN=RIGHT>%s:%d</TD>"
 
587
              "<TD ALIGN=RIGHT>%u</TD><TD ALIGN=LEFT>%u</TD>"
 
588
              "<TD ALIGN=RIGHT>%d sec [%s:%d]</TD></TR>", 
 
589
              mutexName,
 
590
              mutexId->isLocked ? "<FONT COLOR=red>locked</FONT>" : "unlocked",
 
591
              mutexId->lockFile, mutexId->lockLine,
 
592
              mutexId->unlockFile, mutexId->unlockLine,
 
593
              mutexId->numLocks, mutexId->numReleases,
 
594
              mutexId->maxLockedDuration,
 
595
              mutexId->maxLockedDurationUnlockFile,
 
596
              mutexId->maxLockedDurationUnlockLine) < 0)
 
597
    traceEvent(TRACE_ERROR, "Buffer overflow!");
 
598
 
 
599
  sendString(buf);
 
600
}
 
601
#endif
 
602
 
 
603
void printNtopConfigInfo(void) {
 
604
  char buf[BUF_SIZE];
 
605
  int i;
 
606
#ifdef HAVE_PCAP_VERSION
 
607
  extern char pcap_version[];
 
608
#endif /* HAVE_PCAP_VERSION */
 
609
 
 
610
  printHTMLheader("Current ntop Configuration", 0);
 
611
  sendString("<CENTER>\n");
 
612
  sendString("<P><HR><P>"TABLE_ON"<TABLE BORDER=1>\n");
 
613
 
 
614
  printFeatureConfigInfo("OS", osName);
 
615
  printFeatureConfigInfo("ntop version", version);
 
616
  printFeatureConfigInfo("Built on", buildDate);
 
617
  
 
618
  /* *************************** */
 
619
 
 
620
  sendString("<TR><TH "TH_BG" ALIGN=left>Started as</TH><TD "TD_BG" ALIGN=right>");
 
621
  for(i=0; i<ntop_argc; i++) {
 
622
    sendString(ntop_argv[i]);
 
623
    sendString(" ");
 
624
  } 
 
625
  sendString("</TD></TR>\n");
 
626
 
 
627
  /* *************************** */
 
628
 
 
629
#ifdef HAVE_PCAP_VERSION
 
630
  printFeatureConfigInfo("Libpcap version", pcap_version);
 
631
#endif /* HAVE_PCAP_VERSION */
 
632
#if defined(WIN32) && defined(__GNUC__)
 
633
  /* on mingw, gdbm_version not exported by library */
 
634
#else
 
635
  printFeatureConfigInfo("GDBM version", gdbm_version);
 
636
#endif
 
637
  
 
638
#ifdef HAVE_OPENSSL
 
639
  printFeatureConfigInfo("<A HREF=http://www.openssl.org/>OpenSSL Support</A>", 
 
640
                         (char*)SSLeay_version(0));
 
641
  if(sslPort != 0) {
 
642
    sprintf(buf, "%d", sslPort); 
 
643
    printFeatureConfigInfo("SSL Port", buf);
 
644
  } else
 
645
    printFeatureConfigInfo("SSL Port", "Not Active");
 
646
#else
 
647
  printFeatureConfigInfo("<A HREF=http://www.openssl.org/>OpenSSL Support</A>", "Absent");
 
648
#endif
 
649
 
 
650
#ifdef MULTITHREADED
 
651
  printFeatureConfigInfo("Multithreaded", "Yes");
 
652
#else
 
653
  printFeatureConfigInfo("Multithreaded", "No");
 
654
#endif
 
655
 
 
656
#ifdef HAVE_GDCHART
 
657
  printFeatureConfigInfo("<A HREF=http://www.fred.net/brv/chart/>GD Chart</A>", "Present");
 
658
  printFeatureConfigInfo("Chart Format", CHART_FORMAT);
 
659
#else
 
660
  printFeatureConfigInfo("<A HREF=http://www.fred.net/brv/chart/>GD Chart</A>", "Absent");
 
661
#endif
 
662
 
 
663
#ifdef HAVE_UCD_SNMP_UCD_SNMP_AGENT_INCLUDES_H
 
664
  printFeatureConfigInfo("<A HREF=http://net-snmp.sourceforge.net/>UCD/NET SNMP</A>", 
 
665
                         (char*)VersionInfo);
 
666
#else
 
667
  printFeatureConfigInfo("<A HREF=http://net-snmp.sourceforge.net/>UCD/NET SNMP </A>", 
 
668
                         "Absent");
 
669
#endif
 
670
 
 
671
#ifdef HAVE_LIBWRAP
 
672
  printFeatureConfigInfo("TCP Wrappers", "Present");
 
673
#else
 
674
  printFeatureConfigInfo("TCP Wrappers", "Absent");
 
675
#endif
 
676
 
 
677
#ifdef ASYNC_ADDRESS_RESOLUTION
 
678
  printFeatureConfigInfo("Async. Addr. Resolution", "Yes");
 
679
#else
 
680
  printFeatureConfigInfo("Async. Addr. Resolution", "No");
 
681
#endif
 
682
 
 
683
  if(isLsofPresent) 
 
684
    printFeatureConfigInfo("<A HREF=ftp://vic.cc.purdue.edu/pub/tools/unix/lsof/>lsof</A> Support", "Yes");
 
685
  else
 
686
    printFeatureConfigInfo("<A HREF=ftp://vic.cc.purdue.edu/pub/tools/unix/lsof/>lsof</A> Support",
 
687
                           "No (Either disabled [Use -E option] or missing)");
 
688
 
 
689
  if(isNmapPresent) 
 
690
    printFeatureConfigInfo("<A HREF=http://www.insecure.org/nmap/>nmap</A> Support", "Yes");
 
691
  else
 
692
    printFeatureConfigInfo("<A HREF=http://www.insecure.org/nmap/>nmap</A> Support", 
 
693
                           "No (Either disabled [Use -E option] or missing)");
 
694
 
 
695
  if(snprintf(buf, sizeof(buf), "<TR><TH "TH_BG" align=left># Handled HTTP Requests</TH>"
 
696
              "<TD "TD_BG"  align=right>%lu</TD></TR>\n", numHandledHTTPrequests) < 0) 
 
697
    traceEvent(TRACE_ERROR, "Buffer overflow!");
 
698
  sendString(buf);
 
699
 
 
700
  if(snprintf(buf, sizeof(buf), "<TR><TH "TH_BG" align=left>Actual Hash Size</TH>"
 
701
              "<TD "TD_BG"  align=right>%d</TD></TR>\n",
 
702
              (int)device[actualReportDeviceId].actualHashSize) < 0) 
 
703
    traceEvent(TRACE_ERROR, "Buffer overflow!");
 
704
  sendString(buf);
 
705
 
 
706
  if(snprintf(buf, sizeof(buf), "<TR><TH "TH_BG" align=left>Top Hash Size</TH>"
 
707
              "<TD "TD_BG"  align=right>%d</TD></TR>\n", topHashSize) < 0) 
 
708
    traceEvent(TRACE_ERROR, "Buffer overflow!");
 
709
  sendString(buf);
 
710
 
 
711
#ifdef MULTITHREADED
 
712
  if(snprintf(buf, sizeof(buf), "<TR><TH "TH_BG" align=left># Queued Pkts to Process</TH>"
 
713
              "<TD "TD_BG"  align=right>%d</TD></TR>\n",
 
714
              packetQueueLen) < 0) 
 
715
    traceEvent(TRACE_ERROR, "Buffer overflow!");
 
716
  sendString(buf);
 
717
 
 
718
  if(snprintf(buf, sizeof(buf), "<TR><TH "TH_BG" align=left># Max Queued Pkts</TH>"
 
719
              "<TD "TD_BG"  align=right>%u</TD></TR>\n",
 
720
              maxPacketQueueLen) < 0) 
 
721
    traceEvent(TRACE_ERROR, "Buffer overflow!");
 
722
  sendString(buf);
 
723
#endif
 
724
 
 
725
  if(snprintf(buf, sizeof(buf), "<TR><TH "TH_BG" align=left># Stored Hash Hosts</TH>"
 
726
              "<TD "TD_BG"  align=right>%d [%d %%]</TD></TR>\n",
 
727
              (int)device[actualReportDeviceId].hostsno,
 
728
              (((int)device[actualReportDeviceId].hostsno*100)/
 
729
               (int)device[actualReportDeviceId].actualHashSize)) < 0) 
 
730
    traceEvent(TRACE_ERROR, "Buffer overflow!");
 
731
  sendString(buf);
 
732
 
 
733
  if(snprintf(buf, sizeof(buf), "<TR><TH "TH_BG" align=left># Purged Hash Hosts</TH>"
 
734
              "<TD "TD_BG"  align=right>%u</TD></TR>\n",
 
735
              (unsigned int)numPurgedHosts) < 0) 
 
736
    traceEvent(TRACE_ERROR, "Buffer overflow!");
 
737
  sendString(buf);
 
738
 
 
739
  if(snprintf(buf, sizeof(buf), "<TR><TH "TH_BG" align=left># TCP Sessions</TH>"
 
740
              "<TD "TD_BG"  align=right>%u</TD></TR>\n", 
 
741
              device[actualReportDeviceId].numTcpSessions) < 0) 
 
742
    traceEvent(TRACE_ERROR, "Buffer overflow!");
 
743
  sendString(buf);
 
744
 
 
745
  if(snprintf(buf, sizeof(buf), "<TR><TH "TH_BG" align=left># Terminated TCP Sessions</TH>"
 
746
              "<TD "TD_BG"  align=right>%u</TD></TR>\n", 
 
747
              (unsigned int)numTerminatedSessions) < 0) 
 
748
    traceEvent(TRACE_ERROR, "Buffer overflow!");
 
749
  sendString(buf);
 
750
 
 
751
#if defined(MULTITHREADED) && defined(ASYNC_ADDRESS_RESOLUTION)
 
752
  accessMutex(&addressQueueMutex, "NumQueuedAddresses");
 
753
  if(snprintf(buf, sizeof(buf), "<TR><TH "TH_BG" align=left># Queued Addresses</TH>"
 
754
              "<TD "TD_BG"  align=right>%d</TD></TR>\n", addressQueueLen) < 0) 
 
755
    traceEvent(TRACE_ERROR, "Buffer overflow!");
 
756
  sendString(buf);
 
757
  releaseMutex(&addressQueueMutex);
 
758
#endif
 
759
 
 
760
  /* **** */
 
761
 
 
762
#if defined(MULTITHREADED)
 
763
  accessMutex(&addressQueueMutex, "NumQueuedAddresses");
 
764
#endif
 
765
 
 
766
  if(snprintf(buf, sizeof(buf), "<TR><TH "TH_BG" align=left># Addresses Resolved with DNS</TH>"
 
767
              "<TD "TD_BG"  align=right>%ld</TD></TR>\n", numResolvedWithDNSAddresses) < 0) 
 
768
    traceEvent(TRACE_ERROR, "Buffer overflow!");
 
769
  sendString(buf);
 
770
 
 
771
  if(snprintf(buf, sizeof(buf), "<TR><TH "TH_BG" align=left># Addresses Kept Numeric</TH>"
 
772
              "<TD "TD_BG"  align=right>%ld</TD></TR>\n", numKeptNumericAddresses) < 0) 
 
773
    traceEvent(TRACE_ERROR, "Buffer overflow!");
 
774
  sendString(buf);
 
775
 
 
776
  if(snprintf(buf, sizeof(buf), "<TR><TH "TH_BG" align=left># Addresses Found in Cache</TH>"
 
777
              "<TD "TD_BG"  align=right>%ld</TD></TR>\n", numResolvedOnCacheAddresses) < 0) 
 
778
    traceEvent(TRACE_ERROR, "Buffer overflow!");
 
779
  sendString(buf);
 
780
 
 
781
#if defined(MULTITHREADED)
 
782
  if(snprintf(buf, sizeof(buf), "<TR><TH "TH_BG" align=left># Dropped Addresses</TH>"
 
783
              "<TD "TD_BG"  align=right>%ld</TD></TR>\n", (long int)droppedAddresses) < 0) 
 
784
    traceEvent(TRACE_ERROR, "Buffer overflow!");
 
785
  sendString(buf);
 
786
#endif
 
787
 
 
788
#if defined(MULTITHREADED)
 
789
  releaseMutex(&addressQueueMutex);
 
790
#endif
 
791
 
 
792
  /* **** */
 
793
 
 
794
#if defined(MULTITHREADED)
 
795
  if(snprintf(buf, sizeof(buf), "<TR><TH "TH_BG" align=left># Active Threads</TH>"
 
796
              "<TD "TD_BG"  align=right>%d</TD></TR>\n", numThreads) < 0) 
 
797
    traceEvent(TRACE_ERROR, "Buffer overflow!");
 
798
  sendString(buf);
 
799
#endif
 
800
 
 
801
#ifdef MEMORY_DEBUG
 
802
  if(snprintf(buf, sizeof(buf), "<TR><TH "TH_BG" align=left>Allocated Memory</TH>"
 
803
              "<TD "TD_BG"  align=right>%s</TD></TR>\n",
 
804
              formatBytes(allocatedMemory, 0)) < 0) 
 
805
    traceEvent(TRACE_ERROR, "Buffer overflow!");
 
806
  sendString(buf);
 
807
#endif
 
808
 
 
809
  if(isLsofPresent) {
 
810
    if(snprintf(buf, sizeof(buf), "<TR><TH "TH_BG" align=left># Monitored Processes</TH>"
 
811
                "<TD "TD_BG"  align=right>%d</TD></TR>\n", numProcesses) < 0)
 
812
      traceEvent(TRACE_ERROR, "Buffer overflow!");
 
813
    sendString(buf);
 
814
  }
 
815
 
 
816
  sendString("</TABLE>"TABLE_OFF"\n");
 
817
 
 
818
  /* **************************** */
 
819
 
 
820
#ifdef MULTITHREADED
 
821
  sendString("<P>"TABLE_ON"<TABLE BORDER=1>\n");
 
822
  sendString("<TR><TH>Mutex Name</TH><TH>State</TH><TH>Last Lock</TH><TH>Last UnLock</TH>"
 
823
             "<TH COLSPAN=2># Locks/Releases</TH><TH>Max Lock</TH></TR>");
 
824
  printMutexStatus(&gdbmMutex, "gdbmMutex");
 
825
  printMutexStatus(&packetQueueMutex, "packetQueueMutex");
 
826
  printMutexStatus(&addressResolutionMutex, "addressResolutionMutex");
 
827
  printMutexStatus(&hashResizeMutex, "hashResizeMutex");  
 
828
  if(isLsofPresent) printMutexStatus(&lsofMutex, "lsofMutex");
 
829
  printMutexStatus(&hostsHashMutex, "hostsHashMutex");
 
830
  printMutexStatus(&graphMutex, "graphMutex");
 
831
#ifdef ASYNC_ADDRESS_RESOLUTION
 
832
  if(numericFlag == 0) printMutexStatus(&addressQueueMutex, "addressQueueMutex");
 
833
#endif
 
834
  sendString("</TABLE>"TABLE_OFF"\n");
 
835
#endif /* MULTITHREADED */
 
836
 
 
837
  sendString("</CENTER>\n");
 
838
}
 
839
 
 
840
#endif /* MICRO_NTOP */
 
841
 
 
842
/* ******************************* */
 
843
 
 
844
static void initializeWeb(void) {
 
845
#ifndef MICRO_NTOP
 
846
  columnSort = 0, sortSendMode = 0;
 
847
#endif
 
848
  addDefaultAdminUser();
 
849
  initAccessLog();
 
850
}
 
851
 
 
852
/* **************************************** */
 
853
 
 
854
 /* 
 
855
    SSL fix courtesy of 
 
856
    Curtis Doty <Curtis@GreenKey.net>
 
857
 */
 
858
void initWeb(int webPort, char* webAddr, char* sslAddr) {
 
859
  int sockopt = 1;
 
860
  struct sockaddr_in sin;
 
861
 
 
862
  initReports();
 
863
  initializeWeb();
 
864
 
 
865
  actualReportDeviceId = 0;
 
866
 
 
867
  if(webPort > 0) {
 
868
    sin.sin_family      = AF_INET;
 
869
    sin.sin_port        = (int)htons((unsigned short int)webPort);
 
870
    sin.sin_addr.s_addr = INADDR_ANY;
 
871
 
 
872
#ifndef WIN32
 
873
    if(sslAddr) {
 
874
      if(!inet_aton(sslAddr,&sin.sin_addr))
 
875
        traceEvent(TRACE_ERROR, "Unable to convert address '%s'...\n"
 
876
                   "Not binding SSL to a particular interface!\n",  sslAddr);
 
877
    }
 
878
 
 
879
    if (webAddr) {      /* Code added to be able to bind to a particular interface */
 
880
      if (!inet_aton(webAddr,&sin.sin_addr))
 
881
        traceEvent(TRACE_ERROR, "Unable to convert address '%s'...\n"
 
882
                   "Not binding to a particular interface!\n",  webAddr);
 
883
    }
 
884
#endif
 
885
 
 
886
    sock = socket(AF_INET, SOCK_STREAM, 0);
 
887
    if(sock < 0) {
 
888
      traceEvent(TRACE_ERROR, "Unable to create a new socket");
 
889
      exit(-1);
 
890
    }
 
891
 
 
892
    setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&sockopt, sizeof(sockopt));
 
893
  } else
 
894
    sock = 0;
 
895
 
 
896
#ifdef HAVE_OPENSSL
 
897
  if(sslInitialized) {
 
898
    sock_ssl = socket(AF_INET, SOCK_STREAM, 0);
 
899
    if(sock_ssl < 0) {
 
900
      traceEvent(TRACE_ERROR, "unable to create a new socket");
 
901
      exit(-1);
 
902
    }
 
903
 
 
904
    setsockopt(sock_ssl, SOL_SOCKET, SO_REUSEADDR, (char *)&sockopt, sizeof(sockopt));
 
905
  }
 
906
#endif
 
907
 
 
908
  if(webPort > 0) {
 
909
    if(bind(sock, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
 
910
      traceEvent(TRACE_WARNING, "bind: port %d already in use.", webPort);
 
911
      closeNwSocket(&sock);
 
912
      exit(-1);
 
913
    }
 
914
  }
 
915
 
 
916
#ifdef HAVE_OPENSSL
 
917
  if(sslInitialized) {
 
918
    sin.sin_family      = AF_INET;
 
919
    sin.sin_port        = (int)htons(sslPort);
 
920
    sin.sin_addr.s_addr = INADDR_ANY;
 
921
 
 
922
    if(bind(sock_ssl, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
 
923
      traceEvent(TRACE_ERROR, "bind: port %d already in use.", webPort);
 
924
      closeNwSocket(&sock_ssl);
 
925
      exit(-1);
 
926
    }
 
927
  }
 
928
#endif
 
929
 
 
930
  if(webPort > 0) {
 
931
    if(listen(sock, 5) < 0) {
 
932
      traceEvent(TRACE_WARNING, "listen error.\n");
 
933
      closeNwSocket(&sock);
 
934
      exit(-1);
 
935
    } 
 
936
  }
 
937
 
 
938
#ifdef HAVE_OPENSSL
 
939
  if(sslInitialized) 
 
940
    if(listen(sock_ssl, 5) < 0) {
 
941
      traceEvent(TRACE_WARNING, "listen error.\n");
 
942
      closeNwSocket(&sock_ssl);
 
943
      exit(-1);
 
944
    }
 
945
#endif
 
946
 
 
947
  if(webPort > 0) {
 
948
    /* Courtesy of Daniel Savard <daniel.savard@gespro.com> */
 
949
    if (webAddr) 
 
950
      traceEvent(TRACE_INFO, "Waiting for HTTP connections on %s port %d...\n",
 
951
                 webAddr, webPort);
 
952
    else 
 
953
      traceEvent(TRACE_INFO, "Waiting for HTTP connections on port %d...\n",
 
954
                 webPort);
 
955
  }
 
956
 
 
957
#ifdef HAVE_OPENSSL
 
958
  if(sslInitialized) 
 
959
    traceEvent(TRACE_INFO, "Waiting for HTTPS (SSL) connections on port %d...\n",
 
960
               sslPort);
 
961
#endif
 
962
 
 
963
#ifdef MULTITHREADED
 
964
  createThread(&handleWebConnectionsThreadId, handleWebConnections, NULL);
 
965
#endif
 
966
}
 
967
 
 
968
/* **************************************** */
 
969
 
 
970
void usage(void) {
 
971
  char buf[80];
 
972
 
 
973
  if(snprintf(buf, sizeof(buf), "%s v.%s %s [%s] (%s build)", 
 
974
              program_name, version, THREAD_MODE, osName, buildDate) < 0) 
 
975
    traceEvent(TRACE_ERROR, "Buffer overflow!");
 
976
  traceEvent(TRACE_INFO, "%s\n", buf);
 
977
 
 
978
  traceEvent(TRACE_INFO, "Copyright 1998-2001 by %s\n", author);
 
979
  traceEvent(TRACE_INFO, "Get the freshest ntop from http://www.ntop.org/\n");
 
980
  if(snprintf(buf, sizeof(buf), "Written by %s.", author) < 0)
 
981
    traceEvent(TRACE_ERROR, "Buffer overflow!");
 
982
 
 
983
  traceEvent(TRACE_INFO, "%s\n", buf);
 
984
 
 
985
  if(snprintf(buf, sizeof(buf), "Usage: %s", program_name) < 0) 
 
986
    traceEvent(TRACE_ERROR, "Buffer overflow!");
 
987
 
 
988
  traceEvent(TRACE_INFO, "%s\n", buf);
 
989
 
 
990
  traceEvent(TRACE_INFO, "    %s\n",   "[-c <sticky hosts: idle hosts are not purged from hash>]");
 
991
#ifdef WIN32
 
992
  traceEvent(TRACE_INFO, "    [-r <refresh time (web = %d sec)>]\n", REFRESH_TIME);
 
993
#else
 
994
  traceEvent(TRACE_INFO, "    [-r <refresh time (interactive = %d sec/web = %d sec)>]\n",
 
995
             ALARM_TIME, REFRESH_TIME);
 
996
#endif
 
997
  traceEvent(TRACE_INFO, "    %s\n",   "[-f <traffic dump file (see tcpdump)>]");
 
998
#ifndef WIN32
 
999
  traceEvent(TRACE_INFO, "    %s\n",   "[-E <enable lsof/nmap integration (if present)>]");
 
1000
#endif
 
1001
  traceEvent(TRACE_INFO, "    %s\n",   "[-n (numeric IP addresses)]");
 
1002
  traceEvent(TRACE_INFO, "    %s\n",   "[-p <IP protocols to monitor> (see man page)]");
 
1003
#ifndef WIN32
 
1004
  traceEvent(TRACE_INFO, "    %s\n",   "[-i <interface>]");
 
1005
#else
 
1006
  traceEvent(TRACE_INFO, "    %s\n",   "[-i <interface index>]");
 
1007
#endif
 
1008
  traceEvent(TRACE_INFO, "    %s\n",   "[-S <store mode> (store persistently host stats)]");
 
1009
  traceEvent(TRACE_INFO, "    %s\n",   "[-w <HTTP port>]");
 
1010
#ifdef HAVE_OPENSSL
 
1011
  traceEvent(TRACE_INFO, "    %s\n",   "[-W <HTTPS port>]");
 
1012
#endif
 
1013
  traceEvent(TRACE_INFO, "    %s\n",   "[-D <Internet domain name>]");
 
1014
  traceEvent(TRACE_INFO, "    %s\n",   "[-e <max # table rows)]");
 
1015
#ifndef WIN32
 
1016
  traceEvent(TRACE_INFO, "    %s\n",   "[-d (run ntop in daemon mode)]");
 
1017
#endif
 
1018
  traceEvent(TRACE_INFO, "    %s\n",   "[-m <local addresses (see man page)>]");
 
1019
  traceEvent(TRACE_INFO, "    %s\n",   "[-s <max hash size (default 32768)>]");
 
1020
  traceEvent(TRACE_INFO, "    %s\n",   "[-F <flow specs (see man page)>]");
 
1021
  traceEvent(TRACE_INFO, "    %s\n",   "[-b <client:port (ntop DB client)>]");
 
1022
#ifdef HAVE_MYSQL
 
1023
  traceEvent(TRACE_INFO, "    %s\n",   "[-v <username:password:dbName (ntop mySQL client)>]");
 
1024
#endif
 
1025
  traceEvent(TRACE_INFO, "    %s\n",   "[-R <matching rules file>]");
 
1026
  traceEvent(TRACE_INFO, "    %s\n",   "[-N <don't use nmap if installed>]");
 
1027
  traceEvent(TRACE_INFO, "    %s\n",   "[-M <don't merge network interfaces (see man page)>]");
 
1028
  traceEvent(TRACE_INFO, "    %s\n",   "[-q <create file ntop-suspicious-pkts.XXX.pcap>]");
 
1029
  traceEvent(TRACE_INFO, "    %s\n",   "[-l <path> (dump packets captured on a file: debug only!)]");
 
1030
  traceEvent(TRACE_INFO, "    %s\n",   "[-P <path for db-files>]");
 
1031
  traceEvent(TRACE_INFO, "    %s\n",   "[-g <client:port (Cisco NetFlow client)>]");
 
1032
  traceEvent(TRACE_INFO, "    %s\n",   "[-t (trace level [0-5])]");
 
1033
  traceEvent(TRACE_INFO, "    %s\n",   "[-A (accuracy level [0-2])]");
 
1034
  traceEvent(TRACE_INFO, "    %s\n",   "[-u <userid> | <username> (see man page)]");
 
1035
  traceEvent(TRACE_INFO, "    %s\n",   "[-U <mapper.pl URL> | \"\" for not displaying host location ]");  
 
1036
  traceEvent(TRACE_INFO, "    %s\n",   "[-k <show kernel filter expression in extra frame>]");
 
1037
#ifndef WIN32
 
1038
  traceEvent(TRACE_INFO, "    %s\n",   "[-K <enable application debug (no fork() is used)>]");
 
1039
  traceEvent(TRACE_INFO, "    %s\n",   "[-L <use syslog instead of stdout>]");
 
1040
#endif
 
1041
  traceEvent(TRACE_INFO, "    %s\n\n", "[ <filter expression (like tcpdump)>]");
 
1042
}
 
1043
 
 
1044
/* ******************************************* */
 
1045
 
 
1046
void* handleWebConnections(void* notUsed _UNUSED_) {
 
1047
#ifndef MULTITHREADED
 
1048
  struct timeval wait_time;
 
1049
#else
 
1050
  int rc;
 
1051
#endif
 
1052
  fd_set mask, mask_copy;
 
1053
  int topSock = sock;
 
1054
 
 
1055
  FD_ZERO(&mask);
 
1056
 
 
1057
  if(webPort > 0) 
 
1058
    FD_SET((unsigned int)sock, &mask);
 
1059
 
 
1060
#ifdef HAVE_OPENSSL
 
1061
  if(sslInitialized) {
 
1062
    FD_SET(sock_ssl, &mask);
 
1063
    if(sock_ssl > topSock)
 
1064
      topSock = sock_ssl;
 
1065
  }
 
1066
#endif
 
1067
 
 
1068
  memcpy(&mask_copy, &mask, sizeof(fd_set));
 
1069
 
 
1070
#ifndef MULTITHREADED
 
1071
  /* select returns immediately */
 
1072
  wait_time.tv_sec = 0, wait_time.tv_usec = 0;
 
1073
  if(select(topSock+1, &mask, 0, 0, &wait_time) == 1)
 
1074
    handleSingleWebConnection(&mask);
 
1075
#else /* MULTITHREADED */
 
1076
  while(capturePackets) {
 
1077
#ifdef DEBUG
 
1078
    traceEvent(TRACE_INFO, "Select(ing) %d....", topSock);
 
1079
#endif
 
1080
    memcpy(&mask, &mask_copy, sizeof(fd_set));
 
1081
    rc = select(topSock+1, &mask, 0, 0, NULL /* Infinite */);
 
1082
#ifdef DEBUG
 
1083
    traceEvent(TRACE_INFO, "select returned: %d\n", rc);
 
1084
#endif
 
1085
    if(rc > 0)
 
1086
      handleSingleWebConnection(&mask);
 
1087
  }
 
1088
 
 
1089
  traceEvent(TRACE_INFO, "Terminating Web connections...");
 
1090
#endif
 
1091
 
 
1092
  return(NULL);
 
1093
}
 
1094
 
 
1095
/* ************************************* */
 
1096
 
 
1097
void handleSingleWebConnection(fd_set *fdmask) {
 
1098
  struct sockaddr_in from;
 
1099
  int from_len = sizeof(from);
 
1100
 
 
1101
  errno = 0;
 
1102
 
 
1103
  if(FD_ISSET(sock, fdmask)) {
 
1104
#ifdef DEBUG
 
1105
    traceEvent(TRACE_INFO, "Accepting HTTP request...\n");
 
1106
#endif
 
1107
    newSock = accept(sock, (struct sockaddr*)&from, &from_len);
 
1108
  } else {
 
1109
#ifdef DEBUG
 
1110
#ifdef HAVE_OPENSSL
 
1111
    if(sslInitialized)
 
1112
      traceEvent(TRACE_INFO, "Accepting HTTPS request...\n");
 
1113
#endif
 
1114
#endif
 
1115
#ifdef HAVE_OPENSSL
 
1116
    if(sslInitialized)
 
1117
      newSock = accept(sock_ssl, (struct sockaddr*)&from, &from_len); 
 
1118
#else
 
1119
    ;
 
1120
#endif
 
1121
  }
 
1122
 
 
1123
#ifdef DEBUG
 
1124
  traceEvent(TRACE_INFO, "Request accepted (sock=%d) (errno=%d)\n", newSock, errno);
 
1125
#endif
 
1126
 
 
1127
  if(newSock > 0) {
 
1128
#ifdef HAVE_OPENSSL
 
1129
    if(sslInitialized) 
 
1130
      if(FD_ISSET(sock_ssl, fdmask)) {
 
1131
        if(accept_ssl_connection(newSock) == -1) {
 
1132
          traceEvent(TRACE_WARNING, "Unable to accept SSL connection\n");
 
1133
          closeNwSocket(&newSock);
 
1134
          return;
 
1135
        } else {
 
1136
          newSock = -newSock;
 
1137
        }
 
1138
      }
 
1139
#endif /* HAVE_OPENSSL */
 
1140
 
 
1141
#ifdef HAVE_LIBWRAP
 
1142
    {
 
1143
      struct request_info req;
 
1144
      request_init(&req, RQ_DAEMON, DAEMONNAME, RQ_FILE, newSock, NULL);
 
1145
      fromhost(&req);
 
1146
      if (!hosts_access(&req)) {
 
1147
        closelog(); /* just in case */
 
1148
        openlog(DAEMONNAME,LOG_PID,SYSLOG_FACILITY);
 
1149
        syslog(deny_severity, "refused connect from %s", eval_client(&req));
 
1150
      }
 
1151
      else
 
1152
        handleHTTPrequest(from.sin_addr);
 
1153
    }
 
1154
#else
 
1155
    handleHTTPrequest(from.sin_addr);
 
1156
#endif /* HAVE_LIBWRAP */
 
1157
 
 
1158
    closeNwSocket(&newSock);
 
1159
  } else {
 
1160
    traceEvent(TRACE_INFO, "Unable to accept HTTP(S) request (errno=%d)", errno);
 
1161
  }
 
1162
}
 
1163
 
 
1164
/* ******************* */
 
1165
 
 
1166
int handlePluginHTTPRequest(char* url) {
 
1167
  FlowFilterList *flows = flowsList;
 
1168
 
 
1169
  while(flows != NULL)
 
1170
    if((flows->pluginStatus.pluginPtr != NULL)
 
1171
       && (flows->pluginStatus.pluginPtr->pluginURLname != NULL)
 
1172
       && (flows->pluginStatus.pluginPtr->httpFunct != NULL)
 
1173
       && (strncmp(flows->pluginStatus.pluginPtr->pluginURLname,
 
1174
                   url, strlen(flows->pluginStatus.pluginPtr->pluginURLname)) == 0)) {
 
1175
      char *arg;
 
1176
 
 
1177
      /* Courtesy of Roberto F. De Luca <deluca@tandar.cnea.gov.ar> */
 
1178
      if(!flows->pluginStatus.activePlugin) {
 
1179
        char buf[BUF_SIZE], name[32];
 
1180
 
 
1181
        sendHTTPHeader(HTTP_TYPE_HTML, 0);
 
1182
        strncpy(name, flows->pluginStatus.pluginPtr->pluginURLname, sizeof(name));
 
1183
        name[sizeof(name)-1] = '\0'; /* just in case pluginURLname is too long... */
 
1184
        if((strlen(name) > 6) && (strcasecmp(&name[strlen(name)-6], "plugin") == 0))
 
1185
          name[strlen(name)-6] = '\0';
 
1186
        if(snprintf(buf, sizeof(buf),"Status for the \"%s\" Plugin", name) < 0) 
 
1187
          traceEvent(TRACE_ERROR, "Buffer overflow!");
 
1188
        printHTMLheader(buf, HTML_FLAG_NO_REFRESH);
 
1189
        printFlagedWarning("<I>This plugin is currently inactive.</I>");
 
1190
        printHTMLtrailer();
 
1191
        return(1);
 
1192
      }
 
1193
 
 
1194
      if(strlen(url) == strlen(flows->pluginStatus.pluginPtr->pluginURLname))
 
1195
        arg = "";
 
1196
      else
 
1197
        arg = &url[strlen(flows->pluginStatus.pluginPtr->pluginURLname)+1];
 
1198
 
 
1199
      /* traceEvent(TRACE_INFO, "Found %s [%s]\n", 
 
1200
         flows->pluginStatus.pluginPtr->pluginURLname, arg); */
 
1201
      flows->pluginStatus.pluginPtr->httpFunct(arg);
 
1202
      return(1);
 
1203
    } else
 
1204
      flows = flows->next;
 
1205
 
 
1206
  return(0); /* Plugin not found */
 
1207
}