]> git.ozlabs.org Git - ppp.git/blobdiff - pppd/options.c
changes to linux interface for new kernel driver,
[ppp.git] / pppd / options.c
index 59c7b5b9f6e0353bc2335f7587633ea155bb0d9a..7ee1e07f46e5dc5952ff4d676d1474d8ca023468 100644 (file)
@@ -17,9 +17,7 @@
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  */
 
-#ifndef lint
-static const char rcsid[] = "$Id: options.c,v 1.61 1999/08/12 04:17:07 paulus Exp $";
-#endif
+#define RCSID  "$Id: options.c,v 1.71 2000/03/27 06:03:03 paulus Exp $"
 
 #include <ctype.h>
 #include <stdio.h>
@@ -36,6 +34,9 @@ static const char rcsid[] = "$Id: options.c,v 1.61 1999/08/12 04:17:07 paulus Ex
 #include <sys/stat.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
+#ifdef PLUGIN
+#include <dlfcn.h>
+#endif
 #ifdef PPP_FILTER
 #include <pcap.h>
 #include <pcap-int.h>  /* XXX: To get struct pcap */
@@ -57,6 +58,8 @@ static const char rcsid[] = "$Id: options.c,v 1.61 1999/08/12 04:17:07 paulus Ex
 char *strdup __P((char *));
 #endif
 
+static const char rcsid[] = RCSID;
+
 /*
  * Option variables and default values.
  */
@@ -75,8 +78,8 @@ 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   *connect_script = NULL; /* Script to establish physical link */
+char   *disconnect_script = NULL; /* Script to disestablish physical link */
 char   *welcomer = NULL;       /* Script to run after phys link estab. */
 char   *ptycommand = NULL;     /* Command to run on other side of pty */
 int    maxconnect = 0;         /* Maximum connect time */
@@ -88,20 +91,28 @@ bool        demand = 0;             /* do dial-on-demand */
 char   *ipparam = NULL;        /* Extra parameter for ip up/down scripts */
 int    idle_time_limit = 0;    /* Disconnect if idle for this many seconds */
 int    holdoff = 30;           /* # seconds to pause before reconnecting */
+bool   holdoff_specified;      /* true if a holdoff value has been given */
 bool   notty = 0;              /* Stdin/out is not a tty */
+char   *pty_socket = NULL;     /* Socket to connect to pty */
 char   *record_file = NULL;    /* File to record chars sent/received */
 int    using_pty = 0;
 bool   sync_serial = 0;        /* Device is synchronous serial device */
 int    log_to_fd = 1;          /* send log messages to this fd too */
-int    maxfail;                /* max # of unsuccessful connection attempts */
+int    maxfail = 10;           /* max # of unsuccessful connection attempts */
+char   linkname[MAXPATHLEN];   /* logical name for link */
+bool   tune_kernel;            /* may alter kernel settings */
+int    connect_delay = 1000;   /* wait this many ms after connect script */
+int    max_data_rate;          /* max bytes/sec through charshunt */
+int    req_unit = -1;          /* requested interface unit */
+bool   multilink = 0;          /* Enable multilink operation */
 
 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 connect_script_info;
+struct option_info disconnect_script_info;
 struct option_info welcomer_info;
 struct option_info devnam_info;
 struct option_info ptycommand_info;
@@ -133,18 +144,30 @@ 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 **));
+#endif
 
 #ifdef PPP_FILTER
 static int setpassfilter __P((char **));
 static int setactivefilter __P((char **));
 #endif
 
-
 static option_t *find_option __P((char *name));
 static int process_option __P((option_t *, char **));
 static int n_arguments __P((option_t *));
 static int number_option __P((char *, u_int32_t *, int));
 
+/*
+ * Structure to store extra lists of options.
+ */
+struct option_list {
+    option_t *options;
+    struct option_list *next;
+};
+
+static struct option_list *extra_options = NULL;
+
 /*
  * Valid arguments.
  */
