GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.sbin/pppd/options.c Lines: 0 625 0.0 %
Date: 2017-11-07 Branches: 0 396 0.0 %

Line Branch Exec Source
1
/*	$OpenBSD: options.c,v 1.29 2015/12/06 12:00:16 tobias Exp $	*/
2
3
/*
4
 * options.c - handles option processing for PPP.
5
 *
6
 * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved.
7
 *
8
 * Redistribution and use in source and binary forms, with or without
9
 * modification, are permitted provided that the following conditions
10
 * are met:
11
 *
12
 * 1. Redistributions of source code must retain the above copyright
13
 *    notice, this list of conditions and the following disclaimer.
14
 *
15
 * 2. Redistributions in binary form must reproduce the above copyright
16
 *    notice, this list of conditions and the following disclaimer in
17
 *    the documentation and/or other materials provided with the
18
 *    distribution.
19
 *
20
 * 3. The name "Carnegie Mellon University" must not be used to
21
 *    endorse or promote products derived from this software without
22
 *    prior written permission. For permission or any legal
23
 *    details, please contact
24
 *      Office of Technology Transfer
25
 *      Carnegie Mellon University
26
 *      5000 Forbes Avenue
27
 *      Pittsburgh, PA  15213-3890
28
 *      (412) 268-4387, fax: (412) 268-7395
29
 *      tech-transfer@andrew.cmu.edu
30
 *
31
 * 4. Redistributions of any form whatsoever must retain the following
32
 *    acknowledgment:
33
 *    "This product includes software developed by Computing Services
34
 *     at Carnegie Mellon University (http://www.cmu.edu/computing/)."
35
 *
36
 * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
37
 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
38
 * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
39
 * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
40
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
41
 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
42
 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
43
 */
44
45
#include <ctype.h>
46
#include <stdio.h>
47
#include <errno.h>
48
#include <unistd.h>
49
#include <limits.h>
50
#include <stdlib.h>
51
#include <termios.h>
52
#include <syslog.h>
53
#include <string.h>
54
#include <netdb.h>
55
#include <pwd.h>
56
#include <sys/types.h>
57
#include <sys/stat.h>
58
#include <netinet/in.h>
59
#include <arpa/inet.h>
60
#ifdef PPP_FILTER
61
#include <pcap.h>
62
#include <pcap-int.h>	/* XXX: To get struct pcap */
63
#endif
64
65
#include "pppd.h"
66
#include "pathnames.h"
67
#include "patchlevel.h"
68
#include "fsm.h"
69
#include "lcp.h"
70
#include "ipcp.h"
71
#include "upap.h"
72
#include "chap.h"
73
#include "ccp.h"
74
#ifdef CBCP_SUPPORT
75
#include "cbcp.h"
76
#endif
77
78
#include <net/ppp-comp.h>
79
80
#define FALSE	0
81
#define TRUE	1
82
83
#if defined(ultrix) || defined(NeXT)
84
char *strdup(char *);
85
#endif
86
87
#ifndef GIDSET_TYPE
88
#define GIDSET_TYPE	gid_t
89
#endif
90
91
/*
92
 * Option variables and default values.
93
 */
94
#ifdef PPP_FILTER
95
int	dflag = 0;		/* Tell libpcap we want debugging */
96
#endif
97
int	debug = 0;		/* Debug flag */
98
int	kdebugflag = 0;		/* Tell kernel to print debug messages */
99
int	default_device = 1;	/* Using /dev/tty or equivalent */
100
char	devnam[PATH_MAX] = "/dev/tty";	/* Device name */
101
int	crtscts = 0;		/* Use hardware flow control */
102
int	modem = 1;		/* Use modem control lines */
103
int	modem_chat = 0;		/* Use modem control lines during chat */
104
int	inspeed = 0;		/* Input/Output speed requested */
105
u_int32_t netmask = 0;		/* IP netmask to set on interface */
106
int	lockflag = 0;		/* Create lock file to lock the serial dev */
107
int	nodetach = 0;		/* Don't detach from controlling tty */
108
char	*connector = NULL;	/* Script to establish physical link */
109
char	*disconnector = NULL;	/* Script to disestablish physical link */
110
char	*welcomer = NULL;	/* Script to run after phys link estab. */
111
int	maxconnect = 0;		/* Maximum connect time */
112
char	user[MAXNAMELEN];	/* Username for PAP */
113
char	passwd[MAXSECRETLEN];	/* Password for PAP */
114
int	auth_required = 0;	/* Peer is required to authenticate */
115
int	persist = 0;		/* Reopen link after it goes down */
116
int	uselogin = 0;		/* Use /etc/passwd for checking PAP */
117
int	lcp_echo_interval = 0; 	/* Interval between LCP echo-requests */
118
int	lcp_echo_fails = 0;	/* Tolerance to unanswered echo-requests */
119
char	our_name[MAXNAMELEN];	/* Our name for authentication purposes */
120
char	remote_name[MAXNAMELEN]; /* Peer's name for authentication */
121
int	explicit_remote = 0;	/* User specified explicit remote name */
122
int	usehostname = 0;	/* Use hostname for our_name */
123
int	disable_defaultip = 0;	/* Don't use hostname for default IP adrs */
124
int	demand = 0;		/* do dial-on-demand */
125
char	*ipparam = NULL;	/* Extra parameter for ip up/down scripts */
126
int	cryptpap;		/* Passwords in pap-secrets are encrypted */
127
int	idle_time_limit = 0;	/* Disconnect if idle for this many seconds */
128
int	holdoff = 30;		/* # seconds to pause before reconnecting */
129
int	refuse_pap = 0;		/* Set to say we won't do PAP */
130
int	refuse_chap = 0;	/* Set to say we won't do CHAP */
131
132
#ifdef MSLANMAN
133
int	ms_lanman = 0;    	/* Nonzero if use LanMan password instead of NT */
134
			  	/* Has meaning only with MS-CHAP challenges */
135
#endif
136
137
struct option_info auth_req_info;
138
struct option_info connector_info;
139
struct option_info disconnector_info;
140
struct option_info welcomer_info;
141
struct option_info devnam_info;
142
#ifdef PPP_FILTER
143
struct	bpf_program pass_filter;/* Filter program for packets to pass */
144
struct	bpf_program active_filter; /* Filter program for link-active pkts */
145
pcap_t  pc;			/* Fake struct pcap so we can compile expr */
146
#endif
147
148
/*
149
 * Prototypes
150
 */
151
static int setdevname(char *, int);
152
static int setipaddr(char *);
153
static int setspeed(char *);
154
static int setdebug(char **);
155
static int setkdebug(char **);
156
static int setpassive(char **);
157
static int setsilent(char **);
158
static int noopt(char **);
159
static int setnovj(char **);
160
static int setnovjccomp(char **);
161
static int setvjslots(char **);
162
static int reqpap(char **);
163
static int nopap(char **);
164
static int nochap(char **);
165
static int reqchap(char **);
166
static int noaccomp(char **);
167
static int noasyncmap(char **);
168
static int noip(char **);
169
static int nomagicnumber(char **);
170
static int setasyncmap(char **);
171
static int setescape(char **);
172
static int setmru(char **);
173
static int setmtu(char **);
174
#ifdef CBCP_SUPPORT
175
static int setcbcp(char **);
176
#endif
177
static int nomru(char **);
178
static int nopcomp(char **);
179
static int setconnector(char **);
180
static int setdisconnector(char **);
181
static int setwelcomer(char **);
182
static int setmaxconnect(char **);
183
static int setdomain(char **);
184
static int setnetmask(char **);
185
static int setcrtscts(char **);
186
static int setnocrtscts(char **);
187
static int setxonxoff(char **);
188
static int setnodetach(char **);
189
static int setupdetach(char **);
190
static int setmodem(char **);
191
static int setmodem_chat(char **);
192
static int setlocal(char **);
193
static int setlock(char **);
194
static int setname(char **);
195
static int setuser(char **);
196
static int setremote(char **);
197
static int setauth(char **);
198
static int setnoauth(char **);
199
static int readfile(char **);
200
static int callfile(char **);
201
static int setdefaultroute(char **);
202
static int setnodefaultroute(char **);
203
static int setproxyarp(char **);
204
static int setnoproxyarp(char **);
205
static int setpersist(char **);
206
static int setnopersist(char **);
207
static int setdologin(char **);
208
static int setusehostname(char **);
209
static int setnoipdflt(char **);
210
static int setlcptimeout(char **);
211
static int setlcpterm(char **);
212
static int setlcpconf(char **);
213
static int setlcpfails(char **);
214
static int setipcptimeout(char **);
215
static int setipcpterm(char **);
216
static int setipcpconf(char **);
217
static int setipcpfails(char **);
218
static int setpaptimeout(char **);
219
static int setpapreqs(char **);
220
static int setpapreqtime(char **);
221
static int setchaptimeout(char **);
222
static int setchapchal(char **);
223
static int setchapintv(char **);
224
static int setipcpaccl(char **);
225
static int setipcpaccr(char **);
226
static int setlcpechointv(char **);
227
static int setlcpechofails(char **);
228
static int noccp(char **);
229
static int setbsdcomp(char **);
230
static int setnobsdcomp(char **);
231
static int setdeflate(char **);
232
static int setnodeflate(char **);
233
static int setnodeflatedraft(char **);
234
static int setdemand(char **);
235
static int setpred1comp(char **);
236
static int setnopred1comp(char **);
237
static int setipparam(char **);
238
static int setpapcrypt(char **);
239
static int setidle(char **);
240
static int setholdoff(char **);
241
static int setdnsaddr(char **);
242
static int setwinsaddr(char **);
243
static int showversion(char **);
244
static int showhelp(char **);
245
246
#ifdef PPP_FILTER
247
static int setpdebug(char **);
248
static int setpassfilter(char **);
249
static int setactivefilter(char **);
250
#endif
251
252
#ifdef MSLANMAN
253
static int setmslanman(char **);
254
#endif
255
256
static int number_option(char *, u_int32_t *, int);
257
static int int_option(char *, int *);
258
static int readable(int fd);
259
260
/*
261
 * Valid arguments.
262
 */
