/* * Copyright (c) 2004-2006 Endace Technology Ltd, Hamilton, New Zealand. * All rights reserved. * * This source code is proprietary to Endace Technology Limited and no part * of it may be redistributed, published or disclosed except as outlined in * the written contract supplied with this product. * * $Id: dagflood_cli.c 4037 2006-04-03 05:03:37Z koryn $ */ /* dagflood headers. */ #include "dagflood_config.h" #include "dagflood_model.h" #include "dagflood_view.h" /* Endace headers. */ #include "dagapi.h" #include "dagnew.h" #include "dagutil.h" #include "dagclarg.h" /* CVS Header. */ static const char* const kCvsHeader __attribute__ ((unused)) = "$Id: dagflood_cli.c 4037 2006-04-03 05:03:37Z koryn $"; static const char* const kRevisionString = "$Revision: 4037 $"; /* Macros and constants */ #define RUN_TIMELIMIT 0 /* Do a time based uContinue */ #define RUN_REPEAT 1 /* Do a repeat uCounters uContinue */ #define BURST_MAX ONE_MEBI #define EIGHT_MEBI 8*ONE_MEBI #define BUFSIZE 256 #define DEFAULT_DEVICE "dag0" /* Commandline argument codes. */ enum { CLA_FNAME, CLA_BMAX, CLA_DEVICE, CLA_HELP, CLA_TERMN, CLA_VERBOSE, CLA_VERSION, CLA_DELAY, CLA_MODE, CLA_NO_FLUSH, CLA_COUNT }; /* Internal routines. */ static void print_version(void); static void print_usage(ClArgPtr clarg); static void sighandler(int signal); static void report_statistics(DagfloodPtr flooder); /* Implementation of internal routines. */ static void print_usage(ClArgPtr clarg) { print_version(); printf("dagflood - Endace DAG card transmit utility.\n"); printf("Usage: dagflood [options]\n"); dagclarg_display_usage(clarg, stdout); } static void print_version(void) { printf("dagflood (DAG %s) %s\n", kDagReleaseVersion, kRevisionString); } /* Signal processing */ void sighandler (int signal) { static int set_run = 0; if (1 == set_run) { /* Already been signalled to stop - assume that we're stuck in the final dag_tx_get_stream_space(). */ exit(EXIT_FAILURE); } set_run = 1; } void report_statistics(DagfloodPtr flooder) { #if 0 double total_time; total_time = (uCounters.end.tv_sec - uCounters.start.tv_sec) + (((uCounters.end.tv_usec) - uCounters.start.tv_usec) % 1000000) / 1000000.0; printf ("-------------------------------------------------\n"); #if defined(__FreeBSD__) || defined(__linux__) || (defined(__SVR4) && defined(__sun)) || (defined(__APPLE__) && defined(__ppc__)) printf ("total bytes sent to dag card: %lld (%.2f MiB)\n", (long long int) uCounters.wbytes, ((double) uCounters.wbytes) / ONE_MEBI); #elif defined(_WIN32) printf ("total bytes sent to dag card: %10I64u (%.2f MiB)\n", uCounters.wbytes, ((double) uCounters.wbytes) / ONE_MEBI); #else #error Compiling on an unsupported platform - please contact for assistance. #endif /* Platform-specific code. */ printf ("approx. average speed: %4.2f Mbps (%4.2f MiB/s)\n", (uCounters.wbytes * 8 / total_time) / 1000000, (uCounters.wbytes / total_time) / 1000000); #endif /* 0 */ printf("FIXME\n"); } int dagflood_main(int argc, char **argv) { DagfloodPtr flooder = NULL; DagfloodConfigPtr config = NULL; FILE* errorfile = NULL; ClArgPtr clarg = NULL; int argindex; int code; int result; unsigned int run_mode; int dagstream; uint32_t burst_microseconds; uint32_t flush_tx_buffer; char dagname_buf[DAGNAME_BUFSIZE] = DEFAULT_DEVICE; char dagname[DAGNAME_BUFSIZE]; char infile_buffer[BUFSIZE]; uint32_t count; uint32_t runtime_seconds; uint32_t data_bytes; dagutil_set_progname("dagflood"); /* Set up default DAG device. */ if (-1 == dag_parse_name(dagname_buf, dagname, DAGNAME_BUFSIZE, &dagstream)) { dagutil_panic("dag_parse_name(%s): %s\n", dagname_buf, strerror(errno)); } /* Set up the command line options. */ clarg = dagclarg_init(argc, (const char* const *) argv); dagclarg_add_string(clarg, "file containing ERF records to send", "--fname", 'f', "filename", infile_buffer, BUFSIZE, CLA_FNAME); dagclarg_add_uint(clarg, "transmit file times before exiting", "--count", 'c', "count", &count, CLA_COUNT); dagclarg_add(clarg, "display help (this page)", "--help", 'h', CLA_HELP); dagclarg_add_long_option(clarg, CLA_HELP, "--usage"); dagclarg_add_short_option(clarg, CLA_HELP, '?'); dagclarg_add(clarg, "display version information", "--version", 'V', CLA_VERSION); dagclarg_add(clarg, "increase verbosity", "--verbose", 'v', CLA_VERBOSE); dagclarg_add_string(clarg, "DAG device to use. Default: dag0.", "--device", 'd', "device", dagname_buf, DAGNAME_BUFSIZE, CLA_DEVICE); dagclarg_add_uint(clarg, "set program to terminate after seconds. Default: 0 (continue indefinitely).", "--terminate", 't', "seconds", &runtime_seconds, CLA_TERMN); dagclarg_add_uint(clarg, "set burst_max (maximum data burst length). Default: 1 MiB.", "--burst-max", 'l', "bytes", &data_bytes, CLA_BMAX); dagclarg_add_uint(clarg, "inter burst delay (microseconds)","--delay", 'u', "microseconds", &burst_microseconds, CLA_DELAY); dagclarg_add(clarg, "do not flush transmit buffer when a signal is caught", "--no-flush", 'x', CLA_NO_FLUSH); dagclarg_add_uint(clarg, "API mode. 1 = commit bytes, 2 = copy bytes.","--mode", 'r', "api-mode", &run_mode, CLA_MODE); /* Parse the command line options. */ result = dagclarg_parse(clarg, errorfile, &argindex, &code); while (1 == result) { switch (code) { case CLA_DEVICE: if (-1 == dag_parse_name(dagname_buf, dagname, DAGNAME_BUFSIZE, &dagstream)) { dagutil_panic("dag_parse_name(%s): %s\n", dagname_buf, strerror(errno)); } dagutil_verbose_level(2, "device=%s\n", dagname); break; case CLA_FNAME: /* Do nothing. */ break; case CLA_COUNT: run_mode = RUN_REPEAT; break; case CLA_TERMN: run_mode = RUN_TIMELIMIT; break; case CLA_BMAX: /* Do nothing. */ break; case CLA_HELP: print_usage(clarg); return EXIT_SUCCESS; break; case CLA_VERBOSE: dagutil_inc_verbosity(); errorfile = stderr; break; case CLA_VERSION: print_version(); return EXIT_SUCCESS; break; case CLA_MODE: break; case CLA_DELAY: break; case CLA_NO_FLUSH: flush_tx_buffer = 0; break; default: /* Unknown option. */ dagutil_error("unknown option %s\n", argv[argindex]); print_usage(clarg); return EXIT_FAILURE; } result = dagclarg_parse(clarg, errorfile, &argindex, &code); } if (-1 == result) { if (argindex < argc) { dagutil_error("while processing option %s\n", argv[argindex]); } dagclarg_display_usage(clarg, stderr); return EXIT_FAILURE; } /* Check for data file */ if (0 == strlen(infile_buffer)) { print_usage(clarg); dagutil_panic("error: must specify one transmit file\n"); } /* Catch signals */ dagutil_set_signal_handler(sighandler); /* ClargPtr should no longer be necessary. */ dagclarg_dispose(clarg); /* Create a configuration to pass to the main capture loop. */ config = dagflood_config_init(); /* Set up the configuration options. */ dagflood_config_set_device(config, dagname); dagflood_config_set_infile_name(config, (const char*) infile_buffer); dagflood_config_set_dagstream(config, dagstream); dagflood_config_set_run_seconds(config, runtime_seconds); dagflood_config_set_verbosity(config, dagutil_get_verbosity()); flooder = dagflood_create(config); if (NULL == flooder) { return EXIT_FAILURE; } if (dagutil_get_verbosity()) { dagflood_view_init(flooder, dagname, dagutil_get_verbosity()); } result = dagflood_transmit(flooder); /* Report some statistics */ report_statistics(flooder); return result; } #ifndef ENDACE_UNIT_TEST int main(int argc, const char* const * argv) { return dagflood_main(argc, (char**) argv); } #endif /* ENDACE_UNIT_TEST */ .