save/restore cr2, cr3 from vmcb
[freebsd-src/fkvm-freebsd.git] / usr.sbin / pppd / options.c
blobfa3cf93f7122742711308f4dff53d654793ab57e
1 /*
2 * options.c - handles option processing for PPP.
4 * Copyright (c) 1989 Carnegie Mellon University.
5 * All rights reserved.
7 * Redistribution and use in source and binary forms are permitted
8 * provided that the above copyright notice and this paragraph are
9 * duplicated in all such forms and that any documentation,
10 * advertising materials, and other materials related to such
11 * distribution and use acknowledge that the software was developed
12 * by Carnegie Mellon University. The name of the
13 * University may not be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
17 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20 #ifndef lint
21 static char rcsid[] = "$FreeBSD$";
22 #endif
24 #include <ctype.h>
25 #include <stdio.h>
26 #include <errno.h>
27 #include <unistd.h>
28 #include <limits.h>
29 #include <stdlib.h>
30 #include <termios.h>
31 #include <syslog.h>
32 #include <string.h>
33 #include <netdb.h>
34 #include <paths.h>
35 #include <pwd.h>
36 #include <sys/types.h>
37 #include <sys/stat.h>
38 #include <netinet/in.h>
39 #include <arpa/inet.h>
40 #ifdef PPP_FILTER
41 #include <pcap.h>
42 #include <pcap-int.h> /* XXX: To get struct pcap */
43 #endif
45 #include "pppd.h"
46 #include "pathnames.h"
47 #include "patchlevel.h"
48 #include "fsm.h"
49 #include "lcp.h"
50 #include "ipcp.h"
51 #include "upap.h"
52 #include "chap.h"
53 #include "ccp.h"
54 #ifdef CBCP_SUPPORT
55 #include "cbcp.h"
56 #endif
58 #ifdef INET6
59 #include "ipv6cp.h"
60 #endif
62 #ifdef IPX_CHANGE
63 #include "ipxcp.h"
64 #endif /* IPX_CHANGE */
66 #include <net/ppp_comp.h>
68 #define FALSE 0
69 #define TRUE 1
71 #if defined(ultrix) || defined(NeXT)
72 char *strdup(char *);
73 #endif
75 #ifndef GIDSET_TYPE
76 #define GIDSET_TYPE gid_t
77 #endif
80 * Option variables and default values.
82 #ifdef PPP_FILTER
83 int dflag = 0; /* Tell libpcap we want debugging */
84 #endif
85 int debug = 0; /* Debug flag */
86 int kdebugflag = 0; /* Tell kernel to print debug messages */
87 int default_device = 1; /* Using /dev/tty or equivalent */
88 char devnam[MAXPATHLEN] = _PATH_TTY; /* Device name */
89 int crtscts = 0; /* Use hardware flow control */
90 int modem = 1; /* Use modem control lines */
91 int inspeed = 0; /* Input/Output speed requested */
92 u_int32_t netmask = 0; /* IP netmask to set on interface */
93 int lockflag = 0; /* Create lock file to lock the serial dev */
94 int nodetach = 0; /* Don't detach from controlling tty */
95 char *connector = NULL; /* Script to establish physical link */
96 char *disconnector = NULL; /* Script to disestablish physical link */
97 char *welcomer = NULL; /* Script to run after phys link estab. */
98 int max_con_attempts = 0; /* Maximum connect tries in non-demand mode */
99 int maxconnect = 0; /* Maximum connect time */
100 char user[MAXNAMELEN]; /* Username for PAP */
101 char passwd[MAXSECRETLEN]; /* Password for PAP */
102 int auth_required = 0; /* Peer is required to authenticate */
103 int defaultroute = 0; /* assign default route through interface */
104 int proxyarp = 0; /* Set up proxy ARP entry for peer */
105 int persist = 0; /* Reopen link after it goes down */
106 int uselogin = 0; /* Use /etc/passwd for checking PAP */
107 int lcp_echo_interval = 0; /* Interval between LCP echo-requests */
108 int lcp_echo_fails = 0; /* Tolerance to unanswered echo-requests */
109 char our_name[MAXNAMELEN]; /* Our name for authentication purposes */
110 char remote_name[MAXNAMELEN]; /* Peer's name for authentication */
111 int explicit_remote = 0; /* User specified explicit remote name */
112 int usehostname = 0; /* Use hostname for our_name */
113 int disable_defaultip = 0; /* Don't use hostname for default IP adrs */
114 int demand = 0; /* do dial-on-demand */
115 char *ipparam = NULL; /* Extra parameter for ip up/down scripts */
116 int cryptpap; /* Passwords in pap-secrets are encrypted */
117 int idle_time_limit = 0; /* Disconnect if idle for this many seconds */
118 int holdoff = 30; /* # seconds to pause before reconnecting */
119 int refuse_pap = 0; /* Set to say we won't do PAP */
120 int refuse_chap = 0; /* Set to say we won't do CHAP */
122 #ifdef MSLANMAN
123 int ms_lanman = 0; /* Nonzero if use LanMan password instead of NT */
124 /* Has meaning only with MS-CHAP challenges */
125 #endif
127 struct option_info auth_req_info;
128 struct option_info connector_info;
129 struct option_info disconnector_info;
130 struct option_info welcomer_info;
131 struct option_info devnam_info;
132 #ifdef PPP_FILTER
133 struct bpf_program pass_filter;/* Filter program for packets to pass */
134 struct bpf_program active_filter; /* Filter program for link-active pkts */
135 pcap_t pc; /* Fake struct pcap so we can compile expr */
136 #endif
139 * Prototypes
141 static int setdevname(char *, int);
142 static int setspeed(char *);
143 static int setdebug(char **);
144 static int setkdebug(char **);
145 static int setpassive(char **);
146 static int setsilent(char **);
147 static int noopt(char **);
148 static int setnovj(char **);
149 static int setnovjccomp(char **);
150 static int setvjslots(char **);
151 static int reqpap(char **);
152 static int nopap(char **);
153 #ifdef OLD_OPTIONS
154 static int setupapfile(char **);
155 #endif
156 static int nochap(char **);
157 static int reqchap(char **);
158 static int noaccomp(char **);
159 static int noasyncmap(char **);
160 static int noip(char **);
161 static int nomagicnumber(char **);
162 static int setasyncmap(char **);
163 static int setescape(char **);
164 static int setmru(char **);
165 static int setmtu(char **);
166 #ifdef CBCP_SUPPORT
167 static int setcbcp(char **);
168 #endif
169 static int nomru(char **);
170 static int nopcomp(char **);
171 static int setconnector(char **);
172 static int setdisconnector(char **);
173 static int setwelcomer(char **);
174 static int setmaxcon(char **);
175 static int setmaxconnect(char **);
176 static int setdomain(char **);
177 static int setnetmask(char **);
178 static int setcrtscts(char **);
179 static int setnocrtscts(char **);
180 static int setxonxoff(char **);
181 static int setnodetach(char **);
182 static int setupdetach(char **);
183 static int setmodem(char **);
184 static int setlocal(char **);
185 static int setlock(char **);
186 static int setname(char **);
187 static int setuser(char **);
188 static int setremote(char **);
189 static int setauth(char **);
190 static int setnoauth(char **);
191 static int readfile(char **);
192 static int callfile(char **);
193 static int setdefaultroute(char **);
194 static int setnodefaultroute(char **);
195 static int setproxyarp(char **);
196 static int setnoproxyarp(char **);
197 static int setpersist(char **);
198 static int setnopersist(char **);
199 static int setdologin(char **);
200 static int setusehostname(char **);
201 static int setnoipdflt(char **);
202 static int setlcptimeout(char **);
203 static int setlcpterm(char **);
204 static int setlcpconf(char **);
205 static int setlcpfails(char **);
206 static int setipcptimeout(char **);
207 static int setipcpterm(char **);
208 static int setipcpconf(char **);
209 static int setipcpfails(char **);
210 static int setpaptimeout(char **);
211 static int setpapreqs(char **);
212 static int setpapreqtime(char **);
213 static int setchaptimeout(char **);
214 static int setchapchal(char **);
215 static int setchapintv(char **);
216 static int setipcpaccl(char **);
217 static int setipcpaccr(char **);
218 static int setlcpechointv(char **);
219 static int setlcpechofails(char **);
220 static int noccp(char **);
221 static int setbsdcomp(char **);
222 static int setnobsdcomp(char **);
223 static int setdeflate(char **);
224 static int setnodeflate(char **);
225 static int setnodeflatedraft(char **);
226 static int setdemand(char **);
227 static int setpred1comp(char **);
228 static int setnopred1comp(char **);
229 static int setipparam(char **);
230 static int setpapcrypt(char **);
231 static int setidle(char **);
232 static int setholdoff(char **);
233 static int setdnsaddr(char **);
234 static int resetipv6proto(char **);
235 static int resetipxproto(char **);
236 static int setwinsaddr(char **);
237 static int showversion(char **);
238 static int showhelp(char **);
240 #ifdef PPP_FILTER
241 static int setpdebug(char **);
242 static int setpassfilter(char **);
243 static int setactivefilter(char **);
244 #endif
246 #ifdef INET6
247 static int setipv6cp_accept_local(char **);
248 static int setipv6cp_use_ip(char **);
249 #if defined(SOL2)
250 static int setipv6cp_use_persistent(char **);
251 #endif
252 static int setipv6cptimeout(char **);
253 static int setipv6cpterm(char **);
254 static int setipv6cpconf(char **);
255 static int setipv6cpfails(char **);
256 static int setipv6proto(char **);
257 #endif /* INET6 */
259 #ifdef IPX_CHANGE
260 static int setipxproto(char **);
261 static int setipxanet(char **);
262 static int setipxalcl(char **);
263 static int setipxarmt(char **);
264 static int setipxnetwork(char **);
265 static int setipxnode(char **);
266 static int setipxrouter(char **);
267 static int setipxname(char **);
268 static int setipxcptimeout(char **);
269 static int setipxcpterm(char **);
270 static int setipxcpconf(char **);
271 static int setipxcpfails(char **);
272 #endif /* IPX_CHANGE */
274 #ifdef MSLANMAN
275 static int setmslanman(char **);
276 #endif
278 static int number_option(char *, u_int32_t *, int);
279 static int int_option(char *, int *);
280 static int readable(int fd);
283 * Valid arguments.
285 static struct cmd {
286 char *cmd_name;
287 int num_args;
288 int (*cmd_func)(char **);
289 } cmds[] = {
290 {"-all", 0, noopt}, /* Don't request/allow any options (useless) */
291 {"noaccomp", 0, noaccomp}, /* Disable Address/Control compression */
292 {"-ac", 0, noaccomp}, /* Disable Address/Control compress */
293 {"default-asyncmap", 0, noasyncmap}, /* Disable asyncmap negoatiation */
294 {"-am", 0, noasyncmap}, /* Disable asyncmap negotiation */
295 {"-as", 1, setasyncmap}, /* set the desired async map */
296 {"-d", 0, setdebug}, /* Increase debugging level */
297 {"nodetach", 0, setnodetach}, /* Don't detach from controlling tty */
298 {"-detach", 0, setnodetach}, /* don't fork */
299 {"updetach", 0, setupdetach}, /* Detach once an NP has come up */
300 {"noip", 0, noip}, /* Disable IP and IPCP */
301 {"-ip", 0, noip}, /* Disable IP and IPCP */
302 {"nomagic", 0, nomagicnumber}, /* Disable magic number negotiation */
303 {"-mn", 0, nomagicnumber}, /* Disable magic number negotiation */
304 {"default-mru", 0, nomru}, /* Disable MRU negotiation */
305 {"-mru", 0, nomru}, /* Disable mru negotiation */
306 {"-p", 0, setpassive}, /* Set passive mode */
307 {"nopcomp", 0, nopcomp}, /* Disable protocol field compression */
308 {"-pc", 0, nopcomp}, /* Disable protocol field compress */
309 #if OLD_OPTIONS
310 {"+ua", 1, setupapfile}, /* Get PAP user and password from file */
311 #endif
312 {"require-pap", 0, reqpap}, /* Require PAP authentication from peer */
313 {"+pap", 0, reqpap}, /* Require PAP auth from peer */
314 {"refuse-pap", 0, nopap}, /* Don't agree to auth to peer with PAP */
315 {"-pap", 0, nopap}, /* Don't allow UPAP authentication with peer */
316 {"require-chap", 0, reqchap}, /* Require CHAP authentication from peer */
317 {"+chap", 0, reqchap}, /* Require CHAP authentication from peer */
318 {"refuse-chap", 0, nochap}, /* Don't agree to auth to peer with CHAP */
319 {"-chap", 0, nochap}, /* Don't allow CHAP authentication with peer */
320 {"novj", 0, setnovj}, /* Disable VJ compression */
321 {"-vj", 0, setnovj}, /* disable VJ compression */
322 {"novjccomp", 0, setnovjccomp}, /* disable VJ connection-ID compression */
323 {"-vjccomp", 0, setnovjccomp}, /* disable VJ connection-ID compression */
324 {"vj-max-slots", 1, setvjslots}, /* Set maximum VJ header slots */
325 {"asyncmap", 1, setasyncmap}, /* set the desired async map */
326 {"escape", 1, setescape}, /* set chars to escape on transmission */
327 {"connect", 1, setconnector}, /* A program to set up a connection */
328 {"disconnect", 1, setdisconnector}, /* program to disconnect serial dev. */
329 {"welcome", 1, setwelcomer},/* Script to welcome client */
330 {"connect-max-attempts", 1, setmaxcon}, /* maximum # connect attempts */
331 {"maxconnect", 1, setmaxconnect}, /* specify a maximum connect time */
332 {"crtscts", 0, setcrtscts}, /* set h/w flow control */
333 {"nocrtscts", 0, setnocrtscts}, /* clear h/w flow control */
334 {"-crtscts", 0, setnocrtscts}, /* clear h/w flow control */
335 {"xonxoff", 0, setxonxoff}, /* set s/w flow control */
336 {"debug", 0, setdebug}, /* Increase debugging level */
337 {"kdebug", 1, setkdebug}, /* Enable kernel-level debugging */
338 {"domain", 1, setdomain}, /* Add given domain name to hostname*/
339 {"mru", 1, setmru}, /* Set MRU value for negotiation */
340 {"mtu", 1, setmtu}, /* Set our MTU */
341 #ifdef CBCP_SUPPORT
342 {"callback", 1, setcbcp}, /* Ask for callback */
343 #endif
344 {"netmask", 1, setnetmask}, /* set netmask */
345 {"passive", 0, setpassive}, /* Set passive mode */
346 {"silent", 0, setsilent}, /* Set silent mode */
347 {"modem", 0, setmodem}, /* Use modem control lines */
348 {"local", 0, setlocal}, /* Don't use modem control lines */
349 {"lock", 0, setlock}, /* Lock serial device (with lock file) */
350 {"name", 1, setname}, /* Set local name for authentication */
351 {"user", 1, setuser}, /* Set name for auth with peer */
352 {"usehostname", 0, setusehostname}, /* Must use hostname for auth. */
353 {"remotename", 1, setremote}, /* Set remote name for authentication */
354 {"auth", 0, setauth}, /* Require authentication from peer */
355 {"noauth", 0, setnoauth}, /* Don't require peer to authenticate */
356 {"file", 1, readfile}, /* Take options from a file */
357 {"call", 1, callfile}, /* Take options from a privileged file */
358 {"defaultroute", 0, setdefaultroute}, /* Add default route */
359 {"nodefaultroute", 0, setnodefaultroute}, /* disable defaultroute option */
360 {"-defaultroute", 0, setnodefaultroute}, /* disable defaultroute option */
361 {"proxyarp", 0, setproxyarp}, /* Add proxy ARP entry */
362 {"noproxyarp", 0, setnoproxyarp}, /* disable proxyarp option */
363 {"-proxyarp", 0, setnoproxyarp}, /* disable proxyarp option */
364 {"persist", 0, setpersist}, /* Keep on reopening connection after close */
365 {"nopersist", 0, setnopersist}, /* Turn off persist option */
366 {"demand", 0, setdemand}, /* Dial on demand */
367 {"login", 0, setdologin}, /* Use system password database for UPAP */
368 {"noipdefault", 0, setnoipdflt}, /* Don't use name for default IP adrs */
369 {"lcp-echo-failure", 1, setlcpechofails}, /* consecutive echo failures */
370 {"lcp-echo-interval", 1, setlcpechointv}, /* time for lcp echo events */
371 {"lcp-restart", 1, setlcptimeout}, /* Set timeout for LCP */
372 {"lcp-max-terminate", 1, setlcpterm}, /* Set max #xmits for term-reqs */
373 {"lcp-max-configure", 1, setlcpconf}, /* Set max #xmits for conf-reqs */
374 {"lcp-max-failure", 1, setlcpfails}, /* Set max #conf-naks for LCP */
375 {"ipcp-restart", 1, setipcptimeout}, /* Set timeout for IPCP */
376 {"ipcp-max-terminate", 1, setipcpterm}, /* Set max #xmits for term-reqs */
377 {"ipcp-max-configure", 1, setipcpconf}, /* Set max #xmits for conf-reqs */
378 {"ipcp-max-failure", 1, setipcpfails}, /* Set max #conf-naks for IPCP */
379 {"pap-restart", 1, setpaptimeout}, /* Set retransmit timeout for PAP */
380 {"pap-max-authreq", 1, setpapreqs}, /* Set max #xmits for auth-reqs */
381 {"pap-timeout", 1, setpapreqtime}, /* Set time limit for peer PAP auth. */
382 {"chap-restart", 1, setchaptimeout}, /* Set timeout for CHAP */
383 {"chap-max-challenge", 1, setchapchal}, /* Set max #xmits for challenge */
384 {"chap-interval", 1, setchapintv}, /* Set interval for rechallenge */
385 {"ipcp-accept-local", 0, setipcpaccl}, /* Accept peer's address for us */
386 {"ipcp-accept-remote", 0, setipcpaccr}, /* Accept peer's address for it */
387 {"noccp", 0, noccp}, /* Disable CCP negotiation */
388 {"-ccp", 0, noccp}, /* Disable CCP negotiation */
389 {"bsdcomp", 1, setbsdcomp}, /* request BSD-Compress */
390 {"nobsdcomp", 0, setnobsdcomp}, /* don't allow BSD-Compress */
391 {"-bsdcomp", 0, setnobsdcomp}, /* don't allow BSD-Compress */
392 {"deflate", 1, setdeflate}, /* request Deflate compression */
393 {"nodeflate", 0, setnodeflate}, /* don't allow Deflate compression */
394 {"-deflate", 0, setnodeflate}, /* don't allow Deflate compression */
395 {"nodeflatedraft", 0, setnodeflatedraft}, /* don't use draft deflate # */
396 {"predictor1", 0, setpred1comp}, /* request Predictor-1 */
397 {"nopredictor1", 0, setnopred1comp},/* don't allow Predictor-1 */
398 {"-predictor1", 0, setnopred1comp}, /* don't allow Predictor-1 */
399 {"ipparam", 1, setipparam}, /* set ip script parameter */
400 {"papcrypt", 0, setpapcrypt}, /* PAP passwords encrypted */
401 {"idle", 1, setidle}, /* idle time limit (seconds) */
402 {"holdoff", 1, setholdoff}, /* set holdoff time (seconds) */
403 /* backwards compat hack */
404 {"dns1", 1, setdnsaddr}, /* DNS address for the peer's use */
405 {"dns2", 1, setdnsaddr}, /* DNS address for the peer's use */
406 /* end compat hack */
407 {"ms-dns", 1, setdnsaddr}, /* DNS address for the peer's use */
408 {"ms-wins", 1, setwinsaddr}, /* Nameserver for SMB over TCP/IP for peer */
409 {"noipv6", 0, resetipv6proto}, /* Disable IPv6 and IPv6CP */
410 {"-ipv6", 0, resetipv6proto}, /* Disable IPv6 and IPv6CP */
411 {"noipx", 0, resetipxproto}, /* Disable IPXCP (and IPX) */
412 {"-ipx", 0, resetipxproto}, /* Disable IPXCP (and IPX) */
413 {"--version", 0, showversion}, /* Show version number */
414 {"--help", 0, showhelp}, /* Show brief listing of options */
415 {"-h", 0, showhelp}, /* ditto */
417 #ifdef PPP_FILTER
418 {"pdebug", 1, setpdebug}, /* libpcap debugging */
419 {"pass-filter", 1, setpassfilter}, /* set filter for packets to pass */
420 {"active-filter", 1, setactivefilter}, /* set filter for active pkts */
421 #endif
423 #ifdef INET6
424 {"ipv6", 1, setifaceid}, /* Set interface id for IPV6" */
425 {"+ipv6", 0, setipv6proto}, /* Enable IPv6 and IPv6CP */
426 {"ipv6cp-accept-local", 0, setipv6cp_accept_local}, /* Accept peer's iface id for us */
427 {"ipv6cp-use-ipaddr", 0, setipv6cp_use_ip}, /* Use IPv4 addr as iface id */
428 #if defined(SOL2)
429 {"ipv6cp-use-persistent", 0, setipv6cp_use_persistent}, /* Use uniquely-available persistent value for link local addr */
430 #endif
431 {"ipv6cp-restart", 1, setipv6cptimeout}, /* Set timeout for IPv6CP */
432 {"ipv6cp-max-terminate", 1, setipv6cpterm}, /* max #xmits for term-reqs */
433 {"ipv6cp-max-configure", 1, setipv6cpconf}, /* max #xmits for conf-reqs */
434 {"ipv6cp-max-failure", 1, setipv6cpfails}, /* max #conf-naks for IPv6CP */
435 #endif
437 #ifdef IPX_CHANGE
438 {"ipx-network", 1, setipxnetwork}, /* IPX network number */
439 {"ipxcp-accept-network", 0, setipxanet}, /* Accept peer netowrk */
440 {"ipx-node", 1, setipxnode}, /* IPX node number */
441 {"ipxcp-accept-local", 0, setipxalcl}, /* Accept our address */
442 {"ipxcp-accept-remote", 0, setipxarmt}, /* Accept peer's address */
443 {"ipx-routing", 1, setipxrouter}, /* IPX routing proto number */
444 {"ipx-router-name", 1, setipxname}, /* IPX router name */
445 {"ipxcp-restart", 1, setipxcptimeout}, /* Set timeout for IPXCP */
446 {"ipxcp-max-terminate", 1, setipxcpterm}, /* max #xmits for term-reqs */
447 {"ipxcp-max-configure", 1, setipxcpconf}, /* max #xmits for conf-reqs */
448 {"ipxcp-max-failure", 1, setipxcpfails}, /* max #conf-naks for IPXCP */
449 #if 0
450 {"ipx-compression", 1, setipxcompression}, /* IPX compression number */
451 #endif
452 {"ipx", 0, setipxproto}, /* Enable IPXCP (and IPX) */
453 {"+ipx", 0, setipxproto}, /* Enable IPXCP (and IPX) */
454 #endif /* IPX_CHANGE */
456 #ifdef MSLANMAN
457 {"ms-lanman", 0, setmslanman}, /* Use LanMan psswd when using MS-CHAP */
458 #endif
460 {NULL, 0, NULL}
464 #ifndef IMPLEMENTATION
465 #define IMPLEMENTATION ""
466 #endif
468 static const char usage_string[] = "\
469 pppd version %s patch level %d%s\n\
470 Usage: %s [ options ], where options are:\n\
471 <device> Communicate over the named device\n\
472 <speed> Set the baud rate to <speed>\n\
473 <loc>:<rem> Set the local and/or remote interface IP\n\
474 addresses. Either one may be omitted.\n\
475 asyncmap <n> Set the desired async map to hex <n>\n\
476 auth Require authentication from peer\n\
477 connect <p> Invoke shell command <p> to set up the serial line\n\
478 crtscts Use hardware RTS/CTS flow control\n\
479 defaultroute Add default route through interface\n\
480 file <f> Take options from file <f>\n\
481 modem Use modem control lines\n\
482 mru <n> Set MRU value to <n> for negotiation\n\
483 See pppd(8) for more options.\n\
486 static char *current_option; /* the name of the option being parsed */
487 static int privileged_option; /* set iff the current option came from root */
488 static char *option_source; /* string saying where the option came from */
491 * parse_args - parse a string of arguments from the command line.
494 parse_args(argc, argv)
495 int argc;
496 char **argv;
498 char *arg;
499 struct cmd *cmdp;
500 int ret;
502 privileged_option = privileged;
503 option_source = "command line";
504 while (argc > 0) {
505 arg = *argv++;
506 --argc;
509 * First see if it's a command.
511 for (cmdp = cmds; cmdp->cmd_name; cmdp++)
512 if (!strcmp(arg, cmdp->cmd_name))
513 break;
515 if (cmdp->cmd_name != NULL) {
516 if (argc < cmdp->num_args) {
517 option_error("too few parameters for option %s", arg);
518 return 0;
520 current_option = arg;
521 if (!(*cmdp->cmd_func)(argv))
522 return 0;
523 argc -= cmdp->num_args;
524 argv += cmdp->num_args;
526 } else {
528 * Maybe a tty name, speed or IP address?
530 if ((ret = setdevname(arg, 0)) == 0
531 && (ret = setspeed(arg)) == 0
532 && (ret = setipaddr(arg)) == 0) {
533 option_error("unrecognized option '%s'", arg);
534 usage();
535 return 0;
537 if (ret < 0) /* error */
538 return 0;
541 return 1;
545 * scan_args - scan the command line arguments to get the tty name,
546 * if specified.
548 void
549 scan_args(argc, argv)
550 int argc;
551 char **argv;
553 char *arg;
554 struct cmd *cmdp;
556 while (argc > 0) {
557 arg = *argv++;
558 --argc;
560 /* Skip options and their arguments */
561 for (cmdp = cmds; cmdp->cmd_name; cmdp++)
562 if (!strcmp(arg, cmdp->cmd_name))
563 break;
565 if (cmdp->cmd_name != NULL) {
566 argc -= cmdp->num_args;
567 argv += cmdp->num_args;
568 continue;
571 /* Check if it's a tty name and copy it if so */
572 (void) setdevname(arg, 1);
577 * usage - print out a message telling how to use the program.
579 void
580 usage()
582 if (phase == PHASE_INITIALIZE)
583 fprintf(stderr, usage_string, VERSION, PATCHLEVEL, IMPLEMENTATION,
584 progname);
588 * showhelp - print out usage message and exit.
590 static int
591 showhelp(argv)
592 char **argv;
594 if (phase == PHASE_INITIALIZE) {
595 usage();
596 exit(0);
598 return 0;
602 * showversion - print out the version number and exit.
604 static int
605 showversion(argv)
606 char **argv;
608 if (phase == PHASE_INITIALIZE) {
609 fprintf(stderr, "pppd version %s patch level %d%s\n",
610 VERSION, PATCHLEVEL, IMPLEMENTATION);
611 exit(0);
613 return 0;
617 * options_from_file - Read a string of options from a file,
618 * and interpret them.
621 options_from_file(filename, must_exist, check_prot, priv)
622 char *filename;
623 int must_exist;
624 int check_prot;
625 int priv;
627 FILE *f;
628 int i, newline, ret;
629 struct cmd *cmdp;
630 int oldpriv;
631 char *argv[MAXARGS];
632 char args[MAXARGS][MAXWORDLEN];
633 char cmd[MAXWORDLEN];
635 if ((f = fopen(filename, "r")) == NULL) {
636 if (!must_exist && errno == ENOENT)
637 return 1;
638 option_error("Can't open options file %s: %m", filename);
639 return 0;
641 if (check_prot && !readable(fileno(f))) {
642 option_error("Can't open options file %s: access denied", filename);
643 fclose(f);
644 return 0;
647 oldpriv = privileged_option;
648 privileged_option = priv;
649 ret = 0;
650 while (getword(f, cmd, &newline, filename)) {
652 * First see if it's a command.
654 for (cmdp = cmds; cmdp->cmd_name; cmdp++)
655 if (!strcmp(cmd, cmdp->cmd_name))
656 break;
658 if (cmdp->cmd_name != NULL) {
659 for (i = 0; i < cmdp->num_args; ++i) {
660 if (!getword(f, args[i], &newline, filename)) {
661 option_error(
662 "In file %s: too few parameters for option '%s'",
663 filename, cmd);
664 goto err;
666 argv[i] = args[i];
668 current_option = cmd;
669 if (!(*cmdp->cmd_func)(argv))
670 goto err;
672 } else {
674 * Maybe a tty name, speed or IP address?
676 if ((i = setdevname(cmd, 0)) == 0
677 && (i = setspeed(cmd)) == 0
678 && (i = setipaddr(cmd)) == 0) {
679 option_error("In file %s: unrecognized option '%s'",
680 filename, cmd);
681 goto err;
683 if (i < 0) /* error */
684 goto err;
687 ret = 1;
689 err:
690 fclose(f);
691 privileged_option = oldpriv;
692 return ret;
696 * options_from_user - See if the use has a ~/.ppprc file,
697 * and if so, interpret options from it.
700 options_from_user()
702 char *user, *path, *file;
703 int ret;
704 struct passwd *pw;
706 pw = getpwuid(getuid());
707 if (pw == NULL || (user = pw->pw_dir) == NULL || user[0] == 0)
708 return 1;
709 file = _PATH_USEROPT;
710 path = malloc(strlen(user) + strlen(file) + 2);
711 if (path == NULL)
712 novm("init file name");
713 strcpy(path, user);
714 strcat(path, "/");
715 strcat(path, file);
716 ret = options_from_file(path, 0, 1, privileged);
717 free(path);
718 return ret;
722 * options_for_tty - See if an options file exists for the serial
723 * device, and if so, interpret options from it.
726 options_for_tty()
728 char *dev, *path, *p;
729 int ret;
731 dev = devnam;
732 if (strncmp(dev, _PATH_DEV, sizeof _PATH_DEV - 1) == 0)
733 dev += 5;
734 if (strcmp(dev, "tty") == 0)
735 return 1; /* don't look for /etc/ppp/options.tty */
736 path = malloc(strlen(_PATH_TTYOPT) + strlen(dev) + 1);
737 if (path == NULL)
738 novm("tty init file name");
739 strcpy(path, _PATH_TTYOPT);
740 /* Turn slashes into dots, for Solaris case (e.g. /dev/term/a) */
741 for (p = path + strlen(path); *dev != 0; ++dev)
742 *p++ = (*dev == '/'? '.': *dev);
743 *p = 0;
744 ret = options_from_file(path, 0, 0, 1);
745 free(path);
746 return ret;
750 * option_error - print a message about an error in an option.
751 * The message is logged, and also sent to
752 * stderr if phase == PHASE_INITIALIZE.
754 void
755 option_error __V((char *fmt, ...))
757 va_list args;
758 char buf[256];
760 #if __STDC__
761 va_start(args, fmt);
762 #else
763 char *fmt;
764 va_start(args);
765 fmt = va_arg(args, char *);
766 #endif
767 vfmtmsg(buf, sizeof(buf), fmt, args);
768 va_end(args);
769 if (phase == PHASE_INITIALIZE)
770 fprintf(stderr, "%s: %s\n", progname, buf);
771 syslog(LOG_ERR, "%s", buf);
775 * readable - check if a file is readable by the real user.
777 static int
778 readable(fd)
779 int fd;
781 uid_t uid;
782 int ngroups, i;
783 struct stat sbuf;
784 GIDSET_TYPE groups[NGROUPS_MAX];
786 uid = getuid();
787 if (uid == 0)
788 return 1;
789 if (fstat(fd, &sbuf) != 0)
790 return 0;
791 if (sbuf.st_uid == uid)
792 return sbuf.st_mode & S_IRUSR;
793 if (sbuf.st_gid == getgid())
794 return sbuf.st_mode & S_IRGRP;
795 ngroups = getgroups(NGROUPS_MAX, groups);
796 for (i = 0; i < ngroups; ++i)
797 if (sbuf.st_gid == groups[i])
798 return sbuf.st_mode & S_IRGRP;
799 return sbuf.st_mode & S_IROTH;
803 * Read a word from a file.
804 * Words are delimited by white-space or by quotes (" or ').
805 * Quotes, white-space and \ may be escaped with \.
806 * \<newline> is ignored.
809 getword(f, word, newlinep, filename)
810 FILE *f;
811 char *word;
812 int *newlinep;
813 char *filename;
815 int c, len, escape;
816 int quoted, comment;
817 int value, digit, got, n;
819 #define isoctal(c) ((c) >= '0' && (c) < '8')
821 *newlinep = 0;
822 len = 0;
823 escape = 0;
824 comment = 0;
827 * First skip white-space and comments.
829 for (;;) {
830 c = getc(f);
831 if (c == EOF)
832 break;
835 * A newline means the end of a comment; backslash-newline
836 * is ignored. Note that we cannot have escape && comment.
838 if (c == '\n') {
839 if (!escape) {
840 *newlinep = 1;
841 comment = 0;
842 } else
843 escape = 0;
844 continue;
848 * Ignore characters other than newline in a comment.
850 if (comment)
851 continue;
854 * If this character is escaped, we have a word start.
856 if (escape)
857 break;
860 * If this is the escape character, look at the next character.
862 if (c == '\\') {
863 escape = 1;
864 continue;
868 * If this is the start of a comment, ignore the rest of the line.
870 if (c == '#') {
871 comment = 1;
872 continue;
876 * A non-whitespace character is the start of a word.
878 if (!isspace(c))
879 break;
883 * Save the delimiter for quoted strings.
885 if (!escape && (c == '"' || c == '\'')) {
886 quoted = c;
887 c = getc(f);
888 } else
889 quoted = 0;
892 * Process characters until the end of the word.
894 while (c != EOF) {
895 if (escape) {
897 * This character is escaped: backslash-newline is ignored,
898 * various other characters indicate particular values
899 * as for C backslash-escapes.
901 escape = 0;
902 if (c == '\n') {
903 c = getc(f);
904 continue;
907 got = 0;
908 switch (c) {
909 case 'a':
910 value = '\a';
911 break;
912 case 'b':
913 value = '\b';
914 break;
915 case 'f':
916 value = '\f';
917 break;
918 case 'n':
919 value = '\n';
920 break;
921 case 'r':
922 value = '\r';
923 break;
924 case 's':
925 value = ' ';
926 break;
927 case 't':
928 value = '\t';
929 break;
931 default:
932 if (isoctal(c)) {
934 * \ddd octal sequence
936 value = 0;
937 for (n = 0; n < 3 && isoctal(c); ++n) {
938 value = (value << 3) + (c & 07);
939 c = getc(f);
941 got = 1;
942 break;
945 if (c == 'x') {
947 * \x<hex_string> sequence
949 value = 0;
950 c = getc(f);
951 for (n = 0; n < 2 && isxdigit(c); ++n) {
952 digit = toupper(c) - '0';
953 if (digit > 10)
954 digit += '0' + 10 - 'A';
955 value = (value << 4) + digit;
956 c = getc (f);
958 got = 1;
959 break;
963 * Otherwise the character stands for itself.
965 value = c;
966 break;
970 * Store the resulting character for the escape sequence.
972 if (len < MAXWORDLEN-1)
973 word[len] = value;
974 ++len;
976 if (!got)
977 c = getc(f);
978 continue;
983 * Not escaped: see if we've reached the end of the word.
985 if (quoted) {
986 if (c == quoted)
987 break;
988 } else {
989 if (isspace(c) || c == '#') {
990 ungetc (c, f);
991 break;
996 * Backslash starts an escape sequence.
998 if (c == '\\') {
999 escape = 1;
1000 c = getc(f);
1001 continue;
1005 * An ordinary character: store it in the word and get another.
1007 if (len < MAXWORDLEN-1)
1008 word[len] = c;
1009 ++len;
1011 c = getc(f);
1015 * End of the word: check for errors.
1017 if (c == EOF) {
1018 if (ferror(f)) {
1019 if (errno == 0)
1020 errno = EIO;
1021 option_error("Error reading %s: %m", filename);
1022 die(1);
1025 * If len is zero, then we didn't find a word before the
1026 * end of the file.
1028 if (len == 0)
1029 return 0;
1033 * Warn if the word was too long, and append a terminating null.
1035 if (len >= MAXWORDLEN) {
1036 option_error("warning: word in file %s too long (%.20s...)",
1037 filename, word);
1038 len = MAXWORDLEN - 1;
1040 word[len] = 0;
1042 return 1;
1044 #undef isoctal
1049 * number_option - parse an unsigned numeric parameter for an option.
1051 static int
1052 number_option(str, valp, base)
1053 char *str;
1054 u_int32_t *valp;
1055 int base;
1057 char *ptr;
1059 *valp = strtoul(str, &ptr, base);
1060 if (ptr == str) {
1061 option_error("invalid numeric parameter '%s' for %s option",
1062 str, current_option);
1063 return 0;
1065 return 1;
1070 * int_option - like number_option, but valp is int *,
1071 * the base is assumed to be 0, and *valp is not changed
1072 * if there is an error.
1074 static int
1075 int_option(str, valp)
1076 char *str;
1077 int *valp;
1079 u_int32_t v;
1081 if (!number_option(str, &v, 0))
1082 return 0;
1083 *valp = (int) v;
1084 return 1;
1089 * The following procedures parse options.
1093 * readfile - take commands from a file.
1095 static int
1096 readfile(argv)
1097 char **argv;
1099 return options_from_file(*argv, 1, 1, privileged_option);
1103 * callfile - take commands from /etc/ppp/peers/<name>.
1104 * Name may not contain /../, start with / or ../, or end in /..
1106 static int
1107 callfile(argv)
1108 char **argv;
1110 char *fname, *arg, *p;
1111 int l, ok;
1113 arg = *argv;
1114 ok = 1;
1115 if (arg[0] == '/' || arg[0] == 0)
1116 ok = 0;
1117 else {
1118 for (p = arg; *p != 0; ) {
1119 if (p[0] == '.' && p[1] == '.' && (p[2] == '/' || p[2] == 0)) {
1120 ok = 0;
1121 break;
1123 while (*p != '/' && *p != 0)
1124 ++p;
1125 if (*p == '/')
1126 ++p;
1129 if (!ok) {
1130 option_error("call option value may not contain .. or start with /");
1131 return 0;
1134 l = strlen(arg) + strlen(_PATH_PEERFILES) + 1;
1135 if ((fname = (char *) malloc(l)) == NULL)
1136 novm("call file name");
1137 strcpy(fname, _PATH_PEERFILES);
1138 strcat(fname, arg);
1140 ok = options_from_file(fname, 1, 1, 1);
1142 free(fname);
1143 return ok;
1148 * setdebug - Set debug (command line argument).
1150 static int
1151 setdebug(argv)
1152 char **argv;
1154 debug++;
1155 return (1);
1159 * setkdebug - Set kernel debugging level.
1161 static int
1162 setkdebug(argv)
1163 char **argv;
1165 return int_option(*argv, &kdebugflag);
1168 #ifdef PPP_FILTER
1170 * setpdebug - Set libpcap debugging level.
1172 static int
1173 setpdebug(argv)
1174 char **argv;
1176 return int_option(*argv, &dflag);
1180 * setpassfilter - Set the pass filter for packets
1182 static int
1183 setpassfilter(argv)
1184 char **argv;
1186 pc.linktype = DLT_PPP;
1187 pc.snapshot = PPP_HDRLEN;
1189 if (pcap_compile(&pc, &pass_filter, *argv, 1, netmask) == 0)
1190 return 1;
1191 option_error("error in pass-filter expression: %s\n", pcap_geterr(&pc));
1192 return 0;
1196 * setactivefilter - Set the active filter for packets
1198 static int
1199 setactivefilter(argv)
1200 char **argv;
1202 pc.linktype = DLT_PPP;
1203 pc.snapshot = PPP_HDRLEN;
1205 if (pcap_compile(&pc, &active_filter, *argv, 1, netmask) == 0)
1206 return 1;
1207 option_error("error in active-filter expression: %s\n", pcap_geterr(&pc));
1208 return 0;
1210 #endif
1213 * noopt - Disable all options.
1215 static int
1216 noopt(argv)
1217 char **argv;
1219 BZERO((char *) &lcp_wantoptions[0], sizeof (struct lcp_options));
1220 BZERO((char *) &lcp_allowoptions[0], sizeof (struct lcp_options));
1221 BZERO((char *) &ipcp_wantoptions[0], sizeof (struct ipcp_options));
1222 BZERO((char *) &ipcp_allowoptions[0], sizeof (struct ipcp_options));
1224 #ifdef IPX_CHANGE
1225 BZERO((char *) &ipxcp_wantoptions[0], sizeof (struct ipxcp_options));
1226 BZERO((char *) &ipxcp_allowoptions[0], sizeof (struct ipxcp_options));
1227 #endif /* IPX_CHANGE */
1229 return (1);
1233 * noaccomp - Disable Address/Control field compression negotiation.
1235 static int
1236 noaccomp(argv)
1237 char **argv;
1239 lcp_wantoptions[0].neg_accompression = 0;
1240 lcp_allowoptions[0].neg_accompression = 0;
1241 return (1);
1246 * noasyncmap - Disable async map negotiation.
1248 static int
1249 noasyncmap(argv)
1250 char **argv;
1252 lcp_wantoptions[0].neg_asyncmap = 0;
1253 lcp_allowoptions[0].neg_asyncmap = 0;
1254 return (1);
1259 * noip - Disable IP and IPCP.
1261 static int
1262 noip(argv)
1263 char **argv;
1265 ipcp_protent.enabled_flag = 0;
1266 return (1);
1271 * nomagicnumber - Disable magic number negotiation.
1273 static int
1274 nomagicnumber(argv)
1275 char **argv;
1277 lcp_wantoptions[0].neg_magicnumber = 0;
1278 lcp_allowoptions[0].neg_magicnumber = 0;
1279 return (1);
1284 * nomru - Disable mru negotiation.
1286 static int
1287 nomru(argv)
1288 char **argv;
1290 lcp_wantoptions[0].neg_mru = 0;
1291 lcp_allowoptions[0].neg_mru = 0;
1292 return (1);
1297 * setmru - Set MRU for negotiation.
1299 static int
1300 setmru(argv)
1301 char **argv;
1303 u_int32_t mru;
1305 if (!number_option(*argv, &mru, 0))
1306 return 0;
1307 lcp_wantoptions[0].mru = mru;
1308 lcp_wantoptions[0].neg_mru = 1;
1309 return (1);
1314 * setmru - Set the largest MTU we'll use.
1316 static int
1317 setmtu(argv)
1318 char **argv;
1320 u_int32_t mtu;
1322 if (!number_option(*argv, &mtu, 0))
1323 return 0;
1324 if (mtu < MINMRU || mtu > MAXMRU) {
1325 option_error("mtu option value of %u is too %s", mtu,
1326 (mtu < MINMRU? "small": "large"));
1327 return 0;
1329 lcp_allowoptions[0].mru = mtu;
1330 return (1);
1333 #ifdef CBCP_SUPPORT
1334 static int
1335 setcbcp(argv)
1336 char **argv;
1338 lcp_wantoptions[0].neg_cbcp = 1;
1339 cbcp_protent.enabled_flag = 1;
1340 cbcp[0].us_number = strdup(*argv);
1341 if (cbcp[0].us_number == 0)
1342 novm("callback number");
1343 cbcp[0].us_type |= (1 << CB_CONF_USER);
1344 cbcp[0].us_type |= (1 << CB_CONF_ADMIN);
1345 return (1);
1347 #endif
1350 * nopcomp - Disable Protocol field compression negotiation.
1352 static int
1353 nopcomp(argv)
1354 char **argv;
1356 lcp_wantoptions[0].neg_pcompression = 0;
1357 lcp_allowoptions[0].neg_pcompression = 0;
1358 return (1);
1363 * setpassive - Set passive mode (don't give up if we time out sending
1364 * LCP configure-requests).
1366 static int
1367 setpassive(argv)
1368 char **argv;
1370 lcp_wantoptions[0].passive = 1;
1371 return (1);
1376 * setsilent - Set silent mode (don't start sending LCP configure-requests
1377 * until we get one from the peer).
1379 static int
1380 setsilent(argv)
1381 char **argv;
1383 lcp_wantoptions[0].silent = 1;
1384 return 1;
1389 * nopap - Disable PAP authentication with peer.
1391 static int
1392 nopap(argv)
1393 char **argv;
1395 refuse_pap = 1;
1396 return (1);
1401 * reqpap - Require PAP authentication from peer.
1403 static int
1404 reqpap(argv)
1405 char **argv;
1407 lcp_wantoptions[0].neg_upap = 1;
1408 setauth(NULL);
1409 return 1;
1412 #if OLD_OPTIONS
1414 * setupapfile - specifies UPAP info for authenticating with peer.
1416 static int
1417 setupapfile(argv)
1418 char **argv;
1420 FILE * ufile;
1421 int l;
1423 lcp_allowoptions[0].neg_upap = 1;
1425 /* open user info file */
1426 if ((ufile = fopen(*argv, "r")) == NULL) {
1427 option_error("unable to open user login data file %s", *argv);
1428 return 0;
1430 if (!readable(fileno(ufile))) {
1431 option_error("%s: access denied", *argv);
1432 return 0;
1434 check_access(ufile, *argv);
1436 /* get username */
1437 if (fgets(user, MAXNAMELEN - 1, ufile) == NULL
1438 || fgets(passwd, MAXSECRETLEN - 1, ufile) == NULL){
1439 option_error("unable to read user login data file %s", *argv);
1440 return 0;
1442 fclose(ufile);
1444 /* get rid of newlines */
1445 l = strlen(user);
1446 if (l > 0 && user[l-1] == '\n')
1447 user[l-1] = 0;
1448 l = strlen(passwd);
1449 if (l > 0 && passwd[l-1] == '\n')
1450 passwd[l-1] = 0;
1452 return (1);
1454 #endif
1457 * nochap - Disable CHAP authentication with peer.
1459 static int
1460 nochap(argv)
1461 char **argv;
1463 refuse_chap = 1;
1464 return (1);
1469 * reqchap - Require CHAP authentication from peer.
1471 static int
1472 reqchap(argv)
1473 char **argv;
1475 lcp_wantoptions[0].neg_chap = 1;
1476 setauth(NULL);
1477 return (1);
1482 * setnovj - disable vj compression
1484 static int
1485 setnovj(argv)
1486 char **argv;
1488 ipcp_wantoptions[0].neg_vj = 0;
1489 ipcp_allowoptions[0].neg_vj = 0;
1490 return (1);
1495 * setnovjccomp - disable VJ connection-ID compression
1497 static int
1498 setnovjccomp(argv)
1499 char **argv;
1501 ipcp_wantoptions[0].cflag = 0;
1502 ipcp_allowoptions[0].cflag = 0;
1503 return 1;
1508 * setvjslots - set maximum number of connection slots for VJ compression
1510 static int
1511 setvjslots(argv)
1512 char **argv;
1514 int value;
1516 if (!int_option(*argv, &value))
1517 return 0;
1518 if (value < 2 || value > 16) {
1519 option_error("vj-max-slots value must be between 2 and 16");
1520 return 0;
1522 ipcp_wantoptions [0].maxslotindex =
1523 ipcp_allowoptions[0].maxslotindex = value - 1;
1524 return 1;
1529 * setconnector - Set a program to connect to a serial line
1531 static int
1532 setconnector(argv)
1533 char **argv;
1535 connector = strdup(*argv);
1536 if (connector == NULL)
1537 novm("connect script");
1538 connector_info.priv = privileged_option;
1539 connector_info.source = option_source;
1541 return (1);
1545 * setdisconnector - Set a program to disconnect from the serial line
1547 static int
1548 setdisconnector(argv)
1549 char **argv;
1551 disconnector = strdup(*argv);
1552 if (disconnector == NULL)
1553 novm("disconnect script");
1554 disconnector_info.priv = privileged_option;
1555 disconnector_info.source = option_source;
1557 return (1);
1561 * setwelcomer - Set a program to welcome a client after connection
1563 static int
1564 setwelcomer(argv)
1565 char **argv;
1567 welcomer = strdup(*argv);
1568 if (welcomer == NULL)
1569 novm("welcome script");
1570 welcomer_info.priv = privileged_option;
1571 welcomer_info.source = option_source;
1573 return (1);
1576 static int
1577 setmaxcon(argv)
1578 char **argv;
1580 return int_option(*argv, &max_con_attempts);
1584 * setmaxconnect - Set the maximum connect time
1586 static int
1587 setmaxconnect(argv)
1588 char **argv;
1590 int value;
1592 if (!int_option(*argv, &value))
1593 return 0;
1594 if (value < 0) {
1595 option_error("maxconnect time must be positive");
1596 return 0;
1598 if (maxconnect > 0 && (value == 0 || value > maxconnect)) {
1599 option_error("maxconnect time cannot be increased");
1600 return 0;
1602 maxconnect = value;
1603 return 1;
1607 * setdomain - Set domain name to append to hostname
1609 static int
1610 setdomain(argv)
1611 char **argv;
1613 if (!privileged_option) {
1614 option_error("using the domain option requires root privilege");
1615 return 0;
1617 gethostname(hostname, MAXNAMELEN);
1618 if (**argv != 0) {
1619 if (**argv != '.')
1620 strncat(hostname, ".", MAXNAMELEN - strlen(hostname));
1621 strncat(hostname, *argv, MAXNAMELEN - strlen(hostname));
1623 hostname[MAXNAMELEN-1] = 0;
1624 return (1);
1629 * setasyncmap - add bits to asyncmap (what we request peer to escape).
1631 static int
1632 setasyncmap(argv)
1633 char **argv;
1635 u_int32_t asyncmap;
1637 if (!number_option(*argv, &asyncmap, 16))
1638 return 0;
1639 lcp_wantoptions[0].asyncmap |= asyncmap;
1640 lcp_wantoptions[0].neg_asyncmap = 1;
1641 return(1);
1646 * setescape - add chars to the set we escape on transmission.
1648 static int
1649 setescape(argv)
1650 char **argv;
1652 int n, ret;
1653 char *p, *endp;
1655 p = *argv;
1656 ret = 1;
1657 while (*p) {
1658 n = strtol(p, &endp, 16);
1659 if (p == endp) {
1660 option_error("escape parameter contains invalid hex number '%s'",
1662 return 0;
1664 p = endp;
1665 if (n < 0 || (0x20 <= n && n <= 0x3F) || n == 0x5E || n > 0xFF) {
1666 option_error("can't escape character 0x%x", n);
1667 ret = 0;
1668 } else
1669 xmit_accm[0][n >> 5] |= 1 << (n & 0x1F);
1670 while (*p == ',' || *p == ' ')
1671 ++p;
1673 return ret;
1678 * setspeed - Set the speed.
1680 static int
1681 setspeed(arg)
1682 char *arg;
1684 char *ptr;
1685 int spd;
1687 spd = strtol(arg, &ptr, 0);
1688 if (ptr == arg || *ptr != 0 || spd == 0)
1689 return 0;
1690 inspeed = spd;
1691 return 1;
1696 * setdevname - Set the device name.
1698 static int
1699 setdevname(cp, quiet)
1700 char *cp;
1701 int quiet;
1703 struct stat statbuf;
1704 char dev[MAXPATHLEN];
1706 if (*cp == 0)
1707 return 0;
1709 if (strncmp(_PATH_DEV, cp, sizeof _PATH_DEV - 1) != 0) {
1710 strcpy(dev, _PATH_DEV);
1711 strncat(dev, cp, MAXPATHLEN - sizeof _PATH_DEV - 1);
1712 dev[MAXPATHLEN-1] = 0;
1713 cp = dev;
1717 * Check if there is a device by this name.
1719 if (stat(cp, &statbuf) < 0) {
1720 if (errno == ENOENT || quiet)
1721 return 0;
1722 option_error("Couldn't stat %s: %m", cp);
1723 return -1;
1726 (void) strncpy(devnam, cp, MAXPATHLEN);
1727 devnam[MAXPATHLEN-1] = 0;
1728 default_device = FALSE;
1729 devnam_info.priv = privileged_option;
1730 devnam_info.source = option_source;
1732 return 1;
1737 * setipaddr - Set the IP address
1740 setipaddr(arg)
1741 char *arg;
1743 struct hostent *hp;
1744 char *colon;
1745 u_int32_t local, remote;
1746 ipcp_options *wo = &ipcp_wantoptions[0];
1749 * IP address pair separated by ":".
1751 if ((colon = strchr(arg, ':')) == NULL)
1752 return 0;
1755 * If colon first character, then no local addr.
1757 if (colon != arg) {
1758 *colon = '\0';
1759 if ((local = inet_addr(arg)) == -1) {
1760 if ((hp = gethostbyname(arg)) == NULL) {
1761 option_error("unknown host: %s", arg);
1762 return -1;
1763 } else {
1764 local = *(u_int32_t *)hp->h_addr;
1767 if (bad_ip_adrs(local)) {
1768 option_error("bad local IP address %s", ip_ntoa(local));
1769 return -1;
1771 if (local != 0)
1772 wo->ouraddr = local;
1773 *colon = ':';
1777 * If colon last character, then no remote addr.
1779 if (*++colon != '\0') {
1780 if ((remote = inet_addr(colon)) == -1) {
1781 if ((hp = gethostbyname(colon)) == NULL) {
1782 option_error("unknown host: %s", colon);
1783 return -1;
1784 } else {
1785 remote = *(u_int32_t *)hp->h_addr;
1786 if (remote_name[0] == 0) {
1787 strncpy(remote_name, colon, MAXNAMELEN);
1788 remote_name[MAXNAMELEN-1] = 0;
1792 if (bad_ip_adrs(remote)) {
1793 option_error("bad remote IP address %s", ip_ntoa(remote));
1794 return -1;
1796 if (remote != 0)
1797 wo->hisaddr = remote;
1800 return 1;
1805 * setnoipdflt - disable setipdefault()
1807 static int
1808 setnoipdflt(argv)
1809 char **argv;
1811 disable_defaultip = 1;
1812 return 1;
1817 * setipcpaccl - accept peer's idea of our address
1819 static int
1820 setipcpaccl(argv)
1821 char **argv;
1823 ipcp_wantoptions[0].accept_local = 1;
1824 return 1;
1829 * setipcpaccr - accept peer's idea of its address
1831 static int
1832 setipcpaccr(argv)
1833 char **argv;
1835 ipcp_wantoptions[0].accept_remote = 1;
1836 return 1;
1841 * setnetmask - set the netmask to be used on the interface.
1843 static int
1844 setnetmask(argv)
1845 char **argv;
1847 struct in_addr mask;
1849 if (!inet_aton(*argv, &mask) || (netmask & ~mask.s_addr)) {
1850 fprintf(stderr, "Invalid netmask %s\n", *argv);
1851 return (0);
1854 netmask = mask.s_addr;
1855 return (1);
1858 static int
1859 setcrtscts(argv)
1860 char **argv;
1862 crtscts = 1;
1863 return (1);
1866 static int
1867 setnocrtscts(argv)
1868 char **argv;
1870 crtscts = -1;
1871 return (1);
1874 static int
1875 setxonxoff(argv)
1876 char **argv;
1878 lcp_wantoptions[0].asyncmap |= 0x000A0000; /* escape ^S and ^Q */
1879 lcp_wantoptions[0].neg_asyncmap = 1;
1881 crtscts = -2;
1882 return (1);
1885 static int
1886 setnodetach(argv)
1887 char **argv;
1889 nodetach = 1;
1890 return (1);
1893 static int
1894 setupdetach(argv)
1895 char **argv;
1897 nodetach = -1;
1898 return (1);
1901 static int
1902 setdemand(argv)
1903 char **argv;
1905 demand = 1;
1906 persist = 1;
1907 return 1;
1910 static int
1911 setmodem(argv)
1912 char **argv;
1914 modem = 1;
1915 return 1;
1918 static int
1919 setlocal(argv)
1920 char **argv;
1922 modem = 0;
1923 return 1;
1926 static int
1927 setlock(argv)
1928 char **argv;
1930 lockflag = 1;
1931 return 1;
1934 static int
1935 setusehostname(argv)
1936 char **argv;
1938 usehostname = 1;
1939 return 1;
1942 static int
1943 setname(argv)
1944 char **argv;
1946 if (!privileged_option) {
1947 option_error("using the name option requires root privilege");
1948 return 0;
1950 strncpy(our_name, argv[0], MAXNAMELEN);
1951 our_name[MAXNAMELEN-1] = 0;
1952 return 1;
1955 static int
1956 setuser(argv)
1957 char **argv;
1959 strncpy(user, argv[0], MAXNAMELEN);
1960 user[MAXNAMELEN-1] = 0;
1961 return 1;
1964 static int
1965 setremote(argv)
1966 char **argv;
1968 strncpy(remote_name, argv[0], MAXNAMELEN);
1969 remote_name[MAXNAMELEN-1] = 0;
1970 return 1;
1973 static int
1974 setauth(argv)
1975 char **argv;
1977 auth_required = 1;
1978 if (privileged_option > auth_req_info.priv) {
1979 auth_req_info.priv = privileged_option;
1980 auth_req_info.source = option_source;
1982 return 1;
1985 static int
1986 setnoauth(argv)
1987 char **argv;
1989 if (auth_required && privileged_option < auth_req_info.priv) {
1990 option_error("cannot override auth option set by %s",
1991 auth_req_info.source);
1992 return 0;
1994 auth_required = 0;
1995 return 1;
1998 static int
1999 setdefaultroute(argv)
2000 char **argv;
2002 if (!ipcp_allowoptions[0].default_route) {
2003 option_error("defaultroute option is disabled");
2004 return 0;
2006 ipcp_wantoptions[0].default_route = 1;
2007 return 1;
2010 static int
2011 setnodefaultroute(argv)
2012 char **argv;
2014 ipcp_allowoptions[0].default_route = 0;
2015 ipcp_wantoptions[0].default_route = 0;
2016 return 1;
2019 static int
2020 setproxyarp(argv)
2021 char **argv;
2023 if (!ipcp_allowoptions[0].proxy_arp) {
2024 option_error("proxyarp option is disabled");
2025 return 0;
2027 ipcp_wantoptions[0].proxy_arp = 1;
2028 return 1;
2031 static int
2032 setnoproxyarp(argv)
2033 char **argv;
2035 ipcp_wantoptions[0].proxy_arp = 0;
2036 ipcp_allowoptions[0].proxy_arp = 0;
2037 return 1;
2040 static int
2041 setpersist(argv)
2042 char **argv;
2044 persist = 1;
2045 return 1;
2048 static int
2049 setnopersist(argv)
2050 char **argv;
2052 persist = 0;
2053 return 1;
2056 static int
2057 setdologin(argv)
2058 char **argv;
2060 uselogin = 1;
2061 return 1;
2065 * Functions to set the echo interval for modem-less monitors
2068 static int
2069 setlcpechointv(argv)
2070 char **argv;
2072 return int_option(*argv, &lcp_echo_interval);
2075 static int
2076 setlcpechofails(argv)
2077 char **argv;
2079 return int_option(*argv, &lcp_echo_fails);
2083 * Functions to set timeouts, max transmits, etc.
2085 static int
2086 setlcptimeout(argv)
2087 char **argv;
2089 return int_option(*argv, &lcp_fsm[0].timeouttime);
2092 static int
2093 setlcpterm(argv)
2094 char **argv;
2096 return int_option(*argv, &lcp_fsm[0].maxtermtransmits);
2099 static int
2100 setlcpconf(argv)
2101 char **argv;
2103 return int_option(*argv, &lcp_fsm[0].maxconfreqtransmits);
2106 static int
2107 setlcpfails(argv)
2108 char **argv;
2110 return int_option(*argv, &lcp_fsm[0].maxnakloops);
2113 static int
2114 setipcptimeout(argv)
2115 char **argv;
2117 return int_option(*argv, &ipcp_fsm[0].timeouttime);
2120 static int
2121 setipcpterm(argv)
2122 char **argv;
2124 return int_option(*argv, &ipcp_fsm[0].maxtermtransmits);
2127 static int
2128 setipcpconf(argv)
2129 char **argv;
2131 return int_option(*argv, &ipcp_fsm[0].maxconfreqtransmits);
2134 static int
2135 setipcpfails(argv)
2136 char **argv;
2138 return int_option(*argv, &lcp_fsm[0].maxnakloops);
2141 static int
2142 setpaptimeout(argv)
2143 char **argv;
2145 return int_option(*argv, &upap[0].us_timeouttime);
2148 static int
2149 setpapreqtime(argv)
2150 char **argv;
2152 return int_option(*argv, &upap[0].us_reqtimeout);
2155 static int
2156 setpapreqs(argv)
2157 char **argv;
2159 return int_option(*argv, &upap[0].us_maxtransmits);
2162 static int
2163 setchaptimeout(argv)
2164 char **argv;
2166 return int_option(*argv, &chap[0].timeouttime);
2169 static int
2170 setchapchal(argv)
2171 char **argv;
2173 return int_option(*argv, &chap[0].max_transmits);
2176 static int
2177 setchapintv(argv)
2178 char **argv;
2180 return int_option(*argv, &chap[0].chal_interval);
2183 static int
2184 noccp(argv)
2185 char **argv;
2187 ccp_protent.enabled_flag = 0;
2188 return 1;
2191 static int
2192 setbsdcomp(argv)
2193 char **argv;
2195 int rbits, abits;
2196 char *str, *endp;
2198 str = *argv;
2199 abits = rbits = strtol(str, &endp, 0);
2200 if (endp != str && *endp == ',') {
2201 str = endp + 1;
2202 abits = strtol(str, &endp, 0);
2204 if (*endp != 0 || endp == str) {
2205 option_error("invalid parameter '%s' for bsdcomp option", *argv);
2206 return 0;
2208 if ((rbits != 0 && (rbits < BSD_MIN_BITS || rbits > BSD_MAX_BITS))
2209 || (abits != 0 && (abits < BSD_MIN_BITS || abits > BSD_MAX_BITS))) {
2210 option_error("bsdcomp option values must be 0 or %d .. %d",
2211 BSD_MIN_BITS, BSD_MAX_BITS);
2212 return 0;
2214 if (rbits > 0) {
2215 ccp_wantoptions[0].bsd_compress = 1;
2216 ccp_wantoptions[0].bsd_bits = rbits;
2217 } else
2218 ccp_wantoptions[0].bsd_compress = 0;
2219 if (abits > 0) {
2220 ccp_allowoptions[0].bsd_compress = 1;
2221 ccp_allowoptions[0].bsd_bits = abits;
2222 } else
2223 ccp_allowoptions[0].bsd_compress = 0;
2224 return 1;
2227 static int
2228 setnobsdcomp(argv)
2229 char **argv;
2231 ccp_wantoptions[0].bsd_compress = 0;
2232 ccp_allowoptions[0].bsd_compress = 0;
2233 return 1;
2236 static int
2237 setdeflate(argv)
2238 char **argv;
2240 int rbits, abits;
2241 char *str, *endp;
2243 str = *argv;
2244 abits = rbits = strtol(str, &endp, 0);
2245 if (endp != str && *endp == ',') {
2246 str = endp + 1;
2247 abits = strtol(str, &endp, 0);
2249 if (*endp != 0 || endp == str) {
2250 option_error("invalid parameter '%s' for deflate option", *argv);
2251 return 0;
2253 if ((rbits != 0 && (rbits < DEFLATE_MIN_SIZE || rbits > DEFLATE_MAX_SIZE))
2254 || (abits != 0 && (abits < DEFLATE_MIN_SIZE
2255 || abits > DEFLATE_MAX_SIZE))) {
2256 option_error("deflate option values must be 0 or %d .. %d",
2257 DEFLATE_MIN_SIZE, DEFLATE_MAX_SIZE);
2258 return 0;
2260 if (rbits > 0) {
2261 ccp_wantoptions[0].deflate = 1;
2262 ccp_wantoptions[0].deflate_size = rbits;
2263 } else
2264 ccp_wantoptions[0].deflate = 0;
2265 if (abits > 0) {
2266 ccp_allowoptions[0].deflate = 1;
2267 ccp_allowoptions[0].deflate_size = abits;
2268 } else
2269 ccp_allowoptions[0].deflate = 0;
2271 /* XXX copy over settings for switch compatibility */
2272 ccp_wantoptions[0].baddeflate = ccp_wantoptions[0].deflate;
2273 ccp_wantoptions[0].baddeflate_size = ccp_wantoptions[0].deflate_size;
2274 ccp_allowoptions[0].baddeflate = ccp_allowoptions[0].deflate;
2275 ccp_allowoptions[0].baddeflate_size = ccp_allowoptions[0].deflate_size;
2277 return 1;
2280 static int
2281 setnodeflate(argv)
2282 char **argv;
2284 ccp_wantoptions[0].deflate = 0;
2285 ccp_allowoptions[0].deflate = 0;
2286 return 1;
2289 static int
2290 setnodeflatedraft(argv)
2291 char **argv;
2293 ccp_wantoptions[0].deflate_draft = 0;
2294 ccp_allowoptions[0].deflate_draft = 0;
2295 return 1;
2298 static int
2299 setpred1comp(argv)
2300 char **argv;
2302 ccp_wantoptions[0].predictor_1 = 1;
2303 ccp_allowoptions[0].predictor_1 = 1;
2304 return 1;
2307 static int
2308 setnopred1comp(argv)
2309 char **argv;
2311 ccp_wantoptions[0].predictor_1 = 0;
2312 ccp_allowoptions[0].predictor_1 = 0;
2313 return 1;
2316 static int
2317 setipparam(argv)
2318 char **argv;
2320 ipparam = strdup(*argv);
2321 if (ipparam == NULL)
2322 novm("ipparam string");
2324 return 1;
2327 static int
2328 setpapcrypt(argv)
2329 char **argv;
2331 cryptpap = 1;
2332 return 1;
2335 static int
2336 setidle(argv)
2337 char **argv;
2339 return int_option(*argv, &idle_time_limit);
2342 static int
2343 setholdoff(argv)
2344 char **argv;
2346 return int_option(*argv, &holdoff);
2350 * setdnsaddr - set the dns address(es)
2352 static int
2353 setdnsaddr(argv)
2354 char **argv;
2356 u_int32_t dns;
2357 struct hostent *hp;
2359 dns = inet_addr(*argv);
2360 if (dns == -1) {
2361 if ((hp = gethostbyname(*argv)) == NULL) {
2362 option_error("invalid address parameter '%s' for ms-dns option",
2363 *argv);
2364 return 0;
2366 dns = *(u_int32_t *)hp->h_addr;
2369 /* if there is no primary then update it. */
2370 if (ipcp_allowoptions[0].dnsaddr[0] == 0)
2371 ipcp_allowoptions[0].dnsaddr[0] = dns;
2373 /* always set the secondary address value to the same value. */
2374 ipcp_allowoptions[0].dnsaddr[1] = dns;
2376 return (1);
2380 * setwinsaddr - set the wins address(es)
2381 * This is primrarly used with the Samba package under UNIX or for pointing
2382 * the caller to the existing WINS server on a Windows NT platform.
2384 static int
2385 setwinsaddr(argv)
2386 char **argv;
2388 u_int32_t wins;
2389 struct hostent *hp;
2391 wins = inet_addr(*argv);
2392 if (wins == -1) {
2393 if ((hp = gethostbyname(*argv)) == NULL) {
2394 option_error("invalid address parameter '%s' for ms-wins option",
2395 *argv);
2396 return 0;
2398 wins = *(u_int32_t *)hp->h_addr;
2401 /* if there is no primary then update it. */
2402 if (ipcp_allowoptions[0].winsaddr[0] == 0)
2403 ipcp_allowoptions[0].winsaddr[0] = wins;
2405 /* always set the secondary address value to the same value. */
2406 ipcp_allowoptions[0].winsaddr[1] = wins;
2408 return (1);
2411 #ifdef INET6
2412 static int
2413 setipv6cp_accept_local(argv)
2414 char **argv;
2416 ipv6cp_allowoptions[0].accept_local = 1;
2417 return 1;
2420 static int
2421 setipv6cp_use_ip(argv)
2422 char **argv;
2424 ipv6cp_allowoptions[0].use_ip = 1;
2425 return 1;
2428 #if defined(SOL2)
2429 static int
2430 setipv6cp_use_persistent(argv)
2431 char **argv;
2433 ipv6cp_wantoptions[0].use_persistent = 1;
2434 return 1;
2436 #endif
2438 static int
2439 setipv6cptimeout(argv)
2440 char **argv;
2442 return int_option(*argv, &ipv6cp_fsm[0].timeouttime);
2445 static int
2446 setipv6cpterm(argv)
2447 char **argv;
2449 return int_option(*argv, &ipv6cp_fsm[0].maxtermtransmits);
2452 static int
2453 setipv6cpconf(argv)
2454 char **argv;
2456 return int_option(*argv, &ipv6cp_fsm[0].maxconfreqtransmits);
2459 static int
2460 setipv6cpfails(argv)
2461 char **argv;
2463 return int_option(*argv, &ipv6cp_fsm[0].maxnakloops);
2466 static int
2467 setipv6proto(argv)
2468 char **argv;
2470 ipv6cp_protent.enabled_flag = 1;
2471 return 1;
2474 static int
2475 resetipv6proto(argv)
2476 char **argv;
2478 ipv6cp_protent.enabled_flag = 0;
2479 return 1;
2481 #else
2482 static int
2483 resetipv6proto(argv)
2484 char **argv;
2486 return 1;
2488 #endif /* INET6 */
2490 #ifdef IPX_CHANGE
2491 static int
2492 setipxrouter (argv)
2493 char **argv;
2495 ipxcp_wantoptions[0].neg_router = 1;
2496 ipxcp_allowoptions[0].neg_router = 1;
2497 return int_option(*argv, &ipxcp_wantoptions[0].router);
2500 static int
2501 setipxname (argv)
2502 char **argv;
2504 char *dest = ipxcp_wantoptions[0].name;
2505 char *src = *argv;
2506 int count;
2507 char ch;
2509 ipxcp_wantoptions[0].neg_name = 1;
2510 ipxcp_allowoptions[0].neg_name = 1;
2511 memset (dest, '\0', sizeof (ipxcp_wantoptions[0].name));
2513 count = 0;
2514 while (*src) {
2515 ch = *src++;
2516 if (! isalnum (ch) && ch != '_') {
2517 option_error("IPX router name must be alphanumeric or _");
2518 return 0;
2521 if (count >= sizeof (ipxcp_wantoptions[0].name)) {
2522 option_error("IPX router name is limited to %d characters",
2523 sizeof (ipxcp_wantoptions[0].name) - 1);
2524 return 0;
2527 dest[count++] = toupper (ch);
2530 return 1;
2533 static int
2534 setipxcptimeout (argv)
2535 char **argv;
2537 return int_option(*argv, &ipxcp_fsm[0].timeouttime);
2540 static int
2541 setipxcpterm (argv)
2542 char **argv;
2544 return int_option(*argv, &ipxcp_fsm[0].maxtermtransmits);
2547 static int
2548 setipxcpconf (argv)
2549 char **argv;
2551 return int_option(*argv, &ipxcp_fsm[0].maxconfreqtransmits);
2554 static int
2555 setipxcpfails (argv)
2556 char **argv;
2558 return int_option(*argv, &ipxcp_fsm[0].maxnakloops);
2561 static int
2562 setipxnetwork(argv)
2563 char **argv;
2565 u_int32_t v;
2567 if (!number_option(*argv, &v, 16))
2568 return 0;
2570 ipxcp_wantoptions[0].our_network = (int) v;
2571 ipxcp_wantoptions[0].neg_nn = 1;
2572 return 1;
2575 static int
2576 setipxanet(argv)
2577 char **argv;
2579 ipxcp_wantoptions[0].accept_network = 1;
2580 ipxcp_allowoptions[0].accept_network = 1;
2581 return 1;
2584 static int
2585 setipxalcl(argv)
2586 char **argv;
2588 ipxcp_wantoptions[0].accept_local = 1;
2589 ipxcp_allowoptions[0].accept_local = 1;
2590 return 1;
2593 static int
2594 setipxarmt(argv)
2595 char **argv;
2597 ipxcp_wantoptions[0].accept_remote = 1;
2598 ipxcp_allowoptions[0].accept_remote = 1;
2599 return 1;
2602 static u_char *
2603 setipxnodevalue(src,dst)
2604 u_char *src, *dst;
2606 int indx;
2607 int item;
2609 for (;;) {
2610 if (!isxdigit (*src))
2611 break;
2613 for (indx = 0; indx < 5; ++indx) {
2614 dst[indx] <<= 4;
2615 dst[indx] |= (dst[indx + 1] >> 4) & 0x0F;
2618 item = toupper (*src) - '0';
2619 if (item > 9)
2620 item -= 7;
2622 dst[5] = (dst[5] << 4) | item;
2623 ++src;
2625 return src;
2628 static int
2629 setipxnode(argv)
2630 char **argv;
2632 char *end;
2634 memset (&ipxcp_wantoptions[0].our_node[0], 0, 6);
2635 memset (&ipxcp_wantoptions[0].his_node[0], 0, 6);
2637 end = setipxnodevalue (*argv, &ipxcp_wantoptions[0].our_node[0]);
2638 if (*end == ':')
2639 end = setipxnodevalue (++end, &ipxcp_wantoptions[0].his_node[0]);
2641 if (*end == '\0') {
2642 ipxcp_wantoptions[0].neg_node = 1;
2643 return 1;
2646 option_error("invalid parameter '%s' for ipx-node option", *argv);
2647 return 0;
2650 static int
2651 setipxproto(argv)
2652 char **argv;
2654 ipxcp_protent.enabled_flag = 1;
2655 return 1;
2658 static int
2659 resetipxproto(argv)
2660 char **argv;
2662 ipxcp_protent.enabled_flag = 0;
2663 return 1;
2665 #else
2667 static int
2668 resetipxproto(argv)
2669 char **argv;
2671 return 1;
2673 #endif /* IPX_CHANGE */
2675 #ifdef MSLANMAN
2676 static int
2677 setmslanman(argv)
2678 char **argv;
2680 ms_lanman = 1;
2681 return (1);
2683 #endif