/** * \brief The Compare function for MpmStore * * \param data1 Pointer to the first MpmStore. * \param len1 Not used. * \param data2 Pointer to the second MpmStore. * \param len2 Not used. * * \retval 1 If the 2 MpmStores sent as args match. * \retval 0 If the 2 MpmStores sent as args do not match. */ static char MpmStoreCompareFunc(void *data1, uint16_t len1, void *data2, uint16_t len2) { const MpmStore *ms1 = (MpmStore *)data1; const MpmStore *ms2 = (MpmStore *)data2; if (ms1->sid_array_size != ms2->sid_array_size) return 0; if (ms1->buffer != ms2->buffer) return 0; if (ms1->direction != ms2->direction) return 0; if (ms1->sm_list != ms2->sm_list) return 0; if (SCMemcmp(ms1->sid_array, ms2->sid_array, ms1->sid_array_size) != 0) { return 0; } return 1; }
static int MemcmpTest07 (void) { uint8_t a[] = "abcd"; uint8_t b[] = "abcde"; if (SCMemcmp(a, b, sizeof(a)-1) != 0) return 0; return 1; }
static char HashTableDefaultCompareTest(void *data1, uint16_t len1, void *data2, uint16_t len2) { if (len1 != len2) return 0; if (SCMemcmp(data1,data2,len1) != 0) return 0; return 1; }
static int MemcmpTest04 (void) { uint8_t a[] = "abcd"; uint8_t b[] = "abcD"; int r = SCMemcmp(a, b, sizeof(a)-1); if (r != 1) { printf("%s != %s, but memcmp returned %d: ", a, b, r); return 0; } return 1; }
/** * \brief The Compare function to be used by the SigGroupHead hash table - * DetectEngineCtx->sgh_hash_table. * * \param data1 Pointer to the first SigGroupHead. * \param len1 Not used. * \param data2 Pointer to the second SigGroupHead. * \param len2 Not used. * * \retval 1 If the 2 SigGroupHeads sent as args match. * \retval 0 If the 2 SigGroupHeads sent as args do not match. */ char SigGroupHeadCompareFunc(void *data1, uint16_t len1, void *data2, uint16_t len2) { SigGroupHead *sgh1 = (SigGroupHead *)data1; SigGroupHead *sgh2 = (SigGroupHead *)data2; if (data1 == NULL || data2 == NULL) return 0; if (sgh1->init->sig_size != sgh2->init->sig_size) return 0; if (SCMemcmp(sgh1->init->sig_array, sgh2->init->sig_array, sgh1->init->sig_size) != 0) return 0; return 1; }
static int MemcmpTest16 (void) { #ifdef PROFILING uint64_t ticks_start = 0; uint64_t ticks_end = 0; char *a[] = { "0123456789012345", "abc", "abcdefghij", "suricata", "test", "xyz", "rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr", "abcdefghijklmnopqrstuvwxyz", NULL }; char *b[] = { "1234567890123456", "abc", "abcdefghik", "suricatb", "test", "xyz", "rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr", "abcdefghijklmnopqrstuvwxyz", NULL }; int t = 0; int i, j; int r3 = 0; printf("\n"); ticks_start = UtilCpuGetTicks(); for (t = 0; t < TEST_RUNS; t++) { for (i = 0; a[i] != NULL; i++) { // printf("a[%d] = %s\n", i, a[i]); size_t alen = strlen(a[i]) - 1; for (j = 0; b[j] != NULL; j++) { // printf("b[%d] = %s\n", j, b[j]); size_t blen = strlen(b[j]) - 1; r3 += SCMemcmp((uint8_t *)a[i], (uint8_t *)b[j], (alen < blen) ? alen : blen); } } } ticks_end = UtilCpuGetTicks(); printf("SCMemcmp(%d) \t\t\t%"PRIu64"\n", TEST_RUNS, ((uint64_t)(ticks_end - ticks_start))/TEST_RUNS); SCLogInfo("ticks passed %"PRIu64, ticks_end - ticks_start); printf("r3 %d\n", r3); if (r3 != (51 * TEST_RUNS)) return 0; #endif return 1; }
/** * \brief match the specified file extension * * \param t thread local vars * \param det_ctx pattern matcher thread local data * \param f *LOCKED* flow * \param flags direction flags * \param file file being inspected * \param s signature being inspected * \param m sigmatch that we will cast into DetectFileextData * * \retval 0 no match * \retval 1 match */ static int DetectFileextMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Flow *f, uint8_t flags, File *file, Signature *s, SigMatch *m) { SCEnter(); int ret = 0; DetectFileextData *fileext = (DetectFileextData *)m->ctx; if (file->name == NULL) SCReturnInt(0); if (file->txid < det_ctx->tx_id) SCReturnInt(0); if (file->txid > det_ctx->tx_id) SCReturnInt(0); if (file->name_len <= fileext->len) SCReturnInt(0); int offset = file->name_len - fileext->len; if (file->name[offset - 1] == '.' && SCMemcmp(file->name + offset, fileext->ext, fileext->len) == 0) { if (!(fileext->flags & DETECT_CONTENT_NEGATED)) { ret = 1; SCLogDebug("File ext found"); } } if (ret == 0 && (fileext->flags & DETECT_CONTENT_NEGATED)) { SCLogDebug("negated match"); ret = 1; } SCReturnInt(ret); }
static uint32_t SMB2ParseHeader(void *smb2_state, AppLayerParserState *pstate, uint8_t *input, uint32_t input_len) { SCEnter(); SMB2State *sstate = (SMB2State *) smb2_state; uint8_t *p = input; if (input_len) { switch (sstate->bytesprocessed) { case 4: // fallthrough /* above statement to prevent coverity FPs from the switch * fall through */ if (input_len >= SMB2_HDR_LEN) { if (SCMemcmp(p, "\xfe\x53\x4d\x42", 4) != 0) { //printf("SMB2 Header did not validate\n"); return 0; } sstate->smb2.StructureSize = *(p + 4); sstate->smb2.StructureSize |= *(p + 5) << 8; sstate->smb2.CreditCharge = *(p + 6); sstate->smb2.CreditCharge |= *(p + 7) << 8; sstate->smb2.Status = *(p + 8); sstate->smb2.Status |= *(p + 9) << 8; sstate->smb2.Status |= *(p + 10) << 16; sstate->smb2.Status |= *(p + 11) << 24; sstate->smb2.Command = *(p + 12); sstate->smb2.Command |= *(p + 13) << 8; sstate->smb2.CreditRequestResponse = *(p + 14); sstate->smb2.CreditRequestResponse |= *(p + 15) << 8; sstate->smb2.Flags = *(p + 16); sstate->smb2.Flags |= *(p + 17) << 8; sstate->smb2.Flags |= *(p + 18) << 16; sstate->smb2.Flags |= *(p + 19) << 24; sstate->smb2.NextCommand = *(p + 20); sstate->smb2.NextCommand |= *(p + 21) << 8; sstate->smb2.NextCommand |= *(p + 22) << 16; sstate->smb2.NextCommand |= *(p + 23) << 24; sstate->smb2.MessageId = *(p + 24); sstate->smb2.MessageId |= *(p + 25) << 8; sstate->smb2.MessageId |= *(p + 26) << 16; sstate->smb2.MessageId |= (uint64_t) *(p + 27) << 24; sstate->smb2.MessageId |= (uint64_t) *(p + 28) << 32; sstate->smb2.MessageId |= (uint64_t) *(p + 29) << 40; sstate->smb2.MessageId |= (uint64_t) *(p + 30) << 48; sstate->smb2.MessageId |= (uint64_t) *(p + 31) << 56; sstate->smb2.ProcessId = *(p + 32); sstate->smb2.ProcessId |= *(p + 33) << 8; sstate->smb2.ProcessId |= *(p + 34) << 16; sstate->smb2.ProcessId |= *(p + 35) << 24; sstate->smb2.TreeId = *(p + 36); sstate->smb2.TreeId |= *(p + 37) << 8; sstate->smb2.TreeId |= *(p + 38) << 16; sstate->smb2.TreeId |= *(p + 39) << 24; sstate->smb2.SessionId = *(p + 40); sstate->smb2.SessionId |= *(p + 41) << 8; sstate->smb2.SessionId |= *(p + 42) << 16; sstate->smb2.SessionId |= (uint64_t) *(p + 43) << 24; sstate->smb2.SessionId |= (uint64_t) *(p + 44) << 32; sstate->smb2.SessionId |= (uint64_t) *(p + 45) << 40; sstate->smb2.SessionId |= (uint64_t) *(p + 46) << 48; sstate->smb2.SessionId |= (uint64_t) *(p + 47) << 56; sstate->smb2.Signature[0] = *(p + 48); sstate->smb2.Signature[1] = *(p + 49); sstate->smb2.Signature[2] = *(p + 50); sstate->smb2.Signature[3] = *(p + 51); sstate->smb2.Signature[4] = *(p + 52); sstate->smb2.Signature[5] = *(p + 53); sstate->smb2.Signature[6] = *(p + 54); sstate->smb2.Signature[7] = *(p + 55); sstate->smb2.Signature[8] = *(p + 56); sstate->smb2.Signature[9] = *(p + 57); sstate->smb2.Signature[10] = *(p + 58); sstate->smb2.Signature[11] = *(p + 59); sstate->smb2.Signature[12] = *(p + 60); sstate->smb2.Signature[13] = *(p + 61); sstate->smb2.Signature[14] = *(p + 62); sstate->smb2.Signature[15] = *(p + 63); sstate->bytesprocessed += SMB2_HDR_LEN; SCReturnUInt(64U); break; } else { //sstate->smb2.protocol[0] = *(p++); if (*(p++) != 0xfe) return 0; if (!(--input_len)) break; /* We fall through to the next case if we still have input. * Same applies for other cases as well */ } /* fall through */ case 5: //sstate->smb2.protocol[1] = *(p++); if (*(p++) != 'S') return 0; if (!(--input_len)) break; /* fall through */ case 6: //sstate->smb2.protocol[2] = *(p++); if (*(p++) != 'M') return 0; if (!(--input_len)) break; /* fall through */ case 7: //sstate->smb2.protocol[3] = *(p++); if (*(p++) != 'B') return 0; if (!(--input_len)) break; /* fall through */ case 8: sstate->smb2.StructureSize = *(p++); if (!(--input_len)) break; /* fall through */ case 9: sstate->smb2.StructureSize |= *(p++) << 8; if (!(--input_len)) break; /* fall through */ case 10: sstate->smb2.CreditCharge = *(p++); if (!(--input_len)) break; /* fall through */ case 11: sstate->smb2.CreditCharge |= *(p++) << 8; if (!(--input_len)) break; /* fall through */ case 12: sstate->smb2.Status = *(p++); if (!(--input_len)) break; /* fall through */ case 13: sstate->smb2.Status |= *(p++) << 8; if (!(--input_len)) break; /* fall through */ case 14: sstate->smb2.Status |= *(p++) << 16; if (!(--input_len)) break; /* fall through */ case 15: sstate->smb2.Status |= *(p++) << 24; if (!(--input_len)) break; /* fall through */ case 16: sstate->smb2.Command = *(p++); if (!(--input_len)) break; /* fall through */ case 17: sstate->smb2.Command |= *(p++) << 8; if (!(--input_len)) break; /* fall through */ case 18: sstate->smb2.CreditRequestResponse = *(p++); if (!(--input_len)) break; /* fall through */ case 19: sstate->smb2.CreditRequestResponse |= *(p++) << 8; if (!(--input_len)) break; /* fall through */ case 20: sstate->smb2.Flags = *(p++); if (!(--input_len)) break; /* fall through */ case 21: sstate->smb2.Flags |= *(p++) << 8; if (!(--input_len)) break; /* fall through */ case 22: sstate->smb2.Flags |= *(p++) << 16; if (!(--input_len)) break; /* fall through */ case 23: sstate->smb2.Flags |= *(p++) << 24; if (!(--input_len)) break; /* fall through */ case 24: sstate->smb2.NextCommand = *(p++); if (!(--input_len)) break; /* fall through */ case 25: sstate->smb2.NextCommand |= *(p++) << 8; if (!(--input_len)) break; /* fall through */ case 26: sstate->smb2.NextCommand |= *(p++) << 16; if (!(--input_len)) break; /* fall through */ case 27: sstate->smb2.NextCommand |= *(p++) << 24; if (!(--input_len)) break; /* fall through */ case 28: sstate->smb2.MessageId = *(p++); if (!(--input_len)) break; /* fall through */ case 29: sstate->smb2.MessageId = *(p++) << 8; if (!(--input_len)) break; /* fall through */ case 30: sstate->smb2.MessageId = *(p++) << 16; if (!(--input_len)) break; /* fall through */ case 31: sstate->smb2.MessageId = (uint64_t) *(p++) << 24; if (!(--input_len)) break; /* fall through */ case 32: sstate->smb2.MessageId = (uint64_t) *(p++) << 32; if (!(--input_len)) break; /* fall through */ case 33: sstate->smb2.MessageId = (uint64_t) *(p++) << 40; if (!(--input_len)) break; /* fall through */ case 34: sstate->smb2.MessageId = (uint64_t) *(p++) << 48; if (!(--input_len)) break; /* fall through */ case 35: sstate->smb2.MessageId = (uint64_t) *(p++) << 56; if (!(--input_len)) break; /* fall through */ case 36: sstate->smb2.ProcessId = *(p++); if (!(--input_len)) break; /* fall through */ case 37: sstate->smb2.ProcessId |= *(p++) << 8; if (!(--input_len)) break; /* fall through */ case 38: sstate->smb2.ProcessId |= *(p++) << 16; if (!(--input_len)) break; /* fall through */ case 39: sstate->smb2.ProcessId |= *(p++) << 24; if (!(--input_len)) break; /* fall through */ case 40: sstate->smb2.TreeId = *(p++); if (!(--input_len)) break; /* fall through */ case 41: sstate->smb2.TreeId |= *(p++) << 8; if (!(--input_len)) break; /* fall through */ case 42: sstate->smb2.TreeId |= *(p++) << 16; if (!(--input_len)) break; /* fall through */ case 43: sstate->smb2.TreeId |= *(p++) << 24; if (!(--input_len)) break; /* fall through */ case 44: sstate->smb2.SessionId = *(p++); if (!(--input_len)) break; /* fall through */ case 45: sstate->smb2.SessionId |= *(p++) << 8; if (!(--input_len)) break; /* fall through */ case 46: sstate->smb2.SessionId |= *(p++) << 16; if (!(--input_len)) break; /* fall through */ case 47: sstate->smb2.SessionId |= (uint64_t) *(p++) << 24; if (!(--input_len)) break; /* fall through */ case 48: sstate->smb2.SessionId |= (uint64_t) *(p++) << 32; if (!(--input_len)) break; /* fall through */ case 49: sstate->smb2.SessionId |= (uint64_t) *(p++) << 40; if (!(--input_len)) break; /* fall through */ case 50: sstate->smb2.SessionId |= (uint64_t) *(p++) << 48; if (!(--input_len)) break; /* fall through */ case 51: sstate->smb2.SessionId |= (uint64_t) *(p++) << 56; if (!(--input_len)) break; /* fall through */ case 52: sstate->smb2.Signature[0] = *(p++); if (!(--input_len)) break; /* fall through */ case 53: sstate->smb2.Signature[1] = *(p++); if (!(--input_len)) break; /* fall through */ case 54: sstate->smb2.Signature[2] = *(p++); if (!(--input_len)) break; /* fall through */ case 55: sstate->smb2.Signature[3] = *(p++); if (!(--input_len)) break; /* fall through */ case 56: sstate->smb2.Signature[4] = *(p++); if (!(--input_len)) break; /* fall through */ case 57: sstate->smb2.Signature[5] = *(p++); if (!(--input_len)) break; /* fall through */ case 58: sstate->smb2.Signature[6] = *(p++); if (!(--input_len)) break; /* fall through */ case 59: sstate->smb2.Signature[7] = *(p++); if (!(--input_len)) break; /* fall through */ case 60: sstate->smb2.Signature[8] = *(p++); if (!(--input_len)) break; /* fall through */ case 61: sstate->smb2.Signature[9] = *(p++); if (!(--input_len)) break; /* fall through */ case 62: sstate->smb2.Signature[10] = *(p++); if (!(--input_len)) break; /* fall through */ case 63: sstate->smb2.Signature[11] = *(p++); if (!(--input_len)) break; /* fall through */ case 64: sstate->smb2.Signature[12] = *(p++); if (!(--input_len)) break; /* fall through */ case 65: sstate->smb2.Signature[13] = *(p++); if (!(--input_len)) break; /* fall through */ case 66: sstate->smb2.Signature[14] = *(p++); if (!(--input_len)) break; /* fall through */ case 67: sstate->smb2.Signature[15] = *(p++); --input_len; break; /* fall through */ } } sstate->bytesprocessed += (p - input); SCReturnUInt((uint32_t)(p - input)); }
/** * \brief Figured out the FP and their respective content ids for all the * sigs in the engine. * * \param de_ctx Detection engine context. * * \retval 0 On success. * \retval -1 On failure. */ int DetectSetFastPatternAndItsId(DetectEngineCtx *de_ctx) { uint32_t struct_total_size = 0; uint32_t content_total_size = 0; Signature *s = NULL; /* Count the amount of memory needed to store all the structures * and the content of those structures. This will over estimate the * true size, since duplicates are removed below, but counted here. */ for (s = de_ctx->sig_list; s != NULL; s = s->next) { RetrieveFPForSig(s); if (s->mpm_sm != NULL) { DetectContentData *cd = (DetectContentData *)s->mpm_sm->ctx; struct_total_size += sizeof(DetectFPAndItsId); content_total_size += cd->content_len; } } /* array hash buffer - i've run out of ideas to name it */ uint8_t *ahb = SCMalloc(sizeof(uint8_t) * (struct_total_size + content_total_size)); if (unlikely(ahb == NULL)) return -1; uint8_t *content = NULL; uint8_t content_len = 0; PatIntId max_id = 0; DetectFPAndItsId *struct_offset = (DetectFPAndItsId *)ahb; uint8_t *content_offset = ahb + struct_total_size; for (s = de_ctx->sig_list; s != NULL; s = s->next) { if (s->mpm_sm != NULL) { int sm_list = SigMatchListSMBelongsTo(s, s->mpm_sm); BUG_ON(sm_list == -1); DetectContentData *cd = (DetectContentData *)s->mpm_sm->ctx; DetectFPAndItsId *dup = (DetectFPAndItsId *)ahb; if (cd->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) { content = cd->content + cd->fp_chop_offset; content_len = cd->fp_chop_len; } else { content = cd->content; content_len = cd->content_len; } uint32_t flags = cd->flags & DETECT_CONTENT_NOCASE; /* Check for content already found on the same list */ for (; dup != struct_offset; dup++) { if (dup->content_len != content_len) continue; if (dup->sm_list != sm_list) continue; if (dup->flags != flags) continue; /* Check for pattern matching a duplicate. Use case insensitive matching * for case insensitive patterns. */ if (flags & DETECT_CONTENT_NOCASE) { if (SCMemcmpLowercase(dup->content, content, content_len) != 0) continue; } else { /* Case sensitive matching */ if (SCMemcmp(dup->content, content, content_len) != 0) continue; } /* Found a match with a previous pattern. */ break; } if (dup != struct_offset) { /* Exited for-loop before the end, so found an existing match. * Use its ID. */ cd->id = dup->id; continue; } /* Not found, so new content. Give it a new ID and add it * to the array. Copy the content at the end of the * content array. */ struct_offset->id = max_id++; cd->id = struct_offset->id; struct_offset->content_len = content_len; struct_offset->sm_list = sm_list; struct_offset->content = content_offset; struct_offset->flags = flags; content_offset += content_len; if (flags & DETECT_CONTENT_NOCASE) { /* Need to store case-insensitive patterns as lower case * because SCMemcmpLowercase() above assumes that all * patterns are stored lower case so that it doesn't * need to relower its first argument. */ memcpy_tolower(struct_offset->content, content, content_len); } else { memcpy(struct_offset->content, content, content_len); } struct_offset++; } /* if (s->mpm_sm != NULL) */ } /* for */ de_ctx->max_fp_id = max_id; SCFree(ahb); return 0; }
/** * \brief Compare the shared data portion of two segments * * If no data is shared, 0 will be returned. * * \param seg1 first segment * \param seg2 second segment * * \retval 0 shared data is the same (or no data is shared) * \retval 1 shared data is different */ int StreamTcpInlineSegmentCompare(TcpSegment *seg1, TcpSegment *seg2) { SCEnter(); if (seg1 == NULL || seg2 == NULL) { SCReturnInt(0); } if (SEQ_EQ(seg1->seq, seg2->seq) && seg1->payload_len == seg2->payload_len) { int r = SCMemcmp(seg1->payload, seg2->payload, seg1->payload_len); #if 0 if (r) { PrintRawDataFp(stdout,seg1->payload,seg1->payload_len); PrintRawDataFp(stdout,seg2->payload,seg2->payload_len); } #endif SCReturnInt(r); } else if (SEQ_GT(seg1->seq, (seg2->seq + seg2->payload_len))) { SCReturnInt(0); } else if (SEQ_GT(seg2->seq, (seg1->seq + seg1->payload_len))) { SCReturnInt(0); } else { SCLogDebug("seg1 %u (%u), seg2 %u (%u)", seg1->seq, seg1->payload_len, seg2->seq, seg2->payload_len); uint32_t seg1_end = seg1->seq + seg1->payload_len; uint32_t seg2_end = seg2->seq + seg2->payload_len; SCLogDebug("seg1_end %u, seg2_end %u", seg1_end, seg2_end); #if 0 SCLogDebug("seg1"); PrintRawDataFp(stdout,seg1->payload,seg1->payload_len); SCLogDebug("seg2"); PrintRawDataFp(stdout,seg2->payload,seg2->payload_len); #endif /* get the minimal seg*_end */ uint32_t end = (SEQ_GT(seg1_end, seg2_end)) ? seg2_end : seg1_end; /* and the max seq */ uint32_t seq = (SEQ_LT(seg1->seq, seg2->seq)) ? seg2->seq : seg1->seq; SCLogDebug("seq %u, end %u", seq, end); uint16_t seg1_off = seq - seg1->seq; uint16_t seg2_off = seq - seg2->seq; SCLogDebug("seg1_off %u, seg2_off %u", seg1_off, seg2_off); uint32_t range = end - seq; SCLogDebug("range %u", range); BUG_ON(range > 65536); if (range) { int r = SCMemcmp(seg1->payload+seg1_off, seg2->payload+seg2_off, range); #if 0 if (r) { PrintRawDataFp(stdout,seg1->payload+seg1_off,range); PrintRawDataFp(stdout,seg2->payload+seg2_off,range); PrintRawDataFp(stdout,seg1->payload,seg1->payload_len); PrintRawDataFp(stdout,seg2->payload,seg2->payload_len); } #endif SCReturnInt(r); } SCReturnInt(0); } }