Bug #106 » 0002-Moving-back-to-.c-files-the-functions-that-gcc-canno.patch
src/counters.c | ||
---|---|---|
}
|
||
/**
|
||
* \brief Adds a value of type uint64_t to the local counter.
|
||
*
|
||
* \param id ID of the counter as set by the API
|
||
* \param pca Counter array that holds the local counter for this TM
|
||
* \param x Value to add to this local counter
|
||
*/
|
||
void SCPerfCounterAddUI64(uint16_t id, SCPerfCounterArray *pca, uint64_t x)
|
||
{
|
||
if (!pca) {
|
||
SCLogDebug("counterarray is NULL");
|
||
return;
|
||
}
|
||
if ((id < 1) || (id > pca->size)) {
|
||
SCLogDebug("counter doesn't exist");
|
||
return;
|
||
}
|
||
switch (pca->head[id].pc->value->type) {
|
||
case SC_PERF_TYPE_UINT64:
|
||
pca->head[id].ui64_cnt += x;
|
||
break;
|
||
case SC_PERF_TYPE_DOUBLE:
|
||
pca->head[id].d_cnt += x;
|
||
break;
|
||
}
|
||
if (pca->head[id].syncs == ULONG_MAX) {
|
||
pca->head[id].syncs = 0;
|
||
pca->head[id].wrapped_syncs++;
|
||
}
|
||
pca->head[id].syncs++;
|
||
return;
|
||
}
|
||
/**
|
||
* \brief Increments the local counter
|
||
*
|
||
* \param id Index of the counter in the counter array
|
||
* \param pca Counter array that holds the local counters for this TM
|
||
*/
|
||
void SCPerfCounterIncr(uint16_t id, SCPerfCounterArray *pca)
|
||
{
|
||
if (pca == NULL) {
|
||
SCLogDebug("counterarray is NULL");
|
||
return;
|
||
}
|
||
if ((id < 1) || (id > pca->size)) {
|
||
SCLogDebug("counter doesn't exist");
|
||
return;
|
||
}
|
||
switch (pca->head[id].pc->value->type) {
|
||
case SC_PERF_TYPE_UINT64:
|
||
pca->head[id].ui64_cnt++;
|
||
break;
|
||
case SC_PERF_TYPE_DOUBLE:
|
||
pca->head[id].d_cnt++;
|
||
break;
|
||
}
|
||
if (pca->head[id].syncs == ULONG_MAX) {
|
||
pca->head[id].syncs = 0;
|
||
pca->head[id].wrapped_syncs++;
|
||
}
|
||
pca->head[id].syncs++;
|
||
return;
|
||
}
|
||
/**
|
||
* \brief Adds a value of type double to the local counter
|
||
*
|
||
* \param id ID of the counter as set by the API
|
||
* \param pca Counter array that holds the local counter for this TM
|
||
* \param x Value to add to this local counter
|
||
*/
|
||
void SCPerfCounterAddDouble(uint16_t id, SCPerfCounterArray *pca, double x)
|
||
{
|
||
if (!pca) {
|
||
SCLogDebug("counterarray is NULL");
|
||
return;
|
||
}
|
||
if ((id < 1) || (id > pca->size)) {
|
||
SCLogDebug("counter doesn't exist");
|
||
return;
|
||
}
|
||
/* incase you are trying to add a double to a counter of type SC_PERF_TYPE_UINT64
|
||
* it will be truncated */
|
||
switch (pca->head[id].pc->value->type) {
|
||
case SC_PERF_TYPE_UINT64:
|
||
pca->head[id].ui64_cnt += x;
|
||
break;
|
||
case SC_PERF_TYPE_DOUBLE:
|
||
pca->head[id].d_cnt += x;
|
||
break;
|
||
}
|
||
if (pca->head[id].syncs == ULONG_MAX) {
|
||
pca->head[id].syncs = 0;
|
||
pca->head[id].wrapped_syncs++;
|
||
}
|
||
pca->head[id].syncs++;
|
||
return;
|
||
}
|
||
/**
|
||
* \brief Releases the resources alloted to the output context of the Perf
|
||
* Counter API
|
||
*/
|
src/counters.h | ||
---|---|---|
SCPerfCounterArray *SCPerfGetCounterArrayRange(uint16_t, uint16_t, SCPerfContext *);
|
||
SCPerfCounterArray * SCPerfGetAllCountersArray(SCPerfContext *);
|
||
int SCPerfCounterDisplay(uint16_t, SCPerfContext *, int);
|
||
void SCPerfCounterAddDouble(uint16_t, SCPerfCounterArray *, double);
|
||
void SCPerfCounterIncr(uint16_t, SCPerfCounterArray *);
|
||
void SCPerfCounterAddUI64(uint16_t, SCPerfCounterArray *, uint64_t);
|
||
int SCPerfUpdateCounterArray(SCPerfCounterArray *, SCPerfContext *, int);
|
||
... | ... | |
return;
|
||
}
|
||
/**
|
||
* \brief Adds a value of type double to the local counter
|
||
*
|
||
* \param id ID of the counter as set by the API
|
||
* \param pca Counter array that holds the local counter for this TM
|
||
* \param x Value to add to this local counter
|
||
*/
|
||
static inline void SCPerfCounterAddDouble(uint16_t id, SCPerfCounterArray *pca, double x)
|
||
{
|
||
if (!pca) {
|
||
SCLogDebug("counterarray is NULL");
|
||
return;
|
||
}
|
||
if ((id < 1) || (id > pca->size)) {
|
||
SCLogDebug("counter doesn't exist");
|
||
return;
|
||
}
|
||
/* incase you are trying to add a double to a counter of type SC_PERF_TYPE_UINT64
|
||
* it will be truncated */
|
||
switch (pca->head[id].pc->value->type) {
|
||
case SC_PERF_TYPE_UINT64:
|
||
pca->head[id].ui64_cnt += x;
|
||
break;
|
||
case SC_PERF_TYPE_DOUBLE:
|
||
pca->head[id].d_cnt += x;
|
||
break;
|
||
}
|
||
if (pca->head[id].syncs == ULONG_MAX) {
|
||
pca->head[id].syncs = 0;
|
||
pca->head[id].wrapped_syncs++;
|
||
}
|
||
pca->head[id].syncs++;
|
||
return;
|
||
}
|
||
/**
|
||
* \brief Adds a value of type uint64_t to the local counter.
|
||
*
|
||
* \param id ID of the counter as set by the API
|
||
* \param pca Counter array that holds the local counter for this TM
|
||
* \param x Value to add to this local counter
|
||
*/
|
||
static inline void SCPerfCounterAddUI64(uint16_t id, SCPerfCounterArray *pca, uint64_t x)
|
||
{
|
||
if (!pca) {
|
||
SCLogDebug("counterarray is NULL");
|
||
return;
|
||
}
|
||
if ((id < 1) || (id > pca->size)) {
|
||
SCLogDebug("counter doesn't exist");
|
||
return;
|
||
}
|
||
switch (pca->head[id].pc->value->type) {
|
||
case SC_PERF_TYPE_UINT64:
|
||
pca->head[id].ui64_cnt += x;
|
||
break;
|
||
case SC_PERF_TYPE_DOUBLE:
|
||
pca->head[id].d_cnt += x;
|
||
break;
|
||
}
|
||
if (pca->head[id].syncs == ULONG_MAX) {
|
||
pca->head[id].syncs = 0;
|
||
pca->head[id].wrapped_syncs++;
|
||
}
|
||
pca->head[id].syncs++;
|
||
return;
|
||
}
|
||
/**
|
||
* \brief Increments the local counter
|
||
*
|
||
* \param id Index of the counter in the counter array
|
||
* \param pca Counter array that holds the local counters for this TM
|
||
*/
|
||
static inline void SCPerfCounterIncr(uint16_t id, SCPerfCounterArray *pca)
|
||
{
|
||
if (pca == NULL) {
|
||
SCLogDebug("counterarray is NULL");
|
||
return;
|
||
}
|
||
if ((id < 1) || (id > pca->size)) {
|
||
SCLogDebug("counter doesn't exist");
|
||
return;
|
||
}
|
||
switch (pca->head[id].pc->value->type) {
|
||
case SC_PERF_TYPE_UINT64:
|
||
pca->head[id].ui64_cnt++;
|
||
break;
|
||
case SC_PERF_TYPE_DOUBLE:
|
||
pca->head[id].d_cnt++;
|
||
break;
|
||
}
|
||
if (pca->head[id].syncs == ULONG_MAX) {
|
||
pca->head[id].syncs = 0;
|
||
pca->head[id].wrapped_syncs++;
|
||
}
|
||
pca->head[id].syncs++;
|
||
return;
|
||
}
|
||
#endif /* __COUNTERS_H__ */
|
src/decode.c | ||
---|---|---|
}
|
||
}
|
||
/** \brief Set the No payload inspection Flag for the packet.
|
||
*
|
||
* \param p Packet to set the flag in
|
||
*/
|
||
void DecodeSetNoPayloadInspectionFlag(Packet *p) {
|
||
SCEnter();
|
||
p->flags |= PKT_NOPAYLOAD_INSPECTION;
|
||
SCReturn;
|
||
}
|
||
void DecodeRegisterPerfCounters(DecodeThreadVars *dtv, ThreadVars *tv)
|
||
{
|
||
/* register counters */
|
src/decode.h | ||
---|---|---|
#define PKT_NOPACKET_INSPECTION 0x01 /**< Flag to indicate that packet header or contents should not be inspected*/
|
||
#define PKT_NOPAYLOAD_INSPECTION 0x02 /**< Flag to indicate that packet contents should not be inspected*/
|
||
void DecodeSetNoPayloadInspectionFlag(Packet *);
|
||
/** ------ inline functions ------ */
|
||
static inline void DecodeSetNoPayloadInspectionFlag(Packet *);
|
||
static inline void DecodeSetNoPacketInspectionFlag(Packet *);
|
||
/** \brief Set the No payload inspection Flag for the packet.
|
||
*
|
||
* \param p Packet to set the flag in
|
||
*/
|
||
static inline void DecodeSetNoPayloadInspectionFlag(Packet *p) {
|
||
SCEnter();
|
||
p->flags |= PKT_NOPAYLOAD_INSPECTION;
|
||
SCReturn;
|
||
}
|
||
/** \brief Set the No packet inspection Flag for the packet.
|
||
*
|
||
* \param p Packet to set the flag in
|
src/detect-content.c | ||
---|---|---|
}
|
||
#endif
|
||
int TestOffsetDepth(MpmMatch *m, DetectContentData *co, uint16_t pktoff) {
|
||
SCEnter();
|
||
if (m->offset >= pktoff) {
|
||
if (co->offset == 0 || (m->offset >= co->offset)) {
|
||
if (co->depth == 0 || ((m->offset + co->content_len) <= co->depth)) {
|
||
SCLogDebug("depth %" PRIu32 ", offset %" PRIu32 ", m->offset "
|
||
"%" PRIu32 ", return 1", co->depth, co->offset,
|
||
m->offset);
|
||
/* If we reach this point, it means we have obtained a depth and
|
||
* offset match, which indicates that we have a FAILURE if the
|
||
* content is negated, and SUCCESS if the content is not negated */
|
||
if (co->negated == 1)
|
||
SCReturnInt(0);
|
||
else
|
||
SCReturnInt(1);
|
||
} else {
|
||
/* We have success so far with offset, but a failure with
|
||
* depth. We can return a match at the bottom of this function
|
||
* for negated_content, provided offset is 0. If offset
|
||
* isn't 0 for negated_content, we have a failure and we return
|
||
* a no match here. If the content is not negated, we have a no
|
||
* match, which we return at the end of this function. */
|
||
if (co->offset && co->negated == 1)
|
||
SCReturnInt(0);
|
||
}
|
||
} else {
|
||
/* If offset fails, and if the content is negated, we check if depth
|
||
* succeeds. If it succeeds, we have a no match for negated content.
|
||
* Else we have a success for negated content. If the content is
|
||
* not negated, we go down till the end and return a no match. */
|
||
if (co->negated == 1) {
|
||
if (co->offset != 0) {
|
||
SCReturnInt(1);
|
||
} else if (co->depth && (m->offset+co->content_len) <= co->depth) {
|
||
SCLogDebug("depth %" PRIu32 ", offset %" PRIu32 ", m->offset %" PRIu32 ", "
|
||
"return 0", co->depth, co->offset, m->offset);
|
||
SCReturnInt(0);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
SCLogDebug("depth %" PRIu32 ", offset %" PRIu32 ", m->offset %" PRIu32 ", "
|
||
"return 0 (or 1 if negated)", co->depth, co->offset, m->offset);
|
||
/* If we reach this point, we have a match for negated content and no match
|
||
* otherwise */
|
||
if (co->negated == 1)
|
||
SCReturnInt(1);
|
||
else
|
||
SCReturnInt(0);
|
||
}
|
||
/**
|
||
* \brief test the within, distance, offset and depth of a match
|
||
*
|
src/detect-content.h | ||
---|---|---|
int DetectContentPropagateModifiers(SigMatch *);
|
||
void DetectContentFree(void *);
|
||
/** ------ inline functions ------ */
|
||
static inline int
|
||
TestOffsetDepth(MpmMatch *m, DetectContentData *co, uint16_t pktoff) {
|
||
SCEnter();
|
||
if (m->offset >= pktoff) {
|
||
if (co->offset == 0 || (m->offset >= co->offset)) {
|
||
if (co->depth == 0 || ((m->offset + co->content_len) <= co->depth)) {
|
||
SCLogDebug("depth %" PRIu32 ", offset %" PRIu32 ", m->offset "
|
||
"%" PRIu32 ", return 1", co->depth, co->offset,
|
||
m->offset);
|
||
/* If we reach this point, it means we have obtained a depth and
|
||
* offset match, which indicates that we have a FAILURE if the
|
||
* content is negated, and SUCCESS if the content is not negated */
|
||
if (co->negated == 1)
|
||
SCReturnInt(0);
|
||
else
|
||
SCReturnInt(1);
|
||
} else {
|
||
/* We have success so far with offset, but a failure with
|
||
* depth. We can return a match at the bottom of this function
|
||
* for negated_content, provided offset is 0. If offset
|
||
* isn't 0 for negated_content, we have a failure and we return
|
||
* a no match here. If the content is not negated, we have a no
|
||
* match, which we return at the end of this function. */
|
||
if (co->offset && co->negated == 1)
|
||
SCReturnInt(0);
|
||
}
|
||
} else {
|
||
/* If offset fails, and if the content is negated, we check if depth
|
||
* succeeds. If it succeeds, we have a no match for negated content.
|
||
* Else we have a success for negated content. If the content is
|
||
* not negated, we go down till the end and return a no match. */
|
||
if (co->negated == 1) {
|
||
if (co->offset != 0) {
|
||
SCReturnInt(1);
|
||
} else if (co->depth && (m->offset+co->content_len) <= co->depth) {
|
||
SCLogDebug("depth %" PRIu32 ", offset %" PRIu32 ", m->offset %" PRIu32 ", "
|
||
"return 0", co->depth, co->offset, m->offset);
|
||
SCReturnInt(0);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
SCLogDebug("depth %" PRIu32 ", offset %" PRIu32 ", m->offset %" PRIu32 ", "
|
||
"return 0 (or 1 if negated)", co->depth, co->offset, m->offset);
|
||
/* If we reach this point, we have a match for negated content and no match
|
||
* otherwise */
|
||
if (co->negated == 1)
|
||
SCReturnInt(1);
|
||
else
|
||
SCReturnInt(0);
|
||
}
|
||
int TestOffsetDepth(MpmMatch *, DetectContentData *, uint16_t);
|
||
#endif /* __DETECT_CONTENT_H__ */
|
src/detect-stream_size.c | ||
---|---|---|
}
|
||
/**
|
||
* \brief Function to comapre the stream size against defined size in the user
|
||
* options.
|
||
*
|
||
* \param diff The stream size of server or client stream.
|
||
* \param stream_size User defined stream size
|
||
* \param mode The mode defined by user.
|
||
*
|
||
* \retval 1 on success and 0 on failure.
|
||
*/
|
||
int DetectStreamSizeCompare (uint32_t diff, uint32_t stream_size, uint8_t mode) {
|
||
int ret = 0;
|
||
switch (mode) {
|
||
case DETECTSSIZE_LT:
|
||
if (diff < stream_size)
|
||
ret = 1;
|
||
break;
|
||
case DETECTSSIZE_LEQ:
|
||
if (diff <= stream_size)
|
||
ret = 1;
|
||
break;
|
||
case DETECTSSIZE_EQ:
|
||
if (diff == stream_size)
|
||
ret = 1;
|
||
break;
|
||
case DETECTSSIZE_NEQ:
|
||
if (diff != stream_size)
|
||
ret = 1;
|
||
break;
|
||
case DETECTSSIZE_GEQ:
|
||
if (diff >= stream_size)
|
||
ret = 1;
|
||
break;
|
||
case DETECTSSIZE_GT:
|
||
if (diff > stream_size)
|
||
ret = 1;
|
||
break;
|
||
}
|
||
return ret;
|
||
}
|
||
/**
|
||
* \brief This function is used to match Stream size rule option on a packet with those passed via stream_size:
|
||
*
|
||
* \param t pointer to thread vars
|
src/detect-stream_size.h | ||
---|---|---|
}DetectStreamSizeData;
|
||
void DetectStreamSizeRegister(void);
|
||
int DetectStreamSizeCompare (uint32_t, uint32_t, uint8_t);
|
||
/** ------ inline functions ------ */
|
||
/**
|
||
* \brief Function to comapre the stream size against defined size in the user
|
||
* options.
|
||
*
|
||
* \param diff The stream size of server or client stream.
|
||
* \param stream_size User defined stream size
|
||
* \param mode The mode defined by user.
|
||
*
|
||
* \retval 1 on success and 0 on failure.
|
||
*/
|
||
static inline int DetectStreamSizeCompare (uint32_t diff, uint32_t stream_size, uint8_t mode) {
|
||
int ret = 0;
|
||
switch (mode) {
|
||
case DETECTSSIZE_LT:
|
||
if (diff < stream_size)
|
||
ret = 1;
|
||
break;
|
||
case DETECTSSIZE_LEQ:
|
||
if (diff <= stream_size)
|
||
ret = 1;
|
||
break;
|
||
case DETECTSSIZE_EQ:
|
||
if (diff == stream_size)
|
||
ret = 1;
|
||
break;
|
||
case DETECTSSIZE_NEQ:
|
||
if (diff != stream_size)
|
||
ret = 1;
|
||
break;
|
||
case DETECTSSIZE_GEQ:
|
||
if (diff >= stream_size)
|
||
ret = 1;
|
||
break;
|
||
case DETECTSSIZE_GT:
|
||
if (diff > stream_size)
|
||
ret = 1;
|
||
break;
|
||
}
|
||
return ret;
|
||
}
|
||
#endif /* _DETECT_STREAM_SIZE_H */
|
||
src/detect-uricontent.c | ||
---|---|---|
p->http_uri.cnt = 0;
|
||
}
|
||
/* This function is called recursively (if necessary) to be able
|
||
* to determite whether or not a chain of content matches connected
|
||
* with 'within' and 'distance' options fully matches. The reason it
|
||
* was done like this is to make sure we can handle partial matches
|
||
* that turn out to fail being followed by full matches later in the
|
||
* packet. This adds some runtime complexity however. */
|
||
int TestWithinDistanceOffsetDepthUri(ThreadVars *t,
|
||
DetectEngineThreadCtx *det_ctx,
|
||
MpmMatch *m, SigMatch *nsm)
|
||
{
|
||
//printf("test_nextsigmatch m:%p, nsm:%p\n", m,nsm);
|
||
if (nsm == NULL)
|
||
return 1;
|
||
DetectUricontentData *co = (DetectUricontentData *)nsm->ctx;
|
||
MpmMatch *nm = det_ctx->mtcu.match[co->id].top;
|
||
for (; nm; nm = nm->next) {
|
||
SCLogDebug("(nm->offset+1) %" PRIu32 ", (m->offset+1) %" PRIu32 "",
|
||
(nm->offset+1), (m->offset+1));
|
||
if ((co->within == 0 || (co->within &&
|
||
((nm->offset+1) > (m->offset+1)) &&
|
||
((nm->offset+1) - (m->offset+1) <= co->within))))
|
||
{
|
||
SCLogDebug("WITHIN (nm->offset+1) %" PRIu32 ", (m->offset+1) "
|
||
"%" PRIu32 "", (nm->offset+1), (m->offset+1));
|
||
if (co->distance == 0 || (co->distance &&
|
||
((nm->offset+1) > (m->offset+1)) &&
|
||
((nm->offset+1) - (m->offset+1) >= co->distance)))
|
||
{
|
||
if (TestOffsetDepthUri(nm, co) == 1) {
|
||
SCLogDebug("DISTANCE (nm->offset+1) %" PRIu32 ", "
|
||
"(m->offset+1) %" PRIu32 "", (nm->offset+1),
|
||
(m->offset+1));
|
||
return TestWithinDistanceOffsetDepthUri(t, det_ctx, nm,
|
||
nsm->next);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return 0;
|
||
}
|
||
/**
|
||
* \brief Checks if the packet sent as the argument, has a uricontent which
|
src/detect-uricontent.h | ||
---|---|---|
/* prototypes */
|
||
void DetectUricontentRegister (void);
|
||
uint32_t DetectUricontentMaxId(DetectEngineCtx *);
|
||
void PktHttpUriFree(Packet *p);
|
||
uint32_t DetectUricontentInspectMpm(ThreadVars *th_v, DetectEngineThreadCtx *det_ctx, void *alstate);
|
||
void PktHttpUriFree(Packet *);
|
||
uint32_t DetectUricontentInspectMpm(ThreadVars *, DetectEngineThreadCtx *, void *);
|
||
int TestWithinDistanceOffsetDepthUri(ThreadVars *,
|
||
DetectEngineThreadCtx *,
|
||
MpmMatch *, SigMatch *);
|
||
/** ------ inline functions ------ */
|
||
... | ... | |
return 0;
|
||
}
|
||
/* This function is called recursively (if necessary) to be able
|
||
* to determite whether or not a chain of content matches connected
|
||
* with 'within' and 'distance' options fully matches. The reason it
|
||
* was done like this is to make sure we can handle partial matches
|
||
* that turn out to fail being followed by full matches later in the
|
||
* packet. This adds some runtime complexity however. */
|
||
static inline int TestWithinDistanceOffsetDepthUri(ThreadVars *t,
|
||
DetectEngineThreadCtx *det_ctx,
|
||
MpmMatch *m, SigMatch *nsm)
|
||
{
|
||
//printf("test_nextsigmatch m:%p, nsm:%p\n", m,nsm);
|
||
if (nsm == NULL)
|
||
return 1;
|
||
DetectUricontentData *co = (DetectUricontentData *)nsm->ctx;
|
||
MpmMatch *nm = det_ctx->mtcu.match[co->id].top;
|
||
for (; nm; nm = nm->next) {
|
||
SCLogDebug("(nm->offset+1) %" PRIu32 ", (m->offset+1) %" PRIu32 "",
|
||
(nm->offset+1), (m->offset+1));
|
||
if ((co->within == 0 || (co->within &&
|
||
((nm->offset+1) > (m->offset+1)) &&
|
||
((nm->offset+1) - (m->offset+1) <= co->within))))
|
||
{
|
||
SCLogDebug("WITHIN (nm->offset+1) %" PRIu32 ", (m->offset+1) "
|
||
"%" PRIu32 "", (nm->offset+1), (m->offset+1));
|
||
if (co->distance == 0 || (co->distance &&
|
||
((nm->offset+1) > (m->offset+1)) &&
|
||
((nm->offset+1) - (m->offset+1) >= co->distance)))
|
||
{
|
||
if (TestOffsetDepthUri(nm, co) == 1) {
|
||
SCLogDebug("DISTANCE (nm->offset+1) %" PRIu32 ", "
|
||
"(m->offset+1) %" PRIu32 "", (nm->offset+1),
|
||
(m->offset+1));
|
||
return TestWithinDistanceOffsetDepthUri(t, det_ctx, nm,
|
||
nsm->next);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return 0;
|
||
}
|
||
static inline int DoDetectUricontent(ThreadVars *t, DetectEngineThreadCtx *det_ctx,
|
||
Packet *p, SigMatch *sm,
|
||
DetectUricontentData *co)
|
src/detect.c | ||
---|---|---|
SCReturnInt(0);
|
||
}
|
||
SigGroupHead *SigMatchSignaturesGetSgh(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p) {
|
||
SCEnter();
|
||
int ds,f;
|
||
SigGroupHead *sgh = NULL;
|
||
/* select the dsize_gh */
|
||
if (p->payload_len <= 100)
|
||
ds = 0;
|
||
else
|
||
ds = 1;
|
||
/* select the flow_gh */
|
||
if (p->flowflags & FLOW_PKT_TOCLIENT)
|
||
f = 0;
|
||
else
|
||
f = 1;
|
||
SCLogDebug("ds %d, f %d", ds, f);
|
||
/* find the right mpm instance */
|
||
DetectAddress *ag = DetectAddressLookupInHead(de_ctx->dsize_gh[ds].flow_gh[f].src_gh[p->proto],&p->src);
|
||
if (ag != NULL) {
|
||
/* source group found, lets try a dst group */
|
||
ag = DetectAddressLookupInHead(ag->dst_gh,&p->dst);
|
||
if (ag != NULL) {
|
||
if (ag->port == NULL) {
|
||
SCLogDebug("we don't have ports");
|
||
sgh = ag->sh;
|
||
} else {
|
||
SCLogDebug("we have ports");
|
||
DetectPort *sport = DetectPortLookupGroup(ag->port,p->sp);
|
||
if (sport != NULL) {
|
||
DetectPort *dport = DetectPortLookupGroup(sport->dst_ph,p->dp);
|
||
if (dport != NULL) {
|
||
sgh = dport->sh;
|
||
} else {
|
||
SCLogDebug("no dst port group found for the packet");
|
||
}
|
||
} else {
|
||
SCLogDebug("no src port group found for the packet");
|
||
}
|
||
}
|
||
} else {
|
||
SCLogDebug("no dst address group found for the packet");
|
||
}
|
||
} else {
|
||
SCLogDebug("no src address group found for the packet");
|
||
}
|
||
SCReturnPtr(sgh, "SigGroupHead");
|
||
}
|
||
/**
|
||
* \brief Check if a certain sid alerted, this is used in the test functions
|
||
*
|
src/detect.h | ||
---|---|---|
int PacketAlertCheck(Packet *p, uint32_t sid);
|
||
int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx,
|
||
DetectEngineThreadCtx *det_ctx, Packet *p);
|
||
SigGroupHead *SigMatchSignaturesGetSgh(ThreadVars *, DetectEngineCtx *,
|
||
DetectEngineThreadCtx *, Packet *);
|
||
int PacketAlertCheck(Packet *p, uint32_t sid);
|
||
int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx,
|
||
DetectEngineThreadCtx *det_ctx, Packet *p);
|
||
int SignatureIsIPOnly(DetectEngineCtx *de_ctx, Signature *s);
|
||
/** ------ inline functions ------ */
|
||
static inline SigGroupHead *SigMatchSignaturesGetSgh(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p) {
|
||
SCEnter();
|
||
int ds,f;
|
||
SigGroupHead *sgh = NULL;
|
||
/* select the dsize_gh */
|
||
if (p->payload_len <= 100)
|
||
ds = 0;
|
||
else
|
||
ds = 1;
|
||
/* select the flow_gh */
|
||
if (p->flowflags & FLOW_PKT_TOCLIENT)
|
||
f = 0;
|
||
else
|
||
f = 1;
|
||
SCLogDebug("ds %d, f %d", ds, f);
|
||
/* find the right mpm instance */
|
||
DetectAddress *ag = DetectAddressLookupInHead(de_ctx->dsize_gh[ds].flow_gh[f].src_gh[p->proto],&p->src);
|
||
if (ag != NULL) {
|
||
/* source group found, lets try a dst group */
|
||
ag = DetectAddressLookupInHead(ag->dst_gh,&p->dst);
|
||
if (ag != NULL) {
|
||
if (ag->port == NULL) {
|
||
SCLogDebug("we don't have ports");
|
||
sgh = ag->sh;
|
||
} else {
|
||
SCLogDebug("we have ports");
|
||
DetectPort *sport = DetectPortLookupGroup(ag->port,p->sp);
|
||
if (sport != NULL) {
|
||
DetectPort *dport = DetectPortLookupGroup(sport->dst_ph,p->dp);
|
||
if (dport != NULL) {
|
||
sgh = dport->sh;
|
||
} else {
|
||
SCLogDebug("no dst port group found for the packet");
|
||
}
|
||
} else {
|
||
SCLogDebug("no src port group found for the packet");
|
||
}
|
||
}
|
||
} else {
|
||
SCLogDebug("no dst address group found for the packet");
|
||
}
|
||
} else {
|
||
SCLogDebug("no src address group found for the packet");
|
||
}
|
||
SCReturnPtr(sgh, "SigGroupHead");
|
||
}
|
||
#endif /* __DETECT_H__ */
|
||
src/suricata.c | ||
---|---|---|
return 0;
|
||
}
|
||
static void SignalHandlerSigint(/*@unused@*/ int sig) { sigint_count = 1; sigflags |= SURICATA_SIGINT; }
|
||
static void SignalHandlerSigterm(/*@unused@*/ int sig) { sigterm_count = 1; sigflags |= SURICATA_SIGTERM; }
|
||
static void SignalHandlerSighup(/*@unused@*/ int sig) { sighup_count = 1; sigflags |= SURICATA_SIGHUP; }
|
||
/* Added sig = 0 just to avoid warnings of not used
|
||
* (it's a local copy, should not affect) */
|
||
static void SignalHandlerSigint(/*@unused@*/ int sig) { sigint_count = 1; sigflags |= SURICATA_SIGINT; sig = 0; }
|
||
static void SignalHandlerSigterm(/*@unused@*/ int sig) { sigterm_count = 1; sigflags |= SURICATA_SIGTERM; sig = 0; }
|
||
static void SignalHandlerSighup(/*@unused@*/ int sig) { sighup_count = 1; sigflags |= SURICATA_SIGHUP; sig = 0; }
|
||
#ifdef DBG_MEM_ALLOC
|
||
#ifndef _GLOBAL_MEM_
|
src/tm-threads.c | ||
---|---|---|
/* 1 slot functions */
|
||
void TmThreadsSetFlag(ThreadVars *tv, uint8_t flag) {
|
||
if (SCSpinLock(&tv->flags_spinlock) != 0) {
|
||
SCLogError(SC_ERR_SPINLOCK,"spin lock errno=%d",errno);
|
||
return;
|
||
}
|
||
tv->flags |= flag;
|
||
SCSpinUnlock(&tv->flags_spinlock);
|
||
}
|
||
/** \retval 1 flag is set
|
||
* \retval 0 flag is not set
|
||
*/
|
||
int TmThreadsCheckFlag(ThreadVars *tv, uint8_t flag) {
|
||
int r;
|
||
if (SCSpinLock(&tv->flags_spinlock) != 0) {
|
||
SCLogError(SC_ERR_SPINLOCK,"spin lock errno=%d",errno);
|
||
return 0;
|
||
}
|
||
r = (tv->flags & flag);
|
||
SCSpinUnlock(&tv->flags_spinlock);
|
||
return r;
|
||
}
|
||
void TmThreadsUnsetFlag(ThreadVars *tv, uint8_t flag) {
|
||
if (SCSpinLock(&tv->flags_spinlock) != 0) {
|
||
SCLogError(SC_ERR_SPINLOCK,"spin lock errno=%d",errno);
|
||
return;
|
||
}
|
||
tv->flags &= ~flag;
|
||
SCSpinUnlock(&tv->flags_spinlock);
|
||
}
|
||
void *TmThreadsSlot1NoIn(void *td) {
|
||
ThreadVars *tv = (ThreadVars *)td;
|
||
Tm1Slot *s = (Tm1Slot *)tv->tm_slots;
|
src/tm-threads.h | ||
---|---|---|
TmEcode TmThreadSetThreadPriority(ThreadVars *, int);
|
||
TmEcode TmThreadSetupOptions(ThreadVars *);
|
||
void TmThreadSetPrio(ThreadVars *);
|
||
void TmThreadsSetFlag(ThreadVars *, uint8_t);
|
||
void TmThreadInitMC(ThreadVars *);
|
||
void TmThreadTestThreadUnPaused(ThreadVars *);
|
||
... | ... | |
void TmThreadPauseThreads(void);
|
||
void TmThreadCheckThreadState(void);
|
||
TmEcode TmThreadWaitOnThreadInit(void);
|
||
static inline int TmThreadsCheckFlag(ThreadVars *, uint8_t);
|
||
static inline void TmThreadsSetFlag(ThreadVars *, uint8_t);
|
||
ThreadVars *TmThreadsGetCallingThread(void);
|
||
int TmThreadsCheckFlag(ThreadVars *, uint8_t);
|
||
void TmThreadsUnsetFlag(ThreadVars *, uint8_t);
|
||
/** ------ inline functions ------ */
|
||
static inline TmEcode TmThreadsSlotVarRun (ThreadVars *, Packet *, TmSlot *);
|
||
/** \retval 1 flag is set
|
||
* \retval 0 flag is not set
|
||
*/
|
||
static inline int TmThreadsCheckFlag(ThreadVars *tv, uint8_t flag) {
|
||
int r;
|
||
if (SCSpinLock(&tv->flags_spinlock) != 0) {
|
||
SCLogError(SC_ERR_SPINLOCK,"spin lock errno=%d",errno);
|
||
return 0;
|
||
}
|
||
r = (tv->flags & flag);
|
||
SCSpinUnlock(&tv->flags_spinlock);
|
||
return r;
|
||
}
|
||
static inline void TmThreadsSetFlag(ThreadVars *tv, uint8_t flag) {
|
||
if (SCSpinLock(&tv->flags_spinlock) != 0) {
|
||
SCLogError(SC_ERR_SPINLOCK,"spin lock errno=%d",errno);
|
||
return;
|
||
}
|
||
tv->flags |= flag;
|
||
SCSpinUnlock(&tv->flags_spinlock);
|
||
}
|
||
static inline void TmThreadsUnsetFlag(ThreadVars *tv, uint8_t flag) {
|
||
if (SCSpinLock(&tv->flags_spinlock) != 0) {
|
||
SCLogError(SC_ERR_SPINLOCK,"spin lock errno=%d",errno);
|
||
return;
|
||
}
|
||
tv->flags &= ~flag;
|
||
SCSpinUnlock(&tv->flags_spinlock);
|
||
}
|
||
/* separate run function so we can call it recursively */
|
||
static inline TmEcode TmThreadsSlotVarRun (ThreadVars *tv, Packet *p, TmSlot *slot) {
|
||
TmEcode r = TM_ECODE_OK;
|
src/util-bloomfilter.c | ||
---|---|---|
return 0;
|
||
}
|
||
inline int BloomFilterTest(BloomFilter *bf, void *data, uint16_t datalen) {
|
||
uint8_t iter = 0;
|
||
uint32_t hash = 0;
|
||
int hit = 1;
|
||
for (iter = 0; iter < bf->hash_iterations; iter++) {
|
||
hash = bf->Hash(data, datalen, iter, bf->bitarray_size);
|
||
if (!(bf->bitarray[hash/8] & (1<<hash%8))) {
|
||
hit = 0;
|
||
break;
|
||
}
|
||
}
|
||
return hit;
|
||
}
|
||
uint32_t BloomFilterMemoryCnt(BloomFilter *bf) {
|
||
if (bf == NULL)
|
||
return 0;
|
src/util-bloomfilter.h | ||
---|---|---|
void BloomFilterFree(BloomFilter *);
|
||
void BloomFilterPrint(BloomFilter *);
|
||
int BloomFilterAdd(BloomFilter *, void *, uint16_t);
|
||
inline int BloomFilterTest(BloomFilter *, void *, uint16_t);
|
||
uint32_t BloomFilterMemoryCnt(BloomFilter *);
|
||
uint32_t BloomFilterMemorySize(BloomFilter *);
|
||
void BloomFilterRegisterTests(void);
|
||
/** ---- Inline functions ---- */
|
||
static inline int BloomFilterTest(BloomFilter *, void *, uint16_t);
|
||
static inline int BloomFilterTest(BloomFilter *bf, void *data, uint16_t datalen) {
|
||
uint8_t iter = 0;
|
||
uint32_t hash = 0;
|
||
int hit = 1;
|
||
for (iter = 0; iter < bf->hash_iterations; iter++) {
|
||
hash = bf->Hash(data, datalen, iter, bf->bitarray_size);
|
||
if (!(bf->bitarray[hash/8] & (1<<hash%8))) {
|
||
hit = 0;
|
||
break;
|
||
}
|
||
}
|
||
return hit;
|
||
}
|
||
#endif /* __BLOOMFILTER_H__ */
|
||
src/util-byte.c | ||
---|---|---|
#include "util-debug.h"
|
||
/** \todo: Remove the fprintf errors in favor of logging */
|
||
int ByteExtractStringInt64(int64_t *res, int base, uint16_t len, const char *str)
|
||
{
|
||
return ByteExtractStringSigned(res, base, len, str);
|
||
}
|
||
int ByteExtractStringUint64(uint64_t *res, int base, uint16_t len, const char *str)
|
||
{
|
||
return ByteExtractString(res, base, len, str);
|
||
}
|
||
int ByteExtractString(uint64_t *res, int base, uint16_t len, const char *str)
|
||
{
|
||
const char *ptr = str;
|
||
char *endptr = NULL;
|
||
/* 23 - This is the largest string (octal, with a zero prefix) that
|
||
* will not overflow uint64_t. The only way this length
|
||
* could be over 23 and still not overflow is if it were zero
|
||
* prefixed and we only support 1 byte of zero prefix for octal.
|
||
*
|
||
* "01777777777777777777777" = 0xffffffffffffffff
|
||
*/
|
||
char strbuf[24];
|
||
if (len > 23) {
|
||
SCLogError(SC_ERR_ARG_LEN_LONG, "len too large (23 max)");
|
||
return -1;
|
||
}
|
||
if (len) {
|
||
/* Extract out the string so it can be null terminated */
|
||
memcpy(strbuf, str, len);
|
||
strbuf[len] = '\0';
|
||
ptr = strbuf;
|
||
}
|
||
errno = 0;
|
||
*res = strtoull(ptr, &endptr, base);
|
||
if (errno == ERANGE) {
|
||
SCLogError(SC_ERR_NUMERIC_VALUE_ERANGE, "Numeric value out of range");
|
||
return -1;
|
||
} else if (endptr == str) {
|
||
SCLogError(SC_ERR_INVALID_NUMERIC_VALUE, "Invalid numeric value");
|
||
return -1;
|
||
/* If there is no numeric value in the given string then strtoull(), makes
|
||
endptr equals to ptr and return 0 as result */
|
||
} else if (endptr == ptr && *res == 0) {
|
||
SCLogDebug("No numeric value");
|
||
return -1;
|
||
}
|
||
/* This will interfere with some rules that do not know the length
|
||
* in advance and instead are just using the max.
|
||
*/
|
||
#if 0
|
||
else if (len && *endptr != '\0') {
|
||
fprintf(stderr, "ByteExtractString: Extra characters following numeric value\n");
|
||
return -1;
|
||
}
|
||
#endif
|
||
return (endptr - ptr);
|
||
}
|
||
int ByteExtractStringSigned(int64_t *res, int base, uint16_t len, const char *str)
|
||
{
|
||
const char *ptr = str;
|
||
char *endptr;
|
||
/* 23 - This is the largest string (octal, with a zero prefix) that
|
||
* will not overflow int64_t. The only way this length
|
||
* could be over 23 and still not overflow is if it were zero
|
||
* prefixed and we only support 1 byte of zero prefix for octal.
|
||
*
|
||
* "-0777777777777777777777" = 0xffffffffffffffff
|
||
*/
|
||
char strbuf[24];
|
||
if (len > 23) {
|
||
SCLogError(SC_ERR_ARG_LEN_LONG, "len too large (23 max)");
|
||
return -1;
|
||
}
|
||
if (len) {
|
||
/* Extract out the string so it can be null terminated */
|
||
memcpy(strbuf, str, len);
|
||
strbuf[len] = '\0';
|
||
ptr = strbuf;
|
||
}
|
||
errno = 0;
|
||
*res = strtoll(ptr, &endptr, base);
|
||
if (errno == ERANGE) {
|
||
SCLogError(SC_ERR_NUMERIC_VALUE_ERANGE, "Numeric value out of range");
|
||
return -1;
|
||
} else if (endptr == str) {
|
||
SCLogError(SC_ERR_INVALID_NUMERIC_VALUE, "Invalid numeric value");
|
||
return -1;
|
||
}
|
||
/* This will interfere with some rules that do not know the length
|
||
* in advance and instead are just using the max.
|
||
*/
|
||
#if 0
|
||
else if (len && *endptr != '\0') {
|
||
fprintf(stderr, "ByteExtractStringSigned: Extra characters following numeric value\n");
|
||
return -1;
|
||
}
|
||
#endif
|
||
//fprintf(stderr, "ByteExtractStringSigned: Extracted base %d: 0x%" PRIx64 "\n", base, *res);
|
||
return (endptr - ptr);
|
||
}
|
||
int ByteExtractStringUint32(uint32_t *res, int base, uint16_t len, const char *str)
|
||
{
|
||
uint64_t i64;
|
||
int ret;
|
||
ret = ByteExtractString(&i64, base, len, str);
|
||
if (ret <= 0) {
|
||
return ret;
|
||
}
|
||
*res = (uint32_t)i64;
|
||
if ((uint64_t)(*res) != i64) {
|
||
SCLogError(SC_ERR_NUMERIC_VALUE_ERANGE, "Numeric value out of range "
|
||
"(%" PRIx64 " != %" PRIx64 ")", (uint64_t)(*res), i64);
|
||
return -1;
|
||
}
|
||
return ret;
|
||
}
|
||
int ByteExtractStringUint16(uint16_t *res, int base, uint16_t len, const char *str)
|
||
{
|
||
uint64_t i64;
|
||
int ret;
|
||
ret = ByteExtractString(&i64, base, len, str);
|
||
if (ret <= 0) {
|
||
return ret;
|
||
}
|
||
*res = (uint16_t)i64;
|
||
if ((uint64_t)(*res) != i64) {
|
||
SCLogError(SC_ERR_NUMERIC_VALUE_ERANGE, "Numeric value out of range "
|
||
"(%" PRIx64 " != %" PRIx64 ")", (uint64_t)(*res), i64);
|
||
return -1;
|
||
}
|
||
return ret;
|
||
}
|
||
int ByteExtractStringUint8(uint8_t *res, int base, uint16_t len, const char *str)
|
||
{
|
||
uint64_t i64;
|
||
int ret;
|
||
ret = ByteExtractString(&i64, base, len, str);
|
||
if (ret <= 0) {
|
||
return ret;
|
||
}
|
||
*res = (uint8_t)i64;
|
||
if ((uint64_t)(*res) != i64) {
|
||
SCLogError(SC_ERR_NUMERIC_VALUE_ERANGE, "Numeric value out of range "
|
||
"(%" PRIx64 " != %" PRIx64 ")", (uint64_t)(*res), i64);
|
||
return -1;
|
||
}
|
||
return ret;
|
||
}
|
||
int ByteExtractStringInt32(int32_t *res, int base, uint16_t len, const char *str)
|
||
{
|
||
int64_t i64;
|
||
int ret;
|
||
ret = ByteExtractStringSigned(&i64, base, len, str);
|
||
if (ret <= 0) {
|
||
return ret;
|
||
}
|
||
*res = (int32_t)i64;
|
||
if ((int64_t)(*res) != i64) {
|
||
SCLogError(SC_ERR_NUMERIC_VALUE_ERANGE, "Numeric value out of range "
|
||
"(%" PRIx64 " != %" PRIx64 ")\n", (int64_t)(*res), i64);
|
||
return -1;
|
||
}
|
||
return ret;
|
||
}
|
||
int ByteExtractStringInt16(int16_t *res, int base, uint16_t len, const char *str)
|
||
{
|
||
int64_t i64;
|
||
int ret;
|
||
ret = ByteExtractStringSigned(&i64, base, len, str);
|
||
if (ret <= 0) {
|
||
return ret;
|
||
}
|
||
*res = (int16_t)i64;
|
||
if ((int64_t)(*res) != i64) {
|
||
SCLogError(SC_ERR_NUMERIC_VALUE_ERANGE, "Numeric value out of range "
|
||
"(%" PRIx64 " != %" PRIx64 ")\n", (int64_t)(*res), i64);
|
||
return -1;
|
||
}
|
||
return ret;
|
||
}
|
||
int ByteExtractStringInt8(int8_t *res, int base, uint16_t len, const char *str)
|
||
{
|
||
int64_t i64;
|
||
int ret;
|
||
ret = ByteExtractStringSigned(&i64, base, len, str);
|
||
if (ret <= 0) {
|
||
return ret;
|
||
}
|
||
*res = (int8_t)i64;
|
||
if ((int64_t)(*res) != i64) {
|
||
SCLogError(SC_ERR_NUMERIC_VALUE_ERANGE, "Numeric value out of range "
|
||
"(%" PRIx64 " != %" PRIx64 ")\n", (int64_t)(*res), i64);
|
||
return -1;
|
||
}
|
||
return ret;
|
||
}
|
||
#ifdef UNITTESTS
|
||
src/util-byte.h | ||
---|---|---|
* \return n Number of bytes extracted on success
|
||
* \return -1 On error
|
||
*/
|
||
static inline int ByteExtractString(uint64_t *res, int base, uint16_t len, const char *str);
|
||
int ByteExtractString(uint64_t *res, int base, uint16_t len, const char *str);
|
||
/**
|
||
* Extract unsigned integer value from a string as uint64_t.
|
||
... | ... | |
* \return n Number of bytes extracted on success
|
||
* \return -1 On error
|
||
*/
|
||
static inline int ByteExtractStringUint64(uint64_t *res, int base, uint16_t len, const char *str);
|
||
int ByteExtractStringUint64(uint64_t *res, int base, uint16_t len, const char *str);
|
||
/**
|
||
* Extract unsigned integer value from a string as uint32_t.
|
||
... | ... | |
* \return n Number of bytes extracted on success
|
||
* \return -1 On error
|
||
*/
|
||
static inline int ByteExtractStringUint32(uint32_t *res, int base, uint16_t len, const char *str);
|
||
int ByteExtractStringUint32(uint32_t *res, int base, uint16_t len, const char *str);
|
||
/**
|
||
* Extract unsigned integer value from a string as uint16_t.
|
||
... | ... | |
* \return n Number of bytes extracted on success
|
||
* \return -1 On error
|
||
*/
|
||
static inline int ByteExtractStringUint16(uint16_t *res, int base, uint16_t len, const char *str);
|
||
int ByteExtractStringUint16(uint16_t *res, int base, uint16_t len, const char *str);
|
||
/**
|
||
* Extract unsigned integer value from a string as uint8_t.
|
||
... | ... | |
* \return n Number of bytes extracted on success
|
||
* \return -1 On error
|
||
*/
|
||
static inline int ByteExtractStringUint8(uint8_t *res, int base, uint16_t len, const char *str);
|
||
int ByteExtractStringUint8(uint8_t *res, int base, uint16_t len, const char *str);
|
||
/**
|
||
* Extract signed integer value from a string.
|
||
... | ... | |
* \return n Number of bytes extracted on success
|
||
* \return -1 On error
|
||
*/
|
||
static inline int ByteExtractStringSigned(int64_t *res, int base, uint16_t len, const char *str);
|
||
int ByteExtractStringSigned(int64_t *res, int base, uint16_t len, const char *str);
|
||
/**
|
||
* Extract signed integer value from a string as uint64_t.
|
||
... | ... | |
* \return n Number of bytes extracted on success
|
||
* \return -1 On error
|
||
*/
|
||
static inline int ByteExtractStringInt64(int64_t *res, int base, uint16_t len, const char *str);
|
||
int ByteExtractStringInt64(int64_t *res, int base, uint16_t len, const char *str);
|
||
/**
|
||
* Extract signed integer value from a string as uint32_t.
|
||
... | ... | |
* \return n Number of bytes extracted on success
|
||
* \return -1 On error
|
||
*/
|
||
static inline int ByteExtractStringInt32(int32_t *res, int base, uint16_t len, const char *str);
|
||
int ByteExtractStringInt32(int32_t *res, int base, uint16_t len, const char *str);
|
||
/**
|
||
* Extract signed integer value from a string as uint16_t.
|
||
... | ... | |
* \return n Number of bytes extracted on success
|
||
* \return -1 On error
|
||
*/
|
||
static inline int ByteExtractStringInt16(int16_t *res, int base, uint16_t len, const char *str);
|
||
int ByteExtractStringInt16(int16_t *res, int base, uint16_t len, const char *str);
|
||
/**
|
||
* Extract signed integer value from a string as uint8_t.
|
||
... | ... | |
* \return n Number of bytes extracted on success
|
||
* \return -1 On error
|
||
*/
|
||
static inline int ByteExtractStringInt8(int8_t *res, int base, uint16_t len, const char *str);
|
||
int ByteExtractStringInt8(int8_t *res, int base, uint16_t len, const char *str);
|
||
/** ------ Definitions of Inline functions ------ */
|
||
... | ... | |
return len;
|
||
}
|
||
static inline int ByteExtractString(uint64_t *res, int base, uint16_t len, const char *str)
|
||
{
|
||
const char *ptr = str;
|
||
char *endptr = NULL;
|
||
/* 23 - This is the largest string (octal, with a zero prefix) that
|
||
* will not overflow uint64_t. The only way this length
|
||
* could be over 23 and still not overflow is if it were zero
|
||
* prefixed and we only support 1 byte of zero prefix for octal.
|
||
*
|
||
* "01777777777777777777777" = 0xffffffffffffffff
|
||
*/
|
||
char strbuf[24];
|
||
if (len > 23) {
|
||
SCLogError(SC_ERR_ARG_LEN_LONG, "len too large (23 max)");
|
||
return -1;
|
||
}
|
||
if (len) {
|
||
/* Extract out the string so it can be null terminated */
|
||
memcpy(strbuf, str, len);
|
||
strbuf[len] = '\0';
|
||
ptr = strbuf;
|
||
}
|
||
errno = 0;
|
||
*res = strtoull(ptr, &endptr, base);
|
||
if (errno == ERANGE) {
|
||
SCLogError(SC_ERR_NUMERIC_VALUE_ERANGE, "Numeric value out of range");
|
||
return -1;
|
||
} else if (endptr == str) {
|
||
SCLogError(SC_ERR_INVALID_NUMERIC_VALUE, "Invalid numeric value");
|
||
return -1;
|
||
/* If there is no numeric value in the given string then strtoull(), makes
|
||
endptr equals to ptr and return 0 as result */
|
||
} else if (endptr == ptr && *res == 0) {
|
||
SCLogDebug("No numeric value");
|
||
return -1;
|
||
}
|
||
/* This will interfere with some rules that do not know the length
|
||
* in advance and instead are just using the max.
|
||
*/
|
||
#if 0
|
||
else if (len && *endptr != '\0') {
|
||
fprintf(stderr, "ByteExtractString: Extra characters following numeric value\n");
|
||
return -1;
|
||
}
|
||
#endif
|
||
return (endptr - ptr);
|
||
}
|
||
static inline int ByteExtractUint64(uint64_t *res, int e, uint16_t len, const uint8_t *bytes)
|
||
{
|
||
uint64_t i64;
|
||
... | ... | |
return ret;
|
||
}
|
||
static inline int ByteExtractStringInt64(int64_t *res, int base, uint16_t len, const char *str)
|
||
{
|
||
return ByteExtractStringSigned(res, base, len, str);
|
||
}
|
||
static inline int ByteExtractStringInt32(int32_t *res, int base, uint16_t len, const char *str)
|
||
{
|
||
int64_t i64;
|
||
int ret;
|
||
ret = ByteExtractStringSigned(&i64, base, len, str);
|
||
if (ret <= 0) {
|
||
return ret;
|
||
}
|
||
*res = (int32_t)i64;
|
||
if ((int64_t)(*res) != i64) {
|
||
SCLogError(SC_ERR_NUMERIC_VALUE_ERANGE, "Numeric value out of range "
|
||
"(%" PRIx64 " != %" PRIx64 ")\n", (int64_t)(*res), i64);
|
||
return -1;
|
||
}
|
||
return ret;
|
||
}
|
||
static inline int ByteExtractStringInt16(int16_t *res, int base, uint16_t len, const char *str)
|
||
{
|
||
int64_t i64;
|
||
int ret;
|
||
ret = ByteExtractStringSigned(&i64, base, len, str);
|
||
if (ret <= 0) {
|
||
return ret;
|
- « Previous
- 1
- 2
- Next »