Beispiel #1
0
/*
 *  status = appOptionsHandler(cData, opt_index, opt_arg);
 *
 *    This function is passed to skOptionsRegister(); it will be called
 *    by skOptionsParse() for each user-specified switch that the
 *    application has registered; it should handle the switch as
 *    required---typically by setting global variables---and return 1
 *    if the switch processing failed or 0 if it succeeded.  Returning
 *    a non-zero from from the handler causes skOptionsParse() to return
 *    a negative value.
 *
 *    The clientData in 'cData' is typically ignored; 'opt_index' is
 *    the index number that was specified as the last value for each
 *    struct option in appOptions[]; 'opt_arg' is the user's argument
 *    to the switch for options that have a REQUIRED_ARG or an
 *    OPTIONAL_ARG.
 */
static int
appOptionsHandler(
    clientData   UNUSED(cData),
    int                 opt_index,
    char               *opt_arg)
{
    uint32_t val;
    int rv;

    switch ((appOptionsEnum)opt_index) {
      case OPT_TEST_FEATURES:
        rv = skStringParseUint32(&val, opt_arg, 0,
                                 (SKLOG_FEATURE_LEGACY | SKLOG_FEATURE_SYSLOG));
        if (rv) {
            goto PARSE_ERROR;
        }
        if (sklogSetup((int)val)) {
            skAppPrintErr("Unable to setup log");
            exit(EXIT_FAILURE);
        }
        break;

      case OPT_TEST_EMERG:
        test_emerg = 1;
        break;

      case OPT_TEST_THREADED:
        test_threaded = 1;
        sklogEnableThreadedLogging();
        break;

      case OPT_REPEAT_COUNT:
        rv = skStringParseUint32(&val, opt_arg, 0, 0);
        if (rv) {
            goto PARSE_ERROR;
        }
        repeat_count = val;
        break;

      case OPT_REPEAT_DELAY:
        rv = skStringParseUint32(&val, opt_arg, 0, 0);
        if (rv) {
            goto PARSE_ERROR;
        }
        repeat_delay = val;
        break;
    }

    return 0;  /* OK */

  PARSE_ERROR:
    skAppPrintErr("Invalid %s '%s': %s",
                  appOptions[opt_index].name, opt_arg,
                  skStringParseStrerror(rv));
    return 1;
}
Beispiel #2
0
/*
 *  status = appOptionsHandler(cData, opt_index, opt_arg);
 *
 *    This function is passed to skOptionsRegister(); it will be called
 *    by skOptionsParse() for each user-specified switch that the
 *    application has registered; it should handle the switch as
 *    required---typically by setting global variables---and return 1
 *    if the switch processing failed or 0 if it succeeded.  Returning
 *    a non-zero from from the handler causes skOptionsParse() to return
 *    a negative value.
 *
 *    The clientData in 'cData' is typically ignored; 'opt_index' is
 *    the index number that was specified as the last value for each
 *    struct option in appOptions[]; 'opt_arg' is the user's argument
 *    to the switch for options that have a REQUIRED_ARG or an
 *    OPTIONAL_ARG.
 */
static int
appOptionsHandler(
    clientData   UNUSED(cData),
    int                 opt_index,
    char               *opt_arg)
{
    int rv;

    switch ((appOptionsEnum)opt_index) {
#error "Add options handling here.  Return 1 on failure."

      case OPT_FIRST:           /* remove when real options added */
        /* do something with the argument to the switch; for example,
         * parse as an integer */
        rv = skStringParseUint32(&value, opt_arg, 0, 0);
        if (rv) {
            goto PARSE_ERROR;
        }
        break;

      case OPT_SECOND:          /* remove when real options added */
        /* set a flag based on this option */
        flag = 1;
        break;
    }

    return 0;  /* OK */

  PARSE_ERROR:
    skAppPrintErr("Invalid %s '%s': %s",
                  appOptions[opt_index].name, opt_arg,
                  skStringParseStrerror(rv));
    return 1;
}
Beispiel #3
0
/*
 *  printByNameOrNumber(sensor);
 *
 *    Look up the sensor that has the name or the ID specified in the
 *    string 'sensor' and print it to OUT_FH.  Also print its
 *    class(es) if requested.
 */
