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
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 @@
 	"      --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 @@
 			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 @@
 	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 @@
 	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 @@
 	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 @@
 	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 @@
 		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 @@
 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 @@
 			{"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 @@
 					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 @@
 		}		/* 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)