]> git.ozlabs.org Git - ppp.git/blobdiff - pppd/options.c
add stuff for packet filtering
[ppp.git] / pppd / options.c
index 9e8158aaf0836aabb22cde749f79631b3210a6a2..c92e2ddfbf8e120253f1793693cc95a58ac93fcb 100644 (file)
@@ -17,7 +17,7 @@
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  */
 
-#define RCSID  "$Id: options.c,v 1.74 2000/04/15 01:27:13 masputra Exp $"
+#define RCSID  "$Id: options.c,v 1.76 2000/08/01 01:38:30 paulus Exp $"
 
 #include <ctype.h>
 #include <stdio.h>
@@ -70,18 +70,9 @@ int  debug = 0;              /* Debug flag */
 int    kdebugflag = 0;         /* Tell kernel to print debug messages */
 int    default_device = 1;     /* Using /dev/tty or equivalent */
 char   devnam[MAXPATHLEN];     /* Device name */
-int    crtscts = 0;            /* Use hardware flow control */
-bool   modem = 1;              /* Use modem control lines */
-int    inspeed = 0;            /* Input/Output speed requested */
 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   *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 */
 char   user[MAXNAMELEN];       /* Username for PAP */
 char   passwd[MAXSECRETLEN];   /* Password for PAP */
@@ -92,24 +83,17 @@ 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 = 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 */
 char   *bundle_name = NULL;    /* bundle name for multilink */
 
 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 connect_script_info;
@@ -129,6 +113,7 @@ 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 */
 bool log_to_specific_fd;       /* log_to_fd was specified by user option */
+bool no_override;              /* don't override previously-set options */
 
 /*
  * Prototypes
@@ -139,7 +124,6 @@ static int setspeed __P((char *));
 static int noopt __P((char **));
 static int setdomain __P((char **));
 static int setnetmask __P((char **));
-static int setxonxoff __P((char **));
 static int readfile __P((char **));
 static int callfile __P((char **));
 static int showversion __P((char **));
@@ -190,55 +174,16 @@ option_t general_options[] = {
       "Set time in seconds before retrying connection" },
     { "idle", o_int, &idle_time_limit,
       "Set time in seconds before disconnecting idle link" },
-    { "lock", o_bool, &lockflag,
-      "Lock serial device with UUCP-style lock file", 1 },
     { "-all", o_special_noarg, (void *)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, &connect_script,
-      "A program to set up a connection",
-      OPT_A2INFO | OPT_PRIVFIX, &connect_script_info },
-    { "disconnect", o_string, &disconnect_script,
-      "Program to disconnect serial device",
-      OPT_A2INFO | OPT_PRIVFIX, &disconnect_script_info },
-    { "welcome", o_string, &welcomer,
-      "Script to welcome client",
-      OPT_A2INFO | OPT_PRIVFIX, &welcomer_info },
-    { "pty", o_string, &ptycommand,
-      "Script to run on pseudo-tty master side",
-      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,
       "Set connection time limit", OPT_LLIMIT|OPT_NOINCR|OPT_ZEROINF },
-    { "crtscts", o_int, &crtscts,
-      "Set hardware (RTS/CTS) flow control", OPT_NOARG|OPT_VAL(1) },
-    { "nocrtscts", o_int, &crtscts,
-      "Disable hardware flow control", OPT_NOARG|OPT_VAL(-1) },
-    { "-crtscts", o_int, &crtscts,
-      "Disable hardware flow control", OPT_NOARG|OPT_VAL(-1) },
-    { "cdtrcts", o_int, &crtscts,
-      "Set alternate hardware (DTR/CTS) flow control", OPT_NOARG|OPT_VAL(2) },
-    { "nocdtrcts", o_int, &crtscts,
-      "Disable hardware flow control", OPT_NOARG|OPT_VAL(-1) },
-    { "xonxoff", o_special_noarg, (void *)setxonxoff,
-      "Set software (XON/XOFF) flow control" },
     { "domain", o_special, (void *)setdomain,
       "Add given domain name to hostname" },
     { "mtu", o_int, &lcp_allowoptions[0].mru,
       "Set our MTU", OPT_LIMITS, NULL, MAXMRU, MINMRU },
     { "netmask", o_special, (void *)setnetmask,
       "set netmask" },
-    { "modem", o_bool, &modem,
-      "Use modem control lines", 1 },
-    { "local", o_bool, &modem,
-      "Don't use modem control lines" },
     { "file", o_special, (void *)readfile,
       "Take options from a file", OPT_PREPASS },
     { "call", o_special, (void *)callfile,
@@ -255,8 +200,6 @@ option_t general_options[] = {
       "Show brief listing of options" },
     { "-h", o_special_noarg, (void *)showhelp,
       "Show brief listing of options" },
-    { "sync", o_bool, &sync_serial,
-      "Use synchronous HDLC serial encoding", 1 },
     { "logfd", o_int, &log_to_fd,
       "Send log messages to this file descriptor",
       0, &log_to_specific_fd },
@@ -279,8 +222,6 @@ option_t general_options[] = {
       "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
@@ -336,8 +277,6 @@ See pppd(8) for more options.\n\
 
 /*
  * parse_args - parse a string of arguments from the command line.
- * If prepass is true, we are scanning for the device name and only
- * processing a few options, so error messages are suppressed.
  */
 int
 parse_args(argc, argv)
