3
* Copyright (C) 2006-07 Luca Deri <deri@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
#include "globals-report.h"
26
static int initRemoteFunct(void);
27
static void termRemoteFunct(u_char termNtop);
28
static void handleRemoteHTTPrequest(char* url);
32
static pthread_t remoteThread;
34
/* ****************************** */
36
static PluginInfo RemotepluginInfo[] = {
38
VERSION, /* current ntop version */
40
"This plugin allows remote applications to access ntop data",
42
"<a class=mailto href=\"mailto:deri@ntop.org\">L. Deri</A>",
43
"Remoteplugin", /* http://<host>:<port>/plugins/Remoteplugin */
44
0, /* Active by default */
46
0, /* Inactive setup */
47
initRemoteFunct, /* InitFunc */
48
termRemoteFunct, /* TermFunc */
49
NULL, /* PluginFunc */
50
handleRemoteHTTPrequest, /* http request handler */
51
NULL, /* no host creation/deletion handle */
52
NULL, /* BPF Filter */
54
NULL /* no extra pages */
58
/* ****************************** */
59
/* Plugin entry fctn */
60
#ifdef MAKE_STATIC_PLUGIN
61
PluginInfo* remotePluginEntryFctn(void)
63
PluginInfo* PluginEntryFctn(void)
66
traceEvent(CONST_TRACE_ALWAYSDISPLAY,
67
"Remote: Welcome to %s. (C) 2006-07 by L.Deri",
68
RemotepluginInfo->pluginName);
70
return(RemotepluginInfo);
73
/* ****************************** */
75
static void* remoteMainLoop(void* notUsed _UNUSED_) {
76
while(myGlobals.ntopRunState < FLAG_NTOPSTATE_SHUTDOWN) {
78
int rc, all_right = 1;
79
char buf[1500], rsp[1500];
82
FD_SET(sock, &remoteMask);
84
if((rc = select(sock+1, &remoteMask, NULL, NULL, NULL)) > 0) {
85
char *method = NULL, *reference = NULL, *strtokstate;
87
struct sockaddr_in from;
88
socklen_t fromlen = sizeof(from);
90
memset(buf, 0, sizeof(buf));
91
rc = recvfrom(sock, buf, sizeof(buf), 0, (struct sockaddr*)&from, &fromlen);
92
traceEvent(CONST_TRACE_INFO, "Received %d bytes [%s]", rc, buf);
94
method = strtok_r(buf, "\n;", &strtokstate);
96
if((reference = strtok_r(NULL, "\n;", &strtokstate))) {
97
traceEvent(CONST_TRACE_INFO, "-> '%s'", reference);
99
if(!strncmp(reference, "reference: 0x", 13)) {
100
reference += 13; /* Move to the reference pointer */
102
sscanf(reference, "%p", &ref);
103
traceEvent(CONST_TRACE_INFO, "---> '%p'", ref);
108
if(method && reference && all_right) {
109
if(!strncmp(method, "call: ", 6)) {
112
method += 6; /* Move to the method name */
114
traceEvent(CONST_TRACE_INFO, "Method '%s'", method);
116
if(!strncmp(method, "getFirstHost", strlen("getFirstHost"))) {
117
/* getFirstHost(device) */
118
method += 1+strlen("getFirstHost");
119
device = atoi(method);
121
if(device >= myGlobals.numDevices)
122
safe_snprintf(__FILE__, __LINE__, rsp, sizeof(rsp), "error: parameter out of range;\n");
124
HostTraffic *el = getFirstHost(device);
126
safe_snprintf(__FILE__, __LINE__, rsp, sizeof(rsp), "rsp: ok;\nreference: %p;\n", el);
128
} else if(!strncmp(method, "getNextHost", strlen("getNextHost"))) {
129
/* getNextHost(device) */
130
method += 1+strlen("getNextHost");
131
device = atoi(method);
133
if(device >= myGlobals.numDevices)
134
safe_snprintf(__FILE__, __LINE__, rsp, sizeof(rsp), "error: parameter out of range;\n");
135
else if((ref == NULL) || (!is_valid_ptr((void*)ref)))
136
safe_snprintf(__FILE__, __LINE__, rsp, sizeof(rsp), "error: invalid reference;\n");
138
HostTraffic *el = (HostTraffic*)ref, *next;
139
remove_valid_ptr(el);
140
next = getNextHost(device, el);
142
safe_snprintf(__FILE__, __LINE__, rsp, sizeof(rsp), "rsp: ok;\nreference: %p;\n", next);
144
} else if(!strncmp(method, "getHostAttribute", strlen("getHostAttribute"))) {
145
/* getHostAttribute(<attribute name>) */
147
if((ref == NULL) || (!is_valid_ptr((void*)ref)))
148
safe_snprintf(__FILE__, __LINE__, rsp, sizeof(rsp), "error: invalid reference;\n");
150
HostTraffic *el = (HostTraffic*)ref;
151
char *attr = method+1+strlen("getHostAttribute");
154
attr[strlen(attr)-1] = '\0';
156
if(!strcmp(attr, "ethAddress")) ret = el->ethAddressString;
157
else if(!strcmp(attr, "hostNumIpAddress")) ret = el->hostNumIpAddress;
160
safe_snprintf(__FILE__, __LINE__, rsp, sizeof(rsp), "rsp: ok;\nreference: %p;\nvalue: %s;\n", el, ret);
162
safe_snprintf(__FILE__, __LINE__, rsp, sizeof(rsp), "error: unknown host attribute;\n");
165
safe_snprintf(__FILE__, __LINE__, rsp, sizeof(rsp), "error: unknown method;\n");
168
safe_snprintf(__FILE__, __LINE__, rsp, sizeof(rsp), "error: invalid parameters format;\n");
170
rc = sendto(sock, rsp, strlen(rsp), 0, (struct sockaddr*)&from, fromlen);
171
traceEvent(CONST_TRACE_INFO, "Sent %d bytes [%s]", rc, rsp);
175
traceEvent(CONST_TRACE_INFO, "Remote plugin TERMLOOP");
180
/* ****************************** */
182
static int initRemoteFunct(void) {
184
struct sockaddr_in sockIn;
186
traceEvent(CONST_TRACE_INFO, "Welcome to the Remote plugin");
188
if((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
189
traceEvent(CONST_TRACE_ERROR, "REMOTE: unable to create UDP socket");
192
rc = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&sockopt, sizeof(sockopt));
194
memset(&sockIn, 0, sizeof(sockIn));
195
sockIn.sin_family = AF_INET;
196
sockIn.sin_port = (int)htons(myGlobals.runningPref.webPort);
197
sockIn.sin_addr.s_addr = INADDR_ANY;
200
rc = bind(sock, (struct sockaddr *)&sockIn, sizeof(sockIn));
202
if((rc < 0) || (errno != 0)) {
203
closeNwSocket(&myGlobals.sock);
204
traceEvent(CONST_TRACE_ERROR, "REMOTE: binding problem '%s'(%d), plugin disabled", strerror(errno), errno);
205
closeNwSocket(&sock);
209
traceEvent(CONST_TRACE_INFO, "Remote plugin listening on UDP port %d",
210
myGlobals.runningPref.webPort);
211
createThread(&remoteThread, remoteMainLoop, NULL);
217
/* ****************************** */
219
static void termRemoteFunct(u_char termNtop /* 0=term plugin, 1=term ntop */) {
220
if(remoteThread) killThread(&remoteThread);
221
if(sock != -1) closeNwSocket(&sock);
223
traceEvent(CONST_TRACE_INFO, "Remote: Thanks for using ntop Remote plugin");
224
traceEvent(CONST_TRACE_ALWAYSDISPLAY, "Remote: Done");
227
/* ****************************** */
229
static void handleRemoteHTTPrequest(char* url /* NOTUSED */) {
230
sendHTTPHeader(FLAG_HTTP_TYPE_HTML, 0, 1);
231
printHTMLheader("Remote Plugin", NULL, 0);
232
sendString("<center>This plugin is not supposed to display you anything as it<br>"
233
"implements remote network access to ntop</center>\n");