1 /* 2 * PPP User command processing module 3 * 4 * Written by Toshiharu OHNO (tony-o@iij.ad.jp) 5 * 6 * Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd. 7 * 8 * Redistribution and use in source and binary forms are permitted 9 * provided that the above copyright notice and this paragraph are 10 * duplicated in all such forms and that any documentation, 11 * advertising materials, and other materials related to such 12 * distribution and use acknowledge that the software was developed 13 * by the Internet Initiative Japan, Inc. The name of the 14 * IIJ may not be used to endorse or promote products derived 15 * from this software without specific prior written permission. 16 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 18 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 19 * 20 * $Id: command.c,v 1.126 1998/01/10 21:51:31 brian Exp $ 21 * 22 */ 23 #include <sys/param.h> 24 #include <netinet/in_systm.h> 25 #include <netinet/in.h> 26 #include <netinet/ip.h> 27 #include <arpa/inet.h> 28 #include <sys/socket.h> 29 #include <net/route.h> 30 #include <netdb.h> 31 32 #ifndef NOALIAS 33 #include <alias.h> 34 #endif 35 #include <ctype.h> 36 #include <errno.h> 37 #include <fcntl.h> 38 #include <paths.h> 39 #include <stdio.h> 40 #include <stdlib.h> 41 #include <string.h> 42 #include <sys/stat.h> 43 #include <sys/wait.h> 44 #include <termios.h> 45 #include <time.h> 46 #include <unistd.h> 47 48 #include "command.h" 49 #include "mbuf.h" 50 #include "log.h" 51 #include "defs.h" 52 #include "timer.h" 53 #include "fsm.h" 54 #include "phase.h" 55 #include "lcp.h" 56 #include "iplist.h" 57 #include "ipcp.h" 58 #include "modem.h" 59 #include "filter.h" 60 #ifndef NOALIAS 61 #include "alias_cmd.h" 62 #endif 63 #include "hdlc.h" 64 #include "loadalias.h" 65 #include "vars.h" 66 #include "systems.h" 67 #include "chat.h" 68 #include "os.h" 69 #include "server.h" 70 #include "main.h" 71 #include "route.h" 72 #include "ccp.h" 73 #include "ip.h" 74 #include "slcompress.h" 75 #include "auth.h" 76 77 struct in_addr ifnetmask; 78 static const char *HIDDEN = "********"; 79 80 static int ShowCommand(struct cmdargs const *arg); 81 static int TerminalCommand(struct cmdargs const *arg); 82 static int QuitCommand(struct cmdargs const *arg); 83 static int CloseCommand(struct cmdargs const *arg); 84 static int DialCommand(struct cmdargs const *arg); 85 static int DownCommand(struct cmdargs const *arg); 86 static int AllowCommand(struct cmdargs const *arg); 87 static int SetCommand(struct cmdargs const *arg); 88 static int AddCommand(struct cmdargs const *arg); 89 static int DeleteCommand(struct cmdargs const *arg); 90 static int BgShellCommand(struct cmdargs const *arg); 91 static int FgShellCommand(struct cmdargs const *arg); 92 #ifndef NOALIAS 93 static int AliasCommand(struct cmdargs const *arg); 94 static int AliasEnable(struct cmdargs const *arg); 95 static int AliasOption(struct cmdargs const *arg); 96 #endif 97 98 static int 99 HelpCommand(struct cmdargs const *arg) 100 { 101 struct cmdtab const *cmd; 102 int n, cmax, dmax, cols; 103 104 if (!VarTerm) 105 return 0; 106 107 if (arg->argc > 0) { 108 for (cmd = arg->cmd; cmd->name; cmd++) 109 if (strcasecmp(cmd->name, *arg->argv) == 0 && 110 (cmd->lauth & VarLocalAuth)) { 111 fprintf(VarTerm, "%s\n", cmd->syntax); 112 return 0; 113 } 114 return -1; 115 } 116 cmax = dmax = 0; 117 for (cmd = arg->cmd; cmd->func; cmd++) 118 if (cmd->name && (cmd->lauth & VarLocalAuth)) { 119 if ((n = strlen(cmd->name)) > cmax) 120 cmax = n; 121 if ((n = strlen(cmd->helpmes)) > dmax) 122 dmax = n; 123 } 124 125 cols = 80 / (dmax + cmax + 3); 126 n = 0; 127 for (cmd = arg->cmd; cmd->func; cmd++) 128 if (cmd->name && (cmd->lauth & VarLocalAuth)) { 129 fprintf(VarTerm, " %-*.*s: %-*.*s", 130 cmax, cmax, cmd->name, dmax, dmax, cmd->helpmes); 131 if (++n % cols == 0) 132 fprintf(VarTerm, "\n"); 133 } 134 if (n % cols != 0) 135 fprintf(VarTerm, "\n"); 136 137 return 0; 138 } 139 140 int 141 IsInteractive(int Display) 142 { 143 const char *mes = NULL; 144 145 if (mode & MODE_DDIAL) 146 mes = "Working in dedicated dial mode."; 147 else if (mode & MODE_BACKGROUND) 148 mes = "Working in background mode."; 149 else if (mode & MODE_AUTO) 150 mes = "Working in auto mode."; 151 else if (mode & MODE_DIRECT) 152 mes = "Working in direct mode."; 153 else if (mode & MODE_DEDICATED) 154 mes = "Working in dedicated mode."; 155 if (mes) { 156 if (Display && VarTerm) 157 fprintf(VarTerm, "%s\n", mes); 158 return 0; 159 } 160 return 1; 161 } 162 163 static int 164 DialCommand(struct cmdargs const *arg) 165 { 166 int tries; 167 int res; 168 169 if (LcpFsm.state > ST_CLOSED) { 170 if (VarTerm) 171 fprintf(VarTerm, "LCP state is [%s]\n", StateNames[LcpFsm.state]); 172 return 0; 173 } 174 175 if (arg->argc > 0 && (res = LoadCommand(arg)) != 0) 176 return res; 177 178 tries = 0; 179 do { 180 if (tries) { 181 LogPrintf(LogPHASE, "Enter pause (%d) for redialing.\n", 182 VarRedialNextTimeout); 183 nointr_sleep(VarRedialNextTimeout); 184 } 185 if (VarTerm) 186 fprintf(VarTerm, "Dial attempt %u of %d\n", ++tries, VarDialTries); 187 if (OpenModem() < 0) { 188 if (VarTerm) 189 fprintf(VarTerm, "Failed to open modem.\n"); 190 break; 191 } 192 if ((res = DialModem()) == EX_DONE) { 193 nointr_sleep(1); 194 ModemTimeout(NULL); 195 PacketMode(); 196 break; 197 } else if (res == EX_SIG) 198 return 1; 199 } while (VarDialTries == 0 || tries < VarDialTries); 200 201 return 0; 202 } 203 204 static int 205 SetLoopback(struct cmdargs const *arg) 206 { 207 if (arg->argc == 1) 208 if (!strcasecmp(*arg->argv, "on")) { 209 VarLoopback = 1; 210 return 0; 211 } 212 else if (!strcasecmp(*arg->argv, "off")) { 213 VarLoopback = 0; 214 return 0; 215 } 216 return -1; 217 } 218 219 static int 220 ShellCommand(struct cmdargs const *arg, int bg) 221 { 222 const char *shell; 223 pid_t shpid; 224 int argc; 225 char *argv[MAXARGS]; 226 227 #ifdef SHELL_ONLY_INTERACTIVELY 228 /* we're only allowed to shell when we run ppp interactively */ 229 if (mode != MODE_INTER) { 230 LogPrintf(LogWARN, "Can only start a shell in interactive mode\n"); 231 return 1; 232 } 233 #endif 234 #ifdef NO_SHELL_IN_AUTO_INTERACTIVE 235 236 /* 237 * we want to stop shell commands when we've got a telnet connection to an 238 * auto mode ppp 239 */ 240 if (VarTerm && !(mode & MODE_INTER)) { 241 LogPrintf(LogWARN, "Shell is not allowed interactively in auto mode\n"); 242 return 1; 243 } 244 #endif 245 246 if (arg->argc == 0) 247 if (!(mode & MODE_INTER)) { 248 if (VarTerm) 249 LogPrintf(LogWARN, "Can't start an interactive shell from" 250 " a telnet session\n"); 251 else 252 LogPrintf(LogWARN, "Can only start an interactive shell in" 253 " interactive mode\n"); 254 return 1; 255 } else if (bg) { 256 LogPrintf(LogWARN, "Can only start an interactive shell in" 257 " the foreground mode\n"); 258 return 1; 259 } 260 if ((shell = getenv("SHELL")) == 0) 261 shell = _PATH_BSHELL; 262 263 if ((shpid = fork()) == 0) { 264 int dtablesize, i, fd; 265 266 TermTimerService(); 267 signal(SIGINT, SIG_DFL); 268 signal(SIGQUIT, SIG_DFL); 269 signal(SIGTERM, SIG_DFL); 270 signal(SIGHUP, SIG_DFL); 271 signal(SIGALRM, SIG_DFL); 272 273 if (VarTerm) 274 fd = fileno(VarTerm); 275 else if ((fd = open("/dev/null", O_RDWR)) == -1) { 276 LogPrintf(LogALERT, "Failed to open /dev/null: %s\n", strerror(errno)); 277 exit(1); 278 } 279 for (i = 0; i < 3; i++) 280 dup2(fd, i); 281 282 for (dtablesize = getdtablesize(), i = 3; i < dtablesize; i++) 283 close(i); 284 285 TtyOldMode(); 286 setuid(geteuid()); 287 if (arg->argc > 0) { 288 /* substitute pseudo args */ 289 argv[0] = strdup(arg->argv[0]); 290 for (argc = 1; argc < arg->argc; argc++) { 291 if (strcasecmp(arg->argv[argc], "HISADDR") == 0) 292 argv[argc] = strdup(inet_ntoa(IpcpInfo.his_ipaddr)); 293 else if (strcasecmp(arg->argv[argc], "INTERFACE") == 0) 294 argv[argc] = strdup(IfDevName); 295 else if (strcasecmp(arg->argv[argc], "MYADDR") == 0) 296 argv[argc] = strdup(inet_ntoa(IpcpInfo.want_ipaddr)); 297 else 298 argv[argc] = strdup(arg->argv[argc]); 299 } 300 argv[argc] = NULL; 301 if (bg) { 302 pid_t p; 303 304 p = getpid(); 305 if (daemon(1, 1) == -1) { 306 LogPrintf(LogERROR, "%d: daemon: %s\n", p, strerror(errno)); 307 exit(1); 308 } 309 } else if (VarTerm) 310 printf("ppp: Pausing until %s finishes\n", arg->argv[0]); 311 execvp(argv[0], argv); 312 } else { 313 if (VarTerm) 314 printf("ppp: Pausing until %s finishes\n", shell); 315 execl(shell, shell, NULL); 316 } 317 318 LogPrintf(LogWARN, "exec() of %s failed\n", 319 arg->argc > 0 ? arg->argv[0] : shell); 320 exit(255); 321 } 322 if (shpid == (pid_t) - 1) { 323 LogPrintf(LogERROR, "Fork failed: %s\n", strerror(errno)); 324 } else { 325 int status; 326 327 waitpid(shpid, &status, 0); 328 } 329 330 TtyCommandMode(0); 331 332 return (0); 333 } 334 335 static int 336 BgShellCommand(struct cmdargs const *arg) 337 { 338 if (arg->argc == 0) 339 return -1; 340 return ShellCommand(arg, 1); 341 } 342 343 static int 344 FgShellCommand(struct cmdargs const *arg) 345 { 346 return ShellCommand(arg, 0); 347 } 348 349 static struct cmdtab const Commands[] = { 350 {"accept", NULL, AcceptCommand, LOCAL_AUTH, 351 "accept option request", "accept option .."}, 352 {"add", NULL, AddCommand, LOCAL_AUTH, 353 "add route", "add dest mask gateway", NULL}, 354 {"add!", NULL, AddCommand, LOCAL_AUTH, 355 "add or change route", "add! dest mask gateway", (void *)1}, 356 {"allow", "auth", AllowCommand, LOCAL_AUTH, 357 "Allow ppp access", "allow users|modes ...."}, 358 {"bg", "!bg", BgShellCommand, LOCAL_AUTH, 359 "Run a background command", "[!]bg command"}, 360 {"close", NULL, CloseCommand, LOCAL_AUTH, 361 "Close connection", "close"}, 362 {"delete", NULL, DeleteCommand, LOCAL_AUTH, 363 "delete route", "delete dest", NULL}, 364 {"delete!", NULL, DeleteCommand, LOCAL_AUTH, 365 "delete a route if it exists", "delete! dest", (void *)1}, 366 {"deny", NULL, DenyCommand, LOCAL_AUTH, 367 "Deny option request", "deny option .."}, 368 {"dial", "call", DialCommand, LOCAL_AUTH, 369 "Dial and login", "dial|call [remote]"}, 370 {"disable", NULL, DisableCommand, LOCAL_AUTH, 371 "Disable option", "disable option .."}, 372 {"display", NULL, DisplayCommand, LOCAL_AUTH, 373 "Display option configs", "display"}, 374 {"enable", NULL, EnableCommand, LOCAL_AUTH, 375 "Enable option", "enable option .."}, 376 {"passwd", NULL, LocalAuthCommand, LOCAL_NO_AUTH, 377 "Password for manipulation", "passwd LocalPassword"}, 378 {"load", NULL, LoadCommand, LOCAL_AUTH, 379 "Load settings", "load [remote]"}, 380 {"save", NULL, SaveCommand, LOCAL_AUTH, 381 "Save settings", "save"}, 382 {"set", "setup", SetCommand, LOCAL_AUTH, 383 "Set parameters", "set[up] var value"}, 384 {"shell", "!", FgShellCommand, LOCAL_AUTH, 385 "Run a subshell", "shell|! [sh command]"}, 386 {"show", NULL, ShowCommand, LOCAL_AUTH, 387 "Show status and stats", "show var"}, 388 {"term", NULL, TerminalCommand, LOCAL_AUTH, 389 "Enter terminal mode", "term"}, 390 #ifndef NOALIAS 391 {"alias", NULL, AliasCommand, LOCAL_AUTH, 392 "alias control", "alias option [yes|no]"}, 393 #endif 394 {"quit", "bye", QuitCommand, LOCAL_AUTH | LOCAL_NO_AUTH, 395 "Quit PPP program", "quit|bye [all]"}, 396 {"help", "?", HelpCommand, LOCAL_AUTH | LOCAL_NO_AUTH, 397 "Display this message", "help|? [command]", Commands}, 398 {NULL, "down", DownCommand, LOCAL_AUTH, 399 "Generate down event", "down"}, 400 {NULL, NULL, NULL}, 401 }; 402 403 static int 404 ShowLoopback(struct cmdargs const *arg) 405 { 406 if (VarTerm) 407 fprintf(VarTerm, "Local loopback is %s\n", VarLoopback ? "on" : "off"); 408 409 return 0; 410 } 411 412 static int 413 ShowLogLevel(struct cmdargs const *arg) 414 { 415 int i; 416 417 if (!VarTerm) 418 return 0; 419 420 fprintf(VarTerm, "Log: "); 421 for (i = LogMIN; i <= LogMAX; i++) 422 if (LogIsKept(i) & LOG_KEPT_SYSLOG) 423 fprintf(VarTerm, " %s", LogName(i)); 424 425 fprintf(VarTerm, "\nLocal:"); 426 for (i = LogMIN; i <= LogMAX; i++) 427 if (LogIsKept(i) & LOG_KEPT_LOCAL) 428 fprintf(VarTerm, " %s", LogName(i)); 429 430 fprintf(VarTerm, "\n"); 431 432 return 0; 433 } 434 435 static int 436 ShowEscape(struct cmdargs const *arg) 437 { 438 int code, bit; 439 440 if (!VarTerm) 441 return 0; 442 if (EscMap[32]) { 443 for (code = 0; code < 32; code++) 444 if (EscMap[code]) 445 for (bit = 0; bit < 8; bit++) 446 if (EscMap[code] & (1 << bit)) 447 fprintf(VarTerm, " 0x%02x", (code << 3) + bit); 448 fprintf(VarTerm, "\n"); 449 } 450 return 0; 451 } 452 453 static int 454 ShowTimeout(struct cmdargs const *arg) 455 { 456 if (VarTerm) { 457 int remaining; 458 459 fprintf(VarTerm, " Idle Timer: %d secs LQR Timer: %d secs" 460 " Retry Timer: %d secs\n", VarIdleTimeout, VarLqrTimeout, 461 VarRetryTimeout); 462 remaining = RemainingIdleTime(); 463 if (remaining != -1) 464 fprintf(VarTerm, " %d secs remaining\n", remaining); 465 } 466 return 0; 467 } 468 469 static int 470 ShowStopped(struct cmdargs const *arg) 471 { 472 if (!VarTerm) 473 return 0; 474 475 fprintf(VarTerm, " Stopped Timer: LCP: "); 476 if (!LcpFsm.StoppedTimer.load) 477 fprintf(VarTerm, "Disabled"); 478 else 479 fprintf(VarTerm, "%ld secs", LcpFsm.StoppedTimer.load / SECTICKS); 480 481 fprintf(VarTerm, ", IPCP: "); 482 if (!IpcpFsm.StoppedTimer.load) 483 fprintf(VarTerm, "Disabled"); 484 else 485 fprintf(VarTerm, "%ld secs", IpcpFsm.StoppedTimer.load / SECTICKS); 486 487 fprintf(VarTerm, ", CCP: "); 488 if (!CcpFsm.StoppedTimer.load) 489 fprintf(VarTerm, "Disabled"); 490 else 491 fprintf(VarTerm, "%ld secs", CcpFsm.StoppedTimer.load / SECTICKS); 492 493 fprintf(VarTerm, "\n"); 494 495 return 0; 496 } 497 498 static int 499 ShowAuthKey(struct cmdargs const *arg) 500 { 501 if (!VarTerm) 502 return 0; 503 fprintf(VarTerm, "AuthName = %s\n", VarAuthName); 504 fprintf(VarTerm, "AuthKey = %s\n", HIDDEN); 505 #ifdef HAVE_DES 506 fprintf(VarTerm, "Encrypt = %s\n", VarMSChap ? "MSChap" : "MD5" ); 507 #endif 508 return 0; 509 } 510 511 static int 512 ShowVersion(struct cmdargs const *arg) 513 { 514 if (VarTerm) 515 fprintf(VarTerm, "%s - %s \n", VarVersion, VarLocalVersion); 516 return 0; 517 } 518 519 static int 520 ShowInitialMRU(struct cmdargs const *arg) 521 { 522 if (VarTerm) 523 fprintf(VarTerm, " Initial MRU: %d\n", VarMRU); 524 return 0; 525 } 526 527 static int 528 ShowPreferredMTU(struct cmdargs const *arg) 529 { 530 if (VarTerm) 531 if (VarPrefMTU) 532 fprintf(VarTerm, " Preferred MTU: %d\n", VarPrefMTU); 533 else 534 fprintf(VarTerm, " Preferred MTU: unspecified\n"); 535 return 0; 536 } 537 538 static int 539 ShowReconnect(struct cmdargs const *arg) 540 { 541 if (VarTerm) 542 fprintf(VarTerm, " Reconnect Timer: %d, %d tries\n", 543 VarReconnectTimer, VarReconnectTries); 544 return 0; 545 } 546 547 static int 548 ShowRedial(struct cmdargs const *arg) 549 { 550 if (!VarTerm) 551 return 0; 552 fprintf(VarTerm, " Redial Timer: "); 553 554 if (VarRedialTimeout >= 0) { 555 fprintf(VarTerm, " %d seconds, ", VarRedialTimeout); 556 } else { 557 fprintf(VarTerm, " Random 0 - %d seconds, ", REDIAL_PERIOD); 558 } 559 560 fprintf(VarTerm, " Redial Next Timer: "); 561 562 if (VarRedialNextTimeout >= 0) { 563 fprintf(VarTerm, " %d seconds, ", VarRedialNextTimeout); 564 } else { 565 fprintf(VarTerm, " Random 0 - %d seconds, ", REDIAL_PERIOD); 566 } 567 568 if (VarDialTries) 569 fprintf(VarTerm, "%d dial tries", VarDialTries); 570 571 fprintf(VarTerm, "\n"); 572 573 return 0; 574 } 575 576 #ifndef NOMSEXT 577 static int 578 ShowMSExt(struct cmdargs const *arg) 579 { 580 if (VarTerm) { 581 fprintf(VarTerm, " MS PPP extention values \n"); 582 fprintf(VarTerm, " Primary NS : %s\n", inet_ntoa(ns_entries[0])); 583 fprintf(VarTerm, " Secondary NS : %s\n", inet_ntoa(ns_entries[1])); 584 fprintf(VarTerm, " Primary NBNS : %s\n", inet_ntoa(nbns_entries[0])); 585 fprintf(VarTerm, " Secondary NBNS : %s\n", inet_ntoa(nbns_entries[1])); 586 } 587 return 0; 588 } 589 590 #endif 591 592 static struct cmdtab const ShowCommands[] = { 593 {"afilter", NULL, ShowAfilter, LOCAL_AUTH, 594 "Show keep-alive filters", "show afilter option .."}, 595 {"auth", NULL, ShowAuthKey, LOCAL_AUTH, 596 "Show auth details", "show auth"}, 597 {"ccp", NULL, ReportCcpStatus, LOCAL_AUTH, 598 "Show CCP status", "show cpp"}, 599 {"compress", NULL, ReportCompress, LOCAL_AUTH, 600 "Show compression stats", "show compress"}, 601 {"dfilter", NULL, ShowDfilter, LOCAL_AUTH, 602 "Show Demand filters", "show dfilteroption .."}, 603 {"escape", NULL, ShowEscape, LOCAL_AUTH, 604 "Show escape characters", "show escape"}, 605 {"hdlc", NULL, ReportHdlcStatus, LOCAL_AUTH, 606 "Show HDLC errors", "show hdlc"}, 607 {"ifilter", NULL, ShowIfilter, LOCAL_AUTH, 608 "Show Input filters", "show ifilter option .."}, 609 {"ipcp", NULL, ReportIpcpStatus, LOCAL_AUTH, 610 "Show IPCP status", "show ipcp"}, 611 {"lcp", NULL, ReportLcpStatus, LOCAL_AUTH, 612 "Show LCP status", "show lcp"}, 613 {"loopback", NULL, ShowLoopback, LOCAL_AUTH, 614 "Show loopback setting", "show loopback"}, 615 {"log", NULL, ShowLogLevel, LOCAL_AUTH, 616 "Show log levels", "show log"}, 617 {"mem", NULL, ShowMemMap, LOCAL_AUTH, 618 "Show memory map", "show mem"}, 619 {"modem", NULL, ShowModemStatus, LOCAL_AUTH, 620 "Show modem setups", "show modem"}, 621 {"mru", NULL, ShowInitialMRU, LOCAL_AUTH, 622 "Show Initial MRU", "show mru"}, 623 {"mtu", NULL, ShowPreferredMTU, LOCAL_AUTH, 624 "Show Preferred MTU", "show mtu"}, 625 {"ofilter", NULL, ShowOfilter, LOCAL_AUTH, 626 "Show Output filters", "show ofilter option .."}, 627 {"proto", NULL, ReportProtStatus, LOCAL_AUTH, 628 "Show protocol summary", "show proto"}, 629 {"reconnect", NULL, ShowReconnect, LOCAL_AUTH, 630 "Show reconnect timer", "show reconnect"}, 631 {"redial", NULL, ShowRedial, LOCAL_AUTH, 632 "Show Redial timeout", "show redial"}, 633 {"route", NULL, ShowRoute, LOCAL_AUTH, 634 "Show routing table", "show route"}, 635 {"timeout", NULL, ShowTimeout, LOCAL_AUTH, 636 "Show Idle timeout", "show timeout"}, 637 {"stopped", NULL, ShowStopped, LOCAL_AUTH, 638 "Show STOPPED timeout", "show stopped"}, 639 #ifndef NOMSEXT 640 {"msext", NULL, ShowMSExt, LOCAL_AUTH, 641 "Show MS PPP extentions", "show msext"}, 642 #endif 643 {"version", NULL, ShowVersion, LOCAL_NO_AUTH | LOCAL_AUTH, 644 "Show version string", "show version"}, 645 {"help", "?", HelpCommand, LOCAL_NO_AUTH | LOCAL_AUTH, 646 "Display this message", "show help|? [command]", ShowCommands}, 647 {NULL, NULL, NULL}, 648 }; 649 650 static struct cmdtab const * 651 FindCommand(struct cmdtab const *cmds, const char *str, int *pmatch) 652 { 653 int nmatch; 654 int len; 655 struct cmdtab const *found; 656 657 found = NULL; 658 len = strlen(str); 659 nmatch = 0; 660 while (cmds->func) { 661 if (cmds->name && strncasecmp(str, cmds->name, len) == 0) { 662 if (cmds->name[len] == '\0') { 663 *pmatch = 1; 664 return cmds; 665 } 666 nmatch++; 667 found = cmds; 668 } else if (cmds->alias && strncasecmp(str, cmds->alias, len) == 0) { 669 if (cmds->alias[len] == '\0') { 670 *pmatch = 1; 671 return cmds; 672 } 673 nmatch++; 674 found = cmds; 675 } 676 cmds++; 677 } 678 *pmatch = nmatch; 679 return found; 680 } 681 682 static int 683 FindExec(struct cmdtab const *cmds, int argc, char const *const *argv, 684 const char *prefix) 685 { 686 struct cmdtab const *cmd; 687 int val = 1; 688 int nmatch; 689 struct cmdargs arg; 690 691 cmd = FindCommand(cmds, *argv, &nmatch); 692 if (nmatch > 1) 693 LogPrintf(LogWARN, "%s%s: Ambiguous command\n", prefix, *argv); 694 else if (cmd && (cmd->lauth & VarLocalAuth)) { 695 arg.cmd = cmds; 696 arg.argc = argc-1; 697 arg.argv = argv+1; 698 arg.data = cmd->args; 699 val = (cmd->func) (&arg); 700 } else 701 LogPrintf(LogWARN, "%s%s: Invalid command\n", prefix, *argv); 702 703 if (val == -1) 704 LogPrintf(LogWARN, "Usage: %s\n", cmd->syntax); 705 else if (val) 706 LogPrintf(LogWARN, "%s%s: Failed %d\n", prefix, *argv, val); 707 708 return val; 709 } 710 711 int aft_cmd = 1; 712 713 void 714 Prompt() 715 { 716 const char *pconnect, *pauth; 717 718 if (!VarTerm || TermMode) 719 return; 720 721 if (!aft_cmd) 722 fprintf(VarTerm, "\n"); 723 else 724 aft_cmd = 0; 725 726 if (VarLocalAuth == LOCAL_AUTH) 727 pauth = " ON "; 728 else 729 pauth = " on "; 730 if (IpcpFsm.state == ST_OPENED && phase == PHASE_NETWORK) 731 pconnect = "PPP"; 732 else 733 pconnect = "ppp"; 734 fprintf(VarTerm, "%s%s%s> ", pconnect, pauth, VarShortHost); 735 fflush(VarTerm); 736 } 737 738 void 739 InterpretCommand(char *buff, int nb, int *argc, char ***argv) 740 { 741 static char *vector[MAXARGS]; 742 char *cp; 743 744 if (nb > 0) { 745 cp = buff + strcspn(buff, "\r\n"); 746 if (cp) 747 *cp = '\0'; 748 *argc = MakeArgs(buff, vector, VECSIZE(vector)); 749 *argv = vector; 750 } else 751 *argc = 0; 752 } 753 754 static int 755 arghidden(int argc, char const *const *argv, int n) 756 { 757 /* Is arg n of the given command to be hidden from the log ? */ 758 759 /* set authkey xxxxx */ 760 /* set key xxxxx */ 761 if (n == 2 && !strncasecmp(argv[0], "se", 2) && 762 (!strncasecmp(argv[1], "authk", 5) || !strncasecmp(argv[1], "ke", 2))) 763 return 1; 764 765 /* passwd xxxxx */ 766 if (n == 1 && !strncasecmp(argv[0], "p", 1)) 767 return 1; 768 769 return 0; 770 } 771 772 void 773 RunCommand(int argc, char const *const *argv, const char *label) 774 { 775 if (argc > 0) { 776 if (LogIsKept(LogCOMMAND)) { 777 static char buf[LINE_LEN]; 778 int f, n; 779 780 *buf = '\0'; 781 if (label) { 782 strncpy(buf, label, sizeof buf - 3); 783 buf[sizeof buf - 3] = '\0'; 784 strcat(buf, ": "); 785 } 786 n = strlen(buf); 787 for (f = 0; f < argc; f++) { 788 if (n < sizeof buf - 1 && f) 789 buf[n++] = ' '; 790 if (arghidden(argc, argv, f)) 791 strncpy(buf+n, HIDDEN, sizeof buf - n - 1); 792 else 793 strncpy(buf+n, argv[f], sizeof buf - n - 1); 794 n += strlen(buf+n); 795 } 796 LogPrintf(LogCOMMAND, "%s\n", buf); 797 } 798 FindExec(Commands, argc, argv, ""); 799 } 800 } 801 802 void 803 DecodeCommand(char *buff, int nb, const char *label) 804 { 805 int argc; 806 char **argv; 807 808 InterpretCommand(buff, nb, &argc, &argv); 809 RunCommand(argc, (char const *const *)argv, label); 810 } 811 812 static int 813 ShowCommand(struct cmdargs const *arg) 814 { 815 if (arg->argc > 0) 816 FindExec(ShowCommands, arg->argc, arg->argv, "show "); 817 else if (VarTerm) 818 fprintf(VarTerm, "Use ``show ?'' to get a arg->cmd.\n"); 819 else 820 LogPrintf(LogWARN, "show command must have arguments\n"); 821 822 return 0; 823 } 824 825 static int 826 TerminalCommand(struct cmdargs const *arg) 827 { 828 if (LcpFsm.state > ST_CLOSED) { 829 if (VarTerm) 830 fprintf(VarTerm, "LCP state is [%s]\n", StateNames[LcpFsm.state]); 831 return 1; 832 } 833 if (!IsInteractive(1)) 834 return (1); 835 if (OpenModem() < 0) { 836 if (VarTerm) 837 fprintf(VarTerm, "Failed to open modem.\n"); 838 return (1); 839 } 840 if (VarTerm) { 841 fprintf(VarTerm, "Enter to terminal mode.\n"); 842 fprintf(VarTerm, "Type `~?' for help.\n"); 843 } 844 TtyTermMode(); 845 return (0); 846 } 847 848 static int 849 QuitCommand(struct cmdargs const *arg) 850 { 851 if (VarTerm) { 852 DropClient(1); 853 if (mode & MODE_INTER) 854 Cleanup(EX_NORMAL); 855 else if (arg->argc > 0 && !strcasecmp(*arg->argv, "all") && VarLocalAuth&LOCAL_AUTH) 856 Cleanup(EX_NORMAL); 857 } 858 859 return 0; 860 } 861 862 static int 863 CloseCommand(struct cmdargs const *arg) 864 { 865 reconnect(RECON_FALSE); 866 LcpClose(); 867 return 0; 868 } 869 870 static int 871 DownCommand(struct cmdargs const *arg) 872 { 873 LcpDown(); 874 return 0; 875 } 876 877 static int 878 SetModemSpeed(struct cmdargs const *arg) 879 { 880 int speed; 881 882 if (arg->argc > 0) { 883 if (strcasecmp(*arg->argv, "sync") == 0) { 884 VarSpeed = 0; 885 return 0; 886 } 887 speed = atoi(*arg->argv); 888 if (IntToSpeed(speed) != B0) { 889 VarSpeed = speed; 890 return 0; 891 } 892 LogPrintf(LogWARN, "%s: Invalid speed\n", *arg->argv); 893 } 894 return -1; 895 } 896 897 static int 898 SetReconnect(struct cmdargs const *arg) 899 { 900 if (arg->argc == 2) { 901 VarReconnectTimer = atoi(arg->argv[0]); 902 VarReconnectTries = atoi(arg->argv[1]); 903 return 0; 904 } 905 return -1; 906 } 907 908 static int 909 SetRedialTimeout(struct cmdargs const *arg) 910 { 911 int timeout; 912 int tries; 913 char *dot; 914 915 if (arg->argc == 1 || arg->argc == 2) { 916 if (strncasecmp(arg->argv[0], "random", 6) == 0 && 917 (arg->argv[0][6] == '\0' || arg->argv[0][6] == '.')) { 918 VarRedialTimeout = -1; 919 randinit(); 920 } else { 921 timeout = atoi(arg->argv[0]); 922 923 if (timeout >= 0) 924 VarRedialTimeout = timeout; 925 else { 926 LogPrintf(LogWARN, "Invalid redial timeout\n"); 927 return -1; 928 } 929 } 930 931 dot = strchr(arg->argv[0], '.'); 932 if (dot) { 933 if (strcasecmp(++dot, "random") == 0) { 934 VarRedialNextTimeout = -1; 935 randinit(); 936 } else { 937 timeout = atoi(dot); 938 if (timeout >= 0) 939 VarRedialNextTimeout = timeout; 940 else { 941 LogPrintf(LogWARN, "Invalid next redial timeout\n"); 942 return -1; 943 } 944 } 945 } else 946 VarRedialNextTimeout = NEXT_REDIAL_PERIOD; /* Default next timeout */ 947 948 if (arg->argc == 2) { 949 tries = atoi(arg->argv[1]); 950 951 if (tries >= 0) { 952 VarDialTries = tries; 953 } else { 954 LogPrintf(LogWARN, "Invalid retry value\n"); 955 return 1; 956 } 957 } 958 return 0; 959 } 960 return -1; 961 } 962 963 static int 964 SetStoppedTimeout(struct cmdargs const *arg) 965 { 966 LcpFsm.StoppedTimer.load = 0; 967 IpcpFsm.StoppedTimer.load = 0; 968 CcpFsm.StoppedTimer.load = 0; 969 if (arg->argc <= 3) { 970 if (arg->argc > 0) { 971 LcpFsm.StoppedTimer.load = atoi(arg->argv[0]) * SECTICKS; 972 if (arg->argc > 1) { 973 IpcpFsm.StoppedTimer.load = atoi(arg->argv[1]) * SECTICKS; 974 if (arg->argc > 2) 975 CcpFsm.StoppedTimer.load = atoi(arg->argv[2]) * SECTICKS; 976 } 977 } 978 return 0; 979 } 980 return -1; 981 } 982 983 #define ismask(x) \ 984 (*x == '0' && strlen(x) == 4 && strspn(x+1, "0123456789.") == 3) 985 986 static int 987 SetServer(struct cmdargs const *arg) 988 { 989 int res = -1; 990 991 if (arg->argc > 0 && arg->argc < 4) { 992 const char *port, *passwd, *mask; 993 994 /* What's what ? */ 995 port = arg->argv[0]; 996 if (arg->argc == 2) 997 if (ismask(arg->argv[1])) { 998 passwd = NULL; 999 mask = arg->argv[1]; 1000 } else { 1001 passwd = arg->argv[1]; 1002 mask = NULL; 1003 } 1004 else if (arg->argc == 3) { 1005 passwd = arg->argv[1]; 1006 mask = arg->argv[2]; 1007 if (!ismask(mask)) 1008 return -1; 1009 } else 1010 passwd = mask = NULL; 1011 1012 if (passwd == NULL) 1013 VarHaveLocalAuthKey = 0; 1014 else { 1015 strncpy(VarLocalAuthKey, passwd, sizeof VarLocalAuthKey - 1); 1016 VarLocalAuthKey[sizeof VarLocalAuthKey - 1] = '\0'; 1017 VarHaveLocalAuthKey = 1; 1018 } 1019 LocalAuthInit(); 1020 1021 if (strcasecmp(port, "none") == 0) { 1022 int oserver; 1023 1024 if (mask != NULL || passwd != NULL) 1025 return -1; 1026 oserver = server; 1027 ServerClose(); 1028 if (oserver != -1) 1029 LogPrintf(LogPHASE, "Disabling server port.\n"); 1030 res = 0; 1031 } else if (*port == '/') { 1032 mode_t imask; 1033 1034 if (mask != NULL) { 1035 unsigned m; 1036 1037 if (sscanf(mask, "%o", &m) == 1) 1038 imask = m; 1039 else 1040 return -1; 1041 } else 1042 imask = (mode_t)-1; 1043 res = ServerLocalOpen(port, imask); 1044 } else { 1045 int iport; 1046 1047 if (mask != NULL) 1048 return -1; 1049 1050 if (strspn(port, "0123456789") != strlen(port)) { 1051 struct servent *s; 1052 1053 if ((s = getservbyname(port, "tcp")) == NULL) { 1054 iport = 0; 1055 LogPrintf(LogWARN, "%s: Invalid port or service\n", port); 1056 } else 1057 iport = ntohs(s->s_port); 1058 } else 1059 iport = atoi(port); 1060 res = iport ? ServerTcpOpen(iport) : -1; 1061 } 1062 } 1063 1064 return res; 1065 } 1066 1067 static int 1068 SetModemParity(struct cmdargs const *arg) 1069 { 1070 return arg->argc > 0 ? ChangeParity(*arg->argv) : -1; 1071 } 1072 1073 static int 1074 SetLogLevel(struct cmdargs const *arg) 1075 { 1076 int i; 1077 int res; 1078 int argc; 1079 char const *const *argv, *argp; 1080 void (*Discard)(int), (*Keep)(int); 1081 void (*DiscardAll)(void); 1082 1083 argc = arg->argc; 1084 argv = arg->argv; 1085 res = 0; 1086 if (argc == 0 || strcasecmp(argv[0], "local")) { 1087 Discard = LogDiscard; 1088 Keep = LogKeep; 1089 DiscardAll = LogDiscardAll; 1090 } else { 1091 argc--; 1092 argv++; 1093 Discard = LogDiscardLocal; 1094 Keep = LogKeepLocal; 1095 DiscardAll = LogDiscardAllLocal; 1096 } 1097 1098 if (argc == 0 || (argv[0][0] != '+' && argv[0][0] != '-')) 1099 DiscardAll(); 1100 while (argc--) { 1101 argp = **argv == '+' || **argv == '-' ? *argv + 1 : *argv; 1102 for (i = LogMIN; i <= LogMAX; i++) 1103 if (strcasecmp(argp, LogName(i)) == 0) { 1104 if (**argv == '-') 1105 (*Discard)(i); 1106 else 1107 (*Keep)(i); 1108 break; 1109 } 1110 if (i > LogMAX) { 1111 LogPrintf(LogWARN, "%s: Invalid log value\n", argp); 1112 res = -1; 1113 } 1114 argv++; 1115 } 1116 return res; 1117 } 1118 1119 static int 1120 SetEscape(struct cmdargs const *arg) 1121 { 1122 int code; 1123 int argc = arg->argc; 1124 char const *const *argv = arg->argv; 1125 1126 for (code = 0; code < 33; code++) 1127 EscMap[code] = 0; 1128 1129 while (argc-- > 0) { 1130 sscanf(*argv++, "%x", &code); 1131 code &= 0xff; 1132 EscMap[code >> 3] |= (1 << (code & 7)); 1133 EscMap[32] = 1; 1134 } 1135 return 0; 1136 } 1137 1138 static int 1139 SetInitialMRU(struct cmdargs const *arg) 1140 { 1141 long mru; 1142 const char *err; 1143 1144 if (arg->argc > 0) { 1145 mru = atol(*arg->argv); 1146 if (mru < MIN_MRU) 1147 err = "Given MRU value (%ld) is too small.\n"; 1148 else if (mru > MAX_MRU) 1149 err = "Given MRU value (%ld) is too big.\n"; 1150 else { 1151 VarMRU = mru; 1152 return 0; 1153 } 1154 LogPrintf(LogWARN, err, mru); 1155 } 1156 return -1; 1157 } 1158 1159 static int 1160 SetPreferredMTU(struct cmdargs const *arg) 1161 { 1162 long mtu; 1163 const char *err; 1164 1165 if (arg->argc > 0) { 1166 mtu = atol(*arg->argv); 1167 if (mtu == 0) { 1168 VarPrefMTU = 0; 1169 return 0; 1170 } else if (mtu < MIN_MTU) 1171 err = "Given MTU value (%ld) is too small.\n"; 1172 else if (mtu > MAX_MTU) 1173 err = "Given MTU value (%ld) is too big.\n"; 1174 else { 1175 VarPrefMTU = mtu; 1176 return 0; 1177 } 1178 LogPrintf(LogWARN, err, mtu); 1179 } 1180 return -1; 1181 } 1182 1183 static int 1184 SetIdleTimeout(struct cmdargs const *arg) 1185 { 1186 if (arg->argc > 0) { 1187 VarIdleTimeout = atoi(arg->argv[0]); 1188 UpdateIdleTimer(); /* If we're connected, restart the idle timer */ 1189 if (arg->argc > 1) { 1190 VarLqrTimeout = atoi(arg->argv[1]); 1191 if (VarLqrTimeout < 1) 1192 VarLqrTimeout = 30; 1193 if (arg->argc > 2) { 1194 VarRetryTimeout = atoi(arg->argv[2]); 1195 if (VarRetryTimeout < 1 || VarRetryTimeout > 10) 1196 VarRetryTimeout = 3; 1197 } 1198 } 1199 return 0; 1200 } 1201 return -1; 1202 } 1203 1204 static struct in_addr 1205 GetIpAddr(const char *cp) 1206 { 1207 struct hostent *hp; 1208 struct in_addr ipaddr; 1209 1210 if (inet_aton(cp, &ipaddr) == 0) { 1211 hp = gethostbyname(cp); 1212 if (hp && hp->h_addrtype == AF_INET) 1213 memcpy(&ipaddr, hp->h_addr, hp->h_length); 1214 else 1215 ipaddr.s_addr = 0; 1216 } 1217 return (ipaddr); 1218 } 1219 1220 static int 1221 SetInterfaceAddr(struct cmdargs const *arg) 1222 { 1223 const char *hisaddr; 1224 1225 hisaddr = NULL; 1226 DefMyAddress.ipaddr.s_addr = DefHisAddress.ipaddr.s_addr = 0L; 1227 1228 if (arg->argc > 4) 1229 return -1; 1230 1231 HaveTriggerAddress = 0; 1232 ifnetmask.s_addr = 0; 1233 iplist_reset(&DefHisChoice); 1234 1235 if (arg->argc > 0) { 1236 if (!ParseAddr(arg->argc, arg->argv, &DefMyAddress.ipaddr, 1237 &DefMyAddress.mask, &DefMyAddress.width)) 1238 return 1; 1239 if (arg->argc > 1) { 1240 hisaddr = arg->argv[1]; 1241 if (arg->argc > 2) { 1242 ifnetmask = GetIpAddr(arg->argv[2]); 1243 if (arg->argc > 3) { 1244 TriggerAddress = GetIpAddr(arg->argv[3]); 1245 HaveTriggerAddress = 1; 1246 } 1247 } 1248 } 1249 } 1250 1251 /* 1252 * For backwards compatibility, 0.0.0.0 means any address. 1253 */ 1254 if (DefMyAddress.ipaddr.s_addr == 0) { 1255 DefMyAddress.mask.s_addr = 0; 1256 DefMyAddress.width = 0; 1257 } 1258 IpcpInfo.want_ipaddr.s_addr = DefMyAddress.ipaddr.s_addr; 1259 if (DefHisAddress.ipaddr.s_addr == 0) { 1260 DefHisAddress.mask.s_addr = 0; 1261 DefHisAddress.width = 0; 1262 } 1263 1264 if (hisaddr && !UseHisaddr(hisaddr, mode & MODE_AUTO)) 1265 return 4; 1266 1267 return 0; 1268 } 1269 1270 #ifndef NOMSEXT 1271 1272 static void 1273 SetMSEXT(struct in_addr * pri_addr, 1274 struct in_addr * sec_addr, 1275 int argc, 1276 char const *const *argv) 1277 { 1278 int dummyint; 1279 struct in_addr dummyaddr; 1280 1281 pri_addr->s_addr = sec_addr->s_addr = 0L; 1282 1283 if (argc > 0) { 1284 ParseAddr(argc, argv++, pri_addr, &dummyaddr, &dummyint); 1285 if (--argc > 0) 1286 ParseAddr(argc, argv++, sec_addr, &dummyaddr, &dummyint); 1287 else 1288 sec_addr->s_addr = pri_addr->s_addr; 1289 } 1290 1291 /* 1292 * if the primary/secondary ns entries are 0.0.0.0 we should set them to 1293 * either the localhost's ip, or the values in /etc/resolv.conf ?? 1294 * 1295 * up to you if you want to implement this... 1296 */ 1297 1298 } 1299 1300 static int 1301 SetNS(struct cmdargs const *arg) 1302 { 1303 SetMSEXT(&ns_entries[0], &ns_entries[1], arg->argc, arg->argv); 1304 return 0; 1305 } 1306 1307 static int 1308 SetNBNS(struct cmdargs const *arg) 1309 { 1310 SetMSEXT(&nbns_entries[0], &nbns_entries[1], arg->argc, arg->argv); 1311 return 0; 1312 } 1313 1314 #endif /* MS_EXT */ 1315 1316 int 1317 SetVariable(struct cmdargs const *arg) 1318 { 1319 u_long map; 1320 const char *argp; 1321 int param = (int)arg->data; 1322 1323 if (arg->argc > 0) 1324 argp = *arg->argv; 1325 else 1326 argp = ""; 1327 1328 switch (param) { 1329 case VAR_AUTHKEY: 1330 strncpy(VarAuthKey, argp, sizeof VarAuthKey - 1); 1331 VarAuthKey[sizeof VarAuthKey - 1] = '\0'; 1332 break; 1333 case VAR_AUTHNAME: 1334 strncpy(VarAuthName, argp, sizeof VarAuthName - 1); 1335 VarAuthName[sizeof VarAuthName - 1] = '\0'; 1336 break; 1337 case VAR_DIAL: 1338 strncpy(VarDialScript, argp, sizeof VarDialScript - 1); 1339 VarDialScript[sizeof VarDialScript - 1] = '\0'; 1340 break; 1341 case VAR_LOGIN: 1342 strncpy(VarLoginScript, argp, sizeof VarLoginScript - 1); 1343 VarLoginScript[sizeof VarLoginScript - 1] = '\0'; 1344 break; 1345 case VAR_DEVICE: 1346 if (mode & MODE_INTER) 1347 HangupModem(0); 1348 if (modem != -1) 1349 LogPrintf(LogWARN, "Cannot change device to \"%s\" when \"%s\" is open\n", 1350 argp, VarDevice); 1351 else { 1352 strncpy(VarDeviceList, argp, sizeof VarDeviceList - 1); 1353 VarDeviceList[sizeof VarDeviceList - 1] = '\0'; 1354 } 1355 break; 1356 case VAR_ACCMAP: 1357 sscanf(argp, "%lx", &map); 1358 VarAccmap = map; 1359 break; 1360 case VAR_PHONE: 1361 strncpy(VarPhoneList, argp, sizeof VarPhoneList - 1); 1362 VarPhoneList[sizeof VarPhoneList - 1] = '\0'; 1363 strncpy(VarPhoneCopy, VarPhoneList, sizeof VarPhoneCopy - 1); 1364 VarPhoneCopy[sizeof VarPhoneCopy - 1] = '\0'; 1365 VarNextPhone = VarPhoneCopy; 1366 VarAltPhone = NULL; 1367 break; 1368 case VAR_HANGUP: 1369 strncpy(VarHangupScript, argp, sizeof VarHangupScript - 1); 1370 VarHangupScript[sizeof VarHangupScript - 1] = '\0'; 1371 break; 1372 #ifdef HAVE_DES 1373 case VAR_ENC: 1374 VarMSChap = !strcasecmp(argp, "mschap"); 1375 break; 1376 #endif 1377 } 1378 return 0; 1379 } 1380 1381 static int 1382 SetCtsRts(struct cmdargs const *arg) 1383 { 1384 if (arg->argc > 0) { 1385 if (strcmp(*arg->argv, "on") == 0) 1386 VarCtsRts = 1; 1387 else if (strcmp(*arg->argv, "off") == 0) 1388 VarCtsRts = 0; 1389 else 1390 return -1; 1391 return 0; 1392 } 1393 return -1; 1394 } 1395 1396 1397 static int 1398 SetOpenMode(struct cmdargs const *arg) 1399 { 1400 if (arg->argc > 0) { 1401 if (strcmp(*arg->argv, "active") == 0) 1402 VarOpenMode = OPEN_ACTIVE; 1403 else if (strcmp(*arg->argv, "passive") == 0) 1404 VarOpenMode = OPEN_PASSIVE; 1405 else 1406 return -1; 1407 return 0; 1408 } 1409 return -1; 1410 } 1411 1412 static struct cmdtab const SetCommands[] = { 1413 {"accmap", NULL, SetVariable, LOCAL_AUTH, 1414 "Set accmap value", "set accmap hex-value", (const void *) VAR_ACCMAP}, 1415 {"afilter", NULL, SetAfilter, LOCAL_AUTH, 1416 "Set keep Alive filter", "set afilter ..."}, 1417 {"authkey", "key", SetVariable, LOCAL_AUTH, 1418 "Set authentication key", "set authkey|key key", (const void *) VAR_AUTHKEY}, 1419 {"authname", NULL, SetVariable, LOCAL_AUTH, 1420 "Set authentication name", "set authname name", (const void *) VAR_AUTHNAME}, 1421 {"ctsrts", NULL, SetCtsRts, LOCAL_AUTH, 1422 "Use CTS/RTS modem signalling", "set ctsrts [on|off]"}, 1423 {"device", "line", SetVariable, LOCAL_AUTH, "Set modem device name", 1424 "set device|line device-name[,device-name]", (const void *) VAR_DEVICE}, 1425 {"dfilter", NULL, SetDfilter, LOCAL_AUTH, 1426 "Set demand filter", "set dfilter ..."}, 1427 {"dial", NULL, SetVariable, LOCAL_AUTH, 1428 "Set dialing script", "set dial chat-script", (const void *) VAR_DIAL}, 1429 #ifdef HAVE_DES 1430 {"encrypt", NULL, SetVariable, LOCAL_AUTH, "Set CHAP encryption algorithm", 1431 "set encrypt MSChap|MD5", (const void *) VAR_ENC}, 1432 #endif 1433 {"escape", NULL, SetEscape, LOCAL_AUTH, 1434 "Set escape characters", "set escape hex-digit ..."}, 1435 {"hangup", NULL, SetVariable, LOCAL_AUTH, 1436 "Set hangup script", "set hangup chat-script", (const void *) VAR_HANGUP}, 1437 {"ifaddr", NULL, SetInterfaceAddr, LOCAL_AUTH, "Set destination address", 1438 "set ifaddr [src-addr [dst-addr [netmask [trg-addr]]]]"}, 1439 {"ifilter", NULL, SetIfilter, LOCAL_AUTH, 1440 "Set input filter", "set ifilter ..."}, 1441 {"loopback", NULL, SetLoopback, LOCAL_AUTH, 1442 "Set loopback facility", "set loopback on|off"}, 1443 {"log", NULL, SetLogLevel, LOCAL_AUTH, 1444 "Set log level", "set log [local] [+|-]value..."}, 1445 {"login", NULL, SetVariable, LOCAL_AUTH, 1446 "Set login script", "set login chat-script", (const void *) VAR_LOGIN}, 1447 {"mru", NULL, SetInitialMRU, LOCAL_AUTH, 1448 "Set Initial MRU value", "set mru value"}, 1449 {"mtu", NULL, SetPreferredMTU, LOCAL_AUTH, 1450 "Set Preferred MTU value", "set mtu value"}, 1451 {"ofilter", NULL, SetOfilter, LOCAL_AUTH, 1452 "Set output filter", "set ofilter ..."}, 1453 {"openmode", NULL, SetOpenMode, LOCAL_AUTH, 1454 "Set open mode", "set openmode [active|passive]"}, 1455 {"parity", NULL, SetModemParity, LOCAL_AUTH, 1456 "Set modem parity", "set parity [odd|even|none]"}, 1457 {"phone", NULL, SetVariable, LOCAL_AUTH, "Set telephone number(s)", 1458 "set phone phone1[:phone2[...]]", (const void *) VAR_PHONE}, 1459 {"reconnect", NULL, SetReconnect, LOCAL_AUTH, 1460 "Set Reconnect timeout", "set reconnect value ntries"}, 1461 {"redial", NULL, SetRedialTimeout, LOCAL_AUTH, "Set Redial timeout", 1462 "set redial value|random[.value|random] [dial_attempts]"}, 1463 {"stopped", NULL, SetStoppedTimeout, LOCAL_AUTH, "Set STOPPED timeouts", 1464 "set stopped [LCPseconds [IPCPseconds [CCPseconds]]]"}, 1465 {"server", "socket", SetServer, LOCAL_AUTH, 1466 "Set server port", "set server|socket TcpPort|LocalName|none [mask]"}, 1467 {"speed", NULL, SetModemSpeed, LOCAL_AUTH, 1468 "Set modem speed", "set speed value"}, 1469 {"timeout", NULL, SetIdleTimeout, LOCAL_AUTH, 1470 "Set Idle timeout", "set timeout value"}, 1471 #ifndef NOMSEXT 1472 {"ns", NULL, SetNS, LOCAL_AUTH, 1473 "Set NameServer", "set ns pri-addr [sec-addr]"}, 1474 {"nbns", NULL, SetNBNS, LOCAL_AUTH, 1475 "Set NetBIOS NameServer", "set nbns pri-addr [sec-addr]"}, 1476 #endif 1477 {"help", "?", HelpCommand, LOCAL_AUTH | LOCAL_NO_AUTH, 1478 "Display this message", "set help|? [command]", SetCommands}, 1479 {NULL, NULL, NULL}, 1480 }; 1481 1482 static int 1483 SetCommand(struct cmdargs const *arg) 1484 { 1485 if (arg->argc > 0) 1486 FindExec(SetCommands, arg->argc, arg->argv, "set "); 1487 else if (VarTerm) 1488 fprintf(VarTerm, "Use `set ?' to get a arg->cmd or `set ? <var>' for" 1489 " syntax help.\n"); 1490 else 1491 LogPrintf(LogWARN, "set command must have arguments\n"); 1492 1493 return 0; 1494 } 1495 1496 1497 static int 1498 AddCommand(struct cmdargs const *arg) 1499 { 1500 struct in_addr dest, gateway, netmask; 1501 int gw; 1502 1503 if (arg->argc != 3 && arg->argc != 2) 1504 return -1; 1505 1506 if (arg->argc == 2) 1507 if (strcasecmp(arg->argv[0], "default")) 1508 return -1; 1509 else { 1510 dest.s_addr = netmask.s_addr = INADDR_ANY; 1511 gw = 1; 1512 } 1513 else { 1514 if (strcasecmp(arg->argv[0], "MYADDR") == 0) 1515 dest = IpcpInfo.want_ipaddr; 1516 else if (strcasecmp(arg->argv[0], "HISADDR") == 0) 1517 dest = IpcpInfo.his_ipaddr; 1518 else 1519 dest = GetIpAddr(arg->argv[0]); 1520 netmask = GetIpAddr(arg->argv[1]); 1521 gw = 2; 1522 } 1523 if (strcasecmp(arg->argv[gw], "HISADDR") == 0) 1524 gateway = IpcpInfo.his_ipaddr; 1525 else if (strcasecmp(arg->argv[gw], "INTERFACE") == 0) 1526 gateway.s_addr = INADDR_ANY; 1527 else 1528 gateway = GetIpAddr(arg->argv[gw]); 1529 OsSetRoute(RTM_ADD, dest, gateway, netmask, arg->data ? 1 : 0); 1530 return 0; 1531 } 1532 1533 static int 1534 DeleteCommand(struct cmdargs const *arg) 1535 { 1536 struct in_addr dest, none; 1537 1538 if (arg->argc == 1) 1539 if(strcasecmp(arg->argv[0], "all") == 0) 1540 DeleteIfRoutes(0); 1541 else { 1542 if (strcasecmp(arg->argv[0], "MYADDR") == 0) 1543 dest = IpcpInfo.want_ipaddr; 1544 else if (strcasecmp(arg->argv[0], "default") == 0) 1545 dest.s_addr = INADDR_ANY; 1546 else 1547 dest = GetIpAddr(arg->argv[0]); 1548 none.s_addr = INADDR_ANY; 1549 OsSetRoute(RTM_DELETE, dest, none, none, arg->data ? 1 : 0); 1550 } 1551 else 1552 return -1; 1553 1554 return 0; 1555 } 1556 1557 #ifndef NOALIAS 1558 static struct cmdtab const AliasCommands[] = 1559 { 1560 {"enable", NULL, AliasEnable, LOCAL_AUTH, 1561 "enable IP aliasing", "alias enable [yes|no]"}, 1562 {"port", NULL, AliasRedirectPort, LOCAL_AUTH, 1563 "port redirection", "alias port [proto addr_local:port_local port_alias]"}, 1564 {"addr", NULL, AliasRedirectAddr, LOCAL_AUTH, 1565 "static address translation", "alias addr [addr_local addr_alias]"}, 1566 {"deny_incoming", NULL, AliasOption, LOCAL_AUTH, 1567 "stop incoming connections", "alias deny_incoming [yes|no]", 1568 (const void *) PKT_ALIAS_DENY_INCOMING}, 1569 {"log", NULL, AliasOption, LOCAL_AUTH, 1570 "log aliasing link creation", "alias log [yes|no]", 1571 (const void *) PKT_ALIAS_LOG}, 1572 {"same_ports", NULL, AliasOption, LOCAL_AUTH, 1573 "try to leave port numbers unchanged", "alias same_ports [yes|no]", 1574 (const void *) PKT_ALIAS_SAME_PORTS}, 1575 {"use_sockets", NULL, AliasOption, LOCAL_AUTH, 1576 "allocate host sockets", "alias use_sockets [yes|no]", 1577 (const void *) PKT_ALIAS_USE_SOCKETS}, 1578 {"unregistered_only", NULL, AliasOption, LOCAL_AUTH, 1579 "alias unregistered (private) IP address space only", 1580 "alias unregistered_only [yes|no]", 1581 (const void *) PKT_ALIAS_UNREGISTERED_ONLY}, 1582 {"help", "?", HelpCommand, LOCAL_AUTH | LOCAL_NO_AUTH, 1583 "Display this message", "alias help|? [command]", AliasCommands}, 1584 {NULL, NULL, NULL}, 1585 }; 1586 1587 1588 static int 1589 AliasCommand(struct cmdargs const *arg) 1590 { 1591 if (arg->argc > 0) 1592 FindExec(AliasCommands, arg->argc, arg->argv, "alias "); 1593 else if (VarTerm) 1594 fprintf(VarTerm, "Use `alias help' to get a arg->cmd or `alias help <option>'" 1595 " for syntax help.\n"); 1596 else 1597 LogPrintf(LogWARN, "alias command must have arguments\n"); 1598 1599 return 0; 1600 } 1601 1602 static int 1603 AliasEnable(struct cmdargs const *arg) 1604 { 1605 if (arg->argc == 1) 1606 if (strcasecmp(arg->argv[0], "yes") == 0) { 1607 if (!(mode & MODE_ALIAS)) { 1608 if (loadAliasHandlers(&VarAliasHandlers) == 0) { 1609 mode |= MODE_ALIAS; 1610 return 0; 1611 } 1612 LogPrintf(LogWARN, "Cannot load alias library\n"); 1613 return 1; 1614 } 1615 return 0; 1616 } else if (strcasecmp(arg->argv[0], "no") == 0) { 1617 if (mode & MODE_ALIAS) { 1618 unloadAliasHandlers(); 1619 mode &= ~MODE_ALIAS; 1620 } 1621 return 0; 1622 } 1623 return -1; 1624 } 1625 1626 1627 static int 1628 AliasOption(struct cmdargs const *arg) 1629 { 1630 unsigned param = (unsigned)arg->data; 1631 if (arg->argc == 1) 1632 if (strcasecmp(arg->argv[0], "yes") == 0) { 1633 if (mode & MODE_ALIAS) { 1634 VarPacketAliasSetMode(param, param); 1635 return 0; 1636 } 1637 LogPrintf(LogWARN, "alias not enabled\n"); 1638 } else if (strcmp(arg->argv[0], "no") == 0) { 1639 if (mode & MODE_ALIAS) { 1640 VarPacketAliasSetMode(0, param); 1641 return 0; 1642 } 1643 LogPrintf(LogWARN, "alias not enabled\n"); 1644 } 1645 return -1; 1646 } 1647 #endif /* #ifndef NOALIAS */ 1648 1649 static struct cmdtab const AllowCommands[] = { 1650 {"users", "user", AllowUsers, LOCAL_AUTH, 1651 "Allow users access to ppp", "allow users logname..."}, 1652 {"modes", "mode", AllowModes, LOCAL_AUTH, 1653 "Only allow certain ppp modes", "allow modes mode..."}, 1654 {"help", "?", HelpCommand, LOCAL_AUTH | LOCAL_NO_AUTH, 1655 "Display this message", "allow help|? [command]", AllowCommands}, 1656 {NULL, NULL, NULL}, 1657 }; 1658 1659 static int 1660 AllowCommand(struct cmdargs const *arg) 1661 { 1662 if (arg->argc > 0) 1663 FindExec(AllowCommands, arg->argc, arg->argv, "allow "); 1664 else if (VarTerm) 1665 fprintf(VarTerm, "Use `allow ?' to get a arg->cmd or `allow ? <cmd>' for" 1666 " syntax help.\n"); 1667 else 1668 LogPrintf(LogWARN, "allow command must have arguments\n"); 1669 1670 return 0; 1671 } 1672