Example #1
0
static void broadcast_check(void)
{
    struct {
        int version;
        char const *str;
        uint32_t netmask;
        bool is_broadcast;
    } tests[] = {
        { 4, "1.0.0.0",        0xff000000U, false },
        { 4, "127.0.0.1",      0xff000000U, false },
        { 4, "128.10.5.255",   0xffff0000U, false },
        { 4, "192.168.10.9",   0xffffff00U, false },
        { 4, "10.255.255.255", 0xff000000U, true  },
        { 4, "127.0.255.255",  0xff000000U, false },
        { 4, "128.0.255.255",  0xffff0000U, true  },
        { 4, "192.168.10.255", 0xffffff00U, true  },
        { 6, "ff02::1",        0,           true  },
        { 6, "1:2:3:4::",      0,           false },
    };

    for (unsigned t = 0; t < NB_ELEMS(tests); t++) {
        struct ip_addr addr;
        ip_addr_ctor_from_str(&addr, tests[t].str, strlen(tests[t].str), tests[t].version);
        if (addr.family == AF_INET) {
            assert(netmask_of_address(addr.u.v4) == tests[t].netmask);
        }
        assert(ip_addr_is_broadcast(&addr) == tests[t].is_broadcast);
    }
}
Example #2
0
static void all_fini(void)
{
    // Make some effort to honnor any plugins destructor at exit

    doomer_stop();  // doomer_thread must not awake while we destroy parsers, plugins, and so on

    pkt_source_fini();
    plugin_del_all(); // Since hook subscribers is not locked, we must kill sources before unregister plugins

    for (unsigned i = NB_ELEMS(initers); i > 0; ) {
        initers[--i].fini();
    }

#   ifdef DELETE_ALL_AT_EXIT
    /* This is sometime usefull to clean all allocated ressources
     * at exit to help valgrind help us find memory leaks. */
    ERR_free_strings();
#   endif

    redim_array_fini();
    hash_fini();
    ref_fini();
    mallocer_fini();
    cli_fini();
    ext_fini();
    files_fini();
    log_fini();
}
Example #3
0
static void scm_conv_check(void)
{
    scm_init_guile();
    static struct {
        int version;
        char const *str;
        char const *num;
        sa_family_t exp_family;
    } tests[] = {
        { 4, "1.0.0.0", "(%d . 16777216)", AF_INET },
        { 4, "127.0.0.1", "(%d . 2130706433)", AF_INET },
        { 4, "128.10.5.255", "(%d . 2148140543)", AF_INET },
        { 6, "ff02::1", "(%d . 338963523518870617245727861364146307073)", AF_INET6 },
        { 6, "1:2:3:4::", "(%d . 5192455318486707403025865779445760)", AF_INET6 },
    };

    for (unsigned t = 0; t < NB_ELEMS(tests); t++) {
        struct ip_addr addr;
        ip_addr_ctor_from_str(&addr, tests[t].str, strlen(tests[t].str), tests[t].version);
        SCM ip = scm_from_ip_addr(&addr);
        SCM str = scm_simple_format(SCM_BOOL_F, scm_from_latin1_string("~a"), scm_cons(ip, SCM_EOL));
        char buf[256];
        size_t len = scm_to_locale_stringbuf(str, buf, sizeof(buf));
        assert(len < sizeof(buf));
        buf[len] = '\0';
        char expected[256];
        snprintf(expected, sizeof(expected), tests[t].num, tests[t].exp_family);

        printf("%s -> '%s' (expected '%s')\n", tests[t].str, buf, expected);
        assert(0 == strcmp(expected, buf));
    }
}
Example #4
0
/*
 * Check if query is valid.
 * @param cursor to read
 * @param candidate Filled with potential sql size candidate
 * @return True if a correct query has been found and cursor is positioned at the begin of the query
 */
static bool lookup_query(struct cursor *cursor, struct query_candidate *candidate)
{
    SLOG(LOG_DEBUG, "Start looking for query");
    uint8_t current;
    uint8_t next;

    while (cursor->cap_len > QUERY_WITH_SIZE) {
        current = cursor_peek_u8(cursor, 0);
        next = cursor_peek_u8(cursor, 1);
        if (current == TTC_ROW_DATA && next > 0 && next <= 4) {
            SLOG(LOG_DEBUG, " Looks like start of a data query row");
            return false;
        }
        if (current > 0 && current < 3 && next > MIN_QUERY_SIZE
                && candidate->num_candidate_size < NB_ELEMS(candidate->candidate_sizes)) {
            uint64_t buf = 0;
            // Copy cursor since we might have pattern like 0x01 Size Query
            struct cursor cursor_copy = *cursor;
            if (PROTO_OK == cursor_read_variable_int(&cursor_copy, &buf)) {
                SLOG(LOG_DEBUG, " Found a candidate size %"PRIu64, buf);
                insert_array_sorted(candidate, buf);
            }
        }
        if (candidate->num_candidate_size == 0 || current >= candidate->candidate_sizes[0]) {
            if (check_chuncked_query(cursor, current, next, candidate)) return true;
            if (check_fixed_query(cursor, current, next, candidate)) return true;
        } else {
            if (check_fixed_query(cursor, current, next, candidate)) return true;
            if (check_chuncked_query(cursor, current, next, candidate)) return true;
        }
        cursor_drop(cursor, 1);
    }
    return false;
}
Example #5
0
File: mgcp.c Project: rixed/junkie
static enum mgcp_command mgcp_code_2_command(char const *code, size_t len)
{
#   define COMMAND_LEN 4
    static struct {
        char code[COMMAND_LEN+1];
        enum mgcp_command command;
    } verbs[] = {
        { "EPCF", MGCP_EndpointConfiguration },
        { "CRCX", MGCP_CreateConnection },
        { "MDCX", MGCP_ModifyConnection },
        { "DLCX", MGCP_DeleteConnection },
        { "RQNT", MGCP_NotificationRequest },
        { "NTFY", MGCP_Notify },
        { "AUEP", MGCP_AuditEndpoint },
        { "AUCX", MGCP_AuditConnection },
        { "RSIP", MGCP_RestartInProgress },
    };

