From: Eric Leblond Date: Sat, 30 Dec 2017 18:50:12 +0000 (+0100) Subject: util-device: change logic of registration X-Git-Tag: suricata-4.1.0-beta1~205 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4474889667d664a66c1c123f4f7d2756e8a7fbb9;p=thirdparty%2Fsuricata.git util-device: change logic of registration Device storage requires the devices to be created after storage is finalized so we need to first get the list of devices then create them when the storage is finalized. This patch introduces the LiveDeviceName structure that is a list of device name used during registration. Code uses LiveRegisterDeviceName for pre registration and keep using the LiveRegisterDevice function for part of the code that create the interface during the runmode creation. --- diff --git a/src/source-ipfw.c b/src/source-ipfw.c index 6821d69456..fb89a03cc8 100644 --- a/src/source-ipfw.c +++ b/src/source-ipfw.c @@ -737,7 +737,7 @@ int IPFWRegisterQueue(char *queue) nq->port_num = port_num; receive_port_num++; SCMutexUnlock(&ipfw_init_lock); - LiveRegisterDevice(queue); + LiveRegisterDeviceName(queue); SCLogDebug("Queue \"%s\" registered.", queue); return 0; diff --git a/src/source-nfq.c b/src/source-nfq.c index 4f1eb6bb78..f693bccf23 100644 --- a/src/source-nfq.c +++ b/src/source-nfq.c @@ -856,7 +856,7 @@ int NFQRegisterQueue(char *queue) nq->queue_num = queue_num; receive_queue_num++; SCMutexUnlock(&nfq_init_lock); - LiveRegisterDevice(queue); + LiveRegisterDeviceName(queue); SCLogDebug("Queue \"%s\" registered.", queue); return 0; diff --git a/src/suricata.c b/src/suricata.c index dd7aad9902..dae12f0d10 100644 --- a/src/suricata.c +++ b/src/suricata.c @@ -1102,7 +1102,7 @@ static int ParseCommandLineAfpacket(SCInstance *suri, const char *in_arg) if (suri->run_mode == RUNMODE_UNKNOWN) { suri->run_mode = RUNMODE_AFP_DEV; if (in_arg) { - LiveRegisterDevice(in_arg); + LiveRegisterDeviceName(in_arg); memset(suri->pcap_dev, 0, sizeof(suri->pcap_dev)); strlcpy(suri->pcap_dev, in_arg, sizeof(suri->pcap_dev)); } @@ -1110,7 +1110,7 @@ static int ParseCommandLineAfpacket(SCInstance *suri, const char *in_arg) SCLogWarning(SC_WARN_PCAP_MULTI_DEV_EXPERIMENTAL, "using " "multiple devices to get packets is experimental."); if (in_arg) { - LiveRegisterDevice(in_arg); + LiveRegisterDeviceName(in_arg); } else { SCLogInfo("Multiple af-packet option without interface on each is useless"); } @@ -1154,7 +1154,7 @@ static int ParseCommandLinePcapLive(SCInstance *suri, const char *in_arg) if (suri->run_mode == RUNMODE_UNKNOWN) { suri->run_mode = RUNMODE_PCAP_DEV; if (in_arg) { - LiveRegisterDevice(suri->pcap_dev); + LiveRegisterDeviceName(suri->pcap_dev); } } else if (suri->run_mode == RUNMODE_PCAP_DEV) { #ifdef OS_WIN32 @@ -1164,7 +1164,7 @@ static int ParseCommandLinePcapLive(SCInstance *suri, const char *in_arg) #else SCLogWarning(SC_WARN_PCAP_MULTI_DEV_EXPERIMENTAL, "using " "multiple pcap devices to get packets is experimental."); - LiveRegisterDevice(suri->pcap_dev); + LiveRegisterDeviceName(suri->pcap_dev); #endif } else { SCLogError(SC_ERR_MULTIPLE_RUN_MODE, "more than one run mode " @@ -1557,7 +1557,7 @@ static TmEcode ParseCommandLine(int argc, char** argv, SCInstance *suri) strlcpy(suri->pcap_dev, optarg, ((strlen(optarg) < sizeof(suri->pcap_dev)) ? (strlen(optarg) + 1) : sizeof(suri->pcap_dev))); - LiveRegisterDevice(optarg); + LiveRegisterDeviceName(optarg); } #else SCLogError(SC_ERR_NO_PF_RING,"PF_RING not enabled. Make sure " @@ -1599,7 +1599,7 @@ static TmEcode ParseCommandLine(int argc, char** argv, SCInstance *suri) if (suri->run_mode == RUNMODE_UNKNOWN) { suri->run_mode = RUNMODE_NETMAP; if (optarg) { - LiveRegisterDevice(optarg); + LiveRegisterDeviceName(optarg); memset(suri->pcap_dev, 0, sizeof(suri->pcap_dev)); strlcpy(suri->pcap_dev, optarg, ((strlen(optarg) < sizeof(suri->pcap_dev)) ? @@ -1609,7 +1609,7 @@ static TmEcode ParseCommandLine(int argc, char** argv, SCInstance *suri) SCLogWarning(SC_WARN_PCAP_MULTI_DEV_EXPERIMENTAL, "using " "multiple devices to get packets is experimental."); if (optarg) { - LiveRegisterDevice(optarg); + LiveRegisterDeviceName(optarg); } else { SCLogInfo("Multiple netmap option without interface on each is useless"); break; @@ -1758,7 +1758,7 @@ static TmEcode ParseCommandLine(int argc, char** argv, SCInstance *suri) PrintUsage(argv[0]); return TM_ECODE_FAILED; } - LiveRegisterDevice(optarg); + LiveRegisterDeviceName(optarg); #else SCLogError(SC_ERR_DAG_REQUIRED, "libdag and a DAG card are required" " to receive packets using --dag."); @@ -1798,7 +1798,7 @@ static TmEcode ParseCommandLine(int argc, char** argv, SCInstance *suri) strlcpy(suri->pcap_dev, optarg, ((strlen(optarg) < sizeof(suri->pcap_dev)) ? (strlen(optarg) + 1) : sizeof(suri->pcap_dev))); - LiveRegisterDevice(optarg); + LiveRegisterDeviceName(optarg); } } else { SCLogError(SC_ERR_MULTIPLE_RUN_MODE, @@ -2847,6 +2847,8 @@ int main(int argc, char **argv) exit(EXIT_FAILURE); } + LiveDeviceFinalize(); + SCDropMainThreadCaps(suricata.userid, suricata.groupid); PreRunPostPrivsDropInit(suricata.run_mode); diff --git a/src/util-device.c b/src/util-device.c index 1a7aacf020..439d06abb9 100644 --- a/src/util-device.c +++ b/src/util-device.c @@ -36,6 +36,15 @@ static TAILQ_HEAD(, LiveDevice_) live_devices = TAILQ_HEAD_INITIALIZER(live_devices); +/** List of the name of devices + * + * As we don't know the size of the Storage on devices + * before the parsing we need to wait and use this list + * to create later the LiveDevice via LiveDeviceFinalize() + */ +static TAILQ_HEAD(, LiveDeviceName_) pre_live_devices = + TAILQ_HEAD_INITIALIZER(pre_live_devices); + /** if set to 0 when we don't have real devices */ static int live_devices_stats = 1; @@ -60,7 +69,39 @@ int LiveGetOffload(void) } /** - * \brief Add a pcap device for monitoring + * \brief Add a device for monitoring + * + * To be used during option parsing. When a device has + * to be created during runmode init, use LiveRegisterDevice() + * + * \param dev string with the device name + * + * \retval 0 on success. + * \retval -1 on failure. + */ +int LiveRegisterDeviceName(const char *dev) +{ + LiveDeviceName *pd = NULL; + + pd = SCCalloc(1, sizeof(LiveDeviceName)); + if (unlikely(pd == NULL)) { + return -1; + } + + pd->dev = SCStrdup(dev); + if (unlikely(pd->dev == NULL)) { + SCFree(pd); + return -1; + } + + TAILQ_INSERT_TAIL(&pre_live_devices, pd, next); + + SCLogDebug("Device \"%s\" registered.", dev); + return 0; +} + +/** + * \brief Add a pcap device for monitoring and create structure * * \param dev string with the device name * @@ -94,7 +135,7 @@ int LiveRegisterDevice(const char *dev) pd->ignore_checksum = 0; TAILQ_INSERT_TAIL(&live_devices, pd, next); - SCLogDebug("Device \"%s\" registered.", dev); + SCLogDebug("Device \"%s\" registered and created.", dev); return 0; } @@ -254,7 +295,7 @@ int LiveBuildDeviceListCustom(const char *runmode, const char *itemname) break; SCLogConfig("Adding %s %s from config file", itemname, subchild->val); - LiveRegisterDevice(subchild->val); + LiveRegisterDeviceName(subchild->val); i++; } } @@ -389,3 +430,22 @@ LiveDevice *LiveDeviceForEach(LiveDevice **ldev, LiveDevice **ndev) return NULL; } +/** + * Create registered devices + * + * This function creates all needed LiveDevice from + * the LiveDeviceName list created via LiveRegisterDevice() + */ +void LiveDeviceFinalize(void) +{ + LiveDeviceName *ld, *pld; + SCLogDebug("Finalize live device"); + /* Iter on devices and register them */ + TAILQ_FOREACH_SAFE(ld, &pre_live_devices, next, pld) { + if (ld->dev) { + LiveRegisterDevice(ld->dev); + SCFree(ld->dev); + } + SCFree(ld); + } +} diff --git a/src/util-device.h b/src/util-device.h index 80b372ac99..2bdd00d33c 100644 --- a/src/util-device.h +++ b/src/util-device.h @@ -50,6 +50,12 @@ typedef struct LiveDevice_ { uint32_t offload_orig; /**< original offload settings to restore @exit */ } LiveDevice; +typedef struct LiveDeviceName_ { + char *dev; /**< the device (e.g. "eth0") */ + TAILQ_ENTRY(LiveDeviceName_) next; +} LiveDeviceName; + +int LiveRegisterDeviceName(const char *dev); int LiveRegisterDevice(const char *dev); int LiveGetDeviceCount(void); const char *LiveGetDeviceName(int number); @@ -62,6 +68,8 @@ int LiveBuildDeviceListCustom(const char *base, const char *itemname); LiveDevice *LiveDeviceForEach(LiveDevice **ldev, LiveDevice **ndev); +void LiveDeviceFinalize(void); + #ifdef BUILD_UNIX_SOCKET TmEcode LiveDeviceIfaceStat(json_t *cmd, json_t *server_msg, void *data); TmEcode LiveDeviceIfaceList(json_t *cmd, json_t *server_msg, void *data);