aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2017-10-10 08:50:11 +0800
committerHarald Welte <laforge@gnumonks.org>2017-10-14 08:17:07 +0200
commit73abc38dc56d6431f43673d995d6e20f562834b4 (patch)
treebf1976d52e0f2394558dc9fbda2bce6ef87bd807
parentbe4baa6d97e259514ff32f9cd3bd325aa572cbde (diff)
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
-rw-r--r--sgsnemu/cmdline.c84
-rw-r--r--sgsnemu/cmdline.ggo1
-rw-r--r--sgsnemu/cmdline.h8
-rw-r--r--sgsnemu/sgsnemu.c8
4 files changed, 90 insertions, 11 deletions
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},
@@ -1355,6 +1397,22 @@ cmdline_parser_internal(int argc, char **argv,
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
(long_options[option_index].name,
@@ -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);