diff --git a/src/detect-engine.c b/src/detect-engine.c index 823bab5b22..1eaa3465c3 100644 --- a/src/detect-engine.c +++ b/src/detect-engine.c @@ -1724,6 +1724,16 @@ static int DetectEngineTentantRegisterSelector(enum DetectEngineTenantSelectors return -1; } + DetectEngineTenantMapping *m = master->tenant_mapping_list; + while (m) { + if (m->traffic_id == traffic_id) { + SCLogInfo("traffic id already registered"); + SCMutexUnlock(&master->lock); + return -1; + } + m = m->next; + } + DetectEngineTenantMapping *map = SCCalloc(1, sizeof(*map)); if (map == NULL) { SCLogInfo("memory fail"); @@ -1738,6 +1748,7 @@ static int DetectEngineTentantRegisterSelector(enum DetectEngineTenantSelectors master->tenant_selector = selector; + SCLogInfo("tenant handler %u %u %u registered", selector, tenant_id, traffic_id); SCMutexUnlock(&master->lock); return 0; } @@ -1747,6 +1758,12 @@ int DetectEngineTentantRegisterVlanId(uint32_t tenant_id, uint16_t vlan_id) return DetectEngineTentantRegisterSelector(TENANT_SELECTOR_VLAN, tenant_id, (uint32_t)vlan_id); } +int DetectEngineTentantRegisterPcapFile(uint32_t tenant_id) +{ + SCLogInfo("registering %u %d 0", TENANT_SELECTOR_DIRECT, tenant_id); + return DetectEngineTentantRegisterSelector(TENANT_SELECTOR_DIRECT, tenant_id, 0); +} + uint32_t DetectEngineTentantGetIdFromPcap(const void *ctx, const Packet *p) { return p->pcap_v.tenant_id; diff --git a/src/detect-engine.h b/src/detect-engine.h index 76253ab327..e67bc1c7ae 100644 --- a/src/detect-engine.h +++ b/src/detect-engine.h @@ -86,6 +86,9 @@ int DetectEngineReloadIsStart(void); void DetectEngineReloadSetDone(void); int DetectEngineReloadIsDone(void); +int DetectEngineTentantRegisterVlanId(uint32_t tenant_id, uint16_t vlan_id); +int DetectEngineTentantRegisterPcapFile(uint32_t tenant_id); + /** * \brief Registers an app inspection engine. * diff --git a/src/runmode-unix-socket.c b/src/runmode-unix-socket.c index e4c848ca1e..81b5839b07 100644 --- a/src/runmode-unix-socket.c +++ b/src/runmode-unix-socket.c @@ -365,6 +365,8 @@ TmEcode UnixSocketPcapFilesCheck(void *data) PcapFilesFree(cfile); return TM_ECODE_FAILED; } + } else { + SCLogInfo("pcap-file.tenant-id not set"); } this->currentfile = SCStrdup(cfile->filename); if (unlikely(this->currentfile == NULL)) { @@ -425,6 +427,87 @@ void UnixSocketPcapFile(TmEcode tm) } #ifdef BUILD_UNIX_SOCKET +/** + * \brief Command to add a tenant handler + * + * \param cmd the content of command Arguments as a json_t object + * \param answer the json_t object that has to be used to answer + * \param data pointer to data defining the context here a PcapCommand:: + */ +TmEcode UnixSocketRegisterTenantHandler(json_t *cmd, json_t* answer, void *data) +{ + const char *htype; + json_int_t traffic_id = -1; + + if (!(DetectEngineMultiTenantEnabled())) { + SCLogInfo("error: multi-tenant support not enabled"); + json_object_set_new(answer, "message", json_string("multi-tenant support not enabled")); + return TM_ECODE_FAILED; + } + + /* 1 get tenant id */ + json_t *jarg = json_object_get(cmd, "id"); + if (!json_is_integer(jarg)) { + SCLogInfo("error: command is not a string"); + json_object_set_new(answer, "message", json_string("id is not an integer")); + return TM_ECODE_FAILED; + } + int tenant_id = json_integer_value(jarg); + + /* 2 get tenant handler type */ + jarg = json_object_get(cmd, "htype"); + if (!json_is_string(jarg)) { + SCLogInfo("error: command is not a string"); + json_object_set_new(answer, "message", json_string("command is not a string")); + return TM_ECODE_FAILED; + } + htype = json_string_value(jarg); + + SCLogDebug("add-tenant-handler: %d %s", tenant_id, htype); + + /* 3 get optional hargs */ + json_t *hargs = json_object_get(cmd, "hargs"); + if (hargs != NULL) { + if (!json_is_integer(hargs)) { + SCLogInfo("error: hargs not a number"); + json_object_set_new(answer, "message", json_string("hargs not a number")); + return TM_ECODE_FAILED; + } + traffic_id = json_integer_value(hargs); + } + + /* 4 add to system */ + int r = -1; + if (strcmp(htype, "pcap") == 0) { + r = DetectEngineTentantRegisterPcapFile(tenant_id); + } else if (strcmp(htype, "vlan") == 0) { + if (traffic_id < 0) { + json_object_set_new(answer, "message", json_string("vlan requires argument")); + return TM_ECODE_FAILED; + } + if (traffic_id > USHRT_MAX) { + json_object_set_new(answer, "message", json_string("vlan argument out of range")); + return TM_ECODE_FAILED; + } + + SCLogInfo("VLAN handler: id %u maps to tenant %u", (uint32_t)traffic_id, tenant_id); + r = DetectEngineTentantRegisterVlanId(tenant_id, (uint32_t)traffic_id); + } + if (r != 0) { + json_object_set_new(answer, "message", json_string("handler setup failure")); + return TM_ECODE_FAILED; + } + + if (DetectEngineMTApply() < 0) { + json_object_set_new(answer, "message", json_string("couldn't apply settings")); + // TODO cleanup + return TM_ECODE_FAILED; + } + + json_object_set_new(answer, "message", json_string("handler added")); + return TM_ECODE_OK; +} + /** * \brief Command to add a tenant * diff --git a/src/runmode-unix-socket.h b/src/runmode-unix-socket.h index b844c890a6..68e324337c 100644 --- a/src/runmode-unix-socket.h +++ b/src/runmode-unix-socket.h @@ -32,6 +32,7 @@ int RunModeUnixSocketIsActive(void); void UnixSocketPcapFile(TmEcode tm); #ifdef BUILD_UNIX_SOCKET +TmEcode UnixSocketRegisterTenantHandler(json_t *cmd, json_t* answer, void *data); TmEcode UnixSocketRegisterTenant(json_t *cmd, json_t* answer, void *data); TmEcode UnixSocketUnregisterTenant(json_t *cmd, json_t* answer, void *data); #endif diff --git a/src/unix-manager.c b/src/unix-manager.c index 8bea8c4834..384e590785 100644 --- a/src/unix-manager.c +++ b/src/unix-manager.c @@ -899,6 +899,7 @@ static TmEcode UnixManager(ThreadVars *th_v, void *thread_data) UnixManagerRegisterCommand("conf-get", UnixManagerConfGetCommand, &command, UNIX_CMD_TAKE_ARGS); UnixManagerRegisterCommand("dump-counters", StatsOutputCounterSocket, NULL, 0); UnixManagerRegisterCommand("reload-rules", UnixManagerReloadRules, NULL, 0); + UnixManagerRegisterCommand("register-tenant-handler", UnixSocketRegisterTenantHandler, &command, UNIX_CMD_TAKE_ARGS); UnixManagerRegisterCommand("register-tenant", UnixSocketRegisterTenant, &command, UNIX_CMD_TAKE_ARGS); UnixManagerRegisterCommand("unregister-tenant", UnixSocketUnregisterTenant, &command, UNIX_CMD_TAKE_ARGS);