263
static struct cmd {
264
    char *cmd_name;
265
    int num_args;
266
    int (*cmd_func)(char **);
267
} cmds[] = {
268
    {"-all", 0, noopt},		/* Don't request/allow any options (useless) */
269
    {"noaccomp", 0, noaccomp},	/* Disable Address/Control compression */
270
    {"-ac", 0, noaccomp},	/* Disable Address/Control compress */
271
    {"default-asyncmap", 0, noasyncmap}, /* Disable asyncmap negoatiation */
272
    {"-am", 0, noasyncmap},	/* Disable asyncmap negotiation */
273
    {"-as", 1, setasyncmap},	/* set the desired async map */
274
    {"-d", 0, setdebug},	/* Increase debugging level */
275
    {"nodetach", 0, setnodetach}, /* Don't detach from controlling tty */
276
    {"-detach", 0, setnodetach}, /* don't fork */
277
    {"updetach", 0, setupdetach}, /* Detach once an NP has come up */
278
    {"noip", 0, noip},		/* Disable IP and IPCP */
279
    {"-ip", 0, noip},		/* Disable IP and IPCP */
280
    {"nomagic", 0, nomagicnumber}, /* Disable magic number negotiation */
281
    {"-mn", 0, nomagicnumber},	/* Disable magic number negotiation */
282
    {"default-mru", 0, nomru},	/* Disable MRU negotiation */
283
    {"-mru", 0, nomru},		/* Disable mru negotiation */
284
    {"-p", 0, setpassive},	/* Set passive mode */
285
    {"nopcomp", 0, nopcomp},	/* Disable protocol field compression */
286
    {"-pc", 0, nopcomp},	/* Disable protocol field compress */
287
    {"require-pap", 0, reqpap},	/* Require PAP authentication from peer */
288
    {"+pap", 0, reqpap},	/* Require PAP auth from peer */
289
    {"refuse-pap", 0, nopap},	/* Don't agree to auth to peer with PAP */
290
    {"-pap", 0, nopap},		/* Don't allow UPAP authentication with peer */
291
    {"require-chap", 0, reqchap}, /* Require CHAP authentication from peer */
292
    {"+chap", 0, reqchap},	/* Require CHAP authentication from peer */
293
    {"refuse-chap", 0, nochap},	/* Don't agree to auth to peer with CHAP */
294
    {"-chap", 0, nochap},	/* Don't allow CHAP authentication with peer */
295
    {"novj", 0, setnovj},	/* Disable VJ compression */
296
    {"-vj", 0, setnovj},	/* disable VJ compression */
297
    {"novjccomp", 0, setnovjccomp}, /* disable VJ connection-ID compression */
298
    {"-vjccomp", 0, setnovjccomp}, /* disable VJ connection-ID compression */
299
    {"vj-max-slots", 1, setvjslots}, /* Set maximum VJ header slots */
300
    {"asyncmap", 1, setasyncmap}, /* set the desired async map */
301
    {"escape", 1, setescape},	/* set chars to escape on transmission */
302
    {"connect", 1, setconnector}, /* A program to set up a connection */
303
    {"disconnect", 1, setdisconnector},	/* program to disconnect serial dev. */
304
    {"welcome", 1, setwelcomer},/* Script to welcome client */
305
    {"maxconnect", 1, setmaxconnect},  /* specify a maximum connect time */
306
    {"crtscts", 0, setcrtscts},	/* set h/w flow control */
307
    {"nocrtscts", 0, setnocrtscts}, /* clear h/w flow control */
308
    {"-crtscts", 0, setnocrtscts}, /* clear h/w flow control */
309
    {"xonxoff", 0, setxonxoff},	/* set s/w flow control */
310
    {"debug", 0, setdebug},	/* Increase debugging level */
311
    {"kdebug", 1, setkdebug},	/* Enable kernel-level debugging */
312
    {"domain", 1, setdomain},	/* Add given domain name to hostname*/
313
    {"mru", 1, setmru},		/* Set MRU value for negotiation */
314
    {"mtu", 1, setmtu},		/* Set our MTU */
315
#ifdef CBCP_SUPPORT
316
    {"callback", 1, setcbcp},	/* Ask for callback */
317
#endif
318
    {"netmask", 1, setnetmask},	/* set netmask */
319
    {"passive", 0, setpassive},	/* Set passive mode */
320
    {"silent", 0, setsilent},	/* Set silent mode */
321
    {"modem", 0, setmodem},	/* Use modem control lines */
322
    {"modem_chat", 0, setmodem_chat}, /* Use modem control lines during chat */
323
    {"local", 0, setlocal},	/* Don't use modem control lines */
324
    {"lock", 0, setlock},	/* Lock serial device (with lock file) */
325
    {"name", 1, setname},	/* Set local name for authentication */
326
    {"user", 1, setuser},	/* Set name for auth with peer */
327
    {"usehostname", 0, setusehostname},	/* Must use hostname for auth. */
328
    {"remotename", 1, setremote}, /* Set remote name for authentication */
329
    {"auth", 0, setauth},	/* Require authentication from peer */
330
    {"noauth", 0, setnoauth},	/* Don't require peer to authenticate */
331
    {"file", 1, readfile},	/* Take options from a file */
332
    {"call", 1, callfile},	/* Take options from a privileged file */
333
    {"defaultroute", 0, setdefaultroute}, /* Add default route */
334
    {"nodefaultroute", 0, setnodefaultroute}, /* disable defaultroute option */
335
    {"-defaultroute", 0, setnodefaultroute}, /* disable defaultroute option */
336
    {"proxyarp", 0, setproxyarp}, /* Add proxy ARP entry */
337
    {"noproxyarp", 0, setnoproxyarp}, /* disable proxyarp option */
338
    {"-proxyarp", 0, setnoproxyarp}, /* disable proxyarp option */
339
    {"persist", 0, setpersist},	/* Keep on reopening connection after close */
340
    {"nopersist", 0, setnopersist},  /* Turn off persist option */
341
    {"demand", 0, setdemand},	/* Dial on demand */
342
    {"login", 0, setdologin},	/* Use system password database for UPAP */
343
    {"noipdefault", 0, setnoipdflt}, /* Don't use name for default IP adrs */
344
    {"lcp-echo-failure", 1, setlcpechofails}, /* consecutive echo failures */
345
    {"lcp-echo-interval", 1, setlcpechointv}, /* time for lcp echo events */
346
    {"lcp-restart", 1, setlcptimeout}, /* Set timeout for LCP */
347
    {"lcp-max-terminate", 1, setlcpterm}, /* Set max #xmits for term-reqs */
348
    {"lcp-max-configure", 1, setlcpconf}, /* Set max #xmits for conf-reqs */
349
    {"lcp-max-failure", 1, setlcpfails}, /* Set max #conf-naks for LCP */
350
    {"ipcp-restart", 1, setipcptimeout}, /* Set timeout for IPCP */
351
    {"ipcp-max-terminate", 1, setipcpterm}, /* Set max #xmits for term-reqs */
352
    {"ipcp-max-configure", 1, setipcpconf}, /* Set max #xmits for conf-reqs */
353
    {"ipcp-max-failure", 1, setipcpfails}, /* Set max #conf-naks for IPCP */
354
    {"pap-restart", 1, setpaptimeout},	/* Set retransmit timeout for PAP */
355
    {"pap-max-authreq", 1, setpapreqs}, /* Set max #xmits for auth-reqs */
356
    {"pap-timeout", 1, setpapreqtime},	/* Set time limit for peer PAP auth. */
357
    {"chap-restart", 1, setchaptimeout}, /* Set timeout for CHAP */
358
    {"chap-max-challenge", 1, setchapchal}, /* Set max #xmits for challenge */
359
    {"chap-interval", 1, setchapintv}, /* Set interval for rechallenge */
360
    {"ipcp-accept-local", 0, setipcpaccl}, /* Accept peer's address for us */
361
    {"ipcp-accept-remote", 0, setipcpaccr}, /* Accept peer's address for it */
362
    {"noccp", 0, noccp},		/* Disable CCP negotiation */
363
    {"-ccp", 0, noccp},			/* Disable CCP negotiation */
364
    {"bsdcomp", 1, setbsdcomp},		/* request BSD-Compress */
365
    {"nobsdcomp", 0, setnobsdcomp},	/* don't allow BSD-Compress */
366
    {"-bsdcomp", 0, setnobsdcomp},	/* don't allow BSD-Compress */
367
    {"deflate", 1, setdeflate},		/* request Deflate compression */
368
    {"nodeflate", 0, setnodeflate},	/* don't allow Deflate compression */
369
    {"-deflate", 0, setnodeflate},	/* don't allow Deflate compression */
370
    {"nodeflatedraft", 0, setnodeflatedraft}, /* don't use draft deflate # */
371
    {"predictor1", 0, setpred1comp},	/* request Predictor-1 */
372
    {"nopredictor1", 0, setnopred1comp},/* don't allow Predictor-1 */
373
    {"-predictor1", 0, setnopred1comp},	/* don't allow Predictor-1 */
374
    {"ipparam", 1, setipparam},		/* set ip script parameter */
375
    {"papcrypt", 0, setpapcrypt},	/* PAP passwords encrypted */
376
    {"idle", 1, setidle},		/* idle time limit (seconds) */
377
    {"holdoff", 1, setholdoff},		/* set holdoff time (seconds) */
378
    {"ms-dns", 1, setdnsaddr},		/* DNS address for the peer's use */
379
    {"ms-wins", 1, setwinsaddr},	/* Nameserver for SMB over TCP/IP for peer */
380
    {"--version", 0, showversion},	/* Show version number */
381
    {"--help", 0, showhelp},		/* Show brief listing of options */
382
    {"-h", 0, showhelp},		/* ditto */
383
384
#ifdef PPP_FILTER
385
    {"pdebug", 1, setpdebug},		/* libpcap debugging */
386
    {"pass-filter", 1, setpassfilter},	/* set filter for packets to pass */
387
    {"active-filter", 1, setactivefilter}, /* set filter for active pkts */
388
#endif
389
390
#ifdef MSLANMAN
391
    {"ms-lanman", 0, setmslanman},	/* Use LanMan psswd when using MS-CHAP */
392
#endif
393
394
    {NULL, 0, NULL}
395
};
396
397
398
#ifndef IMPLEMENTATION
399
#define IMPLEMENTATION ""
400
#endif
401
402
static const char usage_string[] = "\
403
pppd version %s patch level %d%s\n\
404
Usage: %s [ options ], where options are:\n\
405
	<device>	Communicate over the named device\n\