static void
printByNameOrNumber(
    const char         *sensor)
{
    char sensor_name[SK_MAX_STRLEN_SENSOR+1];
    int rv;
    uint32_t temp;
    sensorID_t sid;
    int count;
    sensor_iter_t si;

    /* try to parse as a number */
    rv = skStringParseUint32(&temp, sensor, 0, SK_INVALID_SENSOR-1);
    if (rv < 0 && rv != SKUTILS_ERR_BAD_CHAR) {
        skAppPrintErr("Invalid Sensor Number '%s': %s",
                      sensor, skStringParseStrerror(rv));
        return;
    }
    if (rv == 0) {
        /* got a clean parse */
        sid = (sensorID_t)temp;
        if ( !sksiteSensorExists(sid) ) {
            skAppPrintErr("Number '%s' is not a valid sensor number",
                          sensor);
            return;
        }

        printSensor(sid, MAP_NUM_TO_NAME);
        return;
    }

    /* didn't get a clean parse. try to treat as a name */
    sid = sksiteSensorLookup(sensor);
    if (sid != SK_INVALID_SENSOR) {
        printSensor(sid, MAP_NAME_TO_NUM);
        return;
    }

    /* try a case-insensitive search, manually iterating over all
     * the sensors */
    count = 0;
    sksiteSensorIterator(&si);
    while (sksiteSensorIteratorNext(&si, &sid)) {
        sksiteSensorGetName(sensor_name, sizeof(sensor_name), sid);
        if (0 == strcasecmp(sensor_name, sensor)) {
            printSensor(sid, MAP_NAME_TO_NUM);
            ++count;
        }
    }
    if (count == 0) {
        skAppPrintErr("Name '%s' is not a valid sensor name", sensor);
    }
}
Beispiel #4
0
/*
 *  status = optionsHandler(opt_arg, &index);
 *
 *    Handles options for the plugin.  'opt_arg' is the argument, or
 *    NULL if no argument was given.  'index' is the enum passed in
 *    when the option was registered.
 *
 *    Returns SKPLUGIN_OK on success, or SKPLUGIN_ERR if there was a
 *    problem.
 */
static skplugin_err_t
optionsHandler(
    const char         *opt_arg,
    void               *cbdata)
{
    skplugin_callbacks_t regdata;
    unsigned int opt_index = *((unsigned int*)cbdata);
    uint32_t opt_val;
    int rv;

    rv = skStringParseUint32(&opt_val, opt_arg, ADDRTYPE_NONROUTABLE,
                             ADDRTYPE_NONINTERNAL);
    if (rv != 0) {
        skAppPrintErr("Invalid %s '%s': %s",
                      plugin_options[opt_index].name, opt_arg,
                      skStringParseStrerror(rv));
        return SKPLUGIN_ERR;
    }

    switch (opt_index) {
      case ADDRTYPE_STYPE:
        if (stype != ADDRTYPE_UNSET) {
            skAppPrintErr("Invalid %s: Switch used multiple times",
                          plugin_options[opt_index].name);
            return SKPLUGIN_ERR;
        }
        stype = (addrtype_t)opt_val;
        break;

      case ADDRTYPE_DTYPE:
        if (dtype != ADDRTYPE_UNSET) {
            skAppPrintErr("Invalid %s: Switch used multiple times",
                          plugin_options[opt_index].name);
            return SKPLUGIN_ERR;
        }
        dtype = (addrtype_t)opt_val;
        break;

      default:
        return SKPLUGIN_ERR_FATAL;
    }

    memset(&regdata, 0, sizeof(regdata));
    regdata.init = addrtypeInit;
    regdata.cleanup = addrtypeCleanup;
    regdata.filter = addrtypeFilter;
    return skpinRegFilter(NULL, &regdata, cbdata);
}
Beispiel #5
0
/*
 *  skplugin_err_t pmap_column_width_handler(const char *opt_arg,
 *      void *cbdata);
 *
 *    Handles the pmap column width command line option.
 */
