From cc71c993f4a26c53c67d520a7a5f7f67d9b2077b Mon Sep 17 00:00:00 2001 From: Eric Leblond Date: Thu, 15 Nov 2012 09:06:01 +0100 Subject: [PATCH] unix-command: add iface information command. This patch adds two commands to unix-command. 'iface-list' displays the list of interface which are sniffed by Suricata and 'iface-stat' display the available statistics for a single interface. For now, this is the number of packets and the number of invalid checksums. --- scripts/suricatasc/suricatasc.in | 15 ++++++- src/suricata.c | 3 ++ src/util-device.c | 74 ++++++++++++++++++++++++++++++++ src/util-device.h | 4 ++ 4 files changed, 95 insertions(+), 1 deletion(-) diff --git a/scripts/suricatasc/suricatasc.in b/scripts/suricatasc/suricatasc.in index 4b36dd4345..78fb78bed4 100755 --- a/scripts/suricatasc/suricatasc.in +++ b/scripts/suricatasc/suricatasc.in @@ -27,7 +27,7 @@ if len(sys.argv) == 2: else: SOCKET_PATH = "@e_localstatedir@/suricata-command.socket" SIZE = 4096 -COMMANDS_REGEX = re.compile("^(?:shutdown|quit|reload-rules|pcap-file .+|pcap-file-number|pcap-file-list)$") +COMMANDS_REGEX = re.compile("^(?:shutdown|quit|reload-rules|pcap-file .+|pcap-file-number|pcap-file-list|iface-list|iface-stat .+)$") socket = socket(AF_UNIX) socket.connect(SOCKET_PATH) @@ -77,6 +77,19 @@ try: cmdmsg["arguments"] = {} cmdmsg["arguments"]["filename"] = filename cmdmsg["arguments"]["output-dir"] = output + elif "iface-stat" in command: + try: + [cmd, iface] = command.split(' ', 1) + except: + print "Error: unable to split command '%s'" % (command) + continue + if cmd != "iface-stat": + print "Error: invalid command '%s'" % (command) + continue + else: + cmdmsg["command"] = cmd + cmdmsg["arguments"] = {} + cmdmsg["arguments"]["iface"] = iface else: cmdmsg["command"] = command socket.send(json.dumps(cmdmsg)) diff --git a/src/suricata.c b/src/suricata.c index f068570b42..add3bccdf6 100644 --- a/src/suricata.c +++ b/src/suricata.c @@ -1944,6 +1944,9 @@ int main(int argc, char **argv) unix_socket = 0; if (unix_socket == 1) { UnixManagerThreadSpawn(de_ctx, 0); + UnixManagerRegisterCommand("iface-stat", LiveDeviceIfaceStat, NULL, + UNIX_CMD_TAKE_ARGS); + UnixManagerRegisterCommand("iface-list", LiveDeviceIfaceList, NULL, 0); } /* Spawn the flow manager thread */ FlowManagerThreadSpawn(); diff --git a/src/util-device.c b/src/util-device.c index 1a4f402ec0..b7993768b3 100644 --- a/src/util-device.c +++ b/src/util-device.c @@ -151,3 +151,77 @@ int LiveBuildDeviceList(char * runmode) return i; } + + +TmEcode LiveDeviceIfaceStat(json_t *cmd, json_t *answer, void *data) +{ + SCEnter(); +#ifdef BUILD_UNIX_SOCKET + LiveDevice *pd; + const char * name = NULL; + json_t *jarg = json_object_get(cmd, "iface"); + if(!json_is_string(jarg)) { + json_object_set_new(answer, "message", json_string("Iface is not a string")); + SCReturn(TM_ECODE_FAILED); + } + name = json_string_value(jarg); + if (name == NULL) { + json_object_set_new(answer, "message", json_string("Iface name is NULL")); + SCReturn(TM_ECODE_FAILED); + } + + TAILQ_FOREACH(pd, &live_devices, next) { + if (!strcmp(name, pd->dev)) { + json_t *jdata = json_object(); + if (jdata == NULL) { + json_object_set_new(answer, "message", + json_string("internal error at json object creation")); + SCReturn(TM_ECODE_FAILED); + } + json_object_set_new(jdata, "pkts", + json_integer(SC_ATOMIC_GET(pd->pkts))); + json_object_set_new(jdata, "invalid-checksums", + json_integer(SC_ATOMIC_GET(pd->invalid_checksums))); + json_object_set_new(answer, "message", jdata); + SCReturn(TM_ECODE_OK); + } + } + json_object_set_new(answer, "message", json_string("Iface does not exist")); +#endif /* BUILD_UNIX_SOCKET */ + SCReturn(TM_ECODE_FAILED); +} + +TmEcode LiveDeviceIfaceList(json_t *cmd, json_t *answer, void *data) +{ + SCEnter(); +#ifdef BUILD_UNIX_SOCKET + json_t *jdata; + json_t *jarray; + LiveDevice *pd; + int i = 0; + + jdata = json_object(); + if (jdata == NULL) { + json_object_set_new(answer, "message", + json_string("internal error at json object creation")); + return TM_ECODE_FAILED; + } + jarray = json_array(); + if (jarray == NULL) { + json_object_set_new(answer, "message", + json_string("internal error at json object creation")); + return TM_ECODE_FAILED; + } + TAILQ_FOREACH(pd, &live_devices, next) { + json_array_append(jarray, json_string(pd->dev)); + i++; + } + + json_object_set_new(jdata, "count", json_integer(i)); + json_object_set_new(jdata, "ifaces", jarray); + json_object_set_new(answer, "message", jdata); + SCReturn(TM_ECODE_OK); +#else /* BUILD_UNIX_SOCKET */ + SCReturn(TM_ECODE_FAILED); +#endif /* BUILD_UNIX_SOCKET */ +} diff --git a/src/util-device.h b/src/util-device.h index c740a5e6a4..5c73e1c9b3 100644 --- a/src/util-device.h +++ b/src/util-device.h @@ -19,6 +19,7 @@ #define __UTIL_DEVICE_H__ #include "queue.h" +#include "unix-manager.h" /** storage for live device names */ typedef struct LiveDevice_ { @@ -36,4 +37,7 @@ char *LiveGetDeviceName(int number); LiveDevice *LiveGetDevice(char *dev); int LiveBuildDeviceList(char * base); +TmEcode LiveDeviceIfaceStat(json_t *cmd, json_t *server_msg, void *data); +TmEcode LiveDeviceIfaceList(json_t *cmd, json_t *server_msg, void *data); + #endif /* __UTIL_DEVICE_H__ */