X-Git-Url: http://git.ozlabs.org/?p=ppp.git;a=blobdiff_plain;f=pppd%2Foptions.c;h=ae12981dffdf34681dc4a0ec441687ffda7b09db;hp=e29dbb051f0f7b03413cc55716cdee9822e93374;hb=289e4c84880ca19342a65ba5703d62b27dc69950;hpb=b6101aaab41daebf1df13747af0923f51d5c549b diff --git a/pppd/options.c b/pppd/options.c index e29dbb0..ae12981 100644 --- a/pppd/options.c +++ b/pppd/options.c @@ -18,9 +18,10 @@ */ #ifndef lint -static char rcsid[] = "$Id: options.c,v 1.28 1996/01/18 03:22:22 paulus Exp $"; +static char rcsid[] = "$Id: options.c,v 1.41 1998/03/25 01:29:05 paulus Exp $"; #endif +#include #include #include #include @@ -34,6 +35,11 @@ static char rcsid[] = "$Id: options.c,v 1.28 1996/01/18 03:22:22 paulus Exp $"; #include #include #include +#include +#ifdef PPP_FILTER +#include +#include /* XXX: To get struct pcap */ +#endif #include "pppd.h" #include "pathnames.h" @@ -44,6 +50,9 @@ static char rcsid[] = "$Id: options.c,v 1.28 1996/01/18 03:22:22 paulus Exp $"; #include "upap.h" #include "chap.h" #include "ccp.h" +#ifdef CBCP_SUPPORT +#include "cbcp.h" +#endif #ifdef IPX_CHANGE #include "ipxcp.h" @@ -65,6 +74,9 @@ char *strdup __P((char *)); /* * Option variables and default values. */ +#ifdef PPP_FILTER +int dflag = 0; /* Tell libpcap we want debugging */ +#endif int debug = 0; /* Debug flag */ int kdebugflag = 0; /* Tell kernel to print debug messages */ int default_device = 1; /* Using /dev/tty or equivalent */ @@ -90,6 +102,7 @@ int lcp_echo_interval = 0; /* Interval between LCP echo-requests */ int lcp_echo_fails = 0; /* Tolerance to unanswered echo-requests */ char our_name[MAXNAMELEN]; /* Our name for authentication purposes */ char remote_name[MAXNAMELEN]; /* Peer's name for authentication */ +int explicit_remote = 0; /* User specified explicit remote name */ 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 */ @@ -97,60 +110,88 @@ 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 MSLANMAN +int ms_lanman = 0; /* Nonzero if use LanMan password instead of NT */ + /* Has meaning only with MS-CHAP challenges */ +#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; +#ifdef PPP_FILTER +struct bpf_program pass_filter;/* Filter program for packets to pass */ +struct bpf_program active_filter; /* Filter program for link-active pkts */ +pcap_t pc; /* Fake struct pcap so we can compile expr */ +#endif /* * Prototypes */ -static int setdebug __P((void)); +static int setdevname __P((char *, int)); +static int setipaddr __P((char *)); +static int setspeed __P((char *)); +static int setdebug __P((char **)); static int setkdebug __P((char **)); -static int setpassive __P((void)); -static int setsilent __P((void)); -static int noopt __P((void)); -static int setnovj __P((void)); -static int setnovjccomp __P((void)); +static int setpassive __P((char **)); +static int setsilent __P((char **)); +static int noopt __P((char **)); +static int setnovj __P((char **)); +static int setnovjccomp __P((char **)); static int setvjslots __P((char **)); -static int reqpap __P((void)); -static int nopap __P((void)); +static int reqpap __P((char **)); +static int nopap __P((char **)); +#ifdef OLD_OPTIONS static int setupapfile __P((char **)); -static int nochap __P((void)); -static int reqchap __P((void)); -static int setspeed __P((char *)); -static int noaccomp __P((void)); -static int noasyncmap __P((void)); -static int noip __P((void)); -static int nomagicnumber __P((void)); +#endif +static int nochap __P((char **)); +static int reqchap __P((char **)); +static int noaccomp __P((char **)); +static int noasyncmap __P((char **)); +static int noip __P((char **)); +static int nomagicnumber __P((char **)); static int setasyncmap __P((char **)); static int setescape __P((char **)); static int setmru __P((char **)); static int setmtu __P((char **)); -static int nomru __P((void)); -static int nopcomp __P((void)); +#ifdef CBCP_SUPPORT +static int setcbcp __P((char **)); +#endif +static int nomru __P((char **)); +static int nopcomp __P((char **)); 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 setcrtscts __P((void)); -static int setnocrtscts __P((void)); -static int setxonxoff __P((void)); -static int setnodetach __P((void)); -static int setmodem __P((void)); -static int setlocal __P((void)); -static int setlock __P((void)); +static int setcrtscts __P((char **)); +static int setnocrtscts __P((char **)); +static int setxonxoff __P((char **)); +static int setnodetach __P((char **)); +static int setmodem __P((char **)); +static int setlocal __P((char **)); +static int setlock __P((char **)); static int setname __P((char **)); static int setuser __P((char **)); static int setremote __P((char **)); -static int setauth __P((void)); +static int setauth __P((char **)); +static int setnoauth __P((char **)); static int readfile __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 setdologin __P((void)); -static int setusehostname __P((void)); -static int setnoipdflt __P((void)); +static int callfile __P((char **)); +static int setdefaultroute __P((char **)); +static int setnodefaultroute __P((char **)); +static int setproxyarp __P((char **)); +static int setnoproxyarp __P((char **)); +static int setpersist __P((char **)); +static int setnopersist __P((char **)); +static int setdologin __P((char **)); +static int setusehostname __P((char **)); +static int setnoipdflt __P((char **)); static int setlcptimeout __P((char **)); static int setlcpterm __P((char **)); static int setlcpconf __P((char **)); @@ -165,28 +206,40 @@ static int setpapreqtime __P((char **)); static int setchaptimeout __P((char **)); static int setchapchal __P((char **)); static int setchapintv __P((char **)); -static int setipcpaccl __P((void)); -static int setipcpaccr __P((void)); +static int setipcpaccl __P((char **)); +static int setipcpaccr __P((char **)); static int setlcpechointv __P((char **)); static int setlcpechofails __P((char **)); +static int noccp __P((char **)); static int setbsdcomp __P((char **)); -static int setnobsdcomp __P((void)); +static int setnobsdcomp __P((char **)); 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 setnodeflate __P((char **)); +static int setnodeflatedraft __P((char **)); +static int setdemand __P((char **)); +static int setpred1comp __P((char **)); +static int setnopred1comp __P((char **)); static int setipparam __P((char **)); -static int setpapcrypt __P((void)); +static int setpapcrypt __P((char **)); static int setidle __P((char **)); static int setholdoff __P((char **)); +static int setdnsaddr __P((char **)); +static int resetipxproto __P((char **)); +static int setwinsaddr __P((char **)); +static int showversion __P((char **)); +static int showhelp __P((char **)); + +#ifdef PPP_FILTER +static int setpdebug __P((char **)); +static int setpassfilter __P((char **)); +static int setactivefilter __P((char **)); +#endif #ifdef IPX_CHANGE -static int setipxproto __P((void)); -static int resetipxproto __P((void)); -static int setipxanet __P((void)); -static int setipxalcl __P((void)); -static int setipxarmt __P((void)); +static int setipxproto __P((char **)); +static int setipxanet __P((char **)); +static int setipxalcl __P((char **)); +static int setipxarmt __P((char **)); static int setipxnetwork __P((char **)); static int setipxnode __P((char **)); static int setipxrouter __P((char **)); @@ -197,40 +250,54 @@ static int setipxcpconf __P((char **)); static int setipxcpfails __P((char **)); #endif /* IPX_CHANGE */ -#ifdef USE_MS_DNS -static int setdnsaddr __P((char **)); +#ifdef MSLANMAN +static int setmslanman __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(); - /* * Valid arguments. */ static struct cmd { char *cmd_name; int num_args; - int (*cmd_func)(); + int (*cmd_func) __P((char **)); } 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 +307,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 */ @@ -247,6 +315,9 @@ static struct cmd { {"domain", 1, setdomain}, /* Add given domain name to hostname*/ {"mru", 1, setmru}, /* Set MRU value for negotiation */ {"mtu", 1, setmtu}, /* Set our MTU */ +#ifdef CBCP_SUPPORT + {"callback", 1, setcbcp}, /* Ask for callback */ +#endif {"netmask", 1, setnetmask}, /* set netmask */ {"passive", 0, setpassive}, /* Set passive mode */ {"silent", 0, setsilent}, /* Set silent mode */ @@ -254,16 +325,21 @@ static struct cmd { {"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 */ @@ -285,16 +361,35 @@ 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 */ + {"nodeflatedraft", 0, setnodeflatedraft}, /* don't use draft deflate # */ {"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) */ + {"ms-dns", 1, setdnsaddr}, /* DNS address for the peer's use */ + {"ms-wins", 1, setwinsaddr}, /* Nameserver for SMB over TCP/IP for peer */ + {"noipx", 0, resetipxproto}, /* Disable IPXCP (and IPX) */ + {"-ipx", 0, resetipxproto}, /* Disable IPXCP (and IPX) */ + {"--version", 0, showversion}, /* Show version number */ + {"--help", 0, showhelp}, /* Show brief listing of options */ + {"-h", 0, showhelp}, /* ditto */ + +#ifdef PPP_FILTER + {"pdebug", 1, setpdebug}, /* libpcap debugging */ + {"pass-filter", 1, setpassfilter}, /* set filter for packets to pass */ + {"active-filter", 1, setactivefilter}, /* set filter for active pkts */ +#endif #ifdef IPX_CHANGE {"ipx-network", 1, setipxnetwork}, /* IPX network number */ @@ -311,16 +406,12 @@ static struct cmd { #if 0 {"ipx-compression", 1, setipxcompression}, /* IPX compression number */ #endif + {"ipx", 0, setipxproto}, /* Enable 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 */ +#ifdef MSLANMAN + {"ms-lanman", 0, setmslanman}, /* Use LanMan psswd when using MS-CHAP */ #endif {NULL, 0, NULL} @@ -333,7 +424,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\ @@ -346,24 +437,27 @@ Usage: %s [ arguments ], where arguments are:\n\ file Take options from file \n\ modem Use modem control lines\n\ mru Set MRU value to for negotiation\n\ - netmask Set interface netmask to \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; @@ -377,9 +471,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 +484,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 +498,76 @@ 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); +} + +/* + * showhelp - print out usage message and exit. + */ +static int +showhelp(argv) + char **argv; +{ + if (phase == PHASE_INITIALIZE) { + usage(); + exit(0); + } + return 0; +} + +/* + * showversion - print out the version number and exit. + */ +static int +showversion(argv) + char **argv; +{ + if (phase == PHASE_INITIALIZE) { + fprintf(stderr, "pppd version %s patch level %d%s\n", + VERSION, PATCHLEVEL, IMPLEMENTATION); + exit(0); + } + return 0; } /* @@ -418,14 +575,16 @@ usage() * 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]; @@ -433,15 +592,18 @@ 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; } + oldpriv = privileged_option; + privileged_option = priv; + ret = 0; while (getword(f, cmd, &newline, filename)) { /* * First see if it's a command. @@ -453,36 +615,38 @@ 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); - 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; } /* @@ -506,7 +670,7 @@ options_from_user() 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; } @@ -518,26 +682,52 @@ options_from_user() 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; + 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. */ @@ -785,7 +975,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); } /* @@ -800,8 +990,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; @@ -825,7 +1015,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; @@ -852,7 +1043,7 @@ int_option(str, valp) /* - * The following procedures execute commands. + * The following procedures parse options. */ /* @@ -862,14 +1053,60 @@ static int 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 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). */ static int -setdebug() +setdebug(argv) + char **argv; { debug++; return (1); @@ -885,11 +1122,56 @@ setkdebug(argv) return int_option(*argv, &kdebugflag); } +#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 + */ +static int +setpassfilter(argv) + char **argv; +{ + pc.linktype = DLT_PPP; + pc.snapshot = PPP_HDRLEN; + + if (pcap_compile(&pc, &pass_filter, *argv, 1, netmask) == 0) + return 1; + option_error("error in pass-filter expression: %s\n", pcap_geterr(&pc)); + return 0; +} + +/* + * setactivefilter - Set the active filter for packets + */ +static int +setactivefilter(argv) + char **argv; +{ + pc.linktype = DLT_PPP; + pc.snapshot = PPP_HDRLEN; + + if (pcap_compile(&pc, &active_filter, *argv, 1, netmask) == 0) + return 1; + option_error("error in active-filter expression: %s\n", pcap_geterr(&pc)); + return 0; +} +#endif + /* * noopt - Disable all options. */ static int -noopt() +noopt(argv) + char **argv; { BZERO((char *) &lcp_wantoptions[0], sizeof (struct lcp_options)); BZERO((char *) &lcp_allowoptions[0], sizeof (struct lcp_options)); @@ -908,7 +1190,8 @@ noopt() * noaccomp - Disable Address/Control field compression negotiation. */ static int -noaccomp() +noaccomp(argv) + char **argv; { lcp_wantoptions[0].neg_accompression = 0; lcp_allowoptions[0].neg_accompression = 0; @@ -920,7 +1203,8 @@ noaccomp() * noasyncmap - Disable async map negotiation. */ static int -noasyncmap() +noasyncmap(argv) + char **argv; { lcp_wantoptions[0].neg_asyncmap = 0; lcp_allowoptions[0].neg_asyncmap = 0; @@ -932,7 +1216,8 @@ noasyncmap() * noip - Disable IP and IPCP. */ static int -noip() +noip(argv) + char **argv; { ipcp_protent.enabled_flag = 0; return (1); @@ -943,7 +1228,8 @@ noip() * nomagicnumber - Disable magic number negotiation. */ static int -nomagicnumber() +nomagicnumber(argv) + char **argv; { lcp_wantoptions[0].neg_magicnumber = 0; lcp_allowoptions[0].neg_magicnumber = 0; @@ -955,7 +1241,8 @@ nomagicnumber() * nomru - Disable mru negotiation. */ static int -nomru() +nomru(argv) + char **argv; { lcp_wantoptions[0].neg_mru = 0; lcp_allowoptions[0].neg_mru = 0; @@ -992,20 +1279,36 @@ 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; return (1); } +#ifdef CBCP_SUPPORT +static int +setcbcp(argv) + char **argv; +{ + lcp_wantoptions[0].neg_cbcp = 1; + cbcp_protent.enabled_flag = 1; + cbcp[0].us_number = strdup(*argv); + if (cbcp[0].us_number == 0) + novm("callback number"); + cbcp[0].us_type |= (1 << CB_CONF_USER); + cbcp[0].us_type |= (1 << CB_CONF_ADMIN); + return (1); +} +#endif /* * nopcomp - Disable Protocol field compression negotiation. */ static int -nopcomp() +nopcomp(argv) + char **argv; { lcp_wantoptions[0].neg_pcompression = 0; lcp_allowoptions[0].neg_pcompression = 0; @@ -1018,7 +1321,8 @@ nopcomp() * LCP configure-requests). */ static int -setpassive() +setpassive(argv) + char **argv; { lcp_wantoptions[0].passive = 1; return (1); @@ -1030,7 +1334,8 @@ setpassive() * until we get one from the peer). */ static int -setsilent() +setsilent(argv) + char **argv; { lcp_wantoptions[0].silent = 1; return 1; @@ -1041,9 +1346,10 @@ setsilent() * nopap - Disable PAP authentication with peer. */ static int -nopap() +nopap(argv) + char **argv; { - lcp_allowoptions[0].neg_upap = 0; + refuse_pap = 1; return (1); } @@ -1052,14 +1358,15 @@ nopap() * reqpap - Require PAP authentication from peer. */ static int -reqpap() +reqpap(argv) + char **argv; { lcp_wantoptions[0].neg_upap = 1; - auth_required = 1; + setauth(NULL); return 1; } - +#if OLD_OPTIONS /* * setupapfile - specifies UPAP info for authenticating with peer. */ @@ -1074,11 +1381,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); @@ -1086,7 +1393,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); @@ -1101,15 +1408,16 @@ setupapfile(argv) return (1); } - +#endif /* * nochap - Disable CHAP authentication with peer. */ static int -nochap() +nochap(argv) + char **argv; { - lcp_allowoptions[0].neg_chap = 0; + refuse_chap = 1; return (1); } @@ -1118,10 +1426,11 @@ nochap() * reqchap - Require CHAP authentication from peer. */ static int -reqchap() +reqchap(argv) + char **argv; { lcp_wantoptions[0].neg_chap = 1; - auth_required = 1; + setauth(NULL); return (1); } @@ -1130,7 +1439,8 @@ reqchap() * setnovj - disable vj compression */ static int -setnovj() +setnovj(argv) + char **argv; { ipcp_wantoptions[0].neg_vj = 0; ipcp_allowoptions[0].neg_vj = 0; @@ -1142,7 +1452,8 @@ setnovj() * setnovjccomp - disable VJ connection-ID compression */ static int -setnovjccomp() +setnovjccomp(argv) + char **argv; { ipcp_wantoptions[0].cflag = 0; ipcp_allowoptions[0].cflag = 0; @@ -1162,7 +1473,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 = @@ -1181,7 +1492,9 @@ setconnector(argv) connector = strdup(*argv); if (connector == NULL) novm("connect script"); - + connector_info.priv = privileged_option; + connector_info.source = option_source; + return (1); } @@ -1195,6 +1508,8 @@ setdisconnector(argv) disconnector = strdup(*argv); if (disconnector == NULL) novm("disconnect script"); + disconnector_info.priv = privileged_option; + disconnector_info.source = option_source; return (1); } @@ -1209,7 +1524,9 @@ setwelcomer(argv) welcomer = strdup(*argv); if (welcomer == NULL) novm("welcome script"); - + welcomer_info.priv = privileged_option; + welcomer_info.source = option_source; + return (1); } @@ -1223,10 +1540,14 @@ setmaxconnect(argv) 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; @@ -1239,6 +1560,10 @@ static int 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 != '.') @@ -1282,12 +1607,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); + if (n < 0 || (0x20 <= n && n <= 0x3F) || n == 0x5E || n > 0xFF) { + option_error("can't escape character 0x%x", n); ret = 0; } else xmit_accm[0][n >> 5] |= 1 << (n & 0x1F); @@ -1319,14 +1645,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); @@ -1338,15 +1667,17 @@ 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; } - + (void) strncpy(devnam, cp, MAXPATHLEN); devnam[MAXPATHLEN-1] = 0; default_device = FALSE; + devnam_info.priv = privileged_option; + devnam_info.source = option_source; return 1; } @@ -1355,7 +1686,7 @@ setdevname(cp) /* * setipaddr - Set the IP address */ -int +static int setipaddr(arg) char *arg; { @@ -1377,18 +1708,14 @@ 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; - 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) @@ -1402,7 +1729,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; @@ -1413,7 +1740,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) @@ -1428,7 +1755,8 @@ setipaddr(arg) * setnoipdflt - disable setipdefault() */ static int -setnoipdflt() +setnoipdflt(argv) + char **argv; { disable_defaultip = 1; return 1; @@ -1439,7 +1767,8 @@ setnoipdflt() * setipcpaccl - accept peer's idea of our address */ static int -setipcpaccl() +setipcpaccl(argv) + char **argv; { ipcp_wantoptions[0].accept_local = 1; return 1; @@ -1450,7 +1779,8 @@ setipcpaccl() * setipcpaccr - accept peer's idea of its address */ static int -setipcpaccr() +setipcpaccr(argv) + char **argv; { ipcp_wantoptions[0].accept_remote = 1; return 1; @@ -1464,10 +1794,40 @@ static int setnetmask(argv) char **argv; { - u_int32_t mask; + u_int32_t mask, b; + int n, ok; + char *p, *endp; - if ((mask = inet_addr(*argv)) == -1 || (netmask & ~mask) != 0) { - fprintf(stderr, "Invalid netmask %s\n", *argv); + /* + * Unfortunately, if we use inet_addr, we can't tell whether + * a result of all 1s is an error or a valid 255.255.255.255. + */ + p = *argv; + ok = 0; + mask = 0; + for (n = 3;; --n) { + b = strtoul(p, &endp, 0); + if (endp == p) + break; + if (b < 0 || b > 255) { + if (n == 3) { + /* accept e.g. 0xffffff00 */ + p = endp; + mask = b; + } + break; + } + mask |= b << (n * 8); + p = endp; + if (*p != '.' || n == 0) + break; + ++p; + } + + mask = htonl(mask); + + if (*p != 0 || (netmask & ~mask) != 0) { + option_error("invalid netmask value '%s'", *argv); return 0; } @@ -1476,21 +1836,24 @@ setnetmask(argv) } static int -setcrtscts() +setcrtscts(argv) + char **argv; { crtscts = 1; return (1); } static int -setnocrtscts() +setnocrtscts(argv) + char **argv; { crtscts = -1; return (1); } static int -setxonxoff() +setxonxoff(argv) + char **argv; { lcp_wantoptions[0].asyncmap |= 0x000A0000; /* escape ^S and ^Q */ lcp_wantoptions[0].neg_asyncmap = 1; @@ -1500,42 +1863,49 @@ setxonxoff() } static int -setnodetach() +setnodetach(argv) + char **argv; { nodetach = 1; return (1); } static int -setdemand() +setdemand(argv) + char **argv; { demand = 1; + persist = 1; return 1; } static int -setmodem() +setmodem(argv) + char **argv; { modem = 1; return 1; } static int -setlocal() +setlocal(argv) + char **argv; { modem = 0; return 1; } static int -setlock() +setlock(argv) + char **argv; { lockflag = 1; return 1; } static int -setusehostname() +setusehostname(argv) + char **argv; { usehostname = 1; return 1; @@ -1545,10 +1915,12 @@ static int setname(argv) char **argv; { - if (our_name[0] == 0) { - strncpy(our_name, argv[0], MAXNAMELEN); - our_name[MAXNAMELEN-1] = 0; + if (!privileged_option) { + option_error("using the name option requires root privilege"); + return 0; } + strncpy(our_name, argv[0], MAXNAMELEN); + our_name[MAXNAMELEN-1] = 0; return 1; } @@ -1571,17 +1943,36 @@ setremote(argv) } static int -setauth() +setauth(argv) + char **argv; { 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(argv) + char **argv; +{ + 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; } static int -setdefaultroute() +setdefaultroute(argv) + char **argv; { 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; @@ -1589,7 +1980,8 @@ setdefaultroute() } static int -setnodefaultroute() +setnodefaultroute(argv) + char **argv; { ipcp_allowoptions[0].default_route = 0; ipcp_wantoptions[0].default_route = 0; @@ -1597,10 +1989,11 @@ setnodefaultroute() } static int -setproxyarp() +setproxyarp(argv) + char **argv; { 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; @@ -1608,7 +2001,8 @@ setproxyarp() } static int -setnoproxyarp() +setnoproxyarp(argv) + char **argv; { ipcp_wantoptions[0].proxy_arp = 0; ipcp_allowoptions[0].proxy_arp = 0; @@ -1616,14 +2010,24 @@ setnoproxyarp() } static int -setpersist() +setpersist(argv) + char **argv; { persist = 1; return 1; } static int -setdologin() +setnopersist(argv) + char **argv; +{ + persist = 0; + return 1; +} + +static int +setdologin(argv) + char **argv; { uselogin = 1; return 1; @@ -1748,6 +2152,14 @@ setchapintv(argv) return int_option(*argv, &chap[0].chal_interval); } +static int +noccp(argv) + char **argv; +{ + ccp_protent.enabled_flag = 0; + return 1; +} + static int setbsdcomp(argv) char **argv; @@ -1762,14 +2174,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); + if ((rbits != 0 && (rbits < BSD_MIN_BITS || rbits > BSD_MAX_BITS)) + || (abits != 0 && (abits < BSD_MIN_BITS || abits > 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) { @@ -1786,7 +2197,8 @@ setbsdcomp(argv) } static int -setnobsdcomp() +setnobsdcomp(argv) + char **argv; { ccp_wantoptions[0].bsd_compress = 0; ccp_allowoptions[0].bsd_compress = 0; @@ -1807,15 +2219,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); + 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) { @@ -1832,7 +2243,8 @@ setdeflate(argv) } static int -setnodeflate() +setnodeflate(argv) + char **argv; { ccp_wantoptions[0].deflate = 0; ccp_allowoptions[0].deflate = 0; @@ -1840,7 +2252,17 @@ setnodeflate() } static int -setpred1comp() +setnodeflatedraft(argv) + char **argv; +{ + ccp_wantoptions[0].deflate_draft = 0; + ccp_allowoptions[0].deflate_draft = 0; + return 1; +} + +static int +setpred1comp(argv) + char **argv; { ccp_wantoptions[0].predictor_1 = 1; ccp_allowoptions[0].predictor_1 = 1; @@ -1848,7 +2270,8 @@ setpred1comp() } static int -setnopred1comp() +setnopred1comp(argv) + char **argv; { ccp_wantoptions[0].predictor_1 = 0; ccp_allowoptions[0].predictor_1 = 0; @@ -1867,7 +2290,8 @@ setipparam(argv) } static int -setpapcrypt() +setpapcrypt(argv) + char **argv; { cryptpap = 1; return 1; @@ -1887,6 +2311,68 @@ setholdoff(argv) return int_option(*argv, &holdoff); } +/* + * setdnsaddr - set the dns address(es) + */ +static int +setdnsaddr(argv) + char **argv; +{ + u_int32_t dns; + struct hostent *hp; + + dns = inet_addr(*argv); + if (dns == -1) { + if ((hp = gethostbyname(*argv)) == NULL) { + option_error("invalid address parameter '%s' for ms-dns option", + *argv); + return 0; + } + dns = *(u_int32_t *)hp->h_addr; + } + + /* if there is no primary then update it. */ + if (ipcp_allowoptions[0].dnsaddr[0] == 0) + ipcp_allowoptions[0].dnsaddr[0] = dns; + + /* always set the secondary address value to the same value. */ + ipcp_allowoptions[0].dnsaddr[1] = dns; + + return (1); +} + +/* + * setwinsaddr - set the wins address(es) + * This is primrarly used with the Samba package under UNIX or for pointing + * the caller to the existing WINS server on a Windows NT platform. + */ +static int +setwinsaddr(argv) + char **argv; +{ + u_int32_t wins; + struct hostent *hp; + + wins = inet_addr(*argv); + if (wins == -1) { + if ((hp = gethostbyname(*argv)) == NULL) { + option_error("invalid address parameter '%s' for ms-wins option", + *argv); + return 0; + } + wins = *(u_int32_t *)hp->h_addr; + } + + /* if there is no primary then update it. */ + if (ipcp_allowoptions[0].winsaddr[0] == 0) + ipcp_allowoptions[0].winsaddr[0] = wins; + + /* always set the secondary address value to the same value. */ + ipcp_allowoptions[0].winsaddr[1] = wins; + + return (1); +} + #ifdef IPX_CHANGE static int setipxrouter (argv) @@ -1914,17 +2400,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; } @@ -1966,29 +2448,41 @@ static int setipxnetwork(argv) char **argv; { - ipxcp_wantoptions[0].neg_nn = 1; - return int_option(*argv, &ipxcp_wantoptions[0].our_network); + u_int32_t v; + + if (!number_option(*argv, &v, 16)) + return 0; + + ipxcp_wantoptions[0].our_network = (int) v; + ipxcp_wantoptions[0].neg_nn = 1; + return 1; } static int -setipxanet() +setipxanet(argv) + char **argv; { ipxcp_wantoptions[0].accept_network = 1; ipxcp_allowoptions[0].accept_network = 1; + return 1; } static int -setipxalcl() +setipxalcl(argv) + char **argv; { ipxcp_wantoptions[0].accept_local = 1; ipxcp_allowoptions[0].accept_local = 1; + return 1; } static int -setipxarmt() +setipxarmt(argv) + char **argv; { ipxcp_wantoptions[0].accept_remote = 1; ipxcp_allowoptions[0].accept_remote = 1; + return 1; } static u_char * @@ -2035,53 +2529,41 @@ 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() +setipxproto(argv) + char **argv; { - ipx_enabled = 1; /* Enable IPXCP and IPX protocol */ + ipxcp_protent.enabled_flag = 1; return 1; } static int -resetipxproto() +resetipxproto(argv) + char **argv; { - ipx_enabled = 0; /* Disable IPXCP and IPX protocol */ + ipxcp_protent.enabled_flag = 0; return 1; } -#endif /* IPX_CHANGE */ - -#ifdef USE_MS_DNS -/* - * setdnsaddr - set the dns address(es) - */ +#else static int -setdnsaddr(argv) +resetipxproto(argv) char **argv; { - u_int32_t dns; - struct hostent *hp; - - dns = inet_addr(*argv); - if (dns == -1) { - if ((hp = gethostbyname(*argv)) == NULL) { - fprintf(stderr, "Invalid DNS Address %s\n", *argv); - return 0; - } - dns = *(u_int32_t *)hp->h_addr; - } - - if (ipcp_allowoptions[0].dnsaddr[0] == 0) { - ipcp_allowoptions[0].dnsaddr[0] = dns; - } else { - ipcp_allowoptions[0].dnsaddr[1] = dns; - } + return 1; +} +#endif /* IPX_CHANGE */ +#ifdef MSLANMAN +static int +setmslanman(argv) + char **argv; +{ + ms_lanman = 1; return (1); } -#endif /* USE_MS_DNS */ +#endif