X-Git-Url: http://git.ozlabs.org/?p=ppp.git;a=blobdiff_plain;f=pppd%2Foptions.c;h=43f8e3df513569020d6fbb140a41e33f33b73fcb;hp=ba5bfe6e44d78dae361d771019e267ae84308c68;hb=c5871dbfa014bb554c101e65150c48fc8ba80c7b;hpb=7e37b204c4f1e186f276dd9f0822cb86dfce406a diff --git a/pppd/options.c b/pppd/options.c index ba5bfe6..43f8e3d 100644 --- a/pppd/options.c +++ b/pppd/options.c @@ -18,9 +18,10 @@ */ #ifndef lint -static char rcsid[] = "$Id: options.c,v 1.29 1996/01/18 03:35:38 paulus Exp $"; +static char rcsid[] = "$Id: options.c,v 1.32 1996/07/01 01:18:23 paulus Exp $"; #endif +#include #include #include #include @@ -34,6 +35,7 @@ static char rcsid[] = "$Id: options.c,v 1.29 1996/01/18 03:35:38 paulus Exp $"; #include #include #include +#include #include "pppd.h" #include "pathnames.h" @@ -97,10 +99,14 @@ 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 */ /* * 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)); @@ -111,7 +117,9 @@ static int setnovjccomp __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 *)); @@ -169,6 +177,7 @@ static int setipcpaccl __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 **)); @@ -202,9 +211,9 @@ static int setdnsaddr __P((char **)); #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(); +static void option_error __P((char *fmt, ...)); /* * Valid arguments. @@ -214,23 +223,38 @@ static struct cmd { 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 */ @@ -240,6 +264,7 @@ static struct cmd { {"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 */ @@ -260,8 +285,10 @@ static struct cmd { {"auth", 0, setauth}, /* Require authentication from peer */ {"file", 1, readfile}, /* Take options from a 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 */ {"demand", 0, setdemand}, /* Dial on demand */ @@ -285,11 +312,16 @@ static struct cmd { {"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 */ @@ -311,14 +343,12 @@ static struct cmd { #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 @@ -333,7 +363,7 @@ static struct cmd { 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\ Communicate over the named device\n\ Set the baud rate to \n\ : Set the local and/or remote interface IP\n\ @@ -350,6 +380,8 @@ Usage: %s [ arguments ], where arguments are:\n\ See pppd(8) for more options.\n\ "; +static char *current_option; /* the name of the option being parsed */ + /* * parse_args - parse a string of arguments, from the command @@ -360,7 +392,7 @@ parse_args(argc, argv) int argc; char **argv; { - char *arg, *val; + char *arg; struct cmd *cmdp; int ret; @@ -377,9 +409,10 @@ parse_args(argc, argv) 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; @@ -389,10 +422,10 @@ parse_args(argc, argv) /* * 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; } @@ -403,14 +436,47 @@ parse_args(argc, argv) 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); } /* @@ -433,11 +499,11 @@ options_from_file(filename, must_exist, check_prot) 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; } @@ -453,14 +519,15 @@ options_from_file(filename, must_exist, check_prot) 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); + option_error( + "In file %s: too few parameters for option '%s'", + filename, cmd); fclose(f); return 0; } argv[i] = args[i]; } + current_option = cmd; if (!(*cmdp->cmd_func)(argv)) { fclose(f); return 0; @@ -470,11 +537,11 @@ options_from_file(filename, must_exist, check_prot) /* * Maybe a tty name, speed or IP address? */ - if ((ret = setdevname(cmd)) == 0 + if ((ret = setdevname(cmd, 0)) == 0 && (ret = setspeed(cmd)) == 0 && (ret = setipaddr(cmd)) == 0) { - fprintf(stderr, "In file %s: unrecognized command %s\n", - filename, cmd); + option_error("In file %s: unrecognized option '%s'", + filename, cmd); fclose(f); return 0; } @@ -539,6 +606,32 @@ options_for_tty() 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. */ @@ -786,7 +879,7 @@ getword(f, word, newlinep, filename) if (ferror(f)) { if (errno == 0) errno = EIO; - perror(filename); + option_error("Error reading %s: %m", filename); die(1); } /* @@ -801,8 +894,8 @@ getword(f, word, newlinep, filename) * 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; @@ -826,7 +919,8 @@ number_option(str, valp, base) *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; @@ -853,7 +947,7 @@ int_option(str, valp) /* - * The following procedures execute commands. + * The following procedures parse options. */ /* @@ -993,8 +1087,8 @@ setmtu(argv) 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; @@ -1044,7 +1138,7 @@ setsilent() static int nopap() { - lcp_allowoptions[0].neg_upap = 0; + refuse_pap = 1; return (1); } @@ -1060,7 +1154,7 @@ reqpap() return 1; } - +#if OLD_OPTIONS /* * setupapfile - specifies UPAP info for authenticating with peer. */ @@ -1075,11 +1169,11 @@ setupapfile(argv) /* 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); @@ -1087,7 +1181,7 @@ setupapfile(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); @@ -1102,7 +1196,7 @@ setupapfile(argv) return (1); } - +#endif /* * nochap - Disable CHAP authentication with peer. @@ -1110,7 +1204,7 @@ setupapfile(argv) static int nochap() { - lcp_allowoptions[0].neg_chap = 0; + refuse_chap = 1; return (1); } @@ -1163,7 +1257,7 @@ setvjslots(argv) 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 = @@ -1226,7 +1320,7 @@ setmaxconnect(argv) if (!int_option(*argv, &value)) return 0; if (value < 0) { - fprintf(stderr, "pppd: maxconnect time must be positive\n"); + option_error("maxconnect time must be positive"); return 0; } maxconnect = value; @@ -1283,12 +1377,13 @@ setescape(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); @@ -1320,14 +1415,17 @@ setspeed(arg) /* * 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); @@ -1339,9 +1437,9 @@ setdevname(cp) * 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; } @@ -1356,7 +1454,7 @@ setdevname(cp) /* * setipaddr - Set the IP address */ -int +static int setipaddr(arg) char *arg; { @@ -1378,7 +1476,7 @@ setipaddr(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; @@ -1389,7 +1487,7 @@ setipaddr(arg) } } 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) @@ -1403,7 +1501,7 @@ setipaddr(arg) 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; @@ -1414,7 +1512,7 @@ setipaddr(arg) } } 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) @@ -1468,7 +1566,7 @@ setnetmask(argv) 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; } @@ -1582,7 +1680,7 @@ static int 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; @@ -1601,7 +1699,7 @@ static int 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; @@ -1749,6 +1847,13 @@ setchapintv(argv) return int_option(*argv, &chap[0].chal_interval); } +static int +noccp() +{ + ccp_protent.enabled_flag = 0; + return 1; +} + static int setbsdcomp(argv) char **argv; @@ -1763,14 +1868,13 @@ setbsdcomp(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) { @@ -1808,15 +1912,14 @@ setdeflate(argv) abits = strtol(str, &endp, 0); } if (*endp != 0 || endp == str) { - fprintf(stderr, "%s: invalid argument format for deflate option\n", - progname); + 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)) { - fprintf(stderr, "%s: deflate option values must be 0 or %d .. %d\n", - progname, DEFLATE_MIN_SIZE, 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) { @@ -1915,17 +2018,13 @@ setipxname (argv) 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; } @@ -2036,22 +2135,21 @@ setipxnode(argv) 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 */ @@ -2071,7 +2169,8 @@ setdnsaddr(argv) 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;