From 73abc38dc56d6431f43673d995d6e20f562834b4 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Tue, 10 Oct 2017 08:50:11 +0800 Subject: sgsnemu: Add '--tun-device' option to specify TUN device name This way, multiple sgsnemu instances can be runnig in parallel, each of them creating a different tun device for their respective PDP context Change-Id: Id12fbadf924a60db255b6d51b9f647aa51dd2e16 --- sgsnemu/cmdline.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++------- sgsnemu/cmdline.ggo | 1 + sgsnemu/cmdline.h | 8 +++++ sgsnemu/sgsnemu.c | 8 ++++- 4 files changed, 90 insertions(+), 11 deletions(-) (limited to 'sgsnemu') diff --git a/sgsnemu/cmdline.c b/sgsnemu/cmdline.c index 60c0a25..441322b 100644 --- a/sgsnemu/cmdline.c +++ b/sgsnemu/cmdline.c @@ -70,6 +70,7 @@ const char *gengetopt_args_info_help[] = { " --defaultroute Create default route (default=off)", " --ipup=STRING Script to run after link-up", " --ipdown=STRING Script to run after link-down", + " --tun-device=STRING Name of the local network interface", " --pinghost=STRING Ping remote host", " --pingrate=INT Number of ping req per second (default=`1')", " --pingsize=INT Number of ping data bytes (default=`56')", @@ -94,6 +95,9 @@ cmdline_parser_internal(int argc, char **argv, struct cmdline_parser_params *params, const char *additional_error); +static int +cmdline_parser_required2(struct gengetopt_args_info *args_info, + const char *prog_name, const char *additional_error); struct line_list { char *string_arg; struct line_list *next; @@ -156,6 +160,7 @@ void clear_given(struct gengetopt_args_info *args_info) args_info->defaultroute_given = 0; args_info->ipup_given = 0; args_info->ipdown_given = 0; + args_info->tun_device_given = 0; args_info->pinghost_given = 0; args_info->pingrate_given = 0; args_info->pingsize_given = 0; @@ -233,6 +238,8 @@ void clear_args(struct gengetopt_args_info *args_info) args_info->ipup_orig = NULL; args_info->ipdown_arg = NULL; args_info->ipdown_orig = NULL; + args_info->tun_device_arg = NULL; + args_info->tun_device_orig = NULL; args_info->pinghost_arg = NULL; args_info->pinghost_orig = NULL; args_info->pingrate_arg = 1; @@ -288,13 +295,14 @@ void init_args_info(struct gengetopt_args_info *args_info) args_info->defaultroute_help = gengetopt_args_info_help[33]; args_info->ipup_help = gengetopt_args_info_help[34]; args_info->ipdown_help = gengetopt_args_info_help[35]; - args_info->pinghost_help = gengetopt_args_info_help[36]; - args_info->pingrate_help = gengetopt_args_info_help[37]; - args_info->pingsize_help = gengetopt_args_info_help[38]; - args_info->pingcount_help = gengetopt_args_info_help[39]; - args_info->pingquiet_help = gengetopt_args_info_help[40]; - args_info->no_tx_gpdu_seq_help = gengetopt_args_info_help[41]; - args_info->pdp_type_help = gengetopt_args_info_help[42]; + args_info->tun_device_help = gengetopt_args_info_help[36]; + args_info->pinghost_help = gengetopt_args_info_help[37]; + args_info->pingrate_help = gengetopt_args_info_help[38]; + args_info->pingsize_help = gengetopt_args_info_help[39]; + args_info->pingcount_help = gengetopt_args_info_help[40]; + args_info->pingquiet_help = gengetopt_args_info_help[41]; + args_info->no_tx_gpdu_seq_help = gengetopt_args_info_help[42]; + args_info->pdp_type_help = gengetopt_args_info_help[43]; } @@ -419,6 +427,8 @@ static void cmdline_parser_release(struct gengetopt_args_info *args_info) free_string_field(&(args_info->ipup_orig)); free_string_field(&(args_info->ipdown_arg)); free_string_field(&(args_info->ipdown_orig)); + free_string_field(&(args_info->tun_device_arg)); + free_string_field(&(args_info->tun_device_orig)); free_string_field(&(args_info->pinghost_arg)); free_string_field(&(args_info->pinghost_orig)); free_string_field(&(args_info->pingrate_orig)); @@ -529,6 +539,9 @@ int cmdline_parser_dump(FILE * outfile, struct gengetopt_args_info *args_info) write_into_file(outfile, "ipup", args_info->ipup_orig, 0); if (args_info->ipdown_given) write_into_file(outfile, "ipdown", args_info->ipdown_orig, 0); + if (args_info->tun_device_given) + write_into_file(outfile, "tun-device", + args_info->tun_device_orig, 0); if (args_info->pinghost_given) write_into_file(outfile, "pinghost", args_info->pinghost_orig, 0); @@ -640,9 +653,37 @@ 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; + int result = EXIT_SUCCESS; + + if (cmdline_parser_required2(args_info, prog_name, 0) > 0) + result = EXIT_FAILURE; + + if (result == EXIT_FAILURE) { + cmdline_parser_free(args_info); + exit(EXIT_FAILURE); + } + + return result; +} + +int +cmdline_parser_required2(struct gengetopt_args_info *args_info, + const char *prog_name, const char *additional_error) +{ + int error_occurred = 0; + FIX_UNUSED(additional_error); + + /* checks for required options */ + + /* checks for dependences among options */ + if (args_info->tun_device_given && !args_info->createif_given) { + fprintf(stderr, + "%s: '--tun-device' option depends on option 'createif'%s\n", + prog_name, (additional_error ? additional_error : "")); + error_occurred = 1; + } + + return error_occurred; } static char *package_name = 0; @@ -837,6 +878,7 @@ cmdline_parser_internal(int argc, char **argv, {"defaultroute", 0, NULL, 0}, {"ipup", 1, NULL, 0}, {"ipdown", 1, NULL, 0}, + {"tun-device", 1, NULL, 0}, {"pinghost", 1, NULL, 0}, {"pingrate", 1, NULL, 0}, {"pingsize", 1, NULL, 0}, @@ -1354,6 +1396,22 @@ cmdline_parser_internal(int argc, char **argv, "ipdown", '-', additional_error)) goto failure; + } + /* Name of the local network interface. */ + else if (strcmp + (long_options[option_index].name, + "tun-device") == 0) { + + if (update_arg + ((void *)&(args_info->tun_device_arg), + &(args_info->tun_device_orig), + &(args_info->tun_device_given), + &(local_args_info.tun_device_given), + optarg, 0, 0, ARG_STRING, check_ambiguity, + override, 0, 0, "tun-device", '-', + additional_error)) + goto failure; + } /* Ping remote host. */ else if (strcmp @@ -1460,6 +1518,12 @@ cmdline_parser_internal(int argc, char **argv, } /* switch */ } /* while */ + if (check_required) { + error_occurred += + cmdline_parser_required2(args_info, argv[0], + additional_error); + } + cmdline_parser_release(&local_args_info); if (error_occurred) diff --git a/sgsnemu/cmdline.ggo b/sgsnemu/cmdline.ggo index d8b3c26..7592eb5 100644 --- a/sgsnemu/cmdline.ggo +++ b/sgsnemu/cmdline.ggo @@ -54,6 +54,7 @@ option "net" n "Network address for local interface" string no option "defaultroute" - "Create default route" flag off option "ipup" - "Script to run after link-up" string no option "ipdown" - "Script to run after link-down" string no +option "tun-device" - "Name of the local network interface" string dependon="createif" no option "pinghost" - "Ping remote host" string no option "pingrate" - "Number of ping req per second" int default="1" no diff --git a/sgsnemu/cmdline.h b/sgsnemu/cmdline.h index 1accfd0..9dc210e 100644 --- a/sgsnemu/cmdline.h +++ b/sgsnemu/cmdline.h @@ -236,6 +236,12 @@ extern "C" { /**< @brief Script to run after link-down original value given at command line. */ const char *ipdown_help; /**< @brief Script to run after link-down help description. */ + char *tun_device_arg; + /**< @brief Name of the local network interface. */ + char *tun_device_orig; + /**< @brief Name of the local network interface original value given at command line. */ + const char *tun_device_help; + /**< @brief Name of the local network interface help description. */ char *pinghost_arg; /**< @brief Ping remote host. */ char *pinghost_orig; @@ -347,6 +353,8 @@ extern "C" { /**< @brief Whether ipup was given. */ unsigned int ipdown_given; /**< @brief Whether ipdown was given. */ + unsigned int tun_device_given; + /**< @brief Whether tun-device was given. */ unsigned int pinghost_given; /**< @brief Whether pinghost was given. */ unsigned int pingrate_given; diff --git a/sgsnemu/sgsnemu.c b/sgsnemu/sgsnemu.c index fa295da..c83aebd 100644 --- a/sgsnemu/sgsnemu.c +++ b/sgsnemu/sgsnemu.c @@ -84,6 +84,7 @@ int echoversion = 1; /* First try this version */ struct { int debug; /* Print debug messages */ int createif; /* Create local network interface */ + char *tun_dev_name; struct in_addr netaddr, destaddr, net; /* Network interface */ size_t prefixlen; char *ipup, *ipdown; /* Filename of scripts */ @@ -289,6 +290,8 @@ int process_options(int argc, char **argv) printf("contexts: %d\n", args_info.contexts_arg); printf("timelimit: %d\n", args_info.timelimit_arg); printf("createif: %d\n", args_info.createif_flag); + if (args_info.tun_device_arg) + printf("tun-device: %d\n", args_info.tun_device_arg); if (args_info.ipup_arg) printf("ipup: %s\n", args_info.ipup_arg); if (args_info.ipdown_arg) @@ -345,6 +348,8 @@ int process_options(int argc, char **argv) printf("contexts: %d\n", args_info.contexts_arg); printf("timelimit: %d\n", args_info.timelimit_arg); printf("createif: %d\n", args_info.createif_flag); + if (args_info.tun_device_arg) + printf("tun-device: %d\n", args_info.tun_device_arg); if (args_info.ipup_arg) printf("ipup: %s\n", args_info.ipup_arg); if (args_info.ipdown_arg) @@ -863,6 +868,7 @@ int process_options(int argc, char **argv) /* createif */ options.createif = args_info.createif_flag; + options.tun_dev_name = args_info.tun_device_arg; /* net */ /* Store net as in_addr net and mask */ @@ -1525,7 +1531,7 @@ int main(int argc, char **argv) if (options.createif) { printf("Setting up interface\n"); /* Create a tunnel interface */ - if (tun_new((struct tun_t **)&tun, NULL)) { + if (tun_new((struct tun_t **)&tun, options.tun_dev_name)) { SYS_ERR(DSGSN, LOGL_ERROR, 0, "Failed to create tun"); exit(1); -- cgit v1.2.3