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