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);