406
	<speed>		Set the baud rate to <speed>\n\
407
	<loc>:<rem>	Set the local and/or remote interface IP\n\
408
			addresses.  Either one may be omitted.\n\
409
	asyncmap <n>	Set the desired async map to hex <n>\n\
410
	auth		Require authentication from peer\n\
411
        connect <p>     Invoke shell command <p> to set up the serial line\n\
412
	crtscts		Use hardware RTS/CTS flow control\n\
413
	defaultroute	Add default route through interface\n\
414
	file <f>	Take options from file <f>\n\
415
	modem		Use modem control lines\n\
416
	modem_chat	Use modem control lines during chat\n\
417
	mru <n>		Set MRU value to <n> for negotiation\n\
418
	netmask <n>	Set interface netmask to <n>\n\
419
See pppd(8) for more options.\n\
420
";
421
422
static char *current_option;	/* the name of the option being parsed */
423
static int privileged_option;	/* set iff the current option came from root */
424
static char *option_source;	/* string saying where the option came from */
425
426
/*
427
 * parse_args - parse a string of arguments from the command line.
428
 */
429
int
430
parse_args(argc, argv)
431
    int argc;
432
    char **argv;
433
{
434
    char *arg;
435
    struct cmd *cmdp;
436
    int ret;
437
438
    privileged_option = privileged;
439
    option_source = "command line";
440
    while (argc > 0) {
441
	arg = *argv++;
442
	--argc;
443
444
	/*
445
	 * First see if it's a command.
446
	 */
447
	for (cmdp = cmds; cmdp->cmd_name; cmdp++)
448
	    if (!strcmp(arg, cmdp->cmd_name))
449
		break;
450
451
	if (cmdp->cmd_name != NULL) {
452
	    if (argc < cmdp->num_args) {
453
		option_error("too few parameters for option %s", arg);
454
		return 0;
455
	    }
456
	    current_option = arg;
457
	    if (!(*cmdp->cmd_func)(argv))
458
		return 0;
459
	    argc -= cmdp->num_args;
460
	    argv += cmdp->num_args;
461
462
	} else {
463
	    /*
464
	     * Maybe a tty name, speed or IP address?
465
	     */
466
	    if ((ret = setdevname(arg, 0)) == 0
467
		&& (ret = setspeed(arg)) == 0
468
		&& (ret = setipaddr(arg)) == 0) {
469
		option_error("unrecognized option '%s'", arg);
470
		usage();
471
		return 0;
472
	    }
473
	    if (ret < 0)	/* error */
474
		return 0;
475
	}
476
    }
477
    return 1;
478
}
479
480
/*
481
 * scan_args - scan the command line arguments to get the tty name,
482
 * if specified.
483
 */
484
void
485
scan_args(argc, argv)
486
    int argc;
487
    char **argv;
488
{
489
    char *arg;
490
    struct cmd *cmdp;
491
492
    while (argc > 0) {
493
	arg = *argv++;
494
	--argc;
495
496
	/* Skip options and their arguments */
497
	for (cmdp = cmds; cmdp->cmd_name; cmdp++)
498
	    if (!strcmp(arg, cmdp->cmd_name))
499
		break;
500
501
	if (cmdp->cmd_name != NULL) {
502
	    argc -= cmdp->num_args;
503
	    argv += cmdp->num_args;
504
	    continue;
505
	}
506
507
	/* Check if it's a tty name and copy it if so */
508
	(void) setdevname(arg, 1);
509
    }
510
}
511
512
/*
513
 * usage - print out a message telling how to use the program.
514
 */
515
void
516
usage()
517
{
518
    if (phase == PHASE_INITIALIZE)
519
	fprintf(stderr, usage_string, VERSION, PATCHLEVEL, IMPLEMENTATION,
520
		__progname);
521
}
522
523
/*
524
 * showhelp - print out usage message and exit.
525
 */
526
static int
527
showhelp(argv)
528
    char **argv;
529
{
530
    if (phase == PHASE_INITIALIZE) {
531
	usage();
532
	exit(0);
533
    }
534
    return 0;
535
}
536
537
/*
538
 * showversion - print out the version number and exit.
539
 */
540
static int
541
showversion(argv)
542
    char **argv;
543
{
544
    if (phase == PHASE_INITIALIZE) {
545
	fprintf(stderr, "pppd version %s patch level %d%s\n",
546
		VERSION, PATCHLEVEL, IMPLEMENTATION);
547
	exit(0);
548
    }
549
    return 0;
550
}
551
552
/*
553
 * options_from_file - Read a string of options from a file,
554
 * and interpret them.
555
 */
556
int
557
options_from_file(filename, must_exist, check_prot, priv)
558
    char *filename;
559
    int must_exist;
560
    int check_prot;
561
    int priv;
562
{
563
    FILE *f;
564
    int i, newline, ret;
565
    struct cmd *cmdp;
566
    int oldpriv;
567
    char *argv[MAXARGS];
568
    char args[MAXARGS][MAXWORDLEN];
569
    char cmd[MAXWORDLEN];
570
571
    if ((f = fopen(filename, "r")) == NULL) {
572
	if (!must_exist && errno == ENOENT)
573
	    return 1;
574
	option_error("Can't open options file %s: %m", filename);
575
	return 0;
576
    }
577
    if (check_prot && !readable(fileno(f))) {
578
	option_error("Can't open options file %s: access denied", filename);
579
	fclose(f);
580
	return 0;
581
    }
582
583
    oldpriv = privileged_option;
584
    privileged_option = priv;
585
    ret = 0;
586
    while (getword(f, cmd, &newline, filename)) {
587
	/*
588
	 * First see if it's a command.
589
	 */
590
	for (cmdp = cmds; cmdp->cmd_name; cmdp++)
591
	    if (!strcmp(cmd, cmdp->cmd_name))
592
		break;
593
594
	if (cmdp->cmd_name != NULL) {
595
	    for (i = 0; i < cmdp->num_args; ++i) {
596
		if (!getword(f, args[i], &newline, filename)) {
597
		    option_error(
598
			"In file %s: too few parameters for option '%s'",
599
			filename, cmd);
600
		    goto err;
601
		}
602
		argv[i] = args[i];
603
	    }
604
	    current_option = cmd;
605
	    if (!(*cmdp->cmd_func)(argv))
606
		goto err;
607
608
	} else {
609
	    /*
610
	     * Maybe a tty name, speed or IP address?
611
	     */
612
	    if ((i = setdevname(cmd, 0)) == 0
613
		&& (i = setspeed(cmd)) == 0
614
		&& (i = setipaddr(cmd)) == 0) {
615
		option_error("In file %s: unrecognized option '%s'",
616
			     filename, cmd);
617
		goto err;
618
	    }
619
	    if (i < 0)		/* error */
620
		goto err;
621
	}
622
    }
623
    ret = 1;
624
625
err:
626
    fclose(f);
627
    privileged_option = oldpriv;
628
    return ret;
629
}
630
631
/*
632
 * options_from_user - See if the use has a ~/.ppprc file,
633
 * and if so, interpret options from it.
634
 */
