diff --git a/ggsn/cmdline.c b/ggsn/cmdline.c index ef50f7c..3c5d7e2 100644 --- a/ggsn/cmdline.c +++ b/ggsn/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: @@ -55,6 +55,8 @@ cmdline_parser_print_help (void) printf(" --timelimit=INT Exit after timelimit seconds (default='0')\n"); printf(" -aSTRING --apn=STRING Access point name (default='internet')\n"); printf(" -qINT --qos=INT Requested quality of service (default='0x0b921f')\n"); + printf(" --ipup=STRING Script to run after link-up\n"); + printf(" --ipdown=STRING Script to run after link-down\n"); } @@ -91,6 +93,8 @@ cmdline_parser (int argc, char * const *argv, struct gengetopt_args_info *args_i args_info->timelimit_given = 0 ; args_info->apn_given = 0 ; args_info->qos_given = 0 ; + args_info->ipup_given = 0 ; + args_info->ipdown_given = 0 ; #define clear_args() { \ args_info->fg_flag = 0;\ args_info->debug_flag = 0;\ @@ -103,6 +107,8 @@ cmdline_parser (int argc, char * const *argv, struct gengetopt_args_info *args_i args_info->timelimit_arg = 0 ;\ args_info->apn_arg = strdup("internet") ;\ args_info->qos_arg = 0x0b921f ;\ + args_info->ipup_arg = NULL; \ + args_info->ipdown_arg = NULL; \ } clear_args(); @@ -130,6 +136,8 @@ cmdline_parser (int argc, char * const *argv, struct gengetopt_args_info *args_i { "timelimit", 1, NULL, 0 }, { "apn", 1, NULL, 'a' }, { "qos", 1, NULL, 'q' }, + { "ipup", 1, NULL, 0 }, + { "ipdown", 1, NULL, 0 }, { NULL, 0, NULL, 0 } }; @@ -280,6 +288,32 @@ cmdline_parser (int argc, char * const *argv, struct gengetopt_args_info *args_i args_info->timelimit_arg = strtol (optarg,&stop_char,0); 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; + } case '?': /* Invalid option. */ /* `getopt_long' already printed an error message. */ @@ -515,6 +549,38 @@ cmdline_parser_configfile (char * const filename, struct gengetopt_args_info *ar } 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 \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 \n", + filename, line_num); + exit (EXIT_FAILURE); + } + } + continue; + } /* Tried all known options. This one is unknown! */ diff --git a/ggsn/cmdline.ggo b/ggsn/cmdline.ggo index 5d3e601..c4d281d 100644 --- a/ggsn/cmdline.ggo +++ b/ggsn/cmdline.ggo @@ -27,3 +27,7 @@ option "timelimit" - "Exit after timelimit seconds" int default="0" no option "apn" a "Access point name" string default="internet" no option "qos" q "Requested quality of service" int default="0x0b921f" no + +option "ipup" - "Script to run after link-up" string no +option "ipdown" - "Script to run after link-down" string no + diff --git a/ggsn/cmdline.h b/ggsn/cmdline.h index f0c177f..22c723f 100644 --- a/ggsn/cmdline.h +++ b/ggsn/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 @@ -31,6 +31,8 @@ struct gengetopt_args_info int timelimit_arg; /* Exit after timelimit seconds (default='0'). */ char * apn_arg; /* Access point name (default='internet'). */ int qos_arg; /* Requested quality of service (default='0x0b921f'). */ + char * ipup_arg; /* Script to run after link-up. */ + char * ipdown_arg; /* Script to run after link-down. */ int help_given ; /* Whether help was given. */ int version_given ; /* Whether version was given. */ @@ -45,6 +47,8 @@ struct gengetopt_args_info int timelimit_given ; /* Whether timelimit was given. */ int apn_given ; /* Whether apn was given. */ int qos_given ; /* Whether qos was given. */ + int ipup_given ; /* Whether ipup was given. */ + int ipdown_given ; /* Whether ipdown was given. */ } ; diff --git a/ggsn/ggsn.c b/ggsn/ggsn.c index effe226..3f9767b 100644 --- a/ggsn/ggsn.c +++ b/ggsn/ggsn.c @@ -61,6 +61,7 @@ int maxfd = 0; /* For select() */ int tun_fd = -1; /* Network file descriptor */ struct tun_t *tun; /* TUN instance */ struct in_addr net, mask; /* Network interface */ +char *ipup, *ipdown; /* Filename of scripts */ int debug; /* Print debug output */ @@ -175,16 +176,26 @@ int create_tun() { exit(1); } - strncpy(snet, inet_ntoa(net), 100); - strncpy(smask, inet_ntoa(mask), 100); + strncpy(snet, inet_ntoa(net), sizeof(snet)); + snet[sizeof(snet)-1] = 0; + strncpy(smask, inet_ntoa(mask), sizeof(smask)); + smask[sizeof(smask)-1] = 0; - sprintf(buf, "/sbin/ifconfig %s %s mtu 1450 netmask %s", + snprintf(buf, sizeof(buf), "/sbin/ifconfig %s %s mtu 1450 netmask %s", tun->devname, snet, smask); + buf[sizeof(buf)-1] = 0; if (debug) printf("%s\n", buf); system(buf); - system("echo 1 > /proc/sys/net/ipv4/ip_forward"); - + if (ipup) { + /* system("ipup /dev/tun0 192.168.0.10"); */ + snprintf(buf, sizeof(buf), "%s %s %s %s", + ipup, tun->devname, snet, smask); + buf[sizeof(buf)-1] = 0; + if (debug) printf("%s\n", buf); + system(buf); + } + return 0; } @@ -249,6 +260,8 @@ int main(int argc, char **argv) printf("apn: %s\n", args_info.apn_arg); printf("net: %s\n", args_info.net_arg); printf("mask: %s\n", args_info.mask_arg); + printf("ipup: %s\n", args_info.ipup_arg); + printf("ipdown: %s\n", args_info.ipdown_arg); printf("pidfile: %s\n", args_info.pidfile_arg); printf("statedir: %s\n", args_info.statedir_arg); printf("timelimit: %d\n", args_info.timelimit_arg); @@ -268,6 +281,8 @@ int main(int argc, char **argv) printf("apn: %s\n", args_info.apn_arg); printf("net: %s\n", args_info.net_arg); printf("mask: %s\n", args_info.mask_arg); + printf("ipup: %s\n", args_info.ipup_arg); + printf("ipdown: %s\n", args_info.ipdown_arg); printf("pidfile: %s\n", args_info.pidfile_arg); printf("statedir: %s\n", args_info.statedir_arg); printf("timelimit: %d\n", args_info.timelimit_arg); @@ -342,6 +357,12 @@ int main(int argc, char **argv) } } + /* ipup */ + ipup = args_info.ipup_arg; + + /* ipdown */ + ipdown = args_info.ipdown_arg; + /* Timelimit */ timelimit = args_info.timelimit_arg; starttime = time(NULL); @@ -354,14 +375,14 @@ int main(int argc, char **argv) qos.v[0] = ((args_info.qos_arg) >> 16) & 0xff; /* apn */ - if (strlen(args_info.apn_arg)>255) { + if (strlen(args_info.apn_arg)>(sizeof(apnh)-1)) { printf("invalid APN\n"); exit(1); } apn.l = strlen(args_info.apn_arg) + 1; apn.v = apnh; apn.v[0] = (char) strlen(args_info.apn_arg); - strncpy(&apn.v[1], args_info.apn_arg, 255); + strncpy(&apn.v[1], args_info.apn_arg, (sizeof(apnh)-1)); if (debug) printf("gtpclient: Initialising GTP tunnel\n"); @@ -410,11 +431,11 @@ 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);