@@ -377,8 +316,7 @@ parse_args(argc, argv)
         */
        if ((ret = setdevname(arg)) == 0
            && (ret = setspeed(arg)) == 0
-           && (ret = setipaddr(arg)) == 0
-           && !prepass) {
+           && (ret = setipaddr(arg)) == 0) {
            option_error("unrecognized option '%s'", arg);
            usage();
            return 0;
@@ -452,9 +390,12 @@ options_from_file(filename, must_exist, check_prot, priv)
     if (check_prot)
        seteuid(0);
     if (f == NULL) {
-       if (!must_exist && err == ENOENT)
-           return 1;
        errno = err;
+       if (!must_exist) {
+           if (err != ENOENT && err != ENOTDIR)
+               warn("Warning: can't open options file %s: %m", filename);
+           return 1;
+       }
        option_error("Can't open options file %s: %m", filename);
        return 0;
     }
@@ -483,7 +424,7 @@ options_from_file(filename, must_exist, check_prot, priv)
                argv[i] = args[i];
            }
            current_option = cmd;
-           if ((opt->flags & OPT_DEVEQUIV) && devnam_fixed) {
+           if ((opt->flags & OPT_DEVEQUIV) && no_override) {
                option_error("the %s option may not be used in the %s file",
                             cmd, filename);
                goto err;
@@ -544,6 +485,9 @@ options_from_user()
 /*
  * options_for_tty - See if an options file exists for the serial
  * device, and if so, interpret options from it.
+ * We only allow the per-tty options file to override anything from
+ * the command line if it is something that the user can't override
+ * once it has been set by root.
  */
 int
 options_for_tty()
@@ -566,7 +510,9 @@ options_for_tty()
     for (p = path + strlen(_PATH_TTYOPT); *p != 0; ++p)
        if (*p == '/')
            *p = '.';
+    no_override = 1;
     ret = options_from_file(path, 0, 0, 1);
+    no_override = 0;
     free(path);
     return ret;
 }
@@ -673,8 +619,14 @@ process_option(opt, argv)
     char *sv;
     int (*parser) __P((char **));
 
-    if ((opt->flags & OPT_PREPASS) == 0 && prepass)
-       return 1;
+    if (no_override && (opt->flags & OPT_SEENIT)) {
+       struct option_info *ip = (struct option_info *) opt->addr2;
+       if (!(privileged && (opt->flags & OPT_PRIVFIX)))
+           return 1;
+       if (!ip || ip->priv)
+           return 1;
+       warn("%s option from per-tty file overrides command line", opt->name);
+    }
     if ((opt->flags & OPT_INITONLY) && phase != PHASE_INITIALIZE) {
        option_error("it's too late to use the %s option", opt->name);
        return 0;
@@ -694,6 +646,7 @@ process_option(opt, argv)
            return 0;
        }
     }
