/* * Prefix any log messages from libflowsource with the program name * instead of the standard logging tag. */ static size_t logprefix( char *buffer, size_t bufsize) { return (size_t)snprintf(buffer, bufsize, "%s: ", skAppName()); }
int main(int argc, char **argv) { char *path; int64_t total_count; int64_t count; int rv; appSetup(argc, argv); /* never returns on failure */ total_count = 0; /* process each file on the command line */ while ((rv = skOptionsCtxNextArgument(optctx, &path)) == 0) { count = pdu2silk(path); if (count < 0) { exit(EXIT_FAILURE); } total_count += count; } if (rv < 0) { exit(EXIT_FAILURE); } if (print_statistics) { fprintf(STATS_FH, ("%s: Wrote %" PRIu64 " records to '%s'\n"), skAppName(), total_count, skStreamGetPathname(silk_output)); } return 0; }
/* * appUsageLong(); * * Print complete usage information to USAGE_FH. Pass this * function to skOptionsSetUsageCallback(); skOptionsParse() will * call this funciton and then exit the program when the --help * option is given. */ static void appUsageLong( void) { FILE *fh = USAGE_FH; unsigned int i; #define USAGE_MSG \ ("--keys=KEYS --counters=COUNTERS [SWITCHES] [FILES]\n" \ "\tRead SiLK Flow records, bin the records by the fields in KEYS,\n" \ "\tcompute the COUNTERS field(s) for each KEYS, and write the binary\n" \ "\tAggregate Bag output to the standard output or the --output-path.\n" \ "\tRead SiLK Flows from the named files or from the standard input.\n") /* Create the string maps for --keys and --counters */ createStringmaps(); fprintf(fh, "%s %s", skAppName(), USAGE_MSG); fprintf(fh, "\nSWITCHES:\n"); skOptionsDefaultUsage(fh); for (i = 0; appOptions[i].name; ++i) { fprintf(fh, "--%s %s. ", appOptions[i].name, SK_OPTION_HAS_ARG(appOptions[i])); switch ((appOptionsEnum)appOptions[i].val) { case OPT_KEYS: /* Dynamically build the help */ fprintf(fh, "%s\n", appHelp[i]); skStringMapPrintUsage(key_name_map, fh, 4); break; case OPT_COUNTERS: fprintf(fh, "%s\n", appHelp[i]); skStringMapPrintUsage(counter_name_map, fh, 4); break; case OPT_OUTPUT_PATH: /* include the help for --notes and --invocation-strip * after --output-path */ fprintf(fh, "%s\n", appHelp[i]); skAggBagOptionsUsage(fh); break; default: /* Simple help text from the appHelp array */ fprintf(fh, "%s\n", appHelp[i]); break; } } skOptionsCtxOptionsUsage(optctx, fh); skIPv6PolicyUsage(fh); sksiteOptionsUsage(fh); /* skPluginOptionsUsage(fh); */ }
/* * appUsageLong(); * * Print complete usage information to USAGE_FH. Pass this * function to skOptionsSetUsageCallback(); skOptionsParse() will * call this funciton and then exit the program when the --help * option is given. */ static void appUsageLong( void) { #define USAGE_MSG \ ("<PREFIX_SWITCH> [<PREFIX_SWITCH>...] [SWITCHES] [FILES]\n" \ "\tRead SiLK Flow records from FILES named on the command line or\n" \ "\tfrom the standard input, keep the specified number of most\n" \ "\tsignificant bits for each IP address, and write the modified\n" \ "\trecords to the specified output file or to the standard output.\n") FILE *fh = USAGE_FH; int i, j; fprintf(fh, "%s %s", skAppName(), USAGE_MSG); fprintf(fh, "\nPREFIX SWITCHES:\n"); /* print everything before --output-path */ for (i=0; appOptions[i].name && appOptions[i].val < OPT_OUTPUT_PATH; ++i) { fprintf(fh, "--%s %s. %s\n", appOptions[i].name, SK_OPTION_HAS_ARG(appOptions[i]), appHelp[i]); } /* print the first three switches again as aliases---use a * different variable!! */ for (j = 0; appOptions[j].name && appOptions[j].val <= OPT_4NHIP_PREFIX_LENGTH; ++j) { fprintf(fh, "--%s %s. Alias for --%s\n", appOptions[j].name + 1, SK_OPTION_HAS_ARG(appOptions[j]), appOptions[j].name); } /* print remaining options */ fprintf(fh, "\nSWITCHES:\n"); skOptionsDefaultUsage(fh); for ( ; appOptions[i].name; ++i) { fprintf(fh, "--%s %s. %s\n", appOptions[i].name, SK_OPTION_HAS_ARG(appOptions[i]), appHelp[i]); } skOptionsCtxOptionsUsage(optctx, fh); skIPv6PolicyUsage(fh); skCompMethodOptionsUsage(fh); skOptionsNotesUsage(fh); sksiteOptionsUsage(fh); }
/* * appUsageLong(); * * Print complete usage information to USAGE_FH. Pass this * function to skOptionsSetUsageCallback(); skOptionsParse() will * call this funciton and then exit the program when the --help * option is given. */ static void appUsageLong( void) { #define USAGE_MSG \ ("[SWITCHES] [FILES]\n" \ "\tSummarize SiLK Flow records across time, producing textual output\n" \ "\twith counts of bytes, packets, and flow records for each time bin.\n" \ "\tWhen no files given on command line, flows are read from STDIN.\n") FILE *fh = USAGE_FH; int i; fprintf(fh, "%s %s", skAppName(), USAGE_MSG); fprintf(fh, "\nSWITCHES:\n"); skOptionsDefaultUsage(fh); for (i = 0; appOptions[i].name; ++i) { fprintf(fh, "--%s %s. ", appOptions[i].name, SK_OPTION_HAS_ARG(appOptions[i])); switch (appOptions[i].val) { case OPT_LOAD_SCHEME: loadschemeUsage(fh); break; case OPT_TIMESTAMP_FORMAT: timestampFormatUsage(fh); break; default: fprintf(fh, "%s\n", appHelp[i]); break; } } for (i = 0; deprecatedOptions[i].name; ++i) { fprintf(fh, "--%s %s. %s\n", deprecatedOptions[i].name, SK_OPTION_HAS_ARG(deprecatedOptions[i]), deprecatedHelp[i]); } skOptionsCtxOptionsUsage(optctx, fh); sksiteOptionsUsage(fh); }
/* * appUsageLong(); * * Print complete usage information to USAGE_FH. Pass this * function to skOptionsSetUsageCallback(); skOptionsParse() will * call this funciton and then exit the program when the --help * option is given. */ static void appUsageLong( void) { #define USAGE_MSG \ ("<SWITCHES>\n" \ "\tA utility to simply print to stdout the list of files\n" \ "\tthat rwfilter would normally process for a given set of\n" \ "\tfile selection switches.\n") FILE *fh = USAGE_FH; int i; fprintf(fh, "%s %s", skAppName(), USAGE_MSG); fprintf(fh, "\nAPPLICATION SWITCHES\n"); skOptionsDefaultUsage(fh); for (i = 0; appOptions[i].name; ++i) { fprintf(fh, "--%s %s. %s\n", appOptions[i].name, SK_OPTION_HAS_ARG(appOptions[i]), appHelp[i]); } fglobUsage(fh); }
/* * appSetup(argc, argv); * * Perform all the setup for this application include setting up * required modules, parsing options, etc. This function should be * passed the same arguments that were passed into main(). * * Returns to the caller if all setup succeeds. If anything fails, * this function will cause the application to exit with a FAILURE * exit status. */ static void appSetup( int argc, char **argv) { SILK_FEATURES_DEFINE_STRUCT(features); unsigned int optctx_flags; sk_file_header_t *silk_hdr; int logmask; int rv; /* verify same number of options and help strings */ assert((sizeof(appHelp)/sizeof(char *)) == (sizeof(appOptions)/sizeof(struct option))); /* register the application */ skAppRegister(argv[0]); skAppVerifyFeatures(&features, NULL); skOptionsSetUsageCallback(&appUsageLong); optctx_flags = (SK_OPTIONS_CTX_INPUT_BINARY | SK_OPTIONS_CTX_XARGS); /* register the options */ if (skOptionsCtxCreate(&optctx, optctx_flags) || skOptionsCtxOptionsRegister(optctx) || skOptionsRegister(appOptions, &appOptionsHandler, NULL) || skOptionsNotesRegister(NULL) || skCompMethodOptionsRegister(&comp_method)) { skAppPrintErr("Unable to register options"); exit(EXIT_FAILURE); } /* enable the logger */ sklogSetup(0); sklogSetDestination("stderr"); sklogSetStampFunction(&logprefix); /* register the teardown handler */ if (atexit(appTeardown) < 0) { skAppPrintErr("Unable to register appTeardown() with atexit()"); appTeardown(); exit(EXIT_FAILURE); } /* parse the options */ rv = skOptionsCtxOptionsParse(optctx, argc, argv); if (rv < 0) { skAppUsage(); /* never returns */ } if ('\0' == log_destination[0]) { strncpy(log_destination, LOG_DESTINATION_DEFAULT, sizeof(log_destination)); } else { sklogSetLevel("debug"); } sklogSetDestination(log_destination); /* default output is "stdout" */ if (!silk_output) { if ((rv =skStreamCreate(&silk_output,SK_IO_WRITE,SK_CONTENT_SILK_FLOW)) || (rv = skStreamBind(silk_output, "-"))) { skStreamPrintLastErr(silk_output, rv, &skAppPrintErr); exit(EXIT_FAILURE); } } /* get the header */ silk_hdr = skStreamGetSilkHeader(silk_output); /* open the output */ if ((rv = skHeaderSetCompressionMethod(silk_hdr, comp_method)) || (rv = skOptionsNotesAddToStream(silk_output)) || (rv = skHeaderAddInvocation(silk_hdr, 1, argc, argv)) || (rv = skStreamOpen(silk_output)) || (rv = skStreamWriteSilkHeader(silk_output))) { skStreamPrintLastErr(silk_output, rv, &skAppPrintErr); exit(EXIT_FAILURE); } if (skpcSetup()) { exit(EXIT_FAILURE); } if (skpcProbeCreate(&probe, PROBE_ENUM_NETFLOW_V5)) { exit(EXIT_FAILURE); } skpcProbeSetName(probe, skAppName()); skpcProbeSetFileSource(probe, "/dev/null"); if (parseLogFlags(log_flags)) { exit(EXIT_FAILURE); } if (skpcProbeVerify(probe, 0)) { exit(EXIT_FAILURE); } /* set level to "warning" to avoid the "Started logging" message */ logmask = sklogGetMask(); sklogSetLevel("warning"); sklogOpen(); sklogSetMask(logmask); return; /* OK */ }