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

« back to all changes in this revision

Viewing changes to ntop/plugin.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
 
 
24
#if defined(WIN32)
 
25
#define STATIC_PLUGIN /* This needs to be fixed */
 
26
#else
 
27
#define RMON_SUPPORT
 
28
#endif
 
29
 
 
30
#ifdef STATIC_PLUGIN
 
31
extern PluginInfo* icmpPluginEntryFctn(void);
 
32
extern PluginInfo* nfsPluginEntryFctn(void);
 
33
extern PluginInfo* wapPluginEntryFctn(void);
 
34
#ifdef RMON_SUPPORT
 
35
extern PluginInfo* rmonPluginEntryFctn(void);
 
36
#endif
 
37
#endif
 
38
 
 
39
#ifndef RTLD_NOW 
 
40
#ifdef RTLD_LAZY
 
41
#define RTLD_NOW RTLD_LAZY 
 
42
#else
 
43
#define RTLD_NOW 1 /* MacOS X Patch */
 
44
#endif
 
45
#endif
 
46
 
 
47
/* ******************* */
 
48
 
 
49
#ifdef AIX
 
50
 
 
51
static char* dlerror() {
 
52
  char *errMsg[768];
 
53
  static char tmpStr[256];
 
54
 
 
55
  if(loadquery(L_GETMESSAGES, &errMsg, 768) != -1) {
 
56
    int i, j, errCode;
 
57
    char* errName;
 
58
 
 
59
    for(i=0; errMsg[i] != NULL; i++){
 
60
      errCode=atoi(errMsg[i]);
 
61
      errName = "";
 
62
          
 
63
      for(j=1; errMsg[i][j] != '\0'; j++)
 
64
        if(errMsg[i][j] != ' ') {
 
65
          errName = &errMsg[i][j];
 
66
          break;
 
67
        }
 
68
          
 
69
      switch(errCode) {
 
70
        /* sys/ldr.h */
 
71
      case 1:
 
72
        return("Too many errors, rest skipped");
 
73
        break;
 
74
      case 2:
 
75
        if(snprintf(tmpStr, sizeof(tmpStr), "Can't load library [%s]", errName) < 0) 
 
76
          traceEvent(TRACE_ERROR, "Buffer overflow!");
 
77
        break;
 
78
      case 3:
 
79
        if(snprintf(tmpStr, sizeof(tmpStr), "Can't find symbol in library [%s]", errName) < 0) 
 
80
          traceEvent(TRACE_ERROR, "Buffer overflow!");
 
81
        break;
 
82
      case 4:
 
83
        return("Rld data offset or symbol index out of range or bad relocation type");
 
84
        break;
 
85
      case 5:
 
86
        if(snprintf(tmpStr, sizeof(tmpStr), "File not valid, executable xcoff [%s]", errName) < 0)
 
87
          traceEvent(TRACE_ERROR, "Buffer overflow!");
 
88
        return(tmpStr);
 
89
        break;
 
90
      case 6:
 
91
        if(snprintf(tmpStr, sizeof(tmpStr), "The errno associated with the failure if not ENOEXEC,"
 
92
                " it indicates the underlying error, such as no memory [%s][errno=%d]", 
 
93
                errName, errno) < 0) traceEvent(TRACE_ERROR, "Buffer overflow!");
 
94
        return(tmpStr);
 
95
        break;
 
96
      case 7:
 
97
        if(snprintf(tmpStr, sizeof(tmpStr), 
 
98
                    "Member requested from a file which is not an archive or does not"
 
99
                    "contain the member [%s]", errName) < 0) traceEvent(TRACE_ERROR, "Buffer overflow!");
 
100
        return(tmpStr);
 
101
        break;
 
102
      case 8:
 
103
        if(snprintf(tmpStr, sizeof(tmpStr), "Symbol type mismatch [%s]", errName) < 0)
 
104
          traceEvent(TRACE_ERROR, "Buffer overflow!");
 
105
        return(tmpStr);
 
106
        break;
 
107
      case 9:
 
108
        return("Text alignment in file is wrong");
 
109
        break;
 
110
      case 10:
 
111
        return("Insufficient permission to create a loader domain");
 
112
        break;
 
113
      case 11:
 
114
        return("Insufficient permission to add entries to a loader domain");
 
115
        break;
 
116
      default:
 
117
        if(snprintf(tmpStr, sizeof(tmpStr), "Unknown error [%d]", errCode) < 0) 
 
118
          traceEvent(TRACE_ERROR, "Buffer overflow!");
 
119
        return(tmpStr);
 
120
      }
 
121
    }
 
122
  }
 
123
}
 
