Ejemplo n.º 1
0
/*
 *    This is the registration function.
 *
 *    When you provide "--plugin=my-plugin.so" on the command line to
 *    an application, the application calls this function to determine
 *    the new switches and/or fields that "my-plugin" provides.
 *
 *    This function is called with three arguments: the first two
 *    describe the version of the plug-in API, and the third is a
 *    pointer that is currently unused.
 */
skplugin_err_t
SKPLUGIN_SETUP_FN(
    uint16_t            major_version,
    uint16_t            minor_version,
    void        UNUSED(*plug_in_data))
{
    skplugin_err_t err;
    const char *env;

    /* Check the plug-in API version */
    err = skpinSimpleCheckVersion(major_version, minor_version,
                                  PLUGIN_API_VERSION_MAJOR,
                                  PLUGIN_API_VERSION_MINOR,
                                  skAppPrintErr);
    if (err != SKPLUGIN_OK) {
        return err;
    }

    env = getenv("INCOMING_FLOWTYPES");
    if (env && *env) {
        parseFlowtypes(env, (void*)&incoming_flowtypes);
    }
    env = getenv("OUTGOING_FLOWTYPES");
    if (env && *env) {
        parseFlowtypes(env, (void*)&outgoing_flowtypes);
    }

    /* register options for all apps that use key-field */
    err = skpinRegOption2("incoming-flowtypes", REQUIRED_ARG,
                          "List of flowtypes representing incoming flows",
                          NULL, parseFlowtypes, (void*)&incoming_flowtypes,
                          5, SKPLUGIN_APP_CUT, SKPLUGIN_APP_GROUP,
                          SKPLUGIN_APP_SORT, SKPLUGIN_APP_STATS_FIELD,
                          SKPLUGIN_APP_UNIQ_FIELD);
    if (err != SKPLUGIN_OK
        && err != SKPLUGIN_ERR_DID_NOT_REGISTER)
    {
        return err;
    }

    err = skpinRegOption2("outgoing-flowtypes", REQUIRED_ARG,
                          "List of flowtypes representing outgoing flows",
                          NULL, parseFlowtypes, (void*)&outgoing_flowtypes,
                          5, SKPLUGIN_APP_CUT, SKPLUGIN_APP_GROUP,
                          SKPLUGIN_APP_SORT, SKPLUGIN_APP_STATS_FIELD,
                          SKPLUGIN_APP_UNIQ_FIELD);
    if (err != SKPLUGIN_OK
        && err != SKPLUGIN_ERR_DID_NOT_REGISTER)
    {
        return err;
    }

    err = skpinRegCleanup(cleanup);
    if (SKPLUGIN_OK != err) {
        return err;
    }

    return SKPLUGIN_OK;
}
Ejemplo n.º 2
0
/* the registration function */
skplugin_err_t
skAddressTypesAddFields(
    uint16_t            major_version,
    uint16_t            minor_version,
    void        UNUSED(*pi_data))
{
    int i, j;
    skplugin_field_t *field = NULL;
    skplugin_callbacks_t regdata;
    skplugin_err_t rv;

     /* Check API version */
    rv = skpinSimpleCheckVersion(major_version, minor_version,
                                 PLUGIN_API_VERSION_MAJOR,
                                 PLUGIN_API_VERSION_MINOR,
                                 skAppPrintErr);
    if (rv != SKPLUGIN_OK) {
        return rv;
    }

   /* register the fields to use for rwcut, rwuniq, rwsort */
    memset(&regdata, 0, sizeof(regdata));
    regdata.init         = addrtypeInit;
    regdata.cleanup      = addrtypeCleanup;
    regdata.column_width = ADDRTYPE_TEXT_WIDTH;
    regdata.bin_bytes    = sizeof(uint8_t);
    regdata.rec_to_text  = recToText;
    regdata.rec_to_bin   = recToBin;
    regdata.bin_to_text  = binToText;

    for (i = 0; plugin_fields[i].name; ++i) {
        rv = skpinRegField(&field, plugin_fields[i].name, NULL,
                           &regdata, (void*)&plugin_fields[i].val);
        if (SKPLUGIN_OK != rv) {
            return rv;
        }
        for (j = 0; plugin_fields[i].aliases[j]; ++j) {
            rv = skpinAddFieldAlias(field, plugin_fields[i].aliases[j]);
            if (SKPLUGIN_OK != rv) {
                return rv;
            }
        }
    }

    /* sanity check */
    assert((sizeof(plugin_options)/sizeof(struct option))
           == (sizeof(plugin_help)/sizeof(char*)));

    /* register the options to use for rwfilter.  when the option is
     * given, we will call skpinRegFilter() to register the filter
     * function. */
    for (i = 0; plugin_options[i].name; ++i) {
        rv = skpinRegOption2(plugin_options[i].name, plugin_options[i].has_arg,
                             plugin_help[i], NULL, &optionsHandler,
                             (void*)&plugin_options[i].val,
                             1, SKPLUGIN_FN_FILTER);
        if (SKPLUGIN_OK != rv && SKPLUGIN_ERR_DID_NOT_REGISTER != rv) {
            return rv;
        }
    }

    return SKPLUGIN_OK;
}
Ejemplo n.º 3
0
/*
 *  skplugin_err_t pmapfile_handler(const char *opt_arg, void *cbdata)
 *
 *    Handler for --pmap-file option.  Actually registers the filter and
 *    fields.
 */
