*/
#ifndef lint
-static char rcsid[] = "$Id: options.c,v 1.26 1995/12/18 03:49:06 paulus Exp $";
+static char rcsid[] = "$Id: options.c,v 1.34 1996/09/14 05:16:56 paulus Exp $";
#endif
+#include <ctype.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <netinet/in.h>
+#include <arpa/inet.h>
#include "pppd.h"
#include "pathnames.h"
int nodetach = 0; /* Don't detach from controlling tty */
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. */
int maxconnect = 0; /* Maximum connect time */
char user[MAXNAMELEN]; /* Username for PAP */
char passwd[MAXSECRETLEN]; /* Password for PAP */
char remote_name[MAXNAMELEN]; /* Peer's name for authentication */
int usehostname = 0; /* Use hostname for our_name */
int disable_defaultip = 0; /* Don't use hostname for default IP adrs */
+int demand = 0; /* do dial-on-demand */
char *ipparam = NULL; /* Extra parameter for ip up/down scripts */
int cryptpap; /* Passwords in pap-secrets are encrypted */
+int idle_time_limit = 0; /* Disconnect if idle for this many seconds */
+int holdoff = 30; /* # seconds to pause before reconnecting */
+int refuse_pap = 0; /* Set to say we won't do PAP */
+int refuse_chap = 0; /* Set to say we won't do CHAP */
-#ifdef _linux_
-int idle_time_limit = 0;
-static int setidle __P((char **));
-#endif
+struct option_info auth_req_info;
+struct option_info connector_info;
+struct option_info disconnector_info;
+struct option_info welcomer_info;
+struct option_info devnam_info;
/*
* Prototypes
*/
+static int setdevname __P((char *, int));
+static int setipaddr __P((char *));
static int setdebug __P((void));
static int setkdebug __P((char **));
static int setpassive __P((void));
static int setvjslots __P((char **));
static int reqpap __P((void));
static int nopap __P((void));
+#ifdef OLD_OPTIONS
static int setupapfile __P((char **));
+#endif
static int nochap __P((void));
static int reqchap __P((void));
static int setspeed __P((char *));
static int nopcomp __P((void));
static int setconnector __P((char **));
static int setdisconnector __P((char **));
+static int setwelcomer __P((char **));
static int setmaxconnect __P((char **));
static int setdomain __P((char **));
static int setnetmask __P((char **));
static int setuser __P((char **));
static int setremote __P((char **));
static int setauth __P((void));
+static int setnoauth __P((void));
static int readfile __P((char **));
+static int callfile __P((char **));
static int setdefaultroute __P((void));
static int setnodefaultroute __P((void));
static int setproxyarp __P((void));
static int setnoproxyarp __P((void));
static int setpersist __P((void));
+static int setnopersist __P((void));
static int setdologin __P((void));
static int setusehostname __P((void));
static int setnoipdflt __P((void));
static int setipcpaccr __P((void));
static int setlcpechointv __P((char **));
static int setlcpechofails __P((char **));
+static int noccp __P((void));
static int setbsdcomp __P((char **));
static int setnobsdcomp __P((void));
+static int setdeflate __P((char **));
+static int setnodeflate __P((void));
+static int setdemand __P((void));
static int setpred1comp __P((void));
static int setnopred1comp __P((void));
static int setipparam __P((char **));
static int setpapcrypt __P((void));
+static int setidle __P((char **));
+static int setholdoff __P((char **));
#ifdef IPX_CHANGE
static int setipxproto __P((void));
#endif
static int number_option __P((char *, u_int32_t *, int));
+static int int_option __P((char *, int *));
static int readable __P((int fd));
-void usage();
-
/*
* Valid arguments.
*/
int num_args;
int (*cmd_func)();
} cmds[] = {
- {"-all", 0, noopt}, /* Don't request/allow any options */
+ {"-all", 0, noopt}, /* Don't request/allow any options (useless) */
+ {"noaccomp", 0, noaccomp}, /* Disable Address/Control compression */
{"-ac", 0, noaccomp}, /* Disable Address/Control compress */
+ {"default-asyncmap", 0, noasyncmap}, /* Disable asyncmap negoatiation */
{"-am", 0, noasyncmap}, /* Disable asyncmap negotiation */
{"-as", 1, setasyncmap}, /* set the desired async map */
{"-d", 0, setdebug}, /* Increase debugging level */
+ {"nodetach", 0, setnodetach}, /* Don't detach from controlling tty */
{"-detach", 0, setnodetach}, /* don't fork */
+ {"noip", 0, noip}, /* Disable IP and IPCP */
{"-ip", 0, noip}, /* Disable IP and IPCP */
+ {"nomagic", 0, nomagicnumber}, /* Disable magic number negotiation */
{"-mn", 0, nomagicnumber}, /* Disable magic number negotiation */
+ {"default-mru", 0, nomru}, /* Disable MRU negotiation */
{"-mru", 0, nomru}, /* Disable mru negotiation */
{"-p", 0, setpassive}, /* Set passive mode */
+ {"nopcomp", 0, nopcomp}, /* Disable protocol field compression */
{"-pc", 0, nopcomp}, /* Disable protocol field compress */
+#if OLD_OPTIONS
{"+ua", 1, setupapfile}, /* Get PAP user and password from file */
+#endif
+ {"require-pap", 0, reqpap}, /* Require PAP authentication from peer */
{"+pap", 0, reqpap}, /* Require PAP auth from peer */
+ {"refuse-pap", 0, nopap}, /* Don't agree to auth to peer with PAP */
{"-pap", 0, nopap}, /* Don't allow UPAP authentication with peer */
+ {"require-chap", 0, reqchap}, /* Require CHAP authentication from peer */
{"+chap", 0, reqchap}, /* Require CHAP authentication from peer */
+ {"refuse-chap", 0, nochap}, /* Don't agree to auth to peer with CHAP */
{"-chap", 0, nochap}, /* Don't allow CHAP authentication with peer */
+ {"novj", 0, setnovj}, /* Disable VJ compression */
{"-vj", 0, setnovj}, /* disable VJ compression */
+ {"novjccomp", 0, setnovjccomp}, /* disable VJ connection-ID compression */
{"-vjccomp", 0, setnovjccomp}, /* disable VJ connection-ID compression */
{"vj-max-slots", 1, setvjslots}, /* Set maximum VJ header slots */
{"asyncmap", 1, setasyncmap}, /* set the desired async map */
{"escape", 1, setescape}, /* set chars to escape on transmission */
{"connect", 1, setconnector}, /* A program to set up a connection */
{"disconnect", 1, setdisconnector}, /* program to disconnect serial dev. */
+ {"welcome", 1, setwelcomer},/* Script to welcome client */
{"maxconnect", 1, setmaxconnect}, /* specify a maximum connect time */
{"crtscts", 0, setcrtscts}, /* set h/w flow control */
+ {"nocrtscts", 0, setnocrtscts}, /* clear h/w flow control */
{"-crtscts", 0, setnocrtscts}, /* clear h/w flow control */
{"xonxoff", 0, setxonxoff}, /* set s/w flow control */
{"debug", 0, setdebug}, /* Increase debugging level */
{"local", 0, setlocal}, /* Don't use modem control lines */
{"lock", 0, setlock}, /* Lock serial device (with lock file) */
{"name", 1, setname}, /* Set local name for authentication */
- {"user", 1, setuser}, /* Set username for PAP auth with peer */
+ {"user", 1, setuser}, /* Set name for auth with peer */
{"usehostname", 0, setusehostname}, /* Must use hostname for auth. */
{"remotename", 1, setremote}, /* Set remote name for authentication */
{"auth", 0, setauth}, /* Require authentication from peer */
+ {"noauth", 0, setnoauth}, /* Don't require peer to authenticate */
{"file", 1, readfile}, /* Take options from a file */
+ {"call", 1, callfile}, /* Take options from a privileged file */
{"defaultroute", 0, setdefaultroute}, /* Add default route */
+ {"nodefaultroute", 0, setnodefaultroute}, /* disable defaultroute option */
{"-defaultroute", 0, setnodefaultroute}, /* disable defaultroute option */
{"proxyarp", 0, setproxyarp}, /* Add proxy ARP entry */
+ {"noproxyarp", 0, setnoproxyarp}, /* disable proxyarp option */
{"-proxyarp", 0, setnoproxyarp}, /* disable proxyarp option */
{"persist", 0, setpersist}, /* Keep on reopening connection after close */
+ {"nopersist", 0, setnopersist}, /* Turn off persist option */
+ {"demand", 0, setdemand}, /* Dial on demand */
{"login", 0, setdologin}, /* Use system password database for UPAP */
{"noipdefault", 0, setnoipdflt}, /* Don't use name for default IP adrs */
{"lcp-echo-failure", 1, setlcpechofails}, /* consecutive echo failures */
{"chap-interval", 1, setchapintv}, /* Set interval for rechallenge */
{"ipcp-accept-local", 0, setipcpaccl}, /* Accept peer's address for us */
{"ipcp-accept-remote", 0, setipcpaccr}, /* Accept peer's address for it */
+ {"noccp", 0, noccp}, /* Disable CCP negotiation */
+ {"-ccp", 0, noccp}, /* Disable CCP negotiation */
{"bsdcomp", 1, setbsdcomp}, /* request BSD-Compress */
+ {"nobsdcomp", 0, setnobsdcomp}, /* don't allow BSD-Compress */
{"-bsdcomp", 0, setnobsdcomp}, /* don't allow BSD-Compress */
+ {"deflate", 1, setdeflate}, /* request Deflate compression */
+ {"nodeflate", 0, setnodeflate}, /* don't allow Deflate compression */
+ {"-deflate", 0, setnodeflate}, /* don't allow Deflate compression */
{"predictor1", 0, setpred1comp}, /* request Predictor-1 */
+ {"nopredictor1", 0, setnopred1comp},/* don't allow Predictor-1 */
{"-predictor1", 0, setnopred1comp}, /* don't allow Predictor-1 */
{"ipparam", 1, setipparam}, /* set ip script parameter */
{"papcrypt", 0, setpapcrypt}, /* PAP passwords encrypted */
+ {"idle", 1, setidle}, /* idle time limit (seconds) */
+ {"holdoff", 1, setholdoff}, /* set holdoff time (seconds) */
#ifdef IPX_CHANGE
{"ipx-network", 1, setipxnetwork}, /* IPX network number */
#if 0
{"ipx-compression", 1, setipxcompression}, /* IPX compression number */
#endif
+ {"ipx", 0, setipxproto}, /* Enable IPXCP (and IPX) */
+ {"noipx", 0, resetipxproto}, /* Disable IPXCP (and IPX) */
{"+ipx", 0, setipxproto}, /* Enable IPXCP (and IPX) */
{"-ipx", 0, resetipxproto}, /* Disable IPXCP (and IPX) */
#endif /* IPX_CHANGE */
-#ifdef _linux_
- {"idle-disconnect", 1, setidle}, /* seconds for disconnect of idle IP */
-#endif
-
#ifdef USE_MS_DNS
{"ms-dns", 1, setdnsaddr}, /* DNS address(es) for the peer's use */
#endif
static char *usage_string = "\
pppd version %s patch level %d%s\n\
-Usage: %s [ arguments ], where arguments are:\n\
+Usage: %s [ options ], where options are:\n\
<device> Communicate over the named device\n\
<speed> Set the baud rate to <speed>\n\
<loc>:<rem> Set the local and/or remote interface IP\n\
See pppd(8) for more options.\n\
";
+static char *current_option; /* the name of the option being parsed */
+static int privileged_option; /* set iff the current option came from root */
+static char *option_source; /* string saying where the option came from */
/*
- * parse_args - parse a string of arguments, from the command
- * line or from a file.
+ * parse_args - parse a string of arguments from the command line.
*/
int
parse_args(argc, argv)
int argc;
char **argv;
{
- char *arg, *val;
+ char *arg;
struct cmd *cmdp;
int ret;
+ privileged_option = privileged;
+ option_source = "command line";
while (argc > 0) {
arg = *argv++;
--argc;
if (cmdp->cmd_name != NULL) {
if (argc < cmdp->num_args) {
- fprintf(stderr, "Too few parameters for command %s\n", arg);
+ option_error("too few parameters for option %s", arg);
return 0;
}
+ current_option = arg;
if (!(*cmdp->cmd_func)(argv))
return 0;
argc -= cmdp->num_args;
/*
* Maybe a tty name, speed or IP address?
*/
- if ((ret = setdevname(arg)) == 0
+ if ((ret = setdevname(arg, 0)) == 0
&& (ret = setspeed(arg)) == 0
&& (ret = setipaddr(arg)) == 0) {
- fprintf(stderr, "%s: unrecognized command\n", arg);
+ option_error("unrecognized option '%s'", arg);
usage();
return 0;
}
return 1;
}
+/*
+ * scan_args - scan the command line arguments to get the tty name,
+ * if specified.
+ */
+void
+scan_args(argc, argv)
+ int argc;
+ char **argv;
+{
+ char *arg;
+ struct cmd *cmdp;
+
+ while (argc > 0) {
+ arg = *argv++;
+ --argc;
+
+ /* Skip options and their arguments */
+ for (cmdp = cmds; cmdp->cmd_name; cmdp++)
+ if (!strcmp(arg, cmdp->cmd_name))
+ break;
+
+ if (cmdp->cmd_name != NULL) {
+ argc -= cmdp->num_args;
+ argv += cmdp->num_args;
+ continue;
+ }
+
+ /* Check if it's a tty name and copy it if so */
+ (void) setdevname(arg, 1);
+ }
+}
+
/*
* usage - print out a message telling how to use the program.
*/
void
usage()
{
- fprintf(stderr, usage_string, VERSION, PATCHLEVEL, IMPLEMENTATION,
- progname);
+ if (phase == PHASE_INITIALIZE)
+ fprintf(stderr, usage_string, VERSION, PATCHLEVEL, IMPLEMENTATION,
+ progname);
}
/*
* and interpret them.
*/
int
-options_from_file(filename, must_exist, check_prot)
+options_from_file(filename, must_exist, check_prot, priv)
char *filename;
int must_exist;
int check_prot;
+ int priv;
{
FILE *f;
int i, newline, ret;
struct cmd *cmdp;
+ int oldpriv;
char *argv[MAXARGS];
char args[MAXARGS][MAXWORDLEN];
char cmd[MAXWORDLEN];
if ((f = fopen(filename, "r")) == NULL) {
if (!must_exist && errno == ENOENT)
return 1;
- perror(filename);
+ option_error("Can't open options file %s: %m", filename);
return 0;
}
if (check_prot && !readable(fileno(f))) {
- fprintf(stderr, "%s: access denied\n", filename);
+ option_error("Can't open options file %s: access denied", filename);
fclose(f);
return 0;
}
+ oldpriv = privileged_option;
+ privileged_option = priv;
+ ret = 0;
while (getword(f, cmd, &newline, filename)) {
/*
* First see if it's a command.
if (cmdp->cmd_name != NULL) {
for (i = 0; i < cmdp->num_args; ++i) {
if (!getword(f, args[i], &newline, filename)) {
- fprintf(stderr,
- "In file %s: too few parameters for command %s\n",
- filename, cmd);
- fclose(f);
- return 0;
+ option_error(
+ "In file %s: too few parameters for option '%s'",
+ filename, cmd);
+ goto err;
}
argv[i] = args[i];
}
- if (!(*cmdp->cmd_func)(argv)) {
- fclose(f);
- return 0;
- }
+ current_option = cmd;
+ if (!(*cmdp->cmd_func)(argv))
+ goto err;
} else {
/*
* Maybe a tty name, speed or IP address?
*/
- if ((ret = setdevname(cmd)) == 0
- && (ret = setspeed(cmd)) == 0
- && (ret = setipaddr(cmd)) == 0) {
- fprintf(stderr, "In file %s: unrecognized command %s\n",
- filename, cmd);
- fclose(f);
- return 0;
+ if ((i = setdevname(cmd, 0)) == 0
+ && (i = setspeed(cmd)) == 0
+ && (i = setipaddr(cmd)) == 0) {
+ option_error("In file %s: unrecognized option '%s'",
+ filename, cmd);
+ goto err;
}
- if (ret < 0) /* error */
- return 0;
+ if (i < 0) /* error */
+ goto err;
}
}
- return 1;
+ ret = 1;
+
+err:
+ fclose(f);
+ privileged_option = oldpriv;
+ return ret;
}
/*
strcpy(path, user);
strcat(path, "/");
strcat(path, file);
- ret = options_from_file(path, 0, 1);
+ ret = options_from_file(path, 0, 1, privileged);
free(path);
return ret;
}
int
options_for_tty()
{
- char *dev, *path;
+ char *dev, *path, *p;
int ret;
- dev = strrchr(devnam, '/');
- if (dev == NULL)
- dev = devnam;
- else
- ++dev;
+ dev = devnam;
+ if (strncmp(dev, "/dev/", 5) == 0)
+ dev += 5;
if (strcmp(dev, "tty") == 0)
return 1; /* don't look for /etc/ppp/options.tty */
path = malloc(strlen(_PATH_TTYOPT) + strlen(dev) + 1);
if (path == NULL)
novm("tty init file name");
strcpy(path, _PATH_TTYOPT);
- strcat(path, dev);
- ret = options_from_file(path, 0, 0);
+ /* Turn slashes into dots, for Solaris case (e.g. /dev/term/a) */
+ for (p = path + strlen(path); *dev != 0; ++dev)
+ *p++ = (*dev == '/'? '.': *dev);
+ *p = 0;
+ ret = options_from_file(path, 0, 0, 1);
free(path);
return ret;
}
+/*
+ * option_error - print a message about an error in an option.
+ * The message is logged, and also sent to
+ * stderr if phase == PHASE_INITIALIZE.
+ */
+void
+option_error __V((char *fmt, ...))
+{
+ va_list args;
+ int n;
+ char buf[256];
+
+#if __STDC__
+ va_start(args, fmt);
+#else
+ char *fmt;
+ va_start(args);
+ fmt = va_arg(args, char *);
+#endif
+ vfmtmsg(buf, sizeof(buf), fmt, args);
+ va_end(args);
+ if (phase == PHASE_INITIALIZE)
+ fprintf(stderr, "%s: %s\n", progname, buf);
+ syslog(LOG_ERR, "%s", buf);
+}
+
/*
* readable - check if a file is readable by the real user.
*/
* Quotes, white-space and \ may be escaped with \.
* \<newline> is ignored.
*/
-
int
getword(f, word, newlinep, filename)
FILE *f;
if (ferror(f)) {
if (errno == 0)
errno = EIO;
- perror(filename);
+ option_error("Error reading %s: %m", filename);
die(1);
}
/*
* Warn if the word was too long, and append a terminating null.
*/
if (len >= MAXWORDLEN) {
- fprintf(stderr, "%s: warning: word in file %s too long (%.20s...)\n",
- progname, filename, word);
+ option_error("warning: word in file %s too long (%.20s...)",
+ filename, word);
len = MAXWORDLEN - 1;
}
word[len] = 0;
*valp = strtoul(str, &ptr, base);
if (ptr == str) {
- fprintf(stderr, "%s: invalid number: %s\n", progname, str);
+ option_error("invalid numeric parameter '%s' for %s option",
+ str, current_option);
return 0;
}
return 1;
/*
- * The following procedures execute commands.
+ * The following procedures parse options.
*/
/*
readfile(argv)
char **argv;
{
- return options_from_file(*argv, 1, 1);
+ return options_from_file(*argv, 1, 1, privileged_option);
}
+/*
+ * callfile - take commands from /etc/ppp/peers/<name>.
+ * Name may not contain /../, start with / or ../, or end in /..
+ */
+static int
+callfile(argv)
+ char **argv;
+{
+ char *fname, *arg, *p;
+ int l, ok;
+
+ arg = *argv;
+ ok = 1;
+ if (arg[0] == '/' || arg[0] == 0)
+ ok = 0;
+ else {
+ for (p = arg; *p != 0; ) {
+ if (p[0] == '.' && p[1] == '.' && (p[2] == '/' || p[2] == 0)) {
+ ok = 0;
+ break;
+ }
+ while (*p != '/' && *p != 0)
+ ++p;
+ if (*p == '/')
+ ++p;
+ }
+ }
+ if (!ok) {
+ option_error("call option value may not contain .. or start with /");
+ return 0;
+ }
+
+ l = strlen(arg) + strlen(_PATH_PEERFILES) + 1;
+ if ((fname = (char *) malloc(l)) == NULL)
+ novm("call file name");
+ strcpy(fname, _PATH_PEERFILES);
+ strcat(fname, arg);
+
+ ok = options_from_file(fname, 1, 1, 1);
+
+ free(fname);
+ return ok;
+}
+
+
/*
* setdebug - Set debug (command line argument).
*/
if (!number_option(*argv, &mtu, 0))
return 0;
if (mtu < MINMRU || mtu > MAXMRU) {
- fprintf(stderr, "mtu option value of %ld is too %s\n", mtu,
- (mtu < MINMRU? "small": "large"));
+ option_error("mtu option value of %u is too %s", mtu,
+ (mtu < MINMRU? "small": "large"));
return 0;
}
lcp_allowoptions[0].mru = mtu;
static int
nopap()
{
- lcp_allowoptions[0].neg_upap = 0;
+ refuse_pap = 1;
return (1);
}
reqpap()
{
lcp_wantoptions[0].neg_upap = 1;
- auth_required = 1;
+ setauth();
return 1;
}
-
+#if OLD_OPTIONS
/*
* setupapfile - specifies UPAP info for authenticating with peer.
*/
/* open user info file */
if ((ufile = fopen(*argv, "r")) == NULL) {
- fprintf(stderr, "unable to open user login data file %s\n", *argv);
+ option_error("unable to open user login data file %s", *argv);
return 0;
}
if (!readable(fileno(ufile))) {
- fprintf(stderr, "%s: access denied\n", *argv);
+ option_error("%s: access denied", *argv);
return 0;
}
check_access(ufile, *argv);
/* get username */
if (fgets(user, MAXNAMELEN - 1, ufile) == NULL
|| fgets(passwd, MAXSECRETLEN - 1, ufile) == NULL){
- fprintf(stderr, "Unable to read user login data file %s.\n", *argv);
+ option_error("unable to read user login data file %s", *argv);
return 0;
}
fclose(ufile);
return (1);
}
-
+#endif
/*
* nochap - Disable CHAP authentication with peer.
static int
nochap()
{
- lcp_allowoptions[0].neg_chap = 0;
+ refuse_chap = 1;
return (1);
}
reqchap()
{
lcp_wantoptions[0].neg_chap = 1;
- auth_required = 1;
+ setauth();
return (1);
}
if (!int_option(*argv, &value))
return 0;
if (value < 2 || value > 16) {
- fprintf(stderr, "pppd: vj-max-slots value must be between 2 and 16\n");
+ option_error("vj-max-slots value must be between 2 and 16");
return 0;
}
ipcp_wantoptions [0].maxslotindex =
{
connector = strdup(*argv);
if (connector == NULL)
- novm("connector string");
-
+ novm("connect script");
+ connector_info.priv = privileged_option;
+ connector_info.source = option_source;
+
return (1);
}
{
disconnector = strdup(*argv);
if (disconnector == NULL)
- novm("disconnector string");
+ novm("disconnect script");
+ disconnector_info.priv = privileged_option;
+ disconnector_info.source = option_source;
return (1);
}
+/*
+ * setwelcomer - Set a program to welcome a client after connection
+ */
+static int
+setwelcomer(argv)
+ char **argv;
+{
+ welcomer = strdup(*argv);
+ if (welcomer == NULL)
+ novm("welcome script");
+ welcomer_info.priv = privileged_option;
+ welcomer_info.source = option_source;
+
+ return (1);
+}
+
/*
* setmaxconnect - Set the maximum connect time
*/
int value;
if (!int_option(*argv, &value))
- return 0;
+ return 0;
if (value < 0) {
- fprintf(stderr, "pppd: maxconnect time must be positive\n");
- return 0;
+ option_error("maxconnect time must be positive");
+ return 0;
+ }
+ if (maxconnect > 0 && (value == 0 || value > maxconnect)) {
+ option_error("maxconnect time cannot be increased");
+ return 0;
}
maxconnect = value;
return 1;
setdomain(argv)
char **argv;
{
+ if (!privileged_option) {
+ option_error("using the domain option requires root privilege");
+ return 0;
+ }
gethostname(hostname, MAXNAMELEN);
if (**argv != 0) {
if (**argv != '.')
while (*p) {
n = strtol(p, &endp, 16);
if (p == endp) {
- fprintf(stderr, "%s: invalid hex number: %s\n", progname, p);
+ option_error("escape parameter contains invalid hex number '%s'",
+ p);
return 0;
}
p = endp;
if (n < 0 || 0x20 <= n && n <= 0x3F || n == 0x5E || n > 0xFF) {
- fprintf(stderr, "%s: can't escape character 0x%x\n", progname, n);
+ option_error("can't escape character 0x%x", n);
ret = 0;
} else
xmit_accm[0][n >> 5] |= 1 << (n & 0x1F);
/*
* setdevname - Set the device name.
*/
-int
-setdevname(cp)
+static int
+setdevname(cp, quiet)
char *cp;
+ int quiet;
{
struct stat statbuf;
- char *tty, *ttyname();
char dev[MAXPATHLEN];
-
+
+ if (*cp == 0)
+ return 0;
+
if (strncmp("/dev/", cp, 5) != 0) {
strcpy(dev, "/dev/");
strncat(dev, cp, MAXPATHLEN - 5);
* Check if there is a device by this name.
*/
if (stat(cp, &statbuf) < 0) {
- if (errno == ENOENT)
+ if (errno == ENOENT || quiet)
return 0;
- syslog(LOG_ERR, cp);
+ option_error("Couldn't stat %s: %m", cp);
return -1;
}
-
+
(void) strncpy(devnam, cp, MAXPATHLEN);
devnam[MAXPATHLEN-1] = 0;
default_device = FALSE;
+ devnam_info.priv = privileged_option;
+ devnam_info.source = option_source;
return 1;
}
/*
* setipaddr - Set the IP address
*/
-int
+static int
setipaddr(arg)
char *arg;
{
*colon = '\0';
if ((local = inet_addr(arg)) == -1) {
if ((hp = gethostbyname(arg)) == NULL) {
- fprintf(stderr, "unknown host: %s\n", arg);
+ option_error("unknown host: %s", arg);
return -1;
} else {
local = *(u_int32_t *)hp->h_addr;
- if (our_name[0] == 0) {
- strncpy(our_name, arg, MAXNAMELEN);
- our_name[MAXNAMELEN-1] = 0;
- }
}
}
if (bad_ip_adrs(local)) {
- fprintf(stderr, "bad local IP address %s\n", ip_ntoa(local));
+ option_error("bad local IP address %s", ip_ntoa(local));
return -1;
}
if (local != 0)
if (*++colon != '\0') {
if ((remote = inet_addr(colon)) == -1) {
if ((hp = gethostbyname(colon)) == NULL) {
- fprintf(stderr, "unknown host: %s\n", colon);
+ option_error("unknown host: %s", colon);
return -1;
} else {
remote = *(u_int32_t *)hp->h_addr;
}
}
if (bad_ip_adrs(remote)) {
- fprintf(stderr, "bad remote IP address %s\n", ip_ntoa(remote));
+ option_error("bad remote IP address %s", ip_ntoa(remote));
return -1;
}
if (remote != 0)
}
-/*
- * setipdefault - default our local IP address based on our hostname.
- */
-void
-setipdefault()
-{
- struct hostent *hp;
- u_int32_t local;
- ipcp_options *wo = &ipcp_wantoptions[0];
-
- /*
- * If local IP address already given, don't bother.
- */
- if (wo->ouraddr != 0 || disable_defaultip)
- return;
-
- /*
- * Look up our hostname (possibly with domain name appended)
- * and take the first IP address as our local IP address.
- * If there isn't an IP address for our hostname, too bad.
- */
- wo->accept_local = 1; /* don't insist on this default value */
- if ((hp = gethostbyname(hostname)) == NULL)
- return;
- local = *(u_int32_t *)hp->h_addr;
- if (local != 0 && !bad_ip_adrs(local))
- wo->ouraddr = local;
-}
-
-
/*
* setnetmask - set the netmask to be used on the interface.
*/
u_int32_t mask;
if ((mask = inet_addr(*argv)) == -1 || (netmask & ~mask) != 0) {
- fprintf(stderr, "Invalid netmask %s\n", *argv);
+ option_error("invalid netmask value '%s'", *argv);
return 0;
}
return (1);
}
+static int
+setdemand()
+{
+ demand = 1;
+ persist = 1;
+ return 1;
+}
+
static int
setmodem()
{
setname(argv)
char **argv;
{
+ if (!privileged_option) {
+ option_error("using the name option requires root privilege");
+ return 0;
+ }
if (our_name[0] == 0) {
strncpy(our_name, argv[0], MAXNAMELEN);
our_name[MAXNAMELEN-1] = 0;
setauth()
{
auth_required = 1;
+ if (privileged_option > auth_req_info.priv) {
+ auth_req_info.priv = privileged_option;
+ auth_req_info.source = option_source;
+ }
+ return 1;
+}
+
+static int
+setnoauth()
+{
+ if (auth_required && privileged_option < auth_req_info.priv) {
+ option_error("cannot override auth option set by %s",
+ auth_req_info.source);
+ return 0;
+ }
+ auth_required = 0;
return 1;
}
setdefaultroute()
{
if (!ipcp_allowoptions[0].default_route) {
- fprintf(stderr, "%s: defaultroute option is disabled\n", progname);
+ option_error("defaultroute option is disabled");
return 0;
}
ipcp_wantoptions[0].default_route = 1;
setproxyarp()
{
if (!ipcp_allowoptions[0].proxy_arp) {
- fprintf(stderr, "%s: proxyarp option is disabled\n", progname);
+ option_error("proxyarp option is disabled");
return 0;
}
ipcp_wantoptions[0].proxy_arp = 1;
return 1;
}
+static int
+setnopersist()
+{
+ persist = 0;
+ return 1;
+}
+
static int
setdologin()
{
return int_option(*argv, &chap[0].chal_interval);
}
+static int
+noccp()
+{
+ ccp_protent.enabled_flag = 0;
+ return 1;
+}
+
static int
setbsdcomp(argv)
char **argv;
abits = strtol(str, &endp, 0);
}
if (*endp != 0 || endp == str) {
- fprintf(stderr, "%s: invalid argument format for bsdcomp option\n",
- progname);
+ option_error("invalid parameter '%s' for bsdcomp option", *argv);
return 0;
}
if (rbits != 0 && (rbits < BSD_MIN_BITS || rbits > BSD_MAX_BITS)
|| abits != 0 && (abits < BSD_MIN_BITS || abits > BSD_MAX_BITS)) {
- fprintf(stderr, "%s: bsdcomp option values must be 0 or %d .. %d\n",
- progname, BSD_MIN_BITS, BSD_MAX_BITS);
+ option_error("bsdcomp option values must be 0 or %d .. %d",
+ BSD_MIN_BITS, BSD_MAX_BITS);
return 0;
}
if (rbits > 0) {
return 1;
}
+static int
+setdeflate(argv)
+ char **argv;
+{
+ int rbits, abits;
+ char *str, *endp;
+
+ str = *argv;
+ abits = rbits = strtol(str, &endp, 0);
+ if (endp != str && *endp == ',') {
+ str = endp + 1;
+ abits = strtol(str, &endp, 0);
+ }
+ if (*endp != 0 || endp == str) {
+ option_error("invalid parameter '%s' for deflate option", *argv);
+ return 0;
+ }
+ if (rbits != 0 && (rbits < DEFLATE_MIN_SIZE || rbits > DEFLATE_MAX_SIZE)
+ || abits != 0 && (abits < DEFLATE_MIN_SIZE
+ || abits > DEFLATE_MAX_SIZE)) {
+ option_error("deflate option values must be 0 or %d .. %d",
+ DEFLATE_MIN_SIZE, DEFLATE_MAX_SIZE);
+ return 0;
+ }
+ if (rbits > 0) {
+ ccp_wantoptions[0].deflate = 1;
+ ccp_wantoptions[0].deflate_size = rbits;
+ } else
+ ccp_wantoptions[0].deflate = 0;
+ if (abits > 0) {
+ ccp_allowoptions[0].deflate = 1;
+ ccp_allowoptions[0].deflate_size = abits;
+ } else
+ ccp_allowoptions[0].deflate = 0;
+ return 1;
+}
+
+static int
+setnodeflate()
+{
+ ccp_wantoptions[0].deflate = 0;
+ ccp_allowoptions[0].deflate = 0;
+ return 1;
+}
+
static int
setpred1comp()
{
return 1;
}
-#ifdef _linux_
-static int setidle (argv)
+static int
+setidle(argv)
char **argv;
{
return int_option(*argv, &idle_time_limit);
}
-#endif
+static int
+setholdoff(argv)
+ char **argv;
+{
+ return int_option(*argv, &holdoff);
+}
#ifdef IPX_CHANGE
static int
while (*src) {
ch = *src++;
if (! isalnum (ch) && ch != '_') {
- fprintf (stderr,
- "%s: IPX router name must be alphanumeric or _\n",
- progname);
+ option_error("IPX router name must be alphanumeric or _");
return 0;
}
if (count >= sizeof (ipxcp_wantoptions[0].name)) {
- fprintf (stderr,
- "%s: IPX router name is limited to %d characters\n",
- progname,
- sizeof (ipxcp_wantoptions[0].name) - 1);
+ option_error("IPX router name is limited to %d characters",
+ sizeof (ipxcp_wantoptions[0].name) - 1);
return 0;
}
return 1;
}
- fprintf(stderr, "%s: invalid argument for ipx-node option\n",
- progname);
+ option_error("invalid parameter '%s' for ipx-node option", *argv);
return 0;
}
static int
setipxproto()
{
- ipx_enabled = 1; /* Enable IPXCP and IPX protocol */
+ ipxcp_protent.enabled_flag = 1;
return 1;
}
static int
resetipxproto()
{
- ipx_enabled = 0; /* Disable IPXCP and IPX protocol */
+ ipxcp_protent.enabled_flag = 0;
return 1;
}
#endif /* IPX_CHANGE */
dns = inet_addr(*argv);
if (dns == -1) {
if ((hp = gethostbyname(*argv)) == NULL) {
- fprintf(stderr, "Invalid DNS Address %s\n", *argv);
+ option_error("invalid address parameter '%s' for ms-dns option",
+ *argv);
return 0;
}
dns = *(u_int32_t *)hp->h_addr;