+    opt->flags |= OPT_SEENIT;
 
     switch (opt->type) {
     case o_bool:
@@ -877,10 +830,6 @@ option_error __V((char *fmt, ...))
     va_start(args);
     fmt = va_arg(args, char *);
 #endif
-    if (prepass) {
-       va_end(args);
-       return;
-    }
     vslprintf(buf, sizeof(buf), fmt, args);
     va_end(args);
     if (phase == PHASE_INITIALIZE)
@@ -1260,16 +1209,6 @@ callfile(argv)
 }
 
 #ifdef PPP_FILTER
-/*
- * setpdebug - Set libpcap debugging level.
- */
-static int
-setpdebug(argv)
-    char **argv;
-{
-    return int_option(*argv, &dflag);
-}
-
 /*
  * setpassfilter - Set the pass filter for packets
  */
@@ -1350,12 +1289,13 @@ setspeed(arg)
     char *ptr;
     int spd;
 
-    if (prepass)
+    if (no_override && inspeed != 0)
        return 1;
     spd = strtol(arg, &ptr, 0);
     if (ptr == arg || *ptr != 0 || spd == 0)
        return 0;
-    inspeed = spd;
+    if (!no_override || inspeed == 0)
+       inspeed = spd;
     return 1;
 }
 
@@ -1396,7 +1336,8 @@ setdevname(cp)
     if (phase != PHASE_INITIALIZE) {
        option_error("device name cannot be changed after initialization");
        return -1;
-    } else if (devnam_fixed) {
+    }
+    if (no_override) {
        option_error("per-tty options file may not specify device name");
        return -1;
     }
@@ -1427,19 +1368,18 @@ setipaddr(arg)
     char *colon;
     u_int32_t local, remote;
     ipcp_options *wo = &ipcp_wantoptions[0];
-  
+    static int seen_local = 0, seen_remote = 0;
+
     /*
      * IP address pair separated by ":".
      */
     if ((colon = strchr(arg, ':')) == NULL)
        return 0;
-    if (prepass)
-       return 1;
   
     /*
      * If colon first character, then no local addr.
      */
-    if (colon != arg) {
+    if (colon != arg && !(no_override && seen_local)) {
        *colon = '\0';
        if ((local = inet_addr(arg)) == (u_int32_t) -1) {
            if ((hp = gethostbyname(arg)) == NULL) {
@@ -1456,12 +1396,13 @@ setipaddr(arg)
        if (local != 0)
            wo->ouraddr = local;
        *colon = ':';
+       seen_local = 1;
     }
   
     /*
      * If colon last character, then no remote addr.
      */
-    if (*++colon != '\0') {
+    if (*++colon != '\0' && !(no_override && seen_remote)) {
        if ((remote = inet_addr(colon)) == (u_int32_t) -1) {
            if ((hp = gethostbyname(colon)) == NULL) {
                option_error("unknown host: %s", colon);
@@ -1478,6 +1419,7 @@ setipaddr(arg)
        }
        if (remote != 0)
            wo->hisaddr = remote;
+       seen_remote = 1;
     }
 
     return 1;
@@ -1546,17 +1488,6 @@ parse_dotted_ip(p, vp)
     return p - p0;
 }
 
-static int
-setxonxoff(argv)
-    char **argv;
-{
-    lcp_wantoptions[0].asyncmap |= 0x000A0000; /* escape ^S and ^Q */
-    lcp_wantoptions[0].neg_asyncmap = 1;
-
-    crtscts = -2;
-    return (1);
-}
-
 static int
 setlogfile(argv)
     char **argv;