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