command.c revision 29549
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.81 1997/09/16 23:15:11 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 55extern void Cleanup(), TtyTermMode(), PacketMode(); 56extern int EnableCommand(), DisableCommand(), DisplayCommand(); 57extern int AcceptCommand(), DenyCommand(); 58static int AliasCommand(); 59extern int LocalAuthCommand(); 60extern int LoadCommand(), SaveCommand(); 61extern int ChangeParity(char *); 62extern int SelectSystem(); 63extern int ShowRoute(); 64extern void TtyOldMode(), TtyCommandMode(); 65extern struct pppvars pppVars; 66extern struct cmdtab const SetCommands[]; 67 68extern char *IfDevName; 69 70struct in_addr ifnetmask; 71int randinit; 72 73static int ShowCommand(struct cmdtab const *, int, char **); 74static int TerminalCommand(struct cmdtab const *, int, char **); 75static int QuitCommand(struct cmdtab const *, int, char **); 76static int CloseCommand(struct cmdtab const *, int, char **); 77static int DialCommand(struct cmdtab const *, int, char **); 78static int DownCommand(struct cmdtab const *, int, char **); 79static int SetCommand(struct cmdtab const *, int, char **); 80static int AddCommand(struct cmdtab const *, int, char **); 81static int DeleteCommand(struct cmdtab const *, int, char **); 82static int BgShellCommand(struct cmdtab const *, int, char **); 83static int FgShellCommand(struct cmdtab const *, int, char **); 84static int ShellCommand(struct cmdtab const *, int, char **, int); 85 86static int 87HelpCommand(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 118int 119IsInteractive() 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 141static int 142DialCommand(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 181static int 182SetLoopback(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 192static int 193BgShellCommand(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 200static int 201FgShellCommand(struct cmdtab const * cmdlist, int argc, char **argv) 202{ 203 return ShellCommand(cmdlist, argc, argv, 0); 204} 205 206static int 207ShellCommand(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 324struct 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 statictics", "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 370extern int ReportCcpStatus(); 371extern int ReportLcpStatus(); 372extern int ReportIpcpStatus(); 373extern int ReportProtStatus(); 374extern int ReportCompress(); 375extern int ShowModemStatus(); 376extern int ReportHdlcStatus(); 377extern int ShowMemMap(); 378 379static int 380ShowLoopback() 381{ 382 if (VarTerm) 383 fprintf(VarTerm, "Local loopback is %s\n", VarLoopback ? "on" : "off"); 384 385 return 0; 386} 387 388static int 389ShowLogLevel() 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 405static int 406ShowEscape() 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 423static int 424ShowTimeout() 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 434static int 435ShowStopped() 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 463static int 464ShowAuthKey() 465{ 466 if (!VarTerm) 467 return 0; 468 fprintf(VarTerm, "AuthName = %s\n", VarAuthName); 469 fprintf(VarTerm, "AuthKey = %s\n", VarAuthKey); 470 fprintf(VarTerm, "Encrypt = %s\n", VarEncMD4 ? "MD4" : "MD5" ); 471 return 1; 472} 473 474static int 475ShowVersion() 476{ 477 extern char VarVersion[]; 478 extern char VarLocalVersion[]; 479 480 if (!VarTerm) 481 return 0; 482 fprintf(VarTerm, "%s - %s \n", VarVersion, VarLocalVersion); 483 return 1; 484} 485 486static int 487ShowInitialMRU() 488{ 489 if (!VarTerm) 490 return 0; 491 fprintf(VarTerm, " Initial MRU: %ld\n", VarMRU); 492 return 1; 493} 494 495static int 496ShowPreferredMTU() 497{ 498 if (!VarTerm) 499 return 0; 500 if (VarPrefMTU) 501 fprintf(VarTerm, " Preferred MTU: %ld\n", VarPrefMTU); 502 else 503 fprintf(VarTerm, " Preferred MTU: unspecified\n"); 504 return 1; 505} 506 507static int 508ShowReconnect() 509{ 510 if (!VarTerm) 511 return 0; 512 fprintf(VarTerm, " Reconnect Timer: %d, %d tries\n", 513 VarReconnectTimer, VarReconnectTries); 514 return 1; 515} 516 517static int 518ShowRedial() 519{ 520 if (!VarTerm) 521 return 0; 522 fprintf(VarTerm, " Redial Timer: "); 523 524 if (VarRedialTimeout >= 0) { 525 fprintf(VarTerm, " %d seconds, ", VarRedialTimeout); 526 } else { 527 fprintf(VarTerm, " Random 0 - %d seconds, ", REDIAL_PERIOD); 528 } 529 530 fprintf(VarTerm, " Redial Next Timer: "); 531 532 if (VarRedialNextTimeout >= 0) { 533 fprintf(VarTerm, " %d seconds, ", VarRedialNextTimeout); 534 } else { 535 fprintf(VarTerm, " Random 0 - %d seconds, ", REDIAL_PERIOD); 536 } 537 538 if (VarDialTries) 539 fprintf(VarTerm, "%d dial tries", VarDialTries); 540 541 fprintf(VarTerm, "\n"); 542 543 return 1; 544} 545 546#ifndef NOMSEXT 547static int 548ShowMSExt() 549{ 550 if (!VarTerm) 551 return 0; 552 fprintf(VarTerm, " MS PPP extention values \n"); 553 fprintf(VarTerm, " Primary NS : %s\n", inet_ntoa(ns_entries[0])); 554 fprintf(VarTerm, " Secondary NS : %s\n", inet_ntoa(ns_entries[1])); 555 fprintf(VarTerm, " Primary NBNS : %s\n", inet_ntoa(nbns_entries[0])); 556 fprintf(VarTerm, " Secondary NBNS : %s\n", inet_ntoa(nbns_entries[1])); 557 return 1; 558} 559 560#endif 561 562extern int ShowIfilter(), ShowOfilter(), ShowDfilter(), ShowAfilter(); 563 564struct cmdtab const ShowCommands[] = { 565 {"afilter", NULL, ShowAfilter, LOCAL_AUTH, 566 "Show keep Alive filters", "show afilter option .."}, 567 {"auth", NULL, ShowAuthKey, LOCAL_AUTH, 568 "Show auth name, key and algorithm", "show auth"}, 569 {"ccp", NULL, ReportCcpStatus, LOCAL_AUTH, 570 "Show CCP status", "show cpp"}, 571 {"compress", NULL, ReportCompress, LOCAL_AUTH, 572 "Show compression statictics", "show compress"}, 573 {"dfilter", NULL, ShowDfilter, LOCAL_AUTH, 574 "Show Demand filters", "show dfilteroption .."}, 575 {"escape", NULL, ShowEscape, LOCAL_AUTH, 576 "Show escape characters", "show escape"}, 577 {"hdlc", NULL, ReportHdlcStatus, LOCAL_AUTH, 578 "Show HDLC error summary", "show hdlc"}, 579 {"ifilter", NULL, ShowIfilter, LOCAL_AUTH, 580 "Show Input filters", "show ifilter option .."}, 581 {"ipcp", NULL, ReportIpcpStatus, LOCAL_AUTH, 582 "Show IPCP status", "show ipcp"}, 583 {"lcp", NULL, ReportLcpStatus, LOCAL_AUTH, 584 "Show LCP status", "show lcp"}, 585 {"loopback", NULL, ShowLoopback, LOCAL_AUTH, 586 "Show current loopback setting", "show loopback"}, 587 {"log", NULL, ShowLogLevel, LOCAL_AUTH, 588 "Show current log level", "show log"}, 589 {"mem", NULL, ShowMemMap, LOCAL_AUTH, 590 "Show memory map", "show mem"}, 591 {"modem", NULL, ShowModemStatus, LOCAL_AUTH, 592 "Show modem setups", "show modem"}, 593 {"mru", NULL, ShowInitialMRU, LOCAL_AUTH, 594 "Show Initial MRU", "show mru"}, 595 {"mtu", NULL, ShowPreferredMTU, LOCAL_AUTH, 596 "Show Preferred MTU", "show mtu"}, 597 {"ofilter", NULL, ShowOfilter, LOCAL_AUTH, 598 "Show Output filters", "show ofilter option .."}, 599 {"proto", NULL, ReportProtStatus, LOCAL_AUTH, 600 "Show protocol summary", "show proto"}, 601 {"reconnect", NULL, ShowReconnect, LOCAL_AUTH, 602 "Show Reconnect timer,tries", "show reconnect"}, 603 {"redial", NULL, ShowRedial, LOCAL_AUTH, 604 "Show Redial timeout value", "show redial"}, 605 {"route", NULL, ShowRoute, LOCAL_AUTH, 606 "Show routing table", "show route"}, 607 {"timeout", NULL, ShowTimeout, LOCAL_AUTH, 608 "Show Idle timeout value", "show timeout"}, 609 {"stopped", NULL, ShowStopped, LOCAL_AUTH, 610 "Show STOPPED timeout value", "show stopped"}, 611#ifndef NOMSEXT 612 {"msext", NULL, ShowMSExt, LOCAL_AUTH, 613 "Show MS PPP extentions", "show msext"}, 614#endif 615 {"version", NULL, ShowVersion, LOCAL_NO_AUTH | LOCAL_AUTH, 616 "Show version string", "show version"}, 617 {"help", "?", HelpCommand, LOCAL_NO_AUTH | LOCAL_AUTH, 618 "Display this message", "show help|? [command]", (void *) ShowCommands}, 619 {NULL, NULL, NULL}, 620}; 621 622struct cmdtab const * 623FindCommand(struct cmdtab const * cmds, char *str, int *pmatch) 624{ 625 int nmatch; 626 int len; 627 struct cmdtab const *found; 628 629 found = NULL; 630 len = strlen(str); 631 nmatch = 0; 632 while (cmds->func) { 633 if (cmds->name && strncasecmp(str, cmds->name, len) == 0) { 634 if (cmds->name[len] == '\0') { 635 *pmatch = 1; 636 return cmds; 637 } 638 nmatch++; 639 found = cmds; 640 } else if (cmds->alias && strncasecmp(str, cmds->alias, len) == 0) { 641 if (cmds->alias[len] == '\0') { 642 *pmatch = 1; 643 return cmds; 644 } 645 nmatch++; 646 found = cmds; 647 } 648 cmds++; 649 } 650 *pmatch = nmatch; 651 return found; 652} 653 654int 655FindExec(struct cmdtab const * cmdlist, int argc, char **argv) 656{ 657 struct cmdtab const *cmd; 658 int val = 1; 659 int nmatch; 660 661 cmd = FindCommand(cmdlist, *argv, &nmatch); 662 if (nmatch > 1) 663 LogPrintf(LogWARN, "%s: Ambiguous command\n", *argv); 664 else if (cmd && (cmd->lauth & VarLocalAuth)) 665 val = (cmd->func) (cmd, argc-1, argv+1, cmd->args); 666 else 667 LogPrintf(LogWARN, "%s: Invalid command\n", *argv); 668 669 if (val == -1) 670 LogPrintf(LogWARN, "Usage: %s\n", cmd->syntax); 671 else if (val) 672 LogPrintf(LogCOMMAND, "%s: Failed %d\n", *argv, val); 673 674 return val; 675} 676 677int aft_cmd = 1; 678extern int TermMode; 679 680void 681Prompt() 682{ 683 char *pconnect, *pauth; 684 685 if (!(mode & MODE_INTER) || !VarTerm || TermMode) 686 return; 687 688 if (!aft_cmd) 689 fprintf(VarTerm, "\n"); 690 else 691 aft_cmd = 0; 692 693 if (VarLocalAuth == LOCAL_AUTH) 694 pauth = " ON "; 695 else 696 pauth = " on "; 697 if (IpcpFsm.state == ST_OPENED && phase == PHASE_NETWORK) 698 pconnect = "PPP"; 699 else 700 pconnect = "ppp"; 701 fprintf(VarTerm, "%s%s%s> ", pconnect, pauth, VarShortHost); 702 fflush(VarTerm); 703} 704 705void 706DecodeCommand(char *buff, int nb, int prompt) 707{ 708 char *vector[20]; 709 char **argv; 710 int argc; 711 char *cp; 712 713 if (nb > 0) { 714 cp = buff + strcspn(buff, "\r\n"); 715 if (cp) 716 *cp = '\0'; 717 argc = MakeArgs(buff, vector, VECSIZE(vector)); 718 argv = vector; 719 720 if (argc > 0) 721 FindExec(Commands, argc, argv); 722 } 723 if (prompt) 724 Prompt(); 725} 726 727static int 728ShowCommand(struct cmdtab const * list, int argc, char **argv) 729{ 730 if (argc > 0) 731 FindExec(ShowCommands, argc, argv); 732 else if (VarTerm) 733 fprintf(VarTerm, "Use ``show ?'' to get a list.\n"); 734 else 735 LogPrintf(LogWARN, "show command must have arguments\n"); 736 737 return 0; 738} 739 740static int 741TerminalCommand(struct cmdtab const * list, int argc, char **argv) 742{ 743 if (LcpFsm.state > ST_CLOSED) { 744 if (VarTerm) 745 fprintf(VarTerm, "LCP state is [%s]\n", StateNames[LcpFsm.state]); 746 return 1; 747 } 748 if (!IsInteractive()) 749 return (1); 750 if (OpenModem(mode) < 0) { 751 if (VarTerm) 752 fprintf(VarTerm, "Failed to open modem.\n"); 753 return (1); 754 } 755 if (VarTerm) { 756 fprintf(VarTerm, "Enter to terminal mode.\n"); 757 fprintf(VarTerm, "Type `~?' for help.\n"); 758 } 759 TtyTermMode(); 760 return (0); 761} 762 763static int 764QuitCommand(struct cmdtab const * list, int argc, char **argv) 765{ 766 FILE *oVarTerm; 767 768 if (mode & (MODE_DIRECT | MODE_DEDICATED | MODE_AUTO)) { 769 if (argc > 0 && !strcasecmp(*argv, "all") && (VarLocalAuth & LOCAL_AUTH)) { 770 mode &= ~MODE_INTER; 771 oVarTerm = VarTerm; 772 VarTerm = 0; 773 if (oVarTerm && oVarTerm != stdout) 774 fclose(oVarTerm); 775 Cleanup(EX_NORMAL); 776 } else if (VarTerm) { 777 LogPrintf(LogPHASE, "Client connection closed.\n"); 778 VarLocalAuth = LOCAL_NO_AUTH; 779 mode &= ~MODE_INTER; 780 oVarTerm = VarTerm; 781 VarTerm = 0; 782 if (oVarTerm && oVarTerm != stdout) 783 fclose(oVarTerm); 784 close(netfd); 785 netfd = -1; 786 } 787 } else 788 Cleanup(EX_NORMAL); 789 790 return 0; 791} 792 793static int 794CloseCommand(struct cmdtab const * list, int argc, char **argv) 795{ 796 reconnect(RECON_FALSE); 797 LcpClose(); 798 if (mode & MODE_BACKGROUND) 799 Cleanup(EX_NORMAL); 800 return 0; 801} 802 803static int 804DownCommand(struct cmdtab const * list, int argc, char **argv) 805{ 806 LcpDown(); 807 return 0; 808} 809 810static int 811SetModemSpeed(struct cmdtab const * list, int argc, char **argv) 812{ 813 int speed; 814 815 if (argc > 0) { 816 if (strcasecmp(*argv, "sync") == 0) { 817 VarSpeed = 0; 818 return 0; 819 } 820 speed = atoi(*argv); 821 if (IntToSpeed(speed) != B0) { 822 VarSpeed = speed; 823 return 0; 824 } 825 LogPrintf(LogWARN, "%s: Invalid speed\n", *argv); 826 } 827 return -1; 828} 829 830static int 831SetReconnect(struct cmdtab const * list, int argc, char **argv) 832{ 833 if (argc == 2) { 834 VarReconnectTimer = atoi(argv[0]); 835 VarReconnectTries = atoi(argv[1]); 836 return 0; 837 } 838 return -1; 839} 840 841static int 842SetRedialTimeout(struct cmdtab const * list, int argc, char **argv) 843{ 844 int timeout; 845 int tries; 846 char *dot; 847 848 if (argc == 1 || argc == 2) { 849 if (strncasecmp(argv[0], "random", 6) == 0 && 850 (argv[0][6] == '\0' || argv[0][6] == '.')) { 851 VarRedialTimeout = -1; 852 if (!randinit) { 853 randinit = 1; 854 srandomdev(); 855 } 856 } else { 857 timeout = atoi(argv[0]); 858 859 if (timeout >= 0) 860 VarRedialTimeout = timeout; 861 else { 862 LogPrintf(LogWARN, "Invalid redial timeout\n"); 863 return -1; 864 } 865 } 866 867 dot = index(argv[0], '.'); 868 if (dot) { 869 if (strcasecmp(++dot, "random") == 0) { 870 VarRedialNextTimeout = -1; 871 if (!randinit) { 872 randinit = 1; 873 srandomdev(); 874 } 875 } else { 876 timeout = atoi(dot); 877 if (timeout >= 0) 878 VarRedialNextTimeout = timeout; 879 else { 880 LogPrintf(LogWARN, "Invalid next redial timeout\n"); 881 return -1; 882 } 883 } 884 } else 885 VarRedialNextTimeout = NEXT_REDIAL_PERIOD; /* Default next timeout */ 886 887 if (argc == 2) { 888 tries = atoi(argv[1]); 889 890 if (tries >= 0) { 891 VarDialTries = tries; 892 } else { 893 LogPrintf(LogWARN, "Invalid retry value\n"); 894 return 1; 895 } 896 } 897 return 0; 898 } 899 return -1; 900} 901 902static int 903SetStoppedTimeout(struct cmdtab const * list, int argc, char **argv) 904{ 905 LcpFsm.StoppedTimer.load = 0; 906 IpcpFsm.StoppedTimer.load = 0; 907 CcpFsm.StoppedTimer.load = 0; 908 if (argc <= 3) { 909 if (argc > 0) { 910 LcpFsm.StoppedTimer.load = atoi(argv[0]) * SECTICKS; 911 if (argc > 1) { 912 IpcpFsm.StoppedTimer.load = atoi(argv[1]) * SECTICKS; 913 if (argc > 2) 914 CcpFsm.StoppedTimer.load = atoi(argv[2]) * SECTICKS; 915 } 916 } 917 return 0; 918 } 919 return -1; 920} 921 922static int 923SetServer(struct cmdtab const * list, int argc, char **argv) 924{ 925 int res = -1; 926 927 if (argc > 0 && argc < 3) 928 if (strcasecmp(argv[0], "none") == 0) { 929 ServerClose(); 930 LogPrintf(LogPHASE, "Disabling server port.\n"); 931 res = 0; 932 } else if (*argv[0] == '/') { 933 mode_t mask; 934 935 umask(mask = umask(0)); 936 if (argc == 2) { 937 unsigned m; 938 939 if (sscanf(argv[1], "%o", &m) == 1) 940 mask = m; 941 } 942 res = ServerLocalOpen(argv[0], mask); 943 } else { 944 int port; 945 946 if (strspn(argv[0], "0123456789") != strlen(argv[0])) { 947 struct servent *s; 948 949 if ((s = getservbyname(argv[0], "tcp")) == NULL) { 950 port = 0; 951 LogPrintf(LogWARN, "%s: Invalid port or service\n", argv[0]); 952 } else 953 port = ntohs(s->s_port); 954 } else 955 port = atoi(argv[0]); 956 if (port) 957 res = ServerTcpOpen(port); 958 } 959 960 return res; 961} 962 963static int 964SetModemParity(struct cmdtab const * list, int argc, char **argv) 965{ 966 return argc > 0 ? ChangeParity(*argv) : -1; 967} 968 969static int 970SetLogLevel(struct cmdtab const * list, int argc, char **argv) 971{ 972 int i; 973 int res; 974 char *arg; 975 976 res = 0; 977 if (argc == 0 || (argv[0][0] != '+' && argv[0][0] != '-')) 978 LogDiscardAll(); 979 while (argc--) { 980 arg = **argv == '+' || **argv == '-' ? *argv + 1 : *argv; 981 for (i = LogMIN; i <= LogMAX; i++) 982 if (strcasecmp(arg, LogName(i)) == 0) { 983 if (**argv == '-') 984 LogDiscard(i); 985 else 986 LogKeep(i); 987 break; 988 } 989 if (i > LogMAX) { 990 LogPrintf(LogWARN, "%s: Invalid log value\n", arg); 991 res = -1; 992 } 993 argv++; 994 } 995 return res; 996} 997 998static int 999SetEscape(struct cmdtab const * list, int argc, char **argv) 1000{ 1001 int code; 1002 1003 for (code = 0; code < 33; code++) 1004 EscMap[code] = 0; 1005 while (argc-- > 0) { 1006 sscanf(*argv++, "%x", &code); 1007 code &= 0xff; 1008 EscMap[code >> 3] |= (1 << (code & 7)); 1009 EscMap[32] = 1; 1010 } 1011 return 0; 1012} 1013 1014static int 1015SetInitialMRU(struct cmdtab const * list, int argc, char **argv) 1016{ 1017 long mru; 1018 char *err; 1019 1020 if (argc > 0) { 1021 mru = atol(*argv); 1022 if (mru < MIN_MRU) 1023 err = "Given MRU value (%ld) is too small.\n"; 1024 else if (mru > MAX_MRU) 1025 err = "Given MRU value (%ld) is too big.\n"; 1026 else { 1027 VarMRU = mru; 1028 return 0; 1029 } 1030 LogPrintf(LogWARN, err, mru); 1031 } 1032 return -1; 1033} 1034 1035static int 1036SetPreferredMTU(struct cmdtab const * list, int argc, char **argv) 1037{ 1038 long mtu; 1039 char *err; 1040 1041 if (argc > 0) { 1042 mtu = atol(*argv); 1043 if (mtu == 0) { 1044 VarPrefMTU = 0; 1045 return 0; 1046 } else if (mtu < MIN_MTU) 1047 err = "Given MTU value (%ld) is too small.\n"; 1048 else if (mtu > MAX_MTU) 1049 err = "Given MTU value (%ld) is too big.\n"; 1050 else { 1051 VarPrefMTU = mtu; 1052 return 0; 1053 } 1054 LogPrintf(LogWARN, err, mtu); 1055 } 1056 return -1; 1057} 1058 1059static int 1060SetIdleTimeout(struct cmdtab const * list, int argc, char **argv) 1061{ 1062 if (argc-- > 0) { 1063 VarIdleTimeout = atoi(*argv++); 1064 UpdateIdleTimer(); /* If we're connected, restart the idle timer */ 1065 if (argc-- > 0) { 1066 VarLqrTimeout = atoi(*argv++); 1067 if (VarLqrTimeout < 1) 1068 VarLqrTimeout = 30; 1069 if (argc > 0) { 1070 VarRetryTimeout = atoi(*argv); 1071 if (VarRetryTimeout < 1 || VarRetryTimeout > 10) 1072 VarRetryTimeout = 3; 1073 } 1074 } 1075 return 0; 1076 } 1077 return -1; 1078} 1079 1080struct in_addr 1081GetIpAddr(char *cp) 1082{ 1083 struct hostent *hp; 1084 struct in_addr ipaddr; 1085 1086 hp = gethostbyname(cp); 1087 if (hp && hp->h_addrtype == AF_INET) 1088 bcopy(hp->h_addr, &ipaddr, hp->h_length); 1089 else if (inet_aton(cp, &ipaddr) == 0) 1090 ipaddr.s_addr = 0; 1091 return (ipaddr); 1092} 1093 1094static int 1095SetInterfaceAddr(struct cmdtab const * list, int argc, char **argv) 1096{ 1097 DefMyAddress.ipaddr.s_addr = DefHisAddress.ipaddr.s_addr = 0L; 1098 1099 if (argc > 4) 1100 return -1; 1101 1102 HaveTriggerAddress = 0; 1103 ifnetmask.s_addr = 0; 1104 1105 if (argc > 0) { 1106 if (ParseAddr(argc, argv++, 1107 &DefMyAddress.ipaddr, 1108 &DefMyAddress.mask, 1109 &DefMyAddress.width) == 0) 1110 return 1; 1111 if (--argc > 0) { 1112 if (ParseAddr(argc, argv++, 1113 &DefHisAddress.ipaddr, 1114 &DefHisAddress.mask, 1115 &DefHisAddress.width) == 0) 1116 return 2; 1117 if (--argc > 0) { 1118 ifnetmask = GetIpAddr(*argv); 1119 if (--argc > 0) { 1120 TriggerAddress = GetIpAddr(*argv); 1121 HaveTriggerAddress = 1; 1122 } 1123 } 1124 } 1125 } 1126 1127 /* 1128 * For backwards compatibility, 0.0.0.0 means any address. 1129 */ 1130 if (DefMyAddress.ipaddr.s_addr == 0) { 1131 DefMyAddress.mask.s_addr = 0; 1132 DefMyAddress.width = 0; 1133 } 1134 if (DefHisAddress.ipaddr.s_addr == 0) { 1135 DefHisAddress.mask.s_addr = 0; 1136 DefHisAddress.width = 0; 1137 } 1138 IpcpInfo.want_ipaddr.s_addr = DefMyAddress.ipaddr.s_addr; 1139 IpcpInfo.his_ipaddr.s_addr = DefHisAddress.ipaddr.s_addr; 1140 1141 if ((mode & MODE_AUTO) || 1142 ((mode & MODE_DEDICATED) && dstsystem)) { 1143 if (OsSetIpaddress(DefMyAddress.ipaddr, DefHisAddress.ipaddr, ifnetmask) < 0) 1144 return 4; 1145 } 1146 return 0; 1147} 1148 1149#ifndef NOMSEXT 1150 1151void 1152SetMSEXT(struct in_addr * pri_addr, 1153 struct in_addr * sec_addr, 1154 int argc, 1155 char **argv) 1156{ 1157 int dummyint; 1158 struct in_addr dummyaddr; 1159 1160 pri_addr->s_addr = sec_addr->s_addr = 0L; 1161 1162 if (argc > 0) { 1163 ParseAddr(argc, argv++, pri_addr, &dummyaddr, &dummyint); 1164 if (--argc > 0) 1165 ParseAddr(argc, argv++, sec_addr, &dummyaddr, &dummyint); 1166 else 1167 sec_addr->s_addr = pri_addr->s_addr; 1168 } 1169 1170 /* 1171 * if the primary/secondary ns entries are 0.0.0.0 we should set them to 1172 * either the localhost's ip, or the values in /etc/resolv.conf ?? 1173 * 1174 * up to you if you want to implement this... 1175 */ 1176 1177} 1178 1179static int 1180SetNS(struct cmdtab const * list, int argc, char **argv) 1181{ 1182 SetMSEXT(&ns_entries[0], &ns_entries[1], argc, argv); 1183 return 0; 1184} 1185 1186static int 1187SetNBNS(struct cmdtab const * list, int argc, char **argv) 1188{ 1189 SetMSEXT(&nbns_entries[0], &nbns_entries[1], argc, argv); 1190 return 0; 1191} 1192 1193#endif /* MS_EXT */ 1194 1195#define VAR_AUTHKEY 0 1196#define VAR_DIAL 1 1197#define VAR_LOGIN 2 1198#define VAR_AUTHNAME 3 1199#define VAR_DEVICE 4 1200#define VAR_ACCMAP 5 1201#define VAR_PHONE 6 1202#define VAR_HANGUP 7 1203#define VAR_ENC 8 1204 1205static int 1206SetVariable(struct cmdtab const * list, int argc, char **argv, int param) 1207{ 1208 u_long map; 1209 char *arg; 1210 1211 if (argc > 0) 1212 arg = *argv; 1213 else 1214 arg = ""; 1215 1216 switch (param) { 1217 case VAR_AUTHKEY: 1218 strncpy(VarAuthKey, arg, sizeof(VarAuthKey) - 1); 1219 VarAuthKey[sizeof(VarAuthKey) - 1] = '\0'; 1220 break; 1221 case VAR_AUTHNAME: 1222 strncpy(VarAuthName, arg, sizeof(VarAuthName) - 1); 1223 VarAuthName[sizeof(VarAuthName) - 1] = '\0'; 1224 break; 1225 case VAR_DIAL: 1226 strncpy(VarDialScript, arg, sizeof(VarDialScript) - 1); 1227 VarDialScript[sizeof(VarDialScript) - 1] = '\0'; 1228 break; 1229 case VAR_LOGIN: 1230 strncpy(VarLoginScript, arg, sizeof(VarLoginScript) - 1); 1231 VarLoginScript[sizeof(VarLoginScript) - 1] = '\0'; 1232 break; 1233 case VAR_DEVICE: 1234 CloseModem(); 1235 strncpy(VarDevice, arg, sizeof(VarDevice) - 1); 1236 VarDevice[sizeof(VarDevice) - 1] = '\0'; 1237 VarBaseDevice = rindex(VarDevice, '/'); 1238 VarBaseDevice = VarBaseDevice ? VarBaseDevice + 1 : ""; 1239 break; 1240 case VAR_ACCMAP: 1241 sscanf(arg, "%lx", &map); 1242 VarAccmap = map; 1243 break; 1244 case VAR_PHONE: 1245 strncpy(VarPhoneList, arg, sizeof(VarPhoneList) - 1); 1246 VarPhoneList[sizeof(VarPhoneList) - 1] = '\0'; 1247 strcpy(VarPhoneCopy, VarPhoneList); 1248 VarNextPhone = VarPhoneCopy; 1249 break; 1250 case VAR_HANGUP: 1251 strncpy(VarHangupScript, arg, sizeof(VarHangupScript) - 1); 1252 VarHangupScript[sizeof(VarHangupScript) - 1] = '\0'; 1253 break; 1254 case VAR_ENC: 1255 VarEncMD4 = !strcasecmp(arg, "md4"); 1256 break; 1257 } 1258 return 0; 1259} 1260 1261static int 1262SetCtsRts(struct cmdtab const * list, int argc, char **argv) 1263{ 1264 if (argc > 0) { 1265 if (strcmp(*argv, "on") == 0) 1266 VarCtsRts = TRUE; 1267 else if (strcmp(*argv, "off") == 0) 1268 VarCtsRts = FALSE; 1269 else 1270 return -1; 1271 return 0; 1272 } 1273 return -1; 1274} 1275 1276 1277static int 1278SetOpenMode(struct cmdtab const * list, int argc, char **argv) 1279{ 1280 if (argc > 0) { 1281 if (strcmp(*argv, "active") == 0) 1282 VarOpenMode = OPEN_ACTIVE; 1283 else if (strcmp(*argv, "passive") == 0) 1284 VarOpenMode = OPEN_PASSIVE; 1285 else 1286 return -1; 1287 return 0; 1288 } 1289 return -1; 1290} 1291 1292extern int SetIfilter(), SetOfilter(), SetDfilter(), SetAfilter(); 1293 1294struct cmdtab const SetCommands[] = { 1295 {"accmap", NULL, SetVariable, LOCAL_AUTH, 1296 "Set accmap value", "set accmap hex-value", (void *) VAR_ACCMAP}, 1297 {"afilter", NULL, SetAfilter, LOCAL_AUTH, 1298 "Set keep Alive filter", "set afilter ..."}, 1299 {"authkey", "key", SetVariable, LOCAL_AUTH, 1300 "Set authentication key", "set authkey|key key", (void *) VAR_AUTHKEY}, 1301 {"authname", NULL, SetVariable, LOCAL_AUTH, 1302 "Set authentication name", "set authname name", (void *) VAR_AUTHNAME}, 1303 {"ctsrts", NULL, SetCtsRts, LOCAL_AUTH, 1304 "Use CTS/RTS modem signalling", "set ctsrts [on|off]"}, 1305 {"device", "line", SetVariable, LOCAL_AUTH, 1306 "Set modem device name", "set device|line device-name", (void *) VAR_DEVICE}, 1307 {"dfilter", NULL, SetDfilter, LOCAL_AUTH, 1308 "Set demand filter", "set dfilter ..."}, 1309 {"dial", NULL, SetVariable, LOCAL_AUTH, 1310 "Set dialing script", "set dial chat-script", (void *) VAR_DIAL}, 1311 {"encrypt", NULL, SetVariable, LOCAL_AUTH, 1312 "Set CHAP encryption algorithm", "set encrypt MD4|MD5", (void *) VAR_ENC}, 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 1362static int 1363SetCommand(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 1377static int 1378AddCommand(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 1398static int 1399DeleteCommand(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 1431static int AliasEnable(); 1432static int AliasOption(); 1433 1434static 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 1465static int 1466AliasCommand(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 1479static int 1480AliasEnable(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 1504static int 1505AliasOption(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