124
 
 
125
#endif /* AIX */
 
126
 
 
127
/* ******************* */
 
128
 
 
129
void notifyPluginsHashResize(int oldSize, int newSize, int* mappings) {
 
130
  FlowFilterList *flows = flowsList;
 
131
 
 
132
  while(flows != NULL)
 
133
    if((flows->pluginStatus.pluginPtr != NULL)
 
134
       && (flows->pluginStatus.activePlugin)
 
135
       && (flows->pluginStatus.pluginPtr->resizeFunct != NULL))
 
136
      flows->pluginStatus.pluginPtr->resizeFunct(oldSize, newSize, mappings);
 
137
    else
 
138
      flows = flows->next;
 
139
}
 
140
 
 
141
/* ******************* */
 
142
 
 
143
#ifndef MICRO_NTOP
 
144
 
 
145
#if (defined(HAVE_DIRENT_H) && defined(HAVE_DLFCN_H)) || defined(WIN32) || defined(DARWIN)
 
146
static void loadPlugin(char* dirName, char* pluginName) {
 
147
  char pluginPath[256];
 
148
  char tmpBuf[BUF_SIZE];
 
149
  int i;
 
150
#ifdef HPUX /* Courtesy Rusetsky Dmitry <dimania@mail.ru> */
 
151
  shl_t pluginPtr;
 
152
#else
 
153
#ifndef WIN32
 
154
  void *pluginPtr;
 
155
#endif
 
156
#endif
 
157
#ifndef WIN32
 
158
  void *pluginEntryFctnPtr;
 
159
#endif
 
160
  PluginInfo* pluginInfo;
 
161
  
 
162
  int rc;
 
163
#ifndef WIN32
 
164
  PluginInfo* (*pluginJumpFunc)();
 
165
#endif
 
166
  FlowFilterList *newFlow;
 
167
 
 
168
  if(snprintf(pluginPath, sizeof(pluginPath), "%s/%s", dirName, pluginName) < 0)
 
169
    traceEvent(TRACE_ERROR, "Buffer overflow!");
 
170
 
 
171
#ifdef DEBUG
 
172
  traceEvent(TRACE_INFO, "Loading plugin '%s'...", pluginPath);
 
173
#endif
 
174
 
 
175
#ifndef STATIC_PLUGIN
 
176
#ifdef HPUX /* Courtesy Rusetsky Dmitry <dimania@mail.ru> */
 
177
  /* Load the library */
 
178
  pluginPtr = shl_load(pluginPath, BIND_IMMEDIATE|BIND_VERBOSE|BIND_NOSTART ,0L);
 
179
#else
 
180
#ifdef AIX
 
181
  pluginPtr = load(pluginName, 1, dirName); /* Load the library */
 
182
#else
 
183
  pluginPtr = dlopen(pluginPath, RTLD_NOW /* RTLD_LAZY */); /* Load the library */
 
184
#endif /* AIX */
 
185
#endif /* HPUX  */
 
186
 
 
187
  if(pluginPtr == NULL) {
 
188
#if HPUX /* Courtesy Rusetsky Dmitry <dimania@mail.ru> */
 
189
    traceEvent(TRACE_WARNING, 
 
190
               "WARNING: unable to load plugin '%s'\n[%s]\n", 
 
191
               pluginPath, strerror(errno));
 
192
#else
 
193
    traceEvent(TRACE_WARNING, 
 
194
               "WARNING: unable to load plugin '%s'\n[%s]\n", 
 
195
               pluginPath, dlerror());
 
196
#endif /* HPUX */
 
197
    return;
 
198
  }
 
199
 
 
200
#ifdef HPUX /* Courtesy Rusetsky Dmitry <dimania@mail.ru> */
 
201
  if(shl_findsym(&pluginPtr ,PLUGIN_ENTRY_FCTN_NAME,
 
202
                 TYPE_PROCEDURE, &pluginEntryFctnPtr) == -1)
 
203
    pluginEntryFctnPtr = NULL;
 
204
#else
 
205
#ifdef AIX
 
206
  pluginEntryFctnPtr = pluginPtr;
 
207
#else
 
208
  pluginEntryFctnPtr = dlsym(pluginPtr, PLUGIN_ENTRY_FCTN_NAME);
 
209
#endif /* AIX */
 
210
#endif /* HPUX */
 
211
 
 
212
  if(pluginEntryFctnPtr == NULL) {
 
213
#ifdef HPUX /* Courtesy Rusetsky Dmitry <dimania@mail.ru> */
 
214
    traceEvent(TRACE_WARNING, "\nWARNING: unable to local plugin '%s' entry function [%s] \n",
 
215
               pluginPath, strerror(errno));
 
216
#else
 
217
#ifdef WIN32
 
218
    traceEvent(TRACE_WARNING, "WARNING: unable to local plugin '%s' entry function [%li]\n", 
 
219
               pluginPath, GetLastError());
 
220
#else
 
221
    traceEvent(TRACE_WARNING, "WARNING: unable to local plugin '%s' entry function [%s]\n",
 
222
               pluginPath, dlerror());
 
223
#endif /* WIN32 */
 
224
#endif /* HPUX */
 
225
    return;
 
226
  }
 
227
 
 
228
  pluginJumpFunc = (PluginInfo*(*)())pluginEntryFctnPtr;
 
229
  pluginInfo = pluginJumpFunc();
 
230
#else /* STATIC_PLUGIN */
 
231
 
 
232
  if(strcmp(pluginName, "icmpPlugin") == 0)
 
233
    pluginInfo = icmpPluginEntryFctn();
 
234
  else if(strcmp(pluginName, "nfsPlugin") == 0)
 
235
    pluginInfo = nfsPluginEntryFctn();
 
236
  else if(strcmp(pluginName, "wapPlugin") == 0)
 
237
    pluginInfo = wapPluginEntryFctn();
 
238
#ifdef RMON_SUPPORT
 
239
  else if(strcmp(pluginName, "ntopRmon") == 0)
 
240
    pluginInfo = rmonPluginEntryFctn();
 
241
#endif
 
242
  else
 
243
    pluginInfo = NULL;
 
244
 
 
245
#endif /* STATIC_PLUGIN */
 
246
 
 
247
  if(pluginInfo == NULL) {
 
248
    traceEvent(TRACE_WARNING, "WARNING: %s call of plugin '%s' failed.\n",
 
249
               PLUGIN_ENTRY_FCTN_NAME, pluginPath);
 
250
    return;
 
251
  }
 
252
 
 
253
  newFlow = (FlowFilterList*)calloc(1, sizeof(FlowFilterList));
 
254
  
 
255
  if(newFlow == NULL) {
 
256
    traceEvent(TRACE_ERROR, "Fatal error: not enough memory. Bye!\n");
 
257
    exit(-1);
 
258
  } else {
 
259
    newFlow->fcode = (struct bpf_program*)calloc(numDevices, sizeof(struct bpf_program));
 
260
    newFlow->flowName = strdup(pluginInfo->pluginName);
 
261
 
 
262
    if((pluginInfo->bpfFilter == NULL)
 
263
       || (pluginInfo->bpfFilter[0] == '\0')) {
 
264
      /*
 
265
        traceEvent(TRACE_WARNING, "WARNING: plugin '%s' has an empty BPF filter.\n",
 
266
        pluginPath);
 
267
      */
 
268
      for(i=0; i<numDevices; i++)
 
269
        newFlow->fcode[i].bf_insns = NULL;
 
270
    } else {
 
271
      strncpy(tmpBuf, pluginInfo->bpfFilter, sizeof(tmpBuf));
 
272
      tmpBuf[sizeof(tmpBuf)-1] = '\0'; /* just in case bpfFilter is too long... */
 
273
 
 
274
      for(i=0; i<numDevices; i++) 
 
275
        if(!device[i].virtualDevice) {
 
276
#ifdef DEBUG
 
277
          traceEvent(TRACE_INFO, "Compiling filter '%s' on device %s\n", 
 
278
                     tmpBuf, device[i].name);
 
279
#endif
 
280
          rc = pcap_compile(device[i].pcapPtr, 
 
281
                            &newFlow->fcode[i], tmpBuf, 1, 
 
282
                            device[i].netmask.s_addr);
 
283
      
 
284
          if(rc < 0) {
 
285
            traceEvent(TRACE_INFO, 
 
286
                       "WARNING: plugin '%s' contains a wrong filter specification\n"
 
287
                       "         \"%s\" on interface %s (%s).\n"
 
288
                       "         This plugin has been discarded.\n",
 
289
                       pluginPath, 
 
290
                       pluginInfo->bpfFilter, 
 
291
                       device[i].name,
 
292
                       pcap_geterr((device[i].pcapPtr)));
 
293
            free(newFlow);
 
294
            return;
 
295
          }
 
296
        }
 
297
    }
 
298
 
 
299
    newFlow->pluginStatus.pluginPtr  = pluginInfo;
 
300
    newFlow->pluginStatus.activePlugin = pluginInfo->activeByDefault;
 
301
    newFlow->next = flowsList;
 
302
    flowsList = newFlow;
 
303
    /* traceEvent(TRACE_INFO, "Adding: %s\n", pluginInfo->pluginName); */
 
304
  }
 
305
 
 
306
#ifdef DEBUG
 
307
  traceEvent(TRACE_INFO, "Plugin '%s' loaded succesfully.\n", pluginPath);
 
308
#endif
 
309
}
 
