allow options in secrets files
authorPaul Mackerras <paulus@samba.org>
Wed, 21 Jul 1999 00:24:32 +0000 (00:24 +0000)
committerPaul Mackerras <paulus@samba.org>
Wed, 21 Jul 1999 00:24:32 +0000 (00:24 +0000)
only disable holdoff if link terminated by idle timer
open all network protos on callback
add init and logfile options
document various options

pppd/auth.c
pppd/cbcp.c
pppd/main.c
pppd/options.c
pppd/pppd.8
pppd/pppd.h

index c51a67d975501cad52673bb38b1f43cb357f538c..7548b4664b29871f8897f18991389d6d4e3af0b5 100644 (file)
@@ -33,7 +33,7 @@
  */
 
 #ifndef lint
-static char rcsid[] = "$Id: auth.c,v 1.53 1999/05/13 00:33:05 paulus Exp $";
+static char rcsid[] = "$Id: auth.c,v 1.54 1999/07/21 00:24:30 paulus Exp $";
 #endif
 
 #include <stdio.h>
@@ -78,12 +78,6 @@ static char rcsid[] = "$Id: auth.c,v 1.53 1999/05/13 00:33:05 paulus Exp $";
 #endif
 #include "pathnames.h"
 
-/* Used for storing a sequence of words.  Usually malloced. */
-struct wordlist {
-    struct wordlist    *next;
-    char               *word;
-};
-
 /* Bits in scan_authfile return value */
 #define NONWILD_SERVER 1
 #define NONWILD_CLIENT 2
@@ -102,6 +96,9 @@ static int logged_in;
 /* List of addresses which the peer may use. */
 static struct permitted_ip *addresses[NUM_PPP];
 
+/* Extra options to apply, from the secrets file entry for the peer. */
+static struct wordlist *extra_options;
+
 /* Number of network protocols which we have opened. */
 static int num_np_open;
 
@@ -432,6 +429,20 @@ network_phase(unit)
     }
 #endif
 