635
int
636
options_from_user()
637
{
638
    char *user, *path, *file;
639
    int ret;
640
    struct passwd *pw;
641
642
    pw = getpwuid(getuid());
643
    if (pw == NULL || (user = pw->pw_dir) == NULL || user[0] == 0)
644
	return 1;
645
    file = _PATH_USEROPT;
646
    if (asprintf(&path, "%s/%s", user, file) == -1)
647
	novm("init file name");
648
    ret = options_from_file(path, 0, 1, privileged);
649
    free(path);
650
    return ret;
651
}
652
653
/*
654
 * options_for_tty - See if an options file exists for the serial
655
 * device, and if so, interpret options from it.
656
 */
657
int
658
options_for_tty()
659
{
660
    char *dev, *path;
661
    int ret;
662
663
    dev = devnam;
664
    if (strncmp(dev, "/dev/", 5) == 0)
665
	dev += 5;
666
    if (strcmp(dev, "tty") == 0)
667
	return 1;		/* don't look for /etc/ppp/options.tty */
668
    if (asprintf(&path, "%s%s", _PATH_TTYOPT, dev) == -1)
669
	novm("tty init file name");
670
    ret = options_from_file(path, 0, 0, 1);
671
    free(path);
672
    return ret;
673
}
674
675
/*
676
 * option_error - print a message about an error in an option.
677
 * The message is logged, and also sent to
678
 * stderr if phase == PHASE_INITIALIZE.
679
 */
680
void
681
option_error(char *fmt, ...)
682
{
683
    va_list args;
684
    char buf[256];
685
686
    va_start(args, fmt);
687
    vfmtmsg(buf, sizeof(buf), fmt, args);
688
    va_end(args);
689
    if (phase == PHASE_INITIALIZE)
690
	fprintf(stderr, "%s: %s\n", __progname, buf);
691
    syslog(LOG_ERR, "%s", buf);
692
}
693
694
/*
695
 * readable - check if a file is readable by the real user.
696
 */
697
static int
698
readable(fd)
699
    int fd;
700
{
701
    uid_t uid;
702
    int ngroups, i;
703
    struct stat sbuf;
704
    GIDSET_TYPE groups[NGROUPS_MAX];
705
706
    uid = getuid();
707
    if (uid == 0)
708
	return 1;
709
    if (fstat(fd, &sbuf) != 0)
710
	return 0;
711
    if (sbuf.st_uid == uid)
712
	return sbuf.st_mode & S_IRUSR;
713
    if (sbuf.st_gid == getgid())
714
	return sbuf.st_mode & S_IRGRP;
715
    ngroups = getgroups(NGROUPS_MAX, groups);
716
    for (i = 0; i < ngroups; ++i)
717
	if (sbuf.st_gid == groups[i])
718
	    return sbuf.st_mode & S_IRGRP;
719
    return sbuf.st_mode & S_IROTH;
720
}
721
722
/*
723
 * Read a word from a file.
724
 * Words are delimited by white-space or by quotes (" or ').
725
 * Quotes, white-space and \ may be escaped with \.
726
 * \<newline> is ignored.
727
 */
728
int
729
getword(f, word, newlinep, filename)
730
    FILE *f;
731
    char *word;
732
    int *newlinep;
733
    char *filename;
734
{
735
    int c, len, escape;
736
    int quoted, comment;
737
    int value, digit, got, n;
738
739
#define isoctal(c) ((c) >= '0' && (c) < '8')
740
741
    *newlinep = 0;
742
    len = 0;
743
    escape = 0;
744
    comment = 0;
745
746
    /*
747
     * First skip white-space and comments.
748
     */
749
    for (;;) {
750
	c = getc(f);
751
	if (c == EOF)
752
	    break;
753
754
	/*
755
	 * A newline means the end of a comment; backslash-newline
756
	 * is ignored.  Note that we cannot have escape && comment.
757
	 */
758
	if (c == '\n') {
759
	    if (!escape) {
760
		*newlinep = 1;
761
		comment = 0;
762
	    } else
763
		escape = 0;
764
	    continue;
765
	}
766
767
	/*
768
	 * Ignore characters other than newline in a comment.
769
	 */
770
	if (comment)
771
	    continue;
772
773
	/*
774
	 * If this character is escaped, we have a word start.
775
	 */
776
	if (escape)
777
	    break;
778
779
	/*
780
	 * If this is the escape character, look at the next character.
781
	 */
782
	if (c == '\\') {
783
	    escape = 1;
784
	    continue;
785
	}
786
787
	/*
788
	 * If this is the start of a comment, ignore the rest of the line.
789
	 */
790
	if (c == '#') {
791
	    comment = 1;
792
	    continue;
793
	}
794
795
	/*
796
	 * A non-whitespace character is the start of a word.
797
	 */
798
	if (!isspace(c))
799
	    break;
800
    }
801
802
    /*
803
     * Save the delimiter for quoted strings.
804
     */
805
    if (!escape && (c == '"' || c == '\'')) {
806
        quoted = c;
807
	c = getc(f);
808
    } else
809
        quoted = 0;
810
811
    /*
812
     * Process characters until the end of the word.
813
     */
814
    while (c != EOF) {
815
	if (escape) {
816
	    /*
817
	     * This character is escaped: backslash-newline is ignored,
818
	     * various other characters indicate particular values
819
	     * as for C backslash-escapes.
820
	     */
821
	    escape = 0;
822
	    if (c == '\n') {
823
	        c = getc(f);
824
		continue;
825
	    }
826
827
	    got = 0;
828
	    switch (c) {
829
	    case 'a':
830
		value = '\a';
831
		break;
832
	    case 'b':
833
		value = '\b';
834
		break;
835
	    case 'f':
836
		value = '\f';
837
		break;
838
	    case 'n':
839
		value = '\n';
840
		break;
841
	    case 'r':
842
		value = '\r';
843
		break;
844
	    case 's':
845
		value = ' ';
846
		break;
847
	    case 't':
848
		value = '\t';
849
		break;
850
851
	    default:
852
		if (isoctal(c)) {
853
		    /*
854
		     * \ddd octal sequence
855
		     */
856
		    value = 0;
857
		    for (n = 0; n < 3 && isoctal(c); ++n) {
858
			value = (value << 3) + (c & 07);
859
			c = getc(f);
860
		    }
861
		    got = 1;
862
		    break;
863
		}
864
865
		if (c == 'x') {
866
		    /*
867
		     * \x<hex_string> sequence
868
		     */
869
		    value = 0;
870
		    c = getc(f);
871
		    for (n = 0; n < 2 && isxdigit(c); ++n) {
872
			digit = toupper(c) - '0';
873
			if (digit > 10)
874
			    digit += '0' + 10 - 'A';
875
			value = (value << 4) + digit;
876
			c = getc (f);
877
		    }
878
		    got = 1;
879
		    break;
880
		}
881
882
		/*
883
		 * Otherwise the character stands for itself.
884
		 */
885
		value = c;
886
		break;
887
	    }
888
889
	    /*
890
	     * Store the resulting character for the escape sequence.
891
	     */
892
	    if (len < MAXWORDLEN) {
893
		word[len] = value;
894
		++len;
895
	    }
896
897
	    if (!got)
898
		c = getc(f);
899
	    continue;
900
901
	}
902
903
	/*
904
	 * Not escaped: see if we've reached the end of the word.
905
	 */
906
	if (quoted) {
907
	    if (c == quoted)
908
		break;
909
	} else {
910
	    if (isspace(c) || c == '#') {
911
		ungetc (c, f);
912
		break;
913
	    }
914
	}
915
916
	/*
917
	 * Backslash starts an escape sequence.
918
	 */
919
	if (c == '\\') {
920
	    escape = 1;
921
	    c = getc(f);
922
	    continue;
923
	}
924
925
	/*
926
	 * An ordinary character: store it in the word and get another.
927
	 */
928
	if (len < MAXWORDLEN) {
929
	    word[len] = c;
930
	    ++len;
931
	}
932
933
	c = getc(f);
934
    }
935
936
    /*
937
     * End of the word: check for errors.
938
     */
939
    if (c == EOF) {
940
	if (ferror(f)) {
941
	    if (errno == 0)
942
		errno = EIO;
943
	    option_error("Error reading %s: %m", filename);
944
	    die(1);
945
	}
946
	/*
947
	 * If len is zero, then we didn't find a word before the
948
	 * end of the file.
949
	 */
950
	if (len == 0)
951
	    return 0;
952
    }
953
954
    /*
955
     * Warn if the word was too long, and append a terminating null.
956
     */
957
    if (len >= MAXWORDLEN) {
958
	option_error("warning: word in file %s too long (%.20s...)",
959
		     filename, word);
960
	len = MAXWORDLEN - 1;
961
    }
962
    word[len] = 0;
963
964
    return 1;
965
966
#undef isoctal
967
968
}
969
970
/*
971
 * number_option - parse an unsigned numeric parameter for an option.
972
 */
973
static int
974
number_option(str, valp, base)
975
    char *str;
976
    u_int32_t *valp;
977
    int base;
978
{
979
    char *ptr;
980
981
    *valp = strtoul(str, &ptr, base);
982
    if (ptr == str) {
983
	option_error("invalid numeric parameter '%s' for %s option",
984
		     str, current_option);
985
	return 0;
986
    }
987
    return 1;
988
}
989
990
991
/*
992
 * int_option - like number_option, but valp is int *,
993
 * the base is assumed to be 0, and *valp is not changed
994
 * if there is an error.
995
 */