310
 
 
311
/* ******************* */
 
312
 
 
313
void loadPlugins(void) {
 
314
#ifndef WIN32
 
315
  char dirPath[256];
 
316
  struct dirent* dp;
 
317
  int idx;
 
318
  DIR* directoryPointer=NULL;
 
319
#endif
 
320
  
 
321
  traceEvent(TRACE_INFO, "Loading plugins (if any)...\n");
 
322
  
 
323
#ifndef STATIC_PLUGIN
 
324
  for(idx=0; pluginDirs[idx] != NULL; idx++) {
 
325
    if(snprintf(dirPath, sizeof(dirPath), "%s", pluginDirs[idx]) < 0) 
 
326
      traceEvent(TRACE_ERROR, "Buffer overflow!");
 
327
 
 
328
    directoryPointer = opendir(dirPath);
 
329
 
 
330
    if(directoryPointer != NULL)
 
331
      break;
 
332
  }
 
333
 
 
334
  if(directoryPointer == NULL) {
 
335
    traceEvent(TRACE_WARNING, 
 
336
               "WARNING: Unable to find the plugins/ directory.\n");
 
337
    return;
 
338
  } else
 
339
    traceEvent(TRACE_INFO, "Searching plugins in %s\n", dirPath);
 
340
 
 
341
  while((dp = readdir(directoryPointer)) != NULL) {
 
342
    if(dp->d_name[0] == '.')
 
343
      continue;
 
344
    else if(strlen(dp->d_name) < strlen(PLUGIN_EXTENSION))
 
345
      continue;
 
346
    else if(strcmp(&dp->d_name[strlen(dp->d_name)-strlen(PLUGIN_EXTENSION)],
 
347
                   PLUGIN_EXTENSION))
 
348
      continue;
 
349
    
 
350
    loadPlugin(dirPath, dp->d_name);
 
351
  }
 
352
 
 
353
  closedir(directoryPointer);
 
354
#else /* STATIC_PLUGIN */
 
355
  loadPlugin(NULL, "icmpPlugin");
 
356
  loadPlugin(NULL, "nfsPlugin");
 
357
  /* loadPlugin(NULL, "wapPlugin"); */
 
358
#ifdef RMON_SUPPORT
 
359
  loadPlugin(NULL, "rmonPlugin");
 
360
#endif
 
361
#endif /* STATIC_PLUGIN */
 
362
}
 
