detect: hostbits keyword

Per host bit similar to 'flowbits'.

Initial code that uses just the 'src' ip for the operations.
pull/1422/head
Victor Julien 10 years ago
parent 99ae643e4e
commit 5c880377ae

@ -137,6 +137,7 @@ detect-fragoffset.c detect-fragoffset.h \
detect-ftpbounce.c detect-ftpbounce.h \
detect-geoip.c detect-geoip.h \
detect-gid.c detect-gid.h \
detect-hostbits.c detect-hostbits.h \
detect-http-client-body.c detect-http-client-body.h \
detect-http-cookie.c detect-http-cookie.h \
detect-http-header.c detect-http-header.h \
@ -207,6 +208,7 @@ flow-timeout.c flow-timeout.h \
flow-util.c flow-util.h \
flow-var.c flow-var.h \
host.c host.h \
host-bit.c host-bit.h \
host-queue.c host-queue.h \
host-storage.c host-storage.h \
host-timeout.c host-timeout.h \

File diff suppressed because it is too large Load Diff

@ -0,0 +1,43 @@
/* Copyright (C) 2007-2014 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 Victor Julien <victor@inliniac.net>
*/
#ifndef __DETECT_HOSTBITS_H__
#define __DETECT_HOSTBITS_H__
#define DETECT_HOSTBITS_CMD_SET 0
#define DETECT_HOSTBITS_CMD_TOGGLE 1
#define DETECT_HOSTBITS_CMD_UNSET 2
#define DETECT_HOSTBITS_CMD_ISNOTSET 3
#define DETECT_HOSTBITS_CMD_ISSET 4
#define DETECT_HOSTBITS_CMD_NOALERT 5
#define DETECT_HOSTBITS_CMD_MAX 6
typedef struct DetectHostbitsData_ {
uint16_t idx;
uint8_t cmd;
} DetectHostbitsData;
/* prototypes */
void DetectHostbitsRegister (void);
#endif /* __DETECT_HOSTBITS_H__ */

@ -108,6 +108,7 @@
#include "detect-pktvar.h"
#include "detect-noalert.h"
#include "detect-flowbits.h"
#include "detect-hostbits.h"
#include "detect-csum.h"
#include "detect-stream_size.h"
#include "detect-engine-sigorder.h"
@ -5002,6 +5003,7 @@ void SigTableSetup(void)
DetectPktvarRegister();
DetectNoalertRegister();
DetectFlowbitsRegister();
DetectHostbitsRegister();
DetectEngineEventRegister();
DetectIpOptsRegister();
DetectFlagsRegister();

