Exemple #1
0
/**
 * \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;
}
Exemple #2
0
static int MemcmpTest07 (void) {
    uint8_t a[] = "abcd";
    uint8_t b[] = "abcde";

    if (SCMemcmp(a, b, sizeof(a)-1) != 0)
        return 0;

    return 1;
}
Exemple #3
0
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;
}
Exemple #4
0
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;
}
Exemple #6
0
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);
}
Exemple #8
0
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));
}
Exemple #9
0
/**
 * \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;
}
Exemple #10
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);
    }
}