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.
25
#define STATIC_PLUGIN /* This needs to be fixed */
31
extern PluginInfo* icmpPluginEntryFctn(void);
32
extern PluginInfo* nfsPluginEntryFctn(void);
33
extern PluginInfo* wapPluginEntryFctn(void);
35
extern PluginInfo* rmonPluginEntryFctn(void);
41
#define RTLD_NOW RTLD_LAZY
43
#define RTLD_NOW 1 /* MacOS X Patch */
47
/* ******************* */
51
static char* dlerror() {
53
static char tmpStr[256];
55
if(loadquery(L_GETMESSAGES, &errMsg, 768) != -1) {
59
for(i=0; errMsg[i] != NULL; i++){
60
errCode=atoi(errMsg[i]);
63
for(j=1; errMsg[i][j] != '\0'; j++)
64
if(errMsg[i][j] != ' ') {
65
errName = &errMsg[i][j];
72
return("Too many errors, rest skipped");
75
if(snprintf(tmpStr, sizeof(tmpStr), "Can't load library [%s]", errName) < 0)
76
traceEvent(TRACE_ERROR, "Buffer overflow!");
79
if(snprintf(tmpStr, sizeof(tmpStr), "Can't find symbol in library [%s]", errName) < 0)
80
traceEvent(TRACE_ERROR, "Buffer overflow!");
83
return("Rld data offset or symbol index out of range or bad relocation type");
86
if(snprintf(tmpStr, sizeof(tmpStr), "File not valid, executable xcoff [%s]", errName) < 0)
87
traceEvent(TRACE_ERROR, "Buffer overflow!");
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!");
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!");
103
if(snprintf(tmpStr, sizeof(tmpStr), "Symbol type mismatch [%s]", errName) < 0)
104
traceEvent(TRACE_ERROR, "Buffer overflow!");
108
return("Text alignment in file is wrong");
111
return("Insufficient permission to create a loader domain");
114
return("Insufficient permission to add entries to a loader domain");
117
if(snprintf(tmpStr, sizeof(tmpStr), "Unknown error [%d]", errCode) < 0)
118
traceEvent(TRACE_ERROR, "Buffer overflow!");
127
/* ******************* */
129
void notifyPluginsHashResize(int oldSize, int newSize, int* mappings) {
130
FlowFilterList *flows = flowsList;
133
if((flows->pluginStatus.pluginPtr != NULL)
134
&& (flows->pluginStatus.activePlugin)
135
&& (flows->pluginStatus.pluginPtr->resizeFunct != NULL))
136
flows->pluginStatus.pluginPtr->resizeFunct(oldSize, newSize, mappings);
141
/* ******************* */
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];
150
#ifdef HPUX /* Courtesy Rusetsky Dmitry <dimania@mail.ru> */
158
void *pluginEntryFctnPtr;
160
PluginInfo* pluginInfo;
164
PluginInfo* (*pluginJumpFunc)();
166
FlowFilterList *newFlow;
168
if(snprintf(pluginPath, sizeof(pluginPath), "%s/%s", dirName, pluginName) < 0)
169
traceEvent(TRACE_ERROR, "Buffer overflow!");
172
traceEvent(TRACE_INFO, "Loading plugin '%s'...", pluginPath);
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);
181
pluginPtr = load(pluginName, 1, dirName); /* Load the library */
183
pluginPtr = dlopen(pluginPath, RTLD_NOW /* RTLD_LAZY */); /* Load the library */
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));
193
traceEvent(TRACE_WARNING,
194
"WARNING: unable to load plugin '%s'\n[%s]\n",
195
pluginPath, dlerror());
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;
206
pluginEntryFctnPtr = pluginPtr;
208
pluginEntryFctnPtr = dlsym(pluginPtr, PLUGIN_ENTRY_FCTN_NAME);
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));
218
traceEvent(TRACE_WARNING, "WARNING: unable to local plugin '%s' entry function [%li]\n",
219
pluginPath, GetLastError());
221
traceEvent(TRACE_WARNING, "WARNING: unable to local plugin '%s' entry function [%s]\n",
222
pluginPath, dlerror());
228
pluginJumpFunc = (PluginInfo*(*)())pluginEntryFctnPtr;
229
pluginInfo = pluginJumpFunc();
230
#else /* STATIC_PLUGIN */
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();
239
else if(strcmp(pluginName, "ntopRmon") == 0)
240
pluginInfo = rmonPluginEntryFctn();
245
#endif /* STATIC_PLUGIN */
247
if(pluginInfo == NULL) {
248
traceEvent(TRACE_WARNING, "WARNING: %s call of plugin '%s' failed.\n",
249
PLUGIN_ENTRY_FCTN_NAME, pluginPath);
253
newFlow = (FlowFilterList*)calloc(1, sizeof(FlowFilterList));
255
if(newFlow == NULL) {
256
traceEvent(TRACE_ERROR, "Fatal error: not enough memory. Bye!\n");
259
newFlow->fcode = (struct bpf_program*)calloc(numDevices, sizeof(struct bpf_program));
260
newFlow->flowName = strdup(pluginInfo->pluginName);
262
if((pluginInfo->bpfFilter == NULL)
263
|| (pluginInfo->bpfFilter[0] == '\0')) {
265
traceEvent(TRACE_WARNING, "WARNING: plugin '%s' has an empty BPF filter.\n",
268
for(i=0; i<numDevices; i++)
269
newFlow->fcode[i].bf_insns = NULL;
271
strncpy(tmpBuf, pluginInfo->bpfFilter, sizeof(tmpBuf));
272
tmpBuf[sizeof(tmpBuf)-1] = '\0'; /* just in case bpfFilter is too long... */
274
for(i=0; i<numDevices; i++)
275
if(!device[i].virtualDevice) {
277
traceEvent(TRACE_INFO, "Compiling filter '%s' on device %s\n",
278
tmpBuf, device[i].name);
280
rc = pcap_compile(device[i].pcapPtr,
281
&newFlow->fcode[i], tmpBuf, 1,
282
device[i].netmask.s_addr);
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",
290
pluginInfo->bpfFilter,
292
pcap_geterr((device[i].pcapPtr)));
299
newFlow->pluginStatus.pluginPtr = pluginInfo;
300
newFlow->pluginStatus.activePlugin = pluginInfo->activeByDefault;
301
newFlow->next = flowsList;
303
/* traceEvent(TRACE_INFO, "Adding: %s\n", pluginInfo->pluginName); */
307
traceEvent(TRACE_INFO, "Plugin '%s' loaded succesfully.\n", pluginPath);
311
/* ******************* */
313
void loadPlugins(void) {
318
DIR* directoryPointer=NULL;
321
traceEvent(TRACE_INFO, "Loading plugins (if any)...\n");
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!");
328
directoryPointer = opendir(dirPath);
330
if(directoryPointer != NULL)
334
if(directoryPointer == NULL) {
335
traceEvent(TRACE_WARNING,
336
"WARNING: Unable to find the plugins/ directory.\n");
339
traceEvent(TRACE_INFO, "Searching plugins in %s\n", dirPath);
341
while((dp = readdir(directoryPointer)) != NULL) {
342
if(dp->d_name[0] == '.')
344
else if(strlen(dp->d_name) < strlen(PLUGIN_EXTENSION))
346
else if(strcmp(&dp->d_name[strlen(dp->d_name)-strlen(PLUGIN_EXTENSION)],
350
loadPlugin(dirPath, dp->d_name);
353
closedir(directoryPointer);
354
#else /* STATIC_PLUGIN */
355
loadPlugin(NULL, "icmpPlugin");
356
loadPlugin(NULL, "nfsPlugin");
357
/* loadPlugin(NULL, "wapPlugin"); */
359
loadPlugin(NULL, "rmonPlugin");
361
#endif /* STATIC_PLUGIN */
364
/* ******************* */
366
void unloadPlugins(void) {
367
FlowFilterList *flows = flowsList;
369
traceEvent(TRACE_INFO, "Unloading plugins (if any)...\n");
371
while(flows != NULL) {
372
if(flows->pluginStatus.pluginPtr != NULL) {
374
traceEvent(TRACE_INFO, "Unloading plugin '%s'...\n",
375
flows->pluginStatus.pluginPtr->pluginName);
377
if(flows->pluginStatus.pluginPtr->termFunc != NULL)
378
flows->pluginStatus.pluginPtr->termFunc();
380
#ifdef HPUX /* Courtesy Rusetsky Dmitry <dimania@mail.ru> */
381
shl_unload((shl_t)flows->pluginStatus.pluginPtr);
384
FreeLibrary((HANDLE)flows->pluginStatus.pluginPtr);
387
unload(flows->pluginStatus.pluginPtr);
389
dlclose(flows->pluginStatus.pluginPtr);
393
flows->pluginStatus.pluginPtr = NULL;
399
#endif /* defined(HAVE_DIRENT_H) && defined(HAVE_DLFCN_H) */
401
/* ******************************* */
403
/* Courtesy of Andreas Pfaller <a.pfaller@pop.gun.de>. */
405
void startPlugins(void) {
406
FlowFilterList *flows = flowsList;
408
traceEvent(TRACE_INFO, "Initializing plugins (if any)...\n");
410
while(flows != NULL) {
411
if(flows->pluginStatus.pluginPtr != NULL) {
413
traceEvent(TRACE_INFO, "Starting plugin '%s'...\n",
414
flows->pluginStatus.pluginPtr->pluginName);
416
if(flows->pluginStatus.pluginPtr->startFunc != NULL)
417
flows->pluginStatus.pluginPtr->startFunc();
423
/* ************************************* */
425
#endif /* MICRO_NTOP */