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