static skplugin_err_t
pmap_column_width_handler(
    const char         *opt_arg,
    void        UNUSED(*cbdata))
{
    uint32_t tmp32;
    int rv;

    if (max_column_width > 0) {
        skAppPrintErr("Invalid %s: Switch used multiple times",
                      pmap_column_width_option);
        return SKPLUGIN_ERR;
    }
    rv = skStringParseUint32(&tmp32, opt_arg, 1, INT32_MAX);
    if (rv) {
        skAppPrintErr("Invalid %s '%s': %s",
                      pmap_column_width_option, opt_arg,
                      skStringParseStrerror(rv));
        return SKPLUGIN_ERR;
    }
    max_column_width = tmp32;

    return SKPLUGIN_OK;
}
Beispiel #6
0
/*
 *  status = appOptionsHandler(cData, opt_index, opt_arg);
 *
 *    This function is passed to skOptionsRegister(); it will be called
 *    by skOptionsParse() for each user-specified switch that the
 *    application has registered; it should handle the switch as
 *    required---typically by setting global variables---and return 1
 *    if the switch processing failed or 0 if it succeeded.  Returning
 *    a non-zero from from the handler causes skOptionsParse() to return
 *    a negative value.
 *
 *    The clientData in 'cData' is typically ignored; 'opt_index' is
 *    the index number that was specified as the last value for each
 *    struct option in appOptions[]; 'opt_arg' is the user's argument
 *    to the switch for options that have a REQUIRED_ARG or an
 *    OPTIONAL_ARG.
 */
