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