aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sgsnemu/cmdline.c422
-rw-r--r--sgsnemu/cmdline.ggo16
-rw-r--r--sgsnemu/cmdline.h30
-rw-r--r--sgsnemu/sgsnemu.c608
4 files changed, 809 insertions, 267 deletions
diff --git a/sgsnemu/cmdline.c b/sgsnemu/cmdline.c
index d8f51df..836e160 100644
--- a/sgsnemu/cmdline.c
+++ b/sgsnemu/cmdline.c
@@ -1,7 +1,7 @@
/*
- File autogenerated by gengetopt version 2.8
+ File autogenerated by gengetopt version 2.8rc
generated with the following command:
- gengetopt --conf-parser
+ ../../gengetopt-2.8rc/src/gengetopt --conf-parser
The developers of gengetopt consider the fixed text that goes in all
gengetopt output files to be in the public domain:
@@ -52,10 +52,7 @@ cmdline_parser_print_help (void)
printf(" --dns=STRING DNS Server to use\n");
printf(" -lSTRING --listen=STRING Local interface\n");
printf(" -rSTRING --remote=STRING Remote host\n");
- printf(" -nSTRING --net=STRING Network (default='192.168.0.0')\n");
- printf(" --mask=STRING Network mask (default='255.255.255.0')\n");
printf(" --contexts=INT Number of contexts (default='1')\n");
- printf(" --static Allocate static tun ifterface (default=off)\n");
printf(" --timelimit=INT Exit after timelimit seconds (default='0')\n");
printf(" -aSTRING --apn=STRING Access point name (default='internet')\n");
printf(" -iSTRING --imsi=STRING IMSI (default='240010123456789')\n");
@@ -63,6 +60,17 @@ cmdline_parser_print_help (void)
printf(" -qINT --qos=INT Requested quality of service (default='0x0b921f')\n");
printf(" -uSTRING --uid=STRING Login user ID (default='mig')\n");
printf(" -pSTRING --pwd=STRING Login password (default='hemmelig')\n");
+ printf(" --createif Create local network interface (default=off)\n");
+ printf(" --ipup=STRING Script to run after link-up\n");
+ printf(" --ipdown=STRING Script to run after link-down\n");
+ printf(" --defaultroute Add default route after link-up (default=off)\n");
+ printf(" --net=STRING Network (default='0.0.0.0')\n");
+ printf(" --mask=STRING Network mask (default='0.0.0.0')\n");
+ printf(" --pinghost=STRING Ping remote host\n");
+ printf(" --pingrate=INT Number of ping req per second (default='1')\n");
+ printf(" --pingsize=INT Number of ping data bytes (default='56')\n");
+ printf(" --pingcount=INT Number of ping req to send (default='0')\n");
+ printf(" --pingquiet Do not print ping packet info (default=off)\n");
}
@@ -96,10 +104,7 @@ cmdline_parser (int argc, char * const *argv, struct gengetopt_args_info *args_i
args_info->dns_given = 0 ;
args_info->listen_given = 0 ;
args_info->remote_given = 0 ;
- args_info->net_given = 0 ;
- args_info->mask_given = 0 ;
args_info->contexts_given = 0 ;
- args_info->static_given = 0 ;
args_info->timelimit_given = 0 ;
args_info->apn_given = 0 ;
args_info->imsi_given = 0 ;
@@ -107,6 +112,17 @@ cmdline_parser (int argc, char * const *argv, struct gengetopt_args_info *args_i
args_info->qos_given = 0 ;
args_info->uid_given = 0 ;
args_info->pwd_given = 0 ;
+ args_info->createif_given = 0 ;
+ args_info->ipup_given = 0 ;
+ args_info->ipdown_given = 0 ;
+ args_info->defaultroute_given = 0 ;
+ args_info->net_given = 0 ;
+ args_info->mask_given = 0 ;
+ args_info->pinghost_given = 0 ;
+ args_info->pingrate_given = 0 ;
+ args_info->pingsize_given = 0 ;
+ args_info->pingcount_given = 0 ;
+ args_info->pingquiet_given = 0 ;
#define clear_args() { \
args_info->fg_flag = 0;\
args_info->debug_flag = 0;\
@@ -116,10 +132,7 @@ cmdline_parser (int argc, char * const *argv, struct gengetopt_args_info *args_i
args_info->dns_arg = NULL; \
args_info->listen_arg = NULL; \
args_info->remote_arg = NULL; \
- args_info->net_arg = strdup("192.168.0.0") ;\
- args_info->mask_arg = strdup("255.255.255.0") ;\
args_info->contexts_arg = 1 ;\
- args_info->static_flag = 0;\
args_info->timelimit_arg = 0 ;\
args_info->apn_arg = strdup("internet") ;\
args_info->imsi_arg = strdup("240010123456789") ;\
@@ -127,6 +140,17 @@ cmdline_parser (int argc, char * const *argv, struct gengetopt_args_info *args_i
args_info->qos_arg = 0x0b921f ;\
args_info->uid_arg = strdup("mig") ;\
args_info->pwd_arg = strdup("hemmelig") ;\
+ args_info->createif_flag = 0;\
+ args_info->ipup_arg = NULL; \
+ args_info->ipdown_arg = NULL; \
+ args_info->defaultroute_flag = 0;\
+ args_info->net_arg = strdup("0.0.0.0") ;\
+ args_info->mask_arg = strdup("0.0.0.0") ;\
+ args_info->pinghost_arg = NULL; \
+ args_info->pingrate_arg = 1 ;\
+ args_info->pingsize_arg = 56 ;\
+ args_info->pingcount_arg = 0 ;\
+ args_info->pingquiet_flag = 0;\
}
clear_args();
@@ -151,10 +175,7 @@ cmdline_parser (int argc, char * const *argv, struct gengetopt_args_info *args_i
{ "dns", 1, NULL, 0 },
{ "listen", 1, NULL, 'l' },
{ "remote", 1, NULL, 'r' },
- { "net", 1, NULL, 'n' },
- { "mask", 1, NULL, 0 },
{ "contexts", 1, NULL, 0 },
- { "static", 0, NULL, 0 },
{ "timelimit", 1, NULL, 0 },
{ "apn", 1, NULL, 'a' },
{ "imsi", 1, NULL, 'i' },
@@ -162,10 +183,21 @@ cmdline_parser (int argc, char * const *argv, struct gengetopt_args_info *args_i
{ "qos", 1, NULL, 'q' },
{ "uid", 1, NULL, 'u' },
{ "pwd", 1, NULL, 'p' },
+ { "createif", 0, NULL, 0 },
+ { "ipup", 1, NULL, 0 },
+ { "ipdown", 1, NULL, 0 },
+ { "defaultroute", 0, NULL, 0 },
+ { "net", 1, NULL, 0 },
+ { "mask", 1, NULL, 0 },
+ { "pinghost", 1, NULL, 0 },
+ { "pingrate", 1, NULL, 0 },
+ { "pingsize", 1, NULL, 0 },
+ { "pingcount", 1, NULL, 0 },
+ { "pingquiet", 0, NULL, 0 },
{ NULL, 0, NULL, 0 }
};
- c = getopt_long (argc, argv, "hVfdc:l:r:n:a:i:m:q:u:p:", long_options, &option_index);
+ c = getopt_long (argc, argv, "hVfdc:l:r:a:i:m:q:u:p:", long_options, &option_index);
if (c == -1) break; /* Exit from `while (1)' loop. */
@@ -236,17 +268,6 @@ cmdline_parser (int argc, char * const *argv, struct gengetopt_args_info *args_i
args_info->remote_arg = strdup (optarg);
break;
- case 'n': /* Network. */
- if (args_info->net_given)
- {
- fprintf (stderr, "%s: `--net' (`-n') option given more than once\n", PACKAGE);
- clear_args ();
- exit (EXIT_FAILURE);
- }
- args_info->net_given = 1;
- args_info->net_arg = strdup (optarg);
- break;
-
case 'a': /* Access point name. */
if (args_info->apn_given)
{
@@ -354,6 +375,97 @@ cmdline_parser (int argc, char * const *argv, struct gengetopt_args_info *args_i
args_info->dns_arg = strdup (optarg);
break;
}
+ /* Number of contexts. */
+ else if (strcmp (long_options[option_index].name, "contexts") == 0)
+ {
+ if (args_info->contexts_given)
+ {
+ fprintf (stderr, "%s: `--contexts' option given more than once\n", PACKAGE);
+ clear_args ();
+ exit (EXIT_FAILURE);
+ }
+ args_info->contexts_given = 1;
+ args_info->contexts_arg = strtol (optarg,&stop_char,0);
+ break;
+ }
+ /* Exit after timelimit seconds. */
+ else if (strcmp (long_options[option_index].name, "timelimit") == 0)
+ {
+ if (args_info->timelimit_given)
+ {
+ fprintf (stderr, "%s: `--timelimit' option given more than once\n", PACKAGE);
+ clear_args ();
+ exit (EXIT_FAILURE);
+ }
+ args_info->timelimit_given = 1;
+ args_info->timelimit_arg = strtol (optarg,&stop_char,0);
+ break;
+ }
+ /* Create local network interface. */
+ else if (strcmp (long_options[option_index].name, "createif") == 0)
+ {
+ if (args_info->createif_given)
+ {
+ fprintf (stderr, "%s: `--createif' option given more than once\n", PACKAGE);
+ clear_args ();
+ exit (EXIT_FAILURE);
+ }
+ args_info->createif_given = 1;
+ args_info->createif_flag = !(args_info->createif_flag);
+ break;
+ }
+ /* Script to run after link-up. */
+ else if (strcmp (long_options[option_index].name, "ipup") == 0)
+ {
+ if (args_info->ipup_given)
+ {
+ fprintf (stderr, "%s: `--ipup' option given more than once\n", PACKAGE);
+ clear_args ();
+ exit (EXIT_FAILURE);
+ }
+ args_info->ipup_given = 1;
+ args_info->ipup_arg = strdup (optarg);
+ break;
+ }
+ /* Script to run after link-down. */
+ else if (strcmp (long_options[option_index].name, "ipdown") == 0)
+ {
+ if (args_info->ipdown_given)
+ {
+ fprintf (stderr, "%s: `--ipdown' option given more than once\n", PACKAGE);
+ clear_args ();
+ exit (EXIT_FAILURE);
+ }
+ args_info->ipdown_given = 1;
+ args_info->ipdown_arg = strdup (optarg);
+ break;
+ }
+ /* Add default route after link-up. */
+ else if (strcmp (long_options[option_index].name, "defaultroute") == 0)
+ {
+ if (args_info->defaultroute_given)
+ {
+ fprintf (stderr, "%s: `--defaultroute' option given more than once\n", PACKAGE);
+ clear_args ();
+ exit (EXIT_FAILURE);
+ }
+ args_info->defaultroute_given = 1;
+ args_info->defaultroute_flag = !(args_info->defaultroute_flag);
+ break;
+ }
+ /* Network. */
+ else if (strcmp (long_options[option_index].name, "net") == 0)
+ {
+ if (args_info->net_given)
+ {
+ fprintf (stderr, "%s: `--net' option given more than once\n", PACKAGE);
+ clear_args ();
+ exit (EXIT_FAILURE);
+ }
+ args_info->net_given = 1;
+ args_info->net_arg = strdup (optarg);
+ break;
+ }
/* Network mask. */
else if (strcmp (long_options[option_index].name, "mask") == 0)
{
@@ -367,43 +479,69 @@ cmdline_parser (int argc, char * const *argv, struct gengetopt_args_info *args_i
args_info->mask_arg = strdup (optarg);
break;
}
- /* Number of contexts. */
- else if (strcmp (long_options[option_index].name, "contexts") == 0)
+ /* Ping remote host. */
+ else if (strcmp (long_options[option_index].name, "pinghost") == 0)
{
- if (args_info->contexts_given)
+ if (args_info->pinghost_given)
{
- fprintf (stderr, "%s: `--contexts' option given more than once\n", PACKAGE);
+ fprintf (stderr, "%s: `--pinghost' option given more than once\n", PACKAGE);
clear_args ();
exit (EXIT_FAILURE);
}
- args_info->contexts_given = 1;
- args_info->contexts_arg = strtol (optarg,&stop_char,0);
+ args_info->pinghost_given = 1;
+ args_info->pinghost_arg = strdup (optarg);
break;
}
- /* Allocate static tun ifterface. */
- else if (strcmp (long_options[option_index].name, "static") == 0)
+ /* Number of ping req per second. */
+ else if (strcmp (long_options[option_index].name, "pingrate") == 0)
{
- if (args_info->static_given)
+ if (args_info->pingrate_given)
{
- fprintf (stderr, "%s: `--static' option given more than once\n", PACKAGE);
+ fprintf (stderr, "%s: `--pingrate' option given more than once\n", PACKAGE);
clear_args ();
exit (EXIT_FAILURE);
}
- args_info->static_given = 1;
- args_info->static_flag = !(args_info->static_flag);
+ args_info->pingrate_given = 1;
+ args_info->pingrate_arg = strtol (optarg,&stop_char,0);
break;
}
- /* Exit after timelimit seconds. */
- else if (strcmp (long_options[option_index].name, "timelimit") == 0)
+ /* Number of ping data bytes. */
+ else if (strcmp (long_options[option_index].name, "pingsize") == 0)
{
- if (args_info->timelimit_given)
+ if (args_info->pingsize_given)
{
- fprintf (stderr, "%s: `--timelimit' option given more than once\n", PACKAGE);
+ fprintf (stderr, "%s: `--pingsize' option given more than once\n", PACKAGE);
clear_args ();
exit (EXIT_FAILURE);
}
- args_info->timelimit_given = 1;
- args_info->timelimit_arg = strtol (optarg,&stop_char,0);
+ args_info->pingsize_given = 1;
+ args_info->pingsize_arg = strtol (optarg,&stop_char,0);
+ break;
+ }
+ /* Number of ping req to send. */
+ else if (strcmp (long_options[option_index].name, "pingcount") == 0)
+ {
+ if (args_info->pingcount_given)
+ {
+ fprintf (stderr, "%s: `--pingcount' option given more than once\n", PACKAGE);
+ clear_args ();
+ exit (EXIT_FAILURE);
+ }
+ args_info->pingcount_given = 1;
+ args_info->pingcount_arg = strtol (optarg,&stop_char,0);
+ break;
+ }
+ /* Do not print ping packet info. */
+ else if (strcmp (long_options[option_index].name, "pingquiet") == 0)
+ {
+ if (args_info->pingquiet_given)
+ {
+ fprintf (stderr, "%s: `--pingquiet' option given more than once\n", PACKAGE);
+ clear_args ();
+ exit (EXIT_FAILURE);
+ }
+ args_info->pingquiet_given = 1;
+ args_info->pingquiet_flag = !(args_info->pingquiet_flag);
break;
}
@@ -593,38 +731,6 @@ cmdline_parser_configfile (char * const filename, struct gengetopt_args_info *ar
}
continue;
}
- if (!strcmp(fopt, "net"))
- {
- if (override || !args_info->net_given)
- {
- args_info->net_given = 1;
- if (fnum == 2)
- args_info->net_arg = strdup (farg);
- else
- {
- fprintf (stderr, "%s:%d: required <option_name> <option_val>\n",
- filename, line_num);
- exit (EXIT_FAILURE);
- }
- }
- continue;
- }
- if (!strcmp(fopt, "mask"))
- {
- if (override || !args_info->mask_given)
- {
- args_info->mask_given = 1;
- if (fnum == 2)
- args_info->mask_arg = strdup (farg);
- else
- {
- fprintf (stderr, "%s:%d: required <option_name> <option_val>\n",
- filename, line_num);
- exit (EXIT_FAILURE);
- }
- }
- continue;
- }
if (!strcmp(fopt, "contexts"))
{
if (override || !args_info->contexts_given)
@@ -641,15 +747,6 @@ cmdline_parser_configfile (char * const filename, struct gengetopt_args_info *ar
}
continue;
}
- if (!strcmp(fopt, "static"))
- {
- if (override || !args_info->static_given)
- {
- args_info->static_given = 1;
- args_info->static_flag = !(args_info->static_flag);
- }
- continue;
- }
if (!strcmp(fopt, "timelimit"))
{
if (override || !args_info->timelimit_given)
@@ -762,6 +859,161 @@ cmdline_parser_configfile (char * const filename, struct gengetopt_args_info *ar
}
continue;
}
+ if (!strcmp(fopt, "createif"))
+ {
+ if (override || !args_info->createif_given)
+ {
+ args_info->createif_given = 1;
+ args_info->createif_flag = !(args_info->createif_flag);
+ }
+ continue;
+ }
+ if (!strcmp(fopt, "ipup"))
+ {
+ if (override || !args_info->ipup_given)
+ {
+ args_info->ipup_given = 1;
+ if (fnum == 2)
+ args_info->ipup_arg = strdup (farg);
+ else
+ {
+ fprintf (stderr, "%s:%d: required <option_name> <option_val>\n",
+ filename, line_num);
+ exit (EXIT_FAILURE);
+ }
+ }
+ continue;
+ }
+ if (!strcmp(fopt, "ipdown"))
+ {
+ if (override || !args_info->ipdown_given)
+ {
+ args_info->ipdown_given = 1;
+ if (fnum == 2)
+ args_info->ipdown_arg = strdup (farg);
+ else
+ {
+ fprintf (stderr, "%s:%d: required <option_name> <option_val>\n",
+ filename, line_num);
+ exit (EXIT_FAILURE);
+ }
+ }
+ continue;
+ }
+ if (!strcmp(fopt, "defaultroute"))
+ {
+ if (override || !args_info->defaultroute_given)
+ {
+ args_info->defaultroute_given = 1;
+ args_info->defaultroute_flag = !(args_info->defaultroute_flag);
+ }
+ continue;
+ }
+ if (!strcmp(fopt, "net"))
+ {
+ if (override || !args_info->net_given)
+ {
+ args_info->net_given = 1;
+ if (fnum == 2)
+ args_info->net_arg = strdup (farg);
+ else
+ {
+ fprintf (stderr, "%s:%d: required <option_name> <option_val>\n",
+ filename, line_num);
+ exit (EXIT_FAILURE);
+ }
+ }
+ continue;
+ }
+ if (!strcmp(fopt, "mask"))
+ {
+ if (override || !args_info->mask_given)
+ {
+ args_info->mask_given = 1;
+ if (fnum == 2)
+ args_info->mask_arg = strdup (farg);
+ else
+ {
+ fprintf (stderr, "%s:%d: required <option_name> <option_val>\n",
+ filename, line_num);
+ exit (EXIT_FAILURE);
+ }
+ }
+ continue;
+ }
+ if (!strcmp(fopt, "pinghost"))
+ {
+ if (override || !args_info->pinghost_given)
+ {
+ args_info->pinghost_given = 1;
+ if (fnum == 2)
+ args_info->pinghost_arg = strdup (farg);
+ else
+ {
+ fprintf (stderr, "%s:%d: required <option_name> <option_val>\n",
+ filename, line_num);
+ exit (EXIT_FAILURE);
+ }
+ }
+ continue;
+ }
+ if (!strcmp(fopt, "pingrate"))
+ {
+ if (override || !args_info->pingrate_given)
+ {
+ args_info->pingrate_given = 1;
+ if (fnum == 2)
+ args_info->pingrate_arg = strtol (farg,&stop_char,0);
+ else
+ {
+ fprintf (stderr, "%s:%d: required <option_name> <option_val>\n",
+ filename, line_num);
+ exit (EXIT_FAILURE);
+ }
+ }
+ continue;
+ }
+ if (!strcmp(fopt, "pingsize"))
+ {
+ if (override || !args_info->pingsize_given)
+ {
+ args_info->pingsize_given = 1;
+ if (fnum == 2)
+ args_info->pingsize_arg = strtol (farg,&stop_char,0);
+ else
+ {
+ fprintf (stderr, "%s:%d: required <option_name> <option_val>\n",
+ filename, line_num);
+ exit (EXIT_FAILURE);
+ }
+ }
+ continue;
+ }
+ if (!strcmp(fopt, "pingcount"))
+ {
+ if (override || !args_info->pingcount_given)
+ {
+ args_info->pingcount_given = 1;
+ if (fnum == 2)
+ args_info->pingcount_arg = strtol (farg,&stop_char,0);
+ else
+ {
+ fprintf (stderr, "%s:%d: required <option_name> <option_val>\n",
+ filename, line_num);
+ exit (EXIT_FAILURE);
+ }
+ }
+ continue;
+ }
+ if (!strcmp(fopt, "pingquiet"))
+ {
+ if (override || !args_info->pingquiet_given)
+ {
+ args_info->pingquiet_given = 1;
+ args_info->pingquiet_flag = !(args_info->pingquiet_flag);
+ }
+ continue;
+ }
/* Tried all known options. This one is unknown! */
diff --git a/sgsnemu/cmdline.ggo b/sgsnemu/cmdline.ggo
index 6b21818..7d5fcfb 100644
--- a/sgsnemu/cmdline.ggo
+++ b/sgsnemu/cmdline.ggo
@@ -21,11 +21,8 @@ option "statedir" - "Directory of nonvolatile data" string default="./" no
option "dns" - "DNS Server to use" string no
option "listen" l "Local interface" string no
option "remote" r "Remote host" string no
-option "net" n "Network" string default="192.168.0.0" no
-option "mask" - "Network mask" string default="255.255.255.0" no
option "contexts" - "Number of contexts" int default="1" no
-option "static" - "Allocate static tun ifterface" flag off
option "timelimit" - "Exit after timelimit seconds" int default="0" no
option "apn" a "Access point name" string default="internet" no
@@ -35,3 +32,16 @@ option "qos" q "Requested quality of service" int default="0x0b921
option "uid" u "Login user ID" string default="mig" no
option "pwd" p "Login password" string default="hemmelig" no
+option "createif" - "Create local network interface" flag off
+option "ipup" - "Script to run after link-up" string no
+option "ipdown" - "Script to run after link-down" string no
+option "defaultroute" - "Add default route after link-up" flag off
+option "net" - "Network" string default="0.0.0.0" no
+option "mask" - "Network mask" string default="0.0.0.0" no
+
+option "pinghost" - "Ping remote host" string no
+option "pingrate" - "Number of ping req per second" int default="1" no
+option "pingsize" - "Number of ping data bytes" int default="56" no
+option "pingcount" - "Number of ping req to send" int default="0" no
+option "pingquiet" - "Do not print ping packet info" flag off
+
diff --git a/sgsnemu/cmdline.h b/sgsnemu/cmdline.h
index c29caf0..475ea1c 100644
--- a/sgsnemu/cmdline.h
+++ b/sgsnemu/cmdline.h
@@ -1,6 +1,6 @@
/* cmdline.h */
-/* File autogenerated by gengetopt version 2.8 */
+/* File autogenerated by gengetopt version 2.8rc */
#ifndef _cmdline_h
#define _cmdline_h
@@ -28,10 +28,7 @@ struct gengetopt_args_info
char * dns_arg; /* DNS Server to use. */
char * listen_arg; /* Local interface. */
char * remote_arg; /* Remote host. */
- char * net_arg; /* Network (default='192.168.0.0'). */
- char * mask_arg; /* Network mask (default='255.255.255.0'). */
int contexts_arg; /* Number of contexts (default='1'). */
- int static_flag; /* Allocate static tun ifterface (default=off). */
int timelimit_arg; /* Exit after timelimit seconds (default='0'). */
char * apn_arg; /* Access point name (default='internet'). */
char * imsi_arg; /* IMSI (default='240010123456789'). */
@@ -39,6 +36,17 @@ struct gengetopt_args_info
int qos_arg; /* Requested quality of service (default='0x0b921f'). */
char * uid_arg; /* Login user ID (default='mig'). */
char * pwd_arg; /* Login password (default='hemmelig'). */
+ int createif_flag; /* Create local network interface (default=off). */
+ char * ipup_arg; /* Script to run after link-up. */
+ char * ipdown_arg; /* Script to run after link-down. */
+ int defaultroute_flag; /* Add default route after link-up (default=off). */
+ char * net_arg; /* Network (default='0.0.0.0'). */
+ char * mask_arg; /* Network mask (default='0.0.0.0'). */
+ char * pinghost_arg; /* Ping remote host. */
+ int pingrate_arg; /* Number of ping req per second (default='1'). */
+ int pingsize_arg; /* Number of ping data bytes (default='56'). */
+ int pingcount_arg; /* Number of ping req to send (default='0'). */
+ int pingquiet_flag; /* Do not print ping packet info (default=off). */
int help_given ; /* Whether help was given. */
int version_given ; /* Whether version was given. */
@@ -50,10 +58,7 @@ struct gengetopt_args_info
int dns_given ; /* Whether dns was given. */
int listen_given ; /* Whether listen was given. */
int remote_given ; /* Whether remote was given. */
- int net_given ; /* Whether net was given. */
- int mask_given ; /* Whether mask was given. */
int contexts_given ; /* Whether contexts was given. */
- int static_given ; /* Whether static was given. */
int timelimit_given ; /* Whether timelimit was given. */
int apn_given ; /* Whether apn was given. */
int imsi_given ; /* Whether imsi was given. */
@@ -61,6 +66,17 @@ struct gengetopt_args_info
int qos_given ; /* Whether qos was given. */
int uid_given ; /* Whether uid was given. */
int pwd_given ; /* Whether pwd was given. */
+ int createif_given ; /* Whether createif was given. */
+ int ipup_given ; /* Whether ipup was given. */
+ int ipdown_given ; /* Whether ipdown was given. */
+ int defaultroute_given ; /* Whether defaultroute was given. */
+ int net_given ; /* Whether net was given. */
+ int mask_given ; /* Whether mask was given. */
+ int pinghost_given ; /* Whether pinghost was given. */
+ int pingrate_given ; /* Whether pingrate was given. */
+ int pingsize_given ; /* Whether pingsize was given. */
+ int pingcount_given ; /* Whether pingcount was given. */
+ int pingquiet_given ; /* Whether pingquiet was given. */
} ;
diff --git a/sgsnemu/sgsnemu.c b/sgsnemu/sgsnemu.c
index dd24fce..0230b55 100644
--- a/sgsnemu/sgsnemu.c
+++ b/sgsnemu/sgsnemu.c
@@ -41,6 +41,7 @@
#include <unistd.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
+#include <sys/time.h>
#include <net/if.h>
#include <features.h>
#include <errno.h>
@@ -55,6 +56,8 @@
#include "../gtp/gtp.h"
#include "cmdline.h"
+#define SGSNEMU_BUFSIZE 1024
+
/* State variable */
/* 0: Idle */
/* 1: Wait_connect */
@@ -68,107 +71,291 @@ struct tun_t *tun; /* TUN instance */
struct tun_t *tun1, *tun2; /* TUN instance for client */
int tun_fd1 = -1; /* Network file descriptor */
int tun_fd2 = -1; /* Network file descriptor */
-struct in_addr net, mask; /* Network interface */
-int stattun; /* Allocate static tun */
+/* Variables matching program configuration parameters */
int debug; /* Print debug messages */
-
-int encaps_printf(void *p, void *packet, unsigned len)
-{
+struct in_addr net, mask; /* Network interface */
+int createif; /* Create local network interface */
+char *ipup, *ipdown; /* Filename of scripts */
+int defaultroute; /* Set up default route */
+struct in_addr pinghost; /* Remote ping host */
+int pingrate, pingsize, pingcount, pingquiet;
+struct in_addr listen_, remote;
+struct in_addr dns;
+int contexts; /* Number of contexts to create */
+int timelimit; /* Number of seconds to be connected */
+
+
+/* Definitions to use for PING. Most of the ping code was derived from */
+/* the original ping program by Mike Muuss */
+
+/* IP header and ICMP echo header */
+#define CREATEPING_MAX 2048
+#define CREATEPING_IP 20
+#define CREATEPING_ICMP 8
+
+struct ip_ping {
+ u_int8_t ipver; /* Type and header length*/
+ u_int8_t tos; /* Type of Service */
+ u_int16_t length; /* Total length */
+ u_int16_t fragid; /* Identifier */
+ u_int16_t offset; /* Flags and fragment offset */
+ u_int8_t ttl; /* Time to live */
+ u_int8_t protocol; /* Protocol */
+ u_int16_t ipcheck; /* Header checksum */
+ u_int32_t src; /* Source address */
+ u_int32_t dst; /* Destination */
+ u_int8_t type; /* Type and header length*/
+ u_int8_t code; /* Code */
+ u_int16_t checksum; /* Header checksum */
+ u_int16_t ident; /* Identifier */
+ u_int16_t seq; /* Sequence number */
+ u_int8_t data[CREATEPING_MAX]; /* Data */
+} __attribute__((packed));
+
+/* Statistical values for ping */
+int nreceived = 0;
+int ntreceived = 0;
+int ntransmitted = 0;
+int tmin = 999999999;
+int tmax = 0;
+int tsum = 0;
+
+
+int encaps_printf(struct pdp_t *pdp, void *pack, unsigned len) {
int i;
printf("The packet looks like this:\n");
for( i=0; i<len; i++) {
- printf("%02x ", (unsigned char)*(char *)(packet+i));
+ printf("%02x ", (unsigned char)*(char *)(pack+i));
if (!((i+1)%16)) printf("\n");
};
- printf("\n");
+ printf("\n");
+ return 0;
}
-/* Used to write process ID to file. Assume someone else will delete */
-void log_pid(char *pidfile) {
- FILE *file;
- mode_t oldmask;
-
- oldmask = umask(022);
- file = fopen(pidfile, "w");
- umask(oldmask);
- if(!file)
- return;
- fprintf(file, "%d\n", getpid());
- fclose(file);
+char * print_ipprot(int t) {
+ switch (t) {
+ case 1: return "ICMP";
+ case 6: return "TCP";
+ case 17: return "UDP";
+ default: return "Unknown";
+ };
}
-int create_tun() {
- char buf[1024];
- char snet[100], smask[100];
+char * print_icmptype(int t) {
+ static char *ttab[] = {
+ "Echo Reply",
+ "ICMP 1",
+ "ICMP 2",
+ "Dest Unreachable",
+ "Source Quench",
+ "Redirect",
+ "ICMP 6",
+ "ICMP 7",
+ "Echo",
+ "ICMP 9",
+ "ICMP 10",
+ "Time Exceeded",
+ "Parameter Problem",
+ "Timestamp",
+ "Timestamp Reply",
+ "Info Request",
+ "Info Reply"
+ };
+ if( t < 0 || t > 16 )
+ return("OUT-OF-RANGE");
+ return(ttab[t]);
+}
- if ((tun_fd = tun_newtun((struct tun_t**) &tun)) > maxfd)
- maxfd = tun_fd;
+/* Print out statistics when at the end of ping sequence */
+int ping_finish()
+{
+ printf("\n");
+ printf("\n----%s PING Statistics----\n", inet_ntoa(pinghost));
+ printf("%d packets transmitted, ", ntransmitted );
+ printf("%d packets received, ", nreceived );
+ if (ntransmitted) {
+ if( nreceived > ntransmitted)
+ printf("-- somebody's printing up packets!");
+ else
+ printf("%d%% packet loss",
+ (int) (((ntransmitted-nreceived)*100) /
+ ntransmitted));
+ }
+ printf("\n");
+ if (debug) printf("%d packets received in total\n", ntreceived );
+ if (nreceived && tsum)
+ printf("round-trip (ms) min/avg/max = %.3f/%.3f/%.3f\n\n",
+ tmin/1000.0,
+ tsum/1000.0/nreceived,
+ tmax/1000.0 );
+ ntransmitted = 0;
+ return 0;
+}
- if (tun_fd == -1) {
- printf("Failed to open tun\n");
- exit(1);
+/* Handle a received ping packet. Print out line and update statistics. */
+int encaps_ping(struct pdp_t *pdp, void *pack, unsigned len) {
+ struct timezone tz;
+ struct timeval tv;
+ struct timeval *tp;
+ struct ip_ping *pingpack = pack;
+ struct in_addr src;
+ int triptime;
+
+ src.s_addr = pingpack->src;
+
+ gettimeofday(&tv, &tz);
+ if (debug) printf("%d.%6d ", (int) tv.tv_sec, (int) tv.tv_usec);
+
+ if (len < CREATEPING_IP + CREATEPING_ICMP) {
+ printf("packet too short (%d bytes) from %s\n", len,
+ inet_ntoa(src));
+ return 0;
+ }
+
+ ntreceived++;
+ if (pingpack->protocol != 1) {
+ if (!pingquiet) printf("%d bytes from %s: ip_protocol=%d (%s)\n",
+ len, inet_ntoa(src), pingpack->protocol,
+ print_ipprot(pingpack->protocol));
+ return 0;
}
- strncpy(snet, inet_ntoa(net), 100);
- strncpy(smask, inet_ntoa(mask), 100);
+ if (pingpack->type != 0) {
+ if (!pingquiet) printf("%d bytes from %s: icmp_type=%d (%s) icmp_code=%d\n",
+ len, inet_ntoa(src), pingpack->type,
+ print_icmptype(pingpack->type), pingpack->code);
+ return 0;
+ }
- sprintf(buf, "/sbin/ifconfig %s %s mtu 1450 netmask %s",
- tun->devname, snet, smask);
- if (debug) printf("%s\n", buf);
- system(buf);
+ nreceived++;
+ if (!pingquiet) printf("%d bytes from %s: icmp_seq=%d", len,
+ inet_ntoa(src), ntohs(pingpack->seq));
- system("echo 1 > /proc/sys/net/ipv4/ip_forward");
-
+ if (len >= sizeof(struct timeval) + CREATEPING_IP + CREATEPING_ICMP) {
+ gettimeofday(&tv, &tz);
+ tp = (struct timeval *) pingpack->data;
+ if( (tv.tv_usec -= tp->tv_usec) < 0 ) {
+ tv.tv_sec--;
+ tv.tv_usec += 1000000;
+ }
+ tv.tv_sec -= tp->tv_sec;
+
+ triptime = tv.tv_sec*1000000+(tv.tv_usec);
+ tsum += triptime;
+ if( triptime < tmin )
+ tmin = triptime;
+ if( triptime > tmax )
+ tmax = triptime;
+
+ if (!pingquiet) printf(" time=%.3f ms\n", triptime/1000.0);
+
+ }
+ else
+ if (!pingquiet) printf("\n");
return 0;
}
-int getip(struct pdp_t *pdp, void* ipif, struct ul66_t *eua,
- struct in_addr *net, struct in_addr *mask) {
- struct in_addr addr;
- uint32_t ip_start, ip_end, ip_cur;
- struct pdp_t *pdp_;
- struct ul66_t eua_;
+/* Create a new ping packet and send it off to peer. */
+int create_ping(void *gsn, struct pdp_t *pdp,
+ struct in_addr *dst, int seq, int datasize) {
+
+ struct ip_ping pack;
+ u_int16_t *p = (u_int16_t *) &pack;
+ u_int8_t *p8 = (u_int8_t *) &pack;
+ struct in_addr src;
+ int n;
+ long int sum = 0;
+ int count = 0;
+
+ struct timezone tz;
+ struct timeval *tp = (struct timeval *) &p8[CREATEPING_IP + CREATEPING_ICMP];
+
+ if (datasize > CREATEPING_MAX) {
+ fprintf(stderr, "%s: Ping size to large: %d!\n",
+ PACKAGE, datasize);
+ syslog(LOG_ERR, "Ping size to large: %d!",
+ datasize);
+ exit(1);
+ }
+
+ memcpy(&src, &(pdp->eua.v[2]), 4); /* Copy a 4 byte address */
+
+ pack.ipver = 0x45;
+ pack.tos = 0x00;
+ pack.length = htons(CREATEPING_IP + CREATEPING_ICMP + datasize);
+ pack.fragid = 0x0000;
+ pack.offset = 0x0040;
+ pack.ttl = 0x40;
+ pack.protocol = 0x01;
+ pack.ipcheck = 0x0000;
+ pack.src = src.s_addr;
+ pack.dst = dst->s_addr;
+ pack.type = 0x08;
+ pack.code = 0x00;
+ pack.checksum = 0x0000;
+ pack.ident = 0x0000;
+ pack.seq = htons(seq);
+
+ /* Generate ICMP payload */
+ p8 = (u_int8_t *) &pack + CREATEPING_IP + CREATEPING_ICMP;
+ for (n=0; n<(datasize); n++) p8[n] = n;
+
+ if (datasize >= sizeof(struct timeval))
+ gettimeofday(tp, &tz);
+
+ /* Calculate IP header checksum */
+ p = (u_int16_t *) &pack;
+ count = CREATEPING_IP;
+ sum = 0;
+ while (count>1) {
+ sum += *p++;
+ count -= 2;
+ }
+ while (sum>>16)
+ sum = (sum & 0xffff) + (sum >> 16);
+ pack.ipcheck = ~sum;
+
+
+ /* Calculate ICMP checksum */
+ count = CREATEPING_ICMP + datasize; /* Length of ICMP message */
+ sum = 0;
+ p = (u_int16_t *) &pack;
+ p += CREATEPING_IP / 2;
+ while (count>1) {
+ sum += *p++;
+ count -= 2;
+ }
+ if (count>0)
+ sum += * (unsigned char *) p;
+ while (sum>>16)
+ sum = (sum & 0xffff) + (sum >> 16);
+ pack.checksum = ~sum;
- printf("Begin getip %d %d %2x%2x%2x%2x\n", (unsigned)ipif, eua->l,
- eua->v[2],eua->v[3],eua->v[4],eua->v[5]);
+ ntransmitted++;
- ip_start = ntoh32(net->s_addr & mask->s_addr);
- ip_end = ntoh32(hton32(ip_start) | ~mask->s_addr);
+ return gtp_gpdu(gsn, pdp, &pack, 28 + datasize);
+}
+
- /* By convention the first address is the network address, and the last */
- /* address is the broadcast address. This way two IP addresses are "lost" */
- ip_start++;
+/* Used to write process ID to file. Assume someone else will delete */
+void log_pid(char *pidfile) {
+ FILE *file;
+ mode_t oldmask;
- if (eua->l == 0) { /* No address supplied. Find one that is available! */
- /* This routine does linear search. In order to support millions of
- * addresses we should instead keep a linked list of available adresses */
- for (ip_cur = ip_start; ip_cur < ip_end; ip_cur++) {
- addr.s_addr = hton32(ip_cur);
- pdp_ntoeua(&addr, &eua_);
- if (pdp_ipget(&pdp_, ipif, &eua_) == -1) {
- pdp_ntoeua(&addr, &pdp->eua);
- pdp->ipif = ipif;
- return 0;
- };
- }
- return EOF; /* No addresses available */
- }
- else { /* Address supplied */
- if (pdp_ipget(&pdp_, ipif, eua) == -1) {
- pdp->ipif = ipif;
- pdp->eua.l = eua->l;
- memcpy(pdp->eua.v, eua->v, eua->l);
- return 0;
- }
- else return EOF; /* Specified address not available */
- }
+ oldmask = umask(022);
+ file = fopen(pidfile, "w");
+ umask(oldmask);
+ if(!file)
+ return;
+ fprintf(file, "%d\n", getpid());
+ fclose(file);
}
int delete_context(struct pdp_t *pdp) {
-
- if (!stattun) {
+ char buf[SGSNEMU_BUFSIZE];
+ if ((createif) && (pdp->ipif!=0)) {
tun_freetun((struct tun_t*) pdp->ipif);
/* Clean up locally */
@@ -181,26 +368,37 @@ int delete_context(struct pdp_t *pdp) {
tun_fd2=-1;
}
}
+
+ if (ipdown) {
+ /* system("ipdown /dev/tun0 192.168.0.10"); */
+ snprintf(buf, sizeof(buf), "%s %s %hu.%hu.%hu.%hu",
+ ipdown,
+ ((struct tun_t*) pdp->ipif)->devname,
+ pdp->eua.v[2], pdp->eua.v[3], pdp->eua.v[4], pdp->eua.v[5]);
+ if (debug) printf("%s\n", buf);
+ system(buf);
+ }
pdp_ipdel(pdp);
return 0;
}
int create_pdp_conf(struct pdp_t *pdp, int cause) {
- char buf[1024];
+ char buf[SGSNEMU_BUFSIZE];
+ char snet[SGSNEMU_BUFSIZE];
+ char smask[SGSNEMU_BUFSIZE];
printf("Received create PDP context response. Cause value: %d\n", cause);
if ((cause == 128) && (pdp->eua.l == 6)) {
-
-
- if (stattun) {
+
+ if (!createif) {
pdp->ipif = tun1;
}
else {
printf("Setting up interface and routing\n");
if ((tun_fd = tun_newtun((struct tun_t**) &pdp->ipif)) > maxfd)
maxfd = tun_fd;
-
+
/* HACK: Only support select of up to two tun interfaces */
if (NULL == tun1) {
tun1 = pdp->ipif;
@@ -212,21 +410,43 @@ int create_pdp_conf(struct pdp_t *pdp, int cause) {
}
/*system("/sbin/ifconfig tun0 192.168.0.10");*/
- sprintf(buf, "/sbin/ifconfig %s %hu.%hu.%hu.%hu",
+ snprintf(buf, sizeof(buf), "/sbin/ifconfig %s %hu.%hu.%hu.%hu",
((struct tun_t*) pdp->ipif)->devname,
pdp->eua.v[2], pdp->eua.v[3], pdp->eua.v[4], pdp->eua.v[5]);
- printf(buf); printf("\n");
- system(buf);
-
-
- /*system("route add -net 192.168.0.0 netmask 255.255.255.0 gw 192.168.0.10");*/
- sprintf(buf, "/sbin/route add -net %hu.%hu.%hu.0 netmask 255.255.255.0 gw %hu.%hu.%hu.%hu",
- pdp->eua.v[2], pdp->eua.v[3], pdp->eua.v[4],
- pdp->eua.v[2], pdp->eua.v[3], pdp->eua.v[4], pdp->eua.v[5]);
- printf(buf); printf("\n");
+ /* if (debug) */ printf("%s\n", buf);
system(buf);
+
+ /* system("route add -host 192.168.0.10 dev tun0"); */
+ /* It seams as if we do not need to set up a route to a p-t-p interface
+ snprintf(buf, sizeof(buf),
+ "/sbin/route add -host %hu.%hu.%hu.%hu dev %s",
+ pdp->eua.v[2], pdp->eua.v[3], pdp->eua.v[4], pdp->eua.v[5],
+ ((struct tun_t*) pdp->ipif)->devname);
+ if (debug) printf("%s\n", buf);
+ system(buf);*/
+
+ if (defaultroute) {
+ strncpy(snet, inet_ntoa(net), sizeof(snet));
+ strncpy(smask, inet_ntoa(mask), sizeof(smask));
+ /* system("route add -net 0.0.0.0 netmask 0.0.0.0 gw 192.168.0.1"); */
+ snprintf(buf, sizeof(buf),
+ "/sbin/route add -net %s netmask %s gw %hu.%hu.%hu.%hu",
+ snet, smask,
+ pdp->eua.v[2], pdp->eua.v[3], pdp->eua.v[4], pdp->eua.v[5]);
+ /* if (debug) */ printf("%s\n", buf);
+ system(buf);
+ }
+
+ if (ipup) {
+ /* system("ipup /dev/tun0 192.168.0.10"); */
+ snprintf(buf, sizeof(buf), "%s %s %hu.%hu.%hu.%hu",
+ ipup,
+ ((struct tun_t*) pdp->ipif)->devname,
+ pdp->eua.v[2], pdp->eua.v[3], pdp->eua.v[4], pdp->eua.v[5]);
+ if (debug) printf("%s\n", buf);
+ system(buf);
+ }
- system("echo 1 > /proc/sys/net/ipv4/ip_forward");
}
pdp_ipset(pdp, pdp->ipif, &pdp->eua);
@@ -242,30 +462,17 @@ int create_pdp_conf(struct pdp_t *pdp, int cause) {
return 0;
}
-
-int create_pdp_ind(struct pdp_t *pdp) {
-
- printf("Received create PDP context request\n");
-
- pdp->eua.l=0; /* TODO: Indicates dynamic IP */
-
- /* ulcpy(&pdp->qos_neg, &pdp->qos_req, sizeof(pdp->qos_req.v)); */
- memcpy(pdp->qos_neg0, pdp->qos_req0, sizeof(pdp->qos_neg));
-
- getip(pdp, &tun, &pdp->eua, &net, &mask);
- pdp_ipset(pdp, pdp->ipif, &pdp->eua);
-
- return 0; /* Success */
-}
-
-
int delete_pdp_conf(struct pdp_t *pdp, int cause) {
printf("Received delete PDP context response. Cause value: %d\n", cause);
+ state = 0; /* Idle */
return 0;
}
int echo_conf(struct pdp_t *pdp, int cause) {
- printf("Received echo response. Cause value: %d\n", cause);
+ if (cause <0)
+ printf("Echo request timed out\n");
+ else
+ printf("Received echo response.\n");
return 0;
}
@@ -298,7 +505,7 @@ int encaps_gtp_client(void *gsn, struct tun_t *tun, void *pack, unsigned len) {
return gtp_gpdu((struct gsn_t*) gsn, pdp, pack, len);
}
else {
- printf("Received packet with no destination!!!\n");
+ printf("Received packet without a valid source address!!!\n");
return 0;
}
}
@@ -313,27 +520,18 @@ int main(int argc, char **argv)
/* gengeopt declarations */
struct gengetopt_args_info args_info;
- /* function-local options */
struct hostent *host;
-
- struct in_addr listen, remote;
- struct in_addr dns;
-
int gtpfd = -1; /* Network file descriptor */
struct gsn_t *gsn; /* GSN instance */
-
fd_set fds; /* For select() */
struct timeval idleTime; /* How long to select() */
-
- struct pdp_t *pdp[2];
-
+ struct pdp_t *pdp[50];
int n; /* For counter */
+ int starttime; /* Time program was started */
+ int pingseq = 0; /* Ping sequence counter */
- int contexts; /* Number of contexts to create */
- int timelimit; /* Number of seconds to be connected */
- int starttime; /* Time program was started */
-
+ /* function-local options */
struct ul_t imsi, qos, apn, msisdn;
unsigned char qosh[3], imsih[8], apnh[256], msisdnh[256];
struct ul255_t pco;
@@ -357,14 +555,22 @@ int main(int argc, char **argv)
printf("msisdn: %s\n", args_info.msisdn_arg);
printf("uid: %s\n", args_info.uid_arg);
printf("pwd: %s\n", args_info.pwd_arg);
- printf("static: %d\n", args_info.static_flag);
- printf("net: %s\n", args_info.net_arg);
- printf("mask: %s\n", args_info.mask_arg);
printf("pidfile: %s\n", args_info.pidfile_arg);
printf("statedir: %s\n", args_info.statedir_arg);
printf("dns: %s\n", args_info.dns_arg);
printf("contexts: %d\n", args_info.contexts_arg);
printf("timelimit: %d\n", args_info.timelimit_arg);
+ printf("createif: %d\n", args_info.createif_flag);
+ printf("ipup: %s\n", args_info.ipup_arg);
+ printf("ipdown: %s\n", args_info.ipdown_arg);
+ printf("defaultroute: %d\n", args_info.defaultroute_flag);
+ printf("net: %s\n", args_info.net_arg);
+ printf("mask: %s\n", args_info.mask_arg);
+ printf("pinghost: %s\n", args_info.pinghost_arg);
+ printf("pingrate: %d\n", args_info.pingrate_arg);
+ printf("pingsize: %d\n", args_info.pingsize_arg);
+ printf("pingcount: %d\n", args_info.pingcount_arg);
+ printf("pingquiet: %d\n", args_info.pingquiet_flag);
}
/* Try out our new parser */
@@ -385,21 +591,29 @@ int main(int argc, char **argv)
printf("msisdn: %s\n", args_info.msisdn_arg);
printf("uid: %s\n", args_info.uid_arg);
printf("pwd: %s\n", args_info.pwd_arg);
- printf("static: %d\n", args_info.static_flag);
- printf("net: %s\n", args_info.net_arg);
- printf("mask: %s\n", args_info.mask_arg);
printf("pidfile: %s\n", args_info.pidfile_arg);
printf("statedir: %s\n", args_info.statedir_arg);
printf("dns: %s\n", args_info.dns_arg);
printf("contexts: %d\n", args_info.contexts_arg);
printf("timelimit: %d\n", args_info.timelimit_arg);
+ printf("createif: %d\n", args_info.createif_flag);
+ printf("ipup: %s\n", args_info.ipup_arg);
+ printf("ipdown: %s\n", args_info.ipdown_arg);
+ printf("defaultroute: %d\n", args_info.defaultroute_flag);
+ printf("net: %s\n", args_info.net_arg);
+ printf("mask: %s\n", args_info.mask_arg);
+ printf("pinghost: %s\n", args_info.pinghost_arg);
+ printf("pingrate: %d\n", args_info.pingrate_arg);
+ printf("pingsize: %d\n", args_info.pingsize_arg);
+ printf("pingcount: %d\n", args_info.pingcount_arg);
+ printf("pingquiet: %d\n", args_info.pingquiet_flag);
}
}
/* Handle each option */
/* foreground */
- /* If flag not given run as a daemon */
+ /* If fg flag not given run as a daemon */
if (!args_info.fg_flag)
{
closelog();
@@ -422,7 +636,7 @@ int main(int argc, char **argv)
}
/* dns */
- /* If no dns option is given use system default */
+ /* If no dns option is given use system default */
/* Do hostname lookup to translate hostname to IP address */
printf("\n");
if (args_info.dns_arg) {
@@ -457,8 +671,8 @@ int main(int argc, char **argv)
exit(1);
}
else {
- memcpy(&listen.s_addr, host->h_addr, host->h_length);
- printf("Local IP address is: %s (%s)\n", args_info.listen_arg, inet_ntoa(listen));
+ memcpy(&listen_.s_addr, host->h_addr, host->h_length);
+ printf("Local IP address is: %s (%s)\n", args_info.listen_arg, inet_ntoa(listen_));
}
}
else {
@@ -494,30 +708,6 @@ int main(int argc, char **argv)
}
- /* net */
- /* Store net as in_addr */
- if (args_info.net_arg) {
- if (!inet_aton(args_info.net_arg, &net)) {
- fprintf(stderr, "%s: Invalid network address: %s!\n",
- PACKAGE, args_info.net_arg);
- syslog(LOG_ERR, "Invalid network address: %s!",
- args_info.net_arg);
- exit(1);
- }
- }
-
- /* mask */
- /* Store mask as in_addr */
- if (args_info.mask_arg) {
- if (!inet_aton(args_info.mask_arg, &mask)) {
- fprintf(stderr, "%s: Invalid network mask: %s!\n",
- PACKAGE, args_info.mask_arg);
- syslog(LOG_ERR, "Invalid network mask: %s!",
- args_info.mask_arg);
- exit(1);
- }
- }
-
/* imsi */
if (strlen(args_info.imsi_arg)!=15) {
printf("Invalid IMSI\n");
@@ -551,6 +741,10 @@ int main(int argc, char **argv)
qos.v[0] = ((args_info.qos_arg) >> 16) & 0xff;
/* contexts */
+ if (args_info.contexts_arg>16) {
+ printf("Contexts has to be less than 16\n");
+ exit(1);
+ }
contexts = args_info.contexts_arg;
/* Timelimit */
@@ -607,27 +801,76 @@ int main(int argc, char **argv)
pco.v[9+strlen(args_info.uid_arg)] = strlen(args_info.pwd_arg);
memcpy(&pco.v[10+strlen(args_info.uid_arg)], args_info.pwd_arg, strlen(args_info.pwd_arg));
- /* static */
- stattun = args_info.static_flag;
+ /* createif */
+ createif = args_info.createif_flag;
+
+ /* ipup */
+ ipup = args_info.ipup_arg;
+
+ /* ipdown */
+ ipdown = args_info.ipdown_arg;
+
+ /* defaultroute */
+ defaultroute = args_info.defaultroute_flag;
+
+ /* net */
+ /* Store net as in_addr */
+ if (args_info.net_arg) {
+ if (!inet_aton(args_info.net_arg, &net)) {
+ fprintf(stderr, "%s: Invalid network address: %s!\n",
+ PACKAGE, args_info.net_arg);
+ syslog(LOG_ERR, "Invalid network address: %s!",
+ args_info.net_arg);
+ exit(1);
+ }
+ }
+
+ /* mask */
+ /* Store mask as in_addr */
+ if (args_info.mask_arg) {
+ if (!inet_aton(args_info.mask_arg, &mask)) {
+ fprintf(stderr, "%s: Invalid network mask: %s!\n",
+ PACKAGE, args_info.mask_arg);
+ syslog(LOG_ERR, "Invalid network mask: %s!",
+ args_info.mask_arg);
+ exit(1);
+ }
+ }
+
+ /* pinghost */
+ /* Store ping host as in_addr */
+ if (args_info.pinghost_arg) {
+ if (!inet_aton(args_info.pinghost_arg, &pinghost)) {
+ fprintf(stderr, "%s: Invalid ping host: %s!\n",
+ PACKAGE, args_info.pinghost_arg);
+ syslog(LOG_ERR, "Invalid ping host: %s!",
+ args_info.pinghost_arg);
+ exit(1);
+ }
+ }
+
+ /* Other ping parameters */
+ pingrate = args_info.pingrate_arg;
+ pingsize = args_info.pingsize_arg;
+ pingcount = args_info.pingcount_arg;
+ pingquiet = args_info.pingquiet_flag;
printf("\nInitialising GTP library\n");
- if ((gtpfd = gtp_new(&gsn, args_info.statedir_arg, &listen)) > maxfd)
+ if ((gtpfd = gtp_new(&gsn, args_info.statedir_arg, &listen_)) > maxfd)
maxfd = gtpfd;
if ((gtpfd = gtp_fd(gsn)) > maxfd)
maxfd = gtpfd;
- gtp_set_cb_gpdu(gsn, encaps_tun);
+ if (createif)
+ gtp_set_cb_gpdu(gsn, encaps_tun);
+ else
+ gtp_set_cb_gpdu(gsn, encaps_ping);
+
gtp_set_cb_delete_context(gsn, delete_context);
gtp_set_cb_conf(gsn, conf);
printf("Done initialising GTP library\n\n");
-
- if (stattun) {
- create_tun();
- tun1 = tun;
- tun_fd1 = tun1->fd;
- }
/* See if anybody is there */
printf("Sending off echo request\n");
@@ -660,9 +903,9 @@ int main(int argc, char **argv)
}
pdp[n]->gsnlc.l = 4;
- memcpy(pdp[n]->gsnlc.v, &listen, 4);
+ memcpy(pdp[n]->gsnlc.v, &listen_, 4);
pdp[n]->gsnlu.l = 4;
- memcpy(pdp[n]->gsnlu.v, &listen, 4);
+ memcpy(pdp[n]->gsnlu.v, &listen_, 4);
if (msisdn.l > sizeof(pdp[n]->msisdn.v)) {
exit(1);
@@ -691,12 +934,13 @@ int main(int argc, char **argv)
printf("Waiting for response from ggsn........\n\n");
-
+
/******************************************************************/
/* Main select loop */
/******************************************************************/
- while (((starttime + timelimit + 10) > time(NULL)) || (0 == timelimit)) {
+ while ((((starttime + timelimit + 10) > time(NULL))
+ || (0 == timelimit)) && (state!=0)) {
/* Take down client connections at some stage */
if (((starttime + timelimit) <= time(NULL)) && (0 != timelimit) && (2 == state)) {
@@ -705,9 +949,23 @@ int main(int argc, char **argv)
/* Delete context */
printf("Disconnecting PDP context #%d\n", n);
if (gtpfd != -1) gtp_delete_context(gsn, pdp[n], NULL);
+ if ((pinghost.s_addr !=0) && ntransmitted) ping_finish();
}
+}
+
+
+ /* Ping */
+ while ((2 == state) && (pinghost.s_addr !=0) &&
+ ((pingseq < pingcount) || (pingcount == 0)) &&
+ (starttime + pingseq/pingrate) <= time(NULL)) {
+ create_ping(gsn, pdp[pingseq % contexts],
+ &pinghost, pingseq++, pingsize);
}
+ if (ntransmitted && pingcount && nreceived >= pingcount)
+ ping_finish();
+
+
FD_ZERO(&fds);
if (tun_fd1 != -1) FD_SET(tun_fd1, &fds);
if (tun_fd2 != -1) FD_SET(tun_fd2, &fds);
@@ -715,6 +973,12 @@ int main(int argc, char **argv)
gtp_retranstimeout(gsn, &idleTime);
+ if ((pinghost.s_addr !=0) &&
+ ((idleTime.tv_sec !=0) || (idleTime.tv_usec !=0))) {
+ idleTime.tv_sec = 0;
+ idleTime.tv_usec = 1000000 / pingrate;
+ }
+
switch (select(maxfd + 1, &fds, NULL, NULL, &idleTime)) {
case -1:
syslog(LOG_ERR, "sgsnemu: select = -1");
@@ -740,15 +1004,15 @@ int main(int argc, char **argv)
if (gtpfd != -1 && FD_ISSET(gtpfd, &fds) &&
gtp_decaps(gsn) < 0) {
- syslog(LOG_ERR, "GTP read failed (gre)=(%d)", gtpfd);
+ syslog(LOG_ERR, "GTP read failed (gtpfd)=(%d)", gtpfd);
}
- }
+ }
gtp_free(gsn); /* Clean up the gsn instance */
- return 1;
+ return 0;
}