static int
appOptionsHandler(
    clientData   UNUSED(cData),
    int                 opt_index,
    char               *opt_arg)
{
#if SK_ENABLE_IPV6
    uint32_t j;
#endif
    uint32_t n;
    uint32_t i;
    int rv;

    /* Store the address of the prefix to set in the switch(), then
     * set the referenced value below the switch() */
    switch ((appOptionsEnum)opt_index) {
      case OPT_4SIP_PREFIX_LENGTH:
      case OPT_4DIP_PREFIX_LENGTH:
      case OPT_4NHIP_PREFIX_LENGTH:
        /* Which mask to change */
        i = (opt_index - OPT_4SIP_PREFIX_LENGTH);
        /* Parse value */
        rv = skStringParseUint32(&n, opt_arg, 1, 32);
        if (rv) {
            goto PARSE_ERROR;
        }
        if (net_mask[i].bits4) {
            skAppPrintErr(("The %s value was given multiple times;\n"
                           "\tusing final value %lu"),
                          appOptions[opt_index].name, (unsigned long)n);
        }
        net_mask[i].bits4 = (uint8_t)n;
        net_mask[i].mask4 = ~((n == 32) ? 0 : (UINT32_MAX >> n));
        break;

#if SK_ENABLE_IPV6
      case OPT_6SIP_PREFIX_LENGTH:
      case OPT_6DIP_PREFIX_LENGTH:
      case OPT_6NHIP_PREFIX_LENGTH:
        /* Which mask to change */
        i = (opt_index - OPT_6SIP_PREFIX_LENGTH);
        /* Parse value */
        rv = skStringParseUint32(&n, opt_arg, 1, 128);
        if (rv) {
            goto PARSE_ERROR;
        }
        if (net_mask[i].bits6) {
            skAppPrintErr(("The %s value was given multiple times;\n"
                           "\tusing final value %lu"),
                          appOptions[opt_index].name, (unsigned long)n);
        }
        net_mask[i].bits6 = (uint8_t)n;
        /* byte in the uint8_t[16] where the change occurs */
        j = n >> 3;
        memset(&net_mask[i].mask6[0], 0xFF, j);
        if (n < 128) {
            net_mask[i].mask6[j] = ~(0xFF >> (n & 0x07));
            memset(&net_mask[i].mask6[j+1], 0, (15 - j));
        }
        break;
#endif  /* SK_ENABLE_IPV6 */

      case OPT_OUTPUT_PATH:
        if (output_path) {
            skAppPrintErr("Invalid %s: Switch used multiple times",
                          appOptions[opt_index].name);
            return 1;
        }
        output_path = opt_arg;
        break;
    }
Beispiel #7
0
/*
 *  status = legacyOptionsHandler(cData, opt_index, opt_arg);
 *
 *    Process the legacy versions of the switches by calling the real
 *    appOptionsHandler().
 */
static int
legacyOptionsHandler(
    clientData          cData,
    int                 opt_index,
    char               *opt_arg)
{
#define KEY_COMBO_ERR(a, b)                                             \

    static int old_id = -1;
    rwstats_legacy_t *leg = (rwstats_legacy_t*)cData;
    const char *val_type = NULL;
    uint32_t val;
    int rv;

    switch ((legacyOptionsEnum)opt_index) {
      case LEGOPT_SIP:
        if (opt_arg) {
            rv = skStringParseUint32(&val, opt_arg, 1, 31);
            if (rv) {
                goto PARSE_ERROR;
            }
            cidr_sip = ~0 << (32 - val);
        }
        break;

      case LEGOPT_DIP:
        if (opt_arg) {
            rv = skStringParseUint32(&val, opt_arg, 1, 31);
            if (rv) {
                goto PARSE_ERROR;
            }
            cidr_dip = ~0 << (32 - val);
        }
        break;

      case LEGOPT_SPORT:
      case LEGOPT_DPORT:
      case LEGOPT_PROTOCOL:
      case LEGOPT_ICMP:
        break;

      case LEGOPT_FLOWS:
        val_type = "Records";
        break;

      case LEGOPT_PACKETS:
      case LEGOPT_BYTES:
        val_type = legacyOptions[opt_index].name;
        break;
    }

    if (opt_index <= LEGOPT_ICMP) {
        if (NULL == leg->fields) {
            old_id = opt_index;
            leg->fields = legacyOptions[opt_index].name;
        } else if (((1 << LEGOPT_SIP) | (1 << LEGOPT_DIP))
                   == ((1 << old_id) | (1 << opt_index)))
        {
            leg->fields = "sip,dip";
        } else if (((1 << LEGOPT_SPORT) | (1 << LEGOPT_DPORT))
                   == ((1 << old_id) | (1 << opt_index)))
        {
            leg->fields = "sport,dport";
        } else {
            skAppPrintErr(("Key combination --%s and --%s is not supported.\n"
                           "\tUse the --fields switch for this combination"),
                          legacyOptions[opt_index].name,
                          legacyOptions[old_id].name);
            return 1;
        }
    } else {
        assert(val_type != NULL);
        if (leg->values) {
            skAppPrintErr(("May only specify one of --%s, --%s or --%s.\n"
                           "Use the --values switch for multiple values"),
                          legacyOptions[LEGOPT_FLOWS].name,
                          legacyOptions[LEGOPT_PACKETS].name,
                          legacyOptions[LEGOPT_BYTES].name);
            return 1;
        }
        leg->values = val_type;
    }

    return 0;                   /* OK */

  PARSE_ERROR:
    skAppPrintErr("Invalid %s '%s': %s",
                  legacyOptions[opt_index].name, opt_arg,
                  skStringParseStrerror(rv));
    return 1;
}
Beispiel #8
0
/*
 *  int pmapFilterSetupBitmap(uint32_t **bitmap, uint32_t **bitmap_size,
 *                            skPrefixMap_t *prefix_map,
 *                            char *opt_arg, char *pmap_path);
 *
 *    Parses 'opt_arg', a string representation of comma-separated
 *    pmap values to filter on with respect to the given 'prefix_map',
 *    and sets the relevant bits in the bit-vector 'bitmap', whose
 *    current size is 'bitmap_size'.  Creates the bitmap if necessary
 *    and may adjust the bitmap's size.  Returns -1 if the argument
 *    was not parsable or if there is a memory allocation error.
 */
static int
pmapFilterSetupBitmap(
    uint32_t              **bitmap_arg,
    uint32_t               *bitmap_size,
    const skPrefixMap_t    *prefix_map,
    const char             *opt_arg,
    const char             *pmap_path)
{
    uint32_t bmap_len;
    char *arg_copy = NULL;
    char *label;
    char *next_token;
    uint32_t code;
    uint32_t *bitmap = NULL;
    int rv = -1;

    if (ignore_prefix_map) {
        return 0;
    }

    assert(bitmap_arg);
    assert(prefix_map);
    assert(opt_arg);

    /* Get a pointer to the bitmap---creating it if required */
    if (*bitmap_arg) {
        bitmap = *bitmap_arg;
    } else {
        /* Allocate the bitmap. */
        bmap_len = skPrefixMapDictionaryGetWordCount(prefix_map);

        bitmap = (uint32_t*)calloc(PMAP_BMAP_SIZE(bmap_len), sizeof(uint32_t));
        if (NULL == bitmap) {
            ERR_NO_MEM(bitmap);
            goto END;
        }
        *bitmap_size = bmap_len;
    }

    /* Make a modifiable copy of the user's argument */
    arg_copy = strdup(opt_arg);
    if (arg_copy == NULL) {
        ERR_NO_MEM(arg_copy);
        goto END;
    }

    /* Find each token which should be a label in the pmap */
    next_token = arg_copy;
    while ((label = strsep(&next_token, ",")) != NULL) {
        code = skPrefixMapDictionaryLookup(prefix_map, label);
        if (SKPREFIXMAP_NOT_FOUND == code) {
            /* label was not found in dictionary.  if label is a
             * number and if any key in the prefix map has that number
             * as its value, set that position in the bitmap,
             * reallocating the bitmap if necessary */
            if (skStringParseUint32(&code, label, 0, SKPREFIXMAP_MAX_VALUE)) {
                skAppPrintErr(("The label '%s' was not found in prefix map\n"
                               "\tdictionary loaded from '%s'"),
                              label, pmap_path);
                goto END;
            }

            if (0 == pmapCheckValueIsValid(prefix_map, code)) {
                skAppPrintErr(("The value '%s' was not found in prefix map\n"
                               "\tdictionary loaded from '%s'"),
                              label, pmap_path);
                goto END;
            }

            /* ensure bitmap can set the bit 'code' */
            bmap_len = code + 1;

            /* see if we need to grow the bitmap */
            if (PMAP_BMAP_SIZE(bmap_len) > PMAP_BMAP_SIZE(*bitmap_size)) {
                uint32_t *old = bitmap;
                bitmap = (uint32_t*)realloc(bitmap, (PMAP_BMAP_SIZE(bmap_len)
                                                     * sizeof(uint32_t)));
                if (NULL == bitmap) {
                    bitmap = old;
                    ERR_NO_MEM(bitmap);
                    goto END;
                }
                memset(&bitmap[PMAP_BMAP_SIZE(*bitmap_size)], 0,
                       ((PMAP_BMAP_SIZE(bmap_len)-PMAP_BMAP_SIZE(*bitmap_size))
                        * sizeof(uint32_t)));
            }
            /* alway set bitmap size to maximum number */
            if (bmap_len > *bitmap_size) {
                *bitmap_size = bmap_len;
            }
        }
        PMAP_BMAP_SET(bitmap, code);
    }

    /* Success */
    rv = 0;
    *bitmap_arg = bitmap;

  END:
    if (*bitmap_arg == NULL && bitmap != NULL) {
        free(bitmap);
    }
    if (arg_copy) {
        free(arg_copy);
    }
    return rv;
}