command.c revision 10528
16059Samurai/*
26059Samurai *		PPP User command processing module
36059Samurai *
46059Samurai *	    Written by Toshiharu OHNO (tony-o@iij.ad.jp)
56059Samurai *
66059Samurai *   Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd.
76059Samurai *
86059Samurai * Redistribution and use in source and binary forms are permitted
96059Samurai * provided that the above copyright notice and this paragraph are
106059Samurai * duplicated in all such forms and that any documentation,
116059Samurai * advertising materials, and other materials related to such
126059Samurai * distribution and use acknowledge that the software was developed
136059Samurai * by the Internet Initiative Japan, Inc.  The name of the
146059Samurai * IIJ may not be used to endorse or promote products derived
156059Samurai * from this software without specific prior written permission.
166059Samurai * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
176059Samurai * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
186059Samurai * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
198857Srgrimes *
209448Samurai * $Id: command.c,v 1.7 1995/07/08 08:28:00 amurai Exp $
218857Srgrimes *
226059Samurai */
236059Samurai#include <ctype.h>
246735Samurai#include <termios.h>
256059Samurai#include "fsm.h"
266059Samurai#include "phase.h"
276059Samurai#include "lcp.h"
286059Samurai#include "ipcp.h"
296059Samurai#include "modem.h"
306059Samurai#include "command.h"
316059Samurai#include "hdlc.h"
326059Samurai#include "vars.h"
336735Samurai#include "auth.h"
346059Samurai#include <netdb.h>
356059Samurai#include <sys/socket.h>
366059Samurai#include <arpa/inet.h>
376059Samurai#include <net/route.h>
386059Samurai#include "os.h"
3910528Samurai#include <paths.h>
406059Samurai
416059Samuraiextern int  MakeArgs();
426059Samuraiextern void Cleanup(), TtyTermMode(), PacketMode();
436059Samuraiextern int  EnableCommand(), DisableCommand(), DisplayCommand();
446059Samuraiextern int  AcceptCommand(), DenyCommand();
456735Samuraiextern int  LocalAuthCommand();
466059Samuraiextern int  LoadCommand(), SaveCommand();
476059Samuraiextern int  ChangeParity(char *);
486059Samuraiextern int  SelectSystem();
496059Samuraiextern int  ShowRoute();
5010528Samuraiextern void TtyOldMode(), TtyCommandMode();
516735Samuraiextern struct pppvars pppVars;
526059Samurai
536059Samuraistruct in_addr ifnetmask;
546059Samurai
556059Samuraistatic int ShowCommand(), TerminalCommand(), QuitCommand();
566059Samuraistatic int CloseCommand(), DialCommand(), DownCommand();
576059Samuraistatic int SetCommand(), AddCommand(), DeleteCommand();
5810528Samuraistatic int ShellCommand();
596059Samurai
606059Samuraistatic int
616059SamuraiHelpCommand(list, argc, argv, plist)
626059Samuraistruct cmdtab *list;
636059Samuraiint argc;
646059Samuraichar **argv;
656059Samuraistruct cmdtab *plist;
666059Samurai{
676059Samurai  struct cmdtab *cmd;
686059Samurai  int n;
696059Samurai  char c;
706059Samurai
716059Samurai  if (argc > 0) {
726059Samurai    for (cmd = plist; cmd->name; cmd++) {
736764Samurai      if (strcmp(cmd->name, *argv) == 0 && (cmd->lauth & VarLocalAuth)) {
746059Samurai        printf("%s %s\n", cmd->name, cmd->syntax);
756059Samurai        return(1);
766059Samurai      }
776059Samurai    }
786059Samurai    return(1);
796059Samurai  }
806059Samurai  n = 0;
816059Samurai  for (cmd = plist; cmd->func; cmd++) {
826764Samurai    if (cmd->name && (cmd->lauth & VarLocalAuth)) {
836764Samurai      c = (n & 1)? '\n' : '\t';
846059Samurai      printf("  %-8s: %-20s%c", cmd->name, cmd->helpmes, c);
856059Samurai      n++;
866059Samurai    }
876059Samurai  }
886059Samurai  if (n & 1)
896059Samurai    printf("\n");
906059Samurai  return(1);
916059Samurai}
926059Samurai
936059Samuraiint
946059SamuraiIsInteractive()
956059Samurai{
966059Samurai  char *mes = NULL;
976059Samurai
986059Samurai  if (mode & MODE_AUTO)
9910528Samurai    mes = "Working in auto mode.";
1006059Samurai  else if (mode & MODE_DIRECT)
10110528Samurai    mes = "Working in direct mode.";
1026059Samurai  else if (mode & MODE_DEDICATED)
10310528Samurai    mes = "Working in dedicated mode.";
1046059Samurai  if (mes) {
1056059Samurai    printf("%s\n", mes);
1066059Samurai    return(0);
1076059Samurai  }
1086059Samurai  return(1);
1096059Samurai}
1106059Samurai
1116059Samuraistatic int
1126059SamuraiDialCommand(cmdlist, argc, argv)
1136059Samuraistruct cmdtab *cmdlist;
1146059Samuraiint argc;
1156059Samuraichar **argv;
1166059Samurai{
1176059Samurai  if (LcpFsm.state > ST_CLOSED) {
1186059Samurai    printf("LCP state is [%s]\n", StateNames[LcpFsm.state]);
1196059Samurai    return(1);
1206059Samurai  }
1216059Samurai  if (!IsInteractive())
1226059Samurai    return(1);
1236735Samurai  if (argc > 0) {
1246735Samurai    if (SelectSystem(*argv, CONFFILE) < 0) {
1256735Samurai      printf("%s: not found.\n", *argv);
1266735Samurai      return(1);
1276735Samurai    }
1286735Samurai  }
1296059Samurai  modem = OpenModem(mode);
1306059Samurai  if (modem < 0) {
1316059Samurai    printf("failed to open modem.\n");
1326059Samurai    modem = 0;
1336059Samurai    return(1);
1346059Samurai  }
1356059Samurai  if (DialModem()) {
1366059Samurai    sleep(1);
1376059Samurai    ModemTimeout();
1386059Samurai    PacketMode();
1396059Samurai  }
1406059Samurai  return(1);
1416059Samurai}
1426059Samurai
14310528Samuraistatic int
14410528SamuraiShellCommand(cmdlist, argc, argv)
14510528Samuraistruct cmdtab *cmdlist;
14610528Samuraiint argc;
14710528Samuraichar **argv;
14810528Samurai{
14910528Samurai  const char *shell;
15010528Samurai  pid_t shpid;
15110528Samurai
15210528Samurai  if((shell = getenv("SHELL")) == 0) {
15310528Samurai    shell = _PATH_BSHELL;
15410528Samurai  }
15510528Samurai
15610528Samurai#ifndef HAVE_SHELL_CMD_WITH_ANY_MODE
15710528Samurai  if( mode != MODE_INTER) {
15810528Samurai     fprintf(stdout,
15910528Samurai             "Can start an shell only in interactive mode\n");
16010528Samurai     return(1);
16110528Samurai  }
16210528Samurai#else
16310528Samurai  if(argc == 0 && !(mode & MODE_INTER)) {
16410528Samurai      fprintf(stderr,
16510528Samurai             "Can start an interactive shell only in interactive mode\n");
16610528Samurai      return(1);
16710528Samurai  }
16810528Samurai#endif /* HAVE_SHELL_CMD_WITH_ANY_MODE */
16910528Samurai
17010528Samurai  if((shpid = fork()) == 0) {
17110528Samurai     int i;
17210528Samurai     for(i = 3; i < getdtablesize(); i++)
17310528Samurai	(void)close(i);
17410528Samurai
17510528Samurai     /*
17610528Samurai      * We are running setuid, we should change to
17710528Samurai      * real user for avoiding security problems.
17810528Samurai      */
17910528Samurai     setgid( getgid() );
18010528Samurai     setuid( getuid() );
18110528Samurai
18210528Samurai     TtyOldMode();
18310528Samurai     if(argc > 0)
18410528Samurai       execvp(argv[0], argv);
18510528Samurai     else
18610528Samurai       execl(shell, shell, NULL);
18710528Samurai
18810528Samurai     fprintf(stdout, "exec() of %s failed\n", argc > 0? argv[0]: shell);
18910528Samurai     exit(255);
19010528Samurai  }
19110528Samurai  if( shpid == (pid_t)-1 ) {
19210528Samurai    fprintf(stdout, "Fork failed\n");
19310528Samurai  } else {
19410528Samurai    int status;
19510528Samurai    (void)waitpid(shpid, &status, 0);
19610528Samurai  }
19710528Samurai
19810528Samurai  TtyCommandMode(1);
19910528Samurai
20010528Samurai  return(0);
20110528Samurai}
20210528Samurai
2036059Samuraistatic char StrOption[] = "option ..";
2046059Samuraistatic char StrRemote[] = "[remote]";
2056059Samuraichar StrNull[] = "";
2066059Samurai
2076059Samuraistruct cmdtab Commands[] = {
2086735Samurai  { "accept",  NULL,    AcceptCommand,	LOCAL_AUTH,
2096735Samurai  	"accept option request",	StrOption},
2106735Samurai  { "add",     NULL,	AddCommand,	LOCAL_AUTH,
2116735Samurai	"add route",			"dest mask gateway"},
2126735Samurai  { "close",   NULL,    CloseCommand,	LOCAL_AUTH,
2136735Samurai	"Close connection",		StrNull},
2146735Samurai  { "delete",  NULL,    DeleteCommand,	LOCAL_AUTH,
2156735Samurai  	"delete route",			"dest gateway"},
2166735Samurai  { "deny",    NULL,    DenyCommand,	LOCAL_AUTH,
2176735Samurai  	"Deny option request",		StrOption},
2186735Samurai  { "dial",    "call",  DialCommand,	LOCAL_AUTH,
2196735Samurai  	"Dial and login",		StrRemote},
2206735Samurai  { "disable", NULL,    DisableCommand,	LOCAL_AUTH,
2216735Samurai  	"Disable option",		StrOption},
2226735Samurai  { "display", NULL,    DisplayCommand,	LOCAL_AUTH,
2236735Samurai  	"Display option configs",	StrNull},
2246735Samurai  { "enable",  NULL,    EnableCommand,	LOCAL_AUTH,
2256735Samurai  	"Enable option",		StrOption},
2266764Samurai  { "passwd",  NULL,	LocalAuthCommand,LOCAL_NO_AUTH,
2279240Sphk  	"Password for manipulation", StrOption},
2286735Samurai  { "load",    NULL,    LoadCommand,	LOCAL_AUTH,
2296735Samurai  	"Load settings",		StrRemote},
2306735Samurai  { "save",    NULL,    SaveCommand,	LOCAL_AUTH,
2316735Samurai  	"Save settings", StrNull},
2326735Samurai  { "set",     "setup", SetCommand,	LOCAL_AUTH,
2336735Samurai  	"Set parameters",  "var value"},
23410528Samurai  { "shell",   "!",     ShellCommand,   LOCAL_AUTH,
23510528Samurai	"Run a subshell",  "[sh command]"},
2366735Samurai  { "show",    NULL,    ShowCommand,	LOCAL_AUTH,
2376735Samurai  	"Show status and statictics", "var"},
2386735Samurai  { "term",    NULL,    TerminalCommand,LOCAL_AUTH,
2396735Samurai  	"Enter to terminal mode", StrNull},
2406764Samurai  { "quit",    "bye",   QuitCommand,	LOCAL_AUTH | LOCAL_NO_AUTH,
2416735Samurai  	"Quit PPP program", StrNull},
2426735Samurai  { "help",    "?",     HelpCommand,	LOCAL_AUTH | LOCAL_NO_AUTH,
2436059Samurai	"Display this message", "[command]", (void *)Commands },
2446735Samurai  { NULL,      "down",  DownCommand,	LOCAL_AUTH,
2456735Samurai  	"Generate down event",		StrNull},
2466059Samurai  { NULL,      NULL,    NULL },
2476059Samurai};
2486059Samurai
2496059Samuraiextern int ReportCcpStatus();
2506059Samuraiextern int ReportLcpStatus();
2516059Samuraiextern int ReportIpcpStatus();
2526059Samuraiextern int ReportProtStatus();
2536059Samuraiextern int ReportCompress();
2546059Samuraiextern int ShowModemStatus();
2556059Samuraiextern int ReportHdlcStatus();
2566059Samuraiextern int ShowMemMap();
2576059Samurai
2586059Samuraistatic char *LogLevelName[] = {
2596059Samurai  LM_PHASE, LM_CHAT, LM_LQM,   LM_LCP,
2606059Samurai  LM_TCPIP, LM_HDLC, LM_ASYNC,
2616059Samurai};
2626059Samurai
2636059Samuraistatic int ShowDebugLevel()
2646059Samurai{
2656059Samurai  int i;
2666059Samurai
2676059Samurai  printf("%02x: ", loglevel);
2686059Samurai  for (i = LOG_PHASE; i < MAXLOGLEVEL; i++) {
2696059Samurai    if (loglevel & (1 << i))
2706059Samurai      printf("%s ", LogLevelName[i]);
2716059Samurai  }
2726059Samurai  printf("\n");
2736059Samurai  return(1);
2746059Samurai}
2756059Samurai
2766059Samuraistatic int ShowEscape()
2776059Samurai{
2786059Samurai  int code, bit;
2796059Samurai
2806059Samurai  if (EscMap[32]) {
2816059Samurai    for (code = 0; code < 32; code++) {
2826059Samurai      if (EscMap[code]) {
2836059Samurai        for (bit = 0; bit < 8; bit++) {
2846059Samurai          if (EscMap[code] & (1<<bit)) {
2856059Samurai            printf(" 0x%02x", (code << 3) + bit);
2866059Samurai          }
2876059Samurai        }
2886059Samurai      }
2896059Samurai    }
2906059Samurai    printf("\n");
2916059Samurai  }
2926059Samurai  return(1);
2936059Samurai}
2946059Samurai
2956059Samuraistatic int ShowTimeout()
2966059Samurai{
2976735Samurai  printf(" Idle Timer: %d secs   LQR Timer: %d secs   Retry Timer: %d secs\n",
2986735Samurai    VarIdleTimeout, VarLqrTimeout, VarRetryTimeout);
2996059Samurai  return(1);
3006059Samurai}
3016059Samurai
3026059Samuraistatic int ShowAuthKey()
3036059Samurai{
3046059Samurai  printf("AuthName = %s\n", VarAuthName);
3056059Samurai  printf("AuthKey  = %s\n", VarAuthKey);
3066059Samurai  return(1);
3076059Samurai}
3086059Samurai
3096059Samuraistatic int ShowVersion()
3106059Samurai{
3116059Samurai  extern char *VarVersion[];
3129448Samurai  extern char *VarLocalVersion[];
3136059Samurai
3149448Samurai  printf("%s - %s \n", VarVersion, VarLocalVersion);
3156059Samurai  return(1);
3166059Samurai}
3176059Samurai
3186059Samuraistatic int ShowLogList()
3196059Samurai{
3206059Samurai  ListLog();
3216059Samurai  return(1);
3226059Samurai}
3236059Samurai
3246735Samuraiextern int ShowIfilter(), ShowOfilter(), ShowDfilter(), ShowAfilter();
3256059Samurai
3266059Samuraistruct cmdtab ShowCommands[] = {
3276735Samurai  { "afilter",  NULL,     ShowAfilter,		LOCAL_AUTH,
3286735Samurai	"Show keep Alive filters", StrOption},
3296735Samurai  { "auth",     NULL,     ShowAuthKey,		LOCAL_AUTH,
3306735Samurai	"Show auth name/key", StrNull},
3316735Samurai  { "ccp",      NULL,     ReportCcpStatus,	LOCAL_AUTH,
3326735Samurai	"Show CCP status", StrNull},
3336735Samurai  { "compress", NULL,     ReportCompress,	LOCAL_AUTH,
3346735Samurai	"Show compression statictics", StrNull},
3356735Samurai  { "debug",	NULL,	  ShowDebugLevel,	LOCAL_AUTH,
3366735Samurai	"Show current debug level", StrNull},
3376735Samurai  { "dfilter",  NULL,     ShowDfilter,		LOCAL_AUTH,
3386735Samurai	"Show Demand filters", StrOption},
3396735Samurai  { "escape",   NULL,     ShowEscape,		LOCAL_AUTH,
3406735Samurai	"Show escape characters", StrNull},
3416735Samurai  { "hdlc",	NULL,	  ReportHdlcStatus,	LOCAL_AUTH,
3426735Samurai	"Show HDLC error summary", StrNull},
3436735Samurai  { "ifilter",  NULL,     ShowIfilter,		LOCAL_AUTH,
3446735Samurai	"Show Input filters", StrOption},
3456735Samurai  { "ipcp",     NULL,     ReportIpcpStatus,	LOCAL_AUTH,
3466735Samurai	"Show IPCP status", StrNull},
3476735Samurai  { "lcp",      NULL,     ReportLcpStatus,	LOCAL_AUTH,
3486735Samurai	"Show LCP status", StrNull},
3496735Samurai  { "log",      NULL,     ShowLogList,		LOCAL_AUTH,
3506735Samurai	"Show log records", StrNull},
3516735Samurai  { "mem",      NULL,     ShowMemMap,		LOCAL_AUTH,
3526735Samurai	"Show memory map", StrNull},
3536735Samurai  { "modem",    NULL,     ShowModemStatus,	LOCAL_AUTH,
3546735Samurai	"Show modem setups", StrNull},
3556735Samurai  { "ofilter",  NULL,     ShowOfilter,		LOCAL_AUTH,
3566735Samurai	"Show Output filters", StrOption},
3576735Samurai  { "proto",    NULL,     ReportProtStatus,	LOCAL_AUTH,
3586735Samurai	"Show protocol summary", StrNull},
3596735Samurai  { "route",    NULL,     ShowRoute,		LOCAL_AUTH,
3606735Samurai	"Show routing table", StrNull},
3616735Samurai  { "timeout",  NULL,	  ShowTimeout,		LOCAL_AUTH,
3626735Samurai	"Show Idle timeout value", StrNull},
3636735Samurai  { "version",  NULL,	  ShowVersion,		LOCAL_NO_AUTH | LOCAL_AUTH,
3646735Samurai	"Show version string", StrNull},
3656735Samurai  { "help",     "?",      HelpCommand,		LOCAL_NO_AUTH | LOCAL_AUTH,
3666735Samurai	"Display this message", StrNull, (void *)ShowCommands},
3676059Samurai  { NULL,       NULL,     NULL },
3686059Samurai};
3696059Samurai
3706059Samuraistruct cmdtab *
3716059SamuraiFindCommand(cmds, str, pmatch)
3726059Samuraistruct cmdtab *cmds;
3736059Samuraichar *str;
3746059Samuraiint *pmatch;
3756059Samurai{
3766059Samurai  int nmatch = 0;
3776059Samurai  int len = strlen(str);
3786059Samurai  struct cmdtab *found = NULL;
3796059Samurai
3806059Samurai  while (cmds->func) {
3816059Samurai    if (cmds->name && strncmp(str, cmds->name, len) == 0) {
3826059Samurai      nmatch++;
3836059Samurai      found = cmds;
3846059Samurai    } else if (cmds->alias && strncmp(str, cmds->alias, len) == 0) {
3856059Samurai      nmatch++;
3866059Samurai      found = cmds;
3876059Samurai    }
3886059Samurai    cmds++;
3896059Samurai  }
3906059Samurai  *pmatch = nmatch;
3916059Samurai  return(found);
3926059Samurai}
3936059Samurai
3946059Samuraiint
3956059SamuraiFindExec(cmdlist, argc, argv)
3966059Samuraistruct cmdtab *cmdlist;
3976059Samuraiint argc;
3986059Samuraichar **argv;
3996059Samurai{
4006059Samurai  struct cmdtab *cmd;
4016059Samurai  int val = 1;
4026059Samurai  int nmatch;
4036059Samurai
4046059Samurai  cmd = FindCommand(cmdlist, *argv, &nmatch);
4056059Samurai  if (nmatch > 1)
4066735Samurai    printf("Ambiguous.\n");
4076735Samurai  else if (cmd && ( cmd->lauth & VarLocalAuth ) )
4086059Samurai    val = (cmd->func)(cmd, --argc, ++argv, cmd->args);
4096059Samurai  else
4106059Samurai    printf("what?\n");
4116059Samurai  return(val);
4126059Samurai}
4136059Samurai
4146059Samuraivoid
4156059SamuraiPrompt(flag)
4166059Samuraiint flag;
4176059Samurai{
4186735Samurai  char *pconnect, *pauth;
4196735Samurai
4206059Samurai  if (!(mode & MODE_INTER))
4216059Samurai    return;
4226735Samurai
4236059Samurai  if (flag) printf("\n");
4246735Samurai
4256735Samurai  if ( VarLocalAuth == LOCAL_AUTH )
4266735Samurai    pauth = " ON ";
4276735Samurai  else
4286735Samurai    pauth = " on ";
4296059Samurai  if (IpcpFsm.state == ST_OPENED && phase == PHASE_NETWORK)
4306735Samurai    pconnect = "PPP";
4316059Samurai  else
4326735Samurai    pconnect = "ppp";
4336735Samurai  printf("%s%s%s> ", pconnect, pauth, VarShortHost);
4346059Samurai  fflush(stdout);
4356059Samurai}
4366059Samurai
4376059Samuraivoid
4386059SamuraiDecodeCommand(buff, nb, prompt)
4396059Samuraichar *buff;
4406059Samuraiint nb;
4416059Samuraiint prompt;
4426059Samurai{
4436059Samurai  char *vector[20];
4446059Samurai  char **argv;
4456059Samurai  int argc, val;
4466059Samurai  char *cp;
4476059Samurai
4486059Samurai  val = 1;
4496059Samurai  if (nb > 0) {
4506059Samurai    cp = buff + strcspn(buff, "\r\n");
4516059Samurai    if (cp)
4526059Samurai      *cp = '\0';
4536059Samurai    {
4546059Samurai      argc = MakeArgs(buff, &vector);
4556059Samurai      argv = vector;
4566059Samurai
4576059Samurai      if (argc > 0)
4586059Samurai        val = FindExec(Commands, argc, argv);
4596059Samurai    }
4606059Samurai  }
4616059Samurai  if (val && prompt)
4626059Samurai    Prompt(0);
4636059Samurai}
4646059Samurai
4656059Samuraistatic int
4666059SamuraiShowCommand(list, argc, argv)
4676059Samuraistruct cmdtab *list;
4686059Samuraiint argc;
4696059Samuraichar **argv;
4706059Samurai{
4716059Samurai  int val = 1;
4726059Samurai
4736059Samurai  if (argc > 0)
4746059Samurai    val = FindExec(ShowCommands, argc, argv);
4756059Samurai  else
4766059Samurai    printf("Use ``show ?'' to get a list.\n");
4776059Samurai  return(val);
4786059Samurai}
4796059Samurai
4806059Samuraistatic int
4816059SamuraiTerminalCommand()
4826059Samurai{
4836059Samurai  if (LcpFsm.state > ST_CLOSED) {
4846059Samurai    printf("LCP state is [%s]\n", StateNames[LcpFsm.state]);
4856059Samurai    return(1);
4866059Samurai  }
4876059Samurai  if (!IsInteractive())
4886059Samurai    return(1);
4896059Samurai  modem = OpenModem(mode);
4906059Samurai  if (modem < 0) {
4916059Samurai    printf("failed to open modem.\n");
4926059Samurai    modem = 0;
4936059Samurai    return(1);
4946059Samurai  }
4956059Samurai  printf("Enter to terminal mode.\n");
4966059Samurai  printf("Type `~?' for help.\n");
4976059Samurai  TtyTermMode();
4986059Samurai  return(0);
4996059Samurai}
5006059Samurai
5016059Samuraistatic int
5026059SamuraiQuitCommand(list, argc, argv)
5036059Samuraistruct cmdtab *list;
5046059Samuraiint argc;
5056059Samuraichar **argv;
5066059Samurai{
5076059Samurai  if (mode & (MODE_DIRECT|MODE_DEDICATED|MODE_AUTO)) {
5086764Samurai    if (argc > 0 && (VarLocalAuth & LOCAL_AUTH)) {
5096059Samurai      Cleanup(EX_NORMAL);
5106059Samurai    } else {
5116735Samurai      VarLocalAuth = LOCAL_NO_AUTH;
5126059Samurai      close(netfd);
5136059Samurai      close(1);
5147886Samurai      dup2(2, 1);     /* Have to have something here or the modem will be 1 */
5156059Samurai      netfd = -1;
5166059Samurai      mode &= ~MODE_INTER;
5176059Samurai    }
5186059Samurai  } else
5196059Samurai    Cleanup(EX_NORMAL);
5206059Samurai  return(1);
5216059Samurai}
5226059Samurai
5236059Samuraistatic int
5246059SamuraiCloseCommand()
5256059Samurai{
5266059Samurai  LcpClose();
5276059Samurai  return(1);
5286059Samurai}
5296059Samurai
5306059Samuraistatic int
5316059SamuraiDownCommand()
5326059Samurai{
5336059Samurai  LcpDown();
5346059Samurai  return(1);
5356059Samurai}
5366059Samurai
5376059Samuraistatic int SetModemSpeed(list, argc, argv)
5386059Samuraistruct cmdtab *list;
5396059Samuraiint argc;
5406059Samuraichar **argv;
5416059Samurai{
5426059Samurai  int speed;
5436059Samurai
5446059Samurai  if (argc > 0) {
5456735Samurai    if (strcmp(*argv, "sync") == 0) {
5466735Samurai      VarSpeed = 0;
5476735Samurai      return(1);
5486735Samurai    }
5496059Samurai    speed = atoi(*argv);
5506735Samurai    if (IntToSpeed(speed) != B0) {
5516735Samurai      VarSpeed = speed;
5526735Samurai      return(1);
5536059Samurai    }
5546059Samurai    printf("invalid speed.\n");
5556059Samurai  }
5566059Samurai  return(1);
5576059Samurai}
5586059Samurai
5596059Samuraistatic int SetModemParity(list, argc, argv)
5606059Samuraistruct cmdtab *list;
5616059Samuraiint argc;
5626059Samuraichar **argv;
5636059Samurai{
5646059Samurai  int parity;
5656059Samurai
5666059Samurai  if (argc > 0) {
5676059Samurai    parity = ChangeParity(*argv);
5686059Samurai    if (parity < 0)
5696059Samurai      printf("Invalid parity.\n");
5706059Samurai    else
5716059Samurai      VarParity = parity;
5726059Samurai  }
5736059Samurai  return(1);
5746059Samurai}
5756059Samurai
5766059Samuraistatic int
5776059SamuraiSetDebugLevel(list, argc, argv)
5786059Samuraistruct cmdtab *list;
5796059Samuraiint argc;
5806059Samuraichar **argv;
5816059Samurai{
5826059Samurai  int level, w;
5836059Samurai
5846059Samurai  for (level = 0; argc-- > 0; argv++) {
5856059Samurai    if (isdigit(**argv)) {
5866059Samurai      w = atoi(*argv);
5876059Samurai      if (w < 0 || w >= MAXLOGLEVEL) {
5886059Samurai	printf("invalid log level.\n");
5896059Samurai	break;
5906059Samurai      } else
5916059Samurai	level |= (1 << w);
5926059Samurai    } else {
5936059Samurai      for (w = 0; w < MAXLOGLEVEL; w++) {
5946059Samurai	if (strcasecmp(*argv, LogLevelName[w]) == 0) {
5956059Samurai	  level |= (1 << w);
5966059Samurai	  continue;
5976059Samurai	}
5986059Samurai      }
5996059Samurai    }
6006059Samurai  }
6016059Samurai  loglevel = level;
6026059Samurai  return(1);
6036059Samurai}
6046059Samurai
6056059Samuraistatic int
6066059SamuraiSetEscape(list, argc, argv)
6076059Samuraistruct cmdtab *list;
6086059Samuraiint argc;
6096059Samuraichar **argv;
6106059Samurai{
6116059Samurai  int code;
6126059Samurai
6136059Samurai  for (code = 0; code < 33; code++)
6146059Samurai    EscMap[code] = 0;
6156059Samurai  while (argc-- > 0) {
6166059Samurai    sscanf(*argv++, "%x", &code);
6176059Samurai    code &= 0xff;
6186059Samurai    EscMap[code >> 3] |= (1 << (code&7));
6196059Samurai    EscMap[32] = 1;
6206059Samurai  }
6216059Samurai  return(1);
6226059Samurai}
6236059Samurai
6246059Samuraistatic int
6256059SamuraiSetInitialMRU(list, argc, argv)
6266059Samuraistruct cmdtab *list;
6276059Samuraiint argc;
6286059Samuraichar **argv;
6296059Samurai{
6306059Samurai  int mru;
6316059Samurai
6326059Samurai  if (argc > 0) {
6336059Samurai    mru = atoi(*argv);
6346059Samurai    if (mru < 100)
6356059Samurai      printf("given value is too small.\n");
6366059Samurai    else if (mru > MAX_MRU)
6376059Samurai      printf("given value is too big.\n");
6386059Samurai    else
6396059Samurai      VarMRU = mru;
6406059Samurai  }
6416059Samurai  return(1);
6426059Samurai}
6436059Samurai
6446059Samuraistatic int
6456059SamuraiSetIdleTimeout(list, argc, argv)
6466059Samuraistruct cmdtab *list;
6476059Samuraiint argc;
6486059Samuraichar **argv;
6496059Samurai{
6506059Samurai  if (argc-- > 0) {
6516059Samurai    VarIdleTimeout = atoi(*argv++);
6526735Samurai    if (argc-- > 0) {
6536735Samurai      VarLqrTimeout = atoi(*argv++);
6546735Samurai      if (VarLqrTimeout < 1)
6556735Samurai	VarLqrTimeout = 30;
6566735Samurai      if (argc > 0) {
6576735Samurai	VarRetryTimeout = atoi(*argv);
6586735Samurai	if (VarRetryTimeout < 1 || VarRetryTimeout > 10)
6596735Samurai	  VarRetryTimeout = 3;
6606735Samurai      }
6616735Samurai    }
6626059Samurai  }
6636059Samurai  return(1);
6646059Samurai}
6656059Samurai
6666059Samuraistruct in_addr
6676059SamuraiGetIpAddr(cp)
6686059Samuraichar *cp;
6696059Samurai{
6706059Samurai  struct hostent *hp;
6716059Samurai  struct in_addr ipaddr;
6726059Samurai
6736059Samurai  hp = gethostbyname(cp);
6746059Samurai  if (hp && hp->h_addrtype == AF_INET)
6756059Samurai    bcopy(hp->h_addr, &ipaddr, hp->h_length);
6766059Samurai  else if (inet_aton(cp, &ipaddr) == 0)
6776059Samurai    ipaddr.s_addr = 0;
6786059Samurai  return(ipaddr);
6796059Samurai}
6806059Samurai
6816059Samuraistatic int
6826059SamuraiSetInterfaceAddr(list, argc, argv)
6836059Samuraistruct cmdtab *list;
6846059Samuraiint argc;
6856059Samuraichar **argv;
6866059Samurai{
6876059Samurai  int width;
6886059Samurai
6896059Samurai  DefMyAddress.ipaddr.s_addr = DefHisAddress.ipaddr.s_addr = 0L;
6906059Samurai  if (argc > 0) {
6916059Samurai    ParseAddr(argc, argv++,
6926059Samurai      &DefMyAddress.ipaddr, &DefMyAddress.mask, &DefMyAddress.width);
6936059Samurai    if (--argc > 0) {
6946059Samurai      ParseAddr(argc, argv++,
6956059Samurai	&DefHisAddress.ipaddr, &DefHisAddress.mask, &DefHisAddress.width);
6966059Samurai      if (--argc > 0) {
6976059Samurai        ifnetmask = GetIpAddr(*argv);
6989440Samurai    	if (--argc > 0) {
6999440Samurai      		ParseAddr(argc, argv++,
7009440Samurai		        &DefTriggerAddress.ipaddr,
7019440Samurai			&DefTriggerAddress.mask,
7029440Samurai			&DefTriggerAddress.width);
7039440Samurai	}
7046059Samurai      }
7056059Samurai    }
7066059Samurai  }
7076059Samurai  /*
7086059Samurai   * For backwards compatibility, 0.0.0.0 means any address.
7096059Samurai   */
7106059Samurai  if (DefMyAddress.ipaddr.s_addr == 0) {
7116059Samurai    DefMyAddress.mask.s_addr = 0;
7126059Samurai    DefMyAddress.width = 0;
7136059Samurai  }
7146059Samurai  if (DefHisAddress.ipaddr.s_addr == 0) {
7156059Samurai    DefHisAddress.mask.s_addr = 0;
7166059Samurai    DefHisAddress.width = 0;
7176059Samurai  }
7186059Samurai
7196735Samurai  if ((mode & MODE_AUTO) ||
7206059Samurai	((mode & MODE_DEDICATED) && dstsystem)) {
7216059Samurai    OsSetIpaddress(DefMyAddress.ipaddr, DefHisAddress.ipaddr, ifnetmask);
7226059Samurai  }
7236059Samurai  return(1);
7246059Samurai}
7256059Samurai
7266059Samurai
7276059Samurai#define	VAR_AUTHKEY	0
7286059Samurai#define	VAR_DIAL	1
7296059Samurai#define	VAR_LOGIN	2
7306059Samurai#define	VAR_AUTHNAME	3
7316059Samurai#define	VAR_DEVICE	4
7326059Samurai#define	VAR_ACCMAP	5
7336059Samurai#define	VAR_PHONE	6
7346059Samurai
7356059Samuraistatic int
7366059SamuraiSetVariable(list, argc, argv, param)
7376059Samuraistruct cmdtab *list;
7386059Samuraiint argc;
7396059Samuraichar **argv;
7406059Samuraiint param;
7416059Samurai{
7426059Samurai  u_long map;
7436059Samurai
7446059Samurai  if (argc > 0) {
7456059Samurai    switch (param) {
7466059Samurai    case VAR_AUTHKEY:
7476059Samurai      strncpy(VarAuthKey, *argv, sizeof(VarAuthKey)-1);
7486059Samurai      break;
7496059Samurai    case VAR_AUTHNAME:
7506059Samurai      strncpy(VarAuthName, *argv, sizeof(VarAuthName)-1);
7516059Samurai      break;
7526059Samurai    case VAR_DIAL:
7536059Samurai      strncpy(VarDialScript, *argv, sizeof(VarDialScript)-1);
7546059Samurai      break;
7556059Samurai    case VAR_LOGIN:
7566059Samurai      strncpy(VarLoginScript, *argv, sizeof(VarDialScript)-1);
7576059Samurai      break;
7586059Samurai    case VAR_DEVICE:
7596059Samurai      strncpy(VarDevice, *argv, sizeof(VarDevice)-1);
7606059Samurai      break;
7616059Samurai    case VAR_ACCMAP:
7626059Samurai      sscanf(*argv, "%x", &map);
7636059Samurai      VarAccmap = map;
7646059Samurai      break;
7656059Samurai    case VAR_PHONE:
7666059Samurai      strncpy(VarPhone, *argv, sizeof(VarPhone)-1);
7676059Samurai      break;
7686059Samurai    }
7696059Samurai  }
7706059Samurai  return(1);
7716059Samurai}
7726059Samurai
7736059Samuraistatic int SetOpenMode(list, argc, argv)
7746059Samuraistruct cmdtab *list;
7756059Samuraiint argc;
7766059Samuraichar **argv;
7776059Samurai{
7786059Samurai  if (argc > 0) {
7796059Samurai    if (strcmp(*argv, "active") == 0)
7806059Samurai      VarOpenMode = OPEN_ACTIVE;
7816059Samurai    else if (strcmp(*argv, "passive") == 0)
7826059Samurai      VarOpenMode = OPEN_PASSIVE;
7836059Samurai    else
7846059Samurai      printf("Invalid mode.\n");
7856059Samurai  }
7866059Samurai  return(1);
7876059Samurai}
7886059Samurai
7896059Samuraistatic char StrChatStr[] = "chat-script";
7906059Samuraistatic char StrValue[] = "value";
7916059Samurai
7926735Samuraiextern int SetIfilter(), SetOfilter(), SetDfilter(), SetAfilter();
7936059Samurai
7946059Samuraistruct cmdtab SetCommands[] = {
7956735Samurai  { "accmap",   NULL,	  SetVariable,		LOCAL_AUTH,
7966735Samurai	"Set accmap value", "hex-value", (void *)VAR_ACCMAP},
7976735Samurai  { "afilter",  NULL,     SetAfilter, 		LOCAL_AUTH,
7986735Samurai	"Set keep Alive filter", "..."},
7996735Samurai  { "authkey",  "key",     SetVariable,		LOCAL_AUTH,
8006735Samurai	"Set authentication key", "key", (void *)VAR_AUTHKEY},
8016735Samurai  { "authname", NULL,     SetVariable,		LOCAL_AUTH,
8026735Samurai	"Set authentication name", "name", (void *)VAR_AUTHNAME},
8036735Samurai  { "debug",    NULL,	  SetDebugLevel,	LOCAL_AUTH,
8046735Samurai	"Set debug level", StrValue},
8056735Samurai  { "device",     "line", SetVariable, 		LOCAL_AUTH,
8066735Samurai	"Set modem device name", "device-name",	(void *)VAR_DEVICE},
8076735Samurai  { "dfilter",  NULL,     SetDfilter,		 LOCAL_AUTH,
8086735Samurai	"Set demand filter", "..."},
8096735Samurai  { "dial",     NULL,     SetVariable, 		LOCAL_AUTH,
8106735Samurai	"Set dialing script", StrChatStr, (void *)VAR_DIAL},
8116735Samurai  { "escape",   NULL,	  SetEscape, 		LOCAL_AUTH,
8126735Samurai	"Set escape characters", "hex-digit ..."},
8136735Samurai  { "ifaddr",   NULL,   SetInterfaceAddr,	LOCAL_AUTH,
8146735Samurai	"Set destination address", "src-addr dst-addr netmask"},
8156735Samurai  { "ifilter",  NULL,     SetIfilter, 		LOCAL_AUTH,
8166735Samurai	"Set input filter", "..."},
8176735Samurai  { "login",    NULL,     SetVariable,		LOCAL_AUTH,
8186735Samurai	"Set login script", StrChatStr,	(void *)VAR_LOGIN },
8196735Samurai  { "mru",      "mtu",    SetInitialMRU,	LOCAL_AUTH,
8206735Samurai	"Set Initial MRU value", StrValue },
8216735Samurai  { "ofilter",  NULL,	  SetOfilter,		LOCAL_AUTH,
8226735Samurai	"Set output filter", "..." },
8236735Samurai  { "openmode", NULL,	  SetOpenMode,		LOCAL_AUTH,
8246735Samurai	"Set open mode", "[active|passive]"},
8256735Samurai  { "parity",   NULL,     SetModemParity,	LOCAL_AUTH,
8266735Samurai	"Set modem parity", "[odd|even|none]"},
8276735Samurai  { "phone",    NULL,     SetVariable,		LOCAL_AUTH,
8286735Samurai	"Set telephone number", "phone-number",	(void *)VAR_PHONE },
8296735Samurai  { "speed",    NULL,     SetModemSpeed,	LOCAL_AUTH,
8306735Samurai	"Set modem speed", "speed"},
8316735Samurai  { "timeout",  NULL,     SetIdleTimeout,	LOCAL_AUTH,
8326735Samurai	"Set Idle timeout", StrValue},
8336735Samurai  { "help",     "?",      HelpCommand,		LOCAL_AUTH | LOCAL_NO_AUTH,
8346735Samurai	"Display this message", StrNull, (void *)SetCommands},
8356059Samurai  { NULL,       NULL,     NULL },
8366059Samurai};
8376059Samurai
8386059Samuraistatic int
8396059SamuraiSetCommand(list, argc, argv)
8406059Samuraistruct cmdtab *list;
8416059Samuraiint argc;
8426059Samuraichar **argv;
8436059Samurai{
8446059Samurai  int val = 1;
8456059Samurai
8466059Samurai  if (argc > 0)
8476059Samurai    val = FindExec(SetCommands, argc, argv);
8486059Samurai  else
8496059Samurai    printf("Use ``set ?'' to get a list.\n");
8506059Samurai  return(val);
8516059Samurai}
8526059Samurai
8536059Samurai
8546059Samuraistatic int
8556059SamuraiAddCommand(list, argc, argv)
8566059Samuraistruct cmdtab *list;
8576059Samuraiint argc;
8586059Samuraichar **argv;
8596059Samurai{
8606059Samurai  struct in_addr dest, gateway, netmask;
8616059Samurai
8626059Samurai  if (argc == 3) {
8636059Samurai    dest = GetIpAddr(argv[0]);
8646059Samurai    netmask = GetIpAddr(argv[1]);
8656059Samurai    if (strcmp(argv[2], "HISADDR") == 0)
8666059Samurai      gateway = IpcpInfo.his_ipaddr;
8676059Samurai    else
8686059Samurai      gateway = GetIpAddr(argv[2]);
8696059Samurai    OsSetRoute(RTM_ADD, dest, gateway, netmask);
8706059Samurai  } else {
8716059Samurai    printf("Usage: %s %s\n", list->name, list->syntax);
8726059Samurai  }
8736059Samurai  return(1);
8746059Samurai}
8756059Samurai
8766059Samuraistatic int
8776059SamuraiDeleteCommand(list, argc, argv)
8786059Samuraistruct cmdtab *list;
8796059Samuraiint argc;
8806059Samuraichar **argv;
8816059Samurai{
8826059Samurai  struct in_addr dest, gateway, netmask;
8836059Samurai
8846059Samurai  if (argc >= 2) {
8856059Samurai    dest = GetIpAddr(argv[0]);
8866059Samurai    if (strcmp(argv[1], "HISADDR") == 0)
8876059Samurai      gateway = IpcpInfo.his_ipaddr;
8886059Samurai    else
8896059Samurai      gateway = GetIpAddr(argv[1]);
8906059Samurai    netmask.s_addr = 0;
8916059Samurai    if (argc == 3) {
8926059Samurai      if (inet_aton(argv[1], &netmask) == 0) {
8936059Samurai	printf("bad netmask value.\n");
8946059Samurai	return(1);
8956059Samurai      }
8966059Samurai    }
8976059Samurai    OsSetRoute(RTM_DELETE, dest, gateway, netmask);
8986059Samurai  } else if (argc == 1 && strcmp(argv[0], "ALL") == 0) {
8996059Samurai    DeleteIfRoutes(0);
9006059Samurai  } else {
9016059Samurai    printf("Usage: %s %s\n", list->name, list->syntax);
9026059Samurai  }
9036059Samurai  return(1);
9046059Samurai}
9056059Samurai
906