    if (len < COMMAND_LEN) return (enum mgcp_command)-1;

    for (unsigned v = 0; v < NB_ELEMS(verbs); v++) {
        if (0 == strncasecmp(code, verbs[v].code, COMMAND_LEN)) return verbs[v].command;
    }

    return (enum mgcp_command)-1;
}
Example #6
0
int sdper_parse(struct sdper const *sdper, size_t *head_sz, uint8_t const *packet, size_t packet_len, void *user_data)
{
    // REVIEW: eols and spcs should be provided by liner.
    struct liner_delimiter
        eols[] = { { "\r\n", 2 }, { "\n", 1 } },
        cols[] = { { "= ", 2}, { "=", 1 } };
    struct liner_delimiter_set const
        lines =  { NB_ELEMS(eols), eols, false },
        eq = { NB_ELEMS(cols), cols, true };

    struct liner liner, tokenizer;

    liner_init(&liner, &lines, (char const *)packet, packet_len);

    // Parse header fields
    while (true) {
        // Next line
        if (liner_eof(&liner)) break;

        // Otherwise tokenize the header line
        liner_init(&tokenizer, &eq, liner.start, liner_tok_length(&liner));

        for (unsigned f = 0; f < sdper->nb_fields; f++) {
            struct sdper_field const *field = sdper->fields + f;

            size_t len = liner_tok_length(&tokenizer);
            if (len != field->length)
              continue;

            if (0 != strncasecmp(field->name, tokenizer.start, len)) continue;

            SLOG(LOG_DEBUG, "Found field %s", field->name);
            liner_next(&tokenizer);
            int ret = field->cb(f, &tokenizer, user_data);
            if (ret) return ret;
            break;
        }

        liner_next(&liner);
    }

    if (head_sz) *head_sz = liner_parsed(&liner);
    return 0;
}
Example #7
0
File: mgcp.c Project: rixed/junkie
unsigned parse_events(struct liner *liner)
{
    unsigned flags = 0;
    for (unsigned e = 0; e < NB_ELEMS(events); e++) {
        if (
            (liner_tok_length(liner) >= 4 && 0 == strncasecmp(liner->start, events[e].code, 4)) ||
            (events[e].from_line && (liner_tok_length(liner) >= 2 && 0 == strncasecmp(liner->start, events[e].code+2, 2)))
        ) {
            flags |= events[e].flag;
        }
    }
    return flags;
}
Example #8
0
void on_load(void)
{
    log_category_duplicogram_init();
    ext_param_bucket_width_init();

    SLOG(LOG_INFO, "Duplicogram loaded");

    term_init(&handle_key);

    cli_register("Duplicogram plugin", duplicogram_opts, NB_ELEMS(duplicogram_opts));

    mutex_ctor(&dup_lock, "Duplicogram mutex");

    ext_function_ctor(&sg_get_duplicogram,
        "get-duplicogram", 0, 0, 0, g_get_duplicogram,
        "(get-duplicogram): fetch duplicogram data and reset internal state. Not for the casual user");

    hook_subscriber_ctor(&dup_hook, &dup_subscription, dup_callback);
    hook_subscriber_ctor(&proto_cap->hook, &cap_subscription, cap_callback);
}
Example #9
0
static void ip_addr_ctor_from_str_check(void)
{
    static struct {
        char const *str;
        int mode;
    } const tests[] = {
        { "0.0.0.0",        4, },
        { "1.2.3.4",        4, },
        { "0.0.0.1",        4, },
        { "128.2.1.255",    4, },
        { "::ffff:1.2.3.4", 6, },
    };

    for (unsigned t = 0; t < NB_ELEMS(tests); t++) {
        struct ip_addr addr;
        ip_addr_ctor_from_str(&addr, tests[t].str, strlen(tests[t].str), tests[t].mode );
        char const *str = ip_addr_2_str(&addr);
        SLOG(LOG_DEBUG, "Comparing '%s' with '%s'", tests[t].str, str);
        assert(0 == strcmp(str, tests[t].str));
    }
}
Example #10
0
static void ip_addr_routable_check(void)
{
    static struct {
        char const *str;
        int mode;
        bool routable;
    } const tests[] = {
        { "0.0.0.0",        4, true },
        { "1.2.3.4",        4, true },
        { "0.0.0.1",        4, true },
        { "128.2.1.255",    4, true },
        { "::ffff:1.2.3.4", 6, true },
        { "127.0.0.1",      4, false },
        { "172.24.5.4",     4, false },
        { "192.168.10.9",   4, false },
    };

    for (unsigned t = 0; t < NB_ELEMS(tests); t++) {
        struct ip_addr addr;
        ip_addr_ctor_from_str(&addr, tests[t].str, strlen(tests[t].str), tests[t].mode);
        assert(ip_addr_is_routable(&addr) == tests[t].routable);
    }
}
Example #11
0
static void all_init(void)
{
    log_init();
    files_init();
    ext_init();
    cli_init();
    mallocer_init();    // as all users do not init it...
    ref_init(); // as all users do not init it...
    hash_init();    // as all users do not init it...
    redim_array_init(); // if there are no users then some ext functions used by the www interface won't be defined
    os_detect_init();   // dummy function just to include os_detect in junkie (that does not use it, but plugins may want to)

    // Openssl don't like to be inited several times so let's do it once and for all
    SSL_load_error_strings();
    SSL_library_init();
    OpenSSL_add_all_algorithms();

    for (unsigned i = 0; i < NB_ELEMS(initers); i++) {
        initers[i].init();
    }

    ext_rebind();
}
Example #12
0
File: sip.c Project: rixed/junkie
        [SIP_CMD_BYE] =      { STRING_AND_LEN("BYE"),      sip_set_command },
        [SIP_CMD_BYE+1] =    { STRING_AND_LEN("SIP/2.0"),  sip_set_response },
    };

    static struct httper_field const fields[] = {
        { STRING_AND_LEN("content-length"), sip_extract_content_length },
        { STRING_AND_LEN("content-type"),   sip_extract_content_type },
        { STRING_AND_LEN("cseq"),           sip_extract_cseq },
        { STRING_AND_LEN("call-id"),        sip_extract_callid },
        { STRING_AND_LEN("from"),           sip_extract_from },
        { STRING_AND_LEN("to"),             sip_extract_to },
        { STRING_AND_LEN("via"),            sip_extract_via },
    };

    static struct httper const httper = {
        .nb_commands = NB_ELEMS(commands),
        .commands = commands,
        .nb_fields = NB_ELEMS(fields),
        .fields = fields
    };

    SLOG(LOG_DEBUG, "Starting SIP analysis");

    /* Parse */

    struct sip_proto_info info;
    info.set_values = 0;

    size_t siphdr_len;
    enum proto_parse_status status = httper_parse(&httper, &siphdr_len, packet, cap_len, &info);
    if (status != PROTO_OK) return PROTO_PARSE_ERR; // TODO: handle short packets with the help of a streambuf ?