996
static int
997
int_option(str, valp)
998
    char *str;
999
    int *valp;
1000
{
1001
    u_int32_t v;
1002
1003
    if (!number_option(str, &v, 0))
1004
	return 0;
1005
    *valp = (int) v;
1006
    return 1;
1007
}
1008
1009
1010
/*
1011
 * The following procedures parse options.
1012
 */
1013
1014
/*
1015
 * readfile - take commands from a file.
1016
 */
1017
static int
1018
readfile(argv)
1019
    char **argv;
1020
{
1021
    return options_from_file(*argv, 1, 1, privileged_option);
1022
}
1023
1024
/*
1025
 * callfile - take commands from /etc/ppp/peers/<name>.
1026
 * Name may not contain /../, start with / or ../, or end in /..
1027
 */
1028
static int
1029
callfile(argv)
1030
    char **argv;
1031
{
1032
    char *fname, *arg, *p;
1033
    int l, ok;
1034
1035
    arg = *argv;
1036
    ok = 1;
1037
    if (arg[0] == '/' || arg[0] == 0)
1038
	ok = 0;
1039
    else {
1040
	for (p = arg; *p != 0; ) {
1041
	    if (p[0] == '.' && p[1] == '.' && (p[2] == '/' || p[2] == 0)) {
1042
		ok = 0;
1043
		break;
1044
	    }
1045
	    while (*p != '/' && *p != 0)
1046
		++p;
1047
	    if (*p == '/')
1048
		++p;
1049
	}
1050
    }
1051
    if (!ok) {
1052
	option_error("call option value may not contain .. or start with /");
1053
	return 0;
1054
    }
1055
1056
    l = strlen(arg) + strlen(_PATH_PEERFILES) + 1;
1057
    if ((fname = (char *) malloc(l)) == NULL)
1058
	novm("call file name");
1059
    strlcpy(fname, _PATH_PEERFILES, l);
1060
    strlcat(fname, arg, l);
1061
1062
    ok = options_from_file(fname, 1, 1, 1);
1063
1064
    free(fname);
1065
    return ok;
1066
}
1067
1068
1069
/*
1070
 * setdebug - Set debug (command line argument).
1071
 */
1072
static int
1073
setdebug(argv)
1074
    char **argv;
1075
{
1076
    debug++;
1077
    return (1);
1078
}
1079
1080
/*
1081
 * setkdebug - Set kernel debugging level.
1082
 */
1083
static int
1084
setkdebug(argv)
1085
    char **argv;
1086
{
1087
    return int_option(*argv, &kdebugflag);
1088
}
1089
1090
#ifdef PPP_FILTER
1091
/*
1092
 * setpdebug - Set libpcap debugging level.
1093
 */
1094
static int
1095
setpdebug(argv)
1096
    char **argv;
1097
{
1098
    return int_option(*argv, &dflag);
1099
}
1100
1101
/*
1102
 * setpassfilter - Set the pass filter for packets
1103
 */
1104
static int
1105
setpassfilter(argv)
1106
    char **argv;
1107
{
1108
    pc.linktype = DLT_PPP;
1109
    pc.snapshot = PPP_HDRLEN;
1110
1111
    if (pcap_compile(&pc, &pass_filter, *argv, 1, netmask) == 0)
1112
	return 1;
1113
    option_error("error in pass-filter expression: %s\n", pcap_geterr(&pc));
1114
    return 0;
1115
}
1116
1117
/*
1118
 * setactivefilter - Set the active filter for packets
1119
 */
1120
static int
1121
setactivefilter(argv)
1122
    char **argv;
1123
{
1124
    pc.linktype = DLT_PPP;
1125
    pc.snapshot = PPP_HDRLEN;
1126
1127
    if (pcap_compile(&pc, &active_filter, *argv, 1, netmask) == 0)
1128
	return 1;
1129
    option_error("error in active-filter expression: %s\n", pcap_geterr(&pc));
1130
    return 0;
1131
}
1132
#endif
1133
1134
/*
1135
 * noopt - Disable all options.
1136
 */
1137
static int
1138
noopt(argv)
1139
    char **argv;
1140
{
1141
    BZERO((char *) &lcp_wantoptions[0], sizeof (struct lcp_options));
1142
    BZERO((char *) &lcp_allowoptions[0], sizeof (struct lcp_options));
1143
    BZERO((char *) &ipcp_wantoptions[0], sizeof (struct ipcp_options));
1144
    BZERO((char *) &ipcp_allowoptions[0], sizeof (struct ipcp_options));
1145
1146
    return (1);
1147
}
1148
1149
/*
1150
 * noaccomp - Disable Address/Control field compression negotiation.
1151
 */
1152
static int
1153
noaccomp(argv)
1154
    char **argv;
1155
{
1156
    lcp_wantoptions[0].neg_accompression = 0;
1157
    lcp_allowoptions[0].neg_accompression = 0;
1158
    return (1);
1159
}
1160
1161
1162
/*
1163
 * noasyncmap - Disable async map negotiation.
1164
 */
1165
static int
1166
noasyncmap(argv)
1167
    char **argv;
1168
{
1169
    lcp_wantoptions[0].neg_asyncmap = 0;
1170
    lcp_allowoptions[0].neg_asyncmap = 0;
1171
    return (1);
1172
}
1173
1174
1175
/*
1176
 * noip - Disable IP and IPCP.
1177
 */
1178
static int
1179
noip(argv)
1180
    char **argv;
1181
{
1182
    ipcp_protent.enabled_flag = 0;
1183
    return (1);
1184
}
1185
1186
1187
/*
1188
 * nomagicnumber - Disable magic number negotiation.
1189
 */
1190
static int
1191
nomagicnumber(argv)
1192
    char **argv;
1193
{
1194
    lcp_wantoptions[0].neg_magicnumber = 0;
1195
    lcp_allowoptions[0].neg_magicnumber = 0;
1196
    return (1);
1197
}
1198
1199
1200
/*
1201
 * nomru - Disable mru negotiation.
1202
 */
1203
static int
1204
nomru(argv)
1205
    char **argv;
1206
{
1207
    lcp_wantoptions[0].neg_mru = 0;
1208
    lcp_allowoptions[0].neg_mru = 0;
1209
    return (1);
1210
}
1211
1212
1213
/*
1214
 * setmru - Set MRU for negotiation.
1215
 */
1216
static int
1217
setmru(argv)
1218
    char **argv;
1219
{
1220
    u_int32_t mru;
1221
1222
    if (!number_option(*argv, &mru, 0))
1223
	return 0;
1224
    lcp_wantoptions[0].mru = mru;
1225
    lcp_wantoptions[0].neg_mru = 1;
1226
    return (1);
1227
}
1228
1229
1230
/*
1231
 * setmru - Set the largest MTU we'll use.
1232
 */
1233
static int
1234
setmtu(argv)
1235
    char **argv;
1236
{
1237
    u_int32_t mtu;
1238
1239
    if (!number_option(*argv, &mtu, 0))
1240
	return 0;
1241
    if (mtu < MINMRU || mtu > MAXMRU) {
1242
	option_error("mtu option value of %u is too %s", mtu,
1243
		     (mtu < MINMRU? "small": "large"));
1244
	return 0;
1245
    }
1246
    lcp_allowoptions[0].mru = mtu;
1247
    return (1);
1248
}
1249
1250
#ifdef CBCP_SUPPORT
1251
static int
1252
setcbcp(argv)
1253
    char **argv;
1254
{
1255
    lcp_wantoptions[0].neg_cbcp = 1;
1256
    cbcp_protent.enabled_flag = 1;
1257
    cbcp[0].us_number = strdup(*argv);
1258
    if (cbcp[0].us_number == 0)
1259
	novm("callback number");
1260
    cbcp[0].us_type |= (1 << CB_CONF_USER);
1261
    cbcp[0].us_type |= (1 << CB_CONF_ADMIN);
1262
    return (1);
1263
}
1264
#endif
1265
1266
/*
1267
 * nopcomp - Disable Protocol field compression negotiation.
1268
 */
1269
static int
1270
nopcomp(argv)
1271
    char **argv;
1272
{
1273
    lcp_wantoptions[0].neg_pcompression = 0;
1274
    lcp_allowoptions[0].neg_pcompression = 0;
1275
    return (1);
1276
}
1277
1278
1279
/*
1280
 * setpassive - Set passive mode (don't give up if we time out sending
1281
 * LCP configure-requests).
1282
 */
1283
static int
1284
setpassive(argv)
1285
    char **argv;
1286
{
1287
    lcp_wantoptions[0].passive = 1;
1288
    return (1);
1289
}
1290
1291
1292
/*
1293
 * setsilent - Set silent mode (don't start sending LCP configure-requests
1294
 * until we get one from the peer).
1295
 */
1296
static int
1297
setsilent(argv)
1298
    char **argv;
1299
{
1300
    lcp_wantoptions[0].silent = 1;
1301
    return 1;
1302
}
1303
1304
1305
/*
1306
 * nopap - Disable PAP authentication with peer.
1307
 */
1308
static int
1309
nopap(argv)
1310
    char **argv;
