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