|
|
|
@ -2801,252 +2801,6 @@ uint32_t DetectContentGetId(MpmPatternIdStore *ht, DetectContentData *co) {
|
|
|
|
|
SCReturnUInt(id);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Get the pattern id for a uricontent pattern
|
|
|
|
|
*
|
|
|
|
|
* \param ht mpm pattern id hash table store
|
|
|
|
|
* \param co content pattern data
|
|
|
|
|
*
|
|
|
|
|
* \retval id pattern id
|
|
|
|
|
*/
|
|
|
|
|
uint32_t DetectUricontentGetId(MpmPatternIdStore *ht, DetectContentData *co) {
|
|
|
|
|
SCEnter();
|
|
|
|
|
|
|
|
|
|
BUG_ON(ht == NULL || ht->hash == NULL);
|
|
|
|
|
|
|
|
|
|
MpmPatternIdTableElmt *e = NULL;
|
|
|
|
|
MpmPatternIdTableElmt *r = NULL;
|
|
|
|
|
uint32_t id = 0;
|
|
|
|
|
|
|
|
|
|
e = SCMalloc(sizeof(MpmPatternIdTableElmt));
|
|
|
|
|
BUG_ON(e == NULL);
|
|
|
|
|
e->pattern = SCMalloc(co->content_len);
|
|
|
|
|
BUG_ON(e->pattern == NULL);
|
|
|
|
|
memcpy(e->pattern, co->content, co->content_len);
|
|
|
|
|
e->pattern_len = co->content_len;
|
|
|
|
|
e->sm_list = DETECT_SM_LIST_UMATCH;
|
|
|
|
|
e->dup_count = 1;
|
|
|
|
|
e->id = 0;
|
|
|
|
|
|
|
|
|
|
r = HashTableLookup(ht->hash, (void *)e, sizeof(MpmPatternIdTableElmt));
|
|
|
|
|
if (r == NULL) {
|
|
|
|
|
e->id = ht->max_id;
|
|
|
|
|
ht->max_id++;
|
|
|
|
|
id = e->id;
|
|
|
|
|
|
|
|
|
|
int ret = HashTableAdd(ht->hash, e, sizeof(MpmPatternIdTableElmt));
|
|
|
|
|
BUG_ON(ret != 0);
|
|
|
|
|
|
|
|
|
|
e = NULL;
|
|
|
|
|
|
|
|
|
|
ht->unique_patterns++;
|
|
|
|
|
} else {
|
|
|
|
|
id = r->id;
|
|
|
|
|
r->dup_count++;
|
|
|
|
|
|
|
|
|
|
ht->shared_patterns++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (e != NULL)
|
|
|
|
|
MpmPatternIdTableElmtFree(e);
|
|
|
|
|
|
|
|
|
|
SCReturnUInt(id);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Get the pattern id for a for any content related keyword.
|
|
|
|
|
*
|
|
|
|
|
* Supported keywords are content, http_client_body,
|
|
|
|
|
* http_method, http_uri, http_header, http_cookie.
|
|
|
|
|
*
|
|
|
|
|
* Please note that you can't use it to get a pattern id for
|
|
|
|
|
* uricontent. To retrieve a uricontent pattern id please
|
|
|
|
|
* use DetectUricontentGetId().
|
|
|
|
|
*
|
|
|
|
|
* \param ht Mpm pattern id hash table store.
|
|
|
|
|
* \param ctx The keyword context.
|
|
|
|
|
* \param type The SigMatch context.
|
|
|
|
|
*
|
|
|
|
|
* \retval id Pattern id.
|
|
|
|
|
*/
|
|
|
|
|
uint32_t DetectPatternGetId(MpmPatternIdStore *ht, void *ctx, Signature *s, uint8_t sm_list)
|
|
|
|
|
{
|
|
|
|
|
SCEnter();
|
|
|
|
|
|
|
|
|
|
MpmPatternIdTableElmt *e = NULL;
|
|
|
|
|
MpmPatternIdTableElmt *r = NULL;
|
|
|
|
|
PatIntId id = 0;
|
|
|
|
|
|
|
|
|
|
e = SCMalloc(sizeof(MpmPatternIdTableElmt));
|
|
|
|
|
if (unlikely(e == NULL)) {
|
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DetectContentData *cd = ctx;
|
|
|
|
|
e->pattern = SCMalloc(cd->content_len);
|
|
|
|
|
if (e->pattern == NULL) {
|
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
|
}
|
|
|
|
|
memcpy(e->pattern, cd->content, cd->content_len);
|
|
|
|
|
e->pattern_len = cd->content_len;
|
|
|
|
|
e->dup_count = 1;
|
|
|
|
|
e->sm_list = sm_list;
|
|
|
|
|
e->id = 0;
|
|
|
|
|
|
|
|
|
|
r = HashTableLookup(ht->hash, (void *)e, sizeof(MpmPatternIdTableElmt));
|
|
|
|
|
if (r == NULL) {
|
|
|
|
|
if (s->list != DETECT_SM_LIST_NOTSET) {
|
|
|
|
|
BUG_ON(sm_list != DETECT_SM_LIST_HSBDMATCH && sm_list != DETECT_SM_LIST_DMATCH && sm_list != DETECT_SM_LIST_DNSQUERY_MATCH);
|
|
|
|
|
e->id = ht->max_id;
|
|
|
|
|
ht->max_id++;
|
|
|
|
|
id = e->id;
|
|
|
|
|
int ret = HashTableAdd(ht->hash, e, sizeof(MpmPatternIdTableElmt));
|
|
|
|
|
BUG_ON(ret != 0);
|
|
|
|
|
e = NULL;
|
|
|
|
|
} else {
|
|
|
|
|
/* we don't have a duplicate with this pattern + id type. If the id is
|
|
|
|
|
* for content, then it is the first entry for such a
|
|
|
|
|
* pattern + id combination. Let us create an entry for it */
|
|
|
|
|
if (sm_list == DETECT_SM_LIST_PMATCH) {
|
|
|
|
|
e->id = ht->max_id;
|
|
|
|
|
ht->max_id++;
|
|
|
|
|
id = e->id;
|
|
|
|
|
int ret = HashTableAdd(ht->hash, e, sizeof(MpmPatternIdTableElmt));
|
|
|
|
|
BUG_ON(ret != 0);
|
|
|
|
|
e = NULL;
|
|
|
|
|
|
|
|
|
|
/* the id type is not content or uricontent. It would be one of
|
|
|
|
|
* those http_ modifiers against content then */
|
|
|
|
|
} else {
|
|
|
|
|
/* we know that this is one of those http_ modifiers against content.
|
|
|
|
|
* So we would have seen a content before coming across this http_
|
|
|
|
|
* modifier. Let's retrieve this content entry that has already
|
|
|
|
|
* been registered. */
|
|
|
|
|
e->sm_list = DETECT_SM_LIST_PMATCH;
|
|
|
|
|
MpmPatternIdTableElmt *tmp_r = HashTableLookup(ht->hash, (void *)e, sizeof(MpmPatternIdTableElmt));
|
|
|
|
|
if (tmp_r == NULL) {
|
|
|
|
|
SCLogError(SC_ERR_FATAL, "How can this happen? We have to have "
|
|
|
|
|
"a content of type DETECT_CONTENT already registered "
|
|
|
|
|
"at this point. Impossible");
|
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* we have retrieved the content, and the content registered was the
|
|
|
|
|
* first entry made(dup_count is 1) for that content. Let us just
|
|
|
|
|
* reset the sm_type to the http_ keyword's sm_type */
|
|
|
|
|
if (tmp_r->dup_count == 1) {
|
|
|
|
|
tmp_r->sm_list = sm_list;
|
|
|
|
|
id = tmp_r->id;
|
|
|
|
|
|
|
|
|
|
/* interestingly we have more than one entry for this content.
|
|
|
|
|
* Out of these tmp_r->dup_count entries, one would be for the content
|
|
|
|
|
* entry made for this http_ modifier. Erase this entry and make
|
|
|
|
|
* a separate entry for the http_ modifier(of course with a new id) */
|
|
|
|
|
} else {
|
|
|
|
|
tmp_r->dup_count--;
|
|
|
|
|
/* reset the sm_type, since we changed it to DETECT_CONTENT prev */
|
|
|
|
|
e->sm_list = sm_list;
|
|
|
|
|
e->id = ht->max_id;
|
|
|
|
|
ht->max_id++;
|
|
|
|
|
id = e->id;
|
|
|
|
|
int ret = HashTableAdd(ht->hash, e, sizeof(MpmPatternIdTableElmt));
|
|
|
|
|
BUG_ON(ret != 0);
|
|
|
|
|
e = NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* we do seem to have an entry for this already */
|
|
|
|
|
} else {
|
|
|
|
|
/* oh cool! It is a duplicate for content, uricontent types. Update the
|
|
|
|
|
* dup_count and get out */
|
|
|
|
|
if ((s->list != DETECT_SM_LIST_NOTSET) ||
|
|
|
|
|
sm_list == DETECT_SM_LIST_PMATCH) {
|
|
|
|
|
/* we have a duplicate */
|
|
|
|
|
r->dup_count++;
|
|
|
|
|
id = r->id;
|
|
|
|
|
goto end;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* uh oh! a duplicate for a http_ modifier type. Let's increase the
|
|
|
|
|
* dup_count for the entry */
|
|
|
|
|
r->dup_count++;
|
|
|
|
|
id = r->id;
|
|
|
|
|
|
|
|
|
|
/* let's get the content entry associated with the http keyword we are
|
|
|
|
|
* currently operating on */
|
|
|
|
|
e->sm_list = DETECT_SM_LIST_PMATCH;
|
|
|
|
|
MpmPatternIdTableElmt *tmp_r = HashTableLookup(ht->hash, (void *)e, sizeof(MpmPatternIdTableElmt));
|
|
|
|
|
if (tmp_r == NULL) {
|
|
|
|
|
SCLogError(SC_ERR_FATAL, "How can this happen? We have to have "
|
|
|
|
|
"a content of type DETECT_CONTENT already registered "
|
|
|
|
|
"at this point. Impossible");
|
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
|
}
|
|
|
|
|
/* so there are more than one content keyword entries for this pattern.
|
|
|
|
|
* Reduce the dup_count */
|
|
|
|
|
if (tmp_r->dup_count > 1) {
|
|
|
|
|
tmp_r->dup_count--;
|
|
|
|
|
|
|
|
|
|
/* We have just one entry. Remove this hash table entry */
|
|
|
|
|
} else {
|
|
|
|
|
HashTableRemove(ht->hash, tmp_r, sizeof(MpmPatternIdTableElmt));
|
|
|
|
|
ht->max_id--;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
end:
|
|
|
|
|
if (e != NULL)
|
|
|
|
|
MpmPatternIdTableElmtFree(e);
|
|
|
|
|
|
|
|
|
|
SCReturnUInt(id);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint32_t DetectPatternGetIdV2(MpmPatternIdStore *ht, void *ctx, Signature *s, uint8_t sm_list)
|
|
|
|
|
{
|
|
|
|
|
SCEnter();
|
|
|
|
|
|
|
|
|
|
MpmPatternIdTableElmt *e = NULL;
|
|
|
|
|
MpmPatternIdTableElmt *r = NULL;
|
|
|
|
|
PatIntId id = 0;
|
|
|
|
|
|
|
|
|
|
e = SCMalloc(sizeof(MpmPatternIdTableElmt));
|
|
|
|
|
if (unlikely(e == NULL)) {
|
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DetectContentData *cd = ctx;
|
|
|
|
|
e->pattern = SCMalloc(cd->content_len);
|
|
|
|
|
if (e->pattern == NULL) {
|
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
|
}
|
|
|
|
|
memcpy(e->pattern, cd->content, cd->content_len);
|
|
|
|
|
e->pattern_len = cd->content_len;
|
|
|
|
|
e->dup_count = 1;
|
|
|
|
|
e->sm_list = sm_list;
|
|
|
|
|
e->id = 0;
|
|
|
|
|
|
|
|
|
|
r = HashTableLookup(ht->hash, (void *)e, sizeof(MpmPatternIdTableElmt));
|
|
|
|
|
if (r == NULL) {
|
|
|
|
|
e->id = ht->max_id;
|
|
|
|
|
ht->max_id++;
|
|
|
|
|
id = e->id;
|
|
|
|
|
int ret = HashTableAdd(ht->hash, e, sizeof(MpmPatternIdTableElmt));
|
|
|
|
|
BUG_ON(ret != 0);
|
|
|
|
|
e = NULL;
|
|
|
|
|
|
|
|
|
|
/* we do seem to have an entry for this already */
|
|
|
|
|
} else {
|
|
|
|
|
r->dup_count++;
|
|
|
|
|
id = r->id;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (e != NULL)
|
|
|
|
|
MpmPatternIdTableElmtFree(e);
|
|
|
|
|
|
|
|
|
|
SCReturnUInt(id);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
typedef struct DetectFPAndItsId_ {
|
|
|
|
|
PatIntId id;
|
|
|
|
|
uint16_t content_len;
|
|
|
|
|