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