command.c revision 26321
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.51 1997/05/29 02:29:12 brian Exp $ 21 * 22 */ 23#include <sys/types.h> 24#include <ctype.h> 25#include <termios.h> 26#include <sys/wait.h> 27#include <time.h> 28#include <netdb.h> 29#include <sys/socket.h> 30#include <netinet/in.h> 31#include <arpa/inet.h> 32#include <net/route.h> 33#include <paths.h> 34#include <alias.h> 35#include "fsm.h" 36#include "phase.h" 37#include "lcp.h" 38#include "ipcp.h" 39#include "modem.h" 40#include "filter.h" 41#include "command.h" 42#include "alias_cmd.h" 43#include "hdlc.h" 44#include "loadalias.h" 45#include "vars.h" 46#include "systems.h" 47#include "chat.h" 48#include "os.h" 49 50extern void Cleanup(), TtyTermMode(), PacketMode(); 51extern int EnableCommand(), DisableCommand(), DisplayCommand(); 52extern int AcceptCommand(), DenyCommand(); 53static int AliasCommand(); 54extern int LocalAuthCommand(); 55extern int LoadCommand(), SaveCommand(); 56extern int ChangeParity(char *); 57extern int SelectSystem(); 58extern int ShowRoute(); 59extern void TtyOldMode(), TtyCommandMode(); 60extern struct pppvars pppVars; 61extern struct cmdtab const SetCommands[]; 62 63extern char *IfDevName; 64 65struct in_addr ifnetmask; 66int randinit; 67 68static int ShowCommand(), TerminalCommand(), QuitCommand(); 69static int CloseCommand(), DialCommand(), DownCommand(); 70static int SetCommand(), AddCommand(), DeleteCommand(); 71static int ShellCommand(); 72 73static int 74HelpCommand(list, argc, argv, plist) 75struct cmdtab *list; 76int argc; 77char **argv; 78struct cmdtab *plist; 79{ 80 struct cmdtab *cmd; 81 int n; 82 83 if (argc > 0) { 84 for (cmd = plist; cmd->name; cmd++) { 85 if (strcasecmp(cmd->name, *argv) == 0 && (cmd->lauth & VarLocalAuth)) { 86 if (plist == SetCommands) 87 printf("set "); 88 printf("%s %s\n", cmd->name, cmd->syntax); 89 return(1); 90 } 91 } 92 return(1); 93 } 94 n = 0; 95 for (cmd = plist; cmd->func; cmd++) { 96 if (cmd->name && (cmd->lauth & VarLocalAuth)) { 97 printf(" %-8s: %-20s\n", cmd->name, cmd->helpmes); 98 n++; 99 } 100 } 101 if (n & 1) 102 printf("\n"); 103 return(1); 104} 105 106int 107IsInteractive() 108{ 109 char *mes = NULL; 110 111 if (mode & MODE_DDIAL) 112 mes = "Working in dedicated dial mode."; 113 else if (mode & MODE_BACKGROUND) 114 mes = "Working in background mode."; 115 else if (mode & MODE_AUTO) 116 mes = "Working in auto mode."; 117 else if (mode & MODE_DIRECT) 118 mes = "Working in direct mode."; 119 else if (mode & MODE_DEDICATED) 120 mes = "Working in dedicated mode."; 121 if (mes) { 122 printf("%s\n", mes); 123 return(0); 124 } 125 return(1); 126} 127 128static int 129DialCommand(cmdlist, argc, argv) 130struct cmdtab *cmdlist; 131int argc; 132char **argv; 133{ 134 int tries; 135 136 if (LcpFsm.state > ST_CLOSED) { 137 printf("LCP state is [%s]\n", StateNames[LcpFsm.state]); 138 return(1); 139 } 140 if (!IsInteractive()) 141 return(1); 142 if (argc > 0) { 143 if (SelectSystem(*argv, CONFFILE) < 0) { 144 printf("%s: not found.\n", *argv); 145 return(1); 146 } 147 } 148 tries = 0; 149 do { 150 printf("Dial attempt %u of %d\n", ++tries, VarDialTries); 151 modem = OpenModem(mode); 152 if (modem < 0) { 153 printf("failed to open modem.\n"); 154 break; 155 } 156 if (DialModem() == EX_DONE) { 157 sleep(1); 158 ModemTimeout(); 159 PacketMode(); 160 break; 161 } 162 } while (VarDialTries == 0 || tries < VarDialTries); 163 return(1); 164} 165 166static int 167ShellCommand(cmdlist, argc, argv) 168struct cmdtab *cmdlist; 169int argc; 170char **argv; 171{ 172 const char *shell; 173 pid_t shpid; 174 175 if((shell = getenv("SHELL")) == 0) { 176 shell = _PATH_BSHELL; 177 } 178#ifdef SHELL_ONLY_INTERACTIVELY 179#ifndef HAVE_SHELL_CMD_WITH_ANY_MODE 180 if( mode != MODE_INTER) { 181 fprintf(stdout, 182 "Can only start a shell in interactive mode\n"); 183 return(1); 184 } 185#else 186 if(argc == 0 && !(mode & MODE_INTER)) { 187 fprintf(stderr, 188 "Can only start an interactive shell in interactive mode\n"); 189 return(1); 190 } 191#endif /* HAVE_SHELL_CMD_WITH_ANY_MODE */ 192#else 193 if ((mode & (MODE_AUTO|MODE_INTER)) == (MODE_AUTO|MODE_INTER)) { 194 fprintf(stdout, 195 "Shell is not allowed interactively in auto mode\n"); 196 return(1); 197 } 198#endif /* SHELL_ONLY_INTERACTIVELY */ 199 if((shpid = fork()) == 0) { 200 int dtablesize, i ; 201 202 for (dtablesize = getdtablesize(), i = 3; i < dtablesize; i++) 203 (void)close(i); 204 205 /* 206 * We are running setuid, we should change to 207 * real user for avoiding security problems. 208 */ 209 if (setgid(getgid()) < 0) { 210 perror("setgid"); 211 exit(1); 212 } 213 if (setuid(getuid()) < 0) { 214 perror("setuid"); 215 exit(1); 216 } 217 TtyOldMode(); 218 if(argc > 0) { 219 /* substitute pseudo args */ 220 for (i=1; i<argc; i++) { 221 if (strcasecmp(argv[i], "HISADDR") == 0) { 222 argv[i] = strdup(inet_ntoa(IpcpInfo.his_ipaddr)); 223 } 224 if (strcasecmp(argv[i], "INTERFACE") == 0) { 225 argv[i] = strdup(IfDevName); 226 } 227 if (strcasecmp(argv[i], "MYADDR") == 0) { 228 argv[i] = strdup(inet_ntoa(IpcpInfo.want_ipaddr)); 229 } 230 } 231 (void)execvp(argv[0], argv); 232 } 233 else 234 (void)execl(shell, shell, NULL); 235 236 fprintf(stdout, "exec() of %s failed\n", argc > 0? argv[0]: shell); 237 exit(255); 238 } 239 if( shpid == (pid_t)-1 ) { 240 fprintf(stdout, "Fork failed\n"); 241 } else { 242 int status; 243 (void)waitpid(shpid, &status, 0); 244 } 245 246 TtyCommandMode(1); 247 248 return(0); 249} 250 251static char StrOption[] = "option .."; 252static char StrRemote[] = "[remote]"; 253char StrNull[] = ""; 254 255struct cmdtab const Commands[] = { 256 { "accept", NULL, AcceptCommand, LOCAL_AUTH, 257 "accept option request", StrOption}, 258 { "add", NULL, AddCommand, LOCAL_AUTH, 259 "add route", "dest mask gateway"}, 260 { "close", NULL, CloseCommand, LOCAL_AUTH, 261 "Close connection", StrNull}, 262 { "delete", NULL, DeleteCommand, LOCAL_AUTH, 263 "delete route", "ALL | dest gateway [mask]"}, 264 { "deny", NULL, DenyCommand, LOCAL_AUTH, 265 "Deny option request", StrOption}, 266 { "dial", "call", DialCommand, LOCAL_AUTH, 267 "Dial and login", StrRemote}, 268 { "disable", NULL, DisableCommand, LOCAL_AUTH, 269 "Disable option", StrOption}, 270 { "display", NULL, DisplayCommand, LOCAL_AUTH, 271 "Display option configs", StrNull}, 272 { "enable", NULL, EnableCommand, LOCAL_AUTH, 273 "Enable option", StrOption}, 274 { "passwd", NULL, LocalAuthCommand,LOCAL_NO_AUTH, 275 "Password for manipulation", StrOption}, 276 { "load", NULL, LoadCommand, LOCAL_AUTH, 277 "Load settings", StrRemote}, 278 { "save", NULL, SaveCommand, LOCAL_AUTH, 279 "Save settings", StrNull}, 280 { "set", "setup", SetCommand, LOCAL_AUTH, 281 "Set parameters", "var value"}, 282 { "shell", "!", ShellCommand, LOCAL_AUTH, 283 "Run a subshell", "[sh command]"}, 284 { "show", NULL, ShowCommand, LOCAL_AUTH, 285 "Show status and statictics", "var"}, 286 { "term", NULL, TerminalCommand,LOCAL_AUTH, 287 "Enter to terminal mode", StrNull}, 288 { "alias", NULL, AliasCommand, LOCAL_AUTH, 289 "alias control", "option [yes|no]"}, 290 { "quit", "bye", QuitCommand, LOCAL_AUTH | LOCAL_NO_AUTH, 291 "Quit PPP program", "[all]"}, 292 { "help", "?", HelpCommand, LOCAL_AUTH | LOCAL_NO_AUTH, 293 "Display this message", "[command]", (void *)Commands }, 294 { NULL, "down", DownCommand, LOCAL_AUTH, 295 "Generate down event", StrNull}, 296 { NULL, NULL, NULL }, 297}; 298 299extern int ReportCcpStatus(); 300extern int ReportLcpStatus(); 301extern int ReportIpcpStatus(); 302extern int ReportProtStatus(); 303extern int ReportCompress(); 304extern int ShowModemStatus(); 305extern int ReportHdlcStatus(); 306extern int ShowMemMap(); 307 308static char *LogLevelName[] = { 309 LM_PHASE, LM_CHAT, LM_LQM, LM_LCP, 310 LM_TCPIP, LM_HDLC, LM_ASYNC, LM_LINK, 311 LM_CONNECT, LM_CARRIER, 312}; 313 314static int ShowDebugLevel() 315{ 316 int i; 317 318 printf("%02x: ", loglevel); 319 for (i = LOG_PHASE; i < MAXLOGLEVEL; i++) { 320 if (loglevel & (1 << i)) 321 printf("%s ", LogLevelName[i]); 322 } 323 printf("\n"); 324 return(1); 325} 326 327static int ShowEscape() 328{ 329 int code, bit; 330 331 if (EscMap[32]) { 332 for (code = 0; code < 32; code++) { 333 if (EscMap[code]) { 334 for (bit = 0; bit < 8; bit++) { 335 if (EscMap[code] & (1<<bit)) { 336 printf(" 0x%02x", (code << 3) + bit); 337 } 338 } 339 } 340 } 341 printf("\n"); 342 } 343 return(1); 344} 345 346static int ShowTimeout() 347{ 348 printf(" Idle Timer: %d secs LQR Timer: %d secs Retry Timer: %d secs\n", 349 VarIdleTimeout, VarLqrTimeout, VarRetryTimeout); 350 return(1); 351} 352 353static int ShowAuthKey() 354{ 355 printf("AuthName = %s\n", VarAuthName); 356 printf("AuthKey = %s\n", VarAuthKey); 357 return(1); 358} 359 360static int ShowVersion() 361{ 362 extern char VarVersion[]; 363 extern char VarLocalVersion[]; 364 365 printf("%s - %s \n", VarVersion, VarLocalVersion); 366 return(1); 367} 368 369static int ShowLogList() 370{ 371 ListLog(); 372 return(1); 373} 374 375static int ShowReconnect() 376{ 377 printf(" Reconnect Timer: %d, %d tries\n", 378 VarReconnectTimer, VarReconnectTries); 379 return(1); 380} 381 382static int ShowRedial() 383{ 384 printf(" Redial Timer: "); 385 386 if (VarRedialTimeout >= 0) { 387 printf(" %d seconds, ", VarRedialTimeout); 388 } 389 else { 390 printf(" Random 0 - %d seconds, ", REDIAL_PERIOD); 391 } 392 393 printf(" Redial Next Timer: "); 394 395 if (VarRedialNextTimeout >= 0) { 396 printf(" %d seconds, ", VarRedialNextTimeout); 397 } 398 else { 399 printf(" Random 0 - %d seconds, ", REDIAL_PERIOD); 400 } 401 402 if (VarDialTries) 403 printf("%d dial tries", VarDialTries); 404 405 printf("\n"); 406 407 return(1); 408} 409 410#ifdef MSEXT 411static int ShowMSExt() 412{ 413 printf(" MS PPP extention values \n" ); 414 printf(" Primary NS : %s\n", inet_ntoa( ns_entries[0] )); 415 printf(" Secondary NS : %s\n", inet_ntoa( ns_entries[1] )); 416 printf(" Primary NBNS : %s\n", inet_ntoa( nbns_entries[0] )); 417 printf(" Secondary NBNS : %s\n", inet_ntoa( nbns_entries[1] )); 418 419 return(1); 420} 421#endif /* MSEXT */ 422 423extern int ShowIfilter(), ShowOfilter(), ShowDfilter(), ShowAfilter(); 424 425struct cmdtab const ShowCommands[] = { 426 { "afilter", NULL, ShowAfilter, LOCAL_AUTH, 427 "Show keep Alive filters", StrOption}, 428 { "auth", NULL, ShowAuthKey, LOCAL_AUTH, 429 "Show auth name/key", StrNull}, 430 { "ccp", NULL, ReportCcpStatus, LOCAL_AUTH, 431 "Show CCP status", StrNull}, 432 { "compress", NULL, ReportCompress, LOCAL_AUTH, 433 "Show compression statictics", StrNull}, 434 { "debug", NULL, ShowDebugLevel, LOCAL_AUTH, 435 "Show current debug level", StrNull}, 436 { "dfilter", NULL, ShowDfilter, LOCAL_AUTH, 437 "Show Demand filters", StrOption}, 438 { "escape", NULL, ShowEscape, LOCAL_AUTH, 439 "Show escape characters", StrNull}, 440 { "hdlc", NULL, ReportHdlcStatus, LOCAL_AUTH, 441 "Show HDLC error summary", StrNull}, 442 { "ifilter", NULL, ShowIfilter, LOCAL_AUTH, 443 "Show Input filters", StrOption}, 444 { "ipcp", NULL, ReportIpcpStatus, LOCAL_AUTH, 445 "Show IPCP status", StrNull}, 446 { "lcp", NULL, ReportLcpStatus, LOCAL_AUTH, 447 "Show LCP status", StrNull}, 448 { "log", NULL, ShowLogList, LOCAL_AUTH, 449 "Show log records", StrNull}, 450 { "mem", NULL, ShowMemMap, LOCAL_AUTH, 451 "Show memory map", StrNull}, 452 { "modem", NULL, ShowModemStatus, LOCAL_AUTH, 453 "Show modem setups", StrNull}, 454 { "ofilter", NULL, ShowOfilter, LOCAL_AUTH, 455 "Show Output filters", StrOption}, 456 { "proto", NULL, ReportProtStatus, LOCAL_AUTH, 457 "Show protocol summary", StrNull}, 458 { "reconnect",NULL, ShowReconnect, LOCAL_AUTH, 459 "Show Reconnect timer,tries", StrNull}, 460 { "redial", NULL, ShowRedial, LOCAL_AUTH, 461 "Show Redial timeout value", StrNull}, 462 { "route", NULL, ShowRoute, LOCAL_AUTH, 463 "Show routing table", StrNull}, 464 { "timeout", NULL, ShowTimeout, LOCAL_AUTH, 465 "Show Idle timeout value", StrNull}, 466#ifdef MSEXT 467 { "msext", NULL, ShowMSExt, LOCAL_AUTH, 468 "Show MS PPP extentions", StrNull}, 469#endif /* MSEXT */ 470 { "version", NULL, ShowVersion, LOCAL_NO_AUTH | LOCAL_AUTH, 471 "Show version string", StrNull}, 472 { "help", "?", HelpCommand, LOCAL_NO_AUTH | LOCAL_AUTH, 473 "Display this message", StrNull, (void *)ShowCommands}, 474 { NULL, NULL, NULL }, 475}; 476 477struct cmdtab * 478FindCommand(cmds, str, pmatch) 479struct cmdtab *cmds; 480char *str; 481int *pmatch; 482{ 483 int nmatch = 0; 484 int len = strlen(str); 485 struct cmdtab *found = NULL; 486 487 while (cmds->func) { 488 if (cmds->name && strncasecmp(str, cmds->name, len) == 0) { 489 nmatch++; 490 found = cmds; 491 } else if (cmds->alias && strncasecmp(str, cmds->alias, len) == 0) { 492 nmatch++; 493 found = cmds; 494 } 495 cmds++; 496 } 497 *pmatch = nmatch; 498 return(found); 499} 500 501int 502FindExec(cmdlist, argc, argv) 503struct cmdtab *cmdlist; 504int argc; 505char **argv; 506{ 507 struct cmdtab *cmd; 508 int val = 1; 509 int nmatch; 510 511 cmd = FindCommand(cmdlist, *argv, &nmatch); 512 if (nmatch > 1) 513 printf("Ambiguous.\n"); 514 else if (cmd && ( cmd->lauth & VarLocalAuth ) ) 515 val = (cmd->func)(cmd, --argc, ++argv, cmd->args); 516 else 517 printf("what?\n"); 518 return(val); 519} 520 521int aft_cmd = 1; 522 523void 524Prompt() 525{ 526 char *pconnect, *pauth; 527 528 if (!(mode & MODE_INTER)) 529 return; 530 531 if (!aft_cmd) 532 printf("\n"); 533 else 534 aft_cmd = 0; 535 536 if ( VarLocalAuth == LOCAL_AUTH ) 537 pauth = " ON "; 538 else 539 pauth = " on "; 540 if (IpcpFsm.state == ST_OPENED && phase == PHASE_NETWORK) 541 pconnect = "PPP"; 542 else 543 pconnect = "ppp"; 544 printf("%s%s%s> ", pconnect, pauth, VarShortHost); 545 fflush(stdout); 546} 547 548void 549DecodeCommand(buff, nb, prompt) 550char *buff; 551int nb; 552int prompt; 553{ 554 char *vector[20]; 555 char **argv; 556 int argc, val; 557 char *cp; 558 559 val = 1; 560 if (nb > 0) { 561 cp = buff + strcspn(buff, "\r\n"); 562 if (cp) 563 *cp = '\0'; 564 { 565 argc = MakeArgs(buff, vector, VECSIZE(vector)); 566 argv = vector; 567 568 if (argc > 0) 569 val = FindExec(Commands, argc, argv); 570 } 571 } 572 if (val && prompt) 573 Prompt(); 574} 575 576static int 577ShowCommand(list, argc, argv) 578struct cmdtab *list; 579int argc; 580char **argv; 581{ 582 int val = 1; 583 584 if (argc > 0) 585 val = FindExec(ShowCommands, argc, argv); 586 else 587 printf("Use ``show ?'' to get a list.\n"); 588 return(val); 589} 590 591static int 592TerminalCommand() 593{ 594 if (LcpFsm.state > ST_CLOSED) { 595 printf("LCP state is [%s]\n", StateNames[LcpFsm.state]); 596 return(1); 597 } 598 if (!IsInteractive()) 599 return(1); 600 modem = OpenModem(mode); 601 if (modem < 0) { 602 printf("failed to open modem.\n"); 603 return(1); 604 } 605 printf("Enter to terminal mode.\n"); 606 printf("Type `~?' for help.\n"); 607 TtyTermMode(); 608 return(0); 609} 610 611static int 612QuitCommand(list, argc, argv) 613struct cmdtab *list; 614int argc; 615char **argv; 616{ 617 if (mode & (MODE_DIRECT|MODE_DEDICATED|MODE_AUTO)) { 618 if (argc > 0 && (VarLocalAuth & LOCAL_AUTH)) { 619 Cleanup(EX_NORMAL); 620 mode &= ~MODE_INTER; 621 } else { 622 LogPrintf(LOG_PHASE_BIT, "client connection closed.\n"); 623 VarLocalAuth = LOCAL_NO_AUTH; 624 close(netfd); 625 close(1); 626 dup2(2, 1); /* Have to have something here or the modem will be 1 */ 627 netfd = -1; 628 mode &= ~MODE_INTER; 629 } 630 } else 631 Cleanup(EX_NORMAL); 632 return(1); 633} 634 635static int 636CloseCommand() 637{ 638 reconnect(RECON_FALSE); 639 LcpClose(); 640 if (mode & MODE_BACKGROUND) 641 Cleanup(EX_NORMAL); 642 return(1); 643} 644 645static int 646DownCommand() 647{ 648 LcpDown(); 649 return(1); 650} 651 652static int 653SetModemSpeed(list, argc, argv) 654struct cmdtab *list; 655int argc; 656char **argv; 657{ 658 int speed; 659 660 if (argc > 0) { 661 if (strcmp(*argv, "sync") == 0) { 662 VarSpeed = 0; 663 return(1); 664 } 665 speed = atoi(*argv); 666 if (IntToSpeed(speed) != B0) { 667 VarSpeed = speed; 668 return(1); 669 } 670 printf("invalid speed.\n"); 671 } 672 return(1); 673} 674 675static int 676SetReconnect(list, argc, argv) 677struct cmdtab *list; 678int argc; 679char **argv; 680{ 681 if (argc == 2) { 682 VarReconnectTimer = atoi(argv[0]); 683 VarReconnectTries = atoi(argv[1]); 684 } else 685 printf("Usage: %s %s\n", list->name, list->syntax); 686 return(1); 687} 688 689static int 690SetRedialTimeout(list, argc, argv) 691struct cmdtab *list; 692int argc; 693char **argv; 694{ 695 int timeout; 696 int tries; 697 char *dot; 698 699 if (argc == 1 || argc == 2 ) { 700 if (strncasecmp(argv[0], "random", 6) == 0 && 701 (argv[0][6] == '\0' || argv[0][6] == '.')) { 702 VarRedialTimeout = -1; 703 printf("Using random redial timeout.\n"); 704 if (!randinit) { 705 randinit = 1; 706 if (srandomdev() < 0) 707 srandom((unsigned long)(time(NULL) ^ getpid())); 708 } 709 } 710 else { 711 timeout = atoi(argv[0]); 712 713 if (timeout >= 0) { 714 VarRedialTimeout = timeout; 715 } 716 else { 717 printf("invalid redial timeout\n"); 718 printf("Usage: %s %s\n", list->name, list->syntax); 719 } 720 } 721 722 dot = index(argv[0],'.'); 723 if (dot) { 724 if (strcasecmp(++dot, "random") == 0) { 725 VarRedialNextTimeout = -1; 726 printf("Using random next redial timeout.\n"); 727 if (!randinit) { 728 randinit = 1; 729 if (srandomdev() < 0) 730 srandom((unsigned long)(time(NULL) ^ getpid())); 731 } 732 } 733 else { 734 timeout = atoi(dot); 735 if (timeout >= 0) { 736 VarRedialNextTimeout = timeout; 737 } 738 else { 739 printf("invalid next redial timeout\n"); 740 printf("Usage: %s %s\n", list->name, list->syntax); 741 } 742 } 743 } 744 else 745 VarRedialNextTimeout = NEXT_REDIAL_PERIOD; /* Default next timeout */ 746 747 if (argc == 2) { 748 tries = atoi(argv[1]); 749 750 if (tries >= 0) { 751 VarDialTries = tries; 752 } 753 else { 754 printf("invalid retry value\n"); 755 printf("Usage: %s %s\n", list->name, list->syntax); 756 } 757 } 758 } 759 else { 760 printf("Usage: %s %s\n", list->name, list->syntax); 761 } 762 return(1); 763} 764 765static int 766SetModemParity(list, argc, argv) 767struct cmdtab *list; 768int argc; 769char **argv; 770{ 771 int parity; 772 773 if (argc > 0) { 774 parity = ChangeParity(*argv); 775 if (parity < 0) 776 printf("Invalid parity.\n"); 777 else 778 VarParity = parity; 779 } 780 return(1); 781} 782 783static int 784SetDebugLevel(list, argc, argv) 785struct cmdtab *list; 786int argc; 787char **argv; 788{ 789 int level, w; 790 791 for (level = 0; argc-- > 0; argv++) { 792 if (isdigit(**argv)) { 793 w = atoi(*argv); 794 if (w < 0 || w >= MAXLOGLEVEL) { 795 printf("invalid log level.\n"); 796 break; 797 } else 798 level |= (1 << w); 799 } else { 800 for (w = 0; w < MAXLOGLEVEL; w++) { 801 if (strcasecmp(*argv, LogLevelName[w]) == 0) { 802 level |= (1 << w); 803 continue; 804 } 805 } 806 } 807 } 808 loglevel = level; 809 return(1); 810} 811 812static int 813SetEscape(list, argc, argv) 814struct cmdtab *list; 815int argc; 816char **argv; 817{ 818 int code; 819 820 for (code = 0; code < 33; code++) 821 EscMap[code] = 0; 822 while (argc-- > 0) { 823 sscanf(*argv++, "%x", &code); 824 code &= 0xff; 825 EscMap[code >> 3] |= (1 << (code&7)); 826 EscMap[32] = 1; 827 } 828 return(1); 829} 830 831static int 832SetInitialMRU(list, argc, argv) 833struct cmdtab *list; 834int argc; 835char **argv; 836{ 837 int mru; 838 839 if (argc > 0) { 840 mru = atoi(*argv); 841 if (mru < 100) 842 printf("given value is too small.\n"); 843 else if (mru > MAX_MRU) 844 printf("given value is too big.\n"); 845 else 846 VarMRU = mru; 847 } 848 return(1); 849} 850 851static int 852SetIdleTimeout(list, argc, argv) 853struct cmdtab *list; 854int argc; 855char **argv; 856{ 857 if (argc-- > 0) { 858 VarIdleTimeout = atoi(*argv++); 859 if (argc-- > 0) { 860 VarLqrTimeout = atoi(*argv++); 861 if (VarLqrTimeout < 1) 862 VarLqrTimeout = 30; 863 if (argc > 0) { 864 VarRetryTimeout = atoi(*argv); 865 if (VarRetryTimeout < 1 || VarRetryTimeout > 10) 866 VarRetryTimeout = 3; 867 } 868 } 869 } 870 return(1); 871} 872 873struct in_addr 874GetIpAddr(cp) 875char *cp; 876{ 877 struct hostent *hp; 878 struct in_addr ipaddr; 879 880 hp = gethostbyname(cp); 881 if (hp && hp->h_addrtype == AF_INET) 882 bcopy(hp->h_addr, &ipaddr, hp->h_length); 883 else if (inet_aton(cp, &ipaddr) == 0) 884 ipaddr.s_addr = 0; 885 return(ipaddr); 886} 887 888static int 889SetInterfaceAddr(list, argc, argv) 890struct cmdtab *list; 891int argc; 892char **argv; 893{ 894 895 DefMyAddress.ipaddr.s_addr = DefHisAddress.ipaddr.s_addr = 0L; 896 if (argc > 4) { 897 printf("set ifaddr: too many arguments (%d > 4)\n", argc); 898 return(0); 899 } 900 if (argc > 0) { 901 if (ParseAddr(argc, argv++, 902 &DefMyAddress.ipaddr, 903 &DefMyAddress.mask, 904 &DefMyAddress.width) == 0) 905 return(0); 906 if (--argc > 0) { 907 if (ParseAddr(argc, argv++, 908 &DefHisAddress.ipaddr, 909 &DefHisAddress.mask, 910 &DefHisAddress.width) == 0) 911 return(0); 912 if (--argc > 0) { 913 ifnetmask = GetIpAddr(*argv); 914 if (--argc > 0) { 915 if (ParseAddr(argc, argv++, 916 &DefTriggerAddress.ipaddr, 917 &DefTriggerAddress.mask, 918 &DefTriggerAddress.width) == 0) 919 return(0); 920 } 921 } 922 } 923 } 924 /* 925 * For backwards compatibility, 0.0.0.0 means any address. 926 */ 927 if (DefMyAddress.ipaddr.s_addr == 0) { 928 DefMyAddress.mask.s_addr = 0; 929 DefMyAddress.width = 0; 930 } 931 if (DefHisAddress.ipaddr.s_addr == 0) { 932 DefHisAddress.mask.s_addr = 0; 933 DefHisAddress.width = 0; 934 } 935 936 if ((mode & MODE_AUTO) || 937 ((mode & MODE_DEDICATED) && dstsystem)) { 938 if (OsSetIpaddress(DefMyAddress.ipaddr, DefHisAddress.ipaddr, ifnetmask) < 0) 939 return(0); 940 } 941 return(1); 942} 943 944#ifdef MSEXT 945 946void 947SetMSEXT(pri_addr, sec_addr, argc, argv) 948struct in_addr *pri_addr; 949struct in_addr *sec_addr; 950int argc; 951char **argv; 952{ 953 int dummyint; 954 struct in_addr dummyaddr; 955 956 pri_addr->s_addr = sec_addr->s_addr = 0L; 957 958 if( argc > 0 ) { 959 ParseAddr(argc, argv++, pri_addr, &dummyaddr, &dummyint); 960 if( --argc > 0 ) 961 ParseAddr(argc, argv++, sec_addr, &dummyaddr, &dummyint); 962 else 963 sec_addr->s_addr = pri_addr->s_addr; 964 } 965 966 /* 967 * if the primary/secondary ns entries are 0.0.0.0 we should 968 * set them to either the localhost's ip, or the values in 969 * /etc/resolv.conf ?? 970 * 971 * up to you if you want to implement this... 972 */ 973 974} 975 976static int 977SetNS(list, argc, argv) 978struct cmdtab *list; 979int argc; 980char **argv; 981{ 982 SetMSEXT(&ns_entries[0], &ns_entries[1], argc, argv); 983 return(1); 984} 985 986static int 987SetNBNS(list, argc, argv) 988struct cmdtab *list; 989int argc; 990char **argv; 991{ 992 SetMSEXT(&nbns_entries[0], &nbns_entries[1], argc, argv); 993 return(1); 994} 995 996#endif /* MS_EXT */ 997 998#define VAR_AUTHKEY 0 999#define VAR_DIAL 1 1000#define VAR_LOGIN 2 1001#define VAR_AUTHNAME 3 1002#define VAR_DEVICE 4 1003#define VAR_ACCMAP 5 1004#define VAR_PHONE 6 1005 1006static int 1007SetVariable(list, argc, argv, param) 1008struct cmdtab *list; 1009int argc; 1010char **argv; 1011int param; 1012{ 1013 u_long map; 1014 1015 if (argc > 0) { 1016 switch (param) { 1017 case VAR_AUTHKEY: 1018 strncpy(VarAuthKey, *argv, sizeof(VarAuthKey)-1); 1019 VarAuthKey[sizeof(VarAuthKey)-1] = '\0'; 1020 break; 1021 case VAR_AUTHNAME: 1022 strncpy(VarAuthName, *argv, sizeof(VarAuthName)-1); 1023 VarAuthName[sizeof(VarAuthName)-1] = '\0'; 1024 break; 1025 case VAR_DIAL: 1026 strncpy(VarDialScript, *argv, sizeof(VarDialScript)-1); 1027 VarDialScript[sizeof(VarDialScript)-1] = '\0'; 1028 break; 1029 case VAR_LOGIN: 1030 strncpy(VarLoginScript, *argv, sizeof(VarLoginScript)-1); 1031 VarLoginScript[sizeof(VarLoginScript)-1] = '\0'; 1032 break; 1033 case VAR_DEVICE: 1034 strncpy(VarDevice, *argv, sizeof(VarDevice)-1); 1035 VarDevice[sizeof(VarDevice)-1] = '\0'; 1036 VarBaseDevice = rindex(VarDevice, '/'); 1037 VarBaseDevice = VarBaseDevice ? VarBaseDevice + 1 : ""; 1038 break; 1039 case VAR_ACCMAP: 1040 sscanf(*argv, "%lx", &map); 1041 VarAccmap = map; 1042 break; 1043 case VAR_PHONE: 1044 strncpy(VarPhoneList, *argv, sizeof(VarPhoneList)-1); 1045 VarPhoneList[sizeof(VarPhoneList)-1] = '\0'; 1046 strcpy(VarPhoneCopy, VarPhoneList); 1047 VarNextPhone = VarPhoneCopy; 1048 break; 1049 } 1050 } 1051 return(1); 1052} 1053 1054static int SetCtsRts(list, argc, argv) 1055struct cmdtab *list; 1056int argc; 1057char **argv; 1058{ 1059 if (argc > 0) { 1060 if (strcmp(*argv, "on") == 0) 1061 VarCtsRts = TRUE; 1062 else if (strcmp(*argv, "off") == 0) 1063 VarCtsRts = FALSE; 1064 else 1065 printf("usage: set ctsrts [on|off].\n"); 1066 } 1067 return(1); 1068} 1069 1070 1071static int SetOpenMode(list, argc, argv) 1072struct cmdtab *list; 1073int argc; 1074char **argv; 1075{ 1076 if (argc > 0) { 1077 if (strcmp(*argv, "active") == 0) 1078 VarOpenMode = OPEN_ACTIVE; 1079 else if (strcmp(*argv, "passive") == 0) 1080 VarOpenMode = OPEN_PASSIVE; 1081 else 1082 printf("Invalid mode.\n"); 1083 } 1084 return(1); 1085} 1086static char StrChatStr[] = "chat-script"; 1087static char StrValue[] = "value"; 1088 1089extern int SetIfilter(), SetOfilter(), SetDfilter(), SetAfilter(); 1090 1091struct cmdtab const SetCommands[] = { 1092 { "accmap", NULL, SetVariable, LOCAL_AUTH, 1093 "Set accmap value", "hex-value", (void *)VAR_ACCMAP}, 1094 { "afilter", NULL, SetAfilter, LOCAL_AUTH, 1095 "Set keep Alive filter", "..."}, 1096 { "authkey", "key", SetVariable, LOCAL_AUTH, 1097 "Set authentication key", "key", (void *)VAR_AUTHKEY}, 1098 { "authname", NULL, SetVariable, LOCAL_AUTH, 1099 "Set authentication name", "name", (void *)VAR_AUTHNAME}, 1100 { "ctsrts", NULL, SetCtsRts, LOCAL_AUTH, 1101 "Use CTS/RTS modem signalling", "[on|off]"}, 1102 { "debug", NULL, SetDebugLevel, LOCAL_AUTH, 1103 "Set debug level", StrValue}, 1104 { "device", "line", SetVariable, LOCAL_AUTH, 1105 "Set modem device name", "device-name", (void *)VAR_DEVICE}, 1106 { "dfilter", NULL, SetDfilter, LOCAL_AUTH, 1107 "Set demand filter", "..."}, 1108 { "dial", NULL, SetVariable, LOCAL_AUTH, 1109 "Set dialing script", StrChatStr, (void *)VAR_DIAL}, 1110 { "escape", NULL, SetEscape, LOCAL_AUTH, 1111 "Set escape characters", "hex-digit ..."}, 1112 { "ifaddr", NULL, SetInterfaceAddr, LOCAL_AUTH, 1113 "Set destination address", "[src-addr [dst-addr [netmask [trg-addr]]]]"}, 1114 { "ifilter", NULL, SetIfilter, LOCAL_AUTH, 1115 "Set input filter", "..."}, 1116 { "login", NULL, SetVariable, LOCAL_AUTH, 1117 "Set login script", StrChatStr, (void *)VAR_LOGIN }, 1118 { "mru", NULL, SetInitialMRU, LOCAL_AUTH, 1119 "Set Initial MRU value", StrValue }, 1120 { "ofilter", NULL, SetOfilter, LOCAL_AUTH, 1121 "Set output filter", "..." }, 1122 { "openmode", NULL, SetOpenMode, LOCAL_AUTH, 1123 "Set open mode", "[active|passive]"}, 1124 { "parity", NULL, SetModemParity, LOCAL_AUTH, 1125 "Set modem parity", "[odd|even|none]"}, 1126 { "phone", NULL, SetVariable, LOCAL_AUTH, 1127 "Set telephone number(s)", "phone1[:phone2[...]]", (void *)VAR_PHONE }, 1128 { "reconnect",NULL, SetReconnect, LOCAL_AUTH, 1129 "Set Reconnect timeout", "value ntries"}, 1130 { "redial", NULL, SetRedialTimeout, LOCAL_AUTH, 1131 "Set Redial timeout", "value|random[.value|random] [dial_attempts]"}, 1132 { "speed", NULL, SetModemSpeed, LOCAL_AUTH, 1133 "Set modem speed", "speed"}, 1134 { "timeout", NULL, SetIdleTimeout, LOCAL_AUTH, 1135 "Set Idle timeout", StrValue}, 1136#ifdef MSEXT 1137 { "ns", NULL, SetNS, LOCAL_AUTH, 1138 "Set NameServer", "pri-addr [sec-addr]"}, 1139 { "nbns", NULL, SetNBNS, LOCAL_AUTH, 1140 "Set NetBIOS NameServer", "pri-addr [sec-addr]"}, 1141#endif /* MSEXT */ 1142 { "help", "?", HelpCommand, LOCAL_AUTH | LOCAL_NO_AUTH, 1143 "Display this message", StrNull, (void *)SetCommands}, 1144 { NULL, NULL, NULL }, 1145}; 1146 1147static int 1148SetCommand(list, argc, argv) 1149struct cmdtab *list; 1150int argc; 1151char **argv; 1152{ 1153 int val = 1; 1154 1155 if (argc > 0) 1156 val = FindExec(SetCommands, argc, argv); 1157 else 1158 printf("Use `set ?' to get a list or `set ? <var>' for syntax help.\n"); 1159 return(val); 1160} 1161 1162 1163static int 1164AddCommand(list, argc, argv) 1165struct cmdtab *list; 1166int argc; 1167char **argv; 1168{ 1169 struct in_addr dest, gateway, netmask; 1170 1171 if (argc == 3) { 1172 dest = GetIpAddr(argv[0]); 1173 netmask = GetIpAddr(argv[1]); 1174 if (strcasecmp(argv[2], "HISADDR") == 0) 1175 gateway = IpcpInfo.his_ipaddr; 1176 else 1177 gateway = GetIpAddr(argv[2]); 1178 OsSetRoute(RTM_ADD, dest, gateway, netmask); 1179 } else { 1180 printf("Usage: %s %s\n", list->name, list->syntax); 1181 } 1182 return(1); 1183} 1184 1185static int 1186DeleteCommand(list, argc, argv) 1187struct cmdtab *list; 1188int argc; 1189char **argv; 1190{ 1191 struct in_addr dest, gateway, netmask; 1192 1193 if (argc >= 2) { 1194 dest = GetIpAddr(argv[0]); 1195 if (strcasecmp(argv[1], "HISADDR") == 0) 1196 gateway = IpcpInfo.his_ipaddr; 1197 else 1198 gateway = GetIpAddr(argv[1]); 1199 netmask.s_addr = 0; 1200 if (argc == 3) { 1201 if (inet_aton(argv[1], &netmask) == 0) { 1202 printf("bad netmask value.\n"); 1203 return(1); 1204 } 1205 } 1206 OsSetRoute(RTM_DELETE, dest, gateway, netmask); 1207 } else if (argc == 1 && strcasecmp(argv[0], "ALL") == 0) { 1208 DeleteIfRoutes(0); 1209 } else { 1210 printf("Usage: %s %s\n", list->name, list->syntax); 1211 } 1212 return(1); 1213} 1214 1215 1216static int AliasEnable(); 1217static int AliasOption(); 1218 1219 1220static struct cmdtab const AliasCommands[] = 1221{ 1222 { "enable", NULL, AliasEnable, LOCAL_AUTH, 1223 "enable IP aliasing", "[yes|no]"}, 1224 { "port", NULL, AliasRedirectPort, LOCAL_AUTH, 1225 "port redirection", "[proto addr_local:port_local port_alias]"}, 1226 { "addr", NULL, AliasRedirectAddr, LOCAL_AUTH, 1227 "static address translation", "[addr_local addr_alias]"}, 1228 { "deny_incoming", NULL, AliasOption, LOCAL_AUTH, 1229 "stop incoming connections", "[yes|no]", 1230 (void*)PKT_ALIAS_DENY_INCOMING}, 1231 { "log", NULL, AliasOption, LOCAL_AUTH, 1232 "log aliasing link creation", "[yes|no]", 1233 (void*)PKT_ALIAS_LOG}, 1234 { "same_ports", NULL, AliasOption, LOCAL_AUTH, 1235 "try to leave port numbers unchanged", "[yes|no]", 1236 (void*)PKT_ALIAS_SAME_PORTS}, 1237 { "use_sockets", NULL, AliasOption, LOCAL_AUTH, 1238 "allocate host sockets", "[yes|no]", 1239 (void*)PKT_ALIAS_USE_SOCKETS }, 1240 { "unregistered_only", NULL, AliasOption, LOCAL_AUTH, 1241 "alias unregistered (private) IP address space only", "[yes|no]", 1242 (void*)PKT_ALIAS_UNREGISTERED_ONLY}, 1243 { "help", "?", HelpCommand, LOCAL_AUTH | LOCAL_NO_AUTH, 1244 "Display this message", StrNull, 1245 (void *)AliasCommands}, 1246 { NULL, NULL, NULL }, 1247}; 1248 1249 1250static int 1251AliasCommand(list, argc, argv) 1252struct cmdtab *list; 1253int argc; 1254char **argv; 1255{ 1256 int val = 1; 1257 1258 if (argc > 0) 1259 val = FindExec(AliasCommands, argc, argv); 1260 else 1261 printf("Use `alias help' to get a list or `alias help <option>' for syntax h 1262elp.\n"); 1263 return(val); 1264} 1265 1266 1267static int 1268AliasEnable(list, argc, argv) 1269struct cmdtab *list; 1270int argc; 1271char **argv; 1272{ 1273 if (argc == 1 && strcmp(argv[0], "yes") == 0) { 1274 if (!(mode & MODE_ALIAS)) 1275 if (loadAliasHandlers(&VarAliasHandlers) == 0) 1276 mode |= MODE_ALIAS; 1277 else 1278 printf("Cannot load alias library\n"); 1279 } else if (argc == 1 && strcmp(argv[0], "no") == 0) { 1280 if (mode & MODE_ALIAS) { 1281 unloadAliasHandlers(); 1282 mode &= ~MODE_ALIAS; 1283 } 1284 } else { 1285 printf("Usage: alias %s %s\n", list->name, list->syntax); 1286 } 1287 return(1); 1288} 1289 1290 1291static int 1292AliasOption(list, argc, argv, param) 1293struct cmdtab *list; 1294int argc; 1295char **argv; 1296void* param; 1297{ 1298 if (argc == 1 && strcmp(argv[0], "yes") == 0) { 1299 if (mode & MODE_ALIAS) 1300 VarSetPacketAliasMode((unsigned)param, (unsigned)param); 1301 else 1302 printf("alias not enabled\n"); 1303 } else if (argc == 1 && strcmp(argv[0], "no") == 0) { 1304 if (mode & MODE_ALIAS) 1305 VarSetPacketAliasMode(0, (unsigned)param); 1306 else 1307 printf("alias not enabled\n"); 1308 } else { 1309 printf("Usage: alias %s %s\n", list->name, list->syntax); 1310 } 1311 return(1); 1312} 1313