diff --git a/src/Makefile.am b/src/Makefile.am index 518153fc38..dfd69ba879 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -258,6 +258,7 @@ detect-within.c detect-within.h \ detect-modbus.c detect-modbus.h \ detect-xbits.c detect-xbits.h \ detect-cipservice.c detect-cipservice.h \ +device-storage.c device-storage.h \ flow-bit.c flow-bit.h \ flow.c flow.h \ flow-bypass.c flow-bypass.h \ diff --git a/src/device-storage.c b/src/device-storage.c new file mode 100644 index 0000000000..2035eb8e97 --- /dev/null +++ b/src/device-storage.c @@ -0,0 +1,111 @@ +/* Copyright (C) 2018 Open Information Security Foundation + * + * You can copy, redistribute or modify this Program under the terms of + * the GNU General Public License version 2 as published by the Free + * Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * version 2 along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +/** + * \file + * + * \author Eric Leblond + * + * Device wrapper around storage api + */ + +#include "suricata-common.h" +#include "device-storage.h" +#include "util-unittest.h" + +unsigned int LiveDevStorageSize(void) +{ + return StorageGetSize(STORAGE_DEVICE); +} + +/** \defgroup devicestorage Device storage API + * + * The device storage API is a per-device storage. It is a mean to extend + * the LiveDevice structure with arbitrary data. + * + * You have first to register the storage via LiveDevStorageRegister() during + * the init of your module. Then you can attach data via LiveDevSetStorageById() + * and access them via LiveDevGetStorageById(). + * @{ + */ + +/** + * \brief Register a LiveDevice storage + * + * \param name the name of the storage + * \param size integer coding the size of the stored value (sizeof(void *) is best choice here) + * \param Alloc allocation function for the storage (can be null) + * \param Free free function for the new storage + * + * \retval The ID of the newly register storage that will be used to access data + * + * It has to be called once during the init of the sub system + */ + +int LiveDevStorageRegister(const char *name, const unsigned int size, void *(*Alloc)(unsigned int), void (*Free)(void *)) { + return StorageRegister(STORAGE_DEVICE, name, size, Alloc, Free); +} + +/** + * \brief Store a pointer in a given LiveDevice storage + * + * \param d a pointer to the LiveDevice + * \param id the id of the storage (return of HostStorageRegister() call) + * \param ptr pointer to the data to store + */ + +int LiveDevSetStorageById(LiveDevice *d, int id, void *ptr) +{ + return StorageSetById((Storage *)((void *)d + sizeof(LiveDevice)), STORAGE_DEVICE, id, ptr); +} + +/** + * \brief Get a value from a given LiveDevice storage + * + * \param d a pointer to the LiveDevice + * \param id the id of the storage (return of LiveDevStorageRegister() call) + * + */ + +void *LiveDevGetStorageById(LiveDevice *d, int id) +{ + return StorageGetById((Storage *)((void *)d + sizeof(LiveDevice)), STORAGE_DEVICE, id); +} + +/** + * @} + */ + +/* Start of "private" function */ + +void *LiveDevAllocStorageById(LiveDevice *d, int id) +{ + return StorageAllocByIdPrealloc((Storage *)((void *)d + sizeof(LiveDevice)), STORAGE_DEVICE, id); +} + +void LiveDevFreeStorageById(LiveDevice *d, int id) +{ + StorageFreeById((Storage *)((void *)d + sizeof(LiveDevice)), STORAGE_DEVICE, id); +} + +void LiveDevFreeStorage(LiveDevice *d) +{ + if (LiveDevStorageSize() > 0) + StorageFreeAll((Storage *)((void *)d + sizeof(LiveDevice)), STORAGE_DEVICE); +} + + diff --git a/src/device-storage.h b/src/device-storage.h new file mode 100644 index 0000000000..0c671eac46 --- /dev/null +++ b/src/device-storage.h @@ -0,0 +1,45 @@ +/* Copyright (C) 2018 Open Information Security Foundation + * + * You can copy, redistribute or modify this Program under the terms of + * the GNU General Public License version 2 as published by the Free + * Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * version 2 along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +/** + * \file + * + * \author Eric Leblond + * + * LiveDevice wrapper around storage api + */ + +#ifndef __DEVICE_STORAGE_H__ +#define __DEVICE_STORAGE_H__ + +#include "util-storage.h" +#include "util-device.h" + +unsigned int LiveDevStorageSize(void); + +void *LiveDevGetStorageById(LiveDevice *d, int id); +int LiveDevSetStorageById(LiveDevice *d, int id, void *ptr); +void *LiveDevAllocStorageById(LiveDevice *d, int id); + +void LiveDevFreeStorageById(LiveDevice *d, int id); +void LiveDevFreeStorage(LiveDevice *d); + +void RegisterLiveDevStorageTests(void); + +int LiveDevStorageRegister(const char *name, const unsigned int size, void *(*Alloc)(unsigned int), void (*Free)(void *)); + +#endif /* __DEVICE_STORAGE_H__ */ diff --git a/src/util-device.c b/src/util-device.c index 9848f2d635..d21a14b27b 100644 --- a/src/util-device.c +++ b/src/util-device.c @@ -20,6 +20,8 @@ #include "util-device.h" #include "util-ioctl.h" +#include "device-storage.h" + #define MAX_DEVNAME 10 /** @@ -67,7 +69,9 @@ int LiveGetOffload(void) */ int LiveRegisterDevice(const char *dev) { - LiveDevice *pd = SCCalloc(1, sizeof(LiveDevice)); + LiveDevice *pd = NULL; + + pd = SCCalloc(1, sizeof(LiveDevice) + LiveDevStorageSize()); if (unlikely(pd == NULL)) { return -1; } @@ -290,6 +294,7 @@ int LiveDeviceListClean() SC_ATOMIC_DESTROY(pd->pkts); SC_ATOMIC_DESTROY(pd->drop); SC_ATOMIC_DESTROY(pd->invalid_checksums); + LiveDevFreeStorage(pd); SCFree(pd); } diff --git a/src/util-storage.c b/src/util-storage.c index 21bbf4e061..756ef240d6 100644 --- a/src/util-storage.c +++ b/src/util-storage.c @@ -56,6 +56,8 @@ static const char *StoragePrintType(StorageEnum type) return "flow"; case STORAGE_IPPAIR: return "ippair"; + case STORAGE_DEVICE: + return "livedevice"; case STORAGE_MAX: return "max"; } diff --git a/src/util-storage.h b/src/util-storage.h index d88b030fbd..984bcf8c20 100644 --- a/src/util-storage.h +++ b/src/util-storage.h @@ -30,6 +30,7 @@ typedef enum StorageEnum_ { STORAGE_HOST, STORAGE_FLOW, STORAGE_IPPAIR, + STORAGE_DEVICE, STORAGE_MAX, } StorageEnum;