command.c revision 31081
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 *
2031081Sbrian * $Id: command.c,v 1.94 1997/11/09 18:51:22 brian Exp $
218857Srgrimes *
226059Samurai */
2330715Sbrian#include <sys/param.h>
2430715Sbrian#include <netinet/in_systm.h>
2526031Sbrian#include <netinet/in.h>
2630715Sbrian#include <netinet/ip.h>
2726031Sbrian#include <arpa/inet.h>
2830715Sbrian#include <sys/socket.h>
2926031Sbrian#include <net/route.h>
3030715Sbrian#include <netdb.h>
3130715Sbrian
3226031Sbrian#include <alias.h>
3330715Sbrian#include <ctype.h>
3430715Sbrian#include <errno.h>
3526516Sbrian#include <fcntl.h>
3630715Sbrian#include <paths.h>
3730715Sbrian#include <stdio.h>
3830715Sbrian#include <stdlib.h>
3930715Sbrian#include <string.h>
4030715Sbrian#include <sys/stat.h>
4130715Sbrian#include <sys/wait.h>
4230715Sbrian#include <termios.h>
4330715Sbrian#include <time.h>
4430715Sbrian#include <unistd.h>
4530715Sbrian
4630715Sbrian#include "mbuf.h"
4730715Sbrian#include "log.h"
4830715Sbrian#include "defs.h"
4930715Sbrian#include "timer.h"
506059Samurai#include "fsm.h"
516059Samurai#include "phase.h"
526059Samurai#include "lcp.h"
536059Samurai#include "ipcp.h"
546059Samurai#include "modem.h"
5530715Sbrian#include "command.h"
5613389Sphk#include "filter.h"
5726031Sbrian#include "alias_cmd.h"
586059Samurai#include "hdlc.h"
5926142Sbrian#include "loadalias.h"
606059Samurai#include "vars.h"
6125630Sbrian#include "systems.h"
6225630Sbrian#include "chat.h"
636059Samurai#include "os.h"
6426940Sbrian#include "server.h"
6530715Sbrian#include "main.h"
6630715Sbrian#include "route.h"
6730715Sbrian#include "ccp.h"
6830733Sbrian#include "ip.h"
6930715Sbrian#include "slcompress.h"
7031080Sbrian#include "auth.h"
716059Samurai
726059Samuraistruct in_addr ifnetmask;
736059Samurai
7428679Sbrianstatic int ShowCommand(struct cmdtab const *, int, char **);
7528679Sbrianstatic int TerminalCommand(struct cmdtab const *, int, char **);
7628679Sbrianstatic int QuitCommand(struct cmdtab const *, int, char **);
7728679Sbrianstatic int CloseCommand(struct cmdtab const *, int, char **);
7828679Sbrianstatic int DialCommand(struct cmdtab const *, int, char **);
7928679Sbrianstatic int DownCommand(struct cmdtab const *, int, char **);
8028679Sbrianstatic int SetCommand(struct cmdtab const *, int, char **);
8128679Sbrianstatic int AddCommand(struct cmdtab const *, int, char **);
8228679Sbrianstatic int DeleteCommand(struct cmdtab const *, int, char **);
8328679Sbrianstatic int BgShellCommand(struct cmdtab const *, int, char **);
8428679Sbrianstatic int FgShellCommand(struct cmdtab const *, int, char **);
8528679Sbrianstatic int ShellCommand(struct cmdtab const *, int, char **, int);
8630715Sbrianstatic int AliasCommand(struct cmdtab const *, int, char **);
8730715Sbrianstatic int AliasEnable(struct cmdtab const *, int, char **);
8830715Sbrianstatic int AliasOption(struct cmdtab const *, int, char **, void *);
896059Samurai
906059Samuraistatic int
9128679SbrianHelpCommand(struct cmdtab const * list,
9228679Sbrian	    int argc,
9328679Sbrian	    char **argv,
9428679Sbrian	    struct cmdtab const * plist)
956059Samurai{
9628679Sbrian  struct cmdtab const *cmd;
976059Samurai  int n;
986059Samurai
9926516Sbrian  if (!VarTerm)
10026516Sbrian    return 0;
10126516Sbrian
1026059Samurai  if (argc > 0) {
10326516Sbrian    for (cmd = plist; cmd->name; cmd++)
10425566Sbrian      if (strcasecmp(cmd->name, *argv) == 0 && (cmd->lauth & VarLocalAuth)) {
10528679Sbrian	fprintf(VarTerm, "%s\n", cmd->syntax);
10628679Sbrian	return 0;
1076059Samurai      }
10826516Sbrian    return -1;
1096059Samurai  }
1106059Samurai  n = 0;
11126516Sbrian  for (cmd = plist; cmd->func; cmd++)
1126764Samurai    if (cmd->name && (cmd->lauth & VarLocalAuth)) {
11326587Sbrian      fprintf(VarTerm, "  %-9s: %-20s\n", cmd->name, cmd->helpmes);
1146059Samurai      n++;
1156059Samurai    }
1166059Samurai  if (n & 1)
11726516Sbrian    fprintf(VarTerm, "\n");
11826516Sbrian
11926516Sbrian  return 0;
1206059Samurai}
1216059Samurai
1226059Samuraiint
12330913SbrianIsInteractive(int Display)
1246059Samurai{
1256059Samurai  char *mes = NULL;
1266059Samurai
12720120Snate  if (mode & MODE_DDIAL)
12820120Snate    mes = "Working in dedicated dial mode.";
12925908Sbrian  else if (mode & MODE_BACKGROUND)
13025908Sbrian    mes = "Working in background mode.";
13120120Snate  else if (mode & MODE_AUTO)
13210528Samurai    mes = "Working in auto mode.";
1336059Samurai  else if (mode & MODE_DIRECT)
13410528Samurai    mes = "Working in direct mode.";
1356059Samurai  else if (mode & MODE_DEDICATED)
13610528Samurai    mes = "Working in dedicated mode.";
1376059Samurai  if (mes) {
13830913Sbrian    if (Display && VarTerm)
13926516Sbrian      fprintf(VarTerm, "%s\n", mes);
14026516Sbrian    return 0;
1416059Samurai  }
14226516Sbrian  return 1;
1436059Samurai}
1446059Samurai
1456059Samuraistatic int
14628679SbrianDialCommand(struct cmdtab const * cmdlist, int argc, char **argv)
1476059Samurai{
14811336Samurai  int tries;
14926858Sbrian  int res;
15011336Samurai
1516059Samurai  if (LcpFsm.state > ST_CLOSED) {
15226516Sbrian    if (VarTerm)
15326516Sbrian      fprintf(VarTerm, "LCP state is [%s]\n", StateNames[LcpFsm.state]);
15426516Sbrian    return 0;
1556059Samurai  }
15626516Sbrian
1576735Samurai  if (argc > 0) {
1586735Samurai    if (SelectSystem(*argv, CONFFILE) < 0) {
15926516Sbrian      if (VarTerm)
16028679Sbrian	fprintf(VarTerm, "%s: not found.\n", *argv);
16126516Sbrian      return -1;
1626735Samurai    }
1636735Samurai  }
16411336Samurai  tries = 0;
16511336Samurai  do {
16626516Sbrian    if (VarTerm)
16726516Sbrian      fprintf(VarTerm, "Dial attempt %u of %d\n", ++tries, VarDialTries);
16831034Sbrian    if (OpenModem() < 0) {
16926516Sbrian      if (VarTerm)
17028679Sbrian	fprintf(VarTerm, "Failed to open modem.\n");
17111336Samurai      break;
17211336Samurai    }
17326858Sbrian    if ((res = DialModem()) == EX_DONE) {
17430697Sbrian      nointr_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
18628679SbrianSetLoopback(struct cmdtab const * cmdlist, int argc, char **argv)
18728536Sbrian{
18828536Sbrian  if (argc == 1)
18928536Sbrian    if (!strcasecmp(*argv, "on"))
19028536Sbrian      VarLoopback = 1;
19128536Sbrian    else if (!strcasecmp(*argv, "off"))
19228536Sbrian      VarLoopback = 0;
19328536Sbrian  return -1;
19428536Sbrian}
19528536Sbrian
19628536Sbrianstatic int
19728679SbrianBgShellCommand(struct cmdtab const * cmdlist, int argc, char **argv)
19810528Samurai{
19928381Sbrian  if (argc == 0)
20028381Sbrian    return -1;
20128381Sbrian  return ShellCommand(cmdlist, argc, argv, 1);
20228381Sbrian}
20328381Sbrian
20428381Sbrianstatic int
20528679SbrianFgShellCommand(struct cmdtab const * cmdlist, int argc, char **argv)
20628381Sbrian{
20728381Sbrian  return ShellCommand(cmdlist, argc, argv, 0);
20828381Sbrian}
20928381Sbrian
21028381Sbrianstatic int
21128679SbrianShellCommand(struct cmdtab const * cmdlist, int argc, char **argv, int bg)
21228381Sbrian{
21310528Samurai  const char *shell;
21410528Samurai  pid_t shpid;
21526516Sbrian  FILE *oVarTerm;
21620813Sjkh
21718856Ssos#ifdef SHELL_ONLY_INTERACTIVELY
21826911Sbrian  /* we're only allowed to shell when we run ppp interactively */
21926516Sbrian  if (mode != MODE_INTER) {
22026516Sbrian    LogPrintf(LogWARN, "Can only start a shell in interactive mode\n");
22126516Sbrian    return 1;
22210528Samurai  }
22326911Sbrian#endif
22426911Sbrian#ifdef NO_SHELL_IN_AUTO_INTERACTIVE
22528679Sbrian
22626911Sbrian  /*
22728679Sbrian   * we want to stop shell commands when we've got a telnet connection to an
22828679Sbrian   * auto mode ppp
22926911Sbrian   */
23028679Sbrian  if ((mode & (MODE_AUTO | MODE_INTER)) == (MODE_AUTO | MODE_INTER)) {
23128679Sbrian    LogPrintf(LogWARN, "Shell is not allowed interactively in auto mode\n");
23226516Sbrian    return 1;
23326516Sbrian  }
23426516Sbrian#endif
23526516Sbrian
23628679Sbrian  if (argc == 0)
23728381Sbrian    if (!(mode & MODE_INTER)) {
23828381Sbrian      LogPrintf(LogWARN, "Can only start an interactive shell in"
23928679Sbrian		" interactive mode\n");
24028381Sbrian      return 1;
24128381Sbrian    } else if (bg) {
24228381Sbrian      LogPrintf(LogWARN, "Can only start an interactive shell in"
24328679Sbrian		" the foreground mode\n");
24428381Sbrian      return 1;
24529255Sbrian    } else if (mode&(MODE_AUTO|MODE_DEDICATED|MODE_DIRECT)) {
24629255Sbrian      LogPrintf(LogWARN, "Can't start an interactive shell from"
24729255Sbrian		" a telnet session\n");
24829255Sbrian      return 1;
24928381Sbrian    }
25028679Sbrian  if ((shell = getenv("SHELL")) == 0)
25126516Sbrian    shell = _PATH_BSHELL;
25226516Sbrian
25328679Sbrian  if ((shpid = fork()) == 0) {
25428679Sbrian    int dtablesize, i, fd;
25518531Sbde
25628679Sbrian    if (VarTerm)
25728679Sbrian      fd = fileno(VarTerm);
25828679Sbrian    else if ((fd = open("/dev/null", O_RDWR)) == -1) {
25928679Sbrian      LogPrintf(LogALERT, "Failed to open /dev/null: %s\n", strerror(errno));
26028679Sbrian      exit(1);
26128679Sbrian    }
26228679Sbrian    for (i = 0; i < 3; i++)
26328679Sbrian      dup2(fd, i);
26426516Sbrian
26528679Sbrian    if (fd > 2)
26628679Sbrian      if (VarTerm) {
26728679Sbrian	oVarTerm = VarTerm;
26828679Sbrian	VarTerm = 0;
26928679Sbrian	if (oVarTerm && oVarTerm != stdout)
27028679Sbrian	  fclose(oVarTerm);
27128679Sbrian      } else
27228679Sbrian	close(fd);
27326516Sbrian
27428679Sbrian    for (dtablesize = getdtablesize(), i = 3; i < dtablesize; i++)
27528679Sbrian      (void) close(i);
27626516Sbrian
27728679Sbrian    TtyOldMode();
27831061Sbrian    setuid(geteuid());
27928679Sbrian    if (argc > 0) {
28028679Sbrian      /* substitute pseudo args */
28128679Sbrian      for (i = 1; i < argc; i++)
28228679Sbrian	if (strcasecmp(argv[i], "HISADDR") == 0)
28328679Sbrian	  argv[i] = strdup(inet_ntoa(IpcpInfo.his_ipaddr));
28428679Sbrian	else if (strcasecmp(argv[i], "INTERFACE") == 0)
28528679Sbrian	  argv[i] = strdup(IfDevName);
28628679Sbrian	else if (strcasecmp(argv[i], "MYADDR") == 0)
28728679Sbrian	  argv[i] = strdup(inet_ntoa(IpcpInfo.want_ipaddr));
28828679Sbrian      if (bg) {
28928679Sbrian	pid_t p;
29010528Samurai
29128679Sbrian	p = getpid();
29228679Sbrian	if (daemon(1, 1) == -1) {
29328974Sbrian	  LogPrintf(LogERROR, "%d: daemon: %s\n", p, strerror(errno));
29428679Sbrian	  exit(1);
29528679Sbrian	}
29628679Sbrian      }
29730316Sbrian      if (VarTerm)
29830316Sbrian        fprintf(VarTerm, "ppp: Pausing until %s finishes\n", argv[0]);
29928679Sbrian      (void) execvp(argv[0], argv);
30030316Sbrian    } else {
30130316Sbrian      if (VarTerm)
30230316Sbrian        fprintf(VarTerm, "ppp: Pausing until %s finishes\n", shell);
30328679Sbrian      (void) execl(shell, shell, NULL);
30430316Sbrian    }
30520813Sjkh
30628679Sbrian    LogPrintf(LogWARN, "exec() of %s failed\n", argc > 0 ? argv[0] : shell);
30728679Sbrian    exit(255);
30810528Samurai  }
30928679Sbrian  if (shpid == (pid_t) - 1) {
31026516Sbrian    LogPrintf(LogERROR, "Fork failed: %s\n", strerror(errno));
31110528Samurai  } else {
31210528Samurai    int status;
31328679Sbrian
31428679Sbrian    (void) waitpid(shpid, &status, 0);
31510528Samurai  }
31620813Sjkh
31710528Samurai  TtyCommandMode(1);
31820813Sjkh
31928679Sbrian  return (0);
32010528Samurai}
32110528Samurai
32230715Sbrianstatic struct cmdtab const Commands[] = {
32328679Sbrian  {"accept", NULL, AcceptCommand, LOCAL_AUTH,
32428679Sbrian  "accept option request", "accept option .."},
32528679Sbrian  {"add", NULL, AddCommand, LOCAL_AUTH,
32628679Sbrian  "add route", "add dest mask gateway"},
32728679Sbrian  {"bg", "!bg", BgShellCommand, LOCAL_AUTH,
32828679Sbrian  "Run a command in the background", "[!]bg command"},
32928679Sbrian  {"close", NULL, CloseCommand, LOCAL_AUTH,
33028679Sbrian  "Close connection", "close"},
33128679Sbrian  {"delete", NULL, DeleteCommand, LOCAL_AUTH,
33228679Sbrian  "delete route", "delete ALL | dest [gateway [mask]]"},
33328679Sbrian  {"deny", NULL, DenyCommand, LOCAL_AUTH,
33428679Sbrian  "Deny option request", "deny option .."},
33528679Sbrian  {"dial", "call", DialCommand, LOCAL_AUTH,
33628679Sbrian  "Dial and login", "dial|call [remote]"},
33728679Sbrian  {"disable", NULL, DisableCommand, LOCAL_AUTH,
33828679Sbrian  "Disable option", "disable option .."},
33928679Sbrian  {"display", NULL, DisplayCommand, LOCAL_AUTH,
34028679Sbrian  "Display option configs", "display"},
34128679Sbrian  {"enable", NULL, EnableCommand, LOCAL_AUTH,
34228679Sbrian  "Enable option", "enable option .."},
34328679Sbrian  {"passwd", NULL, LocalAuthCommand, LOCAL_NO_AUTH,
34429083Sbrian  "Password for manipulation", "passwd LocalPassword"},
34528679Sbrian  {"load", NULL, LoadCommand, LOCAL_AUTH,
34628679Sbrian  "Load settings", "load [remote]"},
34728679Sbrian  {"save", NULL, SaveCommand, LOCAL_AUTH,
34828679Sbrian  "Save settings", "save"},
34928679Sbrian  {"set", "setup", SetCommand, LOCAL_AUTH,
35028679Sbrian  "Set parameters", "set[up] var value"},
35128679Sbrian  {"shell", "!", FgShellCommand, LOCAL_AUTH,
35228679Sbrian  "Run a subshell", "shell|! [sh command]"},
35328679Sbrian  {"show", NULL, ShowCommand, LOCAL_AUTH,
35429660Sbrian  "Show status and statistics", "show var"},
35528679Sbrian  {"term", NULL, TerminalCommand, LOCAL_AUTH,
35628679Sbrian  "Enter to terminal mode", "term"},
35728679Sbrian  {"alias", NULL, AliasCommand, LOCAL_AUTH,
35828679Sbrian  "alias control", "alias option [yes|no]"},
35928679Sbrian  {"quit", "bye", QuitCommand, LOCAL_AUTH | LOCAL_NO_AUTH,
36028679Sbrian  "Quit PPP program", "quit|bye [all]"},
36128679Sbrian  {"help", "?", HelpCommand, LOCAL_AUTH | LOCAL_NO_AUTH,
36228679Sbrian  "Display this message", "help|? [command]", (void *) Commands},
36328679Sbrian  {NULL, "down", DownCommand, LOCAL_AUTH,
36428679Sbrian  "Generate down event", "down"},
36528679Sbrian  {NULL, NULL, NULL},
3666059Samurai};
3676059Samurai
36828536Sbrianstatic int
36928536SbrianShowLoopback()
37028536Sbrian{
37128536Sbrian  if (VarTerm)
37228536Sbrian    fprintf(VarTerm, "Local loopback is %s\n", VarLoopback ? "on" : "off");
37328536Sbrian
37428536Sbrian  return 0;
37528536Sbrian}
37628536Sbrian
37728679Sbrianstatic int
37828679SbrianShowLogLevel()
3796059Samurai{
3806059Samurai  int i;
3816059Samurai
38226516Sbrian  if (!VarTerm)
38326516Sbrian    return 0;
38430913Sbrian
38530913Sbrian  fprintf(VarTerm, "Log:  ");
38630913Sbrian  for (i = LogMIN; i <= LogMAX; i++)
38730913Sbrian    if (LogIsKept(i) & LOG_KEPT_SYSLOG)
38826516Sbrian      fprintf(VarTerm, " %s", LogName(i));
38930913Sbrian
39030913Sbrian  fprintf(VarTerm, "\nLocal:");
39130913Sbrian  for (i = LogMIN; i <= LogMAX; i++)
39230913Sbrian    if (LogIsKept(i) & LOG_KEPT_LOCAL)
39330913Sbrian      fprintf(VarTerm, " %s", LogName(i));
39430913Sbrian
39526516Sbrian  fprintf(VarTerm, "\n");
39626516Sbrian
39726516Sbrian  return 0;
3986059Samurai}
3996059Samurai
40028679Sbrianstatic int
40128679SbrianShowEscape()
4026059Samurai{
4036059Samurai  int code, bit;
4046059Samurai
40526516Sbrian  if (!VarTerm)
40626516Sbrian    return 0;
4076059Samurai  if (EscMap[32]) {
40826516Sbrian    for (code = 0; code < 32; code++)
40926516Sbrian      if (EscMap[code])
41028679Sbrian	for (bit = 0; bit < 8; bit++)
41128679Sbrian	  if (EscMap[code] & (1 << bit))
41228679Sbrian	    fprintf(VarTerm, " 0x%02x", (code << 3) + bit);
41326516Sbrian    fprintf(VarTerm, "\n");
4146059Samurai  }
41531077Sbrian  return 0;
4166059Samurai}
4176059Samurai
41828679Sbrianstatic int
41928679SbrianShowTimeout()
4206059Samurai{
42131077Sbrian  if (VarTerm)
42231077Sbrian    fprintf(VarTerm, " Idle Timer: %d secs   LQR Timer: %d secs"
42331077Sbrian	    "   Retry Timer: %d secs\n", VarIdleTimeout, VarLqrTimeout,
42431077Sbrian	    VarRetryTimeout);
42531077Sbrian  return 0;
4266059Samurai}
4276059Samurai
42828679Sbrianstatic int
42928679SbrianShowStopped()
43028327Sbrian{
43128327Sbrian  if (!VarTerm)
43228327Sbrian    return 0;
43328461Sbrian
43428461Sbrian  fprintf(VarTerm, " Stopped Timer:  LCP: ");
43528461Sbrian  if (!LcpFsm.StoppedTimer.load)
43628461Sbrian    fprintf(VarTerm, "Disabled");
43728327Sbrian  else
43828461Sbrian    fprintf(VarTerm, "%ld secs", LcpFsm.StoppedTimer.load / SECTICKS);
43928461Sbrian
44028461Sbrian  fprintf(VarTerm, ", IPCP: ");
44128461Sbrian  if (!IpcpFsm.StoppedTimer.load)
44228461Sbrian    fprintf(VarTerm, "Disabled");
44328461Sbrian  else
44428461Sbrian    fprintf(VarTerm, "%ld secs", IpcpFsm.StoppedTimer.load / SECTICKS);
44528461Sbrian
44628461Sbrian  fprintf(VarTerm, ", CCP: ");
44728461Sbrian  if (!CcpFsm.StoppedTimer.load)
44828461Sbrian    fprintf(VarTerm, "Disabled");
44928461Sbrian  else
45028461Sbrian    fprintf(VarTerm, "%ld secs", CcpFsm.StoppedTimer.load / SECTICKS);
45128461Sbrian
45228461Sbrian  fprintf(VarTerm, "\n");
45328461Sbrian
45431077Sbrian  return 0;
45528327Sbrian}
45628327Sbrian
45728679Sbrianstatic int
45828679SbrianShowAuthKey()
4596059Samurai{
46026516Sbrian  if (!VarTerm)
46126516Sbrian    return 0;
46226516Sbrian  fprintf(VarTerm, "AuthName = %s\n", VarAuthName);
46326516Sbrian  fprintf(VarTerm, "AuthKey  = %s\n", VarAuthKey);
46429840Sbrian#ifdef HAVE_DES
46529840Sbrian  fprintf(VarTerm, "Encrypt  = %s\n", VarMSChap ? "MSChap" : "MD5" );
46629840Sbrian#endif
46731077Sbrian  return 0;
4686059Samurai}
4696059Samurai
47028679Sbrianstatic int
47128679SbrianShowVersion()
4726059Samurai{
47331077Sbrian  if (VarTerm)
47431077Sbrian    fprintf(VarTerm, "%s - %s \n", VarVersion, VarLocalVersion);
47531077Sbrian  return 0;
4766059Samurai}
4776059Samurai
47828679Sbrianstatic int
47928679SbrianShowInitialMRU()
48026326Sbrian{
48131077Sbrian  if (VarTerm)
48231077Sbrian    fprintf(VarTerm, " Initial MRU: %ld\n", VarMRU);
48331077Sbrian  return 0;
48426326Sbrian}
48526326Sbrian
48628679Sbrianstatic int
48728679SbrianShowPreferredMTU()
48826326Sbrian{
48931077Sbrian  if (VarTerm)
49031077Sbrian    if (VarPrefMTU)
49131077Sbrian      fprintf(VarTerm, " Preferred MTU: %ld\n", VarPrefMTU);
49231077Sbrian    else
49331077Sbrian      fprintf(VarTerm, " Preferred MTU: unspecified\n");
49431077Sbrian  return 0;
49526326Sbrian}
49626326Sbrian
49728679Sbrianstatic int
49828679SbrianShowReconnect()
49925067Sbrian{
50031077Sbrian  if (VarTerm)
50131077Sbrian    fprintf(VarTerm, " Reconnect Timer:  %d,  %d tries\n",
50231077Sbrian	    VarReconnectTimer, VarReconnectTries);
50331077Sbrian  return 0;
50425067Sbrian}
50525067Sbrian
50628679Sbrianstatic int
50728679SbrianShowRedial()
50811336Samurai{
50926516Sbrian  if (!VarTerm)
51026516Sbrian    return 0;
51126516Sbrian  fprintf(VarTerm, " Redial Timer: ");
51211336Samurai
51311336Samurai  if (VarRedialTimeout >= 0) {
51426516Sbrian    fprintf(VarTerm, " %d seconds, ", VarRedialTimeout);
51528679Sbrian  } else {
51626516Sbrian    fprintf(VarTerm, " Random 0 - %d seconds, ", REDIAL_PERIOD);
51711336Samurai  }
51811336Samurai
51926516Sbrian  fprintf(VarTerm, " Redial Next Timer: ");
52024939Sbrian
52124939Sbrian  if (VarRedialNextTimeout >= 0) {
52226516Sbrian    fprintf(VarTerm, " %d seconds, ", VarRedialNextTimeout);
52328679Sbrian  } else {
52426516Sbrian    fprintf(VarTerm, " Random 0 - %d seconds, ", REDIAL_PERIOD);
52524939Sbrian  }
52624939Sbrian
52711336Samurai  if (VarDialTries)
52828679Sbrian    fprintf(VarTerm, "%d dial tries", VarDialTries);
52911336Samurai
53026516Sbrian  fprintf(VarTerm, "\n");
53111336Samurai
53231077Sbrian  return 0;
53311336Samurai}
53411336Samurai
53526516Sbrian#ifndef NOMSEXT
53628679Sbrianstatic int
53728679SbrianShowMSExt()
53818752Sjkh{
53931077Sbrian  if (VarTerm) {
54031077Sbrian    fprintf(VarTerm, " MS PPP extention values \n");
54131077Sbrian    fprintf(VarTerm, "   Primary NS     : %s\n", inet_ntoa(ns_entries[0]));
54231077Sbrian    fprintf(VarTerm, "   Secondary NS   : %s\n", inet_ntoa(ns_entries[1]));
54331077Sbrian    fprintf(VarTerm, "   Primary NBNS   : %s\n", inet_ntoa(nbns_entries[0]));
54431077Sbrian    fprintf(VarTerm, "   Secondary NBNS : %s\n", inet_ntoa(nbns_entries[1]));
54531077Sbrian  }
54631077Sbrian  return 0;
54718752Sjkh}
54828679Sbrian
54926516Sbrian#endif
55018752Sjkh
55130715Sbrianstatic struct cmdtab const ShowCommands[] = {
55228679Sbrian  {"afilter", NULL, ShowAfilter, LOCAL_AUTH,
55328679Sbrian  "Show keep Alive filters", "show afilter option .."},
55428679Sbrian  {"auth", NULL, ShowAuthKey, LOCAL_AUTH,
55529549Sbrian  "Show auth name, key and algorithm", "show auth"},
55628679Sbrian  {"ccp", NULL, ReportCcpStatus, LOCAL_AUTH,
55728679Sbrian  "Show CCP status", "show cpp"},
55828679Sbrian  {"compress", NULL, ReportCompress, LOCAL_AUTH,
55929660Sbrian  "Show compression statistics", "show compress"},
56028679Sbrian  {"dfilter", NULL, ShowDfilter, LOCAL_AUTH,
56128679Sbrian  "Show Demand filters", "show dfilteroption .."},
56228679Sbrian  {"escape", NULL, ShowEscape, LOCAL_AUTH,
56328679Sbrian  "Show escape characters", "show escape"},
56428679Sbrian  {"hdlc", NULL, ReportHdlcStatus, LOCAL_AUTH,
56528679Sbrian  "Show HDLC error summary", "show hdlc"},
56628679Sbrian  {"ifilter", NULL, ShowIfilter, LOCAL_AUTH,
56728679Sbrian  "Show Input filters", "show ifilter option .."},
56828679Sbrian  {"ipcp", NULL, ReportIpcpStatus, LOCAL_AUTH,
56928679Sbrian  "Show IPCP status", "show ipcp"},
57028679Sbrian  {"lcp", NULL, ReportLcpStatus, LOCAL_AUTH,
57128679Sbrian  "Show LCP status", "show lcp"},
57228679Sbrian  {"loopback", NULL, ShowLoopback, LOCAL_AUTH,
57328679Sbrian  "Show current loopback setting", "show loopback"},
57428679Sbrian  {"log", NULL, ShowLogLevel, LOCAL_AUTH,
57528679Sbrian  "Show current log level", "show log"},
57628679Sbrian  {"mem", NULL, ShowMemMap, LOCAL_AUTH,
57728679Sbrian  "Show memory map", "show mem"},
57828679Sbrian  {"modem", NULL, ShowModemStatus, LOCAL_AUTH,
57928679Sbrian  "Show modem setups", "show modem"},
58028679Sbrian  {"mru", NULL, ShowInitialMRU, LOCAL_AUTH,
58128679Sbrian  "Show Initial MRU", "show mru"},
58228679Sbrian  {"mtu", NULL, ShowPreferredMTU, LOCAL_AUTH,
58328679Sbrian  "Show Preferred MTU", "show mtu"},
58428679Sbrian  {"ofilter", NULL, ShowOfilter, LOCAL_AUTH,
58528679Sbrian  "Show Output filters", "show ofilter option .."},
58628679Sbrian  {"proto", NULL, ReportProtStatus, LOCAL_AUTH,
58728679Sbrian  "Show protocol summary", "show proto"},
58828679Sbrian  {"reconnect", NULL, ShowReconnect, LOCAL_AUTH,
58928679Sbrian  "Show Reconnect timer,tries", "show reconnect"},
59028679Sbrian  {"redial", NULL, ShowRedial, LOCAL_AUTH,
59128679Sbrian  "Show Redial timeout value", "show redial"},
59228679Sbrian  {"route", NULL, ShowRoute, LOCAL_AUTH,
59328679Sbrian  "Show routing table", "show route"},
59428679Sbrian  {"timeout", NULL, ShowTimeout, LOCAL_AUTH,
59528679Sbrian  "Show Idle timeout value", "show timeout"},
59628679Sbrian  {"stopped", NULL, ShowStopped, LOCAL_AUTH,
59728679Sbrian  "Show STOPPED timeout value", "show stopped"},
59826516Sbrian#ifndef NOMSEXT
59928679Sbrian  {"msext", NULL, ShowMSExt, LOCAL_AUTH,
60028679Sbrian  "Show MS PPP extentions", "show msext"},
60126516Sbrian#endif
60228679Sbrian  {"version", NULL, ShowVersion, LOCAL_NO_AUTH | LOCAL_AUTH,
60328679Sbrian  "Show version string", "show version"},
60428679Sbrian  {"help", "?", HelpCommand, LOCAL_NO_AUTH | LOCAL_AUTH,
60528679Sbrian  "Display this message", "show help|? [command]", (void *) ShowCommands},
60628679Sbrian  {NULL, NULL, NULL},
6076059Samurai};
6086059Samurai
60930715Sbrianstatic struct cmdtab const *
61028679SbrianFindCommand(struct cmdtab const * cmds, char *str, int *pmatch)
6116059Samurai{
61226516Sbrian  int nmatch;
61326516Sbrian  int len;
61428679Sbrian  struct cmdtab const *found;
6156059Samurai
61626516Sbrian  found = NULL;
61726516Sbrian  len = strlen(str);
61826516Sbrian  nmatch = 0;
6196059Samurai  while (cmds->func) {
62025566Sbrian    if (cmds->name && strncasecmp(str, cmds->name, len) == 0) {
62126516Sbrian      if (cmds->name[len] == '\0') {
62228679Sbrian	*pmatch = 1;
62328679Sbrian	return cmds;
62426516Sbrian      }
6256059Samurai      nmatch++;
6266059Samurai      found = cmds;
62728679Sbrian    } else if (cmds->alias && strncasecmp(str, cmds->alias, len) == 0) {
62826516Sbrian      if (cmds->alias[len] == '\0') {
62928679Sbrian	*pmatch = 1;
63028679Sbrian	return cmds;
63126516Sbrian      }
6326059Samurai      nmatch++;
6336059Samurai      found = cmds;
6346059Samurai    }
6356059Samurai    cmds++;
6366059Samurai  }
6376059Samurai  *pmatch = nmatch;
63826516Sbrian  return found;
6396059Samurai}
6406059Samurai
64130715Sbrianstatic int
64228679SbrianFindExec(struct cmdtab const * cmdlist, int argc, char **argv)
6436059Samurai{
64428679Sbrian  struct cmdtab const *cmd;
6456059Samurai  int val = 1;
6466059Samurai  int nmatch;
6476059Samurai
6486059Samurai  cmd = FindCommand(cmdlist, *argv, &nmatch);
6496059Samurai  if (nmatch > 1)
65026516Sbrian    LogPrintf(LogWARN, "%s: Ambiguous command\n", *argv);
65128679Sbrian  else if (cmd && (cmd->lauth & VarLocalAuth))
65229257Sbrian    val = (cmd->func) (cmd, argc-1, argv+1, cmd->args);
6536059Samurai  else
65426516Sbrian    LogPrintf(LogWARN, "%s: Invalid command\n", *argv);
65526516Sbrian
65626516Sbrian  if (val == -1)
65726516Sbrian    LogPrintf(LogWARN, "Usage: %s\n", cmd->syntax);
65828679Sbrian  else if (val)
65926516Sbrian    LogPrintf(LogCOMMAND, "%s: Failed %d\n", *argv, val);
66026516Sbrian
66126516Sbrian  return val;
6626059Samurai}
6636059Samurai
66418885Sjkhint aft_cmd = 1;
66518885Sjkh
6666059Samuraivoid
66718885SjkhPrompt()
6686059Samurai{
6696735Samurai  char *pconnect, *pauth;
6706735Samurai
67126516Sbrian  if (!(mode & MODE_INTER) || !VarTerm || TermMode)
6726059Samurai    return;
6736735Samurai
67418885Sjkh  if (!aft_cmd)
67526516Sbrian    fprintf(VarTerm, "\n");
67618885Sjkh  else
67718885Sjkh    aft_cmd = 0;
6786735Samurai
67928679Sbrian  if (VarLocalAuth == LOCAL_AUTH)
6806735Samurai    pauth = " ON ";
6816735Samurai  else
6826735Samurai    pauth = " on ";
6836059Samurai  if (IpcpFsm.state == ST_OPENED && phase == PHASE_NETWORK)
6846735Samurai    pconnect = "PPP";
6856059Samurai  else
6866735Samurai    pconnect = "ppp";
68726516Sbrian  fprintf(VarTerm, "%s%s%s> ", pconnect, pauth, VarShortHost);
68826516Sbrian  fflush(VarTerm);
6896059Samurai}
6906059Samurai
6916059Samuraivoid
69228679SbrianDecodeCommand(char *buff, int nb, int prompt)
6936059Samurai{
6946059Samurai  char *vector[20];
6956059Samurai  char **argv;
69626516Sbrian  int argc;
6976059Samurai  char *cp;
6986059Samurai
6996059Samurai  if (nb > 0) {
7006059Samurai    cp = buff + strcspn(buff, "\r\n");
7016059Samurai    if (cp)
7026059Samurai      *cp = '\0';
70326516Sbrian    argc = MakeArgs(buff, vector, VECSIZE(vector));
70426516Sbrian    argv = vector;
7056059Samurai
70626516Sbrian    if (argc > 0)
70726516Sbrian      FindExec(Commands, argc, argv);
7086059Samurai  }
70926516Sbrian  if (prompt)
71025630Sbrian    Prompt();
7116059Samurai}
7126059Samurai
7136059Samuraistatic int
71428679SbrianShowCommand(struct cmdtab const * list, int argc, char **argv)
7156059Samurai{
7166059Samurai  if (argc > 0)
71726516Sbrian    FindExec(ShowCommands, argc, argv);
71826516Sbrian  else if (VarTerm)
71926516Sbrian    fprintf(VarTerm, "Use ``show ?'' to get a list.\n");
7206059Samurai  else
72126516Sbrian    LogPrintf(LogWARN, "show command must have arguments\n");
72226516Sbrian
72326516Sbrian  return 0;
7246059Samurai}
7256059Samurai
7266059Samuraistatic int
72728679SbrianTerminalCommand(struct cmdtab const * list, int argc, char **argv)
7286059Samurai{
7296059Samurai  if (LcpFsm.state > ST_CLOSED) {
73026516Sbrian    if (VarTerm)
73126516Sbrian      fprintf(VarTerm, "LCP state is [%s]\n", StateNames[LcpFsm.state]);
73226516Sbrian    return 1;
7336059Samurai  }
73430913Sbrian  if (!IsInteractive(1))
73528679Sbrian    return (1);
73631034Sbrian  if (OpenModem() < 0) {
73726516Sbrian    if (VarTerm)
73826516Sbrian      fprintf(VarTerm, "Failed to open modem.\n");
73928679Sbrian    return (1);
7406059Samurai  }
74126516Sbrian  if (VarTerm) {
74226516Sbrian    fprintf(VarTerm, "Enter to terminal mode.\n");
74326516Sbrian    fprintf(VarTerm, "Type `~?' for help.\n");
74426516Sbrian  }
7456059Samurai  TtyTermMode();
74628679Sbrian  return (0);
7476059Samurai}
7486059Samurai
7496059Samuraistatic int
75028679SbrianQuitCommand(struct cmdtab const * list, int argc, char **argv)
7516059Samurai{
75226516Sbrian  FILE *oVarTerm;
75326516Sbrian
75428679Sbrian  if (mode & (MODE_DIRECT | MODE_DEDICATED | MODE_AUTO)) {
75529083Sbrian    if (argc > 0 && !strcasecmp(*argv, "all") && (VarLocalAuth & LOCAL_AUTH)) {
75618911Ssos      mode &= ~MODE_INTER;
75726516Sbrian      oVarTerm = VarTerm;
75826516Sbrian      VarTerm = 0;
75926516Sbrian      if (oVarTerm && oVarTerm != stdout)
76028679Sbrian	fclose(oVarTerm);
76129083Sbrian      Cleanup(EX_NORMAL);
76229083Sbrian    } else if (VarTerm) {
76326516Sbrian      LogPrintf(LogPHASE, "Client connection closed.\n");
76426516Sbrian      mode &= ~MODE_INTER;
76526516Sbrian      oVarTerm = VarTerm;
76626516Sbrian      VarTerm = 0;
76726516Sbrian      if (oVarTerm && oVarTerm != stdout)
76828679Sbrian	fclose(oVarTerm);
7696059Samurai      close(netfd);
7706059Samurai      netfd = -1;
7716059Samurai    }
7726059Samurai  } else
7736059Samurai    Cleanup(EX_NORMAL);
77426516Sbrian
77526516Sbrian  return 0;
7766059Samurai}
7776059Samurai
7786059Samuraistatic int
77928679SbrianCloseCommand(struct cmdtab const * list, int argc, char **argv)
7806059Samurai{
78126098Sbrian  reconnect(RECON_FALSE);
7826059Samurai  LcpClose();
78325908Sbrian  if (mode & MODE_BACKGROUND)
78428679Sbrian    Cleanup(EX_NORMAL);
78526516Sbrian  return 0;
7866059Samurai}
7876059Samurai
7886059Samuraistatic int
78928679SbrianDownCommand(struct cmdtab const * list, int argc, char **argv)
7906059Samurai{
7916059Samurai  LcpDown();
79226516Sbrian  return 0;
7936059Samurai}
7946059Samurai
79525067Sbrianstatic int
79628679SbrianSetModemSpeed(struct cmdtab const * list, int argc, char **argv)
7976059Samurai{
7986059Samurai  int speed;
7996059Samurai
8006059Samurai  if (argc > 0) {
80129521Sbrian    if (strcasecmp(*argv, "sync") == 0) {
8026735Samurai      VarSpeed = 0;
80326516Sbrian      return 0;
8046735Samurai    }
8056059Samurai    speed = atoi(*argv);
8066735Samurai    if (IntToSpeed(speed) != B0) {
8076735Samurai      VarSpeed = speed;
80826516Sbrian      return 0;
8096059Samurai    }
81026516Sbrian    LogPrintf(LogWARN, "%s: Invalid speed\n", *argv);
8116059Samurai  }
81226516Sbrian  return -1;
8136059Samurai}
8146059Samurai
81525067Sbrianstatic int
81628679SbrianSetReconnect(struct cmdtab const * list, int argc, char **argv)
81711336Samurai{
81825067Sbrian  if (argc == 2) {
81925067Sbrian    VarReconnectTimer = atoi(argv[0]);
82025067Sbrian    VarReconnectTries = atoi(argv[1]);
82126516Sbrian    return 0;
82226516Sbrian  }
82326516Sbrian  return -1;
82425067Sbrian}
82525067Sbrian
82625067Sbrianstatic int
82728679SbrianSetRedialTimeout(struct cmdtab const * list, int argc, char **argv)
82825067Sbrian{
82911336Samurai  int timeout;
83011336Samurai  int tries;
83124939Sbrian  char *dot;
83211336Samurai
83328679Sbrian  if (argc == 1 || argc == 2) {
83424939Sbrian    if (strncasecmp(argv[0], "random", 6) == 0 &&
83524939Sbrian	(argv[0][6] == '\0' || argv[0][6] == '.')) {
83611336Samurai      VarRedialTimeout = -1;
83730715Sbrian      randinit();
83826516Sbrian    } else {
83911336Samurai      timeout = atoi(argv[0]);
84011336Samurai
84126516Sbrian      if (timeout >= 0)
84211336Samurai	VarRedialTimeout = timeout;
84311336Samurai      else {
84426516Sbrian	LogPrintf(LogWARN, "Invalid redial timeout\n");
84528679Sbrian	return -1;
84611336Samurai      }
84711336Samurai    }
84824939Sbrian
84930715Sbrian    dot = strchr(argv[0], '.');
85024939Sbrian    if (dot) {
85124939Sbrian      if (strcasecmp(++dot, "random") == 0) {
85228679Sbrian	VarRedialNextTimeout = -1;
85330715Sbrian	randinit();
85428679Sbrian      } else {
85528679Sbrian	timeout = atoi(dot);
85628679Sbrian	if (timeout >= 0)
85728679Sbrian	  VarRedialNextTimeout = timeout;
85828679Sbrian	else {
85928679Sbrian	  LogPrintf(LogWARN, "Invalid next redial timeout\n");
86026516Sbrian	  return -1;
86128679Sbrian	}
86224939Sbrian      }
86328679Sbrian    } else
86428679Sbrian      VarRedialNextTimeout = NEXT_REDIAL_PERIOD;	/* Default next timeout */
86524939Sbrian
86611336Samurai    if (argc == 2) {
86711336Samurai      tries = atoi(argv[1]);
86811336Samurai
86911336Samurai      if (tries >= 0) {
87026516Sbrian	VarDialTries = tries;
87126516Sbrian      } else {
87226516Sbrian	LogPrintf(LogWARN, "Invalid retry value\n");
87326516Sbrian	return 1;
87411336Samurai      }
87511336Samurai    }
87626516Sbrian    return 0;
87711336Samurai  }
87826516Sbrian  return -1;
87911336Samurai}
88011336Samurai
88125067Sbrianstatic int
88228679SbrianSetStoppedTimeout(struct cmdtab const * list, int argc, char **argv)
88328327Sbrian{
88428461Sbrian  LcpFsm.StoppedTimer.load = 0;
88528461Sbrian  IpcpFsm.StoppedTimer.load = 0;
88628461Sbrian  CcpFsm.StoppedTimer.load = 0;
88728461Sbrian  if (argc <= 3) {
88828461Sbrian    if (argc > 0) {
88928461Sbrian      LcpFsm.StoppedTimer.load = atoi(argv[0]) * SECTICKS;
89028461Sbrian      if (argc > 1) {
89128679Sbrian	IpcpFsm.StoppedTimer.load = atoi(argv[1]) * SECTICKS;
89228679Sbrian	if (argc > 2)
89328679Sbrian	  CcpFsm.StoppedTimer.load = atoi(argv[2]) * SECTICKS;
89428461Sbrian      }
89528461Sbrian    }
89628327Sbrian    return 0;
89728327Sbrian  }
89828327Sbrian  return -1;
89928327Sbrian}
90028327Sbrian
90131081Sbrian#define ismask(x) \
90231081Sbrian  (*x == '0' && strlen(x) == 4 && strspn(x+1, "0123456789.") == 3)
90331081Sbrian
90428327Sbrianstatic int
90528679SbrianSetServer(struct cmdtab const * list, int argc, char **argv)
90626940Sbrian{
90726940Sbrian  int res = -1;
90826940Sbrian
90931081Sbrian  if (argc > 0 && argc < 4) {
91031081Sbrian    const char *port, *passwd, *mask;
91131081Sbrian
91231081Sbrian    /* What's what ? */
91331081Sbrian    port = argv[0];
91431081Sbrian    if (argc == 2)
91531081Sbrian      if (ismask(argv[1])) {
91631081Sbrian        passwd = NULL;
91731081Sbrian        mask = argv[1];
91831081Sbrian      } else {
91931081Sbrian        passwd = argv[1];
92031081Sbrian        mask = NULL;
92131081Sbrian      }
92231081Sbrian    else if (argc == 3) {
92331081Sbrian      passwd = argv[1];
92431081Sbrian      mask = argv[2];
92531081Sbrian      if (!ismask(mask))
92631081Sbrian        return -1;
92731081Sbrian    } else
92831081Sbrian      passwd = mask = NULL;
92931081Sbrian
93031081Sbrian    if (passwd == NULL)
93131081Sbrian      VarHaveLocalAuthKey = 0;
93231081Sbrian    else {
93331081Sbrian      strncpy(VarLocalAuthKey, passwd, sizeof VarLocalAuthKey);
93431081Sbrian      VarLocalAuthKey[sizeof VarLocalAuthKey - 1] = '\0';
93531081Sbrian      VarHaveLocalAuthKey = 1;
93631081Sbrian    }
93731081Sbrian    LocalAuthInit();
93831081Sbrian
93931081Sbrian    if (strcasecmp(port, "none") == 0) {
94031081Sbrian      int oserver;
94131081Sbrian
94231081Sbrian      if (mask != NULL || passwd != NULL)
94331081Sbrian        return -1;
94431081Sbrian      oserver = server;
94526940Sbrian      ServerClose();
94631081Sbrian      if (oserver != -1)
94731081Sbrian        LogPrintf(LogPHASE, "Disabling server port.\n");
94826940Sbrian      res = 0;
94931081Sbrian    } else if (*port == '/') {
95031081Sbrian      mode_t imask;
95128679Sbrian
95231081Sbrian      if (mask != NULL) {
95328679Sbrian	unsigned m;
95428679Sbrian
95531081Sbrian	if (sscanf(mask, "%o", &m) == 1)
95631081Sbrian	  imask = m;
95731081Sbrian        else
95831081Sbrian          return -1;
95931081Sbrian      } else
96031081Sbrian        imask = (mode_t)-1;
96131081Sbrian      res = ServerLocalOpen(port, imask);
96227346Sbrian    } else {
96331081Sbrian      int iport;
96428679Sbrian
96531081Sbrian      if (mask != NULL)
96631081Sbrian        return -1;
96728679Sbrian
96831081Sbrian      if (strspn(port, "0123456789") != strlen(port)) {
96931081Sbrian        struct servent *s;
97031081Sbrian
97131081Sbrian        if ((s = getservbyname(port, "tcp")) == NULL) {
97231081Sbrian	  iport = 0;
97331081Sbrian	  LogPrintf(LogWARN, "%s: Invalid port or service\n", port);
97428679Sbrian	} else
97531081Sbrian	  iport = ntohs(s->s_port);
97627346Sbrian      } else
97731081Sbrian        iport = atoi(port);
97831081Sbrian      res = iport ? ServerTcpOpen(iport) : -1;
97927346Sbrian    }
98031081Sbrian  }
98126940Sbrian
98226940Sbrian  return res;
98326940Sbrian}
98426940Sbrian
98526940Sbrianstatic int
98628679SbrianSetModemParity(struct cmdtab const * list, int argc, char **argv)
9876059Samurai{
98826845Sbrian  return argc > 0 ? ChangeParity(*argv) : -1;
9896059Samurai}
9906059Samurai
9916059Samuraistatic int
99228679SbrianSetLogLevel(struct cmdtab const * list, int argc, char **argv)
9936059Samurai{
99426516Sbrian  int i;
99526516Sbrian  int res;
99626516Sbrian  char *arg;
99730913Sbrian  void (*Discard)(int), (*Keep)(int);
99830913Sbrian  void (*DiscardAll)(void);
9996059Samurai
100026516Sbrian  res = 0;
100130913Sbrian  if (strcasecmp(argv[0], "local")) {
100230913Sbrian    Discard = LogDiscard;
100330913Sbrian    Keep = LogKeep;
100430913Sbrian    DiscardAll = LogDiscardAll;
100530913Sbrian  } else {
100630913Sbrian    argc--;
100730913Sbrian    argv++;
100830913Sbrian    Discard = LogDiscardLocal;
100930913Sbrian    Keep = LogKeepLocal;
101030913Sbrian    DiscardAll = LogDiscardAllLocal;
101130913Sbrian  }
101230913Sbrian
101326516Sbrian  if (argc == 0 || (argv[0][0] != '+' && argv[0][0] != '-'))
101430913Sbrian    (*DiscardAll)();
101526516Sbrian  while (argc--) {
101626516Sbrian    arg = **argv == '+' || **argv == '-' ? *argv + 1 : *argv;
101726516Sbrian    for (i = LogMIN; i <= LogMAX; i++)
101826516Sbrian      if (strcasecmp(arg, LogName(i)) == 0) {
101928679Sbrian	if (**argv == '-')
102030913Sbrian	  (*Discard)(i);
102128679Sbrian	else
102230913Sbrian	  (*Keep)(i);
10236059Samurai	break;
10246059Samurai      }
102526516Sbrian    if (i > LogMAX) {
102626516Sbrian      LogPrintf(LogWARN, "%s: Invalid log value\n", arg);
102726516Sbrian      res = -1;
10286059Samurai    }
102926516Sbrian    argv++;
10306059Samurai  }
103126516Sbrian  return res;
10326059Samurai}
10336059Samurai
10346059Samuraistatic int
103528679SbrianSetEscape(struct cmdtab const * list, int argc, char **argv)
10366059Samurai{
10376059Samurai  int code;
10386059Samurai
10396059Samurai  for (code = 0; code < 33; code++)
10406059Samurai    EscMap[code] = 0;
10416059Samurai  while (argc-- > 0) {
10426059Samurai    sscanf(*argv++, "%x", &code);
10436059Samurai    code &= 0xff;
104428679Sbrian    EscMap[code >> 3] |= (1 << (code & 7));
10456059Samurai    EscMap[32] = 1;
10466059Samurai  }
104726516Sbrian  return 0;
10486059Samurai}
10496059Samurai
10506059Samuraistatic int
105128679SbrianSetInitialMRU(struct cmdtab const * list, int argc, char **argv)
10526059Samurai{
105326326Sbrian  long mru;
105426516Sbrian  char *err;
10556059Samurai
10566059Samurai  if (argc > 0) {
105726326Sbrian    mru = atol(*argv);
105826326Sbrian    if (mru < MIN_MRU)
105926516Sbrian      err = "Given MRU value (%ld) is too small.\n";
10606059Samurai    else if (mru > MAX_MRU)
106126516Sbrian      err = "Given MRU value (%ld) is too big.\n";
106226516Sbrian    else {
10636059Samurai      VarMRU = mru;
106426516Sbrian      return 0;
106526516Sbrian    }
106626516Sbrian    LogPrintf(LogWARN, err, mru);
106726516Sbrian  }
106826516Sbrian  return -1;
10696059Samurai}
10706059Samurai
10716059Samuraistatic int
107228679SbrianSetPreferredMTU(struct cmdtab const * list, int argc, char **argv)
107326326Sbrian{
107426326Sbrian  long mtu;
107526516Sbrian  char *err;
107626326Sbrian
107726326Sbrian  if (argc > 0) {
107826326Sbrian    mtu = atol(*argv);
107926516Sbrian    if (mtu == 0) {
108026326Sbrian      VarPrefMTU = 0;
108126516Sbrian      return 0;
108226516Sbrian    } else if (mtu < MIN_MTU)
108326516Sbrian      err = "Given MTU value (%ld) is too small.\n";
108426326Sbrian    else if (mtu > MAX_MTU)
108526516Sbrian      err = "Given MTU value (%ld) is too big.\n";
108626516Sbrian    else {
108726326Sbrian      VarPrefMTU = mtu;
108826516Sbrian      return 0;
108926516Sbrian    }
109026516Sbrian    LogPrintf(LogWARN, err, mtu);
109126516Sbrian  }
109226516Sbrian  return -1;
109326326Sbrian}
109426326Sbrian
109526326Sbrianstatic int
109628679SbrianSetIdleTimeout(struct cmdtab const * list, int argc, char **argv)
10976059Samurai{
10986059Samurai  if (argc-- > 0) {
10996059Samurai    VarIdleTimeout = atoi(*argv++);
110028679Sbrian    UpdateIdleTimer();		/* If we're connected, restart the idle timer */
11016735Samurai    if (argc-- > 0) {
11026735Samurai      VarLqrTimeout = atoi(*argv++);
11036735Samurai      if (VarLqrTimeout < 1)
11046735Samurai	VarLqrTimeout = 30;
11056735Samurai      if (argc > 0) {
11066735Samurai	VarRetryTimeout = atoi(*argv);
11076735Samurai	if (VarRetryTimeout < 1 || VarRetryTimeout > 10)
11086735Samurai	  VarRetryTimeout = 3;
11096735Samurai      }
11106735Samurai    }
111126516Sbrian    return 0;
11126059Samurai  }
111326516Sbrian  return -1;
11146059Samurai}
11156059Samurai
111630715Sbrianstatic struct in_addr
111728679SbrianGetIpAddr(char *cp)
11186059Samurai{
11196059Samurai  struct hostent *hp;
11206059Samurai  struct in_addr ipaddr;
11216059Samurai
11226059Samurai  hp = gethostbyname(cp);
11236059Samurai  if (hp && hp->h_addrtype == AF_INET)
112430715Sbrian    memcpy(&ipaddr, hp->h_addr, hp->h_length);
11256059Samurai  else if (inet_aton(cp, &ipaddr) == 0)
11266059Samurai    ipaddr.s_addr = 0;
112728679Sbrian  return (ipaddr);
11286059Samurai}
11296059Samurai
11306059Samuraistatic int
113128679SbrianSetInterfaceAddr(struct cmdtab const * list, int argc, char **argv)
11326059Samurai{
113328394Sbrian  DefMyAddress.ipaddr.s_addr = DefHisAddress.ipaddr.s_addr = 0L;
11346059Samurai
113526516Sbrian  if (argc > 4)
113628679Sbrian    return -1;
113726516Sbrian
113828394Sbrian  HaveTriggerAddress = 0;
113928394Sbrian  ifnetmask.s_addr = 0;
114028394Sbrian
11416059Samurai  if (argc > 0) {
114225630Sbrian    if (ParseAddr(argc, argv++,
114328679Sbrian		  &DefMyAddress.ipaddr,
114428679Sbrian		  &DefMyAddress.mask,
114528679Sbrian		  &DefMyAddress.width) == 0)
114628679Sbrian      return 1;
11476059Samurai    if (--argc > 0) {
114825630Sbrian      if (ParseAddr(argc, argv++,
114925630Sbrian		    &DefHisAddress.ipaddr,
115025630Sbrian		    &DefHisAddress.mask,
115125630Sbrian		    &DefHisAddress.width) == 0)
115228679Sbrian	return 2;
11536059Samurai      if (--argc > 0) {
115428679Sbrian	ifnetmask = GetIpAddr(*argv);
115528679Sbrian	if (--argc > 0) {
115628679Sbrian	  TriggerAddress = GetIpAddr(*argv);
115728679Sbrian	  HaveTriggerAddress = 1;
11589440Samurai	}
11596059Samurai      }
11606059Samurai    }
11616059Samurai  }
116228394Sbrian
11636059Samurai  /*
11646059Samurai   * For backwards compatibility, 0.0.0.0 means any address.
11656059Samurai   */
11666059Samurai  if (DefMyAddress.ipaddr.s_addr == 0) {
11676059Samurai    DefMyAddress.mask.s_addr = 0;
11686059Samurai    DefMyAddress.width = 0;
11696059Samurai  }
11706059Samurai  if (DefHisAddress.ipaddr.s_addr == 0) {
11716059Samurai    DefHisAddress.mask.s_addr = 0;
11726059Samurai    DefHisAddress.width = 0;
11736059Samurai  }
117428537Sbrian  IpcpInfo.want_ipaddr.s_addr = DefMyAddress.ipaddr.s_addr;
117528537Sbrian  IpcpInfo.his_ipaddr.s_addr = DefHisAddress.ipaddr.s_addr;
117628537Sbrian
11776735Samurai  if ((mode & MODE_AUTO) ||
117828679Sbrian      ((mode & MODE_DEDICATED) && dstsystem)) {
117925630Sbrian    if (OsSetIpaddress(DefMyAddress.ipaddr, DefHisAddress.ipaddr, ifnetmask) < 0)
118028679Sbrian      return 4;
11816059Samurai  }
118226516Sbrian  return 0;
11836059Samurai}
11846059Samurai
118526516Sbrian#ifndef NOMSEXT
11866059Samurai
118730715Sbrianstatic void
118828679SbrianSetMSEXT(struct in_addr * pri_addr,
118928679Sbrian	 struct in_addr * sec_addr,
119028679Sbrian	 int argc,
119128679Sbrian	 char **argv)
119218752Sjkh{
119318752Sjkh  int dummyint;
119418752Sjkh  struct in_addr dummyaddr;
119518752Sjkh
119618752Sjkh  pri_addr->s_addr = sec_addr->s_addr = 0L;
119718752Sjkh
119828679Sbrian  if (argc > 0) {
119918752Sjkh    ParseAddr(argc, argv++, pri_addr, &dummyaddr, &dummyint);
120028679Sbrian    if (--argc > 0)
120118752Sjkh      ParseAddr(argc, argv++, sec_addr, &dummyaddr, &dummyint);
120218752Sjkh    else
120318752Sjkh      sec_addr->s_addr = pri_addr->s_addr;
120418752Sjkh  }
120518752Sjkh
120628679Sbrian  /*
120728679Sbrian   * if the primary/secondary ns entries are 0.0.0.0 we should set them to
120828679Sbrian   * either the localhost's ip, or the values in /etc/resolv.conf ??
120928679Sbrian   *
121028679Sbrian   * up to you if you want to implement this...
121128679Sbrian   */
121218752Sjkh
121318752Sjkh}
121418752Sjkh
121518752Sjkhstatic int
121628679SbrianSetNS(struct cmdtab const * list, int argc, char **argv)
121718752Sjkh{
121818752Sjkh  SetMSEXT(&ns_entries[0], &ns_entries[1], argc, argv);
121926516Sbrian  return 0;
122018752Sjkh}
122118752Sjkh
122218752Sjkhstatic int
122328679SbrianSetNBNS(struct cmdtab const * list, int argc, char **argv)
122418752Sjkh{
122518752Sjkh  SetMSEXT(&nbns_entries[0], &nbns_entries[1], argc, argv);
122626516Sbrian  return 0;
122718752Sjkh}
122818752Sjkh
122928679Sbrian#endif				/* MS_EXT */
123018752Sjkh
123129696Sbrianint
123228679SbrianSetVariable(struct cmdtab const * list, int argc, char **argv, int param)
12336059Samurai{
12346059Samurai  u_long map;
123526551Sbrian  char *arg;
12366059Samurai
123726551Sbrian  if (argc > 0)
123826551Sbrian    arg = *argv;
123926551Sbrian  else
124026551Sbrian    arg = "";
124126551Sbrian
124226551Sbrian  switch (param) {
124328679Sbrian  case VAR_AUTHKEY:
124428679Sbrian    strncpy(VarAuthKey, arg, sizeof(VarAuthKey) - 1);
124528679Sbrian    VarAuthKey[sizeof(VarAuthKey) - 1] = '\0';
124628679Sbrian    break;
124728679Sbrian  case VAR_AUTHNAME:
124828679Sbrian    strncpy(VarAuthName, arg, sizeof(VarAuthName) - 1);
124928679Sbrian    VarAuthName[sizeof(VarAuthName) - 1] = '\0';
125028679Sbrian    break;
125128679Sbrian  case VAR_DIAL:
125228679Sbrian    strncpy(VarDialScript, arg, sizeof(VarDialScript) - 1);
125328679Sbrian    VarDialScript[sizeof(VarDialScript) - 1] = '\0';
125428679Sbrian    break;
125528679Sbrian  case VAR_LOGIN:
125628679Sbrian    strncpy(VarLoginScript, arg, sizeof(VarLoginScript) - 1);
125728679Sbrian    VarLoginScript[sizeof(VarLoginScript) - 1] = '\0';
125828679Sbrian    break;
125928679Sbrian  case VAR_DEVICE:
126029696Sbrian    if (modem != -1)
126129696Sbrian      LogPrintf(LogWARN, "Cannot change device to \"%s\" when \"%s\" is open\n",
126229696Sbrian                arg, VarDevice);
126329696Sbrian    else {
126429696Sbrian      strncpy(VarDevice, arg, sizeof(VarDevice) - 1);
126529696Sbrian      VarDevice[sizeof(VarDevice) - 1] = '\0';
126630715Sbrian      VarBaseDevice = strrchr(VarDevice, '/');
126729696Sbrian      VarBaseDevice = VarBaseDevice ? VarBaseDevice + 1 : "";
126829696Sbrian    }
126928679Sbrian    break;
127028679Sbrian  case VAR_ACCMAP:
127128679Sbrian    sscanf(arg, "%lx", &map);
127228679Sbrian    VarAccmap = map;
127328679Sbrian    break;
127428679Sbrian  case VAR_PHONE:
127528679Sbrian    strncpy(VarPhoneList, arg, sizeof(VarPhoneList) - 1);
127628679Sbrian    VarPhoneList[sizeof(VarPhoneList) - 1] = '\0';
127728679Sbrian    strcpy(VarPhoneCopy, VarPhoneList);
127828679Sbrian    VarNextPhone = VarPhoneCopy;
127928679Sbrian    break;
128028679Sbrian  case VAR_HANGUP:
128128679Sbrian    strncpy(VarHangupScript, arg, sizeof(VarHangupScript) - 1);
128228679Sbrian    VarHangupScript[sizeof(VarHangupScript) - 1] = '\0';
128328679Sbrian    break;
128429840Sbrian#ifdef HAVE_DES
128529549Sbrian  case VAR_ENC:
128629840Sbrian    VarMSChap = !strcasecmp(arg, "mschap");
128729549Sbrian    break;
128829840Sbrian#endif
12896059Samurai  }
129026516Sbrian  return 0;
12916059Samurai}
12926059Samurai
129328679Sbrianstatic int
129428679SbrianSetCtsRts(struct cmdtab const * list, int argc, char **argv)
129520812Sjkh{
129620812Sjkh  if (argc > 0) {
129720812Sjkh    if (strcmp(*argv, "on") == 0)
129830715Sbrian      VarCtsRts = 1;
129920812Sjkh    else if (strcmp(*argv, "off") == 0)
130030715Sbrian      VarCtsRts = 0;
130120812Sjkh    else
130226516Sbrian      return -1;
130326516Sbrian    return 0;
130420812Sjkh  }
130526516Sbrian  return -1;
130620812Sjkh}
130720812Sjkh
130820812Sjkh
130928679Sbrianstatic int
131028679SbrianSetOpenMode(struct cmdtab const * list, int argc, char **argv)
13116059Samurai{
13126059Samurai  if (argc > 0) {
13136059Samurai    if (strcmp(*argv, "active") == 0)
13146059Samurai      VarOpenMode = OPEN_ACTIVE;
13156059Samurai    else if (strcmp(*argv, "passive") == 0)
13166059Samurai      VarOpenMode = OPEN_PASSIVE;
13176059Samurai    else
131826516Sbrian      return -1;
131926516Sbrian    return 0;
13206059Samurai  }
132126516Sbrian  return -1;
13226059Samurai}
13236059Samurai
132430715Sbrianstatic struct cmdtab const SetCommands[] = {
132528679Sbrian  {"accmap", NULL, SetVariable, LOCAL_AUTH,
132628679Sbrian  "Set accmap value", "set accmap hex-value", (void *) VAR_ACCMAP},
132728679Sbrian  {"afilter", NULL, SetAfilter, LOCAL_AUTH,
132828679Sbrian  "Set keep Alive filter", "set afilter ..."},
132928679Sbrian  {"authkey", "key", SetVariable, LOCAL_AUTH,
133028679Sbrian  "Set authentication key", "set authkey|key key", (void *) VAR_AUTHKEY},
133128679Sbrian  {"authname", NULL, SetVariable, LOCAL_AUTH,
133228679Sbrian  "Set authentication name", "set authname name", (void *) VAR_AUTHNAME},
133328679Sbrian  {"ctsrts", NULL, SetCtsRts, LOCAL_AUTH,
133428679Sbrian  "Use CTS/RTS modem signalling", "set ctsrts [on|off]"},
133528679Sbrian  {"device", "line", SetVariable, LOCAL_AUTH,
133628679Sbrian  "Set modem device name", "set device|line device-name", (void *) VAR_DEVICE},
133728679Sbrian  {"dfilter", NULL, SetDfilter, LOCAL_AUTH,
133828679Sbrian  "Set demand filter", "set dfilter ..."},
133928679Sbrian  {"dial", NULL, SetVariable, LOCAL_AUTH,
134028679Sbrian  "Set dialing script", "set dial chat-script", (void *) VAR_DIAL},
134129840Sbrian#ifdef HAVE_DES
134229549Sbrian  {"encrypt", NULL, SetVariable, LOCAL_AUTH,
134329840Sbrian  "Set CHAP encryption algorithm", "set encrypt MSChap|MD5", (void *) VAR_ENC},
134429840Sbrian#endif
134528679Sbrian  {"escape", NULL, SetEscape, LOCAL_AUTH,
134628679Sbrian  "Set escape characters", "set escape hex-digit ..."},
134728679Sbrian  {"hangup", NULL, SetVariable, LOCAL_AUTH,
134828679Sbrian  "Set hangup script", "set hangup chat-script", (void *) VAR_HANGUP},
134928679Sbrian  {"ifaddr", NULL, SetInterfaceAddr, LOCAL_AUTH,
135028679Sbrian  "Set destination address", "set ifaddr [src-addr [dst-addr [netmask [trg-addr]]]]"},
135128679Sbrian  {"ifilter", NULL, SetIfilter, LOCAL_AUTH,
135228679Sbrian  "Set input filter", "set ifilter ..."},
135328679Sbrian  {"loopback", NULL, SetLoopback, LOCAL_AUTH,
135428679Sbrian  "Set loopback facility", "set loopback on|off"},
135528679Sbrian  {"log", NULL, SetLogLevel, LOCAL_AUTH,
135630913Sbrian  "Set log level", "set log [local] [+|-]value..."},
135728679Sbrian  {"login", NULL, SetVariable, LOCAL_AUTH,
135828679Sbrian  "Set login script", "set login chat-script", (void *) VAR_LOGIN},
135928679Sbrian  {"mru", NULL, SetInitialMRU, LOCAL_AUTH,
136028679Sbrian  "Set Initial MRU value", "set mru value"},
136128679Sbrian  {"mtu", NULL, SetPreferredMTU, LOCAL_AUTH,
136228679Sbrian  "Set Preferred MTU value", "set mtu value"},
136328679Sbrian  {"ofilter", NULL, SetOfilter, LOCAL_AUTH,
136428679Sbrian  "Set output filter", "set ofilter ..."},
136528679Sbrian  {"openmode", NULL, SetOpenMode, LOCAL_AUTH,
136628679Sbrian  "Set open mode", "set openmode [active|passive]"},
136728679Sbrian  {"parity", NULL, SetModemParity, LOCAL_AUTH,
136828679Sbrian  "Set modem parity", "set parity [odd|even|none]"},
136928679Sbrian  {"phone", NULL, SetVariable, LOCAL_AUTH,
137028679Sbrian  "Set telephone number(s)", "set phone phone1[:phone2[...]]", (void *) VAR_PHONE},
137128679Sbrian  {"reconnect", NULL, SetReconnect, LOCAL_AUTH,
137228679Sbrian  "Set Reconnect timeout", "set reconnect value ntries"},
137328679Sbrian  {"redial", NULL, SetRedialTimeout, LOCAL_AUTH,
137428679Sbrian  "Set Redial timeout", "set redial value|random[.value|random] [dial_attempts]"},
137528679Sbrian  {"stopped", NULL, SetStoppedTimeout, LOCAL_AUTH,
137628679Sbrian  "Set STOPPED timeouts", "set stopped [LCPseconds [IPCPseconds [CCPseconds]]]"},
137728679Sbrian  {"server", "socket", SetServer, LOCAL_AUTH,
137828679Sbrian  "Set server port", "set server|socket TcpPort|LocalName|none [mask]"},
137928679Sbrian  {"speed", NULL, SetModemSpeed, LOCAL_AUTH,
138028679Sbrian  "Set modem speed", "set speed value"},
138128679Sbrian  {"timeout", NULL, SetIdleTimeout, LOCAL_AUTH,
138228679Sbrian  "Set Idle timeout", "set timeout value"},
138326516Sbrian#ifndef NOMSEXT
138428679Sbrian  {"ns", NULL, SetNS, LOCAL_AUTH,
138528679Sbrian  "Set NameServer", "set ns pri-addr [sec-addr]"},
138628679Sbrian  {"nbns", NULL, SetNBNS, LOCAL_AUTH,
138728679Sbrian  "Set NetBIOS NameServer", "set nbns pri-addr [sec-addr]"},
138826516Sbrian#endif
138928679Sbrian  {"help", "?", HelpCommand, LOCAL_AUTH | LOCAL_NO_AUTH,
139028679Sbrian  "Display this message", "set help|? [command]", (void *) SetCommands},
139128679Sbrian  {NULL, NULL, NULL},
13926059Samurai};
13936059Samurai
13946059Samuraistatic int
139528679SbrianSetCommand(struct cmdtab const * list, int argc, char **argv)
13966059Samurai{
13976059Samurai  if (argc > 0)
139826516Sbrian    FindExec(SetCommands, argc, argv);
139926516Sbrian  else if (VarTerm)
140026516Sbrian    fprintf(VarTerm, "Use `set ?' to get a list or `set ? <var>' for"
140126516Sbrian	    " syntax help.\n");
14026059Samurai  else
140326516Sbrian    LogPrintf(LogWARN, "set command must have arguments\n");
140426516Sbrian
140526516Sbrian  return 0;
14066059Samurai}
14076059Samurai
14086059Samurai
14096059Samuraistatic int
141028679SbrianAddCommand(struct cmdtab const * list, int argc, char **argv)
14116059Samurai{
14126059Samurai  struct in_addr dest, gateway, netmask;
14136059Samurai
14146059Samurai  if (argc == 3) {
141527011Sbrian    if (strcasecmp(argv[0], "MYADDR") == 0)
141627011Sbrian      dest = IpcpInfo.want_ipaddr;
141727011Sbrian    else
141827011Sbrian      dest = GetIpAddr(argv[0]);
14196059Samurai    netmask = GetIpAddr(argv[1]);
142025566Sbrian    if (strcasecmp(argv[2], "HISADDR") == 0)
14216059Samurai      gateway = IpcpInfo.his_ipaddr;
14226059Samurai    else
14236059Samurai      gateway = GetIpAddr(argv[2]);
14246059Samurai    OsSetRoute(RTM_ADD, dest, gateway, netmask);
142526516Sbrian    return 0;
14266059Samurai  }
142726516Sbrian  return -1;
14286059Samurai}
14296059Samurai
14306059Samuraistatic int
143128679SbrianDeleteCommand(struct cmdtab const * list, int argc, char **argv)
14326059Samurai{
14336059Samurai  struct in_addr dest, gateway, netmask;
14346059Samurai
143526591Sbrian  if (argc == 1 && strcasecmp(argv[0], "all") == 0)
143626591Sbrian    DeleteIfRoutes(0);
143726591Sbrian  else if (argc > 0 && argc < 4) {
143827011Sbrian    if (strcasecmp(argv[0], "MYADDR") == 0)
143927011Sbrian      dest = IpcpInfo.want_ipaddr;
144027011Sbrian    else
144127011Sbrian      dest = GetIpAddr(argv[0]);
144226591Sbrian    netmask.s_addr = INADDR_ANY;
144326591Sbrian    if (argc > 1) {
144426591Sbrian      if (strcasecmp(argv[1], "HISADDR") == 0)
144528679Sbrian	gateway = IpcpInfo.his_ipaddr;
144626591Sbrian      else
144728679Sbrian	gateway = GetIpAddr(argv[1]);
144826591Sbrian      if (argc == 3) {
144928679Sbrian	if (inet_aton(argv[2], &netmask) == 0) {
145026591Sbrian	  LogPrintf(LogWARN, "Bad netmask value.\n");
145126591Sbrian	  return -1;
145228679Sbrian	}
14536059Samurai      }
145426591Sbrian    } else
145526591Sbrian      gateway.s_addr = INADDR_ANY;
14566059Samurai    OsSetRoute(RTM_DELETE, dest, gateway, netmask);
145726516Sbrian  } else
145826516Sbrian    return -1;
145926516Sbrian
146026516Sbrian  return 0;
14616059Samurai}
14626059Samurai
146326031Sbrianstatic struct cmdtab const AliasCommands[] =
146426031Sbrian{
146528679Sbrian  {"enable", NULL, AliasEnable, LOCAL_AUTH,
146628679Sbrian  "enable IP aliasing", "alias enable [yes|no]"},
146728679Sbrian  {"port", NULL, AliasRedirectPort, LOCAL_AUTH,
146828679Sbrian  "port redirection", "alias port [proto addr_local:port_local  port_alias]"},
146928679Sbrian  {"addr", NULL, AliasRedirectAddr, LOCAL_AUTH,
147028679Sbrian  "static address translation", "alias addr [addr_local addr_alias]"},
147128679Sbrian  {"deny_incoming", NULL, AliasOption, LOCAL_AUTH,
147228679Sbrian    "stop incoming connections", "alias deny_incoming [yes|no]",
147328679Sbrian  (void *) PKT_ALIAS_DENY_INCOMING},
147428679Sbrian  {"log", NULL, AliasOption, LOCAL_AUTH,
147528679Sbrian    "log aliasing link creation", "alias log [yes|no]",
147628679Sbrian  (void *) PKT_ALIAS_LOG},
147728679Sbrian  {"same_ports", NULL, AliasOption, LOCAL_AUTH,
147828679Sbrian    "try to leave port numbers unchanged", "alias same_ports [yes|no]",
147928679Sbrian  (void *) PKT_ALIAS_SAME_PORTS},
148028679Sbrian  {"use_sockets", NULL, AliasOption, LOCAL_AUTH,
148128679Sbrian    "allocate host sockets", "alias use_sockets [yes|no]",
148228679Sbrian  (void *) PKT_ALIAS_USE_SOCKETS},
148328679Sbrian  {"unregistered_only", NULL, AliasOption, LOCAL_AUTH,
148428679Sbrian    "alias unregistered (private) IP address space only",
148528679Sbrian    "alias unregistered_only [yes|no]",
148628679Sbrian  (void *) PKT_ALIAS_UNREGISTERED_ONLY},
148728679Sbrian  {"help", "?", HelpCommand, LOCAL_AUTH | LOCAL_NO_AUTH,
148828679Sbrian    "Display this message", "alias help|? [command]",
148928679Sbrian  (void *) AliasCommands},
149028679Sbrian  {NULL, NULL, NULL},
149126031Sbrian};
149226031Sbrian
149326031Sbrian
149426031Sbrianstatic int
149528679SbrianAliasCommand(struct cmdtab const * list, int argc, char **argv)
149626031Sbrian{
149726031Sbrian  if (argc > 0)
149826516Sbrian    FindExec(AliasCommands, argc, argv);
149926516Sbrian  else if (VarTerm)
150026516Sbrian    fprintf(VarTerm, "Use `alias help' to get a list or `alias help <option>'"
150126516Sbrian	    " for syntax help.\n");
150226031Sbrian  else
150326516Sbrian    LogPrintf(LogWARN, "alias command must have arguments\n");
150426516Sbrian
150526516Sbrian  return 0;
150626031Sbrian}
150726031Sbrian
150826031Sbrianstatic int
150928679SbrianAliasEnable(struct cmdtab const * list, int argc, char **argv)
151026031Sbrian{
151126516Sbrian  if (argc == 1)
151226516Sbrian    if (strcasecmp(argv[0], "yes") == 0) {
151326516Sbrian      if (!(mode & MODE_ALIAS)) {
151428679Sbrian	if (loadAliasHandlers(&VarAliasHandlers) == 0) {
151528679Sbrian	  mode |= MODE_ALIAS;
151628679Sbrian	  return 0;
151728679Sbrian	}
151828679Sbrian	LogPrintf(LogWARN, "Cannot load alias library\n");
151928679Sbrian	return 1;
152026516Sbrian      }
152126516Sbrian      return 0;
152226516Sbrian    } else if (strcasecmp(argv[0], "no") == 0) {
152326516Sbrian      if (mode & MODE_ALIAS) {
152428679Sbrian	unloadAliasHandlers();
152528679Sbrian	mode &= ~MODE_ALIAS;
152626516Sbrian      }
152726516Sbrian      return 0;
152826142Sbrian    }
152926516Sbrian  return -1;
153026031Sbrian}
153126031Sbrian
153226031Sbrian
153326031Sbrianstatic int
153428679SbrianAliasOption(struct cmdtab const * list, int argc, char **argv, void *param)
153526031Sbrian{
153628679Sbrian  if (argc == 1)
153728679Sbrian    if (strcasecmp(argv[0], "yes") == 0) {
153828679Sbrian      if (mode & MODE_ALIAS) {
153928679Sbrian	VarPacketAliasSetMode((unsigned) param, (unsigned) param);
154028679Sbrian	return 0;
154128679Sbrian      }
154228679Sbrian      LogPrintf(LogWARN, "alias not enabled\n");
154328679Sbrian    } else if (strcmp(argv[0], "no") == 0) {
154428679Sbrian      if (mode & MODE_ALIAS) {
154528679Sbrian	VarPacketAliasSetMode(0, (unsigned) param);
154628679Sbrian	return 0;
154728679Sbrian      }
154828679Sbrian      LogPrintf(LogWARN, "alias not enabled\n");
154928679Sbrian    }
155028679Sbrian  return -1;
155126031Sbrian}
1552