+    /*
+     * Process extra options from the secrets file
+     */
+    if (extra_options) {
+       options_from_list(extra_options, 1);
+       free_wordlist(extra_options);
+       extra_options = 0;
+    }
+    start_networks();
+}
+
+void
+start_networks()
+{
     phase = PHASE_NETWORK;
 #if 0
     if (!demand)
@@ -563,7 +574,6 @@ np_up(unit, proto)
        /*
         * At this point we consider that the link has come up successfully.
         */
-       need_holdoff = 0;
        status = EXIT_OK;
 
        if (idle_time_limit > 0)
@@ -628,6 +638,7 @@ check_idle(arg)
        /* link is idle: shut it down. */
        notice("Terminating connection due to lack of activity.");
        lcp_close(0, "Link inactive");
+       need_holdoff = 0;
        status = EXIT_IDLE_TIMEOUT;
     } else {
        TIMEOUT(check_idle, NULL, idle_time_limit - itime);
@@ -1266,14 +1277,16 @@ get_secret(unit, client, server, secret, secret_len, save_addrs)
 
 /*
  * set_allowed_addrs() - set the list of allowed addresses.
+ * Also looks for `--' indicating options to apply for this peer
+ * and leaves the following words in extra_options.
  */
 static void
 set_allowed_addrs(unit, addrs)
     int unit;
     struct wordlist *addrs;
 {
-    int n = 0;
-    struct wordlist *ap;
+    int n;
+    struct wordlist *ap, **pap;
     struct permitted_ip *ip;
     char *ptr_word, *ptr_mask;
     struct hostent *hp;
@@ -1285,9 +1298,23 @@ set_allowed_addrs(unit, addrs)
     if (addresses[unit] != NULL)
        free(addresses[unit]);
     addresses[unit] = NULL;
+    if (extra_options != NULL)
+       free_wordlist(extra_options);
+    extra_options = NULL;
 
-    for (ap = addrs; ap != NULL; ap = ap->next)
-       ++n;
+    /*
+     * Count the number of IP addresses given, and chop off
+     * any extra options for this peer.
+     */
+    for (n = 0, pap = &addrs; (ap = *pap) != NULL; pap = &ap->next, ++n) {
+       if (strcmp(ap->word, "--") == 0) {
+           /* rest are options */
+           *pap = 0;
+           extra_options = ap->next;
+           free(ap);
+           break;
+       }
+    }
     if (n == 0)
        return;
     ip = (struct permitted_ip *) malloc((n + 1) * sizeof(struct permitted_ip));
index 34ba6f756a4a2319ee7c15d649d214cc86dc88cf..b19283feba73d137522f3ee9867793b994e85520 100644 (file)
@@ -19,7 +19,7 @@
  */
 
 #ifndef lint
-static char rcsid[] = "$Id: cbcp.c,v 1.7 1999/05/12 06:19:46 paulus Exp $";
+static char rcsid[] = "$Id: cbcp.c,v 1.8 1999/07/21 00:24:30 paulus Exp $";
 #endif
 
 #include <stdio.h>
@@ -31,7 +31,6 @@ static char rcsid[] = "$Id: cbcp.c,v 1.7 1999/05/12 06:19:46 paulus Exp $";
 #include "cbcp.h"
 #include "fsm.h"
 #include "lcp.h"
-#include "ipcp.h"
 
 /*
  * Options.
@@ -384,7 +383,7 @@ cbcp_resp(us)
        PUTCHAR(len , bufp);
        PUTCHAR(0, bufp);
        cbcp_send(us, CBCP_RESP, buf, len);
-       (*ipcp_protent.open)(us->us_unit);
+       start_networks();
        return;
     }
 }
index 7eee19215e5439dc6aea01d3cb5cb01d92c728e3..a33a5e242188bfc6f0437ce0f448f58853e9750b 100644 (file)
@@ -18,7 +18,7 @@
  */
 
 #ifndef lint
-static char rcsid[] = "$Id: main.c,v 1.79 1999/05/13 00:35:23 paulus Exp $";
+static char rcsid[] = "$Id: main.c,v 1.80 1999/07/21 00:24:31 paulus Exp $";
 #endif
 
 #include <stdio.h>
@@ -85,6 +85,7 @@ int need_holdoff;             /* need holdoff period before restarting */
 int detached;                  /* have detached from terminal */
 struct stat devstat;           /* result of stat() on devnam */
 int prepass = 0;               /* doing prepass to find device name */
+int devnam_fixed;              /* set while in options.ttyxx file */
 volatile int status;           /* exit status for pppd */
 
 static int fd_ppp = -1;                /* fd for talking PPP */
@@ -287,24 +288,13 @@ main(argc, argv)
      * The per-tty options file should not change
      * ptycommand, notty or devnam.
      */
+    devnam_fixed = 1;
     if (!using_pty) {
-       int save_defdev = default_device;
-
-       default_device = 1;
        if (!options_for_tty())
            exit(EXIT_OPTION_ERROR);
-       if (notty || ptycommand != NULL) {
-           option_error("%s option may not be used in per-tty options file",
-                        notty? "notty": "pty");
-           exit(EXIT_OPTION_ERROR);
-       }
-       if (!default_device) {
-           option_error("per-tty options file may not specify device name");
-           exit(EXIT_OPTION_ERROR);
-       }
-       default_device = save_defdev;
     }
 
+    devnam_fixed = 0;
     if (!parse_args(argc-1, argv+1))
        exit(EXIT_OPTION_ERROR);
 
@@ -551,6 +541,8 @@ main(argc, argv)
            info("Starting link");
        }
 
+       phase = PHASE_SERIALCONN;
+
        /*
         * Get a pty master/slave pair if the pty, notty, or record
         * options were specified.
@@ -622,7 +614,7 @@ main(argc, argv)
 
            /*
             * Set line speed, flow control, etc.
-            * If we have a non-null connection script,
+            * If we have a non-null connection or initializer script,
             * on most systems we set CLOCAL for now so that we can talk
             * to the modem before carrier comes up.  But this has the
             * side effect that we might miss it if CD drops before we
@@ -630,7 +622,8 @@ main(argc, argv)
             * successfully to the modem with CLOCAL clear and CD down,
             * we could clear CLOCAL at this point.
             */
-           set_up_tty(ttyfd, (connector != NULL && connector[0] != 0));
+           set_up_tty(ttyfd, ((connector != NULL && connector[0] != 0)
+                              || initializer != NULL));
            real_ttyfd = ttyfd;
        }
 