@@ -172,12 +195,12 @@ option_t general_options[] = {
     { "init", o_string, &initializer,
       "A program to initialize the device",
       OPT_A2INFO | OPT_PRIVFIX, &initializer_info },
-    { "connect", o_string, &connector,
+    { "connect", o_string, &connect_script,
       "A program to set up a connection",
-      OPT_A2INFO | OPT_PRIVFIX, &connector_info },
-    { "disconnect", o_string, &disconnector,
+      OPT_A2INFO | OPT_PRIVFIX, &connect_script_info },
+    { "disconnect", o_string, &disconnect_script,
       "Program to disconnect serial device",
-      OPT_A2INFO | OPT_PRIVFIX, &disconnector_info },
+      OPT_A2INFO | OPT_PRIVFIX, &disconnect_script_info },
     { "welcome", o_string, &welcomer,
       "Script to welcome client",
       OPT_A2INFO | OPT_PRIVFIX, &welcomer_info },
@@ -186,6 +209,8 @@ option_t general_options[] = {
       OPT_A2INFO | OPT_PRIVFIX | OPT_DEVNAM, &ptycommand_info },
     { "notty", o_bool, &notty,
       "Input/output is not a tty", OPT_DEVNAM | 1 },
+    { "socket", o_string, &pty_socket,
+      "Send and receive over socket, arg is host:port", OPT_DEVNAM },
     { "record", o_string, &record_file,
       "Record characters sent/received to file" },
     { "maxconnect", o_int, &maxconnect,
@@ -240,8 +265,35 @@ option_t general_options[] = {
     { "nologfd", o_int, &log_to_fd,
       "Don't send log messages to any file descriptor",
       OPT_NOARG | OPT_VAL(-1) },
+    { "linkname", o_string, linkname,
+      "Set logical name for link",
+      OPT_PRIV|OPT_STATIC, NULL, MAXPATHLEN },
     { "maxfail", o_int, &maxfail,
       "Maximum number of unsuccessful connection attempts to allow" },
+    { "ktune", o_bool, &tune_kernel,
+      "Alter kernel settings as necessary", 1 },
+    { "noktune", o_bool, &tune_kernel,
+      "Don't alter kernel settings", 0 },
+    { "connect-delay", o_int, &connect_delay,
+      "Maximum time (in ms) to wait after connect script finishes" },
+    { "datarate", o_int, &max_data_rate,
+      "Maximum data rate in bytes/sec (with pty, notty or record option)" },
+    { "unit", o_int, &req_unit,
+      "PPP interface unit number to use if possible", OPT_LLIMIT, 0, 0 },
+#ifdef HAVE_MULTILINK
+    { "multilink", o_bool, &multilink,
+      "Enable multilink operation", 1 },
+    { "nomultilink", o_bool, &multilink,
+      "Disable multilink operation", 0 },
+    { "mp", o_bool, &multilink,
+      "Enable multilink operation", 1 },
+    { "nomp", o_bool, &multilink,
+      "Disable multilink operation", 0 },
+#endif /* HAVE_MULTILINK */
+#ifdef PLUGIN
+    { "plugin", o_special, loadplugin,
+      "Load a plug-in module into pppd", OPT_PRIV },
+#endif
 
 #ifdef PPP_FILTER
     { "pdebug", o_int, &dflag,
@@ -320,7 +372,8 @@ parse_args(argc, argv)
         */
        if ((ret = setdevname(arg)) == 0
            && (ret = setspeed(arg)) == 0
-           && (ret = setipaddr(arg)) == 0) {
+           && (ret = setipaddr(arg)) == 0
+           && !prepass) {
            option_error("unrecognized option '%s'", arg);
            usage();
            return 0;
@@ -581,8 +634,13 @@ find_option(name)
     char *name;
 {
     option_t *opt;
+    struct option_list *list;
     int i;
 
+    for (list = extra_options; list != NULL; list = list->next)
+       for (opt = list->options; opt->name != NULL; ++opt)
+           if (strcmp(name, opt->name) == 0)
+               return opt;
     for (opt = general_options; opt->name != NULL; ++opt)
        if (strcmp(name, opt->name) == 0)
            return opt;
@@ -739,6 +797,23 @@ n_arguments(opt)
            || (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;
+{
+    struct option_list *list;
+
+    list = malloc(sizeof(*list));
+    if (list == 0)
+       novm("option list entry");
+    list->options = opt;
+    list->next = extra_options;
+    extra_options = list;
+}
+
 /*
  * usage - print out a message telling how to use the program.
  */
@@ -790,7 +865,7 @@ option_error __V((char *fmt, ...))
     va_list args;
     char buf[256];
 
-#if __STDC__
+#if defined(__STDC__)
     va_start(args, fmt);
 #else
     char *fmt;
@@ -1270,6 +1345,8 @@ setspeed(arg)
     char *ptr;
     int spd;
 
+    if (prepass)
+       return 1;
     spd = strtol(arg, &ptr, 0);
     if (ptr == arg || *ptr != 0 || spd == 0)
        return 0;
@@ -1359,7 +1436,7 @@ setipaddr(arg)
      */
     if (colon != arg) {
        *colon = '\0';
-       if ((local = inet_addr(arg)) == -1) {
+       if ((local = inet_addr(arg)) == (u_int32_t) -1) {
            if ((hp = gethostbyname(arg)) == NULL) {
                option_error("unknown host: %s", arg);
                return -1;
@@ -1380,7 +1457,7 @@ setipaddr(arg)
      * If colon last character, then no remote addr.
      */
     if (*++colon != '\0') {
-       if ((remote = inet_addr(colon)) == -1) {
+       if ((remote = inet_addr(colon)) == (u_int32_t) -1) {
            if ((hp = gethostbyname(colon)) == NULL) {
                option_error("unknown host: %s", colon);
                return -1;
@@ -1424,7 +1501,7 @@ setnetmask(argv)
        b = strtoul(p, &endp, 0);
        if (endp == p)
            break;
-       if (b < 0 || b > 255) {
+       if (b > 255) {
            if (n == 3) {
                /* accept e.g. 0xffffff00 */
                p = endp;
@@ -1469,7 +1546,9 @@ setlogfile(argv)
 
     if (!privileged_option)
        seteuid(getuid());
-    fd = open(*argv, O_WRONLY | O_APPEND);
+    fd = open(*argv, O_WRONLY | O_APPEND | O_CREAT | O_EXCL, 0644);
+    if (fd < 0 && errno == EEXIST)
+       fd = open(*argv, O_WRONLY | O_APPEND);
     err = errno;
     if (!privileged_option)
        seteuid(0);
@@ -1484,3 +1563,33 @@ setlogfile(argv)
     log_to_file = 1;
     return 1;
 }
+
+#ifdef PLUGIN
+static int
+loadplugin(argv)
+    char **argv;
+{
+    char *arg = *argv;
+    void *handle;
+    const char *err;
+    void (*init) __P((void));
+
+    handle = dlopen(arg, RTLD_GLOBAL | RTLD_NOW);
+    if (handle == 0) {
+       err = dlerror();
+       if (err != 0)
+           option_error("%s", err);
+       option_error("Couldn't load plugin %s", arg);
+       return 0;
+    }
+    init = dlsym(handle, "plugin_init");
+    if (init == 0) {
+       option_error("%s has no initialization entry point", arg);
+       dlclose(handle);
+       return 0;
+    }
+    info("Plugin %s loaded.", arg);
+    (*init)();
+    return 1;
+}
+#endif /* PLUGIN */