From: Laurent MAZET Date: Mon, 29 Sep 2025 15:37:00 +0000 (+0200) Subject: add udp test X-Git-Tag: v1.0~83 X-Git-Url: https://secure.softndesign.org/git/?a=commitdiff_plain;h=324680c67e18b708e83fca608220182b664813fb;p=benchmarks.git add udp test --- diff --git a/todo/udptest/Makefile b/todo/udptest/Makefile deleted file mode 100644 index 8075711..0000000 --- a/todo/udptest/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -CC?=gcc -COMMON=com.c timer.c clock.c ftrace.c cmdline.c - -all: udptest udptestserver - -udptest: udptest.c common.h $(COMMON) - $(CC) -o udptest udptest.c $(COMMON) - -udptestserver: udptestserver.c common.h $(COMMON) - $(CC) -o udptestserver udptestserver.c $(COMMON) - -clean: - rm -rf udptest udptestserver *~ *.o - diff --git a/todo/udptest/README b/todo/udptest/README deleted file mode 100644 index 23dcdc6..0000000 --- a/todo/udptest/README +++ /dev/null @@ -1,28 +0,0 @@ -# UDP test program -# ----------------------------------------------------------------------------- -# Developped to test UDP latencies in RT environment and debug sporadic high -# latencies using ftrace. -# -# /!\ Note that enabling ftrace increase measured latencies depending on how -# many tracepoint are logged. So for low impact, make sure to configure -# some function filtering before. -# -# This project is composed of two programs : -# * One test program performing UDP packet sending and receiving -# * One remote program which only respond as fast as possible the same -# packet (like a echo server) -# -# The test program is able to : -# * Compute statistics on packet round trip time (min,max,avg) -# * Drop first iteration to wait for a right ARP table and routing -# * Network configuration is configurable -# * Message size and number are configurable -# * Each iteration can be periodic with a configurable period (using timerfd) -# or as fast as possible (period=0) -# * If a configurable maximum is detected, ftrace can be used to capture this -# latency context (trace is reset at each iteration). Requires root rights -# * Remote server can wait some time before sending back the response (using -# clock_nanosleep) -# * Remote server count input packet and wait to receive all packet before -# sending them back so packet drop will be detected. -# diff --git a/todo/udptest/clock.c b/todo/udptest/clock.c deleted file mode 100644 index 15a9974..0000000 --- a/todo/udptest/clock.c +++ /dev/null @@ -1,129 +0,0 @@ -#include -#include -#include "common.h" - - -#ifdef __vxworks -#include -#include -#else -#include -#endif - -#ifdef __vxworks -void clock_current(uint64_t* now) -{ - *now = sysTimestamp(); -} -#else -void clock_current(clock_s* now) -{ - clock_gettime(CLOCK_MONOTONIC_RAW, now); -} -#endif - -#ifdef __vxworks -int clock_diff_us(uint64_t t1, uint64_t t2) -{ - uint64_t diff = t2 - t1; - uint64_t freq = sysTimestampFreq(); - if (freq == 0) return -1; - return (int)((diff * 1000000ULL) / freq); -} -#else -int clock_diff_us(clock_s c1, clock_s c2) -{ - int diff_us = (c2.tv_sec - c1.tv_sec) * 1000000; - diff_us += (c2.tv_nsec - c1.tv_nsec) / 1000; - return diff_us; -} -#endif - -void clock_latency_init(struct latency_s* latency) -{ - latency->iter_number = 0; - latency->cumul_us = 0; - latency->max_us = 0; - latency->min_us = -1; -} - -#ifdef __vxworks -void clock_latency_update(uint64_t t1, uint64_t t2, struct latency_s* latency, const char* name, int verbose) -{ - int diff = clock_diff_us(t1, t2); - - latency->iter_number++; - latency->cumul_us += diff; - - if (diff > latency->max_us) { - latency->max_us = diff; - if (verbose) { - printf("New max latency for %s: %d us at tick=%llu\n", name, diff, (unsigned long long)t2); - } - } - if (diff < latency->min_us || latency->min_us == -1) { - latency->min_us = diff; - } -} -#else -void clock_latency_update(clock_s t1, clock_s t2, struct latency_s* latency, const char* name, int verbose) -{ - int diff = clock_diff_us(t1, t2); - - latency->iter_number++; - latency->cumul_us += diff; - - if (diff > latency->max_us) { - latency->max_us = diff; - if (verbose) { - printf("New max latency for %s: %d us at %ld.%09ld\n", name, diff, t2.tv_sec, t2.tv_nsec); - } - } - if (diff < latency->min_us || latency->min_us == -1) { - latency->min_us = diff; - } -} -#endif - -void clock_latency_reset_avg(struct latency_s* latency) -{ - latency->iter_number = 0; - latency->cumul_us = 0; -} - -#ifdef __vxworks -void clock_latency_print(struct latency_s* latency, const char* name) -{ - uint64_t now; - double avg; - - clock_current(&now); - - printf("[%s] tick=%llu : min=%d us, max=%d us, ", - name, (unsigned long long)now, latency->min_us, latency->max_us); - - if (latency->iter_number > 0) { - avg = (double)latency->cumul_us / latency->iter_number; - printf("avg: %.2f us\n", avg); - } else { - printf("[no new values]\n"); - } -} -#else -void clock_latency_print(struct latency_s* latency, const char* name) -{ - clock_s now; - double avg; - - clock_current(&now); - - if (latency->iter_number > 0) { - avg = (double)latency->cumul_us / latency->iter_number; - printf("[%s] %ld.%09ld : min=%d us, max=%d us, avg=%.2f us\n", - name, now.tv_sec, now.tv_nsec, latency->min_us, latency->max_us, avg); - } else { - printf("[%s] %ld.%09ld : min=%d us, max=%d us, [no new values]\n", - name, now.tv_sec, now.tv_nsec, latency->min_us, latency->max_us); - } -} -#endif diff --git a/todo/udptest/cmdline.c b/todo/udptest/cmdline.c deleted file mode 100644 index a6de143..0000000 --- a/todo/udptest/cmdline.c +++ /dev/null @@ -1,1288 +0,0 @@ -/* - File autogenerated by gengetopt version 2.22.6 - generated with the following command: - gengetopt --input=udptest.cmdline --include-getopt - - The developers of gengetopt consider the fixed text that goes in all - gengetopt output files to be in the public domain: - we make no copyright claims on it. -*/ - -/* If we use autoconf. */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include - -#ifndef FIX_UNUSED -#define FIX_UNUSED(X) (void) (X) /* avoid warnings for unused params */ -#endif - - -#include "cmdline.h" - -const char *gengetopt_args_info_purpose = "Compute latencies on UDP packets round trip."; - -const char *gengetopt_args_info_usage = "Usage: udptest [OPTIONS]..."; - -const char *gengetopt_args_info_versiontext = ""; - -const char *gengetopt_args_info_description = ""; - -const char *gengetopt_args_info_help[] = { - " -h, --help Print help and exit", - " -V, --version Print version and exit", - " -r, --remote-ip=STRING Remote IP Address (default=`127.0.0.1')", - " -p, --port=INT UDP Port Number (default=`15001')", - " -s, --packet-size=INT Packet size in byte (default=`10')", - " -n, --packet-number=INT Number of packet for each iteration (default=`100')", - " -i, --interval=INT Period time in microseconds. If 0, iteration are\n running as fast as possible (default=`0')", - " -m, --max-rtt=INT Maximum time of one period. If 0, the interval value\n is used and if interval is 0, this check is\n disabled. (default=`0')", - " -w, --wait=INT For server side only. This value define how much the\n server wait before sending back packets.\n (default=`0')", - " -v, --verbose Increase program verbosity (default=off)", - " -t, --ftrace Enable ftrace and reset trace on each iteration. Use\n with max-rtt option. Requires root rights.\n (default=off)", - 0 -}; - -typedef enum {ARG_NO - , ARG_FLAG - , ARG_STRING - , ARG_INT -} cmdline_parser_arg_type; - -static -void clear_given (struct gengetopt_args_info *args_info); -static -void clear_args (struct gengetopt_args_info *args_info); - -static int -cmdline_parser_internal (int argc, char **argv, struct gengetopt_args_info *args_info, - struct cmdline_parser_params *params, const char *additional_error); - - -static char * -gengetopt_strdup (const char *s); - -static -void clear_given (struct gengetopt_args_info *args_info) -{ - args_info->help_given = 0 ; - args_info->version_given = 0 ; - args_info->remote_ip_given = 0 ; - args_info->port_given = 0 ; - args_info->packet_size_given = 0 ; - args_info->packet_number_given = 0 ; - args_info->interval_given = 0 ; - args_info->max_rtt_given = 0 ; - args_info->wait_given = 0 ; - args_info->verbose_given = 0 ; - args_info->ftrace_given = 0 ; -} - -static -void clear_args (struct gengetopt_args_info *args_info) -{ - FIX_UNUSED (args_info); - args_info->remote_ip_arg = gengetopt_strdup ("127.0.0.1"); - args_info->remote_ip_orig = NULL; - args_info->port_arg = 15001; - args_info->port_orig = NULL; - args_info->packet_size_arg = 10; - args_info->packet_size_orig = NULL; - args_info->packet_number_arg = 100; - args_info->packet_number_orig = NULL; - args_info->interval_arg = 0; - args_info->interval_orig = NULL; - args_info->max_rtt_arg = 0; - args_info->max_rtt_orig = NULL; - args_info->wait_arg = 0; - args_info->wait_orig = NULL; - args_info->verbose_flag = 0; - args_info->ftrace_flag = 0; - -} - -static -void init_args_info(struct gengetopt_args_info *args_info) -{ - - - args_info->help_help = gengetopt_args_info_help[0] ; - args_info->version_help = gengetopt_args_info_help[1] ; - args_info->remote_ip_help = gengetopt_args_info_help[2] ; - args_info->port_help = gengetopt_args_info_help[3] ; - args_info->packet_size_help = gengetopt_args_info_help[4] ; - args_info->packet_number_help = gengetopt_args_info_help[5] ; - args_info->interval_help = gengetopt_args_info_help[6] ; - args_info->max_rtt_help = gengetopt_args_info_help[7] ; - args_info->wait_help = gengetopt_args_info_help[8] ; - args_info->verbose_help = gengetopt_args_info_help[9] ; - args_info->ftrace_help = gengetopt_args_info_help[10] ; - -} - -void -cmdline_parser_print_version (void) -{ - printf ("%s %s\n", - (strlen(CMDLINE_PARSER_PACKAGE_NAME) ? CMDLINE_PARSER_PACKAGE_NAME : CMDLINE_PARSER_PACKAGE), - CMDLINE_PARSER_VERSION); - - if (strlen(gengetopt_args_info_versiontext) > 0) - printf("\n%s\n", gengetopt_args_info_versiontext); -} - -static void print_help_common(void) { - cmdline_parser_print_version (); - - if (strlen(gengetopt_args_info_purpose) > 0) - printf("\n%s\n", gengetopt_args_info_purpose); - - if (strlen(gengetopt_args_info_usage) > 0) - printf("\n%s\n", gengetopt_args_info_usage); - - printf("\n"); - - if (strlen(gengetopt_args_info_description) > 0) - printf("%s\n\n", gengetopt_args_info_description); -} - -void -cmdline_parser_print_help (void) -{ - int i = 0; - print_help_common(); - while (gengetopt_args_info_help[i]) - printf("%s\n", gengetopt_args_info_help[i++]); -} - -void -cmdline_parser_init (struct gengetopt_args_info *args_info) -{ - clear_given (args_info); - clear_args (args_info); - init_args_info (args_info); -} - -void -cmdline_parser_params_init(struct cmdline_parser_params *params) -{ - if (params) - { - params->override = 0; - params->initialize = 1; - params->check_required = 1; - params->check_ambiguity = 0; - params->print_errors = 1; - } -} - -struct cmdline_parser_params * -cmdline_parser_params_create(void) -{ - struct cmdline_parser_params *params = - (struct cmdline_parser_params *)malloc(sizeof(struct cmdline_parser_params)); - cmdline_parser_params_init(params); - return params; -} - -static void -free_string_field (char **s) -{ - if (*s) - { - free (*s); - *s = 0; - } -} - - -static void -cmdline_parser_release (struct gengetopt_args_info *args_info) -{ - - free_string_field (&(args_info->remote_ip_arg)); - free_string_field (&(args_info->remote_ip_orig)); - free_string_field (&(args_info->port_orig)); - free_string_field (&(args_info->packet_size_orig)); - free_string_field (&(args_info->packet_number_orig)); - free_string_field (&(args_info->interval_orig)); - free_string_field (&(args_info->max_rtt_orig)); - free_string_field (&(args_info->wait_orig)); - - - - clear_given (args_info); -} - - -static void -write_into_file(FILE *outfile, const char *opt, const char *arg, const char *values[]) -{ - FIX_UNUSED (values); - if (arg) { - fprintf(outfile, "%s=\"%s\"\n", opt, arg); - } else { - fprintf(outfile, "%s\n", opt); - } -} - - -int -cmdline_parser_dump(FILE *outfile, struct gengetopt_args_info *args_info) -{ - int i = 0; - - if (!outfile) - { - fprintf (stderr, "%s: cannot dump options to stream\n", CMDLINE_PARSER_PACKAGE); - return EXIT_FAILURE; - } - - if (args_info->help_given) - write_into_file(outfile, "help", 0, 0 ); - if (args_info->version_given) - write_into_file(outfile, "version", 0, 0 ); - if (args_info->remote_ip_given) - write_into_file(outfile, "remote-ip", args_info->remote_ip_orig, 0); - if (args_info->port_given) - write_into_file(outfile, "port", args_info->port_orig, 0); - if (args_info->packet_size_given) - write_into_file(outfile, "packet-size", args_info->packet_size_orig, 0); - if (args_info->packet_number_given) - write_into_file(outfile, "packet-number", args_info->packet_number_orig, 0); - if (args_info->interval_given) - write_into_file(outfile, "interval", args_info->interval_orig, 0); - if (args_info->max_rtt_given) - write_into_file(outfile, "max-rtt", args_info->max_rtt_orig, 0); - if (args_info->wait_given) - write_into_file(outfile, "wait", args_info->wait_orig, 0); - if (args_info->verbose_given) - write_into_file(outfile, "verbose", 0, 0 ); - if (args_info->ftrace_given) - write_into_file(outfile, "ftrace", 0, 0 ); - - - i = EXIT_SUCCESS; - return i; -} - -int -cmdline_parser_file_save(const char *filename, struct gengetopt_args_info *args_info) -{ - FILE *outfile; - int i = 0; - - outfile = fopen(filename, "w"); - - if (!outfile) - { - fprintf (stderr, "%s: cannot open file for writing: %s\n", CMDLINE_PARSER_PACKAGE, filename); - return EXIT_FAILURE; - } - - i = cmdline_parser_dump(outfile, args_info); - fclose (outfile); - - return i; -} - -void -cmdline_parser_free (struct gengetopt_args_info *args_info) -{ - cmdline_parser_release (args_info); -} - -/** @brief replacement of strdup, which is not standard */ -char * -gengetopt_strdup (const char *s) -{ - char *result = 0; - if (!s) - return result; - - result = (char*)malloc(strlen(s) + 1); - if (result == (char*)0) - return (char*)0; - strcpy(result, s); - return result; -} - -int -cmdline_parser (int argc, char **argv, struct gengetopt_args_info *args_info) -{ - return cmdline_parser2 (argc, argv, args_info, 0, 1, 1); -} - -int -cmdline_parser_ext (int argc, char **argv, struct gengetopt_args_info *args_info, - struct cmdline_parser_params *params) -{ - int result; - result = cmdline_parser_internal (argc, argv, args_info, params, 0); - - if (result == EXIT_FAILURE) - { - cmdline_parser_free (args_info); - exit (EXIT_FAILURE); - } - - return result; -} - -int -cmdline_parser2 (int argc, char **argv, struct gengetopt_args_info *args_info, int override, int initialize, int check_required) -{ - int result; - struct cmdline_parser_params params; - - params.override = override; - params.initialize = initialize; - params.check_required = check_required; - params.check_ambiguity = 0; - params.print_errors = 1; - - result = cmdline_parser_internal (argc, argv, args_info, ¶ms, 0); - - if (result == EXIT_FAILURE) - { - cmdline_parser_free (args_info); - exit (EXIT_FAILURE); - } - - return result; -} - -int -cmdline_parser_required (struct gengetopt_args_info *args_info, const char *prog_name) -{ - FIX_UNUSED (args_info); - FIX_UNUSED (prog_name); - return EXIT_SUCCESS; -} - -/* - * Extracted from the glibc source tree, version 2.3.6 - * - * Licensed under the GPL as per the whole glibc source tree. - * - * This file was modified so that getopt_long can be called - * many times without risking previous memory to be spoiled. - * - * Modified by Andre Noll and Lorenzo Bettini for use in - * GNU gengetopt generated files. - * - */ - -/* - * we must include anything we need since this file is not thought to be - * inserted in a file already using getopt.h - * - * Lorenzo - */ - -struct option -{ - const char *name; - /* has_arg can't be an enum because some compilers complain about - type mismatches in all the code that assumes it is an int. */ - int has_arg; - int *flag; - int val; -}; - -/* This version of `getopt' appears to the caller like standard Unix `getopt' - but it behaves differently for the user, since it allows the user - to intersperse the options with the other arguments. - - As `getopt' works, it permutes the elements of ARGV so that, - when it is done, all the options precede everything else. Thus - all application programs are extended to handle flexible argument order. -*/ -/* - If the field `flag' is not NULL, it points to a variable that is set - to the value given in the field `val' when the option is found, but - left unchanged if the option is not found. - - To have a long-named option do something other than set an `int' to - a compiled-in constant, such as set a value from `custom_optarg', set the - option's `flag' field to zero and its `val' field to a nonzero - value (the equivalent single-letter option character, if there is - one). For long options that have a zero `flag' field, `getopt' - returns the contents of the `val' field. */ - -/* Names for the values of the `has_arg' field of `struct option'. */ -#ifndef no_argument -#define no_argument 0 -#endif - -#ifndef required_argument -#define required_argument 1 -#endif - -#ifndef optional_argument -#define optional_argument 2 -#endif - -struct custom_getopt_data { - /* - * These have exactly the same meaning as the corresponding global variables, - * except that they are used for the reentrant versions of getopt. - */ - int custom_optind; - int custom_opterr; - int custom_optopt; - char *custom_optarg; - - /* True if the internal members have been initialized. */ - int initialized; - - /* - * The next char to be scanned in the option-element in which the last option - * character we returned was found. This allows us to pick up the scan where - * we left off. If this is zero, or a null string, it means resume the scan by - * advancing to the next ARGV-element. - */ - char *nextchar; - - /* - * Describe the part of ARGV that contains non-options that have been skipped. - * `first_nonopt' is the index in ARGV of the first of them; `last_nonopt' is - * the index after the last of them. - */ - int first_nonopt; - int last_nonopt; -}; - -/* - * the variables optarg, optind, opterr and optopt are renamed with - * the custom_ prefix so that they don't interfere with getopt ones. - * - * Moreover they're static so they are visible only from within the - * file where this very file will be included. - */ - -/* - * For communication from `custom_getopt' to the caller. When `custom_getopt' finds an - * option that takes an argument, the argument value is returned here. - */ -static char *custom_optarg; - -/* - * Index in ARGV of the next element to be scanned. This is used for - * communication to and from the caller and for communication between - * successive calls to `custom_getopt'. - * - * On entry to `custom_getopt', 1 means this is the first call; initialize. - * - * When `custom_getopt' returns -1, this is the index of the first of the non-option - * elements that the caller should itself scan. - * - * Otherwise, `custom_optind' communicates from one call to the next how much of ARGV - * has been scanned so far. - * - * 1003.2 says this must be 1 before any call. - */ -static int custom_optind = 1; - -/* - * Callers store zero here to inhibit the error message for unrecognized - * options. - */ -static int custom_opterr = 1; - -/* - * Set to an option character which was unrecognized. This must be initialized - * on some systems to avoid linking in the system's own getopt implementation. - */ -static int custom_optopt = '?'; - -/* - * Exchange two adjacent subsequences of ARGV. One subsequence is elements - * [first_nonopt,last_nonopt) which contains all the non-options that have been - * skipped so far. The other is elements [last_nonopt,custom_optind), which contains - * all the options processed since those non-options were skipped. - * `first_nonopt' and `last_nonopt' are relocated so that they describe the new - * indices of the non-options in ARGV after they are moved. - */ -static void exchange(char **argv, struct custom_getopt_data *d) -{ - int bottom = d->first_nonopt; - int middle = d->last_nonopt; - int top = d->custom_optind; - char *tem; - - /* - * Exchange the shorter segment with the far end of the longer segment. - * That puts the shorter segment into the right place. It leaves the - * longer segment in the right place overall, but it consists of two - * parts that need to be swapped next. - */ - while (top > middle && middle > bottom) { - if (top - middle > middle - bottom) { - /* Bottom segment is the short one. */ - int len = middle - bottom; - int i; - - /* Swap it with the top part of the top segment. */ - for (i = 0; i < len; i++) { - tem = argv[bottom + i]; - argv[bottom + i] = - argv[top - (middle - bottom) + i]; - argv[top - (middle - bottom) + i] = tem; - } - /* Exclude the moved bottom segment from further swapping. */ - top -= len; - } else { - /* Top segment is the short one. */ - int len = top - middle; - int i; - - /* Swap it with the bottom part of the bottom segment. */ - for (i = 0; i < len; i++) { - tem = argv[bottom + i]; - argv[bottom + i] = argv[middle + i]; - argv[middle + i] = tem; - } - /* Exclude the moved top segment from further swapping. */ - bottom += len; - } - } - /* Update records for the slots the non-options now occupy. */ - d->first_nonopt += (d->custom_optind - d->last_nonopt); - d->last_nonopt = d->custom_optind; -} - -/* Initialize the internal data when the first call is made. */ -static void custom_getopt_initialize(struct custom_getopt_data *d) -{ - /* - * Start processing options with ARGV-element 1 (since ARGV-element 0 - * is the program name); the sequence of previously skipped non-option - * ARGV-elements is empty. - */ - d->first_nonopt = d->last_nonopt = d->custom_optind; - d->nextchar = NULL; - d->initialized = 1; -} - -#define NONOPTION_P (argv[d->custom_optind][0] != '-' || argv[d->custom_optind][1] == '\0') - -/* return: zero: continue, nonzero: return given value to user */ -static int shuffle_argv(int argc, char *const *argv,const struct option *longopts, - struct custom_getopt_data *d) -{ - /* - * Give FIRST_NONOPT & LAST_NONOPT rational values if CUSTOM_OPTIND has been - * moved back by the user (who may also have changed the arguments). - */ - if (d->last_nonopt > d->custom_optind) - d->last_nonopt = d->custom_optind; - if (d->first_nonopt > d->custom_optind) - d->first_nonopt = d->custom_optind; - /* - * If we have just processed some options following some - * non-options, exchange them so that the options come first. - */ - if (d->first_nonopt != d->last_nonopt && - d->last_nonopt != d->custom_optind) - exchange((char **) argv, d); - else if (d->last_nonopt != d->custom_optind) - d->first_nonopt = d->custom_optind; - /* - * Skip any additional non-options and extend the range of - * non-options previously skipped. - */ - while (d->custom_optind < argc && NONOPTION_P) - d->custom_optind++; - d->last_nonopt = d->custom_optind; - /* - * The special ARGV-element `--' means premature end of options. Skip - * it like a null option, then exchange with previous non-options as if - * it were an option, then skip everything else like a non-option. - */ - if (d->custom_optind != argc && !strcmp(argv[d->custom_optind], "--")) { - d->custom_optind++; - if (d->first_nonopt != d->last_nonopt - && d->last_nonopt != d->custom_optind) - exchange((char **) argv, d); - else if (d->first_nonopt == d->last_nonopt) - d->first_nonopt = d->custom_optind; - d->last_nonopt = argc; - d->custom_optind = argc; - } - /* - * If we have done all the ARGV-elements, stop the scan and back over - * any non-options that we skipped and permuted. - */ - if (d->custom_optind == argc) { - /* - * Set the next-arg-index to point at the non-options that we - * previously skipped, so the caller will digest them. - */ - if (d->first_nonopt != d->last_nonopt) - d->custom_optind = d->first_nonopt; - return -1; - } - /* - * If we have come to a non-option and did not permute it, either stop - * the scan or describe it to the caller and pass it by. - */ - if (NONOPTION_P) { - d->custom_optarg = argv[d->custom_optind++]; - return 1; - } - /* - * We have found another option-ARGV-element. Skip the initial - * punctuation. - */ - d->nextchar = (argv[d->custom_optind] + 1 + (longopts != NULL && argv[d->custom_optind][1] == '-')); - return 0; -} - -/* - * Check whether the ARGV-element is a long option. - * - * If there's a long option "fubar" and the ARGV-element is "-fu", consider - * that an abbreviation of the long option, just like "--fu", and not "-f" with - * arg "u". - * - * This distinction seems to be the most useful approach. - * - */ -static int check_long_opt(int argc, char *const *argv, const char *optstring, - const struct option *longopts, int *longind, - int print_errors, struct custom_getopt_data *d) -{ - char *nameend; - const struct option *p; - const struct option *pfound = NULL; - int exact = 0; - int ambig = 0; - int indfound = -1; - int option_index; - - for (nameend = d->nextchar; *nameend && *nameend != '='; nameend++) - /* Do nothing. */ ; - - /* Test all long options for either exact match or abbreviated matches */ - for (p = longopts, option_index = 0; p->name; p++, option_index++) - if (!strncmp(p->name, d->nextchar, nameend - d->nextchar)) { - if ((unsigned int) (nameend - d->nextchar) - == (unsigned int) strlen(p->name)) { - /* Exact match found. */ - pfound = p; - indfound = option_index; - exact = 1; - break; - } else if (pfound == NULL) { - /* First nonexact match found. */ - pfound = p; - indfound = option_index; - } else if (pfound->has_arg != p->has_arg - || pfound->flag != p->flag - || pfound->val != p->val) - /* Second or later nonexact match found. */ - ambig = 1; - } - if (ambig && !exact) { - if (print_errors) { - fprintf(stderr, - "%s: option `%s' is ambiguous\n", - argv[0], argv[d->custom_optind]); - } - d->nextchar += strlen(d->nextchar); - d->custom_optind++; - d->custom_optopt = 0; - return '?'; - } - if (pfound) { - option_index = indfound; - d->custom_optind++; - if (*nameend) { - if (pfound->has_arg != no_argument) - d->custom_optarg = nameend + 1; - else { - if (print_errors) { - if (argv[d->custom_optind - 1][1] == '-') { - /* --option */ - fprintf(stderr, "%s: option `--%s' doesn't allow an argument\n", - argv[0], pfound->name); - } else { - /* +option or -option */ - fprintf(stderr, "%s: option `%c%s' doesn't allow an argument\n", - argv[0], argv[d->custom_optind - 1][0], pfound->name); - } - - } - d->nextchar += strlen(d->nextchar); - d->custom_optopt = pfound->val; - return '?'; - } - } else if (pfound->has_arg == required_argument) { - if (d->custom_optind < argc) - d->custom_optarg = argv[d->custom_optind++]; - else { - if (print_errors) { - fprintf(stderr, - "%s: option `%s' requires an argument\n", - argv[0], - argv[d->custom_optind - 1]); - } - d->nextchar += strlen(d->nextchar); - d->custom_optopt = pfound->val; - return optstring[0] == ':' ? ':' : '?'; - } - } - d->nextchar += strlen(d->nextchar); - if (longind != NULL) - *longind = option_index; - if (pfound->flag) { - *(pfound->flag) = pfound->val; - return 0; - } - return pfound->val; - } - /* - * Can't find it as a long option. If this is not getopt_long_only, or - * the option starts with '--' or is not a valid short option, then - * it's an error. Otherwise interpret it as a short option. - */ - if (print_errors) { - if (argv[d->custom_optind][1] == '-') { - /* --option */ - fprintf(stderr, - "%s: unrecognized option `--%s'\n", - argv[0], d->nextchar); - } else { - /* +option or -option */ - fprintf(stderr, - "%s: unrecognized option `%c%s'\n", - argv[0], argv[d->custom_optind][0], - d->nextchar); - } - } - d->nextchar = (char *) ""; - d->custom_optind++; - d->custom_optopt = 0; - return '?'; -} - -static int check_short_opt(int argc, char *const *argv, const char *optstring, - int print_errors, struct custom_getopt_data *d) -{ - char c = *d->nextchar++; - const char *temp = strchr(optstring, c); - - /* Increment `custom_optind' when we start to process its last character. */ - if (*d->nextchar == '\0') - ++d->custom_optind; - if (!temp || c == ':') { - if (print_errors) - fprintf(stderr, "%s: invalid option -- %c\n", argv[0], c); - - d->custom_optopt = c; - return '?'; - } - if (temp[1] == ':') { - if (temp[2] == ':') { - /* This is an option that accepts an argument optionally. */ - if (*d->nextchar != '\0') { - d->custom_optarg = d->nextchar; - d->custom_optind++; - } else - d->custom_optarg = NULL; - d->nextchar = NULL; - } else { - /* This is an option that requires an argument. */ - if (*d->nextchar != '\0') { - d->custom_optarg = d->nextchar; - /* - * If we end this ARGV-element by taking the - * rest as an arg, we must advance to the next - * element now. - */ - d->custom_optind++; - } else if (d->custom_optind == argc) { - if (print_errors) { - fprintf(stderr, - "%s: option requires an argument -- %c\n", - argv[0], c); - } - d->custom_optopt = c; - if (optstring[0] == ':') - c = ':'; - else - c = '?'; - } else - /* - * We already incremented `custom_optind' once; - * increment it again when taking next ARGV-elt - * as argument. - */ - d->custom_optarg = argv[d->custom_optind++]; - d->nextchar = NULL; - } - } - return c; -} - -/* - * Scan elements of ARGV for option characters given in OPTSTRING. - * - * If an element of ARGV starts with '-', and is not exactly "-" or "--", - * then it is an option element. The characters of this element - * (aside from the initial '-') are option characters. If `getopt' - * is called repeatedly, it returns successively each of the option characters - * from each of the option elements. - * - * If `getopt' finds another option character, it returns that character, - * updating `custom_optind' and `nextchar' so that the next call to `getopt' can - * resume the scan with the following option character or ARGV-element. - * - * If there are no more option characters, `getopt' returns -1. - * Then `custom_optind' is the index in ARGV of the first ARGV-element - * that is not an option. (The ARGV-elements have been permuted - * so that those that are not options now come last.) - * - * OPTSTRING is a string containing the legitimate option characters. - * If an option character is seen that is not listed in OPTSTRING, - * return '?' after printing an error message. If you set `custom_opterr' to - * zero, the error message is suppressed but we still return '?'. - * - * If a char in OPTSTRING is followed by a colon, that means it wants an arg, - * so the following text in the same ARGV-element, or the text of the following - * ARGV-element, is returned in `custom_optarg'. Two colons mean an option that - * wants an optional arg; if there is text in the current ARGV-element, - * it is returned in `custom_optarg', otherwise `custom_optarg' is set to zero. - * - * If OPTSTRING starts with `-' or `+', it requests different methods of - * handling the non-option ARGV-elements. - * See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. - * - * Long-named options begin with `--' instead of `-'. - * Their names may be abbreviated as long as the abbreviation is unique - * or is an exact match for some defined option. If they have an - * argument, it follows the option name in the same ARGV-element, separated - * from the option name by a `=', or else the in next ARGV-element. - * When `getopt' finds a long-named option, it returns 0 if that option's - * `flag' field is nonzero, the value of the option's `val' field - * if the `flag' field is zero. - * - * The elements of ARGV aren't really const, because we permute them. - * But we pretend they're const in the prototype to be compatible - * with other systems. - * - * LONGOPTS is a vector of `struct option' terminated by an - * element containing a name which is zero. - * - * LONGIND returns the index in LONGOPT of the long-named option found. - * It is only valid when a long-named option has been found by the most - * recent call. - * - * Return the option character from OPTS just read. Return -1 when there are - * no more options. For unrecognized options, or options missing arguments, - * `custom_optopt' is set to the option letter, and '?' is returned. - * - * The OPTS string is a list of characters which are recognized option letters, - * optionally followed by colons, specifying that that letter takes an - * argument, to be placed in `custom_optarg'. - * - * If a letter in OPTS is followed by two colons, its argument is optional. - * This behavior is specific to the GNU `getopt'. - * - * The argument `--' causes premature termination of argument scanning, - * explicitly telling `getopt' that there are no more options. If OPTS begins - * with `--', then non-option arguments are treated as arguments to the option - * '\0'. This behavior is specific to the GNU `getopt'. - */ - -static int getopt_internal_r(int argc, char *const *argv, const char *optstring, - const struct option *longopts, int *longind, - struct custom_getopt_data *d) -{ - int ret, print_errors = d->custom_opterr; - - if (optstring[0] == ':') - print_errors = 0; - if (argc < 1) - return -1; - d->custom_optarg = NULL; - - /* - * This is a big difference with GNU getopt, since optind == 0 - * means initialization while here 1 means first call. - */ - if (d->custom_optind == 0 || !d->initialized) { - if (d->custom_optind == 0) - d->custom_optind = 1; /* Don't scan ARGV[0], the program name. */ - custom_getopt_initialize(d); - } - if (d->nextchar == NULL || *d->nextchar == '\0') { - ret = shuffle_argv(argc, argv, longopts, d); - if (ret) - return ret; - } - if (longopts && (argv[d->custom_optind][1] == '-' )) - return check_long_opt(argc, argv, optstring, longopts, - longind, print_errors, d); - return check_short_opt(argc, argv, optstring, print_errors, d); -} - -static int custom_getopt_internal(int argc, char *const *argv, const char *optstring, - const struct option *longopts, int *longind) -{ - int result; - /* Keep a global copy of all internal members of d */ - static struct custom_getopt_data d; - - d.custom_optind = custom_optind; - d.custom_opterr = custom_opterr; - result = getopt_internal_r(argc, argv, optstring, longopts, - longind, &d); - custom_optind = d.custom_optind; - custom_optarg = d.custom_optarg; - custom_optopt = d.custom_optopt; - return result; -} - -static int custom_getopt_long (int argc, char *const *argv, const char *options, - const struct option *long_options, int *opt_index) -{ - return custom_getopt_internal(argc, argv, options, long_options, - opt_index); -} - - -static char *package_name = 0; - -/** - * @brief updates an option - * @param field the generic pointer to the field to update - * @param orig_field the pointer to the orig field - * @param field_given the pointer to the number of occurrence of this option - * @param prev_given the pointer to the number of occurrence already seen - * @param value the argument for this option (if null no arg was specified) - * @param possible_values the possible values for this option (if specified) - * @param default_value the default value (in case the option only accepts fixed values) - * @param arg_type the type of this option - * @param check_ambiguity @see cmdline_parser_params.check_ambiguity - * @param override @see cmdline_parser_params.override - * @param no_free whether to free a possible previous value - * @param multiple_option whether this is a multiple option - * @param long_opt the corresponding long option - * @param short_opt the corresponding short option (or '-' if none) - * @param additional_error possible further error specification - */ -static -int update_arg(void *field, char **orig_field, - unsigned int *field_given, unsigned int *prev_given, - char *value, const char *possible_values[], - const char *default_value, - cmdline_parser_arg_type arg_type, - int check_ambiguity, int override, - int no_free, int multiple_option, - const char *long_opt, char short_opt, - const char *additional_error) -{ - char *stop_char = 0; - const char *val = value; - int found; - char **string_field; - FIX_UNUSED (field); - - stop_char = 0; - found = 0; - - if (!multiple_option && prev_given && (*prev_given || (check_ambiguity && *field_given))) - { - if (short_opt != '-') - fprintf (stderr, "%s: `--%s' (`-%c') option given more than once%s\n", - package_name, long_opt, short_opt, - (additional_error ? additional_error : "")); - else - fprintf (stderr, "%s: `--%s' option given more than once%s\n", - package_name, long_opt, - (additional_error ? additional_error : "")); - return 1; /* failure */ - } - - FIX_UNUSED (default_value); - - if (field_given && *field_given && ! override) - return 0; - if (prev_given) - (*prev_given)++; - if (field_given) - (*field_given)++; - if (possible_values) - val = possible_values[found]; - - switch(arg_type) { - case ARG_FLAG: - *((int *)field) = !*((int *)field); - break; - case ARG_INT: - if (val) *((int *)field) = strtol (val, &stop_char, 0); - break; - case ARG_STRING: - if (val) { - string_field = (char **)field; - if (!no_free && *string_field) - free (*string_field); /* free previous string */ - *string_field = gengetopt_strdup (val); - } - break; - default: - break; - }; - - /* check numeric conversion */ - switch(arg_type) { - case ARG_INT: - if (val && !(stop_char && *stop_char == '\0')) { - fprintf(stderr, "%s: invalid numeric value: %s\n", package_name, val); - return 1; /* failure */ - } - break; - default: - ; - }; - - /* store the original value */ - switch(arg_type) { - case ARG_NO: - case ARG_FLAG: - break; - default: - if (value && orig_field) { - if (no_free) { - *orig_field = value; - } else { - if (*orig_field) - free (*orig_field); /* free previous string */ - *orig_field = gengetopt_strdup (value); - } - } - }; - - return 0; /* OK */ -} - - -int -cmdline_parser_internal ( - int argc, char **argv, struct gengetopt_args_info *args_info, - struct cmdline_parser_params *params, const char *additional_error) -{ - int c; /* Character of the parsed option. */ - - int error_occurred = 0; - struct gengetopt_args_info local_args_info; - - int override; - int initialize; - int check_required; - int check_ambiguity; - - char *optarg; - int optind; - int opterr; - int optopt; - - package_name = argv[0]; - - override = params->override; - initialize = params->initialize; - check_required = params->check_required; - check_ambiguity = params->check_ambiguity; - - if (initialize) - cmdline_parser_init (args_info); - - cmdline_parser_init (&local_args_info); - - optarg = 0; - optind = 0; - opterr = params->print_errors; - optopt = '?'; - - while (1) - { - int option_index = 0; - - static struct option long_options[] = { - { "help", 0, NULL, 'h' }, - { "version", 0, NULL, 'V' }, - { "remote-ip", 1, NULL, 'r' }, - { "port", 1, NULL, 'p' }, - { "packet-size", 1, NULL, 's' }, - { "packet-number", 1, NULL, 'n' }, - { "interval", 1, NULL, 'i' }, - { "max-rtt", 1, NULL, 'm' }, - { "wait", 1, NULL, 'w' }, - { "verbose", 0, NULL, 'v' }, - { "ftrace", 0, NULL, 't' }, - { 0, 0, 0, 0 } - }; - - custom_optarg = optarg; - custom_optind = optind; - custom_opterr = opterr; - custom_optopt = optopt; - - c = custom_getopt_long (argc, argv, "hVr:p:s:n:i:m:w:vt", long_options, &option_index); - - optarg = custom_optarg; - optind = custom_optind; - opterr = custom_opterr; - optopt = custom_optopt; - - if (c == -1) break; /* Exit from `while (1)' loop. */ - - switch (c) - { - case 'h': /* Print help and exit. */ - cmdline_parser_print_help (); - cmdline_parser_free (&local_args_info); - exit (EXIT_SUCCESS); - - case 'V': /* Print version and exit. */ - cmdline_parser_print_version (); - cmdline_parser_free (&local_args_info); - exit (EXIT_SUCCESS); - - case 'r': /* Remote IP Address. */ - - - if (update_arg( (void *)&(args_info->remote_ip_arg), - &(args_info->remote_ip_orig), &(args_info->remote_ip_given), - &(local_args_info.remote_ip_given), optarg, 0, "127.0.0.1", ARG_STRING, - check_ambiguity, override, 0, 0, - "remote-ip", 'r', - additional_error)) - goto failure; - - break; - case 'p': /* UDP Port Number. */ - - - if (update_arg( (void *)&(args_info->port_arg), - &(args_info->port_orig), &(args_info->port_given), - &(local_args_info.port_given), optarg, 0, "15001", ARG_INT, - check_ambiguity, override, 0, 0, - "port", 'p', - additional_error)) - goto failure; - - break; - case 's': /* Packet size in byte. */ - - - if (update_arg( (void *)&(args_info->packet_size_arg), - &(args_info->packet_size_orig), &(args_info->packet_size_given), - &(local_args_info.packet_size_given), optarg, 0, "10", ARG_INT, - check_ambiguity, override, 0, 0, - "packet-size", 's', - additional_error)) - goto failure; - - break; - case 'n': /* Number of packet for each iteration. */ - - - if (update_arg( (void *)&(args_info->packet_number_arg), - &(args_info->packet_number_orig), &(args_info->packet_number_given), - &(local_args_info.packet_number_given), optarg, 0, "100", ARG_INT, - check_ambiguity, override, 0, 0, - "packet-number", 'n', - additional_error)) - goto failure; - - break; - case 'i': /* Period time in microseconds. If 0, iteration are running as fast as possible. */ - - - if (update_arg( (void *)&(args_info->interval_arg), - &(args_info->interval_orig), &(args_info->interval_given), - &(local_args_info.interval_given), optarg, 0, "0", ARG_INT, - check_ambiguity, override, 0, 0, - "interval", 'i', - additional_error)) - goto failure; - - break; - case 'm': /* Maximum time of one period. If 0, the interval value is used and if interval is 0, this check is disabled.. */ - - - if (update_arg( (void *)&(args_info->max_rtt_arg), - &(args_info->max_rtt_orig), &(args_info->max_rtt_given), - &(local_args_info.max_rtt_given), optarg, 0, "0", ARG_INT, - check_ambiguity, override, 0, 0, - "max-rtt", 'm', - additional_error)) - goto failure; - - break; - case 'w': /* For server side only. This value define how much the server wait before sending back packets.. */ - - - if (update_arg( (void *)&(args_info->wait_arg), - &(args_info->wait_orig), &(args_info->wait_given), - &(local_args_info.wait_given), optarg, 0, "0", ARG_INT, - check_ambiguity, override, 0, 0, - "wait", 'w', - additional_error)) - goto failure; - - break; - case 'v': /* Increase program verbosity. */ - - - if (update_arg((void *)&(args_info->verbose_flag), 0, &(args_info->verbose_given), - &(local_args_info.verbose_given), optarg, 0, 0, ARG_FLAG, - check_ambiguity, override, 1, 0, "verbose", 'v', - additional_error)) - goto failure; - - break; - case 't': /* Enable ftrace and reset trace on each iteration. Use with max-rtt option. Requires root rights.. */ - - - if (update_arg((void *)&(args_info->ftrace_flag), 0, &(args_info->ftrace_given), - &(local_args_info.ftrace_given), optarg, 0, 0, ARG_FLAG, - check_ambiguity, override, 1, 0, "ftrace", 't', - additional_error)) - goto failure; - - break; - - case 0: /* Long option with no short option */ - case '?': /* Invalid option. */ - /* `getopt_long' already printed an error message. */ - goto failure; - - default: /* bug: option not considered. */ - fprintf (stderr, "%s: option unknown: %c%s\n", CMDLINE_PARSER_PACKAGE, c, (additional_error ? additional_error : "")); - abort (); - } /* switch */ - } /* while */ - - - - - cmdline_parser_release (&local_args_info); - - if ( error_occurred ) - return (EXIT_FAILURE); - - return 0; - -failure: - - cmdline_parser_release (&local_args_info); - return (EXIT_FAILURE); -} diff --git a/todo/udptest/cmdline.h b/todo/udptest/cmdline.h deleted file mode 100644 index 65d3080..0000000 --- a/todo/udptest/cmdline.h +++ /dev/null @@ -1,207 +0,0 @@ -/** @file cmdline.h - * @brief The header file for the command line option parser - * generated by GNU Gengetopt version 2.22.6 - * http://www.gnu.org/software/gengetopt. - * DO NOT modify this file, since it can be overwritten - * @author GNU Gengetopt by Lorenzo Bettini */ - -#ifndef CMDLINE_H -#define CMDLINE_H - -/* If we use autoconf. */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include /* for FILE */ - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -#ifndef CMDLINE_PARSER_PACKAGE -/** @brief the program name (used for printing errors) */ -#define CMDLINE_PARSER_PACKAGE "udptest" -#endif - -#ifndef CMDLINE_PARSER_PACKAGE_NAME -/** @brief the complete program name (used for help and version) */ -#define CMDLINE_PARSER_PACKAGE_NAME "udptest" -#endif - -#ifndef CMDLINE_PARSER_VERSION -/** @brief the program version */ -#define CMDLINE_PARSER_VERSION "0.1" -#endif - -/** @brief Where the command line options are stored */ -struct gengetopt_args_info -{ - const char *help_help; /**< @brief Print help and exit help description. */ - const char *version_help; /**< @brief Print version and exit help description. */ - char * remote_ip_arg; /**< @brief Remote IP Address (default='127.0.0.1'). */ - char * remote_ip_orig; /**< @brief Remote IP Address original value given at command line. */ - const char *remote_ip_help; /**< @brief Remote IP Address help description. */ - int port_arg; /**< @brief UDP Port Number (default='15001'). */ - char * port_orig; /**< @brief UDP Port Number original value given at command line. */ - const char *port_help; /**< @brief UDP Port Number help description. */ - int packet_size_arg; /**< @brief Packet size in byte (default='10'). */ - char * packet_size_orig; /**< @brief Packet size in byte original value given at command line. */ - const char *packet_size_help; /**< @brief Packet size in byte help description. */ - int packet_number_arg; /**< @brief Number of packet for each iteration (default='100'). */ - char * packet_number_orig; /**< @brief Number of packet for each iteration original value given at command line. */ - const char *packet_number_help; /**< @brief Number of packet for each iteration help description. */ - int interval_arg; /**< @brief Period time in microseconds. If 0, iteration are running as fast as possible (default='0'). */ - char * interval_orig; /**< @brief Period time in microseconds. If 0, iteration are running as fast as possible original value given at command line. */ - const char *interval_help; /**< @brief Period time in microseconds. If 0, iteration are running as fast as possible help description. */ - int max_rtt_arg; /**< @brief Maximum time of one period. If 0, the interval value is used and if interval is 0, this check is disabled. (default='0'). */ - char * max_rtt_orig; /**< @brief Maximum time of one period. If 0, the interval value is used and if interval is 0, this check is disabled. original value given at command line. */ - const char *max_rtt_help; /**< @brief Maximum time of one period. If 0, the interval value is used and if interval is 0, this check is disabled. help description. */ - int wait_arg; /**< @brief For server side only. This value define how much the server wait before sending back packets. (default='0'). */ - char * wait_orig; /**< @brief For server side only. This value define how much the server wait before sending back packets. original value given at command line. */ - const char *wait_help; /**< @brief For server side only. This value define how much the server wait before sending back packets. help description. */ - int verbose_flag; /**< @brief Increase program verbosity (default=off). */ - const char *verbose_help; /**< @brief Increase program verbosity help description. */ - int ftrace_flag; /**< @brief Enable ftrace and reset trace on each iteration. Use with max-rtt option. Requires root rights. (default=off). */ - const char *ftrace_help; /**< @brief Enable ftrace and reset trace on each iteration. Use with max-rtt option. Requires root rights. help description. */ - - unsigned int help_given ; /**< @brief Whether help was given. */ - unsigned int version_given ; /**< @brief Whether version was given. */ - unsigned int remote_ip_given ; /**< @brief Whether remote-ip was given. */ - unsigned int port_given ; /**< @brief Whether port was given. */ - unsigned int packet_size_given ; /**< @brief Whether packet-size was given. */ - unsigned int packet_number_given ; /**< @brief Whether packet-number was given. */ - unsigned int interval_given ; /**< @brief Whether interval was given. */ - unsigned int max_rtt_given ; /**< @brief Whether max-rtt was given. */ - unsigned int wait_given ; /**< @brief Whether wait was given. */ - unsigned int verbose_given ; /**< @brief Whether verbose was given. */ - unsigned int ftrace_given ; /**< @brief Whether ftrace was given. */ - -} ; - -/** @brief The additional parameters to pass to parser functions */ -struct cmdline_parser_params -{ - int override; /**< @brief whether to override possibly already present options (default 0) */ - int initialize; /**< @brief whether to initialize the option structure gengetopt_args_info (default 1) */ - int check_required; /**< @brief whether to check that all required options were provided (default 1) */ - int check_ambiguity; /**< @brief whether to check for options already specified in the option structure gengetopt_args_info (default 0) */ - int print_errors; /**< @brief whether getopt_long should print an error message for a bad option (default 1) */ -} ; - -/** @brief the purpose string of the program */ -extern const char *gengetopt_args_info_purpose; -/** @brief the usage string of the program */ -extern const char *gengetopt_args_info_usage; -/** @brief the description string of the program */ -extern const char *gengetopt_args_info_description; -/** @brief all the lines making the help output */ -extern const char *gengetopt_args_info_help[]; - -/** - * The command line parser - * @param argc the number of command line options - * @param argv the command line options - * @param args_info the structure where option information will be stored - * @return 0 if everything went fine, NON 0 if an error took place - */ -int cmdline_parser (int argc, char **argv, - struct gengetopt_args_info *args_info); - -/** - * The command line parser (version with additional parameters - deprecated) - * @param argc the number of command line options - * @param argv the command line options - * @param args_info the structure where option information will be stored - * @param override whether to override possibly already present options - * @param initialize whether to initialize the option structure my_args_info - * @param check_required whether to check that all required options were provided - * @return 0 if everything went fine, NON 0 if an error took place - * @deprecated use cmdline_parser_ext() instead - */ -int cmdline_parser2 (int argc, char **argv, - struct gengetopt_args_info *args_info, - int override, int initialize, int check_required); - -/** - * The command line parser (version with additional parameters) - * @param argc the number of command line options - * @param argv the command line options - * @param args_info the structure where option information will be stored - * @param params additional parameters for the parser - * @return 0 if everything went fine, NON 0 if an error took place - */ -int cmdline_parser_ext (int argc, char **argv, - struct gengetopt_args_info *args_info, - struct cmdline_parser_params *params); - -/** - * Save the contents of the option struct into an already open FILE stream. - * @param outfile the stream where to dump options - * @param args_info the option struct to dump - * @return 0 if everything went fine, NON 0 if an error took place - */ -int cmdline_parser_dump(FILE *outfile, - struct gengetopt_args_info *args_info); - -/** - * Save the contents of the option struct into a (text) file. - * This file can be read by the config file parser (if generated by gengetopt) - * @param filename the file where to save - * @param args_info the option struct to save - * @return 0 if everything went fine, NON 0 if an error took place - */ -int cmdline_parser_file_save(const char *filename, - struct gengetopt_args_info *args_info); - -/** - * Print the help - */ -void cmdline_parser_print_help(void); -/** - * Print the version - */ -void cmdline_parser_print_version(void); - -/** - * Initializes all the fields a cmdline_parser_params structure - * to their default values - * @param params the structure to initialize - */ -void cmdline_parser_params_init(struct cmdline_parser_params *params); - -/** - * Allocates dynamically a cmdline_parser_params structure and initializes - * all its fields to their default values - * @return the created and initialized cmdline_parser_params structure - */ -struct cmdline_parser_params *cmdline_parser_params_create(void); - -/** - * Initializes the passed gengetopt_args_info structure's fields - * (also set default values for options that have a default) - * @param args_info the structure to initialize - */ -void cmdline_parser_init (struct gengetopt_args_info *args_info); -/** - * Deallocates the string fields of the gengetopt_args_info structure - * (but does not deallocate the structure itself) - * @param args_info the structure to deallocate - */ -void cmdline_parser_free (struct gengetopt_args_info *args_info); - -/** - * Checks that all the required options were specified - * @param args_info the structure to check - * @param prog_name the name of the program that will be used to print - * possible errors - * @return - */ -int cmdline_parser_required (struct gengetopt_args_info *args_info, - const char *prog_name); - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif /* CMDLINE_H */ diff --git a/todo/udptest/com.c b/todo/udptest/com.c deleted file mode 100644 index 349ac83..0000000 --- a/todo/udptest/com.c +++ /dev/null @@ -1,109 +0,0 @@ -#include "common.h" - -int com_init_server(struct sockaddr_in *sockaddr, socklen_t *socklen, int port) -{ - int s; - - s = socket(AF_INET, SOCK_DGRAM, 0/*IPPROTO_UDP*/); - if (s < 0) - { - printf("Failed to create socket\n"); - return -1; - } - - /* This will be filled by the first recvfrom() with the peer's addr */ - *socklen = sizeof(struct sockaddr_in); - memset((char *) sockaddr, 0, sizeof(struct sockaddr_in)); - - struct sockaddr_in host; - host.sin_family = AF_INET; - host.sin_port = htons(port); - host.sin_addr.s_addr = htonl(INADDR_ANY); - - if(bind(s, (struct sockaddr*)&host, sizeof(struct sockaddr_in)) == -1) - { - printf("Failed to bind sockaddr\n"); - return -2; - } - - return s; -} - -int com_init_client(struct sockaddr_in *sockaddr, socklen_t *socklen, const char* ipaddr, int port, int timeout_us) -{ - int s; - struct timeval tv; - - s = socket(AF_INET, SOCK_DGRAM, 0 /*IPPROTO_UDP*/); - if (s < 0) - { - printf("Failed to create socket\n"); - return -1; - } - - *socklen = sizeof(struct sockaddr_in); - memset((char *) sockaddr, 0, sizeof(struct sockaddr_in)); - sockaddr->sin_family = AF_INET; - sockaddr->sin_port = htons(port); - - if (inet_aton(ipaddr, &(sockaddr->sin_addr)) == 0) - { - printf("Failed to binarize IP addr\n"); - return -2; - } - - if (timeout_us > 0) { - /* Note : Starting from NH4, this timeout must be greater than 2*Hz - * Assuming HZ=1000, this means the minimum timeout is 2ms. - * This timeout is only here to unblock blocking rcv()/send(), time checking is done in the main loop. - */ - if (timeout_us < 2000) { - timeout_us = 2000; - } - tv.tv_sec = timeout_us / 1000000; - tv.tv_usec = timeout_us % 1000000; - setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(struct timeval)); - } - - return s; -} - -int com_send(struct sockaddr_in *sockaddr, socklen_t *socklen, int fd, char *packet_out, int size) -{ - ssize_t sent; - - sent = sendto(fd, packet_out, size, 0 , (struct sockaddr *) sockaddr, *socklen); - - if (sent < 0) - { - printf("Failed to send packet, errno = %d\n", errno); - return -errno; - } - else if (sent != size) - { - printf("Sendto has not sent all the bytes : %ld sent and %d expected.\n", sent, size); - return -1; - } - - return 0; -} - -int com_receive(struct sockaddr_in *sockaddr, socklen_t *socklen, int fd, char *packet_in, int size) -{ - ssize_t rcvd; - - rcvd = recvfrom(fd, packet_in, size, 0, (struct sockaddr *) sockaddr, socklen); - - if (rcvd < 0) - { - printf("Failed to receive packet, errno = %d (%s)\n", errno, strerror(errno)); - return -errno; - } - else if (rcvd != size) - { - printf("Recvfrom has not received all the bytes : %ld received and %d expected.\n", rcvd, size); - return -1; - } - - return 0; -} diff --git a/todo/udptest/common.h b/todo/udptest/common.h deleted file mode 100644 index 6cab22c..0000000 --- a/todo/udptest/common.h +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef COMMON_H -#define COMMON_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef __vxworks -#include -#endif - -#define clock_s struct timespec - -struct latency_s { - int max_us; - int min_us; - long long cumul_us; - long long iter_number; -}; - -int com_init_server(struct sockaddr_in *sockaddr, socklen_t *socklen, int port); -int com_init_client(struct sockaddr_in *sockaddr, socklen_t *socklen, const char* ipaddr, int port, int timeout_us); -int com_send(struct sockaddr_in *sockaddr, socklen_t *socklen, int fd, char *packet_out, int size); -int com_receive(struct sockaddr_in *sockaddr, socklen_t *socklen, int fd, char *packet_in, int size); - -int timer_init(void); /* Return fd to use */ -int timer_setdelay(int fd, unsigned int delay_us); -int timer_wait(int fd); - -#ifndef __vxworks -void clock_current(clock_s *now); -int clock_diff_us(clock_s c1, clock_s c2); /* Return the difference in milliseconds */ -void clock_latency_update(clock_s prev, clock_s now, struct latency_s *latency, const char* name, int verbose); -#else -void clock_current(uint64_t* now); -int clock_diff_us(uint64_t t1, uint64_t t2); -void clock_latency_update(uint64_t t1, uint64_t t2, struct latency_s* latency, const char* name, int verbose); -#endif -void clock_latency_print(struct latency_s* latency, const char* name); -void clock_latency_reset_avg(struct latency_s* latency); -void clock_latency_init(struct latency_s* latency); - -int start_ftrace(); /* Return fd to use with stop_ftrace() */ -void stop_ftrace(); -void reset_ftrace(); -void init_trace_marker(); -void trace_write(const char *fmt, ...); - - -#endif diff --git a/todo/udptest/ftrace.c b/todo/udptest/ftrace.c deleted file mode 100644 index fb75cb4..0000000 --- a/todo/udptest/ftrace.c +++ /dev/null @@ -1,64 +0,0 @@ -#include -#include -#include -#include -#include "common.h" - -int start_ftrace() -{ - int fd; - char one = '1'; - - fd = open("/sys/kernel/debug/tracing/tracing_on", O_WRONLY); - write(fd, &one, 1); - close(fd); - - return fd; -} - -void stop_ftrace() -{ - int fd; - char zero = '0'; - - fd = open("/sys/kernel/debug/tracing/tracing_on", O_WRONLY); - write(fd, &zero, 1); - close(fd); -} - -void reset_ftrace() -{ - int fd; - char zero = '0'; - - fd = open("/sys/kernel/debug/tracing/trace", O_WRONLY); - write(fd, &zero, 1); - close(fd); -} - -static int trace_marker_fd = -1; -void init_trace_marker() -{ - trace_marker_fd = open("/sys/kernel/debug/tracing/trace_marker", O_WRONLY); - if(trace_marker_fd < 0) { - fprintf(stderr, "Warning can't open ftrace marker (errno=%d) (it will be ignored)\n", errno); - } - -} - -void trace_write(const char *fmt, ...) -{ - va_list ap; - char buf[256]; - int n; - - if (trace_marker_fd < 0) - return; - - va_start(ap, fmt); - n = vsnprintf(buf, 256, fmt, ap); - va_end(ap); - - write(trace_marker_fd, buf, n); -} - diff --git a/todo/udptest/launch.c b/todo/udptest/launch.c deleted file mode 100644 index d118962..0000000 --- a/todo/udptest/launch.c +++ /dev/null @@ -1,15 +0,0 @@ -#include -#include -#include - -extern int main(int argc, char **argv); - -int launch_udptest(char *ip_addr) { - - printf ("IP= <%s>\n", ip_addr); - - char *argv[] = { "udptest", "-n", "1", "-r", ip_addr}; - int argc = sizeof(argv) / sizeof(argv[0]); - - return main(argc, argv); -} diff --git a/todo/udptest/timer.c b/todo/udptest/timer.c deleted file mode 100644 index 55fb675..0000000 --- a/todo/udptest/timer.c +++ /dev/null @@ -1,49 +0,0 @@ -#include -#include -#include -#include "common.h" - -/* Use timerfd using the libc */ -int timer_init(void) -{ - int timerfd = -1; - - /* Create FD */ - timerfd = timerfd_create(CLOCK_REALTIME, 0); - - return timerfd; -} - -int timer_setdelay(int fd, unsigned int delay_us) -{ - struct itimerspec ts; - - memset(&ts, sizeof(ts), 0); - ts.it_interval.tv_sec = 0; - ts.it_interval.tv_nsec = 0; - ts.it_value.tv_sec = delay_us / 1000000; - ts.it_value.tv_nsec = (delay_us * 1000) % 1000000000; - - int res = timerfd_settime(fd, 0, &ts, 0); - if(res < 0){ - printf("Failed to configure timer\n"); - return -1; - } - - return 0; -} - -int timer_wait(int fd) -{ - fd_set set; - int ret; - - FD_ZERO(&set); - FD_SET(fd, &set); - - ret = select(FD_SETSIZE, &set, NULL, NULL,NULL); - - return ret; -} - - diff --git a/todo/udptest/udptest.c b/todo/udptest/udptest.c deleted file mode 100644 index 9f1e346..0000000 --- a/todo/udptest/udptest.c +++ /dev/null @@ -1,188 +0,0 @@ -#include "common.h" -#include "cmdline.h" - -int main(int argc, char** argv) -{ - - struct gengetopt_args_info opt; - char* packets; - struct sockaddr_in sockaddr; - struct latency_s lat_rtt; - #ifndef __vxworks - clock_s time_begin_of_iter, time_end_of_iter; - clock_s time_last_print; - #else - uint64_t time_begin_of_iter, time_end_of_iter; - uint64_t time_last_print; - #endif - socklen_t socklen; - int fd_udp, fd_timer, i, timeout_socket_us = 0, loop_iter = 0, rc; - int duration_iter, since_last_print; - uint32_t seq_start = 0; /* Sequence counter to check for packet ordering and synchro */ - uint32_t *seq; - int warmup = 1; /* Drop only first iteration */ - int leaving = 0; - - if (cmdline_parser(argc, argv, &opt) != 0) { - return -1; - } - - if (opt.packet_size_arg < 4) { - printf("Error: Packet size must be at least 4 bytes as we store a sequence counter in it.\n"); - return -1; - } - -#ifndef __vxworks - init_trace_marker(); -#endif - - printf("Starting UDPtest.\n"); - printf("Send %d packets of %d bytes and receive them every %d us.\n", opt.packet_number_arg, opt.packet_size_arg, opt.interval_arg); - - if (opt.interval_arg > 0) { - timeout_socket_us = opt.interval_arg; - } else if (opt.max_rtt_arg > 0) { - timeout_socket_us = opt.max_rtt_arg; - } else { - timeout_socket_us = 1000000; /* One second timeout */ - } - - fd_udp = com_init_client(&sockaddr, &socklen, opt.remote_ip_arg, opt.port_arg, timeout_socket_us); - if (fd_udp < 0) { - printf("Failed to open socket for UDP communication. Check ip address and port number availability.\n"); - return -1; - } else if (opt.verbose_flag) { - printf("Fd for UDP communication is %d.\n", fd_udp); - } - printf("Sending to %s on port %d\n", opt.remote_ip_arg, opt.port_arg); - - /* Buffer allocation */ - packets = malloc(opt.packet_size_arg * opt.packet_number_arg); - memset(packets, 0xaa, opt.packet_size_arg * opt.packet_number_arg); /* Will trigger allocation on write for overcommit system */ - - /* TimerFD initialization */ -#ifndef __vxworks - fd_timer = timer_init(); -#endif - - /* Latency statistics initialization */ - clock_latency_init(&lat_rtt); - clock_current(&time_last_print); - - /* Ftrace initialization */ - if (opt.ftrace_flag) { - //TODO configure? - //TODO check if possible or fail (ie.root rights) -#ifndef __vxworks - start_ftrace(); -#endif - } - - while (!leaving) { - loop_iter++; - - if (opt.ftrace_flag) { -#ifndef __vxworks - reset_ftrace(); -#endif - } - -#ifndef __vxworks - timer_setdelay(fd_timer, opt.interval_arg); -#endif - - /* Init time */ - clock_current(&time_begin_of_iter); - - /* Init sequence counter */ - seq_start = (loop_iter * opt.packet_number_arg) % UINT_MAX; - - for (i=0; i 1000000) { /* Print statistics each second */ - time_last_print = time_end_of_iter; - clock_latency_print(&lat_rtt, "lat_rtt"); - clock_latency_reset_avg(&lat_rtt); - } - } - - /* Check that one iteration is less than the period */ - duration_iter = clock_diff_us(time_begin_of_iter, time_end_of_iter); - // trace_write("udptest : %dus lat", duration_iter); - if (opt.interval_arg > 0 && duration_iter > opt.interval_arg && !warmup) { - if (opt.ftrace_flag) { - // stop_ftrace(); - } - clock_latency_print(&lat_rtt, "lat_rtt"); - printf("Loop period exceeded. Exit.\n"); - leaving = 1; - } - /* Check that RTT is less than the one asked */ - if (opt.max_rtt_arg > 0 && duration_iter > opt.max_rtt_arg && !warmup) { - if (opt.ftrace_flag) { - // stop_ftrace(); - } - clock_latency_print(&lat_rtt, "lat_rtt"); - printf("UDP packets RTT exceeded. Exit.\n"); - leaving = 1; - } - - if (warmup > 0) { - warmup--; - } - - if (opt.verbose_flag) { - printf("End of loop %d.\n", loop_iter); - } - - if (!leaving && opt.interval_arg > 0) { -#ifndef __vxworks - timer_wait(fd_timer); -#endif - } - } - - close(fd_udp); - - return 0; -} diff --git a/todo/udptest/udptestserver.c b/todo/udptest/udptestserver.c deleted file mode 100644 index b00aa76..0000000 --- a/todo/udptest/udptestserver.c +++ /dev/null @@ -1,87 +0,0 @@ -#include "common.h" -#include "cmdline.h" - -int main(int argc, char** argv) -{ - struct gengetopt_args_info opt; - struct sockaddr_in sockaddr; - socklen_t socklen; - char* packets; - int fd_udp, i; - int loop_iter = 0; - struct timespec wait; - uint32_t seq_start = 0; /* Sequence counter to check for packet ordering and synchro */ - uint32_t *seq; - - if (cmdline_parser(argc, argv, &opt) != 0) { - return -1; - } - - if (opt.packet_size_arg < 4) { - printf("Error: Packet size must be at least 4 bytes as we store a sequence counter in it.\n"); - return -1; - } - - printf("Starting UDPtest server side.\n"); - printf("Receive %d packets of %d bytes and send them back after %d us.\n", opt.packet_number_arg, opt.packet_size_arg, opt.wait_arg); - - fd_udp = com_init_server(&sockaddr, &socklen, opt.port_arg); - if (fd_udp < 0) { - printf("Failed to open socket for UDP communication. Check port number availability %d.\n", opt.port_arg); - return -1; - } else if (opt.verbose_flag) { - printf("Fd for UDP communication is %d.\n", fd_udp); - } - printf("Listening on port %d\n", opt.port_arg); - - /* Buffer allocation */ - packets = malloc(opt.packet_size_arg * opt.packet_number_arg); - memset(packets, 0xaa, opt.packet_size_arg * opt.packet_number_arg); /* Will trigger allocation on write for overcommit system */ - - /* Wait timeval initialization */ - if (opt.wait_arg > 0) { - wait.tv_sec = opt.wait_arg / 1000000; - wait.tv_nsec = (opt.wait_arg * 1000) % 1000000; - } - - while (1) { - loop_iter++; - - /* Init sequence counter (same init as udptest program) */ - seq_start = (loop_iter * opt.packet_number_arg) % UINT_MAX; - - for (i=0; i 0) { - clock_nanosleep(CLOCK_MONOTONIC, 0, &wait, NULL); - } - - if (opt.verbose_flag) { - printf("Send back the packets\n"); - } - - for (i=0; i +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include "mtime.h" +#include "test.h" + +/* global variables */ + +nstime_t *deltas = NULL; +int nb_measurements = 0; + +char *message = "udp socket"; + +#define MAXBUF 1024 + +sec_t ping (int local_port, int remote_addr, int remote_port) +{ + + int sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (sock == -1) { + fprintf (stderr, "ping error: socket\n"); + return none_e; + } + + struct sockaddr_in local = { 0 }; + local.sin_family = AF_INET; + local.sin_port = htons (local_port); + local.sin_addr.s_addr = htonl (INADDR_ANY); + + if (bind (sock, (struct sockaddr *)&local, sizeof (local)) == -1) { + fprintf (stderr, "ping error: bind\n"); + return none_e; + } + + struct sockaddr_in remote = { 0 }; + remote.sin_family = AF_INET; + remote.sin_port = htons (remote_port); + remote.sin_addr.s_addr = htonl (remote_addr); + + printf ("Sending ping...\n"); + for (int i = 0; i < nb_measurements; i++) { + + char buffer[MAXBUF] = { 0 }; + sprintf (buffer, "ping %d", i); + + mtime_t ts1; + sys_timestamp (&ts1); + + if (sendto (sock, buffer, strlen (buffer) + 1, 0, (struct sockaddr *)&remote, sizeof (remote)) == -1) { + fprintf (stderr, "ping error: sendto (%d)\n", i); + return none_e; + } + //printf ("sendto '%s'\n", buffer); + + int len = recv (sock, buffer, MAXBUF, 0); + if (len == -1) { + fprintf (stderr, "ping error: recv_from (%d)\n", i); + return none_e; + } + //printf ("recv_from '%s'\n", buffer); + + mtime_t ts2; + sys_timestamp (&ts2); + deltas[i] = diff_timestamp (&ts2, &ts1); + } + + close (sock); + + return nsec_e; +} + +sec_t pong (int local_port, int remote_addr, int remote_port) +{ + + int sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (sock == -1) { + fprintf (stderr, "pong error: socket\n"); + return none_e; + } + + struct sockaddr_in local = { 0 }; + local.sin_family = AF_INET; + local.sin_port = htons (local_port); + local.sin_addr.s_addr = htonl (INADDR_ANY); + + if (bind (sock, (struct sockaddr *)&local, sizeof (local)) == -1) { + fprintf (stderr, "pong error: bind\n"); + return none_e; + } + + struct sockaddr_in remote = { 0 }; + remote.sin_family = AF_INET; + remote.sin_port = htons (remote_port); + remote.sin_addr.s_addr = htonl (remote_addr); + + printf ("Sending pong...\n"); + for (int i = 0; i < nb_measurements; i++) { + + char buffer[MAXBUF] = { 0 }; + + int len = recv (sock, buffer, MAXBUF, 0); + if (len == -1) { + fprintf (stderr, "pong error: recv_from (%d)\n", i); + return none_e; + } + //printf ("recv_from '%s'\n", buffer); + + if (sendto (sock, buffer, len, 0, (struct sockaddr *)&remote, sizeof (remote)) == -1) { + fprintf (stderr, "pong error: sendto (%d)\n", i); + return none_e; + } + //printf ("sendto '%s'\n", buffer); + } + + close (sock); + + return nsec_e; +} + +int get_ip (char *hostname) { + struct hostent *he = gethostbyname (hostname); + if (he == NULL) { + fprintf (stderr, "error: gethostbyname (%s)\n", hostname); + return -1; + } + struct in_addr **addr_list = (struct in_addr **) he->h_addr_list; + return ntohl (addr_list[0]->s_addr); +} + +sec_t test (unsigned int *buffer, int nb) +{ + char *local_host = "localhost"; + int local_port = 1024; + char *remote_host = "localhost"; + int remote_port = 1025; + + /* set global variables */ + + deltas = buffer; + nb_measurements = nb; + + /* udp socket test */ + int local_ip = get_ip (local_host); + if (local_ip == -1) { + return none_e; + } + int remote_ip = get_ip (remote_host); + if (remote_ip == -1) { + return none_e; + } + + pid_t pid = fork (); + if (pid == -1) { + fprintf (stderr, "error: fork\n"); + return none_e; + } else if (pid == 0) { + pong (remote_port, local_ip, local_port); + exit (0); + } + + sec_t rc = ping (local_port, remote_ip, remote_port); + + if (kill (pid, SIGTERM) == 0) { + int wstatus; + if (waitpid (pid, &wstatus, WUNTRACED | WCONTINUED) == -1) { + fprintf (stderr, "error: waitpid\n"); + } + } + + return rc; +}