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