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