34 #include <sys/utsname.h>
63 xmlrpc_value *
const param_array,
64 void *
const user_data)
69 xmlrpc_value *ret = 0;
70 char* destination_host = 0;
72 char* bind_address = 0;
73 xmlrpc_value* extra_options = 0;
80 DEBUG_MSG(LOG_WARNING,
"method add_flow_source called");
83 xmlrpc_decompose_value(env, param_array,
87 "{s:d,s:d,s:d,s:d,s:d,*}"
90 "{s:b,s:b,s:b,s:b,s:b,*}"
97 "{s:i,s:i,s:i,s:i,s:i,*}"
104 "bind_address", &bind_address,
154 "extra_socket_options", &extra_options,
157 "destination_address", &destination_host,
161 if (env->fault_occurred)
166 XMLRPC_FAIL(env, XMLRPC_TYPE_ERROR,
"Daemon was asked to dump traffic, but wasn't compiled with libpcap support");
183 XMLRPC_FAIL(env, XMLRPC_TYPE_ERROR,
"Flow settings incorrect");
189 const unsigned char* buffer = 0;
191 xmlrpc_value *option, *level = 0, *optname = 0, *value = 0;
192 xmlrpc_array_read_item(env, extra_options, i, &option);
194 if (!env->fault_occurred)
195 xmlrpc_struct_read_value(env, option,
"level", &level);
196 if (!env->fault_occurred)
197 xmlrpc_struct_read_value(env, option,
"optname", &optname);
198 if (!env->fault_occurred)
199 xmlrpc_struct_read_value(env, option,
"value", &value);
200 if (!env->fault_occurred)
202 if (!env->fault_occurred)
204 if (!env->fault_occurred)
205 xmlrpc_read_base64(env, value, &len, &buffer);
207 xmlrpc_DECREF(level);
209 xmlrpc_DECREF(optname);
211 xmlrpc_DECREF(value);
212 if (!env->fault_occurred) {
214 free((
void *)buffer);
215 XMLRPC_FAIL(env, XMLRPC_TYPE_ERROR,
"Too long extra socket option length");
219 free((
void *)buffer);
221 if (env->fault_occurred)
235 XMLRPC_FAIL(env, XMLRPC_INTERNAL_ERROR,
request->r.
error);
238 ret = xmlrpc_build_value(env,
"{s:i,s:s,s:i,s:i}",
241 "real_send_buffer_size",
request->real_send_buffer_size,
242 "real_read_buffer_size",
request->real_read_buffer_size);
250 xmlrpc_DECREF(extra_options);
252 if (env->fault_occurred)
253 logging(LOG_WARNING,
"method add_flow_source failed: %s",
256 DEBUG_MSG(LOG_WARNING,
"method add_flow_source successful");
278 xmlrpc_value *
const param_array,
279 void *
const user_data)
284 xmlrpc_value *ret = 0;
286 char* bind_address = 0;
287 xmlrpc_value* extra_options = 0;
293 DEBUG_MSG(LOG_WARNING,
"method add_flow_destination called");
296 xmlrpc_decompose_value(env, param_array,
300 "{s:d,s:d,s:d,s:d,s:d,*}"
303 "{s:b,s:b,s:b,s:b,s:b,*}"
308 "{s:b,s:b,s:i,s:i,*}"
310 "{s:i,s:i,s:i,s:i,s:i,*}"
316 "bind_address", &bind_address,
366 "extra_socket_options", &extra_options);
368 if (env->fault_occurred)
373 XMLRPC_FAIL(env, XMLRPC_TYPE_ERROR,
"Daemon was asked to dump traffic, but wasn't compiled with libpcap support");
386 XMLRPC_FAIL(env, XMLRPC_TYPE_ERROR,
"Flow settings incorrect");
392 const unsigned char* buffer = 0;
394 xmlrpc_value *option, *level = 0, *optname = 0, *value = 0;
395 xmlrpc_array_read_item(env, extra_options, i, &option);
397 if (!env->fault_occurred)
398 xmlrpc_struct_read_value(env, option,
"level", &level);
399 if (!env->fault_occurred)
400 xmlrpc_struct_read_value(env, option,
"optname", &optname);
401 if (!env->fault_occurred)
402 xmlrpc_struct_read_value(env, option,
"value", &value);
403 if (!env->fault_occurred)
405 if (!env->fault_occurred)
407 if (!env->fault_occurred)
408 xmlrpc_read_base64(env, value, &len, &buffer);
410 xmlrpc_DECREF(level);
412 xmlrpc_DECREF(optname);
414 xmlrpc_DECREF(value);
415 if (!env->fault_occurred) {
417 free((
void *)buffer);
418 XMLRPC_FAIL(env, XMLRPC_TYPE_ERROR,
"Too long extra socket option length");
422 free((
void *)buffer);
424 if (env->fault_occurred)
430 DEBUG_MSG(LOG_WARNING,
"bind_address=%s", bind_address);
436 XMLRPC_FAIL(env, XMLRPC_INTERNAL_ERROR,
request->r.
error);
439 ret = xmlrpc_build_value(env,
"{s:i,s:i,s:i,s:i}",
441 "listen_data_port",
request->listen_data_port,
442 "real_listen_send_buffer_size",
request->real_listen_send_buffer_size,
443 "real_listen_read_buffer_size",
request->real_listen_read_buffer_size);
451 xmlrpc_DECREF(extra_options);
453 if (env->fault_occurred)
454 logging(LOG_WARNING,
"method add_flow_destination failed: %s",
457 DEBUG_MSG(LOG_WARNING,
"method add_flow_destination successful");
463 xmlrpc_value *
const param_array,
464 void *
const user_data)
469 xmlrpc_value *ret = 0;
473 DEBUG_MSG(LOG_WARNING,
"method start_flows called");
476 xmlrpc_decompose_value(env, param_array,
"({s:i,*})",
481 if (env->fault_occurred)
489 XMLRPC_FAIL(env, XMLRPC_INTERNAL_ERROR,
request->r.
error);
492 ret = xmlrpc_build_value(env,
"i", 0);
498 if (env->fault_occurred)
499 logging(LOG_WARNING,
"method start_flows failed: %s",
502 DEBUG_MSG(LOG_WARNING,
"method start_flows successful");
519 xmlrpc_value *
const param_array,
520 void *
const user_data)
523 xmlrpc_value *ret = 0, *item = 0;
528 DEBUG_MSG(LOG_NOTICE,
"method get_reports called");
532 ret = xmlrpc_array_new(env);
535 item = xmlrpc_int_new(env, has_more);
536 xmlrpc_array_append_item(env, ret, item);
540 xmlrpc_value *rv = xmlrpc_build_value(env,
542 "{s:i,s:i,s:i,s:i,s:i,s:i,s:i}"
545 "{s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d}"
547 "{s:i,s:i,s:i,s:i,s:i}"
548 "{s:i,s:i,s:i,s:i,s:i}"
549 "{s:i,s:i,s:i,s:i,s:i}"
605 xmlrpc_array_append_item(env, ret, rv);
614 if (env->fault_occurred)
615 logging(LOG_WARNING,
"method get_reports failed: %s",
618 DEBUG_MSG(LOG_WARNING,
"method get_reports successful");
624 xmlrpc_value *
const param_array,
625 void *
const user_data)
630 xmlrpc_value *ret = 0;
634 DEBUG_MSG(LOG_WARNING,
"method stop_flow called");
637 xmlrpc_decompose_value(env, param_array,
"({s:i,*})",
642 if (env->fault_occurred)
650 XMLRPC_FAIL(env, XMLRPC_INTERNAL_ERROR,
request->r.
error);
653 ret = xmlrpc_build_value(env,
"()");
659 if (env->fault_occurred)
660 logging(LOG_WARNING,
"method stop_flow failed: %s",
663 DEBUG_MSG(LOG_WARNING,
"method stop_flow successful");
670 xmlrpc_value *
const param_array,
671 void *
const user_data)
677 xmlrpc_value *ret = 0;
679 DEBUG_MSG(LOG_WARNING,
"method get_version called");
682 logging(LOG_WARNING,
"uname() failed %s", strerror(errno));
686 ret = xmlrpc_build_value(env,
"{s:s,s:i,s:s,s:s}",
689 "os_name", buf.sysname,
690 "os_release", buf.release);
692 if (env->fault_occurred)
693 logging(LOG_WARNING,
"method get_version failed: %s",
696 DEBUG_MSG(LOG_WARNING,
"method get_version successful");
703 xmlrpc_value *
const param_array,
704 void *
const user_data)
710 xmlrpc_value *ret = 0;
713 DEBUG_MSG(LOG_WARNING,
"method get_status called");
719 XMLRPC_FAIL(env, XMLRPC_INTERNAL_ERROR,
request->r.
error);
722 ret = xmlrpc_build_value(env,
"{s:i,s:i}",
724 "num_flows",
request->num_flows);
730 if (env->fault_occurred)
731 logging(LOG_WARNING,
"method get_status failed: %s",
734 DEBUG_MSG(LOG_WARNING,
"method get_status successful");
753 xmlrpc_value *
const param_array,
754 void *
const user_data)
759 DEBUG_MSG(LOG_WARNING,
"Method get_uuid called");
761 xmlrpc_value *ret = 0;
766 XMLRPC_FAIL(env, XMLRPC_INTERNAL_ERROR,
request->r.
error);
769 ret = xmlrpc_build_value(env,
"{s:s}",
"server_uuid",
request->server_uuid);
775 if (env->fault_occurred)
776 logging(LOG_WARNING,
"Method get_uuid failed: %s", env->fault_string);
778 DEBUG_MSG(LOG_WARNING,
"Method get_uuid successful");
788 struct addrinfo hints, *res, *ressave;
791 bzero(&hints,
sizeof(
struct addrinfo));
792 hints.ai_flags = AI_PASSIVE | AI_NUMERICSERV;
793 hints.ai_family = AF_UNSPEC;
794 hints.ai_socktype = SOCK_STREAM;
795 sprintf(tmp_port,
"%u",
port);
797 if ((rc = getaddrinfo(bind_addr, tmp_port,
798 &hints, &res)) != 0) {
799 critx(
"Failed to find address to bind rpc_server: %s\n",
809 fd = socket(res->ai_family, res->ai_socktype,
815 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval,
sizeof(optval));
817 setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &optval,
sizeof(optval));
819 if (bind(fd, res->ai_addr, res->ai_addrlen) == 0)
823 }
while ((res = res->ai_next) != NULL);
826 crit(
"failed to bind RPC listen socket");
827 freeaddrinfo(ressave);
837 xmlrpc_registry * registryP;
838 xmlrpc_env *env = &(server->
env);
839 memset(&(server->
parms), 0,
sizeof(server->
parms));
841 xmlrpc_env_init(env);
842 registryP = xmlrpc_registry_new(env);
844 xmlrpc_registry_add_method(env, registryP, NULL,
"add_flow_destination", &
add_flow_destination, NULL);
845 xmlrpc_registry_add_method(env, registryP, NULL,
"add_flow_source", &
add_flow_source, NULL);
846 xmlrpc_registry_add_method(env, registryP, NULL,
"start_flows", &
start_flows, NULL);
847 xmlrpc_registry_add_method(env, registryP, NULL,
"get_reports", &
method_get_reports, NULL);
848 xmlrpc_registry_add_method(env, registryP, NULL,
"stop_flow", &
method_stop_flow, NULL);
849 xmlrpc_registry_add_method(env, registryP, NULL,
"get_version", &
method_get_version, NULL);
850 xmlrpc_registry_add_method(env, registryP, NULL,
"get_status", &
method_get_status, NULL);
851 xmlrpc_registry_add_method(env, registryP, NULL,
"get_uuid", &
method_get_uuid, NULL);
857 server->
parms.config_file_name = NULL;
858 server->
parms.registryP = registryP;
859 server->
parms.socket_bound = 1;
860 server->
parms.log_file_name = NULL;
865 server->
parms.keepalive_timeout = 60;
866 server->
parms.keepalive_max_conn = 1000;
869 server->
parms.dont_advertise = 1;
871 logging(LOG_NOTICE,
"running XML-RPC server on port %u",
port);
872 printf(
"Running XML-RPC server...\n");
880 xmlrpc_env *env = &(server->
env);
881 xmlrpc_server_abyss(env, &(server->
parms), XMLRPC_APSIZE(socket_handle));
883 if (env->fault_occurred)
884 logging(LOG_ALERT,
"XML-RPC Fault: %s (%d)", env->fault_string,