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