command.c revision 29696
1230557Sjimharris/* 2230557Sjimharris * PPP User command processing module 3230557Sjimharris * 4230557Sjimharris * Written by Toshiharu OHNO (tony-o@iij.ad.jp) 5230557Sjimharris * 6230557Sjimharris * Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd. 7230557Sjimharris * 8230557Sjimharris * Redistribution and use in source and binary forms are permitted 9230557Sjimharris * provided that the above copyright notice and this paragraph are 10230557Sjimharris * duplicated in all such forms and that any documentation, 11230557Sjimharris * advertising materials, and other materials related to such 12230557Sjimharris * distribution and use acknowledge that the software was developed 13230557Sjimharris * by the Internet Initiative Japan, Inc. The name of the 14230557Sjimharris * IIJ may not be used to endorse or promote products derived 15230557Sjimharris * from this software without specific prior written permission. 16230557Sjimharris * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 17230557Sjimharris * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 18230557Sjimharris * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 19230557Sjimharris * 20230557Sjimharris * $Id: command.c,v 1.83 1997/09/21 13:07:57 brian Exp $ 21230557Sjimharris * 22230557Sjimharris */ 23230557Sjimharris#include <sys/types.h> 24230557Sjimharris#include <sys/stat.h> 25230557Sjimharris#include <ctype.h> 26230557Sjimharris#include <termios.h> 27230557Sjimharris#include <sys/wait.h> 28230557Sjimharris#include <time.h> 29230557Sjimharris#include <netdb.h> 30230557Sjimharris#include <sys/socket.h> 31230557Sjimharris#include <netinet/in.h> 32230557Sjimharris#include <arpa/inet.h> 33230557Sjimharris#include <net/route.h> 34230557Sjimharris#include <paths.h> 35230557Sjimharris#include <alias.h> 36230557Sjimharris#include <fcntl.h> 37230557Sjimharris#include <errno.h> 38230557Sjimharris#include "fsm.h" 39230557Sjimharris#include "phase.h" 40230557Sjimharris#include "lcp.h" 41230557Sjimharris#include "ipcp.h" 42230557Sjimharris#include "modem.h" 43230557Sjimharris#include "filter.h" 44230557Sjimharris#include "command.h" 45230557Sjimharris#include "alias_cmd.h" 46230557Sjimharris#include "hdlc.h" 47230557Sjimharris#include "loadalias.h" 48230557Sjimharris#include "vars.h" 49230557Sjimharris#include "systems.h" 50230557Sjimharris#include "chat.h" 51230557Sjimharris#include "os.h" 52230557Sjimharris#include "timeout.h" 53230557Sjimharris#include "server.h" 54230557Sjimharris 55230557Sjimharrisextern void Cleanup(), TtyTermMode(), PacketMode(); 56230557Sjimharrisextern int EnableCommand(), DisableCommand(), DisplayCommand(); 57230557Sjimharrisextern int AcceptCommand(), DenyCommand(); 58230557Sjimharrisstatic int AliasCommand(); 59230557Sjimharrisextern int LocalAuthCommand(); 60230557Sjimharrisextern int LoadCommand(), SaveCommand(); 61230557Sjimharrisextern int ChangeParity(char *); 62230557Sjimharrisextern int SelectSystem(); 63230557Sjimharrisextern int ShowRoute(); 64230557Sjimharrisextern void TtyOldMode(), TtyCommandMode(); 65230557Sjimharrisextern struct pppvars pppVars; 66230557Sjimharrisextern struct cmdtab const SetCommands[]; 67230557Sjimharris 68230557Sjimharrisextern char *IfDevName; 69230557Sjimharris 70230557Sjimharrisstruct in_addr ifnetmask; 71230557Sjimharrisint randinit; 72230557Sjimharris 73230557Sjimharrisstatic int ShowCommand(struct cmdtab const *, int, char **); 74230557Sjimharrisstatic int TerminalCommand(struct cmdtab const *, int, char **); 75230557Sjimharrisstatic int QuitCommand(struct cmdtab const *, int, char **); 76230557Sjimharrisstatic int CloseCommand(struct cmdtab const *, int, char **); 77230557Sjimharrisstatic int DialCommand(struct cmdtab const *, int, char **); 78230557Sjimharrisstatic int DownCommand(struct cmdtab const *, int, char **); 79230557Sjimharrisstatic int SetCommand(struct cmdtab const *, int, char **); 80230557Sjimharrisstatic int AddCommand(struct cmdtab const *, int, char **); 81230557Sjimharrisstatic int DeleteCommand(struct cmdtab const *, int, char **); 82230557Sjimharrisstatic int BgShellCommand(struct cmdtab const *, int, char **); 83230557Sjimharrisstatic int FgShellCommand(struct cmdtab const *, int, char **); 84230557Sjimharrisstatic int ShellCommand(struct cmdtab const *, int, char **, int); 85230557Sjimharris 86230557Sjimharrisstatic int 87230557SjimharrisHelpCommand(struct cmdtab const * list, 88230557Sjimharris int argc, 89230557Sjimharris char **argv, 90230557Sjimharris struct cmdtab const * plist) 91230557Sjimharris{ 92230557Sjimharris struct cmdtab const *cmd; 93230557Sjimharris int n; 94230557Sjimharris 95230557Sjimharris if (!VarTerm) 96230557Sjimharris return 0; 97230557Sjimharris 98230557Sjimharris if (argc > 0) { 99230557Sjimharris for (cmd = plist; cmd->name; cmd++) 100230557Sjimharris if (strcasecmp(cmd->name, *argv) == 0 && (cmd->lauth & VarLocalAuth)) { 101230557Sjimharris fprintf(VarTerm, "%s\n", cmd->syntax); 102230557Sjimharris return 0; 103230557Sjimharris } 104230557Sjimharris return -1; 105230557Sjimharris } 106230557Sjimharris n = 0; 107230557Sjimharris for (cmd = plist; cmd->func; cmd++) 108230557Sjimharris if (cmd->name && (cmd->lauth & VarLocalAuth)) { 109230557Sjimharris fprintf(VarTerm, " %-9s: %-20s\n", cmd->name, cmd->helpmes); 110230557Sjimharris n++; 111230557Sjimharris } 112230557Sjimharris if (n & 1) 113230557Sjimharris fprintf(VarTerm, "\n"); 114230557Sjimharris 115230557Sjimharris return 0; 116230557Sjimharris} 117230557Sjimharris 118230557Sjimharrisint 119230557SjimharrisIsInteractive() 120230557Sjimharris{ 121230557Sjimharris char *mes = NULL; 122230557Sjimharris 123230557Sjimharris if (mode & MODE_DDIAL) 124230557Sjimharris mes = "Working in dedicated dial mode."; 125230557Sjimharris else if (mode & MODE_BACKGROUND) 126230557Sjimharris mes = "Working in background mode."; 127230557Sjimharris else if (mode & MODE_AUTO) 128230557Sjimharris mes = "Working in auto mode."; 129230557Sjimharris else if (mode & MODE_DIRECT) 130230557Sjimharris mes = "Working in direct mode."; 131230557Sjimharris else if (mode & MODE_DEDICATED) 132230557Sjimharris mes = "Working in dedicated mode."; 133230557Sjimharris if (mes) { 134230557Sjimharris if (VarTerm) 135230557Sjimharris fprintf(VarTerm, "%s\n", mes); 136230557Sjimharris return 0; 137230557Sjimharris } 138230557Sjimharris return 1; 139230557Sjimharris} 140230557Sjimharris 141230557Sjimharrisstatic int 142230557SjimharrisDialCommand(struct cmdtab const * cmdlist, int argc, char **argv) 143230557Sjimharris{ 144230557Sjimharris int tries; 145230557Sjimharris int res; 146230557Sjimharris 147230557Sjimharris if (LcpFsm.state > ST_CLOSED) { 148230557Sjimharris if (VarTerm) 149230557Sjimharris fprintf(VarTerm, "LCP state is [%s]\n", StateNames[LcpFsm.state]); 150230557Sjimharris return 0; 151230557Sjimharris } 152230557Sjimharris 153230557Sjimharris if (argc > 0) { 154230557Sjimharris if (SelectSystem(*argv, CONFFILE) < 0) { 155230557Sjimharris if (VarTerm) 156230557Sjimharris fprintf(VarTerm, "%s: not found.\n", *argv); 157230557Sjimharris return -1; 158230557Sjimharris } 159230557Sjimharris } 160230557Sjimharris tries = 0; 161230557Sjimharris do { 162230557Sjimharris if (VarTerm) 163230557Sjimharris fprintf(VarTerm, "Dial attempt %u of %d\n", ++tries, VarDialTries); 164230557Sjimharris if (OpenModem(mode) < 0) { 165230557Sjimharris if (VarTerm) 166230557Sjimharris fprintf(VarTerm, "Failed to open modem.\n"); 167230557Sjimharris break; 168230557Sjimharris } 169230557Sjimharris if ((res = DialModem()) == EX_DONE) { 170230557Sjimharris sleep(1); 171230557Sjimharris ModemTimeout(); 172230557Sjimharris PacketMode(); 173230557Sjimharris break; 174230557Sjimharris } else if (res == EX_SIG) 175230557Sjimharris return 1; 176230557Sjimharris } while (VarDialTries == 0 || tries < VarDialTries); 177230557Sjimharris 178230557Sjimharris return 0; 179230557Sjimharris} 180230557Sjimharris 181230557Sjimharrisstatic int 182230557SjimharrisSetLoopback(struct cmdtab const * cmdlist, int argc, char **argv) 183230557Sjimharris{ 184230557Sjimharris if (argc == 1) 185230557Sjimharris if (!strcasecmp(*argv, "on")) 186230557Sjimharris VarLoopback = 1; 187230557Sjimharris else if (!strcasecmp(*argv, "off")) 188230557Sjimharris VarLoopback = 0; 189230557Sjimharris return -1; 190230557Sjimharris} 191230557Sjimharris 192230557Sjimharrisstatic int 193230557SjimharrisBgShellCommand(struct cmdtab const * cmdlist, int argc, char **argv) 194230557Sjimharris{ 195230557Sjimharris if (argc == 0) 196230557Sjimharris return -1; 197230557Sjimharris return ShellCommand(cmdlist, argc, argv, 1); 198230557Sjimharris} 199230557Sjimharris 200230557Sjimharrisstatic int 201230557SjimharrisFgShellCommand(struct cmdtab const * cmdlist, int argc, char **argv) 202230557Sjimharris{ 203230557Sjimharris return ShellCommand(cmdlist, argc, argv, 0); 204230557Sjimharris} 205230557Sjimharris 206230557Sjimharrisstatic int 207230557SjimharrisShellCommand(struct cmdtab const * cmdlist, int argc, char **argv, int bg) 208230557Sjimharris{ 209230557Sjimharris const char *shell; 210230557Sjimharris pid_t shpid; 211230557Sjimharris FILE *oVarTerm; 212230557Sjimharris 213230557Sjimharris#ifdef SHELL_ONLY_INTERACTIVELY 214230557Sjimharris /* we're only allowed to shell when we run ppp interactively */ 215230557Sjimharris if (mode != MODE_INTER) { 216230557Sjimharris LogPrintf(LogWARN, "Can only start a shell in interactive mode\n"); 217230557Sjimharris return 1; 218230557Sjimharris } 219230557Sjimharris#endif 220230557Sjimharris#ifdef NO_SHELL_IN_AUTO_INTERACTIVE 221230557Sjimharris 222230557Sjimharris /* 223230557Sjimharris * we want to stop shell commands when we've got a telnet connection to an 224230557Sjimharris * auto mode ppp 225230557Sjimharris */ 226230557Sjimharris if ((mode & (MODE_AUTO | MODE_INTER)) == (MODE_AUTO | MODE_INTER)) { 227230557Sjimharris LogPrintf(LogWARN, "Shell is not allowed interactively in auto mode\n"); 228230557Sjimharris return 1; 229230557Sjimharris } 230230557Sjimharris#endif 231230557Sjimharris 232230557Sjimharris if (argc == 0) 233230557Sjimharris if (!(mode & MODE_INTER)) { 234230557Sjimharris LogPrintf(LogWARN, "Can only start an interactive shell in" 235230557Sjimharris " interactive mode\n"); 236230557Sjimharris return 1; 237230557Sjimharris } else if (bg) { 238230557Sjimharris LogPrintf(LogWARN, "Can only start an interactive shell in" 239230557Sjimharris " the foreground mode\n"); 240230557Sjimharris return 1; 241230557Sjimharris } else if (mode&(MODE_AUTO|MODE_DEDICATED|MODE_DIRECT)) { 242230557Sjimharris LogPrintf(LogWARN, "Can't start an interactive shell from" 243230557Sjimharris " a telnet session\n"); 244230557Sjimharris return 1; 245230557Sjimharris } 246230557Sjimharris if ((shell = getenv("SHELL")) == 0) 247230557Sjimharris shell = _PATH_BSHELL; 248230557Sjimharris 249230557Sjimharris if ((shpid = fork()) == 0) { 250230557Sjimharris int dtablesize, i, fd; 251230557Sjimharris 252230557Sjimharris if (VarTerm) 253230557Sjimharris fd = fileno(VarTerm); 254230557Sjimharris else if ((fd = open("/dev/null", O_RDWR)) == -1) { 255230557Sjimharris LogPrintf(LogALERT, "Failed to open /dev/null: %s\n", strerror(errno)); 256230557Sjimharris exit(1); 257230557Sjimharris } 258230557Sjimharris for (i = 0; i < 3; i++) 259230557Sjimharris dup2(fd, i); 260230557Sjimharris 261230557Sjimharris if (fd > 2) 262230557Sjimharris if (VarTerm) { 263230557Sjimharris oVarTerm = VarTerm; 264230557Sjimharris VarTerm = 0; 265230557Sjimharris if (oVarTerm && oVarTerm != stdout) 266230557Sjimharris fclose(oVarTerm); 267230557Sjimharris } else 268230557Sjimharris close(fd); 269230557Sjimharris 270230557Sjimharris for (dtablesize = getdtablesize(), i = 3; i < dtablesize; i++) 271230557Sjimharris (void) close(i); 272230557Sjimharris 273230557Sjimharris /* 274230557Sjimharris * We are running setuid, we should change to real user for avoiding 275230557Sjimharris * security problems. 276230557Sjimharris */ 277230557Sjimharris if (setgid(getgid()) < 0) { 278230557Sjimharris LogPrintf(LogERROR, "setgid: %s\n", strerror(errno)); 279230557Sjimharris exit(1); 280230557Sjimharris } 281230557Sjimharris if (setuid(getuid()) < 0) { 282230557Sjimharris LogPrintf(LogERROR, "setuid: %s\n", strerror(errno)); 283230557Sjimharris exit(1); 284230557Sjimharris } 285230557Sjimharris TtyOldMode(); 286230557Sjimharris if (argc > 0) { 287230557Sjimharris /* substitute pseudo args */ 288230557Sjimharris for (i = 1; i < argc; i++) 289230557Sjimharris if (strcasecmp(argv[i], "HISADDR") == 0) 290230557Sjimharris argv[i] = strdup(inet_ntoa(IpcpInfo.his_ipaddr)); 291230557Sjimharris else if (strcasecmp(argv[i], "INTERFACE") == 0) 292230557Sjimharris argv[i] = strdup(IfDevName); 293230557Sjimharris else if (strcasecmp(argv[i], "MYADDR") == 0) 294230557Sjimharris argv[i] = strdup(inet_ntoa(IpcpInfo.want_ipaddr)); 295230557Sjimharris if (bg) { 296230557Sjimharris pid_t p; 297230557Sjimharris 298230557Sjimharris p = getpid(); 299230557Sjimharris if (daemon(1, 1) == -1) { 300230557Sjimharris LogPrintf(LogERROR, "%d: daemon: %s\n", p, strerror(errno)); 301230557Sjimharris exit(1); 302230557Sjimharris } 303230557Sjimharris } 304230557Sjimharris (void) execvp(argv[0], argv); 305230557Sjimharris } else 306230557Sjimharris (void) execl(shell, shell, NULL); 307230557Sjimharris 308230557Sjimharris LogPrintf(LogWARN, "exec() of %s failed\n", argc > 0 ? argv[0] : shell); 309230557Sjimharris exit(255); 310230557Sjimharris } 311230557Sjimharris if (shpid == (pid_t) - 1) { 312230557Sjimharris LogPrintf(LogERROR, "Fork failed: %s\n", strerror(errno)); 313230557Sjimharris } else { 314230557Sjimharris int status; 315230557Sjimharris 316230557Sjimharris (void) waitpid(shpid, &status, 0); 317230557Sjimharris } 318230557Sjimharris 319230557Sjimharris TtyCommandMode(1); 320230557Sjimharris 321230557Sjimharris return (0); 322230557Sjimharris} 323230557Sjimharris 324230557Sjimharrisstruct cmdtab const Commands[] = { 325230557Sjimharris {"accept", NULL, AcceptCommand, LOCAL_AUTH, 326230557Sjimharris "accept option request", "accept option .."}, 327230557Sjimharris {"add", NULL, AddCommand, LOCAL_AUTH, 328230557Sjimharris "add route", "add dest mask gateway"}, 329230557Sjimharris {"bg", "!bg", BgShellCommand, LOCAL_AUTH, 330230557Sjimharris "Run a command in the background", "[!]bg command"}, 331230557Sjimharris {"close", NULL, CloseCommand, LOCAL_AUTH, 332230557Sjimharris "Close connection", "close"}, 333230557Sjimharris {"delete", NULL, DeleteCommand, LOCAL_AUTH, 334230557Sjimharris "delete route", "delete ALL | dest [gateway [mask]]"}, 335230557Sjimharris {"deny", NULL, DenyCommand, LOCAL_AUTH, 336230557Sjimharris "Deny option request", "deny option .."}, 337230557Sjimharris {"dial", "call", DialCommand, LOCAL_AUTH, 338230557Sjimharris "Dial and login", "dial|call [remote]"}, 339230557Sjimharris {"disable", NULL, DisableCommand, LOCAL_AUTH, 340230557Sjimharris "Disable option", "disable option .."}, 341230557Sjimharris {"display", NULL, DisplayCommand, LOCAL_AUTH, 342230557Sjimharris "Display option configs", "display"}, 343230557Sjimharris {"enable", NULL, EnableCommand, LOCAL_AUTH, 344230557Sjimharris "Enable option", "enable option .."}, 345230557Sjimharris {"passwd", NULL, LocalAuthCommand, LOCAL_NO_AUTH, 346230557Sjimharris "Password for manipulation", "passwd LocalPassword"}, 347230557Sjimharris {"load", NULL, LoadCommand, LOCAL_AUTH, 348230557Sjimharris "Load settings", "load [remote]"}, 349230557Sjimharris {"save", NULL, SaveCommand, LOCAL_AUTH, 350230557Sjimharris "Save settings", "save"}, 351230557Sjimharris {"set", "setup", SetCommand, LOCAL_AUTH, 352230557Sjimharris "Set parameters", "set[up] var value"}, 353230557Sjimharris {"shell", "!", FgShellCommand, LOCAL_AUTH, 354230557Sjimharris "Run a subshell", "shell|! [sh command]"}, 355230557Sjimharris {"show", NULL, ShowCommand, LOCAL_AUTH, 356230557Sjimharris "Show status and statistics", "show var"}, 357230557Sjimharris {"term", NULL, TerminalCommand, LOCAL_AUTH, 358230557Sjimharris "Enter to terminal mode", "term"}, 359230557Sjimharris {"alias", NULL, AliasCommand, LOCAL_AUTH, 360230557Sjimharris "alias control", "alias option [yes|no]"}, 361230557Sjimharris {"quit", "bye", QuitCommand, LOCAL_AUTH | LOCAL_NO_AUTH, 362230557Sjimharris "Quit PPP program", "quit|bye [all]"}, 363230557Sjimharris {"help", "?", HelpCommand, LOCAL_AUTH | LOCAL_NO_AUTH, 364230557Sjimharris "Display this message", "help|? [command]", (void *) Commands}, 365231137Sjimharris {NULL, "down", DownCommand, LOCAL_AUTH, 366231137Sjimharris "Generate down event", "down"}, 367230557Sjimharris {NULL, NULL, NULL}, 368230557Sjimharris}; 369230557Sjimharris 370230557Sjimharrisextern int ReportCcpStatus(); 371230557Sjimharrisextern int ReportLcpStatus(); 372230557Sjimharrisextern int ReportIpcpStatus(); 373230557Sjimharrisextern int ReportProtStatus(); 374230557Sjimharrisextern int ReportCompress(); 375231137Sjimharrisextern int ShowModemStatus(); 376230557Sjimharrisextern int ReportHdlcStatus(); 377230557Sjimharrisextern int ShowMemMap(); 378230557Sjimharris 379230557Sjimharrisstatic int 380230557SjimharrisShowLoopback() 381230557Sjimharris{ 382230557Sjimharris if (VarTerm) 383230557Sjimharris fprintf(VarTerm, "Local loopback is %s\n", VarLoopback ? "on" : "off"); 384230557Sjimharris 385230557Sjimharris return 0; 386230557Sjimharris} 387230557Sjimharris 388230557Sjimharrisstatic int 389230557SjimharrisShowLogLevel() 390230557Sjimharris{ 391230557Sjimharris int i; 392230557Sjimharris 393230557Sjimharris if (!VarTerm) 394230557Sjimharris return 0; 395230557Sjimharris fprintf(VarTerm, "Log:"); 396230557Sjimharris for (i = LogMIN; i < LogMAXCONF; i++) { 397230557Sjimharris if (LogIsKept(i)) 398230557Sjimharris fprintf(VarTerm, " %s", LogName(i)); 399230557Sjimharris } 400230557Sjimharris fprintf(VarTerm, "\n"); 401230557Sjimharris 402230557Sjimharris return 0; 403230557Sjimharris} 404230557Sjimharris 405230557Sjimharrisstatic int 406230557SjimharrisShowEscape() 407230557Sjimharris{ 408230557Sjimharris int code, bit; 409230557Sjimharris 410230557Sjimharris if (!VarTerm) 411230557Sjimharris return 0; 412230557Sjimharris if (EscMap[32]) { 413230557Sjimharris for (code = 0; code < 32; code++) 414230557Sjimharris if (EscMap[code]) 415230557Sjimharris for (bit = 0; bit < 8; bit++) 416230557Sjimharris if (EscMap[code] & (1 << bit)) 417230557Sjimharris fprintf(VarTerm, " 0x%02x", (code << 3) + bit); 418230557Sjimharris fprintf(VarTerm, "\n"); 419230557Sjimharris } 420230557Sjimharris return 1; 421230557Sjimharris} 422230557Sjimharris 423230557Sjimharrisstatic int 424230557SjimharrisShowTimeout() 425230557Sjimharris{ 426230557Sjimharris if (!VarTerm) 427230557Sjimharris return 0; 428230557Sjimharris fprintf(VarTerm, " Idle Timer: %d secs LQR Timer: %d secs" 429230557Sjimharris " Retry Timer: %d secs\n", VarIdleTimeout, VarLqrTimeout, 430230557Sjimharris VarRetryTimeout); 431230557Sjimharris return 1; 432230557Sjimharris} 433230557Sjimharris 434230557Sjimharrisstatic int 435230557SjimharrisShowStopped() 436230557Sjimharris{ 437230557Sjimharris if (!VarTerm) 438230557Sjimharris return 0; 439230557Sjimharris 440230557Sjimharris fprintf(VarTerm, " Stopped Timer: LCP: "); 441230557Sjimharris if (!LcpFsm.StoppedTimer.load) 442230557Sjimharris fprintf(VarTerm, "Disabled"); 443230557Sjimharris else 444230557Sjimharris fprintf(VarTerm, "%ld secs", LcpFsm.StoppedTimer.load / SECTICKS); 445230557Sjimharris 446230557Sjimharris fprintf(VarTerm, ", IPCP: "); 447230557Sjimharris if (!IpcpFsm.StoppedTimer.load) 448230557Sjimharris fprintf(VarTerm, "Disabled"); 449230557Sjimharris else 450230557Sjimharris fprintf(VarTerm, "%ld secs", IpcpFsm.StoppedTimer.load / SECTICKS); 451230557Sjimharris 452230557Sjimharris fprintf(VarTerm, ", CCP: "); 453230557Sjimharris if (!CcpFsm.StoppedTimer.load) 454230557Sjimharris fprintf(VarTerm, "Disabled"); 455230557Sjimharris else 456230557Sjimharris fprintf(VarTerm, "%ld secs", CcpFsm.StoppedTimer.load / SECTICKS); 457230557Sjimharris 458230557Sjimharris fprintf(VarTerm, "\n"); 459230557Sjimharris 460230557Sjimharris return 1; 461230557Sjimharris} 462230557Sjimharris 463230557Sjimharrisstatic int 464230557SjimharrisShowAuthKey() 465230557Sjimharris{ 466230557Sjimharris if (!VarTerm) 467230557Sjimharris return 0; 468230557Sjimharris fprintf(VarTerm, "AuthName = %s\n", VarAuthName); 469230557Sjimharris fprintf(VarTerm, "AuthKey = %s\n", VarAuthKey); 470230557Sjimharris fprintf(VarTerm, "Encrypt = %s\n", VarEncMD4 ? "MD4" : "MD5" ); 471230557Sjimharris return 1; 472230557Sjimharris} 473230557Sjimharris 474230557Sjimharrisstatic int 475230557SjimharrisShowVersion() 476230557Sjimharris{ 477230557Sjimharris extern char VarVersion[]; 478230557Sjimharris extern char VarLocalVersion[]; 479230557Sjimharris 480230557Sjimharris if (!VarTerm) 481230557Sjimharris return 0; 482230557Sjimharris fprintf(VarTerm, "%s - %s \n", VarVersion, VarLocalVersion); 483230557Sjimharris return 1; 484230557Sjimharris} 485230557Sjimharris 486230557Sjimharrisstatic int 487230557SjimharrisShowInitialMRU() 488230557Sjimharris{ 489230557Sjimharris if (!VarTerm) 490230557Sjimharris return 0; 491230557Sjimharris fprintf(VarTerm, " Initial MRU: %ld\n", VarMRU); 492230557Sjimharris return 1; 493230557Sjimharris} 494230557Sjimharris 495230557Sjimharrisstatic int 496230557SjimharrisShowPreferredMTU() 497230557Sjimharris{ 498230557Sjimharris if (!VarTerm) 499230557Sjimharris return 0; 500230557Sjimharris if (VarPrefMTU) 501230557Sjimharris fprintf(VarTerm, " Preferred MTU: %ld\n", VarPrefMTU); 502230557Sjimharris else 503230557Sjimharris fprintf(VarTerm, " Preferred MTU: unspecified\n"); 504230557Sjimharris return 1; 505230557Sjimharris} 506230557Sjimharris 507230557Sjimharrisstatic int 508230557SjimharrisShowReconnect() 509230557Sjimharris{ 510230557Sjimharris if (!VarTerm) 511230557Sjimharris return 0; 512230557Sjimharris fprintf(VarTerm, " Reconnect Timer: %d, %d tries\n", 513230557Sjimharris VarReconnectTimer, VarReconnectTries); 514230557Sjimharris return 1; 515230557Sjimharris} 516230557Sjimharris 517230557Sjimharrisstatic int 518230557SjimharrisShowRedial() 519230557Sjimharris{ 520230557Sjimharris if (!VarTerm) 521230557Sjimharris return 0; 522230557Sjimharris fprintf(VarTerm, " Redial Timer: "); 523230557Sjimharris 524230557Sjimharris if (VarRedialTimeout >= 0) { 525230557Sjimharris fprintf(VarTerm, " %d seconds, ", VarRedialTimeout); 526230557Sjimharris } else { 527230557Sjimharris fprintf(VarTerm, " Random 0 - %d seconds, ", REDIAL_PERIOD); 528230557Sjimharris } 529230557Sjimharris 530230557Sjimharris fprintf(VarTerm, " Redial Next Timer: "); 531230557Sjimharris 532230557Sjimharris if (VarRedialNextTimeout >= 0) { 533230557Sjimharris fprintf(VarTerm, " %d seconds, ", VarRedialNextTimeout); 534230557Sjimharris } else { 535230557Sjimharris fprintf(VarTerm, " Random 0 - %d seconds, ", REDIAL_PERIOD); 536230557Sjimharris } 537230557Sjimharris 538230557Sjimharris if (VarDialTries) 539230557Sjimharris fprintf(VarTerm, "%d dial tries", VarDialTries); 540230557Sjimharris 541230557Sjimharris fprintf(VarTerm, "\n"); 542230557Sjimharris 543230557Sjimharris return 1; 544230557Sjimharris} 545230557Sjimharris 546230557Sjimharris#ifndef NOMSEXT 547230557Sjimharrisstatic int 548230557SjimharrisShowMSExt() 549230557Sjimharris{ 550230557Sjimharris if (!VarTerm) 551230557Sjimharris return 0; 552230557Sjimharris fprintf(VarTerm, " MS PPP extention values \n"); 553230557Sjimharris fprintf(VarTerm, " Primary NS : %s\n", inet_ntoa(ns_entries[0])); 554230557Sjimharris fprintf(VarTerm, " Secondary NS : %s\n", inet_ntoa(ns_entries[1])); 555230557Sjimharris fprintf(VarTerm, " Primary NBNS : %s\n", inet_ntoa(nbns_entries[0])); 556230557Sjimharris fprintf(VarTerm, " Secondary NBNS : %s\n", inet_ntoa(nbns_entries[1])); 557230557Sjimharris return 1; 558230557Sjimharris} 559230557Sjimharris 560230557Sjimharris#endif 561230557Sjimharris 562230557Sjimharrisextern int ShowIfilter(), ShowOfilter(), ShowDfilter(), ShowAfilter(); 563230557Sjimharris 564230557Sjimharrisstruct cmdtab const ShowCommands[] = { 565230557Sjimharris {"afilter", NULL, ShowAfilter, LOCAL_AUTH, 566230557Sjimharris "Show keep Alive filters", "show afilter option .."}, 567230557Sjimharris {"auth", NULL, ShowAuthKey, LOCAL_AUTH, 568230557Sjimharris "Show auth name, key and algorithm", "show auth"}, 569230557Sjimharris {"ccp", NULL, ReportCcpStatus, LOCAL_AUTH, 570230557Sjimharris "Show CCP status", "show cpp"}, 571230557Sjimharris {"compress", NULL, ReportCompress, LOCAL_AUTH, 572230557Sjimharris "Show compression statistics", "show compress"}, 573230557Sjimharris {"dfilter", NULL, ShowDfilter, LOCAL_AUTH, 574230557Sjimharris "Show Demand filters", "show dfilteroption .."}, 575230557Sjimharris {"escape", NULL, ShowEscape, LOCAL_AUTH, 576230557Sjimharris "Show escape characters", "show escape"}, 577230557Sjimharris {"hdlc", NULL, ReportHdlcStatus, LOCAL_AUTH, 578230557Sjimharris "Show HDLC error summary", "show hdlc"}, 579230557Sjimharris {"ifilter", NULL, ShowIfilter, LOCAL_AUTH, 580230557Sjimharris "Show Input filters", "show ifilter option .."}, 581230557Sjimharris {"ipcp", NULL, ReportIpcpStatus, LOCAL_AUTH, 582230557Sjimharris "Show IPCP status", "show ipcp"}, 583230557Sjimharris {"lcp", NULL, ReportLcpStatus, LOCAL_AUTH, 584230557Sjimharris "Show LCP status", "show lcp"}, 585230557Sjimharris {"loopback", NULL, ShowLoopback, LOCAL_AUTH, 586230557Sjimharris "Show current loopback setting", "show loopback"}, 587230557Sjimharris {"log", NULL, ShowLogLevel, LOCAL_AUTH, 588230557Sjimharris "Show current log level", "show log"}, 589230557Sjimharris {"mem", NULL, ShowMemMap, LOCAL_AUTH, 590230557Sjimharris "Show memory map", "show mem"}, 591230557Sjimharris {"modem", NULL, ShowModemStatus, LOCAL_AUTH, 592230557Sjimharris "Show modem setups", "show modem"}, 593230557Sjimharris {"mru", NULL, ShowInitialMRU, LOCAL_AUTH, 594230557Sjimharris "Show Initial MRU", "show mru"}, 595230557Sjimharris {"mtu", NULL, ShowPreferredMTU, LOCAL_AUTH, 596230557Sjimharris "Show Preferred MTU", "show mtu"}, 597230557Sjimharris {"ofilter", NULL, ShowOfilter, LOCAL_AUTH, 598230557Sjimharris "Show Output filters", "show ofilter option .."}, 599230557Sjimharris {"proto", NULL, ReportProtStatus, LOCAL_AUTH, 600230557Sjimharris "Show protocol summary", "show proto"}, 601230557Sjimharris {"reconnect", NULL, ShowReconnect, LOCAL_AUTH, 602230557Sjimharris "Show Reconnect timer,tries", "show reconnect"}, 603230557Sjimharris {"redial", NULL, ShowRedial, LOCAL_AUTH, 604230557Sjimharris "Show Redial timeout value", "show redial"}, 605230557Sjimharris {"route", NULL, ShowRoute, LOCAL_AUTH, 606230557Sjimharris "Show routing table", "show route"}, 607230557Sjimharris {"timeout", NULL, ShowTimeout, LOCAL_AUTH, 608230557Sjimharris "Show Idle timeout value", "show timeout"}, 609230557Sjimharris {"stopped", NULL, ShowStopped, LOCAL_AUTH, 610230557Sjimharris "Show STOPPED timeout value", "show stopped"}, 611230557Sjimharris#ifndef NOMSEXT 612230557Sjimharris {"msext", NULL, ShowMSExt, LOCAL_AUTH, 613230557Sjimharris "Show MS PPP extentions", "show msext"}, 614230557Sjimharris#endif 615230557Sjimharris {"version", NULL, ShowVersion, LOCAL_NO_AUTH | LOCAL_AUTH, 616230557Sjimharris "Show version string", "show version"}, 617230557Sjimharris {"help", "?", HelpCommand, LOCAL_NO_AUTH | LOCAL_AUTH, 618230557Sjimharris "Display this message", "show help|? [command]", (void *) ShowCommands}, 619230557Sjimharris {NULL, NULL, NULL}, 620230557Sjimharris}; 621230557Sjimharris 622230557Sjimharrisstruct cmdtab const * 623230557SjimharrisFindCommand(struct cmdtab const * cmds, char *str, int *pmatch) 624230557Sjimharris{ 625230557Sjimharris int nmatch; 626230557Sjimharris int len; 627230557Sjimharris struct cmdtab const *found; 628230557Sjimharris 629230557Sjimharris found = NULL; 630230557Sjimharris len = strlen(str); 631230557Sjimharris nmatch = 0; 632230557Sjimharris while (cmds->func) { 633230557Sjimharris if (cmds->name && strncasecmp(str, cmds->name, len) == 0) { 634230557Sjimharris if (cmds->name[len] == '\0') { 635230557Sjimharris *pmatch = 1; 636230557Sjimharris return cmds; 637230557Sjimharris } 638230557Sjimharris nmatch++; 639230557Sjimharris found = cmds; 640230557Sjimharris } else if (cmds->alias && strncasecmp(str, cmds->alias, len) == 0) { 641230557Sjimharris if (cmds->alias[len] == '\0') { 642230557Sjimharris *pmatch = 1; 643230557Sjimharris return cmds; 644230557Sjimharris } 645230557Sjimharris nmatch++; 646230557Sjimharris found = cmds; 647230557Sjimharris } 648230557Sjimharris cmds++; 649230557Sjimharris } 650230557Sjimharris *pmatch = nmatch; 651230557Sjimharris return found; 652230557Sjimharris} 653230557Sjimharris 654230557Sjimharrisint 655230557SjimharrisFindExec(struct cmdtab const * cmdlist, int argc, char **argv) 656230557Sjimharris{ 657230557Sjimharris struct cmdtab const *cmd; 658230557Sjimharris int val = 1; 659230557Sjimharris int nmatch; 660230557Sjimharris 661230557Sjimharris cmd = FindCommand(cmdlist, *argv, &nmatch); 662230557Sjimharris if (nmatch > 1) 663230557Sjimharris LogPrintf(LogWARN, "%s: Ambiguous command\n", *argv); 664230557Sjimharris else if (cmd && (cmd->lauth & VarLocalAuth)) 665230557Sjimharris val = (cmd->func) (cmd, argc-1, argv+1, cmd->args); 666230557Sjimharris else 667230557Sjimharris LogPrintf(LogWARN, "%s: Invalid command\n", *argv); 668230557Sjimharris 669230557Sjimharris if (val == -1) 670230557Sjimharris LogPrintf(LogWARN, "Usage: %s\n", cmd->syntax); 671230557Sjimharris else if (val) 672230557Sjimharris LogPrintf(LogCOMMAND, "%s: Failed %d\n", *argv, val); 673230557Sjimharris 674230557Sjimharris return val; 675230557Sjimharris} 676230557Sjimharris 677230557Sjimharrisint aft_cmd = 1; 678230557Sjimharrisextern int TermMode; 679230557Sjimharris 680230557Sjimharrisvoid 681230557SjimharrisPrompt() 682230557Sjimharris{ 683230557Sjimharris char *pconnect, *pauth; 684230557Sjimharris 685230557Sjimharris if (!(mode & MODE_INTER) || !VarTerm || TermMode) 686230557Sjimharris return; 687230557Sjimharris 688230557Sjimharris if (!aft_cmd) 689230557Sjimharris fprintf(VarTerm, "\n"); 690230557Sjimharris else 691230557Sjimharris aft_cmd = 0; 692230557Sjimharris 693230557Sjimharris if (VarLocalAuth == LOCAL_AUTH) 694230557Sjimharris pauth = " ON "; 695230557Sjimharris else 696230557Sjimharris pauth = " on "; 697230557Sjimharris if (IpcpFsm.state == ST_OPENED && phase == PHASE_NETWORK) 698230557Sjimharris pconnect = "PPP"; 699230557Sjimharris else 700230557Sjimharris pconnect = "ppp"; 701230557Sjimharris fprintf(VarTerm, "%s%s%s> ", pconnect, pauth, VarShortHost); 702230557Sjimharris fflush(VarTerm); 703230557Sjimharris} 704230557Sjimharris 705230557Sjimharrisvoid 706230557SjimharrisDecodeCommand(char *buff, int nb, int prompt) 707230557Sjimharris{ 708230557Sjimharris char *vector[20]; 709230557Sjimharris char **argv; 710230557Sjimharris int argc; 711230557Sjimharris char *cp; 712230557Sjimharris 713230557Sjimharris if (nb > 0) { 714230557Sjimharris cp = buff + strcspn(buff, "\r\n"); 715230557Sjimharris if (cp) 716230557Sjimharris *cp = '\0'; 717230557Sjimharris argc = MakeArgs(buff, vector, VECSIZE(vector)); 718230557Sjimharris argv = vector; 719230557Sjimharris 720230557Sjimharris if (argc > 0) 721230557Sjimharris FindExec(Commands, argc, argv); 722230557Sjimharris } 723230557Sjimharris if (prompt) 724230557Sjimharris Prompt(); 725230557Sjimharris} 726230557Sjimharris 727230557Sjimharrisstatic int 728230557SjimharrisShowCommand(struct cmdtab const * list, int argc, char **argv) 729230557Sjimharris{ 730230557Sjimharris if (argc > 0) 731230557Sjimharris FindExec(ShowCommands, argc, argv); 732230557Sjimharris else if (VarTerm) 733230557Sjimharris fprintf(VarTerm, "Use ``show ?'' to get a list.\n"); 734230557Sjimharris else 735230557Sjimharris LogPrintf(LogWARN, "show command must have arguments\n"); 736230557Sjimharris 737230557Sjimharris return 0; 738230557Sjimharris} 739230557Sjimharris 740230557Sjimharrisstatic int 741230557SjimharrisTerminalCommand(struct cmdtab const * list, int argc, char **argv) 742230557Sjimharris{ 743230557Sjimharris if (LcpFsm.state > ST_CLOSED) { 744230557Sjimharris if (VarTerm) 745230557Sjimharris fprintf(VarTerm, "LCP state is [%s]\n", StateNames[LcpFsm.state]); 746230557Sjimharris return 1; 747230557Sjimharris } 748230557Sjimharris if (!IsInteractive()) 749230557Sjimharris return (1); 750230557Sjimharris if (OpenModem(mode) < 0) { 751230557Sjimharris if (VarTerm) 752230557Sjimharris fprintf(VarTerm, "Failed to open modem.\n"); 753230557Sjimharris return (1); 754230557Sjimharris } 755230557Sjimharris if (VarTerm) { 756230557Sjimharris fprintf(VarTerm, "Enter to terminal mode.\n"); 757230557Sjimharris fprintf(VarTerm, "Type `~?' for help.\n"); 758230557Sjimharris } 759230557Sjimharris TtyTermMode(); 760230557Sjimharris return (0); 761230557Sjimharris} 762230557Sjimharris 763230557Sjimharrisstatic int 764230557SjimharrisQuitCommand(struct cmdtab const * list, int argc, char **argv) 765230557Sjimharris{ 766230557Sjimharris FILE *oVarTerm; 767230557Sjimharris 768230557Sjimharris if (mode & (MODE_DIRECT | MODE_DEDICATED | MODE_AUTO)) { 769230557Sjimharris if (argc > 0 && !strcasecmp(*argv, "all") && (VarLocalAuth & LOCAL_AUTH)) { 770230557Sjimharris mode &= ~MODE_INTER; 771230557Sjimharris oVarTerm = VarTerm; 772230557Sjimharris VarTerm = 0; 773230557Sjimharris if (oVarTerm && oVarTerm != stdout) 774230557Sjimharris fclose(oVarTerm); 775230557Sjimharris Cleanup(EX_NORMAL); 776230557Sjimharris } else if (VarTerm) { 777230557Sjimharris LogPrintf(LogPHASE, "Client connection closed.\n"); 778230557Sjimharris VarLocalAuth = LOCAL_NO_AUTH; 779230557Sjimharris mode &= ~MODE_INTER; 780230557Sjimharris oVarTerm = VarTerm; 781230557Sjimharris VarTerm = 0; 782230557Sjimharris if (oVarTerm && oVarTerm != stdout) 783230557Sjimharris fclose(oVarTerm); 784230557Sjimharris close(netfd); 785230557Sjimharris netfd = -1; 786230557Sjimharris } 787230557Sjimharris } else 788230557Sjimharris Cleanup(EX_NORMAL); 789230557Sjimharris 790230557Sjimharris return 0; 791230557Sjimharris} 792230557Sjimharris 793230557Sjimharrisstatic int 794230557SjimharrisCloseCommand(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 1195int 1196SetVariable(struct cmdtab const * list, int argc, char **argv, int param) 1197{ 1198 u_long map; 1199 char *arg; 1200 1201 if (argc > 0) 1202 arg = *argv; 1203 else 1204 arg = ""; 1205 1206 switch (param) { 1207 case VAR_AUTHKEY: 1208 strncpy(VarAuthKey, arg, sizeof(VarAuthKey) - 1); 1209 VarAuthKey[sizeof(VarAuthKey) - 1] = '\0'; 1210 break; 1211 case VAR_AUTHNAME: 1212 strncpy(VarAuthName, arg, sizeof(VarAuthName) - 1); 1213 VarAuthName[sizeof(VarAuthName) - 1] = '\0'; 1214 break; 1215 case VAR_DIAL: 1216 strncpy(VarDialScript, arg, sizeof(VarDialScript) - 1); 1217 VarDialScript[sizeof(VarDialScript) - 1] = '\0'; 1218 break; 1219 case VAR_LOGIN: 1220 strncpy(VarLoginScript, arg, sizeof(VarLoginScript) - 1); 1221 VarLoginScript[sizeof(VarLoginScript) - 1] = '\0'; 1222 break; 1223 case VAR_DEVICE: 1224 if (modem != -1) 1225 LogPrintf(LogWARN, "Cannot change device to \"%s\" when \"%s\" is open\n", 1226 arg, VarDevice); 1227 else { 1228 strncpy(VarDevice, arg, sizeof(VarDevice) - 1); 1229 VarDevice[sizeof(VarDevice) - 1] = '\0'; 1230 VarBaseDevice = rindex(VarDevice, '/'); 1231 VarBaseDevice = VarBaseDevice ? VarBaseDevice + 1 : ""; 1232 } 1233 break; 1234 case VAR_ACCMAP: 1235 sscanf(arg, "%lx", &map); 1236 VarAccmap = map; 1237 break; 1238 case VAR_PHONE: 1239 strncpy(VarPhoneList, arg, sizeof(VarPhoneList) - 1); 1240 VarPhoneList[sizeof(VarPhoneList) - 1] = '\0'; 1241 strcpy(VarPhoneCopy, VarPhoneList); 1242 VarNextPhone = VarPhoneCopy; 1243 break; 1244 case VAR_HANGUP: 1245 strncpy(VarHangupScript, arg, sizeof(VarHangupScript) - 1); 1246 VarHangupScript[sizeof(VarHangupScript) - 1] = '\0'; 1247 break; 1248 case VAR_ENC: 1249 VarEncMD4 = !strcasecmp(arg, "md4"); 1250 break; 1251 } 1252 return 0; 1253} 1254 1255static int 1256SetCtsRts(struct cmdtab const * list, int argc, char **argv) 1257{ 1258 if (argc > 0) { 1259 if (strcmp(*argv, "on") == 0) 1260 VarCtsRts = TRUE; 1261 else if (strcmp(*argv, "off") == 0) 1262 VarCtsRts = FALSE; 1263 else 1264 return -1; 1265 return 0; 1266 } 1267 return -1; 1268} 1269 1270 1271static int 1272SetOpenMode(struct cmdtab const * list, int argc, char **argv) 1273{ 1274 if (argc > 0) { 1275 if (strcmp(*argv, "active") == 0) 1276 VarOpenMode = OPEN_ACTIVE; 1277 else if (strcmp(*argv, "passive") == 0) 1278 VarOpenMode = OPEN_PASSIVE; 1279 else 1280 return -1; 1281 return 0; 1282 } 1283 return -1; 1284} 1285 1286extern int SetIfilter(), SetOfilter(), SetDfilter(), SetAfilter(); 1287 1288struct cmdtab const SetCommands[] = { 1289 {"accmap", NULL, SetVariable, LOCAL_AUTH, 1290 "Set accmap value", "set accmap hex-value", (void *) VAR_ACCMAP}, 1291 {"afilter", NULL, SetAfilter, LOCAL_AUTH, 1292 "Set keep Alive filter", "set afilter ..."}, 1293 {"authkey", "key", SetVariable, LOCAL_AUTH, 1294 "Set authentication key", "set authkey|key key", (void *) VAR_AUTHKEY}, 1295 {"authname", NULL, SetVariable, LOCAL_AUTH, 1296 "Set authentication name", "set authname name", (void *) VAR_AUTHNAME}, 1297 {"ctsrts", NULL, SetCtsRts, LOCAL_AUTH, 1298 "Use CTS/RTS modem signalling", "set ctsrts [on|off]"}, 1299 {"device", "line", SetVariable, LOCAL_AUTH, 1300 "Set modem device name", "set device|line device-name", (void *) VAR_DEVICE}, 1301 {"dfilter", NULL, SetDfilter, LOCAL_AUTH, 1302 "Set demand filter", "set dfilter ..."}, 1303 {"dial", NULL, SetVariable, LOCAL_AUTH, 1304 "Set dialing script", "set dial chat-script", (void *) VAR_DIAL}, 1305 {"encrypt", NULL, SetVariable, LOCAL_AUTH, 1306 "Set CHAP encryption algorithm", "set encrypt MD4|MD5", (void *) VAR_ENC}, 1307 {"escape", NULL, SetEscape, LOCAL_AUTH, 1308 "Set escape characters", "set escape hex-digit ..."}, 1309 {"hangup", NULL, SetVariable, LOCAL_AUTH, 1310 "Set hangup script", "set hangup chat-script", (void *) VAR_HANGUP}, 1311 {"ifaddr", NULL, SetInterfaceAddr, LOCAL_AUTH, 1312 "Set destination address", "set ifaddr [src-addr [dst-addr [netmask [trg-addr]]]]"}, 1313 {"ifilter", NULL, SetIfilter, LOCAL_AUTH, 1314 "Set input filter", "set ifilter ..."}, 1315 {"loopback", NULL, SetLoopback, LOCAL_AUTH, 1316 "Set loopback facility", "set loopback on|off"}, 1317 {"log", NULL, SetLogLevel, LOCAL_AUTH, 1318 "Set log level", "set log [+|-]value..."}, 1319 {"login", NULL, SetVariable, LOCAL_AUTH, 1320 "Set login script", "set login chat-script", (void *) VAR_LOGIN}, 1321 {"mru", NULL, SetInitialMRU, LOCAL_AUTH, 1322 "Set Initial MRU value", "set mru value"}, 1323 {"mtu", NULL, SetPreferredMTU, LOCAL_AUTH, 1324 "Set Preferred MTU value", "set mtu value"}, 1325 {"ofilter", NULL, SetOfilter, LOCAL_AUTH, 1326 "Set output filter", "set ofilter ..."}, 1327 {"openmode", NULL, SetOpenMode, LOCAL_AUTH, 1328 "Set open mode", "set openmode [active|passive]"}, 1329 {"parity", NULL, SetModemParity, LOCAL_AUTH, 1330 "Set modem parity", "set parity [odd|even|none]"}, 1331 {"phone", NULL, SetVariable, LOCAL_AUTH, 1332 "Set telephone number(s)", "set phone phone1[:phone2[...]]", (void *) VAR_PHONE}, 1333 {"reconnect", NULL, SetReconnect, LOCAL_AUTH, 1334 "Set Reconnect timeout", "set reconnect value ntries"}, 1335 {"redial", NULL, SetRedialTimeout, LOCAL_AUTH, 1336 "Set Redial timeout", "set redial value|random[.value|random] [dial_attempts]"}, 1337 {"stopped", NULL, SetStoppedTimeout, LOCAL_AUTH, 1338 "Set STOPPED timeouts", "set stopped [LCPseconds [IPCPseconds [CCPseconds]]]"}, 1339 {"server", "socket", SetServer, LOCAL_AUTH, 1340 "Set server port", "set server|socket TcpPort|LocalName|none [mask]"}, 1341 {"speed", NULL, SetModemSpeed, LOCAL_AUTH, 1342 "Set modem speed", "set speed value"}, 1343 {"timeout", NULL, SetIdleTimeout, LOCAL_AUTH, 1344 "Set Idle timeout", "set timeout value"}, 1345#ifndef NOMSEXT 1346 {"ns", NULL, SetNS, LOCAL_AUTH, 1347 "Set NameServer", "set ns pri-addr [sec-addr]"}, 1348 {"nbns", NULL, SetNBNS, LOCAL_AUTH, 1349 "Set NetBIOS NameServer", "set nbns pri-addr [sec-addr]"}, 1350#endif 1351 {"help", "?", HelpCommand, LOCAL_AUTH | LOCAL_NO_AUTH, 1352 "Display this message", "set help|? [command]", (void *) SetCommands}, 1353 {NULL, NULL, NULL}, 1354}; 1355 1356static int 1357SetCommand(struct cmdtab const * list, int argc, char **argv) 1358{ 1359 if (argc > 0) 1360 FindExec(SetCommands, argc, argv); 1361 else if (VarTerm) 1362 fprintf(VarTerm, "Use `set ?' to get a list or `set ? <var>' for" 1363 " syntax help.\n"); 1364 else 1365 LogPrintf(LogWARN, "set command must have arguments\n"); 1366 1367 return 0; 1368} 1369 1370 1371static int 1372AddCommand(struct cmdtab const * list, int argc, char **argv) 1373{ 1374 struct in_addr dest, gateway, netmask; 1375 1376 if (argc == 3) { 1377 if (strcasecmp(argv[0], "MYADDR") == 0) 1378 dest = IpcpInfo.want_ipaddr; 1379 else 1380 dest = GetIpAddr(argv[0]); 1381 netmask = GetIpAddr(argv[1]); 1382 if (strcasecmp(argv[2], "HISADDR") == 0) 1383 gateway = IpcpInfo.his_ipaddr; 1384 else 1385 gateway = GetIpAddr(argv[2]); 1386 OsSetRoute(RTM_ADD, dest, gateway, netmask); 1387 return 0; 1388 } 1389 return -1; 1390} 1391 1392static int 1393DeleteCommand(struct cmdtab const * list, int argc, char **argv) 1394{ 1395 struct in_addr dest, gateway, netmask; 1396 1397 if (argc == 1 && strcasecmp(argv[0], "all") == 0) 1398 DeleteIfRoutes(0); 1399 else if (argc > 0 && argc < 4) { 1400 if (strcasecmp(argv[0], "MYADDR") == 0) 1401 dest = IpcpInfo.want_ipaddr; 1402 else 1403 dest = GetIpAddr(argv[0]); 1404 netmask.s_addr = INADDR_ANY; 1405 if (argc > 1) { 1406 if (strcasecmp(argv[1], "HISADDR") == 0) 1407 gateway = IpcpInfo.his_ipaddr; 1408 else 1409 gateway = GetIpAddr(argv[1]); 1410 if (argc == 3) { 1411 if (inet_aton(argv[2], &netmask) == 0) { 1412 LogPrintf(LogWARN, "Bad netmask value.\n"); 1413 return -1; 1414 } 1415 } 1416 } else 1417 gateway.s_addr = INADDR_ANY; 1418 OsSetRoute(RTM_DELETE, dest, gateway, netmask); 1419 } else 1420 return -1; 1421 1422 return 0; 1423} 1424 1425static int AliasEnable(); 1426static int AliasOption(); 1427 1428static struct cmdtab const AliasCommands[] = 1429{ 1430 {"enable", NULL, AliasEnable, LOCAL_AUTH, 1431 "enable IP aliasing", "alias enable [yes|no]"}, 1432 {"port", NULL, AliasRedirectPort, LOCAL_AUTH, 1433 "port redirection", "alias port [proto addr_local:port_local port_alias]"}, 1434 {"addr", NULL, AliasRedirectAddr, LOCAL_AUTH, 1435 "static address translation", "alias addr [addr_local addr_alias]"}, 1436 {"deny_incoming", NULL, AliasOption, LOCAL_AUTH, 1437 "stop incoming connections", "alias deny_incoming [yes|no]", 1438 (void *) PKT_ALIAS_DENY_INCOMING}, 1439 {"log", NULL, AliasOption, LOCAL_AUTH, 1440 "log aliasing link creation", "alias log [yes|no]", 1441 (void *) PKT_ALIAS_LOG}, 1442 {"same_ports", NULL, AliasOption, LOCAL_AUTH, 1443 "try to leave port numbers unchanged", "alias same_ports [yes|no]", 1444 (void *) PKT_ALIAS_SAME_PORTS}, 1445 {"use_sockets", NULL, AliasOption, LOCAL_AUTH, 1446 "allocate host sockets", "alias use_sockets [yes|no]", 1447 (void *) PKT_ALIAS_USE_SOCKETS}, 1448 {"unregistered_only", NULL, AliasOption, LOCAL_AUTH, 1449 "alias unregistered (private) IP address space only", 1450 "alias unregistered_only [yes|no]", 1451 (void *) PKT_ALIAS_UNREGISTERED_ONLY}, 1452 {"help", "?", HelpCommand, LOCAL_AUTH | LOCAL_NO_AUTH, 1453 "Display this message", "alias help|? [command]", 1454 (void *) AliasCommands}, 1455 {NULL, NULL, NULL}, 1456}; 1457 1458 1459static int 1460AliasCommand(struct cmdtab const * list, int argc, char **argv) 1461{ 1462 if (argc > 0) 1463 FindExec(AliasCommands, argc, argv); 1464 else if (VarTerm) 1465 fprintf(VarTerm, "Use `alias help' to get a list or `alias help <option>'" 1466 " for syntax help.\n"); 1467 else 1468 LogPrintf(LogWARN, "alias command must have arguments\n"); 1469 1470 return 0; 1471} 1472 1473static int 1474AliasEnable(struct cmdtab const * list, int argc, char **argv) 1475{ 1476 if (argc == 1) 1477 if (strcasecmp(argv[0], "yes") == 0) { 1478 if (!(mode & MODE_ALIAS)) { 1479 if (loadAliasHandlers(&VarAliasHandlers) == 0) { 1480 mode |= MODE_ALIAS; 1481 return 0; 1482 } 1483 LogPrintf(LogWARN, "Cannot load alias library\n"); 1484 return 1; 1485 } 1486 return 0; 1487 } else if (strcasecmp(argv[0], "no") == 0) { 1488 if (mode & MODE_ALIAS) { 1489 unloadAliasHandlers(); 1490 mode &= ~MODE_ALIAS; 1491 } 1492 return 0; 1493 } 1494 return -1; 1495} 1496 1497 1498static int 1499AliasOption(struct cmdtab const * list, int argc, char **argv, void *param) 1500{ 1501 if (argc == 1) 1502 if (strcasecmp(argv[0], "yes") == 0) { 1503 if (mode & MODE_ALIAS) { 1504 VarPacketAliasSetMode((unsigned) param, (unsigned) param); 1505 return 0; 1506 } 1507 LogPrintf(LogWARN, "alias not enabled\n"); 1508 } else if (strcmp(argv[0], "no") == 0) { 1509 if (mode & MODE_ALIAS) { 1510 VarPacketAliasSetMode(0, (unsigned) param); 1511 return 0; 1512 } 1513 LogPrintf(LogWARN, "alias not enabled\n"); 1514 } 1515 return -1; 1516} 1517