* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#define RCSID "$Id: options.c,v 1.102 2008/06/15 06:53:06 paulus Exp $"
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
#include <ctype.h>
+#include <stdarg.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <syslog.h>
#include <string.h>
#include <pwd.h>
-#ifdef PLUGIN
+#ifdef PPP_WITH_PLUGINS
#include <dlfcn.h>
#endif
-#ifdef PPP_FILTER
+#ifdef PPP_WITH_FILTER
#include <pcap.h>
/*
* There have been 3 or 4 different names for this in libpcap CVS, but
#define DLT_PPP_PPPD DLT_PPP
#endif
#endif
-#endif /* PPP_FILTER */
+#endif /* PPP_WITH_FILTER */
#include "pppd.h"
#include "pathnames.h"
#if defined(ultrix) || defined(NeXT)
-char *strdup __P((char *));
+char *strdup(char *);
#endif
-static const char rcsid[] = RCSID;
struct option_value {
struct option_value *next;
bool nodetach = 0; /* Don't detach from controlling tty */
bool updetach = 0; /* Detach once link is up */
bool master_detach; /* Detach when we're (only) multilink master */
+#ifdef SYSTEMD
+bool up_sdnotify = 0; /* Notify systemd once link is up */
+#endif
int maxconnect = 0; /* Maximum connect time */
char user[MAXNAMELEN]; /* Username for PAP */
char passwd[MAXSECRETLEN]; /* Password for PAP */
bool tune_kernel; /* may alter kernel settings */
int connect_delay = 1000; /* wait this many ms after connect script */
int req_unit = -1; /* requested interface unit */
+char path_ipup[MAXPATHLEN]; /* pathname of ip-up script */
+char path_ipdown[MAXPATHLEN];/* pathname of ip-down script */
+char req_ifname[IFNAMSIZ]; /* requested interface name */
bool multilink = 0; /* Enable multilink operation */
char *bundle_name = NULL; /* bundle name for multilink */
bool dump_options; /* print out option values */
struct userenv *userenv_list; /* user environment variables */
int dfl_route_metric = -1; /* metric of the default route to set over the PPP link */
+#ifdef PPP_WITH_IPV6CP
+char path_ipv6up[MAXPATHLEN]; /* pathname of ipv6-up script */
+char path_ipv6down[MAXPATHLEN]; /* pathname of ipv6-down script */
+#endif
+
#ifdef MAXOCTETS
unsigned int maxoctets = 0; /* default - no limit */
int maxoctets_dir = 0; /* default - sum of traffic */
extern option_t auth_options[];
extern struct stat devstat;
-#ifdef PPP_FILTER
+#ifdef PPP_WITH_FILTER
struct bpf_program pass_filter;/* Filter program for packets to pass */
struct bpf_program active_filter; /* Filter program for link-active pkts */
#endif
static int logfile_fd = -1; /* fd opened for log file */
static char logfile_name[MAXPATHLEN]; /* name of log file */
+static bool noipx_opt; /* dummy for noipx option */
+
/*
* Prototypes
*/
-static int setdomain __P((char **));
-static int readfile __P((char **));
-static int callfile __P((char **));
-static int showversion __P((char **));
-static int showhelp __P((char **));
-static void usage __P((void));
-static int setlogfile __P((char **));
-#ifdef PLUGIN
-static int loadplugin __P((char **));
+static int setdomain(char **);
+static int readfile(char **);
+static int callfile(char **);
+static int showversion(char **);
+static int showhelp(char **);
+static void usage(void);
+static int setlogfile(char **);
+#ifdef PPP_WITH_PLUGINS
+static int loadplugin(char **);
#endif
-#ifdef PPP_FILTER
-static int setpassfilter __P((char **));
-static int setactivefilter __P((char **));
+#ifdef PPP_WITH_FILTER
+static int setpassfilter(char **);
+static int setactivefilter(char **);
#endif
#ifdef MAXOCTETS
-static int setmodir __P((char **));
+static int setmodir(char **);
#endif
-static int user_setenv __P((char **));
-static void user_setprint __P((option_t *, printer_func, void *));
-static int user_unsetenv __P((char **));
-static void user_unsetprint __P((option_t *, printer_func, void *));
+static int user_setenv(char **);
+static void user_setprint(option_t *, printer_func, void *);
+static int user_unsetenv(char **);
+static void user_unsetprint(option_t *, printer_func, void *);
-static option_t *find_option __P((const char *name));
-static int process_option __P((option_t *, char *, char **));
-static int n_arguments __P((option_t *));
-static int number_option __P((char *, u_int32_t *, int));
+static option_t *find_option(char *name);
+static int process_option(option_t *, char *, char **);
+static int n_arguments(option_t *);
+static int number_option(char *, u_int32_t *, int);
/*
* Structure to store extra lists of options.
"Don't detach from controlling tty", OPT_PRIO | 1 },
{ "-detach", o_bool, &nodetach,
"Don't detach from controlling tty", OPT_ALIAS | OPT_PRIOSUB | 1 },
+#ifdef SYSTEMD
+ { "up_sdnotify", o_bool, &up_sdnotify,
+ "Notify systemd once link is up (implies nodetach)",
+ OPT_PRIOSUB | OPT_A2COPY | 1, &nodetach },
+#endif
{ "updetach", o_bool, &updetach,
"Detach from controlling tty once link is up",
OPT_PRIOSUB | OPT_A2CLR | 1, &nodetach },
"PPP interface unit number to use if possible",
OPT_PRIO | OPT_LLIMIT, 0, 0 },
+ { "ifname", o_string, req_ifname,
+ "Set PPP interface name",
+ OPT_PRIO | OPT_PRIV | OPT_STATIC, NULL, IFNAMSIZ },
+
{ "dump", o_bool, &dump_options,
"Print out option values after parsing all options", 1 },
{ "dryrun", o_bool, &dryrun,
"Metric to use for the default route (Linux only; -1 for default behavior)",
OPT_PRIV|OPT_LLIMIT|OPT_INITONLY, NULL, 0, -1 },
-#ifdef HAVE_MULTILINK
+ { "ip-up-script", o_string, path_ipup,
+ "Set pathname of ip-up script",
+ OPT_PRIV|OPT_STATIC, NULL, MAXPATHLEN },
+ { "ip-down-script", o_string, path_ipdown,
+ "Set pathname of ip-down script",
+ OPT_PRIV|OPT_STATIC, NULL, MAXPATHLEN },
+
+#ifdef PPP_WITH_IPV6CP
+ { "ipv6-up-script", o_string, path_ipv6up,
+ "Set pathname of ipv6-up script",
+ OPT_PRIV|OPT_STATIC, NULL, MAXPATHLEN },
+ { "ipv6-down-script", o_string, path_ipv6down,
+ "Set pathname of ipv6-down script",
+ OPT_PRIV|OPT_STATIC, NULL, MAXPATHLEN },
+#endif
+
+#ifdef PPP_WITH_MULTILINK
{ "multilink", o_bool, &multilink,
"Enable multilink operation", OPT_PRIO | 1 },
{ "mp", o_bool, &multilink,
{ "bundle", o_string, &bundle_name,
"Bundle name for multilink", OPT_PRIO },
-#endif /* HAVE_MULTILINK */
+#endif /* PPP_WITH_MULTILINK */
-#ifdef PLUGIN
+#ifdef PPP_WITH_PLUGINS
{ "plugin", o_special, (void *)loadplugin,
"Load a plug-in module into pppd", OPT_PRIV | OPT_A2LIST },
#endif
-#ifdef PPP_FILTER
+#ifdef PPP_WITH_FILTER
{ "pass-filter", o_special, setpassfilter,
"set filter for packets to pass", OPT_PRIO },
"Check for traffic limit every N seconds", OPT_PRIO | OPT_LLIMIT | 1 },
#endif
+ /* Dummy option, does nothing */
+ { "noipx", o_bool, &noipx_opt, NULL, OPT_NOPRINT | 1 },
+
{ NULL }
};
* parse_args - parse a string of arguments from the command line.
*/
int
-parse_args(argc, argv)
- int argc;
- char **argv;
+parse_args(int argc, char **argv)
{
char *arg;
option_t *opt;
* and interpret them.
*/
int
-options_from_file(filename, must_exist, check_prot, priv)
- char *filename;
- int must_exist;
- int check_prot;
- int priv;
+options_from_file(char *filename, int must_exist, int check_prot, int priv)
{
FILE *f;
int i, newline, ret, err;
* and if so, interpret options from it.
*/
int
-options_from_user()
+options_from_user(void)
{
char *user, *path, *file;
int ret;
* files a lower priority than the command line.
*/
int
-options_for_tty()
+options_for_tty(void)
{
char *dev, *path, *p;
int ret;
* options_from_list - process a string of options in a wordlist.
*/
int
-options_from_list(w, priv)
- struct wordlist *w;
- int priv;
+options_from_list(struct wordlist *w, int priv)
{
char *argv[MAXARGS];
option_t *opt;
* match_option - see if this option matches an option_t structure.
*/
static int
-match_option(name, opt, dowild)
- char *name;
- option_t *opt;
- int dowild;
+match_option(char *name, option_t *opt, int dowild)
{
- int (*match) __P((char *, char **, int));
+ int (*match)(char *, char **, int);
if (dowild != (opt->type == o_wild))
return 0;
if (!dowild)
return strcmp(name, opt->name) == 0;
- match = (int (*) __P((char *, char **, int))) opt->addr;
+ match = (int (*)(char *, char **, int)) opt->addr;
return (*match)(name, NULL, 0);
}
* This could be optimized by using a hash table.
*/
static option_t *
-find_option(name)
- const char *name;
+find_option(char *name)
{
option_t *opt;
struct option_list *list;
* process_option - process one new-style option.
*/
static int
-process_option(opt, cmd, argv)
- option_t *opt;
- char *cmd;
- char **argv;
+process_option(option_t *opt, char *cmd, char **argv)
{
u_int32_t v;
int iv, a;
char *sv;
- int (*parser) __P((char **));
- int (*wildp) __P((char *, char **, int));
+ int (*parser)(char **);
+ int (*wildp)(char *, char **, int);
char *optopt = (opt->type == o_wild)? "": " option";
int prio = option_priority;
option_t *mainopt = opt;
free(*optptr);
*optptr = sv;
}
+ /* obfuscate original argument for things like password */
+ if (opt->flags & OPT_HIDE) {
+ memset(*argv, '?', strlen(*argv));
+ *argv = "********";
+ }
break;
case o_special_noarg:
case o_special:
- parser = (int (*) __P((char **))) opt->addr;
+ parser = (int (*)(char **)) opt->addr;
curopt = opt;
if (!(*parser)(argv))
return 0;
break;
case o_wild:
- wildp = (int (*) __P((char *, char **, int))) opt->addr;
+ wildp = (int (*)(char *, char **, int)) opt->addr;
if (!(*wildp)(cmd, argv, 1))
return 0;
break;
* and source of the option value. Otherwise returns 0.
*/
int
-override_value(option, priority, source)
- const char *option;
- int priority;
- const char *source;
+override_value(char *option, int priority, const char *source)
{
option_t *opt;
* n_arguments - tell how many arguments an option takes
*/
static int
-n_arguments(opt)
- option_t *opt;
+n_arguments(option_t *opt)
{
return (opt->type == o_bool || opt->type == o_special_noarg
|| (opt->flags & OPT_NOARG))? 0: 1;
* add_options - add a list of options to the set we grok.
*/
void
-add_options(opt)
- option_t *opt;
+add_options(option_t *opt)
{
struct option_list *list;
* check_options - check that options are valid and consistent.
*/
void
-check_options()
+check_options(void)
{
if (logfile_fd >= 0 && logfile_fd != log_to_fd)
close(logfile_fd);
* print_option - print out an option and its value
*/
static void
-print_option(opt, mainopt, printer, arg)
- option_t *opt, *mainopt;
- printer_func printer;
- void *arg;
+print_option(option_t *opt, option_t *mainopt, printer_func printer, void *arg)
{
int i, v;
char *p;
printer(arg, " ");
}
if (opt->flags & OPT_A2PRINTER) {
- void (*oprt) __P((option_t *, printer_func, void *));
- oprt = (void (*) __P((option_t *, printer_func,
- void *)))opt->addr2;
+ void (*oprt)(option_t *, printer_func, void *);
+ oprt = (void (*)(option_t *, printer_func, void *))
+ opt->addr2;
(*oprt)(opt, printer, arg);
} else if (opt->flags & OPT_A2STRVAL) {
p = (char *) opt->addr2;
if ((opt->flags & OPT_STATIC) == 0)
p = *(char **)p;
- printer("%q", p);
+ printer(arg, "%q", p);
} else if (opt->flags & OPT_A2LIST) {
struct option_value *ovp;
* array of options.
*/
static void
-print_option_list(opt, printer, arg)
- option_t *opt;
- printer_func printer;
- void *arg;
+print_option_list(option_t *opt, printer_func printer, void *arg)
{
while (opt->name != NULL) {
if (opt->priority != OPRIO_DEFAULT
* print_options - print out what options are in effect.
*/
void
-print_options(printer, arg)
- printer_func printer;
- void *arg;
+print_options(printer_func printer, void *arg)
{
struct option_list *list;
int i;
* usage - print out a message telling how to use the program.
*/
static void
-usage()
+usage(void)
{
if (phase == PHASE_INITIALIZE)
fprintf(stderr, usage_string, VERSION, progname);
* showhelp - print out usage message and exit.
*/
static int
-showhelp(argv)
- char **argv;
+showhelp(char **argv)
{
if (phase == PHASE_INITIALIZE) {
usage();
* showversion - print out the version number and exit.
*/
static int
-showversion(argv)
- char **argv;
+showversion(char **argv)
{
if (phase == PHASE_INITIALIZE) {
- fprintf(stderr, "pppd version %s\n", VERSION);
+ fprintf(stdout, "pppd version %s\n", VERSION);
exit(0);
}
return 0;
* stderr if phase == PHASE_INITIALIZE.
*/
void
-option_error __V((char *fmt, ...))
+option_error(char *fmt, ...)
{
va_list args;
char buf[1024];
-#if defined(__STDC__)
va_start(args, fmt);
-#else
- char *fmt;
- va_start(args);
- fmt = va_arg(args, char *);
-#endif
vslprintf(buf, sizeof(buf), fmt, args);
va_end(args);
if (phase == PHASE_INITIALIZE)
* readable - check if a file is readable by the real user.
*/
int
-readable(fd)
- int fd;
+readable(int fd)
{
uid_t uid;
int i;
* \<newline> is ignored.
*/
int
-getword(f, word, newlinep, filename)
- FILE *f;
- char *word;
- int *newlinep;
- char *filename;
+getword(FILE *f, char *word, int *newlinep, char *filename)
{
int c, len, escape;
int quoted, comment;
c = getc(f);
}
+ word[MAXWORDLEN-1] = 0; /* make sure word is null-terminated */
/*
* End of the word: check for errors.
* number_option - parse an unsigned numeric parameter for an option.
*/
static int
-number_option(str, valp, base)
- char *str;
- u_int32_t *valp;
- int base;
+number_option(char *str, u_int32_t *valp, int base)
{
char *ptr;
* if there is an error.
*/
int
-int_option(str, valp)
- char *str;
- int *valp;
+int_option(char *str, int *valp)
{
u_int32_t v;
* readfile - take commands from a file.
*/
static int
-readfile(argv)
- char **argv;
+readfile(char **argv)
{
return options_from_file(*argv, 1, 1, privileged_option);
}
* Name may not contain /../, start with / or ../, or end in /..
*/
static int
-callfile(argv)
- char **argv;
+callfile(char **argv)
{
char *fname, *arg, *p;
int l, ok;
if ((fname = (char *) malloc(l)) == NULL)
novm("call file name");
slprintf(fname, l, "%s%s", _PATH_PEERFILES, arg);
+ script_setenv("CALL_FILE", arg, 0);
ok = options_from_file(fname, 1, 1, 1);
return ok;
}
-#ifdef PPP_FILTER
+#ifdef PPP_WITH_FILTER
/*
* setpassfilter - Set the pass filter for packets
*/
static int
-setpassfilter(argv)
- char **argv;
+setpassfilter(char **argv)
{
pcap_t *pc;
int ret = 1;
* setactivefilter - Set the active filter for packets
*/
static int
-setactivefilter(argv)
- char **argv;
+setactivefilter(char **argv)
{
pcap_t *pc;
int ret = 1;
* setdomain - Set domain name to append to hostname
*/
static int
-setdomain(argv)
- char **argv;
+setdomain(char **argv)
{
gethostname(hostname, MAXNAMELEN);
if (**argv != 0) {
}
static int
-setlogfile(argv)
- char **argv;
+setlogfile(char **argv)
{
int fd, err;
uid_t euid;
#ifdef MAXOCTETS
static int
-setmodir(argv)
- char **argv;
+setmodir(char **argv)
{
if(*argv == NULL)
return 0;
}
#endif
-#ifdef PLUGIN
+#ifdef PPP_WITH_PLUGINS
static int
-loadplugin(argv)
- char **argv;
+loadplugin(char **argv)
{
char *arg = *argv;
void *handle;
const char *err;
- void (*init) __P((void));
+ void (*init)(void);
char *path = arg;
const char *vers;
free(path);
return 0;
}
-#endif /* PLUGIN */
+#endif /* PPP_WITH_PLUGINS */
/*
* Set an environment variable specified by the user.
*/
static int
-user_setenv(argv)
- char **argv;
+user_setenv(char **argv)
{
char *arg = argv[0];
char *eqp;
}
static void
-user_setprint(opt, printer, arg)
- option_t *opt;
- printer_func printer;
- void *arg;
+user_setprint(option_t *opt, printer_func printer, void *arg)
{
struct userenv *uep, *uepnext;
}
static int
-user_unsetenv(argv)
- char **argv;
+user_unsetenv(char **argv)
{
struct userenv *uep, **insp;
char *arg = argv[0];
option_error("unexpected = in name: %s", arg);
return 0;
}
- if (arg == '\0') {
+ if (*arg == '\0') {
option_error("missing variable name for unset");
return 0;
}
}
static void
-user_unsetprint(opt, printer, arg)
- option_t *opt;
- printer_func printer;
- void *arg;
+user_unsetprint(option_t *opt, printer_func printer, void *arg)
{
struct userenv *uep, *uepnext;