1311
{
1312
    refuse_pap = 1;
1313
    return (1);
1314
}
1315
1316
1317
/*
1318
 * reqpap - Require PAP authentication from peer.
1319
 */
1320
static int
1321
reqpap(argv)
1322
    char **argv;
1323
{
1324
    lcp_wantoptions[0].neg_upap = 1;
1325
    setauth(NULL);
1326
    return 1;
1327
}
1328
1329
/*
1330
 * nochap - Disable CHAP authentication with peer.
1331
 */
1332
static int
1333
nochap(argv)
1334
    char **argv;
1335
{
1336
    refuse_chap = 1;
1337
    return (1);
1338
}
1339
1340
1341
/*
1342
 * reqchap - Require CHAP authentication from peer.
1343
 */
1344
static int
1345
reqchap(argv)
1346
    char **argv;
1347
{
1348
    lcp_wantoptions[0].neg_chap = 1;
1349
    setauth(NULL);
1350
    return (1);
1351
}
1352
1353
1354
/*
1355
 * setnovj - disable vj compression
1356
 */
1357
static int
1358
setnovj(argv)
1359
    char **argv;
1360
{
1361
    ipcp_wantoptions[0].neg_vj = 0;
1362
    ipcp_allowoptions[0].neg_vj = 0;
1363
    return (1);
1364
}
1365
1366
1367
/*
1368
 * setnovjccomp - disable VJ connection-ID compression
1369
 */
1370
static int
1371
setnovjccomp(argv)
1372
    char **argv;
1373
{
1374
    ipcp_wantoptions[0].cflag = 0;
1375
    ipcp_allowoptions[0].cflag = 0;
1376
    return 1;
1377
}
1378
1379
1380
/*
1381
 * setvjslots - set maximum number of connection slots for VJ compression
1382
 */
1383
static int
1384
setvjslots(argv)
1385
    char **argv;
1386
{
1387
    int value;
1388
1389
    if (!int_option(*argv, &value))
1390
	return 0;
1391
    if (value < 2 || value > 16) {
1392
	option_error("vj-max-slots value must be between 2 and 16");
1393
	return 0;
1394
    }
1395
    ipcp_wantoptions [0].maxslotindex =
1396
        ipcp_allowoptions[0].maxslotindex = value - 1;
1397
    return 1;
1398
}
1399
1400
1401
/*
1402
 * setconnector - Set a program to connect to a serial line
1403
 */
1404
static int
1405
setconnector(argv)
1406
    char **argv;
1407
{
1408
    connector = strdup(*argv);
1409
    if (connector == NULL)
1410
	novm("connect script");
1411
    connector_info.priv = privileged_option;
1412
    connector_info.source = option_source;
1413
1414
    return (1);
1415
}
1416
1417
/*
1418
 * setdisconnector - Set a program to disconnect from the serial line
1419
 */
1420
static int
1421
setdisconnector(argv)
1422
    char **argv;
1423
{
1424
    disconnector = strdup(*argv);
1425
    if (disconnector == NULL)
1426
	novm("disconnect script");
1427
    disconnector_info.priv = privileged_option;
1428
    disconnector_info.source = option_source;
1429
1430
    return (1);
1431
}
1432
1433
/*
1434
 * setwelcomer - Set a program to welcome a client after connection
1435
 */
1436
static int
1437
setwelcomer(argv)
1438
    char **argv;
1439
{
1440
    welcomer = strdup(*argv);
1441
    if (welcomer == NULL)
1442
	novm("welcome script");
1443
    welcomer_info.priv = privileged_option;
1444
    welcomer_info.source = option_source;
1445
1446
    return (1);
1447
}
1448
1449
/*
1450
 * setmaxconnect - Set the maximum connect time
1451
 */
1452
static int
1453
setmaxconnect(argv)
1454
    char **argv;
1455
{
1456
    int value;
1457
1458
    if (!int_option(*argv, &value))
1459
	return 0;
1460
    if (value < 0) {
1461
	option_error("maxconnect time must be positive");
1462
	return 0;
1463
    }
1464
    if (maxconnect > 0 && (value == 0 || value > maxconnect)) {
1465
	option_error("maxconnect time cannot be increased");
1466
	return 0;
1467
    }
1468
    maxconnect = value;
1469
    return 1;
1470
}
1471
1472
/*
1473
 * setdomain - Set domain name to append to hostname
1474
 */
1475
static int
1476
setdomain(argv)
1477
    char **argv;
1478
{
1479
    if (!privileged_option) {
1480
	option_error("using the domain option requires root privilege");
1481
	return 0;
1482
    }
1483
    gethostname(hostname, MAXNAMELEN);
1484
    if (**argv != 0) {
1485
	if (**argv != '.')
1486
	    strlcat(hostname, ".", MAXNAMELEN);
1487
	strlcat(hostname, *argv, MAXNAMELEN);
1488
    }
1489
    hostname[MAXNAMELEN-1] = 0;
1490
    return (1);
1491
}
1492
1493
1494
/*
1495
 * setasyncmap - add bits to asyncmap (what we request peer to escape).
1496
 */
1497
static int
1498
setasyncmap(argv)
1499
    char **argv;
1500
{
1501
    u_int32_t asyncmap;
1502
1503
    if (!number_option(*argv, &asyncmap, 16))
1504
	return 0;
1505
    lcp_wantoptions[0].asyncmap |= asyncmap;
1506
    lcp_wantoptions[0].neg_asyncmap = 1;
1507
    return(1);
1508
}
1509
1510
1511
/*
1512
 * setescape - add chars to the set we escape on transmission.
1513
 */
1514
static int
1515
setescape(argv)
1516
    char **argv;
1517
{
1518
    int n, ret;
1519
    char *p, *endp;
1520
1521
    p = *argv;
1522
    ret = 1;
1523
    while (*p) {
1524
	n = strtol(p, &endp, 16);
1525
	if (p == endp) {
1526
	    option_error("escape parameter contains invalid hex number '%s'",
1527
			 p);
1528
	    return 0;
1529
	}
1530
	p = endp;
1531
	if (n < 0 || (0x20 <= n && n <= 0x3F) || n == 0x5E || n > 0xFF) {
1532
	    option_error("can't escape character 0x%x", n);
1533
	    ret = 0;
1534
	} else
1535
	    xmit_accm[0][n >> 5] |= 1 << (n & 0x1F);
1536
	while (*p == ',' || *p == ' ')
1537
	    ++p;
1538
    }
1539
    return ret;
1540
}
1541
1542
1543
/*
1544
 * setspeed - Set the speed.
1545
 */
1546
static int
1547
setspeed(arg)
1548
    char *arg;
1549
{
1550
    char *ptr;
1551
    int spd;
1552
1553
    spd = strtol(arg, &ptr, 0);
1554
    if (ptr == arg || *ptr != 0 || spd == 0)
1555
	return 0;
1556
    inspeed = spd;
1557
    return 1;
1558
}
1559
1560
1561
/*
1562
 * setdevname - Set the device name.
1563
 */
1564
static int
1565
setdevname(cp, quiet)
1566
    char *cp;
1567
    int quiet;
1568
{
1569
    struct stat statbuf;
1570
    char dev[PATH_MAX];
1571
1572
    if (*cp == 0)
1573
	return 0;
1574
1575
    if (strncmp("/dev/", cp, 5) != 0) {
1576
	strlcpy(dev, "/dev/", sizeof dev);
1577
	strlcat(dev, cp, sizeof dev);
1578
	cp = dev;
1579
    }
1580
1581
    /*
1582
     * Check if there is a device by this name.
1583
     */
1584
    if (stat(cp, &statbuf) < 0) {
1585
	if (errno == ENOENT || quiet)
1586
	    return 0;
1587
	option_error("Couldn't stat %s: %m", cp);
1588
	return -1;
1589
    }
1590
1591
    (void) strlcpy(devnam, cp, PATH_MAX);
1592
    default_device = FALSE;
1593
    devnam_info.priv = privileged_option;
1594
    devnam_info.source = option_source;
1595
1596
    return 1;
1597
}
1598
1599
1600
/*
1601
 * setipaddr - Set the IP address
1602
 */
1603
static int
1604
setipaddr(arg)
1605
    char *arg;