@ -1106,6 +1106,7 @@ enum {
DETECT_PKTVAR,
DETECT_NOALERT,
DETECT_FLOWBITS,
DETECT_HOSTBITS,
DETECT_IPV4_CSUM,
DETECT_TCPV4_CSUM,
DETECT_TCPV6_CSUM,

@ -0,0 +1,489 @@
/* Copyright (C) 2014 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 Victor Julien <victor@inliniac.net>
*
* Implements per host bits. Actually, not a bit,
* but called that way because of Snort's flowbits.
* It's a binary storage.
*
* \todo move away from a linked list implementation
* \todo use different datatypes, such as string, int, etc.
*/
#include "suricata-common.h"
#include "threads.h"
#include "host-bit.h"
#include "host.h"
#include "detect.h"
#include "util-var.h"
#include "util-debug.h"
#include "util-unittest.h"
#include "host-storage.h"
static int host_bit_id = -1; /**< Host storage id for bits */
void HostBitFreeAll(void *store) {
GenericVar *gv = store;
GenericVarFree(gv);
}
void HostBitInitCtx(void)
{
host_bit_id = HostStorageRegister("bit", sizeof(void *), NULL, HostBitFreeAll);
if (host_bit_id == -1) {
SCLogError(SC_ERR_HOST_INIT, "Can't initiate host storage for bits");
exit(EXIT_FAILURE);
}
}
/* lock before using this */
int HostHasHostBits(Host *host)
{
if (host == NULL)
return 0;
return HostGetStorageById(host, host_bit_id) ? 1 : 0;
}
/* get the bit with idx from the host */
static HostBit *HostBitGet(Host *h, uint16_t idx)
{
GenericVar *gv = HostGetStorageById(h, host_bit_id);
for ( ; gv != NULL; gv = gv->next) {
if (gv->type == DETECT_HOSTBITS && gv->idx == idx) {
return (HostBit *)gv;
}
}
return NULL;
}
/* add a flowbit to the flow */
static void HostBitAdd(Host *h, uint16_t idx)
{
HostBit *fb = HostBitGet(h, idx);
if (fb == NULL) {
fb = SCMalloc(sizeof(HostBit));
if (unlikely(fb == NULL))
return;
fb->type = DETECT_HOSTBITS;
fb->idx = idx;
fb->next = NULL;
GenericVar *gv = HostGetStorageById(h, host_bit_id);
GenericVarAppend(&gv, (GenericVar *)fb);
HostSetStorageById(h, host_bit_id, gv);
}
}
static void HostBitRemove(Host *h, uint16_t idx)
{
HostBit *fb = HostBitGet(h, idx);
if (fb == NULL)
return;
GenericVar *gv = HostGetStorageById(h, host_bit_id);
if (gv) {
GenericVarRemove(&gv, (GenericVar *)fb);
HostSetStorageById(h, host_bit_id, gv);
}
}
void HostBitSet(Host *h, uint16_t idx)
{
HostBit *fb = HostBitGet(h, idx);
if (fb == NULL) {
HostBitAdd(h, idx);
}
}
void HostBitUnset(Host *h, uint16_t idx)
{
HostBit *fb = HostBitGet(h, idx);
if (fb != NULL) {
HostBitRemove(h, idx);
}
}
void HostBitToggle(Host *h, uint16_t idx)
{
HostBit *fb = HostBitGet(h, idx);
if (fb != NULL) {
HostBitRemove(h, idx);
} else {
HostBitAdd(h, idx);
}
}
int HostBitIsset(Host *h, uint16_t idx)
{
int r = 0;
HostBit *fb = HostBitGet(h, idx);
if (fb != NULL) {
r = 1;
}
return r;
}
int HostBitIsnotset(Host *h, uint16_t idx)
{
int r = 0;
HostBit *fb = HostBitGet(h, idx);
if (fb == NULL) {
r = 1;
}
return r;
}
void HostBitFree(HostBit *fb)
{
if (fb == NULL)
return;
SCFree(fb);
}
/* TESTS */
#ifdef UNITTESTS
static int HostBitTest01 (void)
{
int ret = 0;
HostInitConfig(TRUE);
Host *h = HostAlloc();
if (h == NULL)
goto end;
HostBitAdd(h, 0);
HostBit *fb = HostBitGet(h,0);
if (fb != NULL)
ret = 1;
HostFree(h);
end:
HostCleanup();
return ret;
}
static int HostBitTest02 (void)
{
int ret = 0;
HostInitConfig(TRUE);
Host *h = HostAlloc();
if (h == NULL)
goto end;
HostBit *fb = HostBitGet(h,0);
if (fb == NULL)
ret = 1;
HostFree(h);
end:
HostCleanup();
return ret;
}
static int HostBitTest03 (void)
{
int ret = 0;
HostInitConfig(TRUE);
Host *h = HostAlloc();
if (h == NULL)
goto end;
HostBitAdd(h, 0);
HostBit *fb = HostBitGet(h,0);
if (fb == NULL) {
printf("fb == NULL although it was just added: ");
goto end;
}
HostBitRemove(h, 0);
fb = HostBitGet(h,0);
if (fb != NULL) {
printf("fb != NULL although it was just removed: ");
goto end;
} else {
ret = 1;
}
HostFree(h);
end:
HostCleanup();
return ret;
}
static int HostBitTest04 (void)
{
int ret = 0;
HostInitConfig(TRUE);
Host *h = HostAlloc();
if (h == NULL)
goto end;
HostBitAdd(h, 0);
HostBitAdd(h, 1);
HostBitAdd(h, 2);
HostBitAdd(h, 3);
HostBit *fb = HostBitGet(h,0);
if (fb != NULL)
ret = 1;
HostFree(h);
end:
HostCleanup();
return ret;
}
static int HostBitTest05 (void)
{
int ret = 0;
HostInitConfig(TRUE);
Host *h = HostAlloc();
if (h == NULL)
goto end;
HostBitAdd(h, 0);
HostBitAdd(h, 1);
HostBitAdd(h, 2);
HostBitAdd(h, 3);
HostBit *fb = HostBitGet(h,1);
if (fb != NULL)
ret = 1;
HostFree(h);
end:
HostCleanup();
return ret;
}
static int HostBitTest06 (void)
{
int ret = 0;
HostInitConfig(TRUE);
Host *h = HostAlloc();
if (h == NULL)
goto end;
HostBitAdd(h, 0);
HostBitAdd(h, 1);
HostBitAdd(h, 2);
HostBitAdd(h, 3);
HostBit *fb = HostBitGet(h,2);
if (fb != NULL)
ret = 1;
HostFree(h);
end:
HostCleanup();
return ret;
}
static int HostBitTest07 (void)
{
int ret = 0;
HostInitConfig(TRUE);
Host *h = HostAlloc();
if (h == NULL)
goto end;
HostBitAdd(h, 0);
HostBitAdd(h, 1);
HostBitAdd(h, 2);
HostBitAdd(h, 3);
HostBit *fb = HostBitGet(h,3);
if (fb != NULL)
ret = 1;
HostFree(h);
end:
HostCleanup();
return ret;
}
static int HostBitTest08 (void)
{
int ret = 0;
HostInitConfig(TRUE);
Host *h = HostAlloc();
if (h == NULL)
goto end;
HostBitAdd(h, 0);
HostBitAdd(h, 1);
HostBitAdd(h, 2);
HostBitAdd(h, 3);
HostBit *fb = HostBitGet(h,0);
if (fb == NULL)
goto end;
HostBitRemove(h,0);
fb = HostBitGet(h,0);
if (fb != NULL) {
printf("fb != NULL even though it was removed: ");
goto end;
}
ret = 1;
HostFree(h);
end:
HostCleanup();
return ret;
}
static int HostBitTest09 (void)
{
int ret = 0;
HostInitConfig(TRUE);
Host *h = HostAlloc();
if (h == NULL)
goto end;
HostBitAdd(h, 0);
HostBitAdd(h, 1);
HostBitAdd(h, 2);
HostBitAdd(h, 3);
HostBit *fb = HostBitGet(h,1);
if (fb == NULL)
goto end;
HostBitRemove(h,1);
fb = HostBitGet(h,1);
if (fb != NULL) {
printf("fb != NULL even though it was removed: ");
goto end;
}
ret = 1;
HostFree(h);
end:
HostCleanup();
return ret;
}
static int HostBitTest10 (void)
{
int ret = 0;
HostInitConfig(TRUE);
Host *h = HostAlloc();
if (h == NULL)
goto end;
HostBitAdd(h, 0);
HostBitAdd(h, 1);
HostBitAdd(h, 2);
HostBitAdd(h, 3);
HostBit *fb = HostBitGet(h,2);
if (fb == NULL)
goto end;
HostBitRemove(h,2);
fb = HostBitGet(h,2);
if (fb != NULL) {
printf("fb != NULL even though it was removed: ");
goto end;
}
ret = 1;
HostFree(h);
end:
HostCleanup();
return ret;
}
static int HostBitTest11 (void)
{
int ret = 0;
HostInitConfig(TRUE);
Host *h = HostAlloc();
if (h == NULL)
goto end;
HostBitAdd(h, 0);
HostBitAdd(h, 1);
HostBitAdd(h, 2);
HostBitAdd(h, 3);
HostBit *fb = HostBitGet(h,3);
if (fb == NULL)
goto end;
HostBitRemove(h,3);
fb = HostBitGet(h,3);
if (fb != NULL) {
printf("fb != NULL even though it was removed: ");
goto end;
}
ret = 1;
HostFree(h);
end:
HostCleanup();
ret = 1;
return ret;
}
#endif /* UNITTESTS */
void HostBitRegisterTests(void)
{
#ifdef UNITTESTS
UtRegisterTest("HostBitTest01", HostBitTest01, 1);
UtRegisterTest("HostBitTest02", HostBitTest02, 1);
UtRegisterTest("HostBitTest03", HostBitTest03, 1);
UtRegisterTest("HostBitTest04", HostBitTest04, 1);
UtRegisterTest("HostBitTest05", HostBitTest05, 1);
UtRegisterTest("HostBitTest06", HostBitTest06, 1);
UtRegisterTest("HostBitTest07", HostBitTest07, 1);
UtRegisterTest("HostBitTest08", HostBitTest08, 1);
UtRegisterTest("HostBitTest09", HostBitTest09, 1);
UtRegisterTest("HostBitTest10", HostBitTest10, 1);
UtRegisterTest("HostBitTest11", HostBitTest11, 1);
#endif /* UNITTESTS */
}

@ -0,0 +1,49 @@
/* Copyright (C) 2007-2010 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 Victor Julien <victor@inliniac.net>
*/
#ifndef __HOST_BIT_H__
#define __HOST_BIT_H__
#include "host.h"
#include "util-var.h"
typedef struct HostBit_ {
uint8_t type; /* type, DETECT_HOSTBITS in this case */
uint16_t idx; /* name idx */
GenericVar *next; /* right now just implement this as a list,
* in the long run we have think of something
* faster. */
} HostBit;
void HostBitInitCtx(void);
void HostBitFree(HostBit *);
void HostBitRegisterTests(void);
int HostHasHostBits(Host *host);
void HostBitSet(Host *, uint16_t);
void HostBitUnset(Host *, uint16_t);
void HostBitToggle(Host *, uint16_t);
int HostBitIsset(Host *, uint16_t);
int HostBitIsnotset(Host *, uint16_t);
#endif /* __FLOW_BIT_H__ */

@ -29,6 +29,7 @@
#include "util-debug.h"
#include "host.h"
#include "host-storage.h"
#include "host-bit.h"
#include "util-random.h"
#include "util-misc.h"
@ -439,6 +440,12 @@ void HostLock(Host *h)
SCMutexLock(&h->m);
}
void HostUnlock(Host *h)
{
SCMutexUnlock(&h->m);
}
/* HostGetHostFromHash
*
* Hash retrieval function for hosts. Looks up the hash bucket containing the

@ -148,5 +148,10 @@ void HostPrintStats (void);
void HostRegisterUnittests(void);
Host *HostAlloc();
void HostFree();
void HostUnlock(Host *h);
#endif /* __HOST_H__ */