Example #13
0
File: tcp.c Project: Mybrc91/junkie
static ssize_t parse_next_option(struct tcp_proto_info *info, uint8_t const *options, size_t rem_len)
{
    assert(rem_len > 0);
    if (rem_len < 1) return -1;

    uint8_t const kind = options[0];

    // We only decode MSS and WSF but record all options
    if (info->nb_options < NB_ELEMS(info->options)) {
        info->options[info->nb_options++] = kind;
    }

    if (kind == 0) {    // end of option list
        if (rem_len > 4) {
            SLOG(LOG_DEBUG, "Option list terminated while %zu bytes left", rem_len-1);
            return rem_len; // keep parsing payload
        }
        if ((intptr_t)(options+rem_len) & 0x3) {
            SLOG(LOG_DEBUG, "Option list ends in a non word boundary");
            return -1;
        }
        // TODO: check that padding is composed of zeros
        return rem_len;
    } else if (kind == 1) {
        return 1;
    }

    if (rem_len < 2) {
        SLOG(LOG_DEBUG, "Invalid TCP options: can't read length");
        return -1;
    }
    size_t const len = options[1];  // len includes what's read before
    if (len < 2) {
        SLOG(LOG_DEBUG, "Invalid TCP options: len field (%zu) < 2", len);
        return -1;
    }
    if (rem_len < len) {
        SLOG(LOG_DEBUG, "Invalid TCP options: length (%zu) > rem options bytes (%zu)", len, rem_len);
        return -1;
    }

    switch (kind) {
        case 2: // MSS
            if (len != 4) {
                SLOG(LOG_DEBUG, "MSS with length %zu", len);
                return -1;
            }
            info->set_values |= TCP_MSS_SET;
            info->mss = READ_U16N(options+2);
            break;
        case 3: // Window Scale Factor
            if (len != 3) {
                SLOG(LOG_DEBUG, "WSF with length %zu", len);
                return -1;
            }
            info->set_values |= TCP_WSF_SET;
            info->wsf = options[2];
            break;
    }

    return len;
}