command.c revision 27346
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 *
2027346Sbrian * $Id: command.c,v 1.65 1997/06/30 03:03:29 brian Exp $
218857Srgrimes *
226059Samurai */
2313379Sphk#include <sys/types.h>
2427089Sbrian#include <sys/stat.h>
256059Samurai#include <ctype.h>
266735Samurai#include <termios.h>
2713385Speter#include <sys/wait.h>
2813379Sphk#include <time.h>
2926031Sbrian#include <netdb.h>
3026031Sbrian#include <sys/socket.h>
3126031Sbrian#include <netinet/in.h>
3226031Sbrian#include <arpa/inet.h>
3326031Sbrian#include <net/route.h>
3426031Sbrian#include <paths.h>
3526031Sbrian#include <alias.h>
3626516Sbrian#include <fcntl.h>
3726516Sbrian#include <errno.h>
386059Samurai#include "fsm.h"
396059Samurai#include "phase.h"
406059Samurai#include "lcp.h"
416059Samurai#include "ipcp.h"
426059Samurai#include "modem.h"
4313389Sphk#include "filter.h"
446059Samurai#include "command.h"
4526031Sbrian#include "alias_cmd.h"
466059Samurai#include "hdlc.h"
4726142Sbrian#include "loadalias.h"
486059Samurai#include "vars.h"
4925630Sbrian#include "systems.h"
5025630Sbrian#include "chat.h"
516059Samurai#include "os.h"
5226516Sbrian#include "timeout.h"
5326940Sbrian#include "server.h"
546059Samurai
556059Samuraiextern void Cleanup(), TtyTermMode(), PacketMode();
566059Samuraiextern int  EnableCommand(), DisableCommand(), DisplayCommand();
576059Samuraiextern int  AcceptCommand(), DenyCommand();
5826031Sbrianstatic int  AliasCommand();
596735Samuraiextern int  LocalAuthCommand();
606059Samuraiextern int  LoadCommand(), SaveCommand();
616059Samuraiextern int  ChangeParity(char *);
626059Samuraiextern int  SelectSystem();
636059Samuraiextern int  ShowRoute();
6410528Samuraiextern void TtyOldMode(), TtyCommandMode();
656735Samuraiextern struct pppvars pppVars;
6614418Sacheextern struct cmdtab const SetCommands[];
676059Samurai
6822973Sphkextern char *IfDevName;
6922973Sphk
706059Samuraistruct in_addr ifnetmask;
7123603Sacheint randinit;
726059Samurai
736059Samuraistatic int ShowCommand(), TerminalCommand(), QuitCommand();
746059Samuraistatic int CloseCommand(), DialCommand(), DownCommand();
756059Samuraistatic int SetCommand(), AddCommand(), DeleteCommand();
7610528Samuraistatic int ShellCommand();
776059Samurai
786059Samuraistatic int
796059SamuraiHelpCommand(list, argc, argv, plist)
806059Samuraistruct cmdtab *list;
816059Samuraiint argc;
826059Samuraichar **argv;
836059Samuraistruct cmdtab *plist;
846059Samurai{
856059Samurai  struct cmdtab *cmd;
866059Samurai  int n;
876059Samurai
8826516Sbrian  if (!VarTerm)
8926516Sbrian    return 0;
9026516Sbrian
916059Samurai  if (argc > 0) {
9226516Sbrian    for (cmd = plist; cmd->name; cmd++)
9325566Sbrian      if (strcasecmp(cmd->name, *argv) == 0 && (cmd->lauth & VarLocalAuth)) {
9426516Sbrian        fprintf(VarTerm, "%s\n", cmd->syntax);
9526516Sbrian        return 0;
966059Samurai      }
9726516Sbrian
9826516Sbrian    return -1;
996059Samurai  }
10026516Sbrian
1016059Samurai  n = 0;
10226516Sbrian  for (cmd = plist; cmd->func; cmd++)
1036764Samurai    if (cmd->name && (cmd->lauth & VarLocalAuth)) {
10426587Sbrian      fprintf(VarTerm, "  %-9s: %-20s\n", cmd->name, cmd->helpmes);
1056059Samurai      n++;
1066059Samurai    }
10726516Sbrian
1086059Samurai  if (n & 1)
10926516Sbrian    fprintf(VarTerm, "\n");
11026516Sbrian
11126516Sbrian  return 0;
1126059Samurai}
1136059Samurai
1146059Samuraiint
1156059SamuraiIsInteractive()
1166059Samurai{
1176059Samurai  char *mes = NULL;
1186059Samurai
11920120Snate  if (mode & MODE_DDIAL)
12020120Snate    mes = "Working in dedicated dial mode.";
12125908Sbrian  else if (mode & MODE_BACKGROUND)
12225908Sbrian    mes = "Working in background mode.";
12320120Snate  else if (mode & MODE_AUTO)
12410528Samurai    mes = "Working in auto mode.";
1256059Samurai  else if (mode & MODE_DIRECT)
12610528Samurai    mes = "Working in direct mode.";
1276059Samurai  else if (mode & MODE_DEDICATED)
12810528Samurai    mes = "Working in dedicated mode.";
1296059Samurai  if (mes) {
13026516Sbrian    if (VarTerm)
13126516Sbrian      fprintf(VarTerm, "%s\n", mes);
13226516Sbrian    return 0;
1336059Samurai  }
13426516Sbrian  return 1;
1356059Samurai}
1366059Samurai
1376059Samuraistatic int
1386059SamuraiDialCommand(cmdlist, argc, argv)
1396059Samuraistruct cmdtab *cmdlist;
1406059Samuraiint argc;
1416059Samuraichar **argv;
1426059Samurai{
14311336Samurai  int tries;
14426858Sbrian  int res;
14511336Samurai
1466059Samurai  if (LcpFsm.state > ST_CLOSED) {
14726516Sbrian    if (VarTerm)
14826516Sbrian      fprintf(VarTerm, "LCP state is [%s]\n", StateNames[LcpFsm.state]);
14926516Sbrian    return 0;
1506059Samurai  }
15126516Sbrian
1526059Samurai  if (!IsInteractive())
1536059Samurai    return(1);
15426516Sbrian
1556735Samurai  if (argc > 0) {
1566735Samurai    if (SelectSystem(*argv, CONFFILE) < 0) {
15726516Sbrian      if (VarTerm)
15826516Sbrian        fprintf(VarTerm, "%s: not found.\n", *argv);
15926516Sbrian      return -1;
1606735Samurai    }
1616735Samurai  }
16226516Sbrian
16311336Samurai  tries = 0;
16411336Samurai  do {
16526516Sbrian    if (VarTerm)
16626516Sbrian      fprintf(VarTerm, "Dial attempt %u of %d\n", ++tries, VarDialTries);
16711336Samurai    modem = OpenModem(mode);
16811336Samurai    if (modem < 0) {
16926516Sbrian      if (VarTerm)
17026516Sbrian        fprintf(VarTerm, "Failed to open modem.\n");
17111336Samurai      break;
17211336Samurai    }
17326858Sbrian    if ((res = DialModem()) == EX_DONE) {
17411336Samurai      sleep(1);
17511336Samurai      ModemTimeout();
17611336Samurai      PacketMode();
17711336Samurai      break;
17826858Sbrian    } else if (res == EX_SIG)
17926858Sbrian      return 1;
18011336Samurai  } while (VarDialTries == 0 || tries < VarDialTries);
18126516Sbrian
18226516Sbrian  return 0;
1836059Samurai}
1846059Samurai
18510528Samuraistatic int
18610528SamuraiShellCommand(cmdlist, argc, argv)
18710528Samuraistruct cmdtab *cmdlist;
18810528Samuraiint argc;
18910528Samuraichar **argv;
19010528Samurai{
19110528Samurai  const char *shell;
19210528Samurai  pid_t shpid;
19326516Sbrian  FILE *oVarTerm;
19420813Sjkh
19518856Ssos#ifdef SHELL_ONLY_INTERACTIVELY
19626911Sbrian  /* we're only allowed to shell when we run ppp interactively */
19726516Sbrian  if (mode != MODE_INTER) {
19826516Sbrian    LogPrintf(LogWARN, "Can only start a shell in interactive mode\n");
19926516Sbrian    return 1;
20010528Samurai  }
20126911Sbrian#endif
20226911Sbrian#ifdef NO_SHELL_IN_AUTO_INTERACTIVE
20326911Sbrian  /*
20426911Sbrian   * we want to stop shell commands when we've got a telnet connection
20526911Sbrian   * to an auto mode ppp
20626911Sbrian   */
20726516Sbrian  if ((mode & (MODE_AUTO|MODE_INTER)) == (MODE_AUTO|MODE_INTER)) {
20826516Sbrian    LogPrintf(LogWARN,  "Shell is not allowed interactively in auto mode\n");
20926516Sbrian    return 1;
21026516Sbrian  }
21126516Sbrian#endif
21226516Sbrian
21310528Samurai  if(argc == 0 && !(mode & MODE_INTER)) {
21426516Sbrian    LogPrintf(LogWARN, "Can only start an interactive shell in"
21526516Sbrian	      " interactive mode\n");
21626516Sbrian    return 1;
21710528Samurai  }
21826516Sbrian
21926516Sbrian  if((shell = getenv("SHELL")) == 0)
22026516Sbrian    shell = _PATH_BSHELL;
22126516Sbrian
22210528Samurai  if((shpid = fork()) == 0) {
22326516Sbrian     int dtablesize, i, fd;
22418531Sbde
22526516Sbrian     if (VarTerm)
22626516Sbrian       fd = fileno(VarTerm);
22726516Sbrian     else if ((fd = open("/dev/null", O_RDWR)) == -1) {
22826516Sbrian       LogPrintf(LogALERT, "Failed to open /dev/null: %s\n", strerror(errno));
22926516Sbrian       exit(1);
23026516Sbrian     }
23126516Sbrian
23226516Sbrian     for (i = 0; i < 3; i++)
23326516Sbrian       dup2(fd, i);
23426516Sbrian
23526516Sbrian     if (fd > 2)
23626516Sbrian       if (VarTerm) {
23726516Sbrian	 oVarTerm = VarTerm;
23826516Sbrian	 VarTerm = 0;
23926516Sbrian         if (oVarTerm && oVarTerm != stdout)
24026516Sbrian           fclose(oVarTerm);
24126516Sbrian       } else
24226516Sbrian         close(fd);
24326516Sbrian
24418531Sbde     for (dtablesize = getdtablesize(), i = 3; i < dtablesize; i++)
24510528Samurai	(void)close(i);
24610528Samurai
24710528Samurai     /*
24810528Samurai      * We are running setuid, we should change to
24910528Samurai      * real user for avoiding security problems.
25010528Samurai      */
25116263Sache     if (setgid(getgid()) < 0) {
25226516Sbrian        LogPrintf(LogERROR, "setgid: %s\n", strerror(errno));
25316263Sache	exit(1);
25416263Sache     }
25516263Sache     if (setuid(getuid()) < 0) {
25626516Sbrian        LogPrintf(LogERROR, "setuid: %s\n", strerror(errno));
25716263Sache	exit(1);
25816263Sache     }
25910528Samurai     TtyOldMode();
26018790Ssos     if(argc > 0) {
26118790Ssos       /* substitute pseudo args */
26227011Sbrian       for (i=1; i<argc; i++)
26327011Sbrian         if (strcasecmp(argv[i], "HISADDR") == 0)
26418790Ssos           argv[i] = strdup(inet_ntoa(IpcpInfo.his_ipaddr));
26527011Sbrian         else if (strcasecmp(argv[i], "INTERFACE") == 0)
26622973Sphk           argv[i] = strdup(IfDevName);
26727011Sbrian         else if (strcasecmp(argv[i], "MYADDR") == 0)
26818790Ssos           argv[i] = strdup(inet_ntoa(IpcpInfo.want_ipaddr));
26925630Sbrian       (void)execvp(argv[0], argv);
27018790Ssos     }
27110528Samurai     else
27225630Sbrian       (void)execl(shell, shell, NULL);
27320813Sjkh
27426516Sbrian     LogPrintf(LogWARN, "exec() of %s failed\n", argc > 0 ? argv[0] : shell);
27510528Samurai     exit(255);
27610528Samurai  }
27726516Sbrian
27810528Samurai  if( shpid == (pid_t)-1 ) {
27926516Sbrian    LogPrintf(LogERROR, "Fork failed: %s\n", strerror(errno));
28010528Samurai  } else {
28110528Samurai    int status;
28210528Samurai    (void)waitpid(shpid, &status, 0);
28310528Samurai  }
28420813Sjkh
28510528Samurai  TtyCommandMode(1);
28620813Sjkh
28710528Samurai  return(0);
28810528Samurai}
28910528Samurai
29013760Sphkstruct cmdtab const Commands[] = {
2916735Samurai  { "accept",  NULL,    AcceptCommand,	LOCAL_AUTH,
29226516Sbrian  	"accept option request",	"accept option .."},
2936735Samurai  { "add",     NULL,	AddCommand,	LOCAL_AUTH,
29426516Sbrian	"add route",			"add dest mask gateway"},
2956735Samurai  { "close",   NULL,    CloseCommand,	LOCAL_AUTH,
29626516Sbrian	"Close connection",		"close"},
2976735Samurai  { "delete",  NULL,    DeleteCommand,	LOCAL_AUTH,
29826591Sbrian	"delete route",                 "delete ALL | dest [gateway [mask]]"},
2996735Samurai  { "deny",    NULL,    DenyCommand,	LOCAL_AUTH,
30026516Sbrian  	"Deny option request",		"deny option .."},
3016735Samurai  { "dial",    "call",  DialCommand,	LOCAL_AUTH,
30226516Sbrian  	"Dial and login",		"dial|call [remote]"},
3036735Samurai  { "disable", NULL,    DisableCommand,	LOCAL_AUTH,
30426516Sbrian  	"Disable option",		"disable option .."},
3056735Samurai  { "display", NULL,    DisplayCommand,	LOCAL_AUTH,
30626516Sbrian  	"Display option configs",	"display"},
3076735Samurai  { "enable",  NULL,    EnableCommand,	LOCAL_AUTH,
30826516Sbrian  	"Enable option",		"enable option .."},
3096764Samurai  { "passwd",  NULL,	LocalAuthCommand,LOCAL_NO_AUTH,
31026516Sbrian  	"Password for manipulation", "passwd option .."},
3116735Samurai  { "load",    NULL,    LoadCommand,	LOCAL_AUTH,
31226516Sbrian  	"Load settings",		"load [remote]"},
3136735Samurai  { "save",    NULL,    SaveCommand,	LOCAL_AUTH,
31426516Sbrian  	"Save settings", "save"},
3156735Samurai  { "set",     "setup", SetCommand,	LOCAL_AUTH,
31626516Sbrian  	"Set parameters",  "set[up] var value"},
31710528Samurai  { "shell",   "!",     ShellCommand,   LOCAL_AUTH,
31826516Sbrian	"Run a subshell",  "shell|! [sh command]"},
3196735Samurai  { "show",    NULL,    ShowCommand,	LOCAL_AUTH,
32026516Sbrian  	"Show status and statictics", "show var"},
3216735Samurai  { "term",    NULL,    TerminalCommand,LOCAL_AUTH,
32226516Sbrian  	"Enter to terminal mode", "term"},
32326031Sbrian  { "alias",   NULL,    AliasCommand,   LOCAL_AUTH,
32426516Sbrian        "alias control",        "alias option [yes|no]"},
3256764Samurai  { "quit",    "bye",   QuitCommand,	LOCAL_AUTH | LOCAL_NO_AUTH,
32626516Sbrian	"Quit PPP program", "quit|bye [all]"},
3276735Samurai  { "help",    "?",     HelpCommand,	LOCAL_AUTH | LOCAL_NO_AUTH,
32826516Sbrian	"Display this message", "help|? [command]", (void *)Commands },
3296735Samurai  { NULL,      "down",  DownCommand,	LOCAL_AUTH,
33026516Sbrian  	"Generate down event",		"down"},
3316059Samurai  { NULL,      NULL,    NULL },
3326059Samurai};
3336059Samurai
3346059Samuraiextern int ReportCcpStatus();
3356059Samuraiextern int ReportLcpStatus();
3366059Samuraiextern int ReportIpcpStatus();
3376059Samuraiextern int ReportProtStatus();
3386059Samuraiextern int ReportCompress();
3396059Samuraiextern int ShowModemStatus();
3406059Samuraiextern int ReportHdlcStatus();
3416059Samuraiextern int ShowMemMap();
3426059Samurai
34326516Sbrianstatic int ShowLogLevel()
3446059Samurai{
3456059Samurai  int i;
3466059Samurai
34726516Sbrian  if (!VarTerm)
34826516Sbrian    return 0;
34926516Sbrian  fprintf(VarTerm, "Log:");
35026516Sbrian  for (i = LogMIN; i < LogMAXCONF; i++) {
35126516Sbrian    if (LogIsKept(i))
35226516Sbrian      fprintf(VarTerm, " %s", LogName(i));
3536059Samurai  }
35426516Sbrian  fprintf(VarTerm, "\n");
35526516Sbrian
35626516Sbrian  return 0;
3576059Samurai}
3586059Samurai
3596059Samuraistatic int ShowEscape()
3606059Samurai{
3616059Samurai  int code, bit;
3626059Samurai
36326516Sbrian  if (!VarTerm)
36426516Sbrian    return 0;
3656059Samurai  if (EscMap[32]) {
36626516Sbrian    for (code = 0; code < 32; code++)
36726516Sbrian      if (EscMap[code])
36826516Sbrian        for (bit = 0; bit < 8; bit++)
36926516Sbrian          if (EscMap[code] & (1<<bit))
37026516Sbrian            fprintf(VarTerm, " 0x%02x", (code << 3) + bit);
37126516Sbrian    fprintf(VarTerm, "\n");
3726059Samurai  }
37326516Sbrian  return 1;
3746059Samurai}
3756059Samurai
3766059Samuraistatic int ShowTimeout()
3776059Samurai{
37826516Sbrian  if (!VarTerm)
37926516Sbrian    return 0;
38026516Sbrian  fprintf(VarTerm, " Idle Timer: %d secs   LQR Timer: %d secs"
38126516Sbrian          "   Retry Timer: %d secs\n", VarIdleTimeout, VarLqrTimeout,
38226516Sbrian          VarRetryTimeout);
38326516Sbrian  return 1;
3846059Samurai}
3856059Samurai
3866059Samuraistatic int ShowAuthKey()
3876059Samurai{
38826516Sbrian  if (!VarTerm)
38926516Sbrian    return 0;
39026516Sbrian  fprintf(VarTerm, "AuthName = %s\n", VarAuthName);
39126516Sbrian  fprintf(VarTerm, "AuthKey  = %s\n", VarAuthKey);
39226516Sbrian  return 1;
3936059Samurai}
3946059Samurai
3956059Samuraistatic int ShowVersion()
3966059Samurai{
39713389Sphk  extern char VarVersion[];
39813389Sphk  extern char VarLocalVersion[];
3996059Samurai
40026516Sbrian  if (!VarTerm)
40126516Sbrian    return 0;
40226516Sbrian  fprintf(VarTerm, "%s - %s \n", VarVersion, VarLocalVersion);
40326516Sbrian  return 1;
4046059Samurai}
4056059Samurai
40626326Sbrianstatic int ShowInitialMRU()
40726326Sbrian{
40826516Sbrian  if (!VarTerm)
40926516Sbrian    return 0;
41026516Sbrian  fprintf(VarTerm, " Initial MRU: %ld\n", VarMRU);
41126516Sbrian  return 1;
41226326Sbrian}
41326326Sbrian
41426326Sbrianstatic int ShowPreferredMTU()
41526326Sbrian{
41626516Sbrian  if (!VarTerm)
41726516Sbrian    return 0;
41826326Sbrian  if (VarPrefMTU)
41926516Sbrian    fprintf(VarTerm, " Preferred MTU: %ld\n", VarPrefMTU);
42026326Sbrian  else
42126516Sbrian    fprintf(VarTerm, " Preferred MTU: unspecified\n");
42226516Sbrian  return 1;
42326326Sbrian}
42426326Sbrian
42525067Sbrianstatic int ShowReconnect()
42625067Sbrian{
42726516Sbrian  if (!VarTerm)
42826516Sbrian    return 0;
42926516Sbrian  fprintf(VarTerm, " Reconnect Timer:  %d,  %d tries\n",
43025067Sbrian         VarReconnectTimer, VarReconnectTries);
43126516Sbrian  return 1;
43225067Sbrian}
43325067Sbrian
43411336Samuraistatic int ShowRedial()
43511336Samurai{
43626516Sbrian  if (!VarTerm)
43726516Sbrian    return 0;
43826516Sbrian  fprintf(VarTerm, " Redial Timer: ");
43911336Samurai
44011336Samurai  if (VarRedialTimeout >= 0) {
44126516Sbrian    fprintf(VarTerm, " %d seconds, ", VarRedialTimeout);
44211336Samurai  }
44311336Samurai  else {
44426516Sbrian    fprintf(VarTerm, " Random 0 - %d seconds, ", REDIAL_PERIOD);
44511336Samurai  }
44611336Samurai
44726516Sbrian  fprintf(VarTerm, " Redial Next Timer: ");
44824939Sbrian
44924939Sbrian  if (VarRedialNextTimeout >= 0) {
45026516Sbrian    fprintf(VarTerm, " %d seconds, ", VarRedialNextTimeout);
45124939Sbrian  }
45224939Sbrian  else {
45326516Sbrian    fprintf(VarTerm, " Random 0 - %d seconds, ", REDIAL_PERIOD);
45424939Sbrian  }
45524939Sbrian
45611336Samurai  if (VarDialTries)
45726516Sbrian      fprintf(VarTerm, "%d dial tries", VarDialTries);
45811336Samurai
45926516Sbrian  fprintf(VarTerm, "\n");
46011336Samurai
46126516Sbrian  return 1;
46211336Samurai}
46311336Samurai
46426516Sbrian#ifndef NOMSEXT
46518752Sjkhstatic int ShowMSExt()
46618752Sjkh{
46726516Sbrian  if (!VarTerm)
46826516Sbrian    return 0;
46926516Sbrian  fprintf(VarTerm, " MS PPP extention values \n" );
47026516Sbrian  fprintf(VarTerm, "   Primary NS     : %s\n", inet_ntoa( ns_entries[0] ));
47126516Sbrian  fprintf(VarTerm, "   Secondary NS   : %s\n", inet_ntoa( ns_entries[1] ));
47226516Sbrian  fprintf(VarTerm, "   Primary NBNS   : %s\n", inet_ntoa( nbns_entries[0] ));
47326516Sbrian  fprintf(VarTerm, "   Secondary NBNS : %s\n", inet_ntoa( nbns_entries[1] ));
47426516Sbrian  return 1;
47518752Sjkh}
47626516Sbrian#endif
47718752Sjkh
4786735Samuraiextern int ShowIfilter(), ShowOfilter(), ShowDfilter(), ShowAfilter();
4796059Samurai
48013760Sphkstruct cmdtab const ShowCommands[] = {
4816735Samurai  { "afilter",  NULL,     ShowAfilter,		LOCAL_AUTH,
48226516Sbrian	"Show keep Alive filters", "show afilter option .."},
4836735Samurai  { "auth",     NULL,     ShowAuthKey,		LOCAL_AUTH,
48426516Sbrian	"Show auth name/key", "show auth"},
4856735Samurai  { "ccp",      NULL,     ReportCcpStatus,	LOCAL_AUTH,
48626516Sbrian	"Show CCP status", "show cpp"},
4876735Samurai  { "compress", NULL,     ReportCompress,	LOCAL_AUTH,
48826516Sbrian	"Show compression statictics", "show compress"},
4896735Samurai  { "dfilter",  NULL,     ShowDfilter,		LOCAL_AUTH,
49026516Sbrian	"Show Demand filters", "show dfilteroption .."},
4916735Samurai  { "escape",   NULL,     ShowEscape,		LOCAL_AUTH,
49226516Sbrian	"Show escape characters", "show escape"},
4936735Samurai  { "hdlc",	NULL,	  ReportHdlcStatus,	LOCAL_AUTH,
49426516Sbrian	"Show HDLC error summary", "show hdlc"},
4956735Samurai  { "ifilter",  NULL,     ShowIfilter,		LOCAL_AUTH,
49626516Sbrian	"Show Input filters", "show ifilter option .."},
4976735Samurai  { "ipcp",     NULL,     ReportIpcpStatus,	LOCAL_AUTH,
49826516Sbrian	"Show IPCP status", "show ipcp"},
4996735Samurai  { "lcp",      NULL,     ReportLcpStatus,	LOCAL_AUTH,
50026516Sbrian	"Show LCP status", "show lcp"},
50126516Sbrian  { "log",	NULL,	  ShowLogLevel,	LOCAL_AUTH,
50226516Sbrian	"Show current log level", "show log"},
5036735Samurai  { "mem",      NULL,     ShowMemMap,		LOCAL_AUTH,
50426516Sbrian	"Show memory map", "show mem"},
5056735Samurai  { "modem",    NULL,     ShowModemStatus,	LOCAL_AUTH,
50626516Sbrian	"Show modem setups", "show modem"},
50726326Sbrian  { "mru",      NULL,     ShowInitialMRU,	LOCAL_AUTH,
50826516Sbrian	"Show Initial MRU", "show mru"},
50926326Sbrian  { "mtu",      NULL,     ShowPreferredMTU,	LOCAL_AUTH,
51026516Sbrian	"Show Preferred MTU", "show mtu"},
5116735Samurai  { "ofilter",  NULL,     ShowOfilter,		LOCAL_AUTH,
51226516Sbrian	"Show Output filters", "show ofilter option .."},
5136735Samurai  { "proto",    NULL,     ReportProtStatus,	LOCAL_AUTH,
51426516Sbrian	"Show protocol summary", "show proto"},
51525067Sbrian  { "reconnect",NULL,	  ShowReconnect,	LOCAL_AUTH,
51626516Sbrian	"Show Reconnect timer,tries", "show reconnect"},
51725067Sbrian  { "redial",   NULL,	  ShowRedial,		LOCAL_AUTH,
51826516Sbrian	"Show Redial timeout value", "show redial"},
5196735Samurai  { "route",    NULL,     ShowRoute,		LOCAL_AUTH,
52026516Sbrian	"Show routing table", "show route"},
5216735Samurai  { "timeout",  NULL,	  ShowTimeout,		LOCAL_AUTH,
52226516Sbrian	"Show Idle timeout value", "show timeout"},
52326516Sbrian#ifndef NOMSEXT
52418752Sjkh  { "msext", 	NULL,	  ShowMSExt,		LOCAL_AUTH,
52526516Sbrian	"Show MS PPP extentions", "show msext"},
52626516Sbrian#endif
5276735Samurai  { "version",  NULL,	  ShowVersion,		LOCAL_NO_AUTH | LOCAL_AUTH,
52826516Sbrian	"Show version string", "show version"},
5296735Samurai  { "help",     "?",      HelpCommand,		LOCAL_NO_AUTH | LOCAL_AUTH,
53026698Sbrian	"Display this message", "show help|? [command]", (void *)ShowCommands},
5316059Samurai  { NULL,       NULL,     NULL },
5326059Samurai};
5336059Samurai
5346059Samuraistruct cmdtab *
5356059SamuraiFindCommand(cmds, str, pmatch)
5366059Samuraistruct cmdtab *cmds;
5376059Samuraichar *str;
5386059Samuraiint *pmatch;
5396059Samurai{
54026516Sbrian  int nmatch;
54126516Sbrian  int len;
54226516Sbrian  struct cmdtab *found;
5436059Samurai
54426516Sbrian  found = NULL;
54526516Sbrian  len = strlen(str);
54626516Sbrian  nmatch = 0;
5476059Samurai  while (cmds->func) {
54825566Sbrian    if (cmds->name && strncasecmp(str, cmds->name, len) == 0) {
54926516Sbrian      if (cmds->name[len] == '\0') {
55026516Sbrian        *pmatch = 1;
55126516Sbrian        return cmds;
55226516Sbrian      }
5536059Samurai      nmatch++;
5546059Samurai      found = cmds;
55526516Sbrian    } else if(cmds->alias && strncasecmp(str, cmds->alias, len) == 0) {
55626516Sbrian      if (cmds->alias[len] == '\0') {
55726516Sbrian        *pmatch = 1;
55826516Sbrian        return cmds;
55926516Sbrian      }
5606059Samurai      nmatch++;
5616059Samurai      found = cmds;
5626059Samurai    }
5636059Samurai    cmds++;
5646059Samurai  }
5656059Samurai  *pmatch = nmatch;
56626516Sbrian  return found;
5676059Samurai}
5686059Samurai
5696059Samuraiint
5706059SamuraiFindExec(cmdlist, argc, argv)
5716059Samuraistruct cmdtab *cmdlist;
5726059Samuraiint argc;
5736059Samuraichar **argv;
5746059Samurai{
5756059Samurai  struct cmdtab *cmd;
5766059Samurai  int val = 1;
5776059Samurai  int nmatch;
5786059Samurai
5796059Samurai  cmd = FindCommand(cmdlist, *argv, &nmatch);
5806059Samurai  if (nmatch > 1)
58126516Sbrian    LogPrintf(LogWARN, "%s: Ambiguous command\n", *argv);
5826735Samurai  else if (cmd && ( cmd->lauth & VarLocalAuth ) )
5836059Samurai    val = (cmd->func)(cmd, --argc, ++argv, cmd->args);
5846059Samurai  else
58526516Sbrian    LogPrintf(LogWARN, "%s: Invalid command\n", *argv);
58626516Sbrian
58726516Sbrian  if (val == -1)
58826516Sbrian    LogPrintf(LogWARN, "Usage: %s\n", cmd->syntax);
58926516Sbrian  else if(val)
59026516Sbrian    LogPrintf(LogCOMMAND, "%s: Failed %d\n", *argv, val);
59126516Sbrian
59226516Sbrian  return val;
5936059Samurai}
5946059Samurai
59518885Sjkhint aft_cmd = 1;
59626516Sbrianextern int TermMode;
59718885Sjkh
5986059Samuraivoid
59918885SjkhPrompt()
6006059Samurai{
6016735Samurai  char *pconnect, *pauth;
6026735Samurai
60326516Sbrian  if (!(mode & MODE_INTER) || !VarTerm || TermMode)
6046059Samurai    return;
6056735Samurai
60618885Sjkh  if (!aft_cmd)
60726516Sbrian    fprintf(VarTerm, "\n");
60818885Sjkh  else
60918885Sjkh    aft_cmd = 0;
6106735Samurai
6116735Samurai  if ( VarLocalAuth == LOCAL_AUTH )
6126735Samurai    pauth = " ON ";
6136735Samurai  else
6146735Samurai    pauth = " on ";
6156059Samurai  if (IpcpFsm.state == ST_OPENED && phase == PHASE_NETWORK)
6166735Samurai    pconnect = "PPP";
6176059Samurai  else
6186735Samurai    pconnect = "ppp";
61926516Sbrian  fprintf(VarTerm, "%s%s%s> ", pconnect, pauth, VarShortHost);
62026516Sbrian  fflush(VarTerm);
6216059Samurai}
6226059Samurai
6236059Samuraivoid
6246059SamuraiDecodeCommand(buff, nb, prompt)
6256059Samuraichar *buff;
6266059Samuraiint nb;
6276059Samuraiint prompt;
6286059Samurai{
6296059Samurai  char *vector[20];
6306059Samurai  char **argv;
63126516Sbrian  int argc;
6326059Samurai  char *cp;
6336059Samurai
6346059Samurai  if (nb > 0) {
6356059Samurai    cp = buff + strcspn(buff, "\r\n");
6366059Samurai    if (cp)
6376059Samurai      *cp = '\0';
63826516Sbrian    argc = MakeArgs(buff, vector, VECSIZE(vector));
63926516Sbrian    argv = vector;
6406059Samurai
64126516Sbrian    if (argc > 0)
64226516Sbrian      FindExec(Commands, argc, argv);
6436059Samurai  }
64426516Sbrian  if (prompt)
64525630Sbrian    Prompt();
6466059Samurai}
6476059Samurai
6486059Samuraistatic int
6496059SamuraiShowCommand(list, argc, argv)
6506059Samuraistruct cmdtab *list;
6516059Samuraiint argc;
6526059Samuraichar **argv;
6536059Samurai{
6546059Samurai  if (argc > 0)
65526516Sbrian    FindExec(ShowCommands, argc, argv);
65626516Sbrian  else if (VarTerm)
65726516Sbrian    fprintf(VarTerm, "Use ``show ?'' to get a list.\n");
6586059Samurai  else
65926516Sbrian    LogPrintf(LogWARN, "show command must have arguments\n");
66026516Sbrian
66126516Sbrian  return 0;
6626059Samurai}
6636059Samurai
6646059Samuraistatic int
6656059SamuraiTerminalCommand()
6666059Samurai{
6676059Samurai  if (LcpFsm.state > ST_CLOSED) {
66826516Sbrian    if (VarTerm)
66926516Sbrian      fprintf(VarTerm, "LCP state is [%s]\n", StateNames[LcpFsm.state]);
67026516Sbrian    return 1;
6716059Samurai  }
6726059Samurai  if (!IsInteractive())
6736059Samurai    return(1);
6746059Samurai  modem = OpenModem(mode);
6756059Samurai  if (modem < 0) {
67626516Sbrian    if (VarTerm)
67726516Sbrian      fprintf(VarTerm, "Failed to open modem.\n");
6786059Samurai    return(1);
6796059Samurai  }
68026516Sbrian  if (VarTerm) {
68126516Sbrian    fprintf(VarTerm, "Enter to terminal mode.\n");
68226516Sbrian    fprintf(VarTerm, "Type `~?' for help.\n");
68326516Sbrian  }
6846059Samurai  TtyTermMode();
6856059Samurai  return(0);
6866059Samurai}
6876059Samurai
6886059Samuraistatic int
6896059SamuraiQuitCommand(list, argc, argv)
6906059Samuraistruct cmdtab *list;
6916059Samuraiint argc;
6926059Samuraichar **argv;
6936059Samurai{
69426516Sbrian  FILE *oVarTerm;
69526516Sbrian
6966059Samurai  if (mode & (MODE_DIRECT|MODE_DEDICATED|MODE_AUTO)) {
6976764Samurai    if (argc > 0 && (VarLocalAuth & LOCAL_AUTH)) {
6986059Samurai      Cleanup(EX_NORMAL);
69918911Ssos      mode &= ~MODE_INTER;
70026516Sbrian      oVarTerm = VarTerm;
70126516Sbrian      VarTerm = 0;
70226516Sbrian      if (oVarTerm && oVarTerm != stdout)
70326516Sbrian        fclose(oVarTerm);
7046059Samurai    } else {
70526516Sbrian      LogPrintf(LogPHASE, "Client connection closed.\n");
7066735Samurai      VarLocalAuth = LOCAL_NO_AUTH;
70726516Sbrian      mode &= ~MODE_INTER;
70826516Sbrian      oVarTerm = VarTerm;
70926516Sbrian      VarTerm = 0;
71026516Sbrian      if (oVarTerm && oVarTerm != stdout)
71126516Sbrian        fclose(oVarTerm);
7126059Samurai      close(netfd);
7136059Samurai      netfd = -1;
7146059Samurai    }
7156059Samurai  } else
7166059Samurai    Cleanup(EX_NORMAL);
71726516Sbrian
71826516Sbrian  return 0;
7196059Samurai}
7206059Samurai
7216059Samuraistatic int
7226059SamuraiCloseCommand()
7236059Samurai{
72426098Sbrian  reconnect(RECON_FALSE);
7256059Samurai  LcpClose();
72625908Sbrian  if (mode & MODE_BACKGROUND)
72725908Sbrian      Cleanup(EX_NORMAL);
72826516Sbrian  return 0;
7296059Samurai}
7306059Samurai
7316059Samuraistatic int
7326059SamuraiDownCommand()
7336059Samurai{
7346059Samurai  LcpDown();
73526516Sbrian  return 0;
7366059Samurai}
7376059Samurai
73825067Sbrianstatic int
73925067SbrianSetModemSpeed(list, argc, argv)
7406059Samuraistruct cmdtab *list;
7416059Samuraiint argc;
7426059Samuraichar **argv;
7436059Samurai{
7446059Samurai  int speed;
7456059Samurai
7466059Samurai  if (argc > 0) {
7476735Samurai    if (strcmp(*argv, "sync") == 0) {
7486735Samurai      VarSpeed = 0;
74926516Sbrian      return 0;
7506735Samurai    }
7516059Samurai    speed = atoi(*argv);
7526735Samurai    if (IntToSpeed(speed) != B0) {
7536735Samurai      VarSpeed = speed;
75426516Sbrian      return 0;
7556059Samurai    }
75626516Sbrian    LogPrintf(LogWARN, "%s: Invalid speed\n", *argv);
7576059Samurai  }
75826516Sbrian  return -1;
7596059Samurai}
7606059Samurai
76125067Sbrianstatic int
76225067SbrianSetReconnect(list, argc, argv)
76311336Samuraistruct cmdtab *list;
76411336Samuraiint argc;
76511336Samuraichar **argv;
76611336Samurai{
76725067Sbrian  if (argc == 2) {
76825067Sbrian    VarReconnectTimer = atoi(argv[0]);
76925067Sbrian    VarReconnectTries = atoi(argv[1]);
77026516Sbrian    return 0;
77126516Sbrian  }
77226516Sbrian
77326516Sbrian  return -1;
77425067Sbrian}
77525067Sbrian
77625067Sbrianstatic int
77725067SbrianSetRedialTimeout(list, argc, argv)
77825067Sbrianstruct cmdtab *list;
77925067Sbrianint argc;
78025067Sbrianchar **argv;
78125067Sbrian{
78211336Samurai  int timeout;
78311336Samurai  int tries;
78424939Sbrian  char *dot;
78511336Samurai
78611336Samurai  if (argc == 1 || argc == 2 ) {
78724939Sbrian    if (strncasecmp(argv[0], "random", 6) == 0 &&
78824939Sbrian	(argv[0][6] == '\0' || argv[0][6] == '.')) {
78911336Samurai      VarRedialTimeout = -1;
79023603Sache      if (!randinit) {
79123603Sache	randinit = 1;
79226626Sache	srandomdev();
79323603Sache      }
79426516Sbrian    } else {
79511336Samurai      timeout = atoi(argv[0]);
79611336Samurai
79726516Sbrian      if (timeout >= 0)
79811336Samurai	VarRedialTimeout = timeout;
79911336Samurai      else {
80026516Sbrian	LogPrintf(LogWARN, "Invalid redial timeout\n");
80126516Sbrian        return -1;
80211336Samurai      }
80311336Samurai    }
80424939Sbrian
80524939Sbrian    dot = index(argv[0],'.');
80624939Sbrian    if (dot) {
80724939Sbrian      if (strcasecmp(++dot, "random") == 0) {
80824939Sbrian        VarRedialNextTimeout = -1;
80924939Sbrian        if (!randinit) {
81024939Sbrian          randinit = 1;
81126626Sache	  srandomdev();
81224939Sbrian        }
81324939Sbrian      }
81424939Sbrian      else {
81524939Sbrian        timeout = atoi(dot);
81626516Sbrian        if (timeout >= 0)
81724939Sbrian          VarRedialNextTimeout = timeout;
81824939Sbrian        else {
81926516Sbrian          LogPrintf(LogWARN, "Invalid next redial timeout\n");
82026516Sbrian	  return -1;
82124939Sbrian        }
82224939Sbrian      }
82324939Sbrian    }
82424939Sbrian    else
82524939Sbrian      VarRedialNextTimeout = NEXT_REDIAL_PERIOD;   /* Default next timeout */
82624939Sbrian
82711336Samurai    if (argc == 2) {
82811336Samurai      tries = atoi(argv[1]);
82911336Samurai
83011336Samurai      if (tries >= 0) {
83126516Sbrian	VarDialTries = tries;
83226516Sbrian      } else {
83326516Sbrian	LogPrintf(LogWARN, "Invalid retry value\n");
83426516Sbrian	return 1;
83511336Samurai      }
83611336Samurai    }
83726516Sbrian    return 0;
83811336Samurai  }
83926516Sbrian
84026516Sbrian  return -1;
84111336Samurai}
84211336Samurai
84325067Sbrianstatic int
84426940SbrianSetServer(list, argc, argv)
84526940Sbrianstruct cmdtab *list;
84626940Sbrianint argc;
84726940Sbrianchar **argv;
84826940Sbrian{
84926940Sbrian  int res = -1;
85026940Sbrian
85127089Sbrian  if (argc > 0 && argc < 3)
85226940Sbrian    if (strcasecmp(argv[0], "none") == 0) {
85326940Sbrian      ServerClose();
85426940Sbrian      LogPrintf(LogPHASE, "Disabling server port.\n");
85526940Sbrian      res = 0;
85627089Sbrian    } else if (*argv[0] == '/') {
85727089Sbrian      mode_t mask;
85827089Sbrian      umask(mask = umask(0));
85927089Sbrian      if (argc == 2) {
86027089Sbrian        unsigned m;
86127089Sbrian        if (sscanf(argv[1], "%o", &m) == 1)
86227089Sbrian          mask = m;
86327089Sbrian      }
86427089Sbrian      res = ServerLocalOpen(argv[0], mask);
86527346Sbrian    } else {
86627346Sbrian      int port;
86727346Sbrian      if (strspn(argv[0], "0123456789") != strlen(argv[0])) {
86827346Sbrian        struct servent *s;
86927346Sbrian        if ((s = getservbyname(argv[0], "tcp")) == NULL) {
87027346Sbrian          port = 0;
87127346Sbrian          LogPrintf(LogWARN, "%s: Invalid port or service\n", argv[0]);
87227346Sbrian        } else
87327346Sbrian          port = ntohs(s->s_port);
87427346Sbrian      } else
87527346Sbrian        port = atoi(argv[0]);
87627346Sbrian      if (port)
87727346Sbrian        res = ServerTcpOpen(port);
87827346Sbrian    }
87926940Sbrian
88026940Sbrian  return res;
88126940Sbrian}
88226940Sbrian
88326940Sbrianstatic int
88425067SbrianSetModemParity(list, argc, argv)
8856059Samuraistruct cmdtab *list;
8866059Samuraiint argc;
8876059Samuraichar **argv;
8886059Samurai{
88926845Sbrian  return argc > 0 ? ChangeParity(*argv) : -1;
8906059Samurai}
8916059Samurai
8926059Samuraistatic int
89326516SbrianSetLogLevel(list, argc, argv)
8946059Samuraistruct cmdtab *list;
8956059Samuraiint argc;
8966059Samuraichar **argv;
8976059Samurai{
89826516Sbrian  int i;
89926516Sbrian  int res;
90026516Sbrian  char *arg;
9016059Samurai
90226516Sbrian  res = 0;
90326516Sbrian  if (argc == 0 || (argv[0][0] != '+' && argv[0][0] != '-'))
90426516Sbrian    LogDiscardAll();
90526516Sbrian  while (argc--) {
90626516Sbrian    arg = **argv == '+' || **argv == '-' ? *argv + 1 : *argv;
90726516Sbrian    for (i = LogMIN; i <= LogMAX; i++)
90826516Sbrian      if (strcasecmp(arg, LogName(i)) == 0) {
90926516Sbrian        if (**argv == '-')
91026516Sbrian          LogDiscard(i);
91126516Sbrian        else
91226516Sbrian	  LogKeep(i);
9136059Samurai	break;
9146059Samurai      }
91526516Sbrian    if (i > LogMAX) {
91626516Sbrian      LogPrintf(LogWARN, "%s: Invalid log value\n", arg);
91726516Sbrian      res = -1;
9186059Samurai    }
91926516Sbrian    argv++;
9206059Samurai  }
92126516Sbrian  return res;
9226059Samurai}
9236059Samurai
9246059Samuraistatic int
9256059SamuraiSetEscape(list, argc, argv)
9266059Samuraistruct cmdtab *list;
9276059Samuraiint argc;
9286059Samuraichar **argv;
9296059Samurai{
9306059Samurai  int code;
9316059Samurai
9326059Samurai  for (code = 0; code < 33; code++)
9336059Samurai    EscMap[code] = 0;
9346059Samurai  while (argc-- > 0) {
9356059Samurai    sscanf(*argv++, "%x", &code);
9366059Samurai    code &= 0xff;
9376059Samurai    EscMap[code >> 3] |= (1 << (code&7));
9386059Samurai    EscMap[32] = 1;
9396059Samurai  }
94026516Sbrian  return 0;
9416059Samurai}
9426059Samurai
9436059Samuraistatic int
9446059SamuraiSetInitialMRU(list, argc, argv)
9456059Samuraistruct cmdtab *list;
9466059Samuraiint argc;
9476059Samuraichar **argv;
9486059Samurai{
94926326Sbrian  long mru;
95026516Sbrian  char *err;
9516059Samurai
9526059Samurai  if (argc > 0) {
95326326Sbrian    mru = atol(*argv);
95426326Sbrian    if (mru < MIN_MRU)
95526516Sbrian      err = "Given MRU value (%ld) is too small.\n";
9566059Samurai    else if (mru > MAX_MRU)
95726516Sbrian      err = "Given MRU value (%ld) is too big.\n";
95826516Sbrian    else {
9596059Samurai      VarMRU = mru;
96026516Sbrian      return 0;
96126516Sbrian    }
96226516Sbrian    LogPrintf(LogWARN, err, mru);
96326516Sbrian  }
96426326Sbrian
96526516Sbrian  return -1;
9666059Samurai}
9676059Samurai
9686059Samuraistatic int
96926326SbrianSetPreferredMTU(list, argc, argv)
97026326Sbrianstruct cmdtab *list;
97126326Sbrianint argc;
97226326Sbrianchar **argv;
97326326Sbrian{
97426326Sbrian  long mtu;
97526516Sbrian  char *err;
97626326Sbrian
97726326Sbrian  if (argc > 0) {
97826326Sbrian    mtu = atol(*argv);
97926516Sbrian    if (mtu == 0) {
98026326Sbrian      VarPrefMTU = 0;
98126516Sbrian      return 0;
98226516Sbrian    } else if (mtu < MIN_MTU)
98326516Sbrian      err = "Given MTU value (%ld) is too small.\n";
98426326Sbrian    else if (mtu > MAX_MTU)
98526516Sbrian      err = "Given MTU value (%ld) is too big.\n";
98626516Sbrian    else {
98726326Sbrian      VarPrefMTU = mtu;
98826516Sbrian      return 0;
98926516Sbrian    }
99026516Sbrian    LogPrintf(LogWARN, err, mtu);
99126516Sbrian  }
99226326Sbrian
99326516Sbrian  return -1;
99426326Sbrian}
99526326Sbrian
99626326Sbrianstatic int
9976059SamuraiSetIdleTimeout(list, argc, argv)
9986059Samuraistruct cmdtab *list;
9996059Samuraiint argc;
10006059Samuraichar **argv;
10016059Samurai{
10026059Samurai  if (argc-- > 0) {
10036059Samurai    VarIdleTimeout = atoi(*argv++);
100426516Sbrian    UpdateIdleTimer();  /* If we're connected, restart the idle timer */
10056735Samurai    if (argc-- > 0) {
10066735Samurai      VarLqrTimeout = atoi(*argv++);
10076735Samurai      if (VarLqrTimeout < 1)
10086735Samurai	VarLqrTimeout = 30;
10096735Samurai      if (argc > 0) {
10106735Samurai	VarRetryTimeout = atoi(*argv);
10116735Samurai	if (VarRetryTimeout < 1 || VarRetryTimeout > 10)
10126735Samurai	  VarRetryTimeout = 3;
10136735Samurai      }
10146735Samurai    }
101526516Sbrian    return 0;
10166059Samurai  }
101726516Sbrian
101826516Sbrian  return -1;
10196059Samurai}
10206059Samurai
10216059Samuraistruct in_addr
10226059SamuraiGetIpAddr(cp)
10236059Samuraichar *cp;
10246059Samurai{
10256059Samurai  struct hostent *hp;
10266059Samurai  struct in_addr ipaddr;
10276059Samurai
10286059Samurai  hp = gethostbyname(cp);
10296059Samurai  if (hp && hp->h_addrtype == AF_INET)
10306059Samurai    bcopy(hp->h_addr, &ipaddr, hp->h_length);
10316059Samurai  else if (inet_aton(cp, &ipaddr) == 0)
10326059Samurai    ipaddr.s_addr = 0;
10336059Samurai  return(ipaddr);
10346059Samurai}
10356059Samurai
10366059Samuraistatic int
10376059SamuraiSetInterfaceAddr(list, argc, argv)
10386059Samuraistruct cmdtab *list;
10396059Samuraiint argc;
10406059Samuraichar **argv;
10416059Samurai{
10426059Samurai
10436059Samurai  DefMyAddress.ipaddr.s_addr = DefHisAddress.ipaddr.s_addr = 0L;
104426516Sbrian  if (argc > 4)
104526516Sbrian     return -1;
104626516Sbrian
10476059Samurai  if (argc > 0) {
104825630Sbrian    if (ParseAddr(argc, argv++,
104925630Sbrian            &DefMyAddress.ipaddr,
105025630Sbrian	    &DefMyAddress.mask,
105125630Sbrian	    &DefMyAddress.width) == 0)
105226516Sbrian       return 1;
10536059Samurai    if (--argc > 0) {
105425630Sbrian      if (ParseAddr(argc, argv++,
105525630Sbrian		    &DefHisAddress.ipaddr,
105625630Sbrian		    &DefHisAddress.mask,
105725630Sbrian		    &DefHisAddress.width) == 0)
105826516Sbrian	 return 2;
10596059Samurai      if (--argc > 0) {
10606059Samurai        ifnetmask = GetIpAddr(*argv);
10619440Samurai    	if (--argc > 0) {
106225630Sbrian	   if (ParseAddr(argc, argv++,
106325630Sbrian			 &DefTriggerAddress.ipaddr,
106425630Sbrian			 &DefTriggerAddress.mask,
106525630Sbrian			 &DefTriggerAddress.width) == 0)
106626516Sbrian	      return 3;
10679440Samurai	}
10686059Samurai      }
10696059Samurai    }
10706059Samurai  }
10716059Samurai  /*
10726059Samurai   * For backwards compatibility, 0.0.0.0 means any address.
10736059Samurai   */
10746059Samurai  if (DefMyAddress.ipaddr.s_addr == 0) {
10756059Samurai    DefMyAddress.mask.s_addr = 0;
10766059Samurai    DefMyAddress.width = 0;
10776059Samurai  }
10786059Samurai  if (DefHisAddress.ipaddr.s_addr == 0) {
10796059Samurai    DefHisAddress.mask.s_addr = 0;
10806059Samurai    DefHisAddress.width = 0;
10816059Samurai  }
10826059Samurai
10836735Samurai  if ((mode & MODE_AUTO) ||
10846059Samurai	((mode & MODE_DEDICATED) && dstsystem)) {
108525630Sbrian    if (OsSetIpaddress(DefMyAddress.ipaddr, DefHisAddress.ipaddr, ifnetmask) < 0)
108626516Sbrian       return 4;
10876059Samurai  }
108826516Sbrian  return 0;
10896059Samurai}
10906059Samurai
109126516Sbrian#ifndef NOMSEXT
10926059Samurai
109318752Sjkhvoid
109418752SjkhSetMSEXT(pri_addr, sec_addr, argc, argv)
109518752Sjkhstruct in_addr *pri_addr;
109618752Sjkhstruct in_addr *sec_addr;
109718752Sjkhint argc;
109818752Sjkhchar **argv;
109918752Sjkh{
110018752Sjkh  int dummyint;
110118752Sjkh  struct in_addr dummyaddr;
110218752Sjkh
110318752Sjkh  pri_addr->s_addr = sec_addr->s_addr = 0L;
110418752Sjkh
110518752Sjkh  if( argc > 0 ) {
110618752Sjkh    ParseAddr(argc, argv++, pri_addr, &dummyaddr, &dummyint);
110718752Sjkh    if( --argc > 0 )
110818752Sjkh      ParseAddr(argc, argv++, sec_addr, &dummyaddr, &dummyint);
110918752Sjkh    else
111018752Sjkh      sec_addr->s_addr = pri_addr->s_addr;
111118752Sjkh  }
111218752Sjkh
111318752Sjkh /*
111418752Sjkh  * if the primary/secondary ns entries are 0.0.0.0 we should
111518752Sjkh  * set them to either the localhost's ip, or the values in
111618752Sjkh  * /etc/resolv.conf ??
111718752Sjkh  *
111818752Sjkh  * up to you if you want to implement this...
111918752Sjkh  */
112018752Sjkh
112118752Sjkh}
112218752Sjkh
112318752Sjkhstatic int
112418752SjkhSetNS(list, argc, argv)
112518752Sjkhstruct cmdtab *list;
112618752Sjkhint argc;
112718752Sjkhchar **argv;
112818752Sjkh{
112918752Sjkh  SetMSEXT(&ns_entries[0], &ns_entries[1], argc, argv);
113026516Sbrian  return 0;
113118752Sjkh}
113218752Sjkh
113318752Sjkhstatic int
113418752SjkhSetNBNS(list, argc, argv)
113518752Sjkhstruct cmdtab *list;
113618752Sjkhint argc;
113718752Sjkhchar **argv;
113818752Sjkh{
113918752Sjkh  SetMSEXT(&nbns_entries[0], &nbns_entries[1], argc, argv);
114026516Sbrian  return 0;
114118752Sjkh}
114218752Sjkh
114318752Sjkh#endif /* MS_EXT */
114418752Sjkh
11456059Samurai#define	VAR_AUTHKEY	0
11466059Samurai#define	VAR_DIAL	1
11476059Samurai#define	VAR_LOGIN	2
11486059Samurai#define	VAR_AUTHNAME	3
11496059Samurai#define	VAR_DEVICE	4
11506059Samurai#define	VAR_ACCMAP	5
11516059Samurai#define	VAR_PHONE	6
11526059Samurai
11536059Samuraistatic int
11546059SamuraiSetVariable(list, argc, argv, param)
11556059Samuraistruct cmdtab *list;
11566059Samuraiint argc;
11576059Samuraichar **argv;
11586059Samuraiint param;
11596059Samurai{
11606059Samurai  u_long map;
116126551Sbrian  char *arg;
11626059Samurai
116326551Sbrian  if (argc > 0)
116426551Sbrian    arg = *argv;
116526551Sbrian  else
116626551Sbrian    arg = "";
116726551Sbrian
116826551Sbrian  switch (param) {
11696059Samurai    case VAR_AUTHKEY:
117026551Sbrian      strncpy(VarAuthKey, arg, sizeof(VarAuthKey)-1);
117121488Simp      VarAuthKey[sizeof(VarAuthKey)-1] = '\0';
11726059Samurai      break;
11736059Samurai    case VAR_AUTHNAME:
117426551Sbrian      strncpy(VarAuthName, arg, sizeof(VarAuthName)-1);
117521488Simp      VarAuthName[sizeof(VarAuthName)-1] = '\0';
11766059Samurai      break;
11776059Samurai    case VAR_DIAL:
117826551Sbrian      strncpy(VarDialScript, arg, sizeof(VarDialScript)-1);
117921488Simp      VarDialScript[sizeof(VarDialScript)-1] = '\0';
11806059Samurai      break;
11816059Samurai    case VAR_LOGIN:
118226551Sbrian      strncpy(VarLoginScript, arg, sizeof(VarLoginScript)-1);
118321488Simp      VarLoginScript[sizeof(VarLoginScript)-1] = '\0';
11846059Samurai      break;
11856059Samurai    case VAR_DEVICE:
118626516Sbrian      CloseModem();
118726551Sbrian      strncpy(VarDevice, arg, sizeof(VarDevice)-1);
118821488Simp      VarDevice[sizeof(VarDevice)-1] = '\0';
118925634Sbrian      VarBaseDevice = rindex(VarDevice, '/');
119025634Sbrian      VarBaseDevice = VarBaseDevice ? VarBaseDevice + 1 : "";
11916059Samurai      break;
11926059Samurai    case VAR_ACCMAP:
119326551Sbrian      sscanf(arg, "%lx", &map);
11946059Samurai      VarAccmap = map;
11956059Samurai      break;
11966059Samurai    case VAR_PHONE:
119726551Sbrian      strncpy(VarPhoneList, arg, sizeof(VarPhoneList)-1);
119821488Simp      VarPhoneList[sizeof(VarPhoneList)-1] = '\0';
119914423Sache      strcpy(VarPhoneCopy, VarPhoneList);
120014423Sache      VarNextPhone = VarPhoneCopy;
12016059Samurai      break;
12026059Samurai  }
120326516Sbrian  return 0;
12046059Samurai}
12056059Samurai
120620812Sjkhstatic int SetCtsRts(list, argc, argv)
120720812Sjkhstruct cmdtab *list;
120820812Sjkhint argc;
120920812Sjkhchar **argv;
121020812Sjkh{
121120812Sjkh  if (argc > 0) {
121220812Sjkh    if (strcmp(*argv, "on") == 0)
121320812Sjkh      VarCtsRts = TRUE;
121420812Sjkh    else if (strcmp(*argv, "off") == 0)
121520812Sjkh      VarCtsRts = FALSE;
121620812Sjkh    else
121726516Sbrian      return -1;
121826516Sbrian    return 0;
121920812Sjkh  }
122026516Sbrian  return -1;
122120812Sjkh}
122220812Sjkh
122320812Sjkh
12246059Samuraistatic int SetOpenMode(list, argc, argv)
12256059Samuraistruct cmdtab *list;
12266059Samuraiint argc;
12276059Samuraichar **argv;
12286059Samurai{
12296059Samurai  if (argc > 0) {
12306059Samurai    if (strcmp(*argv, "active") == 0)
12316059Samurai      VarOpenMode = OPEN_ACTIVE;
12326059Samurai    else if (strcmp(*argv, "passive") == 0)
12336059Samurai      VarOpenMode = OPEN_PASSIVE;
12346059Samurai    else
123526516Sbrian      return -1;
123626516Sbrian    return 0;
12376059Samurai  }
123826516Sbrian  return -1;
12396059Samurai}
12406059Samurai
12416735Samuraiextern int SetIfilter(), SetOfilter(), SetDfilter(), SetAfilter();
12426059Samurai
124313760Sphkstruct cmdtab const SetCommands[] = {
12446735Samurai  { "accmap",   NULL,	  SetVariable,		LOCAL_AUTH,
124526516Sbrian	"Set accmap value", "set accmap hex-value", (void *)VAR_ACCMAP},
12466735Samurai  { "afilter",  NULL,     SetAfilter, 		LOCAL_AUTH,
124726516Sbrian	"Set keep Alive filter", "set afilter ..."},
12486735Samurai  { "authkey",  "key",     SetVariable,		LOCAL_AUTH,
124926516Sbrian	"Set authentication key", "set authkey|key key", (void *)VAR_AUTHKEY},
12506735Samurai  { "authname", NULL,     SetVariable,		LOCAL_AUTH,
125126516Sbrian	"Set authentication name", "set authname name", (void *)VAR_AUTHNAME},
125220812Sjkh  { "ctsrts", NULL,	  SetCtsRts,		LOCAL_AUTH,
125326516Sbrian	"Use CTS/RTS modem signalling", "set ctsrts [on|off]"},
12546735Samurai  { "device",     "line", SetVariable, 		LOCAL_AUTH,
125526516Sbrian	"Set modem device name", "set device|line device-name", (void *)VAR_DEVICE},
12566735Samurai  { "dfilter",  NULL,     SetDfilter,		 LOCAL_AUTH,
125726516Sbrian	"Set demand filter", "set dfilter ..."},
12586735Samurai  { "dial",     NULL,     SetVariable, 		LOCAL_AUTH,
125926516Sbrian	"Set dialing script", "set dial chat-script", (void *)VAR_DIAL},
12606735Samurai  { "escape",   NULL,	  SetEscape, 		LOCAL_AUTH,
126126516Sbrian	"Set escape characters", "set escape hex-digit ..."},
12626735Samurai  { "ifaddr",   NULL,   SetInterfaceAddr,	LOCAL_AUTH,
126326516Sbrian	"Set destination address", "set ifaddr [src-addr [dst-addr [netmask [trg-addr]]]]"},
12646735Samurai  { "ifilter",  NULL,     SetIfilter, 		LOCAL_AUTH,
126526516Sbrian	"Set input filter", "set ifilter ..."},
126626516Sbrian  { "log",    NULL,	  SetLogLevel,	LOCAL_AUTH,
126726516Sbrian	"Set log level", "set log [+|-]value..."},
12686735Samurai  { "login",    NULL,     SetVariable,		LOCAL_AUTH,
126926516Sbrian	"Set login script", "set login chat-script",	(void *)VAR_LOGIN },
127026321Sbrian  { "mru",      NULL,     SetInitialMRU,	LOCAL_AUTH,
127126516Sbrian	"Set Initial MRU value", "set mru value" },
127226326Sbrian  { "mtu",      NULL,     SetPreferredMTU,	LOCAL_AUTH,
127326516Sbrian	"Set Preferred MTU value", "set mtu value" },
12746735Samurai  { "ofilter",  NULL,	  SetOfilter,		LOCAL_AUTH,
127526516Sbrian	"Set output filter", "set ofilter ..." },
12766735Samurai  { "openmode", NULL,	  SetOpenMode,		LOCAL_AUTH,
127726516Sbrian	"Set open mode", "set openmode [active|passive]"},
12786735Samurai  { "parity",   NULL,     SetModemParity,	LOCAL_AUTH,
127926516Sbrian	"Set modem parity", "set parity [odd|even|none]"},
12806735Samurai  { "phone",    NULL,     SetVariable,		LOCAL_AUTH,
128126516Sbrian	"Set telephone number(s)", "set phone phone1[:phone2[...]]", (void *)VAR_PHONE },
128225067Sbrian  { "reconnect",NULL,     SetReconnect,		LOCAL_AUTH,
128326516Sbrian	"Set Reconnect timeout", "set reconnect value ntries"},
128425067Sbrian  { "redial",   NULL,     SetRedialTimeout,	LOCAL_AUTH,
128526516Sbrian	"Set Redial timeout", "set redial value|random[.value|random] [dial_attempts]"},
128626940Sbrian  { "server",    "socket",     SetServer,	LOCAL_AUTH,
128727089Sbrian	"Set server port", "set server|socket TcpPort|LocalName|none [mask]"},
12886735Samurai  { "speed",    NULL,     SetModemSpeed,	LOCAL_AUTH,
128926516Sbrian	"Set modem speed", "set speed value"},
12906735Samurai  { "timeout",  NULL,     SetIdleTimeout,	LOCAL_AUTH,
129126516Sbrian	"Set Idle timeout", "set timeout value"},
129226516Sbrian#ifndef NOMSEXT
129318752Sjkh  { "ns",	NULL,	  SetNS,		LOCAL_AUTH,
129426516Sbrian	"Set NameServer", "set ns pri-addr [sec-addr]"},
129518752Sjkh  { "nbns",	NULL,	  SetNBNS,		LOCAL_AUTH,
129626516Sbrian	"Set NetBIOS NameServer", "set nbns pri-addr [sec-addr]"},
129726516Sbrian#endif
12986735Samurai  { "help",     "?",      HelpCommand,		LOCAL_AUTH | LOCAL_NO_AUTH,
129926698Sbrian	"Display this message", "set help|? [command]", (void *)SetCommands},
13006059Samurai  { NULL,       NULL,     NULL },
13016059Samurai};
13026059Samurai
13036059Samuraistatic int
13046059SamuraiSetCommand(list, argc, argv)
13056059Samuraistruct cmdtab *list;
13066059Samuraiint argc;
13076059Samuraichar **argv;
13086059Samurai{
13096059Samurai  if (argc > 0)
131026516Sbrian    FindExec(SetCommands, argc, argv);
131126516Sbrian  else if (VarTerm)
131226516Sbrian    fprintf(VarTerm, "Use `set ?' to get a list or `set ? <var>' for"
131326516Sbrian	    " syntax help.\n");
13146059Samurai  else
131526516Sbrian    LogPrintf(LogWARN, "set command must have arguments\n");
131626516Sbrian
131726516Sbrian  return 0;
13186059Samurai}
13196059Samurai
13206059Samurai
13216059Samuraistatic int
13226059SamuraiAddCommand(list, argc, argv)
13236059Samuraistruct cmdtab *list;
13246059Samuraiint argc;
13256059Samuraichar **argv;
13266059Samurai{
13276059Samurai  struct in_addr dest, gateway, netmask;
13286059Samurai
13296059Samurai  if (argc == 3) {
133027011Sbrian    if (strcasecmp(argv[0], "MYADDR") == 0)
133127011Sbrian      dest = IpcpInfo.want_ipaddr;
133227011Sbrian    else
133327011Sbrian      dest = GetIpAddr(argv[0]);
13346059Samurai    netmask = GetIpAddr(argv[1]);
133525566Sbrian    if (strcasecmp(argv[2], "HISADDR") == 0)
13366059Samurai      gateway = IpcpInfo.his_ipaddr;
13376059Samurai    else
13386059Samurai      gateway = GetIpAddr(argv[2]);
13396059Samurai    OsSetRoute(RTM_ADD, dest, gateway, netmask);
134026516Sbrian    return 0;
13416059Samurai  }
134226516Sbrian
134326516Sbrian  return -1;
13446059Samurai}
13456059Samurai
13466059Samuraistatic int
13476059SamuraiDeleteCommand(list, argc, argv)
13486059Samuraistruct cmdtab *list;
13496059Samuraiint argc;
13506059Samuraichar **argv;
13516059Samurai{
13526059Samurai  struct in_addr dest, gateway, netmask;
13536059Samurai
135426591Sbrian  if (argc == 1 && strcasecmp(argv[0], "all") == 0)
135526591Sbrian    DeleteIfRoutes(0);
135626591Sbrian  else if (argc > 0 && argc < 4) {
135727011Sbrian    if (strcasecmp(argv[0], "MYADDR") == 0)
135827011Sbrian      dest = IpcpInfo.want_ipaddr;
135927011Sbrian    else
136027011Sbrian      dest = GetIpAddr(argv[0]);
136126591Sbrian    netmask.s_addr = INADDR_ANY;
136226591Sbrian    if (argc > 1) {
136326591Sbrian      if (strcasecmp(argv[1], "HISADDR") == 0)
136426591Sbrian        gateway = IpcpInfo.his_ipaddr;
136526591Sbrian      else
136626591Sbrian        gateway = GetIpAddr(argv[1]);
136726591Sbrian      if (argc == 3) {
136826591Sbrian        if (inet_aton(argv[2], &netmask) == 0) {
136926591Sbrian	  LogPrintf(LogWARN, "Bad netmask value.\n");
137026591Sbrian	  return -1;
137126591Sbrian        }
13726059Samurai      }
137326591Sbrian    } else
137426591Sbrian      gateway.s_addr = INADDR_ANY;
13756059Samurai    OsSetRoute(RTM_DELETE, dest, gateway, netmask);
137626516Sbrian  } else
137726516Sbrian    return -1;
137826516Sbrian
137926516Sbrian  return 0;
13806059Samurai}
13816059Samurai
138226031Sbrianstatic int AliasEnable();
138326031Sbrianstatic int AliasOption();
138426031Sbrian
138526031Sbrianstatic struct cmdtab const AliasCommands[] =
138626031Sbrian{
138726031Sbrian  { "enable",   NULL,     AliasEnable,          LOCAL_AUTH,
138826516Sbrian        "enable IP aliasing", "alias enable [yes|no]"},
138926031Sbrian  { "port",   NULL,     AliasRedirectPort,          LOCAL_AUTH,
139026516Sbrian        "port redirection", "alias port [proto addr_local:port_local  port_alias]"},
139126031Sbrian  { "addr",   NULL,     AliasRedirectAddr,          LOCAL_AUTH,
139226516Sbrian        "static address translation", "alias addr [addr_local addr_alias]"},
139326031Sbrian  { "deny_incoming",  NULL,    AliasOption,     LOCAL_AUTH,
139426516Sbrian        "stop incoming connections",   "alias deny_incoming [yes|no]",
139526031Sbrian        (void*)PKT_ALIAS_DENY_INCOMING},
139626031Sbrian  { "log",  NULL,     AliasOption,              LOCAL_AUTH,
139726516Sbrian        "log aliasing link creation",           "alias log [yes|no]",
139826031Sbrian        (void*)PKT_ALIAS_LOG},
139926031Sbrian  { "same_ports", NULL,     AliasOption,        LOCAL_AUTH,
140026516Sbrian        "try to leave port numbers unchanged", "alias same_ports [yes|no]",
140126031Sbrian        (void*)PKT_ALIAS_SAME_PORTS},
140226031Sbrian  { "use_sockets", NULL,     AliasOption,       LOCAL_AUTH,
140326516Sbrian        "allocate host sockets", "alias use_sockets [yes|no]",
140426031Sbrian        (void*)PKT_ALIAS_USE_SOCKETS },
140526031Sbrian  { "unregistered_only", NULL,     AliasOption, LOCAL_AUTH,
140626516Sbrian        "alias unregistered (private) IP address space only",
140726516Sbrian        "alias unregistered_only [yes|no]",
140826031Sbrian        (void*)PKT_ALIAS_UNREGISTERED_ONLY},
140926031Sbrian  { "help",     "?",      HelpCommand,          LOCAL_AUTH | LOCAL_NO_AUTH,
141026698Sbrian        "Display this message", "alias help|? [command]",
141126031Sbrian        (void *)AliasCommands},
141226031Sbrian  { NULL,       NULL,     NULL },
141326031Sbrian};
141426031Sbrian
141526031Sbrian
141626031Sbrianstatic int
141726031SbrianAliasCommand(list, argc, argv)
141826031Sbrianstruct cmdtab *list;
141926031Sbrianint argc;
142026031Sbrianchar **argv;
142126031Sbrian{
142226031Sbrian  if (argc > 0)
142326516Sbrian    FindExec(AliasCommands, argc, argv);
142426516Sbrian  else if (VarTerm)
142526516Sbrian    fprintf(VarTerm, "Use `alias help' to get a list or `alias help <option>'"
142626516Sbrian	    " for syntax help.\n");
142726031Sbrian  else
142826516Sbrian    LogPrintf(LogWARN, "alias command must have arguments\n");
142926516Sbrian
143026516Sbrian  return 0;
143126031Sbrian}
143226031Sbrian
143326031Sbrianstatic int
143426031SbrianAliasEnable(list, argc, argv)
143526031Sbrianstruct cmdtab *list;
143626031Sbrianint argc;
143726031Sbrianchar **argv;
143826031Sbrian{
143926516Sbrian  if (argc == 1)
144026516Sbrian    if (strcasecmp(argv[0], "yes") == 0) {
144126516Sbrian      if (!(mode & MODE_ALIAS)) {
144226516Sbrian        if (loadAliasHandlers(&VarAliasHandlers) == 0) {
144326516Sbrian          mode |= MODE_ALIAS;
144426516Sbrian          return 0;
144526142Sbrian        }
144626516Sbrian        LogPrintf(LogWARN, "Cannot load alias library\n");
144726516Sbrian        return 1;
144826516Sbrian      }
144926516Sbrian      return 0;
145026516Sbrian    } else if (strcasecmp(argv[0], "no") == 0) {
145126516Sbrian      if (mode & MODE_ALIAS) {
145226516Sbrian        unloadAliasHandlers();
145326516Sbrian        mode &= ~MODE_ALIAS;
145426516Sbrian      }
145526516Sbrian      return 0;
145626142Sbrian    }
145726516Sbrian
145826516Sbrian  return -1;
145926031Sbrian}
146026031Sbrian
146126031Sbrian
146226031Sbrianstatic int
146326031SbrianAliasOption(list, argc, argv, param)
146426031Sbrianstruct cmdtab *list;
146526031Sbrianint argc;
146626031Sbrianchar **argv;
146726031Sbrianvoid* param;
146826031Sbrian{
146926516Sbrian   if (argc == 1)
147026516Sbrian     if (strcasecmp(argv[0], "yes") == 0) {
147126516Sbrian       if (mode & MODE_ALIAS) {
147226142Sbrian         VarSetPacketAliasMode((unsigned)param, (unsigned)param);
147326516Sbrian         return 0;
147426516Sbrian       }
147526516Sbrian       LogPrintf(LogWARN, "alias not enabled\n");
147626516Sbrian     } else if (strcmp(argv[0], "no") == 0) {
147726516Sbrian       if (mode & MODE_ALIAS) {
147826142Sbrian         VarSetPacketAliasMode(0, (unsigned)param);
147926516Sbrian         return 0;
148026516Sbrian       }
148126516Sbrian       LogPrintf(LogWARN, "alias not enabled\n");
148226516Sbrian     }
148326516Sbrian
148426516Sbrian   return -1;
148526031Sbrian}
1486