@ -60,6 +60,7 @@
#include "pkt-var.h"
#include "host.h"
#include "host-bit.h"
#include "ippair.h"
#include "unix-manager.h"
@ -171,6 +172,8 @@ void RunUnittests(int list_unittests, char *regex_arg)
DetectEngineRegisterAppInspectionEngines();
HostBitInitCtx();
StorageFinalize();
/* test and initialize the unittesting subsystem */
if(regex_arg == NULL){
@ -194,6 +197,7 @@ void RunUnittests(int list_unittests, char *regex_arg)
ByteRegisterTests();
MpmRegisterTests();
FlowBitRegisterTests();
HostBitRegisterTests();
SCPerfRegisterTests();
DecodePPPRegisterTests();
DecodeVLANRegisterTests();

@ -130,6 +130,7 @@
#include "flow-var.h"
#include "flow-bit.h"
#include "pkt-var.h"
#include "host-bit.h"
#include "ippair.h"
#include "host.h"
@ -2097,6 +2098,7 @@ static int PostConfLoadedSetup(SCInstance *suri)
TagInitCtx();
ThresholdInit();
HostBitInitCtx();
if (DetectAddressTestConfVars() < 0) {
SCLogError(SC_ERR_INVALID_YAML_CONF_ENTRY,

@ -31,6 +31,7 @@
#include "flow-var.h"
#include "flow-bit.h"
#include "pkt-var.h"
#include "host-bit.h"
#include "util-debug.h"
@ -50,6 +51,13 @@ void GenericVarFree(GenericVar *gv)
FlowBitFree(fb);
break;
}
case DETECT_HOSTBITS:
{
HostBit *fb = (HostBit *)gv;
//printf("GenericVarFree: fb %p, removing\n", fb);
HostBitFree(fb);
break;
}
case DETECT_FLOWVAR:
{
FlowVar *fv = (FlowVar *)gv;

Loading…
Cancel
Save