1606
{
1607
    struct hostent *hp;
1608
    char *colon;
1609
    struct in_addr ina;
1610
    u_int32_t local, remote;
1611
    ipcp_options *wo = &ipcp_wantoptions[0];
1612
1613
    /*
1614
     * IP address pair separated by ":".
1615
     */
1616
    if ((colon = strchr(arg, ':')) == NULL)
1617
	return 0;
1618
1619
    /*
1620
     * If colon first character, then no local addr.
1621
     */
1622
    if (colon != arg) {
1623
	*colon = '\0';
1624
	if (inet_aton(arg, &ina) == 0) {
1625
	    if ((hp = gethostbyname(arg)) == NULL) {
1626
		option_error("unknown host: %s", arg);
1627
		return -1;
1628
	    } else {
1629
		local = *(u_int32_t *)hp->h_addr;
1630
		if (our_name[0] == 0)
1631
		    strlcpy(our_name, arg, MAXNAMELEN);
1632
	    }
1633
	} else
1634
	    local = ina.s_addr;
1635
	if (bad_ip_adrs(local)) {
1636
	    option_error("bad local IP address %s", ip_ntoa(local));
1637
	    return -1;
1638
	}
1639
	if (local != 0)
1640
	    wo->ouraddr = local;
1641
	*colon = ':';
1642
    }
1643
1644
    /*
1645
     * If colon last character, then no remote addr.
1646
     */
1647
    if (*++colon != '\0') {
1648
	if (inet_aton(colon, &ina) == 0) {
1649
	    if ((hp = gethostbyname(colon)) == NULL) {
1650
		option_error("unknown host: %s", colon);
1651
		return -1;
1652
	    } else {
1653
		remote = *(u_int32_t *)hp->h_addr;
1654
		if (remote_name[0] == 0)
1655
		    strlcpy(remote_name, colon, MAXNAMELEN);
1656
	    }
1657
	} else
1658
	    remote = ina.s_addr;
1659
	if (bad_ip_adrs(remote)) {
1660
	    option_error("bad remote IP address %s", ip_ntoa(remote));
1661
	    return -1;
1662
	}
1663
	if (remote != 0)
1664
	    wo->hisaddr = remote;
1665
    }
1666
1667
    return 1;
1668
}
1669
1670
1671
/*
1672
 * setnoipdflt - disable setipdefault()
1673
 */
1674
static int
1675
setnoipdflt(argv)
1676
    char **argv;
1677
{
1678
    disable_defaultip = 1;
1679
    return 1;
1680
}
1681
1682
1683
/*
1684
 * setipcpaccl - accept peer's idea of our address
1685
 */
1686
static int
1687
setipcpaccl(argv)
1688
    char **argv;
1689
{
1690
    ipcp_wantoptions[0].accept_local = 1;
1691
    return 1;
1692
}
1693
1694
1695
/*
1696
 * setipcpaccr - accept peer's idea of its address
1697
 */
1698
static int
1699
setipcpaccr(argv)
1700
    char **argv;
1701
{
1702
    ipcp_wantoptions[0].accept_remote = 1;
1703
    return 1;
1704
}
1705
1706
1707
/*
1708
 * setnetmask - set the netmask to be used on the interface.
1709
 */
1710
static int
1711
setnetmask(argv)
1712
    char **argv;
1713
{
1714
    struct in_addr ina;
1715
1716
    if (inet_aton(*argv, &ina) == 0 || (netmask & ~ina.s_addr) != 0) {
1717
	option_error("invalid netmask value '%s'", *argv);
1718
	return (0);
1719
    }
1720
1721
    netmask = ina.s_addr;
1722
    return (1);
1723
}
1724
1725
static int
1726
setcrtscts(argv)
1727
    char **argv;
1728
{
1729
    crtscts = 1;
1730
    return (1);
1731
}
1732
1733
static int
1734
setnocrtscts(argv)
1735
    char **argv;
1736
{
1737
    crtscts = -1;
1738
    return (1);
1739
}
1740
1741
static int
1742
setxonxoff(argv)
1743
    char **argv;
1744
{
1745
    lcp_wantoptions[0].asyncmap |= 0x000A0000;	/* escape ^S and ^Q */
1746
    lcp_wantoptions[0].neg_asyncmap = 1;
1747
1748
    crtscts = -2;
1749
    return (1);
1750
}
1751
1752
static int
1753
setnodetach(argv)
1754
    char **argv;
1755
{
1756
    nodetach = 1;
1757
    return (1);
1758
}
1759
1760
static int
1761
setupdetach(argv)
1762
    char **argv;
1763
{
1764
    nodetach = -1;
1765
    return (1);
1766
}
1767
1768
static int
1769
setdemand(argv)
1770
    char **argv;
1771
{
1772
    demand = 1;
1773
    persist = 1;
1774
    return 1;
1775
}
1776
1777
static int
1778
setmodem(argv)
1779
    char **argv;
1780
{
1781
    modem = 1;
1782
    return 1;
1783
}
1784
1785
static int
1786
setmodem_chat(argv)
1787
    char **argv;
1788
{
1789
    modem_chat = 1;
1790
    return 1;
1791
}
1792
1793
static int
1794
setlocal(argv)
1795
    char **argv;
1796
{
1797
    modem = 0;
1798
    return 1;
1799
}
1800
1801
static int
1802
setlock(argv)
1803
    char **argv;
1804
{
1805
    lockflag = 1;
1806
    return 1;
1807
}
1808
1809
static int
1810
setusehostname(argv)
1811
    char **argv;
1812
{
1813
    usehostname = 1;
1814
    return 1;
1815
}
1816
1817
static int
1818
setname(argv)
1819
    char **argv;
1820
{
1821
    if (!privileged_option) {
1822
	option_error("using the name option requires root privilege");
1823
	return 0;
1824
    }
1825
    strlcpy(our_name, argv[0], MAXNAMELEN);
1826
    return 1;
1827
}
1828
1829
static int
1830
setuser(argv)
1831
    char **argv;
1832
{
1833
    strlcpy(user, argv[0], MAXNAMELEN);
1834
    return 1;
1835
}
1836
1837
static int
1838
setremote(argv)
1839
    char **argv;
1840
{
1841
    strlcpy(remote_name, argv[0], MAXNAMELEN);
1842
    return 1;
1843
}
1844
1845
static int
1846
setauth(argv)
1847
    char **argv;
1848
{
1849
    auth_required = 1;
1850
    if (privileged_option > auth_req_info.priv) {
1851
	auth_req_info.priv = privileged_option;
1852
	auth_req_info.source = option_source;
1853
    }
1854
    return 1;
1855
}
1856
1857
static int
1858
setnoauth(argv)
1859
    char **argv;
1860
{
1861
    if (auth_required && privileged_option < auth_req_info.priv) {
1862
	if (auth_req_info.source == NULL)
1863
	    option_error("cannot override default auth option");
1864
	else
1865
	    option_error("cannot override auth option set by %s",
1866
	        auth_req_info.source);
1867
	return 0;
1868
    }
1869
    auth_required = 0;
1870
    return 1;
1871
}
1872
1873
static int
1874
setdefaultroute(argv)
1875
    char **argv;
1876
{
1877
    if (!ipcp_allowoptions[0].default_route) {
1878
	option_error("defaultroute option is disabled");
1879
	return 0;
1880
    }
1881
    ipcp_wantoptions[0].default_route = 1;
1882
    return 1;
1883
}
1884
1885
static int
1886
setnodefaultroute(argv)
1887
    char **argv;
1888
{
1889
    ipcp_allowoptions[0].default_route = 0;
1890
    ipcp_wantoptions[0].default_route = 0;
1891
    return 1;
1892
}
1893
1894
static int
1895
setproxyarp(argv)
1896
    char **argv;
1897
{
1898
    if (!ipcp_allowoptions[0].proxy_arp) {
1899
	option_error("proxyarp option is disabled");
1900
	return 0;
1901
    }
1902
    ipcp_wantoptions[0].proxy_arp = 1;
1903
    return 1;
1904
}
1905
1906
static int
1907
setnoproxyarp(argv)
1908
    char **argv;
1909
{
1910
    ipcp_wantoptions[0].proxy_arp = 0;
1911
    ipcp_allowoptions[0].proxy_arp = 0;
1912
    return 1;
1913
}
1914
1915
static int
1916
setpersist(argv)
1917
    char **argv;
1918
{
1919
    persist = 1;
1920
    return 1;
1921
}
1922
1923
static int
1924
setnopersist(argv)
1925
    char **argv;
1926
{
1927
    persist = 0;
1928
    return 1;
1929
}
1930
1931
static int
1932
setdologin(argv)
1933
    char **argv;
1934
{
1935
    uselogin = 1;
1936
    return 1;
1937
}
1938
1939
/*
1940
 * Functions to set the echo interval for modem-less monitors
1941
 */
1942
1943
static int
1944
setlcpechointv(argv)
1945
    char **argv;
1946
{
1947
    return int_option(*argv, &lcp_echo_interval);
1948
}
1949
1950
static int
1951
setlcpechofails(argv)
1952
    char **argv;
1953
{
1954
    return int_option(*argv, &lcp_echo_fails);
1955
}
1956
1957
/*
1958
 * Functions to set timeouts, max transmits, etc.
1959
 */
1960
static int
1961
setlcptimeout(argv)
1962
    char **argv;
1963
{
1964
    return int_option(*argv, &lcp_fsm[0].timeouttime);
1965
}
1966
1967
static int
1968
setlcpterm(argv)
1969
    char **argv;
1970
{
1971
    return int_option(*argv, &lcp_fsm[0].maxtermtransmits);
1972
}
1973
1974
static int
1975
setlcpconf(argv)
1976
    char **argv;
1977
{
1978
    return int_option(*argv, &lcp_fsm[0].maxconfreqtransmits);
1979
}
1980
1981
static int
1982
setlcpfails(argv)
1983
    char **argv;
1984
{
1985
    return int_option(*argv, &lcp_fsm[0].maxnakloops);
1986
}
1987
1988
static int
1989
setipcptimeout(argv)
1990
    char **argv;
1991
{
1992
    return int_option(*argv, &ipcp_fsm[0].timeouttime);
1993
}
1994
1995
static int
1996
setipcpterm(argv)
1997
    char **argv;
