command.c revision 26256
1193323Sed/* 2193323Sed * PPP User command processing module 3193323Sed * 4193323Sed * Written by Toshiharu OHNO (tony-o@iij.ad.jp) 5193323Sed * 6193323Sed * Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd. 7193323Sed * 8193323Sed * Redistribution and use in source and binary forms are permitted 9193323Sed * provided that the above copyright notice and this paragraph are 10193323Sed * duplicated in all such forms and that any documentation, 11193323Sed * advertising materials, and other materials related to such 12193323Sed * distribution and use acknowledge that the software was developed 13193323Sed * by the Internet Initiative Japan, Inc. The name of the 14193323Sed * IIJ may not be used to endorse or promote products derived 15193323Sed * from this software without specific prior written permission. 16193323Sed * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 17202375Srdivacky * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 18193323Sed * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 19193323Sed * 20193323Sed * $Id: command.c,v 1.50 1997/05/26 00:43:58 brian Exp $ 21193323Sed * 22201360Srdivacky */ 23201360Srdivacky#include <sys/types.h> 24201360Srdivacky#include <ctype.h> 25201360Srdivacky#include <termios.h> 26201360Srdivacky#include <sys/wait.h> 27201360Srdivacky#include <time.h> 28201360Srdivacky#include <netdb.h> 29201360Srdivacky#include <sys/socket.h> 30201360Srdivacky#include <netinet/in.h> 31201360Srdivacky#include <arpa/inet.h> 32201360Srdivacky#include <net/route.h> 33201360Srdivacky#include <paths.h> 34201360Srdivacky#include <alias.h> 35201360Srdivacky#include "fsm.h" 36203954Srdivacky#include "phase.h" 37201360Srdivacky#include "lcp.h" 38203954Srdivacky#include "ipcp.h" 39203954Srdivacky#include "modem.h" 40201360Srdivacky#include "filter.h" 41201360Srdivacky#include "command.h" 42201360Srdivacky#include "alias_cmd.h" 43201360Srdivacky#include "hdlc.h" 44193323Sed#include "loadalias.h" 45193323Sed#include "vars.h" 46201360Srdivacky#include "systems.h" 47198090Srdivacky#include "chat.h" 48201360Srdivacky#include "os.h" 49193323Sed 50201360Srdivackyextern void Cleanup(), TtyTermMode(), PacketMode(); 51193323Sedextern int EnableCommand(), DisableCommand(), DisplayCommand(); 52193323Sedextern int AcceptCommand(), DenyCommand(); 53193323Sedstatic int AliasCommand(); 54193323Sedextern int LocalAuthCommand(); 55201360Srdivackyextern int LoadCommand(), SaveCommand(); 56193323Sedextern int ChangeParity(char *); 57193323Sedextern int SelectSystem(); 58193323Sedextern int ShowRoute(); 59193323Sedextern void TtyOldMode(), TtyCommandMode(); 60201360Srdivackyextern struct pppvars pppVars; 61193323Sedextern struct cmdtab const SetCommands[]; 62193323Sed 63193323Sedextern char *IfDevName; 64193323Sed 65201360Srdivackystruct in_addr ifnetmask; 66201360Srdivackyint randinit; 67193323Sed 68201360Srdivackystatic int ShowCommand(), TerminalCommand(), QuitCommand(); 69203954Srdivackystatic int CloseCommand(), DialCommand(), DownCommand(); 70193323Sedstatic int SetCommand(), AddCommand(), DeleteCommand(); 71203954Srdivackystatic int ShellCommand(); 72203954Srdivacky 73193323Sedstatic int 74193323SedHelpCommand(list, argc, argv, plist) 75193323Sedstruct cmdtab *list; 76193323Sedint argc; 77193323Sedchar **argv; 78201360Srdivackystruct cmdtab *plist; 79193323Sed{ 80201360Srdivacky struct cmdtab *cmd; 81193323Sed int n; 82201360Srdivacky 83193323Sed if (argc > 0) { 84193323Sed for (cmd = plist; cmd->name; cmd++) { 85201360Srdivacky if (strcasecmp(cmd->name, *argv) == 0 && (cmd->lauth & VarLocalAuth)) { 86193323Sed if (plist == SetCommands) 87193323Sed printf("set "); 88193323Sed printf("%s %s\n", cmd->name, cmd->syntax); 89193323Sed return(1); 90193323Sed } 91201360Srdivacky } 92198090Srdivacky return(1); 93193323Sed } 94193323Sed n = 0; 95193323Sed for (cmd = plist; cmd->func; cmd++) { 96193323Sed if (cmd->name && (cmd->lauth & VarLocalAuth)) { 97193323Sed printf(" %-8s: %-20s\n", cmd->name, cmd->helpmes); 98193323Sed n++; 99193323Sed } 100193323Sed } 101193323Sed if (n & 1) 102193323Sed printf("\n"); 103193323Sed return(1); 104193323Sed} 105193323Sed 106193323Sedint 107193323SedIsInteractive() 108193323Sed{ 109193323Sed char *mes = NULL; 110193323Sed 111193323Sed if (mode & MODE_DDIAL) 112193323Sed mes = "Working in dedicated dial mode."; 113193323Sed else if (mode & MODE_BACKGROUND) 114193323Sed mes = "Working in background mode."; 115193323Sed else if (mode & MODE_AUTO) 116198892Srdivacky mes = "Working in auto mode."; 117193323Sed else if (mode & MODE_DIRECT) 118193323Sed mes = "Working in direct mode."; 119193323Sed else if (mode & MODE_DEDICATED) 120193323Sed mes = "Working in dedicated mode."; 121193323Sed if (mes) { 122198090Srdivacky printf("%s\n", mes); 123198090Srdivacky return(0); 124193323Sed } 125193323Sed return(1); 126205407Srdivacky} 127205407Srdivacky 128193323Sedstatic int 129204642SrdivackyDialCommand(cmdlist, argc, argv) 130193323Sedstruct cmdtab *cmdlist; 131193323Sedint argc; 132205407Srdivackychar **argv; 133193323Sed{ 134205407Srdivacky int tries; 135205407Srdivacky 136205407Srdivacky if (LcpFsm.state > ST_CLOSED) { 137205407Srdivacky printf("LCP state is [%s]\n", StateNames[LcpFsm.state]); 138205407Srdivacky return(1); 139205407Srdivacky } 140205407Srdivacky if (!IsInteractive()) 141205407Srdivacky return(1); 142205407Srdivacky if (argc > 0) { 143205407Srdivacky if (SelectSystem(*argv, CONFFILE) < 0) { 144205407Srdivacky printf("%s: not found.\n", *argv); 145205407Srdivacky return(1); 146205407Srdivacky } 147205407Srdivacky } 148205407Srdivacky tries = 0; 149193323Sed do { 150193323Sed printf("Dial attempt %u of %d\n", ++tries, VarDialTries); 151205407Srdivacky modem = OpenModem(mode); 152205407Srdivacky if (modem < 0) { 153205407Srdivacky printf("failed to open modem.\n"); 154205407Srdivacky break; 155205407Srdivacky } 156205407Srdivacky if (DialModem() == EX_DONE) { 157205407Srdivacky sleep(1); 158205407Srdivacky ModemTimeout(); 159205407Srdivacky PacketMode(); 160205407Srdivacky break; 161205407Srdivacky } 162205407Srdivacky } while (VarDialTries == 0 || tries < VarDialTries); 163193323Sed return(1); 164193323Sed} 165193323Sed 166193323Sedstatic int 167193323SedShellCommand(cmdlist, argc, argv) 168193323Sedstruct cmdtab *cmdlist; 169193323Sedint argc; 170193323Sedchar **argv; 171193323Sed{ 172193323Sed const char *shell; 173201360Srdivacky pid_t shpid; 174193323Sed 175193323Sed if((shell = getenv("SHELL")) == 0) { 176193323Sed shell = _PATH_BSHELL; 177193323Sed } 178193323Sed#ifdef SHELL_ONLY_INTERACTIVELY 179193323Sed#ifndef HAVE_SHELL_CMD_WITH_ANY_MODE 180193323Sed if( mode != MODE_INTER) { 181193323Sed fprintf(stdout, 182193323Sed "Can only start a shell in interactive mode\n"); 183193323Sed return(1); 184193323Sed } 185193323Sed#else 186193323Sed if(argc == 0 && !(mode & MODE_INTER)) { 187193323Sed fprintf(stderr, 188193323Sed "Can only start an interactive shell in interactive mode\n"); 189193323Sed return(1); 190193323Sed } 191193323Sed#endif /* HAVE_SHELL_CMD_WITH_ANY_MODE */ 192193323Sed#else 193201360Srdivacky if ((mode & (MODE_AUTO|MODE_INTER)) == (MODE_AUTO|MODE_INTER)) { 194193323Sed fprintf(stdout, 195193323Sed "Shell is not allowed interactively in auto mode\n"); 196193323Sed return(1); 197193323Sed } 198193323Sed#endif /* SHELL_ONLY_INTERACTIVELY */ 199205407Srdivacky if((shpid = fork()) == 0) { 200193323Sed int dtablesize, i ; 201193323Sed 202205407Srdivacky for (dtablesize = getdtablesize(), i = 3; i < dtablesize; i++) 203193323Sed (void)close(i); 204193323Sed 205201360Srdivacky /* 206205407Srdivacky * We are running setuid, we should change to 207193323Sed * real user for avoiding security problems. 208193323Sed */ 209193323Sed if (setgid(getgid()) < 0) { 210193323Sed perror("setgid"); 211193323Sed exit(1); 212193323Sed } 213201360Srdivacky if (setuid(getuid()) < 0) { 214193323Sed perror("setuid"); 215193323Sed exit(1); 216193323Sed } 217203954Srdivacky TtyOldMode(); 218193323Sed if(argc > 0) { 219193323Sed /* substitute pseudo args */ 220203954Srdivacky for (i=1; i<argc; i++) { 221203954Srdivacky if (strcasecmp(argv[i], "HISADDR") == 0) { 222193323Sed argv[i] = strdup(inet_ntoa(IpcpInfo.his_ipaddr)); 223201360Srdivacky } 224193323Sed if (strcasecmp(argv[i], "INTERFACE") == 0) { 225193323Sed argv[i] = strdup(IfDevName); 226193323Sed } 227202375Srdivacky if (strcasecmp(argv[i], "MYADDR") == 0) { 228202375Srdivacky argv[i] = strdup(inet_ntoa(IpcpInfo.want_ipaddr)); 229193323Sed } 230193323Sed } 231193323Sed (void)execvp(argv[0], argv); 232193323Sed } 233193323Sed else 234193323Sed (void)execl(shell, shell, NULL); 235193323Sed 236193323Sed fprintf(stdout, "exec() of %s failed\n", argc > 0? argv[0]: shell); 237193323Sed exit(255); 238193323Sed } 239193323Sed if( shpid == (pid_t)-1 ) { 240193323Sed fprintf(stdout, "Fork failed\n"); 241193323Sed } else { 242193323Sed int status; 243193323Sed (void)waitpid(shpid, &status, 0); 244193323Sed } 245193323Sed 246193323Sed TtyCommandMode(1); 247193323Sed 248193323Sed return(0); 249193323Sed} 250193323Sed 251193323Sedstatic char StrOption[] = "option .."; 252193323Sedstatic char StrRemote[] = "[remote]"; 253201360Srdivackychar StrNull[] = ""; 254193323Sed 255193323Sedstruct cmdtab const Commands[] = { 256193323Sed { "accept", NULL, AcceptCommand, LOCAL_AUTH, 257193323Sed "accept option request", StrOption}, 258201360Srdivacky { "add", NULL, AddCommand, LOCAL_AUTH, 259193323Sed "add route", "dest mask gateway"}, 260193323Sed { "close", NULL, CloseCommand, LOCAL_AUTH, 261201360Srdivacky "Close connection", StrNull}, 262193323Sed { "delete", NULL, DeleteCommand, LOCAL_AUTH, 263193323Sed "delete route", "ALL | dest gateway [mask]"}, 264193323Sed { "deny", NULL, DenyCommand, LOCAL_AUTH, 265193323Sed "Deny option request", StrOption}, 266193323Sed { "dial", "call", DialCommand, LOCAL_AUTH, 267193323Sed "Dial and login", StrRemote}, 268193323Sed { "disable", NULL, DisableCommand, LOCAL_AUTH, 269193323Sed "Disable option", StrOption}, 270201360Srdivacky { "display", NULL, DisplayCommand, LOCAL_AUTH, 271193323Sed "Display option configs", StrNull}, 272193323Sed { "enable", NULL, EnableCommand, LOCAL_AUTH, 273193323Sed "Enable option", StrOption}, 274193323Sed { "passwd", NULL, LocalAuthCommand,LOCAL_NO_AUTH, 275193323Sed "Password for manipulation", StrOption}, 276193323Sed { "load", NULL, LoadCommand, LOCAL_AUTH, 277193323Sed "Load settings", StrRemote}, 278193323Sed { "save", NULL, SaveCommand, LOCAL_AUTH, 279201360Srdivacky "Save settings", StrNull}, 280193323Sed { "set", "setup", SetCommand, LOCAL_AUTH, 281193323Sed "Set parameters", "var value"}, 282193323Sed { "shell", "!", ShellCommand, LOCAL_AUTH, 283201360Srdivacky "Run a subshell", "[sh command]"}, 284193323Sed { "show", NULL, ShowCommand, LOCAL_AUTH, 285193323Sed "Show status and statictics", "var"}, 286193323Sed { "term", NULL, TerminalCommand,LOCAL_AUTH, 287193323Sed "Enter to terminal mode", StrNull}, 288201360Srdivacky { "alias", NULL, AliasCommand, LOCAL_AUTH, 289193323Sed "alias control", "option [yes|no]"}, 290193323Sed { "quit", "bye", QuitCommand, LOCAL_AUTH | LOCAL_NO_AUTH, 291193323Sed "Quit PPP program", "[all]"}, 292193323Sed { "help", "?", HelpCommand, LOCAL_AUTH | LOCAL_NO_AUTH, 293193323Sed "Display this message", "[command]", (void *)Commands }, 294193323Sed { NULL, "down", DownCommand, LOCAL_AUTH, 295193323Sed "Generate down event", StrNull}, 296193323Sed { 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", "mtu", 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