static skplugin_err_t
pmapfile_handler(
    const char         *opt_arg,
    void        UNUSED(*cbdata))
{
    /* Whether we have seen any unnamed pmaps */
    static int           have_unnamed_pmap = 0;
    skPrefixMapErr_t     map_error         = SKPREFIXMAP_OK;
    skstream_t          *stream            = NULL;
    skPrefixMap_t       *prefix_map        = NULL;
    pmap_data_t         *pmap_data         = NULL;
    int                  ok;
    const char          *filename;
    const char          *sep;
    const char          *mapname;
    char                *prefixed_name     = NULL;
    char                *short_prefixed_name;
    size_t               namelen           = 0;
    size_t               i;
    int                  rv                = SKPLUGIN_ERR;
    skplugin_callbacks_t regdata;

    /* We can only have one pmap whenever we any any pmap without a
     * mapname.  If we've seen one and enter this function a second
     * time, it is an error */
    if (have_unnamed_pmap) {
        skAppPrintErr(("Invalid %s: You may use only one prefix map"
                       " when you are\n"
                       "\tusing a prefix map without specifying a mapname"),
                      pmap_file_option);
        return SKPLUGIN_ERR;
    }

    /* Parse the argument into a field name and file name */
    sep = strchr(opt_arg, ':');
    if (NULL == sep) {
        /* We do not have a mapname.  We'll check for one in the pmap
         * once we read it. */
        mapname = NULL;
        filename = opt_arg;
    } else {
        /* A mapname was supplied on the command line */
        if (sep == opt_arg) {
            skAppPrintErr("Invalid %s: Zero length mapnames are not allowed",
                          pmap_file_option);
            return SKPLUGIN_ERR;
        }
        if (memchr(opt_arg, ',', sep - opt_arg) != NULL) {
            skAppPrintErr("Invalid %s: The mapname may not include a comma",
                          pmap_file_option);
            return SKPLUGIN_ERR;
        }
        mapname = opt_arg;
        filename = sep + 1;
        namelen = sep - opt_arg;
    }

    ok = skpinOpenDataInputStream(&stream, SK_CONTENT_SILK, filename);
    if (ok == -1) {
        /* problem opening file */
        skAppPrintErr("Failed to open the prefix map file '%s'",
                      filename);
        return SKPLUGIN_ERR;
    }
    if (ok == 1) {
        /* master needs to process the file, since it may contain the
         * map name we use for creating switches */
        if ((rv = skStreamCreate(&stream, SK_IO_READ, SK_CONTENT_SILK))
            || (rv = skStreamBind(stream, filename))
            || (rv = skStreamOpen(stream)))
        {
            skStreamPrintLastErr(stream, rv, &skAppPrintErr);
            skStreamDestroy(&stream);
            return SKPLUGIN_ERR;
        }

        /* the master can ignore the file for filtering */
        ignore_prefix_map = 1;
    }

    map_error = skPrefixMapRead(&prefix_map, stream);
    if (SKPREFIXMAP_OK != map_error) {
        if (SKPREFIXMAP_ERR_IO == map_error) {
            skStreamPrintLastErr(stream, skStreamGetLastReturnValue(stream),
                                 &skAppPrintErr);
        } else {
            skAppPrintErr("Failed to read the prefix map file '%s': %s",
                          opt_arg, skPrefixMapStrerror(map_error));
        }
        skStreamDestroy(&stream);
        return SKPLUGIN_ERR;
    }
    skStreamDestroy(&stream);

    if (NULL == mapname) {
        /* No mapname was supplied on the command line.  Check for a
         * mapname insided the pmap. */
        mapname = skPrefixMapGetMapName(prefix_map);
        if (mapname) {
            /* The pmap supplied a mapname */
            namelen = strlen(mapname);
        } else {
            /* No mapname.  Accept for legacy purposes, unless we have
             * read any other pmaps */
            have_unnamed_pmap = 1;
            if (skVectorGetCount(pmap_vector) != 0) {
                skAppPrintErr(("Invalid %s: You may use only one prefix map"
                               " when you are\n"
                               "\t using a prefix map without"
                               " specifying a mapname"),
                              pmap_file_option);
                goto END;
            }
        }
    }

    /* Allocate the pmap_data structure */
    pmap_data = (pmap_data_t *)calloc(1, sizeof(*pmap_data));
    if (pmap_data == NULL) {
        ERR_NO_MEM(pmap_data);
        rv = SKPLUGIN_ERR_FATAL;
        goto END;
    }

    /* pmap_data now "owns" prefix_map */
    pmap_data->pmap = prefix_map;
    prefix_map = NULL;

    /* Cache the content type */
    pmap_data->type = skPrefixMapGetContentType(pmap_data->pmap);

    /* Fill the direction structure for each direction */
    pmap_data->sdir.dir = DIR_SOURCE;
    pmap_data->ddir.dir = DIR_DEST;
    pmap_data->adir.dir = DIR_ANY;
    pmap_data->sdir.data = pmap_data;
    pmap_data->ddir.data = pmap_data;
    pmap_data->adir.data = pmap_data;

    /* Record the path to the pmap file */
    pmap_data->filepath = strdup(filename);
    if (NULL == pmap_data->filepath) {
        ERR_NO_MEM(pmap_data->filepath);
        rv = SKPLUGIN_ERR_FATAL;
        goto END;
    }

    if (mapname == NULL)  {
        /* Pmap without a mapname. */

        /* Add the proper legacy option names to the pmap_data structure */
        switch (pmap_data->type) {
          case SKPREFIXMAP_CONT_ADDR_V4:
          case SKPREFIXMAP_CONT_ADDR_V6:
            pmap_data->sdir.filter_option = strdup(pmap_saddress_option);
            pmap_data->ddir.filter_option = strdup(pmap_daddress_option);
            pmap_data->adir.filter_option = strdup(pmap_aaddress_option);
            break;
          case SKPREFIXMAP_CONT_PROTO_PORT:
            pmap_data->sdir.filter_option = strdup(pmap_sport_proto_option);
            pmap_data->ddir.filter_option = strdup(pmap_dport_proto_option);
            pmap_data->adir.filter_option = strdup(pmap_aport_proto_option);
            break;
        }
        if ((pmap_data->sdir.filter_option == NULL)
            || (pmap_data->ddir.filter_option == NULL)
            || (pmap_data->adir.filter_option == NULL))
        {
            ERR_NO_MEM(filter_option);
            rv = SKPLUGIN_ERR_FATAL;
            goto END;
        }
        pmap_data->mapname = strdup(pmap_title_val);
        pmap_data->sdir.field_name = strdup(pmap_title_sval);
        pmap_data->ddir.field_name = strdup(pmap_title_dval);
        if ((pmap_data->mapname == NULL)
            || (pmap_data->sdir.field_name == NULL)
            || (pmap_data->ddir.field_name == NULL))
        {
            ERR_NO_MEM(field_name);
            rv = SKPLUGIN_ERR_FATAL;
            goto END;
        }

    } else { /* if (mapname == NULL) */

        /* Create the field names*/
        pmap_data->mapname = (char*)malloc(namelen + 1);
        if (NULL == pmap_data->mapname) {
            ERR_NO_MEM(pmap_data->mapname);
            rv = SKPLUGIN_ERR_FATAL;
            goto END;
        }
        strncpy(pmap_data->mapname, mapname, namelen);
        pmap_data->mapname[namelen] = '\0';

        /* Allocate space for the [pmap-]{src-,dst-}<mapname> string */
        prefixed_name
            = (char*)malloc(namelen + pmap_prefix_len + dir_name_len + 1);
        if (NULL == prefixed_name) {
            ERR_NO_MEM(prefixed_name);
            rv = SKPLUGIN_ERR_FATAL;
            goto END;
        }

        /* Copy in the pmap- prefix */
        strncpy(prefixed_name, pmap_prefix, pmap_prefix_len);

        /* short name (for fields) starts at the {src-,dst-} */
        short_prefixed_name = prefixed_name + pmap_prefix_len;

        /* add in the actual field name, and zero terminate it */
        strncpy(short_prefixed_name + dir_name_len, mapname, namelen);
        short_prefixed_name[namelen + dir_name_len] = '\0';

        /* Create the destination-themed names */
        strncpy(short_prefixed_name, src_dir_name, dir_name_len);
        pmap_data->sdir.filter_option = strdup(prefixed_name);
        pmap_data->sdir.field_name = strdup(short_prefixed_name);
        if ((pmap_data->sdir.filter_option == NULL)
            || (pmap_data->sdir.field_name == NULL))
        {
            ERR_NO_MEM(pmap_data->sdir);
            rv = SKPLUGIN_ERR_FATAL;
            goto END;
        }
        strncpy(short_prefixed_name, dst_dir_name, dir_name_len);
        pmap_data->ddir.filter_option = strdup(prefixed_name);
        pmap_data->ddir.field_name = strdup(short_prefixed_name);
        if ((pmap_data->ddir.filter_option == NULL)
            || (pmap_data->ddir.field_name == NULL))
        {
            ERR_NO_MEM(pmap_data->ddir);
            rv = SKPLUGIN_ERR_FATAL;
            goto END;
        }
        strncpy(short_prefixed_name, any_dir_name, dir_name_len);
        pmap_data->adir.filter_option = strdup(prefixed_name);
        if (pmap_data->adir.filter_option == NULL) {
            ERR_NO_MEM(pmap_data->adir);
            rv = SKPLUGIN_ERR_FATAL;
            goto END;
        }

        /* Free the temporary name buffer */
        free(prefixed_name);
        prefixed_name = NULL;

    } /* if (mapname == NULL) */


    /* Verify unique field names */
    for (i = 0; i < skVectorGetCount(pmap_vector); i++) {
        pmap_data_t *p;

        skVectorGetValue(&p, pmap_vector, i);
        if ((strcmp(pmap_data->mapname, p->mapname) == 0) ||
            (strcmp(pmap_data->sdir.field_name, p->sdir.field_name) == 0) ||
            (strcmp(pmap_data->ddir.field_name, p->ddir.field_name) == 0))
        {
            skAppPrintErr(("Invalid %s: Multiple pmaps use the mapname '%s':\n"
                           "\t%s\n\t%s"),
                          pmap_file_option, pmap_data->mapname,
                          p->filepath, pmap_data->filepath);
            rv = SKPLUGIN_ERR;
            goto END;
        }
    }

    /* Register fields and filter options */
    memset(&regdata, 0, sizeof(regdata));
    regdata.init = pmap_field_init;
    regdata.column_width = 0;
    regdata.bin_bytes = 4;
    regdata.rec_to_text = pmap_text_fn;
    regdata.rec_to_bin = pmap_bin_fn;
    regdata.bin_to_text = pmap_bin_to_text_fn;

    for (i = 0; i < 2; ++i) {
        directed_pmap_data_t *dir = ((0 == i)
                                     ? &pmap_data->sdir
                                     : &pmap_data->ddir);

        skpinRegField(&dir->field, dir->field_name, NULL, &regdata, dir);
        skpinRegOption2(dir->filter_option,
                        REQUIRED_ARG,
                        NULL, &pmap_filter_help,
                        &pmap_handle_filter_option, dir,
                        1, SKPLUGIN_FN_FILTER);
    }

    /* Register the "any" filter separately */
    skpinRegOption2(pmap_data->adir.filter_option,
                    REQUIRED_ARG,
                    NULL, &pmap_filter_help,
                    &pmap_handle_filter_option, &pmap_data->adir,
                    1, SKPLUGIN_FN_FILTER);


    if (skVectorAppendValue(pmap_vector, &pmap_data)) {
        rv = SKPLUGIN_ERR_FATAL;
        goto END;
    }

    rv = SKPLUGIN_OK;

  END:
    /* Free the temporary name buffer */
    if (prefixed_name) {
        free(prefixed_name);
    }
    if (rv != SKPLUGIN_OK) {
        if (prefix_map) {
            skPrefixMapDelete(prefix_map);
        }
        if (pmap_data) {
            pmap_data_destroy(pmap_data);
        }
    }
    return (skplugin_err_t)rv;
}
Ejemplo n.º 4
0
/* Public entry point */
skplugin_err_t
skPrefixMapAddFields(
    uint16_t            major_version,
    uint16_t            minor_version,
    void        UNUSED(*data))
{
    skplugin_err_t err;

#define PMAP_FILE_HELP(str_arg)                                         \
    ("Prefix map file to read.  Def. None.  When the argument has\n"    \
     "\tthe form \"<mapfile>:<filename>\","                             \
     " the \"mapname\" is used to generate\n"                           \
     str_arg)

    assert(strlen(src_dir_name) == strlen(dst_dir_name));

    /* Check API version */
    err = skpinSimpleCheckVersion(major_version, minor_version,
                                  PLUGIN_API_VERSION_MAJOR,
                                  PLUGIN_API_VERSION_MINOR,
                                  skAppPrintErr);
    if (err != SKPLUGIN_OK) {
        return err;
    }

    /* Initialize global variables */
    pmap_vector = skVectorNew(sizeof(pmap_data_t *));
    if (pmap_vector == NULL) {
        ERR_NO_MEM(pmap_vector);
        return SKPLUGIN_ERR;
    }

    /* Add --pmap-file to apps that accept RWREC: rwcut, rwsort, etc */
    err = skpinRegOption2(pmap_file_option,
                          REQUIRED_ARG,
                          PMAP_FILE_HELP(
                              "\tfield names.  As such, this switch must"
                              " precede the --fields switch."), NULL,
                          pmapfile_handler, NULL,
                          2,
                          SKPLUGIN_FN_REC_TO_TEXT,
                          SKPLUGIN_FN_REC_TO_BIN);
    if (err == SKPLUGIN_ERR_FATAL) {
        return err;
    }

    /* Add --pmap-column-width to apps that produce TEXT: rwcut, rwuniq  */
    err = skpinRegOption2(pmap_column_width_option,
                          REQUIRED_ARG,
                          "Maximum column width to use for output.", NULL,
                          pmap_column_width_handler, NULL,
                          2,
                          SKPLUGIN_FN_REC_TO_TEXT,
                          SKPLUGIN_FN_BIN_TO_TEXT);
    if (err == SKPLUGIN_ERR_FATAL) {
        return err;
    }

    /* Add --pmap-file to rwfilter */
    err = skpinRegOption2(pmap_file_option,
                          REQUIRED_ARG,
                          PMAP_FILE_HELP(
                              "\tfiltering switches.  This switch must"
                              " precede other --pmap-* switches."), NULL,
                          pmapfile_handler, NULL,
                          1, SKPLUGIN_FN_FILTER);
    if (err == SKPLUGIN_ERR_FATAL) {
        return err;
    }

    /* Register cleanup function */
    skpinRegCleanup(pmap_teardown);

    return SKPLUGIN_OK;
}
Ejemplo n.º 5
0
/* the registration function called by skplugin.c */
skplugin_err_t
SKPLUGIN_SETUP_FN(
    uint16_t            major_version,
    uint16_t            minor_version,
    void        UNUSED(*pi_data))
{
    int i;
    skplugin_field_t *field;
    skplugin_err_t rv;
    skplugin_callbacks_t regdata;

    /* Check API version */
    rv = skpinSimpleCheckVersion(major_version, minor_version,
                                 PLUGIN_API_VERSION_MAJOR,
                                 PLUGIN_API_VERSION_MINOR,
                                 skAppPrintErr);
    if (rv != SKPLUGIN_OK) {
        return rv;
    }

    assert((sizeof(plugin_options)/sizeof(struct option))
           == (sizeof(plugin_help)/sizeof(char*)));

    /* register the options for rwfilter.  when the option is given,
     * we call skpinRegFilter() to register the filter function.
     * NOTE: Skip the first entry in the plugin_options[] array. */
    for (i = 1; plugin_options[i].name; ++i) {
        rv = skpinRegOption2(plugin_options[i].name,
                             plugin_options[i].has_arg, plugin_help[i],
                             NULL, &optionsHandler,
                             (void*)&plugin_options[i].val,
                             1, SKPLUGIN_FN_FILTER);
        if (SKPLUGIN_OK != rv && SKPLUGIN_ERR_DID_NOT_REGISTER != rv) {
            return rv;
        }
    }

    /* the first entry in the plugin_options[] array is usable by all
     * applications */
    rv = skpinRegOption2(plugin_options[0].name,
                         plugin_options[0].has_arg, plugin_help[0],
                         NULL, &optionsHandler,
                         (void*)&plugin_options[0].val,
                         3, SKPLUGIN_FN_FILTER, SKPLUGIN_FN_REC_TO_TEXT,
                         SKPLUGIN_FN_REC_TO_BIN);
    if (SKPLUGIN_OK != rv && SKPLUGIN_ERR_DID_NOT_REGISTER != rv) {
        return rv;
    }

    /* register the key fields to use for rwcut, rwuniq, rwsort,
     * rwstats */
    memset(&regdata, 0, sizeof(regdata));
    regdata.column_width = RATE_TEXT_WIDTH;
    regdata.bin_bytes    = RATE_BINARY_SIZE_KEY;
    regdata.rec_to_text  = recToTextKey;
    regdata.rec_to_bin   = recToBinKey;
    regdata.bin_to_text  = binToTextKey;

    for (i = 0; plugin_fields[i].name; ++i) {
        rv = skpinRegField(&field, plugin_fields[i].name,
                           plugin_fields[i].description,
                           &regdata, (void*)&plugin_fields[i].val);
        if (SKPLUGIN_OK != rv) {
            return rv;
        }
    }

    /* register the aggregate value fields to use for rwuniq and
     * rwstats */
    memset(&regdata, 0, sizeof(regdata));
    regdata.column_width    = RATE_TEXT_WIDTH;
    regdata.bin_bytes       = RATE_BINARY_SIZE_AGG;
    regdata.add_rec_to_bin  = addRecToBinAgg;
    regdata.bin_to_text     = binToTextAgg;
    regdata.bin_merge       = binMergeAgg;
    regdata.bin_compare     = binCompareAgg;

    for (++i; plugin_fields[i].name; ++i) {
        if (PAYLOAD_BYTES_AGG == plugin_fields[i].val) {
            /* special case size of payload-bytes */
            regdata.bin_bytes = sizeof(uint64_t);
            rv = skpinRegField(&field, plugin_fields[i].name,
                               plugin_fields[i].description,
                               &regdata, (void*)&plugin_fields[i].val);
            regdata.bin_bytes = RATE_BINARY_SIZE_AGG;
        } else {
            rv = skpinRegField(&field, plugin_fields[i].name,
                               plugin_fields[i].description,
                               &regdata, (void*)&plugin_fields[i].val);
        }
        if (SKPLUGIN_OK != rv) {
            return rv;
        }
    }

    return SKPLUGIN_OK;
}