/* * 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; }
/* * 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; }
/* * 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); } }
/* * 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(®data, 0, sizeof(regdata)); regdata.init = addrtypeInit; regdata.cleanup = addrtypeCleanup; regdata.filter = addrtypeFilter; return skpinRegFilter(NULL, ®data, cbdata); }
/* * 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; }
/* * 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; }
/* * 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; }
/* * 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; }