1998
{
1999
    return int_option(*argv, &ipcp_fsm[0].maxtermtransmits);
2000
}
2001
2002
static int
2003
setipcpconf(argv)
2004
    char **argv;
2005
{
2006
    return int_option(*argv, &ipcp_fsm[0].maxconfreqtransmits);
2007
}
2008
2009
static int
2010
setipcpfails(argv)
2011
    char **argv;
2012
{
2013
    return int_option(*argv, &lcp_fsm[0].maxnakloops);
2014
}
2015
2016
static int
2017
setpaptimeout(argv)
2018
    char **argv;
2019
{
2020
    return int_option(*argv, &upap[0].us_timeouttime);
2021
}
2022
2023
static int
2024
setpapreqtime(argv)
2025
    char **argv;
2026
{
2027
    return int_option(*argv, &upap[0].us_reqtimeout);
2028
}
2029
2030
static int
2031
setpapreqs(argv)
2032
    char **argv;
2033
{
2034
    return int_option(*argv, &upap[0].us_maxtransmits);
2035
}
2036
2037
static int
2038
setchaptimeout(argv)
2039
    char **argv;
2040
{
2041
    return int_option(*argv, &chap[0].timeouttime);
2042
}
2043
2044
static int
2045
setchapchal(argv)
2046
    char **argv;
2047
{
2048
    return int_option(*argv, &chap[0].max_transmits);
2049
}
2050
2051
static int
2052
setchapintv(argv)
2053
    char **argv;
2054
{
2055
    return int_option(*argv, &chap[0].chal_interval);
2056
}
2057
2058
static int
2059
noccp(argv)
2060
    char **argv;
2061
{
2062
    ccp_protent.enabled_flag = 0;
2063
    return 1;
2064
}
2065
2066
static int
2067
setbsdcomp(argv)
2068
    char **argv;
2069
{
2070
    int rbits, abits;
2071
    char *str, *endp;
2072
2073
    str = *argv;
2074
    abits = rbits = strtol(str, &endp, 0);
2075
    if (endp != str && *endp == ',') {
2076
	str = endp + 1;
2077
	abits = strtol(str, &endp, 0);
2078
    }
2079
    if (*endp != 0 || endp == str) {
2080
	option_error("invalid parameter '%s' for bsdcomp option", *argv);
2081
	return 0;
2082
    }
2083
    if ((rbits != 0 && (rbits < BSD_MIN_BITS || rbits > BSD_MAX_BITS))
2084
	|| (abits != 0 && (abits < BSD_MIN_BITS || abits > BSD_MAX_BITS))) {
2085
	option_error("bsdcomp option values must be 0 or %d .. %d",
2086
		     BSD_MIN_BITS, BSD_MAX_BITS);
2087
	return 0;
2088
    }
2089
    if (rbits > 0) {
2090
	ccp_wantoptions[0].bsd_compress = 1;
2091
	ccp_wantoptions[0].bsd_bits = rbits;
2092
    } else
2093
	ccp_wantoptions[0].bsd_compress = 0;
2094
    if (abits > 0) {
2095
	ccp_allowoptions[0].bsd_compress = 1;
2096
	ccp_allowoptions[0].bsd_bits = abits;
2097
    } else
2098
	ccp_allowoptions[0].bsd_compress = 0;
2099
    return 1;
2100
}
2101
2102
static int
2103
setnobsdcomp(argv)
2104
    char **argv;
2105
{
2106
    ccp_wantoptions[0].bsd_compress = 0;
2107
    ccp_allowoptions[0].bsd_compress = 0;
2108
    return 1;
2109
}
2110
2111
static int
2112
setdeflate(argv)
2113
    char **argv;
2114
{
2115
    int rbits, abits;
2116
    char *str, *endp;
2117
2118
    str = *argv;
2119
    abits = rbits = strtol(str, &endp, 0);
2120
    if (endp != str && *endp == ',') {
2121
	str = endp + 1;
2122
	abits = strtol(str, &endp, 0);
2123
    }
2124
    if (*endp != 0 || endp == str) {
2125
	option_error("invalid parameter '%s' for deflate option", *argv);
2126
	return 0;
2127
    }
2128
    if ((rbits != 0 && (rbits < DEFLATE_MIN_SIZE || rbits > DEFLATE_MAX_SIZE))
2129
	|| (abits != 0 && (abits < DEFLATE_MIN_SIZE
2130
			  || abits > DEFLATE_MAX_SIZE))) {
2131
	option_error("deflate option values must be 0 or %d .. %d",
2132
		     DEFLATE_MIN_SIZE, DEFLATE_MAX_SIZE);
2133
	return 0;
2134
    }
2135
    if (rbits > 0) {
2136
	ccp_wantoptions[0].deflate = 1;
2137
	ccp_wantoptions[0].deflate_size = rbits;
2138
    } else
2139
	ccp_wantoptions[0].deflate = 0;
2140
    if (abits > 0) {
2141
	ccp_allowoptions[0].deflate = 1;
2142
	ccp_allowoptions[0].deflate_size = abits;
2143
    } else
2144
	ccp_allowoptions[0].deflate = 0;
2145
    return 1;
2146
}
2147
2148
static int
2149
setnodeflate(argv)
2150
    char **argv;
2151
{
2152
    ccp_wantoptions[0].deflate = 0;
2153
    ccp_allowoptions[0].deflate = 0;
2154
    return 1;
2155
}
2156
2157
static int
2158
setnodeflatedraft(argv)
2159
    char **argv;
2160
{
2161
    ccp_wantoptions[0].deflate_draft = 0;
2162
    ccp_allowoptions[0].deflate_draft = 0;
2163
    return 1;
2164
}
2165
2166
static int
2167
setpred1comp(argv)
2168
    char **argv;
2169
{
2170
    ccp_wantoptions[0].predictor_1 = 1;
2171
    ccp_allowoptions[0].predictor_1 = 1;
2172
    return 1;
2173
}
2174
2175
static int
2176
setnopred1comp(argv)
2177
    char **argv;
2178
{
2179
    ccp_wantoptions[0].predictor_1 = 0;
2180
    ccp_allowoptions[0].predictor_1 = 0;
2181
    return 1;
2182
}
2183
2184
static int
2185
setipparam(argv)
2186
    char **argv;
2187
{
2188
    ipparam = strdup(*argv);
2189
    if (ipparam == NULL)
2190
	novm("ipparam string");
2191
2192
    return 1;
2193
}
2194
2195
static int
2196
setpapcrypt(argv)
2197
    char **argv;
2198
{
2199
    cryptpap = 1;
2200
    return 1;
2201
}
2202
2203
static int
2204
setidle(argv)
2205
    char **argv;
2206
{
2207
    return int_option(*argv, &idle_time_limit);
2208
}
2209
2210
static int
2211
setholdoff(argv)
2212
    char **argv;
2213
{
2214
    return int_option(*argv, &holdoff);
2215
}
2216
2217
/*
2218
 * setdnsaddr - set the dns address(es)
2219
 */
2220
static int
2221
setdnsaddr(argv)
2222
    char **argv;
2223
{
2224
    struct in_addr ina;
2225
    struct hostent *hp;
2226
2227
    if (inet_aton(*argv, &ina) == 0) {
2228
	if ((hp = gethostbyname(*argv)) == NULL) {
2229
	    option_error("invalid address parameter '%s' for ms-dns option",
2230
			 *argv);
2231
	    return (0);
2232
	}
2233
	ina.s_addr = *(u_int32_t *)hp->h_addr;
2234
    }
2235
2236
    /* if there is no primary then update it. */
2237
    if (ipcp_allowoptions[0].dnsaddr[0] == 0)
2238
	ipcp_allowoptions[0].dnsaddr[0] = ina.s_addr;
2239
2240
    /* always set the secondary address value to the same value. */
2241
    ipcp_allowoptions[0].dnsaddr[1] = ina.s_addr;
2242
2243
    return (1);
2244
}
2245
2246
/*
2247
 * setwinsaddr - set the wins address(es)
2248
 * This is primrarly used with the Samba package under UNIX or for pointing
2249
 * the caller to the existing WINS server on a Windows NT platform.
2250
 */
2251
static int
2252
setwinsaddr(argv)
2253
    char **argv;
2254
{
2255
    struct in_addr ina;
2256
    struct hostent *hp;
2257
2258
    if (inet_aton(*argv, &ina) == 0) {
2259
	if ((hp = gethostbyname(*argv)) == NULL) {
2260
	    option_error("invalid address parameter '%s' for ms-wins option",
2261
			 *argv);
2262
	    return (0);
2263
	}
2264
	ina.s_addr = *(u_int32_t *)hp->h_addr;
2265
    }
2266
2267
    /* if there is no primary then update it. */
2268
    if (ipcp_allowoptions[0].winsaddr[0] == 0)
2269
	ipcp_allowoptions[0].winsaddr[0] = ina.s_addr;
2270
2271
    /* always set the secondary address value to the same value. */
2272
    ipcp_allowoptions[0].winsaddr[1] = ina.s_addr;
2273
2274
    return (1);
2275
}
2276
2277
#ifdef MSLANMAN
2278
static int
2279
setmslanman(argv)
2280
    char **argv;
2281
{
2282
    ms_lanman = 1;
2283
    return (1);
2284
}
2285
#endif