@@ -669,9 +662,7 @@ main(argc, argv)
        }
 
        /* run connection script */
-       if (connector && connector[0]) {
-           MAINDEBUG(("Connecting with <%s>", connector));
-
+       if ((connector && connector[0]) || initializer) {
            if (real_ttyfd != -1) {
                if (!default_device && modem) {
                    setdtr(real_ttyfd, 0);      /* in case modem is off hook */
@@ -680,15 +671,29 @@ main(argc, argv)
                }
            }
 
-           if (device_script(connector, ttyfd, ttyfd, 0) < 0) {
-               error("Connect script failed");
-               status = EXIT_CONNECT_FAILED;
-               goto fail;
+           if (initializer && initializer[0]) {
+               if (device_script(initializer, ttyfd, ttyfd, 0) < 0) {
+                   error("Initializer script failed");
+                   status = EXIT_INIT_FAILED;
+                   goto fail;
+               }
+               if (kill_link)
+                   goto disconnect;
+
+               info("Serial port initialized.");
            }
-           if (kill_link)
-               goto disconnect;
 
-           info("Serial connection established.");
+           if (connector && connector[0]) {
+               if (device_script(connector, ttyfd, ttyfd, 0) < 0) {
+                   error("Connect script failed");
+                   status = EXIT_CONNECT_FAILED;
+                   goto fail;
+               }
+               if (kill_link)
+                   goto disconnect;
+
+               info("Serial connection established.");
+           }
 
            /* set line speed, flow control, etc.;
               clear CLOCAL if modem option */
@@ -886,6 +891,7 @@ main(argc, argv)
     }
 
     /* Wait for scripts to finish */
+    /* XXX should have a timeout here */
     while (n_children > 0) {
        if (debug) {
            struct subprocess *chp;
index 495c29ae17c38c32591db568b0367292b223da2a..5d144162a66b5c9cc4d01069c46c89a457551c5a 100644 (file)
  */
 
 #ifndef lint
-static char rcsid[] = "$Id: options.c,v 1.59 1999/05/14 01:09:03 paulus Exp $";
+static char rcsid[] = "$Id: options.c,v 1.60 1999/07/21 00:24:31 paulus Exp $";
 #endif
 
 #include <ctype.h>
 #include <stdio.h>
 #include <errno.h>
 #include <unistd.h>
+#include <fcntl.h>
 #include <stdlib.h>
 #include <termios.h>
 #include <syslog.h>
@@ -73,6 +74,7 @@ u_int32_t netmask = 0;                /* IP netmask to set on interface */
 bool   lockflag = 0;           /* Create lock file to lock the serial dev */
 bool   nodetach = 0;           /* Don't detach from controlling tty */
 bool   updetach = 0;           /* Detach once link is up */
+char   *initializer = NULL;    /* Script to initialize physical link */
 char   *connector = NULL;      /* Script to establish physical link */
 char   *disconnector = NULL;   /* Script to disestablish physical link */
 char   *welcomer = NULL;       /* Script to run after phys link estab. */
@@ -96,6 +98,7 @@ extern option_t auth_options[];
 extern struct stat devstat;
 extern int prepass;            /* Doing pre-pass to find device name */
 
+struct option_info initializer_info;
 struct option_info connector_info;
 struct option_info disconnector_info;
 struct option_info welcomer_info;
@@ -111,6 +114,7 @@ pcap_t  pc;                 /* Fake struct pcap so we can compile expr */
 char *current_option;          /* the name of the option being parsed */
 int  privileged_option;                /* set iff the current option came from root */
 char *option_source;           /* string saying where the option came from */
+bool log_to_file;              /* log_to_fd is a file opened by us */
 
 /*
  * Prototypes
@@ -127,6 +131,7 @@ 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 PPP_FILTER
 static int setpassfilter __P((char **));
@@ -163,6 +168,9 @@ option_t general_options[] = {
       "Lock serial device with UUCP-style lock file", 1 },
     { "-all", o_special_noarg, noopt,
       "Don't request/allow any LCP or IPCP options (useless)" },
+    { "init", o_string, &initializer,
+      "A program to initialize the device",
+      OPT_A2INFO | OPT_PRIVFIX, &initializer_info },
     { "connect", o_string, &connector,
       "A program to set up a connection",
       OPT_A2INFO | OPT_PRIVFIX, &connector_info },
@@ -174,9 +182,9 @@ option_t general_options[] = {
       OPT_A2INFO | OPT_PRIVFIX, &welcomer_info },
     { "pty", o_string, &ptycommand,
       "Script to run on pseudo-tty master side",
-      OPT_A2INFO | OPT_PRIVFIX | OPT_PREPASS, &ptycommand_info },
+      OPT_A2INFO | OPT_PRIVFIX | OPT_DEVNAM, &ptycommand_info },
     { "notty", o_bool, &notty,
-      "Input/output is not a tty", OPT_PREPASS | 1 },
+      "Input/output is not a tty", OPT_DEVNAM | 1 },
     { "record", o_string, &record_file,
       "Record characters sent/received to file" },
     { "maxconnect", o_int, &maxconnect,
@@ -212,7 +220,7 @@ option_t general_options[] = {
     { "nopersist", o_bool, &persist,
       "Turn off persist option" },
     { "demand", o_bool, &demand,
-      "Dial on demand", 1, &persist },
+      "Dial on demand", OPT_INITONLY | 1, &persist },
     { "--version", o_special_noarg, showversion,
       "Show version number" },
     { "--help", o_special_noarg, showhelp,
@@ -223,6 +231,11 @@ option_t general_options[] = {
       "Use synchronous HDLC serial encoding", 1 },
     { "logfd", o_int, &log_to_fd,
       "Send log messages to this file descriptor" },
+    { "logfile", o_special, setlogfile,
+      "Append log messages to this file" },
+    { "nolog", o_int, &log_to_fd,
+      "Don't send log messages to any file",
+      OPT_NOARG | OPT_VAL(-1) },
     { "nologfd", o_int, &log_to_fd,
       "Don't send log messages to any file descriptor",
       OPT_NOARG | OPT_VAL(-1) },
@@ -409,6 +422,11 @@ options_from_file(filename, must_exist, check_prot, priv)
                argv[i] = args[i];
            }
            current_option = cmd;
+           if ((opt->flags & OPT_DEVEQUIV) && devnam_fixed) {
+               option_error("the %s option may not be used in the %s file",
+                            cmd, filename);
+               goto err;
+           }
            if (!process_option(opt, argv))
                goto err;
            continue;
@@ -492,6 +510,64 @@ options_for_tty()
     return ret;
 }
 
+/*
+ * options_from_list - process a string of options in a wordlist.
+ */
+int
+options_from_list(w, priv)
+    struct wordlist *w;
+    int priv;
+{
+    char *argv[MAXARGS];
+    option_t *opt;
+    int i, ret = 0;
+
+    privileged_option = priv;
+    option_source = "secrets file";
+
+    while (w != NULL) {
+       /*
+        * First see if it's a command.
+        */
+       opt = find_option(w->word);
+       if (opt != NULL) {
+           int n = n_arguments(opt);
+           struct wordlist *w0 = w;
+           for (i = 0; i < n; ++i) {
+               w = w->next;
+               if (w == NULL) {
+                   option_error(
+                       "In secrets file: too few parameters for option '%s'",
+                       w0->word);
+                   goto err;
+               }
+               argv[i] = w->word;
+           }
+           current_option = w0->word;
+           if (!process_option(opt, argv))
+               goto err;
+           continue;
+       }
+
+       /*
+        * Maybe a tty name, speed or IP address?
+        */
+       if ((i = setdevname(w->word)) == 0
+           && (i = setspeed(w->word)) == 0
+           && (i = setipaddr(w->word)) == 0) {
+           option_error("In secrets file: unrecognized option '%s'",
+                        w->word);
+           goto err;
+       }
+       if (i < 0)              /* error */
+           goto err;
+    }
+    ret = 1;
+
+err:
+    return ret;
+}
+
 /*
  * find_option - scan the option lists for the various protocols
  * looking for an entry with the given name.
@@ -531,9 +607,12 @@ process_option(opt, argv)
     char *sv;
     int (*parser) __P((char **));
 
-    if (prepass && (opt->flags & OPT_PREPASS) == 0)
+    if ((opt->flags & OPT_PREPASS) == 0 && prepass)
        return 1;
-
+    if ((opt->flags & OPT_INITONLY) && phase != PHASE_INITIALIZE) {
+       option_error("it's too late to use the %s option", opt->name);
+       return 0;
+    }
     if ((opt->flags & OPT_PRIV) && !privileged_option) {
        option_error("using the %s option requires root privilege", opt->name);
        return 0;
@@ -1229,6 +1308,14 @@ setdevname(cp)
        return -1;
     }
 
+    if (phase != PHASE_INITIALIZE) {
+       option_error("device name cannot be changed after initialization");
+       return -1;
+    } else if (devnam_fixed) {
+       option_error("per-tty options file may not specify device name");
+       return -1;
+    }
+
     if (devnam_info.priv && !privileged_option) {
        option_error("device name cannot be overridden");
        return -1;
@@ -1370,3 +1457,27 @@ setxonxoff(argv)
     crtscts = -2;
     return (1);
 }
+
+static int
+setlogfile(argv)
+    char **argv;
+{
+    int fd, err;
+
+    if (!privileged_option)
+       seteuid(getuid());
+    fd = open(*argv, O_WRONLY | O_APPEND);
+    err = errno;
+    if (!privileged_option)
+       seteuid(0);
+    if (fd < 0) {
+       errno = err;
+       option_error("Can't open log file %s: %m", *argv);
+       return 0;
+    }
+    if (log_to_file && log_to_fd >= 0)
+       close(log_to_fd);
+    log_to_fd = fd;
+    log_to_file = 1;
+    return 1;
+}
index 4c83af808c0aa4a0a00874f41cfe576ee5533ddf..105c0a10f0903a40e2bdb62b03094b13ece07a4b 100644 (file)
@@ -1,5 +1,5 @@
 .\" manual page [] for pppd 2.3
-.\" $Id: pppd.8,v 1.40 1999/05/13 00:34:04 paulus Exp $
+.\" $Id: pppd.8,v 1.41 1999/07/21 00:24:32 paulus Exp $
 .\" SH section heading
 .\" SS subsection heading
 .\" LP paragraph
@@ -132,6 +132,13 @@ with hex values 0x20 - 0x3f or 0x5e.
 Read options from file \fIname\fR (the format is described below).
 The file must be readable by the user who has invoked pppd.
 .TP
+.B init \fIscript
+Run the executable or shell command specified by \fIscript\fR to
+initialize the serial line.  This script would typically use the
+chat(8) program to configure the modem to enable auto answer.  A value
+for this option from a privileged source cannot be overridden by a
+non-privileged user.
+.TP
 .B lock
 Specifies that pppd should create a UUCP-style lock file for the
 serial device to ensure exclusive access to the device.
@@ -424,6 +431,18 @@ Don't use the modem control lines.  With this option, pppd will ignore
 the state of the CD (Carrier Detect) signal from the modem and will
 not change the state of the DTR (Data Terminal Ready) signal.
 .TP
+.B logfd \fIn
+Send log messages to file descriptor \fIn\fR.  Pppd will send log
+messages to at most one file or file descriptor (as well as sending
+the log messages to syslog), so this option and the \fBlogfile\fR
+option are mutually exclusive.  The default is for pppd to send log
+messages to stdout (file descriptor 1), unless the serial port is
+already open on stdout.
+.TP
+.B logfile \fIfilename
+Append log messages to the file \fIfilename\fR (as well as sending the
+log messages to syslog).  The file is opened with the privileges of
+the user who invoked pppd, in append mode.
 .B login
 Use the system password database for authenticating the peer using
 PAP, and record the user in the system wtmp file.  Note that the peer
@@ -538,6 +557,9 @@ Disable the IPXCP and IPX protocols.  This option should only be
 required if the peer is buggy and gets confused by requests from pppd
 for IPXCP negotiation.
 .TP
+.B nolog
+Do not send log messages to a file or file descriptor.  This option
+cancels the \fBlogfd\fR and \fBlogfile\fR options.
 .B nomagic
 Disable magic number negotiation.  With this option, pppd cannot
 detect a looped-back line.  This option should only be needed if the
@@ -696,12 +718,23 @@ The device used by pppd with this option must have sync support.
 Currently supports Microgate SyncLink adapters
 under Linux and FreeBSD 2.2.8 and later.
 .TP
+.B updetach
+With this option, pppd will detach from its controlling terminal once
+it has successfully established the ppp connection (to the point where
+the first network control protocol, usually the IP control protocol,
+has come up).
+.TP
 .B usehostname
 Enforce the use of the hostname (with domain name appended, if given)
 as the name of the local system for authentication purposes (overrides
 the \fIname\fR option).  This option is not normally needed since the
 \fIname\fR option is privileged.
 .TP
+.B usepeerdns
+Ask the peer for up to 2 DNS server addresses.  The addresses supplied
+by the peer (if any) are passed to the /etc/ppp/ip-up script in the
+environment variables DNS1 and DNS2.
+.TP
 .B user \fIname
 Sets the name used for authenticating the local system to the peer to
 \fIname\fR.
@@ -1115,6 +1148,9 @@ The link was terminated by the modem hanging up.
 .TP
 .B 17
 The PPP negotiation failed because serial loopback was detected.
+.TP
+.B 18
+The init script failed (returned a non-zero exit status).
 .SH SCRIPTS
 Pppd invokes scripts at various stages in its processing which can be
 used to perform site-specific ancillary processing.  These scripts are
index a95f461e20c75a5267976ec39daf2bda507d06df..c7ddd3b0b3683012e543a7ce49d023da77854cb9 100644 (file)
@@ -16,7 +16,7 @@
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
- * $Id: pppd.h,v 1.41 1999/05/14 01:09:03 paulus Exp $
+ * $Id: pppd.h,v 1.42 1999/07/21 00:24:32 paulus Exp $
  */
 
 /*
@@ -97,7 +97,10 @@ typedef struct {
 #define OPT_A2COPY     0x200000 /* addr2 -> second location to rcv value */
 #define OPT_ENABLE     0x400000 /* use *addr2 as enable for option */
 #define OPT_PRIVFIX    0x800000 /* can't be overridden if noauth */
-#define OPT_PREPASS    0x1000000/* do this opt in pre-pass to find device */
+#define OPT_PREPASS    0x1000000 /* do this opt in pre-pass to find device */
+#define OPT_INITONLY   0x2000000 /* option can only be set in init phase */
+#define OPT_DEVEQUIV   0x4000000 /* equiv to device name */
+#define OPT_DEVNAM     (OPT_PREPASS | OPT_INITONLY | OPT_DEVEQUIV)
 
 #define OPT_VAL(x)     ((x) & OPT_VALUE)
 
@@ -123,6 +126,12 @@ struct pppd_stats {
     unsigned int       bytes_out;
 };
 
+/* Used for storing a sequence of words.  Usually malloced. */
+struct wordlist {
+    struct wordlist    *next;
+    char               *word;
+};
+
 /*
  * Global variables.
  */
@@ -150,6 +159,7 @@ extern int  using_pty;      /* using pty as device (notty or pty opt.) */
 extern int     log_to_fd;      /* logging to this fd as well as syslog */
 extern char    *no_ppp_msg;    /* message to print if ppp not in kernel */
 extern volatile int status;    /* exit status for pppd */
+extern int     devnam_fixed;   /* can no longer change devnam */
 
 /*
  * Variables set by command-line options.
@@ -166,6 +176,7 @@ extern u_int32_t netmask;   /* IP netmask to set on interface */
 extern bool    lockflag;       /* Create lock file to lock the serial dev */
 extern bool    nodetach;       /* Don't detach from controlling tty */
 extern bool    updetach;       /* Detach from controlling tty when link up */
+extern char    *initializer;   /* Script to initialize physical link */
 extern char    *connector;     /* Script to establish physical link */
 extern char    *disconnector;  /* Script to disestablish physical link */
 extern char    *welcomer;      /* Script to welcome client after connection */
@@ -207,13 +218,14 @@ extern char *option_source;       /* string saying where the option came from */
  */
 #define PHASE_DEAD             0
 #define PHASE_INITIALIZE       1
-#define PHASE_DORMANT          2
-#define PHASE_ESTABLISH                3
-#define PHASE_AUTHENTICATE     4
-#define PHASE_CALLBACK         5
-#define PHASE_NETWORK          6
-#define PHASE_TERMINATE                7
-#define PHASE_HOLDOFF          8
+#define PHASE_SERIALCONN       2
+#define PHASE_DORMANT          3
+#define PHASE_ESTABLISH                4
+#define PHASE_AUTHENTICATE     5
+#define PHASE_CALLBACK         6
+#define PHASE_NETWORK          7
+#define PHASE_TERMINATE                8
+#define PHASE_HOLDOFF          9
 
 /*
  * The following struct gives the addresses of procedures to call
@@ -298,6 +310,7 @@ void link_required __P((int));        /* we are starting to use the link */
 void link_terminated __P((int));  /* we are finished with the link */
 void link_down __P((int));       /* the LCP layer has left the Opened state */
 void link_established __P((int)); /* the link is up; authenticate now */
+void start_networks __P((void));  /* start all the network control protos */
 void np_up __P((int, int));      /* a network protocol has come up */
 void np_down __P((int, int));    /* a network protocol has gone down */
 void np_finished __P((int, int)); /* a network protocol no longer needs link */
@@ -410,8 +423,8 @@ int  options_from_file __P((char *filename, int must_exist, int check_prot,
                                /* Parse options from an options file */
 int  options_from_user __P((void)); /* Parse options from user's .ppprc */
 int  options_for_tty __P((void)); /* Parse options from /etc/ppp/options.tty */
-void scan_args __P((int argc, char **argv));
-                               /* Look for tty name in command-line args */
+int  options_from_list __P((struct wordlist *, int privileged));
+                               /* Parse options from a wordlist */
 int  getword __P((FILE *f, char *word, int *newlinep, char *filename));
                                /* Read a word from a file */
 void option_error __P((char *fmt, ...));
@@ -431,6 +444,7 @@ struct option_info {
 };
 
 extern struct option_info devnam_info;
+extern struct option_info initializer_info;
 extern struct option_info connector_info;
 extern struct option_info disconnector_info;
 extern struct option_info welcomer_info;
@@ -516,6 +530,7 @@ extern struct option_info ptycommand_info;
 #define EXIT_PEER_DEAD         15
 #define EXIT_HANGUP            16
 #define EXIT_LOOPBACK          17
+#define EXIT_INIT_FAILED       18
 
 /*
  * Debug macros.  Slightly useful for finding bugs in pppd, not particularly