363
 
 
364
/* ******************* */
 
365
 
 
366
void unloadPlugins(void) {
 
367
  FlowFilterList *flows = flowsList;
 
368
 
 
369
  traceEvent(TRACE_INFO, "Unloading plugins (if any)...\n");
 
370
 
 
371
  while(flows != NULL) {
 
372
    if(flows->pluginStatus.pluginPtr != NULL) {
 
373
#ifdef DEBUG
 
374
      traceEvent(TRACE_INFO, "Unloading plugin '%s'...\n",
 
375
                 flows->pluginStatus.pluginPtr->pluginName);
 
376
#endif
 
377
      if(flows->pluginStatus.pluginPtr->termFunc != NULL)
 
378
        flows->pluginStatus.pluginPtr->termFunc();
 
379
 
 
380
#ifdef HPUX /* Courtesy Rusetsky Dmitry <dimania@mail.ru> */
 
381
      shl_unload((shl_t)flows->pluginStatus.pluginPtr);
 
382
#else
 
383
#ifdef WIN32
 
384
      FreeLibrary((HANDLE)flows->pluginStatus.pluginPtr);
 
385
#else
 
386
#ifdef AIX
 
387
      unload(flows->pluginStatus.pluginPtr);
 
388
#else
 
389
      dlclose(flows->pluginStatus.pluginPtr);
 
390
#endif /* AIX */
 
391
#endif /* WIN32 */
 
392
#endif /* HPUX */
 
393
      flows->pluginStatus.pluginPtr = NULL;
 
394
    }
 
395
    flows = flows->next;
 
396
  }
 
397
}
 
398
 
 
399
#endif /* defined(HAVE_DIRENT_H) && defined(HAVE_DLFCN_H) */
 
400
 
 
401
/* ******************************* */
 
402
 
 
403
/* Courtesy of Andreas Pfaller <a.pfaller@pop.gun.de>. */
 
404
 
 
405
void startPlugins(void) {
 
406
  FlowFilterList *flows = flowsList;
 
407
 
 
408
  traceEvent(TRACE_INFO, "Initializing plugins (if any)...\n");
 
409
 
 
410
  while(flows != NULL) {
 
411
    if(flows->pluginStatus.pluginPtr != NULL) {
 
412
#ifdef DEBUG
 
413
      traceEvent(TRACE_INFO, "Starting plugin '%s'...\n",
 
414
                 flows->pluginStatus.pluginPtr->pluginName);
 
415
#endif
 
416
      if(flows->pluginStatus.pluginPtr->startFunc != NULL)
 
417
        flows->pluginStatus.pluginPtr->startFunc();
 
418
    }
 
419
    flows = flows->next;
 
420
  }
 
421
}
 
422
 
 
423
/* ************************************* */
 
424
 
 
425
#endif /* MICRO_NTOP */
 
426