command.c revision 31156
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 *
2031156Sbrian * $Id: command.c,v 1.101 1997/11/12 18:47:28 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 **);
8031121Sbrianstatic int AllowCommand(struct cmdtab const *, int, char **);
8128679Sbrianstatic int SetCommand(struct cmdtab const *, int, char **);
8228679Sbrianstatic int AddCommand(struct cmdtab const *, int, char **);
8328679Sbrianstatic int DeleteCommand(struct cmdtab const *, int, char **);
8428679Sbrianstatic int BgShellCommand(struct cmdtab const *, int, char **);
8528679Sbrianstatic int FgShellCommand(struct cmdtab const *, int, char **);
8628679Sbrianstatic int ShellCommand(struct cmdtab const *, int, char **, int);
8730715Sbrianstatic int AliasCommand(struct cmdtab const *, int, char **);
8830715Sbrianstatic int AliasEnable(struct cmdtab const *, int, char **);
8930715Sbrianstatic int AliasOption(struct cmdtab const *, int, char **, void *);
906059Samurai
916059Samuraistatic int
9228679SbrianHelpCommand(struct cmdtab const * list,
9328679Sbrian	    int argc,
9428679Sbrian	    char **argv,
9528679Sbrian	    struct cmdtab const * plist)
966059Samurai{
9728679Sbrian  struct cmdtab const *cmd;
986059Samurai  int n;
996059Samurai
10026516Sbrian  if (!VarTerm)
10126516Sbrian    return 0;
10226516Sbrian
1036059Samurai  if (argc > 0) {
10426516Sbrian    for (cmd = plist; cmd->name; cmd++)
10525566Sbrian      if (strcasecmp(cmd->name, *argv) == 0 && (cmd->lauth & VarLocalAuth)) {
10628679Sbrian	fprintf(VarTerm, "%s\n", cmd->syntax);
10728679Sbrian	return 0;
1086059Samurai      }
10926516Sbrian    return -1;
1106059Samurai  }
1116059Samurai  n = 0;
11226516Sbrian  for (cmd = plist; cmd->func; cmd++)
1136764Samurai    if (cmd->name && (cmd->lauth & VarLocalAuth)) {
11426587Sbrian      fprintf(VarTerm, "  %-9s: %-20s\n", cmd->name, cmd->helpmes);
1156059Samurai      n++;
1166059Samurai    }
1176059Samurai  if (n & 1)
11826516Sbrian    fprintf(VarTerm, "\n");
11926516Sbrian
12026516Sbrian  return 0;
1216059Samurai}
1226059Samurai
1236059Samuraiint
12430913SbrianIsInteractive(int Display)
1256059Samurai{
1266059Samurai  char *mes = NULL;
1276059Samurai
12820120Snate  if (mode & MODE_DDIAL)
12920120Snate    mes = "Working in dedicated dial mode.";
13025908Sbrian  else if (mode & MODE_BACKGROUND)
13125908Sbrian    mes = "Working in background mode.";
13220120Snate  else if (mode & MODE_AUTO)
13310528Samurai    mes = "Working in auto mode.";
1346059Samurai  else if (mode & MODE_DIRECT)
13510528Samurai    mes = "Working in direct mode.";
1366059Samurai  else if (mode & MODE_DEDICATED)
13710528Samurai    mes = "Working in dedicated mode.";
1386059Samurai  if (mes) {
13930913Sbrian    if (Display && VarTerm)
14026516Sbrian      fprintf(VarTerm, "%s\n", mes);
14126516Sbrian    return 0;
1426059Samurai  }
14326516Sbrian  return 1;
1446059Samurai}
1456059Samurai
1466059Samuraistatic int
14728679SbrianDialCommand(struct cmdtab const * cmdlist, int argc, char **argv)
1486059Samurai{
14911336Samurai  int tries;
15026858Sbrian  int res;
15111336Samurai
1526059Samurai  if (LcpFsm.state > ST_CLOSED) {
15326516Sbrian    if (VarTerm)
15426516Sbrian      fprintf(VarTerm, "LCP state is [%s]\n", StateNames[LcpFsm.state]);
15526516Sbrian    return 0;
1566059Samurai  }
15726516Sbrian
15831140Sbrian  if (argc > 0 && (res = LoadCommand(cmdlist, argc, argv)) != 0)
15931140Sbrian    return res;
16031121Sbrian
16111336Samurai  tries = 0;
16211336Samurai  do {
16326516Sbrian    if (VarTerm)
16426516Sbrian      fprintf(VarTerm, "Dial attempt %u of %d\n", ++tries, VarDialTries);
16531034Sbrian    if (OpenModem() < 0) {
16626516Sbrian      if (VarTerm)
16728679Sbrian	fprintf(VarTerm, "Failed to open modem.\n");
16811336Samurai      break;
16911336Samurai    }
17026858Sbrian    if ((res = DialModem()) == EX_DONE) {
17130697Sbrian      nointr_sleep(1);
17211336Samurai      ModemTimeout();
17311336Samurai      PacketMode();
17411336Samurai      break;
17526858Sbrian    } else if (res == EX_SIG)
17626858Sbrian      return 1;
17711336Samurai  } while (VarDialTries == 0 || tries < VarDialTries);
17826516Sbrian
17926516Sbrian  return 0;
1806059Samurai}
1816059Samurai
18210528Samuraistatic int
18328679SbrianSetLoopback(struct cmdtab const * cmdlist, int argc, char **argv)
18428536Sbrian{
18528536Sbrian  if (argc == 1)
18631141Sbrian    if (!strcasecmp(*argv, "on")) {
18728536Sbrian      VarLoopback = 1;
18831141Sbrian      return 0;
18931141Sbrian    }
19031141Sbrian    else if (!strcasecmp(*argv, "off")) {
19128536Sbrian      VarLoopback = 0;
19231141Sbrian      return 0;
19331141Sbrian    }
19428536Sbrian  return -1;
19528536Sbrian}
19628536Sbrian
19728536Sbrianstatic int
19828679SbrianBgShellCommand(struct cmdtab const * cmdlist, int argc, char **argv)
19910528Samurai{
20028381Sbrian  if (argc == 0)
20128381Sbrian    return -1;
20228381Sbrian  return ShellCommand(cmdlist, argc, argv, 1);
20328381Sbrian}
20428381Sbrian
20528381Sbrianstatic int
20628679SbrianFgShellCommand(struct cmdtab const * cmdlist, int argc, char **argv)
20728381Sbrian{
20828381Sbrian  return ShellCommand(cmdlist, argc, argv, 0);
20928381Sbrian}
21028381Sbrian
21128381Sbrianstatic int
21228679SbrianShellCommand(struct cmdtab const * cmdlist, int argc, char **argv, int bg)
21328381Sbrian{
21410528Samurai  const char *shell;
21510528Samurai  pid_t shpid;
21626516Sbrian  FILE *oVarTerm;
21720813Sjkh
21818856Ssos#ifdef SHELL_ONLY_INTERACTIVELY
21926911Sbrian  /* we're only allowed to shell when we run ppp interactively */
22026516Sbrian  if (mode != MODE_INTER) {
22126516Sbrian    LogPrintf(LogWARN, "Can only start a shell in interactive mode\n");
22226516Sbrian    return 1;
22310528Samurai  }
22426911Sbrian#endif
22526911Sbrian#ifdef NO_SHELL_IN_AUTO_INTERACTIVE
22628679Sbrian
22726911Sbrian  /*
22828679Sbrian   * we want to stop shell commands when we've got a telnet connection to an
22928679Sbrian   * auto mode ppp
23026911Sbrian   */
23131121Sbrian  if (VarTerm && !(mode & MODE_INTER)) {
23228679Sbrian    LogPrintf(LogWARN, "Shell is not allowed interactively in auto mode\n");
23326516Sbrian    return 1;
23426516Sbrian  }
23526516Sbrian#endif
23626516Sbrian
23728679Sbrian  if (argc == 0)
23828381Sbrian    if (!(mode & MODE_INTER)) {
23931121Sbrian      if (VarTerm)
24031121Sbrian        LogPrintf(LogWARN, "Can't start an interactive shell from"
24131121Sbrian		  " a telnet session\n");
24231121Sbrian      else
24331121Sbrian        LogPrintf(LogWARN, "Can only start an interactive shell in"
24431121Sbrian		  " interactive mode\n");
24528381Sbrian      return 1;
24628381Sbrian    } else if (bg) {
24728381Sbrian      LogPrintf(LogWARN, "Can only start an interactive shell in"
24828679Sbrian		" the foreground mode\n");
24928381Sbrian      return 1;
25028381Sbrian    }
25128679Sbrian  if ((shell = getenv("SHELL")) == 0)
25226516Sbrian    shell = _PATH_BSHELL;
25326516Sbrian
25428679Sbrian  if ((shpid = fork()) == 0) {
25528679Sbrian    int dtablesize, i, fd;
25618531Sbde
25728679Sbrian    if (VarTerm)
25828679Sbrian      fd = fileno(VarTerm);
25928679Sbrian    else if ((fd = open("/dev/null", O_RDWR)) == -1) {
26028679Sbrian      LogPrintf(LogALERT, "Failed to open /dev/null: %s\n", strerror(errno));
26128679Sbrian      exit(1);
26228679Sbrian    }
26328679Sbrian    for (i = 0; i < 3; i++)
26428679Sbrian      dup2(fd, i);
26526516Sbrian
26628679Sbrian    if (fd > 2)
26728679Sbrian      if (VarTerm) {
26828679Sbrian	oVarTerm = VarTerm;
26928679Sbrian	VarTerm = 0;
27028679Sbrian	if (oVarTerm && oVarTerm != stdout)
27128679Sbrian	  fclose(oVarTerm);
27228679Sbrian      } else
27328679Sbrian	close(fd);
27426516Sbrian
27528679Sbrian    for (dtablesize = getdtablesize(), i = 3; i < dtablesize; i++)
27628679Sbrian      (void) close(i);
27726516Sbrian
27828679Sbrian    TtyOldMode();
27931061Sbrian    setuid(geteuid());
28028679Sbrian    if (argc > 0) {
28128679Sbrian      /* substitute pseudo args */
28228679Sbrian      for (i = 1; i < argc; i++)
28328679Sbrian	if (strcasecmp(argv[i], "HISADDR") == 0)
28428679Sbrian	  argv[i] = strdup(inet_ntoa(IpcpInfo.his_ipaddr));
28528679Sbrian	else if (strcasecmp(argv[i], "INTERFACE") == 0)
28628679Sbrian	  argv[i] = strdup(IfDevName);
28728679Sbrian	else if (strcasecmp(argv[i], "MYADDR") == 0)
28828679Sbrian	  argv[i] = strdup(inet_ntoa(IpcpInfo.want_ipaddr));
28928679Sbrian      if (bg) {
29028679Sbrian	pid_t p;
29110528Samurai
29228679Sbrian	p = getpid();
29328679Sbrian	if (daemon(1, 1) == -1) {
29428974Sbrian	  LogPrintf(LogERROR, "%d: daemon: %s\n", p, strerror(errno));
29528679Sbrian	  exit(1);
29628679Sbrian	}
29731125Sbrian      } else 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"},
32731121Sbrian  {"allow", "auth", AllowCommand, LOCAL_AUTH,
32831121Sbrian  "Allow ppp access", "allow users|modes ...."},
32928679Sbrian  {"bg", "!bg", BgShellCommand, LOCAL_AUTH,
33028679Sbrian  "Run a command in the background", "[!]bg command"},
33128679Sbrian  {"close", NULL, CloseCommand, LOCAL_AUTH,
33228679Sbrian  "Close connection", "close"},
33328679Sbrian  {"delete", NULL, DeleteCommand, LOCAL_AUTH,
33428679Sbrian  "delete route", "delete ALL | dest [gateway [mask]]"},
33528679Sbrian  {"deny", NULL, DenyCommand, LOCAL_AUTH,
33628679Sbrian  "Deny option request", "deny option .."},
33728679Sbrian  {"dial", "call", DialCommand, LOCAL_AUTH,
33828679Sbrian  "Dial and login", "dial|call [remote]"},
33928679Sbrian  {"disable", NULL, DisableCommand, LOCAL_AUTH,
34028679Sbrian  "Disable option", "disable option .."},
34128679Sbrian  {"display", NULL, DisplayCommand, LOCAL_AUTH,
34228679Sbrian  "Display option configs", "display"},
34328679Sbrian  {"enable", NULL, EnableCommand, LOCAL_AUTH,
34428679Sbrian  "Enable option", "enable option .."},
34528679Sbrian  {"passwd", NULL, LocalAuthCommand, LOCAL_NO_AUTH,
34629083Sbrian  "Password for manipulation", "passwd LocalPassword"},
34728679Sbrian  {"load", NULL, LoadCommand, LOCAL_AUTH,
34828679Sbrian  "Load settings", "load [remote]"},
34928679Sbrian  {"save", NULL, SaveCommand, LOCAL_AUTH,
35028679Sbrian  "Save settings", "save"},
35128679Sbrian  {"set", "setup", SetCommand, LOCAL_AUTH,
35228679Sbrian  "Set parameters", "set[up] var value"},
35328679Sbrian  {"shell", "!", FgShellCommand, LOCAL_AUTH,
35428679Sbrian  "Run a subshell", "shell|! [sh command]"},
35528679Sbrian  {"show", NULL, ShowCommand, LOCAL_AUTH,
35629660Sbrian  "Show status and statistics", "show var"},
35728679Sbrian  {"term", NULL, TerminalCommand, LOCAL_AUTH,
35828679Sbrian  "Enter to terminal mode", "term"},
35928679Sbrian  {"alias", NULL, AliasCommand, LOCAL_AUTH,
36028679Sbrian  "alias control", "alias option [yes|no]"},
36128679Sbrian  {"quit", "bye", QuitCommand, LOCAL_AUTH | LOCAL_NO_AUTH,
36228679Sbrian  "Quit PPP program", "quit|bye [all]"},
36328679Sbrian  {"help", "?", HelpCommand, LOCAL_AUTH | LOCAL_NO_AUTH,
36428679Sbrian  "Display this message", "help|? [command]", (void *) Commands},
36528679Sbrian  {NULL, "down", DownCommand, LOCAL_AUTH,
36628679Sbrian  "Generate down event", "down"},
36728679Sbrian  {NULL, NULL, NULL},
3686059Samurai};
3696059Samurai
37028536Sbrianstatic int
37128536SbrianShowLoopback()
37228536Sbrian{
37328536Sbrian  if (VarTerm)
37428536Sbrian    fprintf(VarTerm, "Local loopback is %s\n", VarLoopback ? "on" : "off");
37528536Sbrian
37628536Sbrian  return 0;
37728536Sbrian}
37828536Sbrian
37928679Sbrianstatic int
38028679SbrianShowLogLevel()
3816059Samurai{
3826059Samurai  int i;
3836059Samurai
38426516Sbrian  if (!VarTerm)
38526516Sbrian    return 0;
38630913Sbrian
38730913Sbrian  fprintf(VarTerm, "Log:  ");
38830913Sbrian  for (i = LogMIN; i <= LogMAX; i++)
38930913Sbrian    if (LogIsKept(i) & LOG_KEPT_SYSLOG)
39026516Sbrian      fprintf(VarTerm, " %s", LogName(i));
39130913Sbrian
39230913Sbrian  fprintf(VarTerm, "\nLocal:");
39330913Sbrian  for (i = LogMIN; i <= LogMAX; i++)
39430913Sbrian    if (LogIsKept(i) & LOG_KEPT_LOCAL)
39530913Sbrian      fprintf(VarTerm, " %s", LogName(i));
39630913Sbrian
39726516Sbrian  fprintf(VarTerm, "\n");
39826516Sbrian
39926516Sbrian  return 0;
4006059Samurai}
4016059Samurai
40228679Sbrianstatic int
40328679SbrianShowEscape()
4046059Samurai{
4056059Samurai  int code, bit;
4066059Samurai
40726516Sbrian  if (!VarTerm)
40826516Sbrian    return 0;
4096059Samurai  if (EscMap[32]) {
41026516Sbrian    for (code = 0; code < 32; code++)
41126516Sbrian      if (EscMap[code])
41228679Sbrian	for (bit = 0; bit < 8; bit++)
41328679Sbrian	  if (EscMap[code] & (1 << bit))
41428679Sbrian	    fprintf(VarTerm, " 0x%02x", (code << 3) + bit);
41526516Sbrian    fprintf(VarTerm, "\n");
4166059Samurai  }
41731077Sbrian  return 0;
4186059Samurai}
4196059Samurai
42028679Sbrianstatic int
42128679SbrianShowTimeout()
4226059Samurai{
42331077Sbrian  if (VarTerm)
42431077Sbrian    fprintf(VarTerm, " Idle Timer: %d secs   LQR Timer: %d secs"
42531077Sbrian	    "   Retry Timer: %d secs\n", VarIdleTimeout, VarLqrTimeout,
42631077Sbrian	    VarRetryTimeout);
42731077Sbrian  return 0;
4286059Samurai}
4296059Samurai
43028679Sbrianstatic int
43128679SbrianShowStopped()
43228327Sbrian{
43328327Sbrian  if (!VarTerm)
43428327Sbrian    return 0;
43528461Sbrian
43628461Sbrian  fprintf(VarTerm, " Stopped Timer:  LCP: ");
43728461Sbrian  if (!LcpFsm.StoppedTimer.load)
43828461Sbrian    fprintf(VarTerm, "Disabled");
43928327Sbrian  else
44028461Sbrian    fprintf(VarTerm, "%ld secs", LcpFsm.StoppedTimer.load / SECTICKS);
44128461Sbrian
44228461Sbrian  fprintf(VarTerm, ", IPCP: ");
44328461Sbrian  if (!IpcpFsm.StoppedTimer.load)
44428461Sbrian    fprintf(VarTerm, "Disabled");
44528461Sbrian  else
44628461Sbrian    fprintf(VarTerm, "%ld secs", IpcpFsm.StoppedTimer.load / SECTICKS);
44728461Sbrian
44828461Sbrian  fprintf(VarTerm, ", CCP: ");
44928461Sbrian  if (!CcpFsm.StoppedTimer.load)
45028461Sbrian    fprintf(VarTerm, "Disabled");
45128461Sbrian  else
45228461Sbrian    fprintf(VarTerm, "%ld secs", CcpFsm.StoppedTimer.load / SECTICKS);
45328461Sbrian
45428461Sbrian  fprintf(VarTerm, "\n");
45528461Sbrian
45631077Sbrian  return 0;
45728327Sbrian}
45828327Sbrian
45928679Sbrianstatic int
46028679SbrianShowAuthKey()
4616059Samurai{
46226516Sbrian  if (!VarTerm)
46326516Sbrian    return 0;
46426516Sbrian  fprintf(VarTerm, "AuthName = %s\n", VarAuthName);
46526516Sbrian  fprintf(VarTerm, "AuthKey  = %s\n", VarAuthKey);
46629840Sbrian#ifdef HAVE_DES
46729840Sbrian  fprintf(VarTerm, "Encrypt  = %s\n", VarMSChap ? "MSChap" : "MD5" );
46829840Sbrian#endif
46931077Sbrian  return 0;
4706059Samurai}
4716059Samurai
47228679Sbrianstatic int
47328679SbrianShowVersion()
4746059Samurai{
47531077Sbrian  if (VarTerm)
47631077Sbrian    fprintf(VarTerm, "%s - %s \n", VarVersion, VarLocalVersion);
47731077Sbrian  return 0;
4786059Samurai}
4796059Samurai
48028679Sbrianstatic int
48128679SbrianShowInitialMRU()
48226326Sbrian{
48331077Sbrian  if (VarTerm)
48431077Sbrian    fprintf(VarTerm, " Initial MRU: %ld\n", VarMRU);
48531077Sbrian  return 0;
48626326Sbrian}
48726326Sbrian
48828679Sbrianstatic int
48928679SbrianShowPreferredMTU()
49026326Sbrian{
49131077Sbrian  if (VarTerm)
49231077Sbrian    if (VarPrefMTU)
49331077Sbrian      fprintf(VarTerm, " Preferred MTU: %ld\n", VarPrefMTU);
49431077Sbrian    else
49531077Sbrian      fprintf(VarTerm, " Preferred MTU: unspecified\n");
49631077Sbrian  return 0;
49726326Sbrian}
49826326Sbrian
49928679Sbrianstatic int
50028679SbrianShowReconnect()
50125067Sbrian{
50231077Sbrian  if (VarTerm)
50331077Sbrian    fprintf(VarTerm, " Reconnect Timer:  %d,  %d tries\n",
50431077Sbrian	    VarReconnectTimer, VarReconnectTries);
50531077Sbrian  return 0;
50625067Sbrian}
50725067Sbrian
50828679Sbrianstatic int
50928679SbrianShowRedial()
51011336Samurai{
51126516Sbrian  if (!VarTerm)
51226516Sbrian    return 0;
51326516Sbrian  fprintf(VarTerm, " Redial Timer: ");
51411336Samurai
51511336Samurai  if (VarRedialTimeout >= 0) {
51626516Sbrian    fprintf(VarTerm, " %d seconds, ", VarRedialTimeout);
51728679Sbrian  } else {
51826516Sbrian    fprintf(VarTerm, " Random 0 - %d seconds, ", REDIAL_PERIOD);
51911336Samurai  }
52011336Samurai
52126516Sbrian  fprintf(VarTerm, " Redial Next Timer: ");
52224939Sbrian
52324939Sbrian  if (VarRedialNextTimeout >= 0) {
52426516Sbrian    fprintf(VarTerm, " %d seconds, ", VarRedialNextTimeout);
52528679Sbrian  } else {
52626516Sbrian    fprintf(VarTerm, " Random 0 - %d seconds, ", REDIAL_PERIOD);
52724939Sbrian  }
52824939Sbrian
52911336Samurai  if (VarDialTries)
53028679Sbrian    fprintf(VarTerm, "%d dial tries", VarDialTries);
53111336Samurai
53226516Sbrian  fprintf(VarTerm, "\n");
53311336Samurai
53431077Sbrian  return 0;
53511336Samurai}
53611336Samurai
53726516Sbrian#ifndef NOMSEXT
53828679Sbrianstatic int
53928679SbrianShowMSExt()
54018752Sjkh{
54131077Sbrian  if (VarTerm) {
54231077Sbrian    fprintf(VarTerm, " MS PPP extention values \n");
54331077Sbrian    fprintf(VarTerm, "   Primary NS     : %s\n", inet_ntoa(ns_entries[0]));
54431077Sbrian    fprintf(VarTerm, "   Secondary NS   : %s\n", inet_ntoa(ns_entries[1]));
54531077Sbrian    fprintf(VarTerm, "   Primary NBNS   : %s\n", inet_ntoa(nbns_entries[0]));
54631077Sbrian    fprintf(VarTerm, "   Secondary NBNS : %s\n", inet_ntoa(nbns_entries[1]));
54731077Sbrian  }
54831077Sbrian  return 0;
54918752Sjkh}
55028679Sbrian
55126516Sbrian#endif
55218752Sjkh
55330715Sbrianstatic struct cmdtab const ShowCommands[] = {
55428679Sbrian  {"afilter", NULL, ShowAfilter, LOCAL_AUTH,
55528679Sbrian  "Show keep Alive filters", "show afilter option .."},
55628679Sbrian  {"auth", NULL, ShowAuthKey, LOCAL_AUTH,
55729549Sbrian  "Show auth name, key and algorithm", "show auth"},
55828679Sbrian  {"ccp", NULL, ReportCcpStatus, LOCAL_AUTH,
55928679Sbrian  "Show CCP status", "show cpp"},
56028679Sbrian  {"compress", NULL, ReportCompress, LOCAL_AUTH,
56129660Sbrian  "Show compression statistics", "show compress"},
56228679Sbrian  {"dfilter", NULL, ShowDfilter, LOCAL_AUTH,
56328679Sbrian  "Show Demand filters", "show dfilteroption .."},
56428679Sbrian  {"escape", NULL, ShowEscape, LOCAL_AUTH,
56528679Sbrian  "Show escape characters", "show escape"},
56628679Sbrian  {"hdlc", NULL, ReportHdlcStatus, LOCAL_AUTH,
56728679Sbrian  "Show HDLC error summary", "show hdlc"},
56828679Sbrian  {"ifilter", NULL, ShowIfilter, LOCAL_AUTH,
56928679Sbrian  "Show Input filters", "show ifilter option .."},
57028679Sbrian  {"ipcp", NULL, ReportIpcpStatus, LOCAL_AUTH,
57128679Sbrian  "Show IPCP status", "show ipcp"},
57228679Sbrian  {"lcp", NULL, ReportLcpStatus, LOCAL_AUTH,
57328679Sbrian  "Show LCP status", "show lcp"},
57428679Sbrian  {"loopback", NULL, ShowLoopback, LOCAL_AUTH,
57528679Sbrian  "Show current loopback setting", "show loopback"},
57628679Sbrian  {"log", NULL, ShowLogLevel, LOCAL_AUTH,
57728679Sbrian  "Show current log level", "show log"},
57828679Sbrian  {"mem", NULL, ShowMemMap, LOCAL_AUTH,
57928679Sbrian  "Show memory map", "show mem"},
58028679Sbrian  {"modem", NULL, ShowModemStatus, LOCAL_AUTH,
58128679Sbrian  "Show modem setups", "show modem"},
58228679Sbrian  {"mru", NULL, ShowInitialMRU, LOCAL_AUTH,
58328679Sbrian  "Show Initial MRU", "show mru"},
58428679Sbrian  {"mtu", NULL, ShowPreferredMTU, LOCAL_AUTH,
58528679Sbrian  "Show Preferred MTU", "show mtu"},
58628679Sbrian  {"ofilter", NULL, ShowOfilter, LOCAL_AUTH,
58728679Sbrian  "Show Output filters", "show ofilter option .."},
58828679Sbrian  {"proto", NULL, ReportProtStatus, LOCAL_AUTH,
58928679Sbrian  "Show protocol summary", "show proto"},
59028679Sbrian  {"reconnect", NULL, ShowReconnect, LOCAL_AUTH,
59128679Sbrian  "Show Reconnect timer,tries", "show reconnect"},
59228679Sbrian  {"redial", NULL, ShowRedial, LOCAL_AUTH,
59328679Sbrian  "Show Redial timeout value", "show redial"},
59428679Sbrian  {"route", NULL, ShowRoute, LOCAL_AUTH,
59528679Sbrian  "Show routing table", "show route"},
59628679Sbrian  {"timeout", NULL, ShowTimeout, LOCAL_AUTH,
59728679Sbrian  "Show Idle timeout value", "show timeout"},
59828679Sbrian  {"stopped", NULL, ShowStopped, LOCAL_AUTH,
59928679Sbrian  "Show STOPPED timeout value", "show stopped"},
60026516Sbrian#ifndef NOMSEXT
60128679Sbrian  {"msext", NULL, ShowMSExt, LOCAL_AUTH,
60228679Sbrian  "Show MS PPP extentions", "show msext"},
60326516Sbrian#endif
60428679Sbrian  {"version", NULL, ShowVersion, LOCAL_NO_AUTH | LOCAL_AUTH,
60528679Sbrian  "Show version string", "show version"},
60628679Sbrian  {"help", "?", HelpCommand, LOCAL_NO_AUTH | LOCAL_AUTH,
60728679Sbrian  "Display this message", "show help|? [command]", (void *) ShowCommands},
60828679Sbrian  {NULL, NULL, NULL},
6096059Samurai};
6106059Samurai
61130715Sbrianstatic struct cmdtab const *
61228679SbrianFindCommand(struct cmdtab const * cmds, char *str, int *pmatch)
6136059Samurai{
61426516Sbrian  int nmatch;
61526516Sbrian  int len;
61628679Sbrian  struct cmdtab const *found;
6176059Samurai
61826516Sbrian  found = NULL;
61926516Sbrian  len = strlen(str);
62026516Sbrian  nmatch = 0;
6216059Samurai  while (cmds->func) {
62225566Sbrian    if (cmds->name && strncasecmp(str, cmds->name, len) == 0) {
62326516Sbrian      if (cmds->name[len] == '\0') {
62428679Sbrian	*pmatch = 1;
62528679Sbrian	return cmds;
62626516Sbrian      }
6276059Samurai      nmatch++;
6286059Samurai      found = cmds;
62928679Sbrian    } else if (cmds->alias && strncasecmp(str, cmds->alias, len) == 0) {
63026516Sbrian      if (cmds->alias[len] == '\0') {
63128679Sbrian	*pmatch = 1;
63228679Sbrian	return cmds;
63326516Sbrian      }
6346059Samurai      nmatch++;
6356059Samurai      found = cmds;
6366059Samurai    }
6376059Samurai    cmds++;
6386059Samurai  }
6396059Samurai  *pmatch = nmatch;
64026516Sbrian  return found;
6416059Samurai}
6426059Samurai
64330715Sbrianstatic int
64428679SbrianFindExec(struct cmdtab const * cmdlist, int argc, char **argv)
6456059Samurai{
64628679Sbrian  struct cmdtab const *cmd;
6476059Samurai  int val = 1;
6486059Samurai  int nmatch;
6496059Samurai
6506059Samurai  cmd = FindCommand(cmdlist, *argv, &nmatch);
6516059Samurai  if (nmatch > 1)
65226516Sbrian    LogPrintf(LogWARN, "%s: Ambiguous command\n", *argv);
65328679Sbrian  else if (cmd && (cmd->lauth & VarLocalAuth))
65429257Sbrian    val = (cmd->func) (cmd, argc-1, argv+1, cmd->args);
6556059Samurai  else
65626516Sbrian    LogPrintf(LogWARN, "%s: Invalid command\n", *argv);
65726516Sbrian
65826516Sbrian  if (val == -1)
65926516Sbrian    LogPrintf(LogWARN, "Usage: %s\n", cmd->syntax);
66028679Sbrian  else if (val)
66126516Sbrian    LogPrintf(LogCOMMAND, "%s: Failed %d\n", *argv, val);
66226516Sbrian
66326516Sbrian  return val;
6646059Samurai}
6656059Samurai
66618885Sjkhint aft_cmd = 1;
66718885Sjkh
6686059Samuraivoid
66918885SjkhPrompt()
6706059Samurai{
6716735Samurai  char *pconnect, *pauth;
6726735Samurai
67331121Sbrian  if (!VarTerm || TermMode)
6746059Samurai    return;
6756735Samurai
67618885Sjkh  if (!aft_cmd)
67726516Sbrian    fprintf(VarTerm, "\n");
67818885Sjkh  else
67918885Sjkh    aft_cmd = 0;
6806735Samurai
68128679Sbrian  if (VarLocalAuth == LOCAL_AUTH)
6826735Samurai    pauth = " ON ";
6836735Samurai  else
6846735Samurai    pauth = " on ";
6856059Samurai  if (IpcpFsm.state == ST_OPENED && phase == PHASE_NETWORK)
6866735Samurai    pconnect = "PPP";
6876059Samurai  else
6886735Samurai    pconnect = "ppp";
68926516Sbrian  fprintf(VarTerm, "%s%s%s> ", pconnect, pauth, VarShortHost);
69026516Sbrian  fflush(VarTerm);
6916059Samurai}
6926059Samurai
6936059Samuraivoid
69431121SbrianInterpretCommand(char *buff, int nb, int *argc, char ***argv)
6956059Samurai{
69631121Sbrian  static char *vector[40];
6976059Samurai  char *cp;
6986059Samurai
6996059Samurai  if (nb > 0) {
7006059Samurai    cp = buff + strcspn(buff, "\r\n");
7016059Samurai    if (cp)
7026059Samurai      *cp = '\0';
70331121Sbrian    *argc = MakeArgs(buff, vector, VECSIZE(vector));
70431121Sbrian    *argv = vector;
70531121Sbrian  } else
70631121Sbrian    *argc = 0;
70731121Sbrian}
7086059Samurai
70931121Sbrianvoid
71031156SbrianRunCommand(int argc, char **argv, const char *label)
71131121Sbrian{
71231156Sbrian  if (argc > 0) {
71331156Sbrian    if (LogIsKept(LogCOMMAND)) {
71431156Sbrian      static char buf[LINE_LEN];
71531156Sbrian      int f, n;
71631156Sbrian
71731156Sbrian      *buf = '\0';
71831156Sbrian      if (label) {
71931156Sbrian        strcpy(buf, label);
72031156Sbrian        strcat(buf, ": ");
72131156Sbrian      }
72231156Sbrian      n = strlen(buf);
72331156Sbrian      for (f = 0; f < argc; f++) {
72431156Sbrian        if (n < sizeof(buf)-1 && f)
72531156Sbrian          buf[n++] = ' ';
72631156Sbrian        strncpy(buf+n, argv[f], sizeof(buf)-n-1);
72731156Sbrian        n += strlen(buf+n);
72831156Sbrian      }
72931156Sbrian      LogPrintf(LogCOMMAND, "%s\n", buf);
73031156Sbrian    }
73131121Sbrian    FindExec(Commands, argc, argv);
73231156Sbrian  }
7336059Samurai}
7346059Samurai
73531121Sbrianvoid
73631156SbrianDecodeCommand(char *buff, int nb, const char *label)
73731121Sbrian{
73831121Sbrian  int argc;
73931121Sbrian  char **argv;
74031121Sbrian
74131121Sbrian  InterpretCommand(buff, nb, &argc, &argv);
74231156Sbrian  RunCommand(argc, argv, label);
74331121Sbrian}
74431121Sbrian
7456059Samuraistatic int
74628679SbrianShowCommand(struct cmdtab const * list, int argc, char **argv)
7476059Samurai{
7486059Samurai  if (argc > 0)
74926516Sbrian    FindExec(ShowCommands, argc, argv);
75026516Sbrian  else if (VarTerm)
75126516Sbrian    fprintf(VarTerm, "Use ``show ?'' to get a list.\n");
7526059Samurai  else
75326516Sbrian    LogPrintf(LogWARN, "show command must have arguments\n");
75426516Sbrian
75526516Sbrian  return 0;
7566059Samurai}
7576059Samurai
7586059Samuraistatic int
75928679SbrianTerminalCommand(struct cmdtab const * list, int argc, char **argv)
7606059Samurai{
7616059Samurai  if (LcpFsm.state > ST_CLOSED) {
76226516Sbrian    if (VarTerm)
76326516Sbrian      fprintf(VarTerm, "LCP state is [%s]\n", StateNames[LcpFsm.state]);
76426516Sbrian    return 1;
7656059Samurai  }
76630913Sbrian  if (!IsInteractive(1))
76728679Sbrian    return (1);
76831034Sbrian  if (OpenModem() < 0) {
76926516Sbrian    if (VarTerm)
77026516Sbrian      fprintf(VarTerm, "Failed to open modem.\n");
77128679Sbrian    return (1);
7726059Samurai  }
77326516Sbrian  if (VarTerm) {
77426516Sbrian    fprintf(VarTerm, "Enter to terminal mode.\n");
77526516Sbrian    fprintf(VarTerm, "Type `~?' for help.\n");
77626516Sbrian  }
7776059Samurai  TtyTermMode();
77828679Sbrian  return (0);
7796059Samurai}
7806059Samurai
7816059Samuraistatic int
78228679SbrianQuitCommand(struct cmdtab const * list, int argc, char **argv)
7836059Samurai{
78426516Sbrian  FILE *oVarTerm;
78526516Sbrian
78631121Sbrian  if (mode & MODE_INTER)
7876059Samurai    Cleanup(EX_NORMAL);
78831121Sbrian  else if (argc > 0 && !strcasecmp(*argv, "all") &&
78931121Sbrian           (VarLocalAuth & LOCAL_AUTH)) {
79031121Sbrian    oVarTerm = VarTerm;
79131121Sbrian    VarTerm = 0;
79231121Sbrian    if (oVarTerm && oVarTerm != stdout)
79331121Sbrian      fclose(oVarTerm);
79431121Sbrian    close(netfd);
79531121Sbrian    netfd = -1;
79631121Sbrian    Cleanup(EX_NORMAL);
79731121Sbrian  } else if (VarTerm) {
79831121Sbrian    LogPrintf(LogPHASE, "Client connection closed.\n");
79931121Sbrian    oVarTerm = VarTerm;
80031121Sbrian    VarTerm = 0;
80131121Sbrian    if (oVarTerm && oVarTerm != stdout)
80231121Sbrian      fclose(oVarTerm);
80331121Sbrian    close(netfd);
80431121Sbrian    netfd = -1;
80531121Sbrian  }
80626516Sbrian
80726516Sbrian  return 0;
8086059Samurai}
8096059Samurai
8106059Samuraistatic int
81128679SbrianCloseCommand(struct cmdtab const * list, int argc, char **argv)
8126059Samurai{
81326098Sbrian  reconnect(RECON_FALSE);
8146059Samurai  LcpClose();
81526516Sbrian  return 0;
8166059Samurai}
8176059Samurai
8186059Samuraistatic int
81928679SbrianDownCommand(struct cmdtab const * list, int argc, char **argv)
8206059Samurai{
8216059Samurai  LcpDown();
82226516Sbrian  return 0;
8236059Samurai}
8246059Samurai
82525067Sbrianstatic int
82628679SbrianSetModemSpeed(struct cmdtab const * list, int argc, char **argv)
8276059Samurai{
8286059Samurai  int speed;
8296059Samurai
8306059Samurai  if (argc > 0) {
83129521Sbrian    if (strcasecmp(*argv, "sync") == 0) {
8326735Samurai      VarSpeed = 0;
83326516Sbrian      return 0;
8346735Samurai    }
8356059Samurai    speed = atoi(*argv);
8366735Samurai    if (IntToSpeed(speed) != B0) {
8376735Samurai      VarSpeed = speed;
83826516Sbrian      return 0;
8396059Samurai    }
84026516Sbrian    LogPrintf(LogWARN, "%s: Invalid speed\n", *argv);
8416059Samurai  }
84226516Sbrian  return -1;
8436059Samurai}
8446059Samurai
84525067Sbrianstatic int
84628679SbrianSetReconnect(struct cmdtab const * list, int argc, char **argv)
84711336Samurai{
84825067Sbrian  if (argc == 2) {
84925067Sbrian    VarReconnectTimer = atoi(argv[0]);
85025067Sbrian    VarReconnectTries = atoi(argv[1]);
85126516Sbrian    return 0;
85226516Sbrian  }
85326516Sbrian  return -1;
85425067Sbrian}
85525067Sbrian
85625067Sbrianstatic int
85728679SbrianSetRedialTimeout(struct cmdtab const * list, int argc, char **argv)
85825067Sbrian{
85911336Samurai  int timeout;
86011336Samurai  int tries;
86124939Sbrian  char *dot;
86211336Samurai
86328679Sbrian  if (argc == 1 || argc == 2) {
86424939Sbrian    if (strncasecmp(argv[0], "random", 6) == 0 &&
86524939Sbrian	(argv[0][6] == '\0' || argv[0][6] == '.')) {
86611336Samurai      VarRedialTimeout = -1;
86730715Sbrian      randinit();
86826516Sbrian    } else {
86911336Samurai      timeout = atoi(argv[0]);
87011336Samurai
87126516Sbrian      if (timeout >= 0)
87211336Samurai	VarRedialTimeout = timeout;
87311336Samurai      else {
87426516Sbrian	LogPrintf(LogWARN, "Invalid redial timeout\n");
87528679Sbrian	return -1;
87611336Samurai      }
87711336Samurai    }
87824939Sbrian
87930715Sbrian    dot = strchr(argv[0], '.');
88024939Sbrian    if (dot) {
88124939Sbrian      if (strcasecmp(++dot, "random") == 0) {
88228679Sbrian	VarRedialNextTimeout = -1;
88330715Sbrian	randinit();
88428679Sbrian      } else {
88528679Sbrian	timeout = atoi(dot);
88628679Sbrian	if (timeout >= 0)
88728679Sbrian	  VarRedialNextTimeout = timeout;
88828679Sbrian	else {
88928679Sbrian	  LogPrintf(LogWARN, "Invalid next redial timeout\n");
89026516Sbrian	  return -1;
89128679Sbrian	}
89224939Sbrian      }
89328679Sbrian    } else
89428679Sbrian      VarRedialNextTimeout = NEXT_REDIAL_PERIOD;	/* Default next timeout */
89524939Sbrian
89611336Samurai    if (argc == 2) {
89711336Samurai      tries = atoi(argv[1]);
89811336Samurai
89911336Samurai      if (tries >= 0) {
90026516Sbrian	VarDialTries = tries;
90126516Sbrian      } else {
90226516Sbrian	LogPrintf(LogWARN, "Invalid retry value\n");
90326516Sbrian	return 1;
90411336Samurai      }
90511336Samurai    }
90626516Sbrian    return 0;
90711336Samurai  }
90826516Sbrian  return -1;
90911336Samurai}
91011336Samurai
91125067Sbrianstatic int
91228679SbrianSetStoppedTimeout(struct cmdtab const * list, int argc, char **argv)
91328327Sbrian{
91428461Sbrian  LcpFsm.StoppedTimer.load = 0;
91528461Sbrian  IpcpFsm.StoppedTimer.load = 0;
91628461Sbrian  CcpFsm.StoppedTimer.load = 0;
91728461Sbrian  if (argc <= 3) {
91828461Sbrian    if (argc > 0) {
91928461Sbrian      LcpFsm.StoppedTimer.load = atoi(argv[0]) * SECTICKS;
92028461Sbrian      if (argc > 1) {
92128679Sbrian	IpcpFsm.StoppedTimer.load = atoi(argv[1]) * SECTICKS;
92228679Sbrian	if (argc > 2)
92328679Sbrian	  CcpFsm.StoppedTimer.load = atoi(argv[2]) * SECTICKS;
92428461Sbrian      }
92528461Sbrian    }
92628327Sbrian    return 0;
92728327Sbrian  }
92828327Sbrian  return -1;
92928327Sbrian}
93028327Sbrian
93131081Sbrian#define ismask(x) \
93231081Sbrian  (*x == '0' && strlen(x) == 4 && strspn(x+1, "0123456789.") == 3)
93331081Sbrian
93428327Sbrianstatic int
93528679SbrianSetServer(struct cmdtab const * list, int argc, char **argv)
93626940Sbrian{
93726940Sbrian  int res = -1;
93826940Sbrian
93931081Sbrian  if (argc > 0 && argc < 4) {
94031081Sbrian    const char *port, *passwd, *mask;
94131081Sbrian
94231081Sbrian    /* What's what ? */
94331081Sbrian    port = argv[0];
94431081Sbrian    if (argc == 2)
94531081Sbrian      if (ismask(argv[1])) {
94631081Sbrian        passwd = NULL;
94731081Sbrian        mask = argv[1];
94831081Sbrian      } else {
94931081Sbrian        passwd = argv[1];
95031081Sbrian        mask = NULL;
95131081Sbrian      }
95231081Sbrian    else if (argc == 3) {
95331081Sbrian      passwd = argv[1];
95431081Sbrian      mask = argv[2];
95531081Sbrian      if (!ismask(mask))
95631081Sbrian        return -1;
95731081Sbrian    } else
95831081Sbrian      passwd = mask = NULL;
95931081Sbrian
96031081Sbrian    if (passwd == NULL)
96131081Sbrian      VarHaveLocalAuthKey = 0;
96231081Sbrian    else {
96331081Sbrian      strncpy(VarLocalAuthKey, passwd, sizeof VarLocalAuthKey);
96431081Sbrian      VarLocalAuthKey[sizeof VarLocalAuthKey - 1] = '\0';
96531081Sbrian      VarHaveLocalAuthKey = 1;
96631081Sbrian    }
96731081Sbrian    LocalAuthInit();
96831081Sbrian
96931081Sbrian    if (strcasecmp(port, "none") == 0) {
97031081Sbrian      int oserver;
97131081Sbrian
97231081Sbrian      if (mask != NULL || passwd != NULL)
97331081Sbrian        return -1;
97431081Sbrian      oserver = server;
97526940Sbrian      ServerClose();
97631081Sbrian      if (oserver != -1)
97731081Sbrian        LogPrintf(LogPHASE, "Disabling server port.\n");
97826940Sbrian      res = 0;
97931081Sbrian    } else if (*port == '/') {
98031081Sbrian      mode_t imask;
98128679Sbrian
98231081Sbrian      if (mask != NULL) {
98328679Sbrian	unsigned m;
98428679Sbrian
98531081Sbrian	if (sscanf(mask, "%o", &m) == 1)
98631081Sbrian	  imask = m;
98731081Sbrian        else
98831081Sbrian          return -1;
98931081Sbrian      } else
99031081Sbrian        imask = (mode_t)-1;
99131081Sbrian      res = ServerLocalOpen(port, imask);
99227346Sbrian    } else {
99331081Sbrian      int iport;
99428679Sbrian
99531081Sbrian      if (mask != NULL)
99631081Sbrian        return -1;
99728679Sbrian
99831081Sbrian      if (strspn(port, "0123456789") != strlen(port)) {
99931081Sbrian        struct servent *s;
100031081Sbrian
100131081Sbrian        if ((s = getservbyname(port, "tcp")) == NULL) {
100231081Sbrian	  iport = 0;
100331081Sbrian	  LogPrintf(LogWARN, "%s: Invalid port or service\n", port);
100428679Sbrian	} else
100531081Sbrian	  iport = ntohs(s->s_port);
100627346Sbrian      } else
100731081Sbrian        iport = atoi(port);
100831081Sbrian      res = iport ? ServerTcpOpen(iport) : -1;
100927346Sbrian    }
101031081Sbrian  }
101126940Sbrian
101226940Sbrian  return res;
101326940Sbrian}
101426940Sbrian
101526940Sbrianstatic int
101628679SbrianSetModemParity(struct cmdtab const * list, int argc, char **argv)
10176059Samurai{
101826845Sbrian  return argc > 0 ? ChangeParity(*argv) : -1;
10196059Samurai}
10206059Samurai
10216059Samuraistatic int
102228679SbrianSetLogLevel(struct cmdtab const * list, int argc, char **argv)
10236059Samurai{
102426516Sbrian  int i;
102526516Sbrian  int res;
102626516Sbrian  char *arg;
102730913Sbrian  void (*Discard)(int), (*Keep)(int);
102830913Sbrian  void (*DiscardAll)(void);
10296059Samurai
103026516Sbrian  res = 0;
103130913Sbrian  if (strcasecmp(argv[0], "local")) {
103230913Sbrian    Discard = LogDiscard;
103330913Sbrian    Keep = LogKeep;
103430913Sbrian    DiscardAll = LogDiscardAll;
103530913Sbrian  } else {
103630913Sbrian    argc--;
103730913Sbrian    argv++;
103830913Sbrian    Discard = LogDiscardLocal;
103930913Sbrian    Keep = LogKeepLocal;
104030913Sbrian    DiscardAll = LogDiscardAllLocal;
104130913Sbrian  }
104230913Sbrian
104326516Sbrian  if (argc == 0 || (argv[0][0] != '+' && argv[0][0] != '-'))
104430913Sbrian    (*DiscardAll)();
104526516Sbrian  while (argc--) {
104626516Sbrian    arg = **argv == '+' || **argv == '-' ? *argv + 1 : *argv;
104726516Sbrian    for (i = LogMIN; i <= LogMAX; i++)
104826516Sbrian      if (strcasecmp(arg, LogName(i)) == 0) {
104928679Sbrian	if (**argv == '-')
105030913Sbrian	  (*Discard)(i);
105128679Sbrian	else
105230913Sbrian	  (*Keep)(i);
10536059Samurai	break;
10546059Samurai      }
105526516Sbrian    if (i > LogMAX) {
105626516Sbrian      LogPrintf(LogWARN, "%s: Invalid log value\n", arg);
105726516Sbrian      res = -1;
10586059Samurai    }
105926516Sbrian    argv++;
10606059Samurai  }
106126516Sbrian  return res;
10626059Samurai}
10636059Samurai
10646059Samuraistatic int
106528679SbrianSetEscape(struct cmdtab const * list, int argc, char **argv)
10666059Samurai{
10676059Samurai  int code;
10686059Samurai
10696059Samurai  for (code = 0; code < 33; code++)
10706059Samurai    EscMap[code] = 0;
10716059Samurai  while (argc-- > 0) {
10726059Samurai    sscanf(*argv++, "%x", &code);
10736059Samurai    code &= 0xff;
107428679Sbrian    EscMap[code >> 3] |= (1 << (code & 7));
10756059Samurai    EscMap[32] = 1;
10766059Samurai  }
107726516Sbrian  return 0;
10786059Samurai}
10796059Samurai
10806059Samuraistatic int
108128679SbrianSetInitialMRU(struct cmdtab const * list, int argc, char **argv)
10826059Samurai{
108326326Sbrian  long mru;
108426516Sbrian  char *err;
10856059Samurai
10866059Samurai  if (argc > 0) {
108726326Sbrian    mru = atol(*argv);
108826326Sbrian    if (mru < MIN_MRU)
108926516Sbrian      err = "Given MRU value (%ld) is too small.\n";
10906059Samurai    else if (mru > MAX_MRU)
109126516Sbrian      err = "Given MRU value (%ld) is too big.\n";
109226516Sbrian    else {
10936059Samurai      VarMRU = mru;
109426516Sbrian      return 0;
109526516Sbrian    }
109626516Sbrian    LogPrintf(LogWARN, err, mru);
109726516Sbrian  }
109826516Sbrian  return -1;
10996059Samurai}
11006059Samurai
11016059Samuraistatic int
110228679SbrianSetPreferredMTU(struct cmdtab const * list, int argc, char **argv)
110326326Sbrian{
110426326Sbrian  long mtu;
110526516Sbrian  char *err;
110626326Sbrian
110726326Sbrian  if (argc > 0) {
110826326Sbrian    mtu = atol(*argv);
110926516Sbrian    if (mtu == 0) {
111026326Sbrian      VarPrefMTU = 0;
111126516Sbrian      return 0;
111226516Sbrian    } else if (mtu < MIN_MTU)
111326516Sbrian      err = "Given MTU value (%ld) is too small.\n";
111426326Sbrian    else if (mtu > MAX_MTU)
111526516Sbrian      err = "Given MTU value (%ld) is too big.\n";
111626516Sbrian    else {
111726326Sbrian      VarPrefMTU = mtu;
111826516Sbrian      return 0;
111926516Sbrian    }
112026516Sbrian    LogPrintf(LogWARN, err, mtu);
112126516Sbrian  }
112226516Sbrian  return -1;
112326326Sbrian}
112426326Sbrian
112526326Sbrianstatic int
112628679SbrianSetIdleTimeout(struct cmdtab const * list, int argc, char **argv)
11276059Samurai{
11286059Samurai  if (argc-- > 0) {
11296059Samurai    VarIdleTimeout = atoi(*argv++);
113028679Sbrian    UpdateIdleTimer();		/* If we're connected, restart the idle timer */
11316735Samurai    if (argc-- > 0) {
11326735Samurai      VarLqrTimeout = atoi(*argv++);
11336735Samurai      if (VarLqrTimeout < 1)
11346735Samurai	VarLqrTimeout = 30;
11356735Samurai      if (argc > 0) {
11366735Samurai	VarRetryTimeout = atoi(*argv);
11376735Samurai	if (VarRetryTimeout < 1 || VarRetryTimeout > 10)
11386735Samurai	  VarRetryTimeout = 3;
11396735Samurai      }
11406735Samurai    }
114126516Sbrian    return 0;
11426059Samurai  }
114326516Sbrian  return -1;
11446059Samurai}
11456059Samurai
114630715Sbrianstatic struct in_addr
114728679SbrianGetIpAddr(char *cp)
11486059Samurai{
11496059Samurai  struct hostent *hp;
11506059Samurai  struct in_addr ipaddr;
11516059Samurai
11526059Samurai  hp = gethostbyname(cp);
11536059Samurai  if (hp && hp->h_addrtype == AF_INET)
115430715Sbrian    memcpy(&ipaddr, hp->h_addr, hp->h_length);
11556059Samurai  else if (inet_aton(cp, &ipaddr) == 0)
11566059Samurai    ipaddr.s_addr = 0;
115728679Sbrian  return (ipaddr);
11586059Samurai}
11596059Samurai
11606059Samuraistatic int
116128679SbrianSetInterfaceAddr(struct cmdtab const * list, int argc, char **argv)
11626059Samurai{
116328394Sbrian  DefMyAddress.ipaddr.s_addr = DefHisAddress.ipaddr.s_addr = 0L;
11646059Samurai
116526516Sbrian  if (argc > 4)
116628679Sbrian    return -1;
116726516Sbrian
116828394Sbrian  HaveTriggerAddress = 0;
116928394Sbrian  ifnetmask.s_addr = 0;
117028394Sbrian
11716059Samurai  if (argc > 0) {
117225630Sbrian    if (ParseAddr(argc, argv++,
117328679Sbrian		  &DefMyAddress.ipaddr,
117428679Sbrian		  &DefMyAddress.mask,
117528679Sbrian		  &DefMyAddress.width) == 0)
117628679Sbrian      return 1;
11776059Samurai    if (--argc > 0) {
117825630Sbrian      if (ParseAddr(argc, argv++,
117925630Sbrian		    &DefHisAddress.ipaddr,
118025630Sbrian		    &DefHisAddress.mask,
118125630Sbrian		    &DefHisAddress.width) == 0)
118228679Sbrian	return 2;
11836059Samurai      if (--argc > 0) {
118428679Sbrian	ifnetmask = GetIpAddr(*argv);
118528679Sbrian	if (--argc > 0) {
118628679Sbrian	  TriggerAddress = GetIpAddr(*argv);
118728679Sbrian	  HaveTriggerAddress = 1;
11889440Samurai	}
11896059Samurai      }
11906059Samurai    }
11916059Samurai  }
119228394Sbrian
11936059Samurai  /*
11946059Samurai   * For backwards compatibility, 0.0.0.0 means any address.
11956059Samurai   */
11966059Samurai  if (DefMyAddress.ipaddr.s_addr == 0) {
11976059Samurai    DefMyAddress.mask.s_addr = 0;
11986059Samurai    DefMyAddress.width = 0;
11996059Samurai  }
12006059Samurai  if (DefHisAddress.ipaddr.s_addr == 0) {
12016059Samurai    DefHisAddress.mask.s_addr = 0;
12026059Samurai    DefHisAddress.width = 0;
12036059Samurai  }
120428537Sbrian  IpcpInfo.want_ipaddr.s_addr = DefMyAddress.ipaddr.s_addr;
120528537Sbrian  IpcpInfo.his_ipaddr.s_addr = DefHisAddress.ipaddr.s_addr;
120628537Sbrian
120731121Sbrian  if ((mode & MODE_AUTO) &&
120831121Sbrian      OsSetIpaddress(DefMyAddress.ipaddr, DefHisAddress.ipaddr, ifnetmask) < 0)
120931121Sbrian    return 4;
121031121Sbrian
121126516Sbrian  return 0;
12126059Samurai}
12136059Samurai
121426516Sbrian#ifndef NOMSEXT
12156059Samurai
121630715Sbrianstatic void
121728679SbrianSetMSEXT(struct in_addr * pri_addr,
121828679Sbrian	 struct in_addr * sec_addr,
121928679Sbrian	 int argc,
122028679Sbrian	 char **argv)
122118752Sjkh{
122218752Sjkh  int dummyint;
122318752Sjkh  struct in_addr dummyaddr;
122418752Sjkh
122518752Sjkh  pri_addr->s_addr = sec_addr->s_addr = 0L;
122618752Sjkh
122728679Sbrian  if (argc > 0) {
122818752Sjkh    ParseAddr(argc, argv++, pri_addr, &dummyaddr, &dummyint);
122928679Sbrian    if (--argc > 0)
123018752Sjkh      ParseAddr(argc, argv++, sec_addr, &dummyaddr, &dummyint);
123118752Sjkh    else
123218752Sjkh      sec_addr->s_addr = pri_addr->s_addr;
123318752Sjkh  }
123418752Sjkh
123528679Sbrian  /*
123628679Sbrian   * if the primary/secondary ns entries are 0.0.0.0 we should set them to
123728679Sbrian   * either the localhost's ip, or the values in /etc/resolv.conf ??
123828679Sbrian   *
123928679Sbrian   * up to you if you want to implement this...
124028679Sbrian   */
124118752Sjkh
124218752Sjkh}
124318752Sjkh
124418752Sjkhstatic int
124528679SbrianSetNS(struct cmdtab const * list, int argc, char **argv)
124618752Sjkh{
124718752Sjkh  SetMSEXT(&ns_entries[0], &ns_entries[1], argc, argv);
124826516Sbrian  return 0;
124918752Sjkh}
125018752Sjkh
125118752Sjkhstatic int
125228679SbrianSetNBNS(struct cmdtab const * list, int argc, char **argv)
125318752Sjkh{
125418752Sjkh  SetMSEXT(&nbns_entries[0], &nbns_entries[1], argc, argv);
125526516Sbrian  return 0;
125618752Sjkh}
125718752Sjkh
125828679Sbrian#endif				/* MS_EXT */
125918752Sjkh
126029696Sbrianint
126128679SbrianSetVariable(struct cmdtab const * list, int argc, char **argv, int param)
12626059Samurai{
12636059Samurai  u_long map;
126426551Sbrian  char *arg;
12656059Samurai
126626551Sbrian  if (argc > 0)
126726551Sbrian    arg = *argv;
126826551Sbrian  else
126926551Sbrian    arg = "";
127026551Sbrian
127126551Sbrian  switch (param) {
127228679Sbrian  case VAR_AUTHKEY:
127328679Sbrian    strncpy(VarAuthKey, arg, sizeof(VarAuthKey) - 1);
127428679Sbrian    VarAuthKey[sizeof(VarAuthKey) - 1] = '\0';
127528679Sbrian    break;
127628679Sbrian  case VAR_AUTHNAME:
127728679Sbrian    strncpy(VarAuthName, arg, sizeof(VarAuthName) - 1);
127828679Sbrian    VarAuthName[sizeof(VarAuthName) - 1] = '\0';
127928679Sbrian    break;
128028679Sbrian  case VAR_DIAL:
128128679Sbrian    strncpy(VarDialScript, arg, sizeof(VarDialScript) - 1);
128228679Sbrian    VarDialScript[sizeof(VarDialScript) - 1] = '\0';
128328679Sbrian    break;
128428679Sbrian  case VAR_LOGIN:
128528679Sbrian    strncpy(VarLoginScript, arg, sizeof(VarLoginScript) - 1);
128628679Sbrian    VarLoginScript[sizeof(VarLoginScript) - 1] = '\0';
128728679Sbrian    break;
128828679Sbrian  case VAR_DEVICE:
128929696Sbrian    if (modem != -1)
129029696Sbrian      LogPrintf(LogWARN, "Cannot change device to \"%s\" when \"%s\" is open\n",
129129696Sbrian                arg, VarDevice);
129229696Sbrian    else {
129329696Sbrian      strncpy(VarDevice, arg, sizeof(VarDevice) - 1);
129429696Sbrian      VarDevice[sizeof(VarDevice) - 1] = '\0';
129530715Sbrian      VarBaseDevice = strrchr(VarDevice, '/');
129629696Sbrian      VarBaseDevice = VarBaseDevice ? VarBaseDevice + 1 : "";
129729696Sbrian    }
129828679Sbrian    break;
129928679Sbrian  case VAR_ACCMAP:
130028679Sbrian    sscanf(arg, "%lx", &map);
130128679Sbrian    VarAccmap = map;
130228679Sbrian    break;
130328679Sbrian  case VAR_PHONE:
130428679Sbrian    strncpy(VarPhoneList, arg, sizeof(VarPhoneList) - 1);
130528679Sbrian    VarPhoneList[sizeof(VarPhoneList) - 1] = '\0';
130628679Sbrian    strcpy(VarPhoneCopy, VarPhoneList);
130728679Sbrian    VarNextPhone = VarPhoneCopy;
130831082Sbrian    VarAltPhone = NULL;
130928679Sbrian    break;
131028679Sbrian  case VAR_HANGUP:
131128679Sbrian    strncpy(VarHangupScript, arg, sizeof(VarHangupScript) - 1);
131228679Sbrian    VarHangupScript[sizeof(VarHangupScript) - 1] = '\0';
131328679Sbrian    break;
131429840Sbrian#ifdef HAVE_DES
131529549Sbrian  case VAR_ENC:
131629840Sbrian    VarMSChap = !strcasecmp(arg, "mschap");
131729549Sbrian    break;
131829840Sbrian#endif
13196059Samurai  }
132026516Sbrian  return 0;
13216059Samurai}
13226059Samurai
132328679Sbrianstatic int
132428679SbrianSetCtsRts(struct cmdtab const * list, int argc, char **argv)
132520812Sjkh{
132620812Sjkh  if (argc > 0) {
132720812Sjkh    if (strcmp(*argv, "on") == 0)
132830715Sbrian      VarCtsRts = 1;
132920812Sjkh    else if (strcmp(*argv, "off") == 0)
133030715Sbrian      VarCtsRts = 0;
133120812Sjkh    else
133226516Sbrian      return -1;
133326516Sbrian    return 0;
133420812Sjkh  }
133526516Sbrian  return -1;
133620812Sjkh}
133720812Sjkh
133820812Sjkh
133928679Sbrianstatic int
134028679SbrianSetOpenMode(struct cmdtab const * list, int argc, char **argv)
13416059Samurai{
13426059Samurai  if (argc > 0) {
13436059Samurai    if (strcmp(*argv, "active") == 0)
13446059Samurai      VarOpenMode = OPEN_ACTIVE;
13456059Samurai    else if (strcmp(*argv, "passive") == 0)
13466059Samurai      VarOpenMode = OPEN_PASSIVE;
13476059Samurai    else
134826516Sbrian      return -1;
134926516Sbrian    return 0;
13506059Samurai  }
135126516Sbrian  return -1;
13526059Samurai}
13536059Samurai
135430715Sbrianstatic struct cmdtab const SetCommands[] = {
135528679Sbrian  {"accmap", NULL, SetVariable, LOCAL_AUTH,
135628679Sbrian  "Set accmap value", "set accmap hex-value", (void *) VAR_ACCMAP},
135728679Sbrian  {"afilter", NULL, SetAfilter, LOCAL_AUTH,
135828679Sbrian  "Set keep Alive filter", "set afilter ..."},
135928679Sbrian  {"authkey", "key", SetVariable, LOCAL_AUTH,
136028679Sbrian  "Set authentication key", "set authkey|key key", (void *) VAR_AUTHKEY},
136128679Sbrian  {"authname", NULL, SetVariable, LOCAL_AUTH,
136228679Sbrian  "Set authentication name", "set authname name", (void *) VAR_AUTHNAME},
136328679Sbrian  {"ctsrts", NULL, SetCtsRts, LOCAL_AUTH,
136428679Sbrian  "Use CTS/RTS modem signalling", "set ctsrts [on|off]"},
136528679Sbrian  {"device", "line", SetVariable, LOCAL_AUTH,
136628679Sbrian  "Set modem device name", "set device|line device-name", (void *) VAR_DEVICE},
136728679Sbrian  {"dfilter", NULL, SetDfilter, LOCAL_AUTH,
136828679Sbrian  "Set demand filter", "set dfilter ..."},
136928679Sbrian  {"dial", NULL, SetVariable, LOCAL_AUTH,
137028679Sbrian  "Set dialing script", "set dial chat-script", (void *) VAR_DIAL},
137129840Sbrian#ifdef HAVE_DES
137229549Sbrian  {"encrypt", NULL, SetVariable, LOCAL_AUTH,
137329840Sbrian  "Set CHAP encryption algorithm", "set encrypt MSChap|MD5", (void *) VAR_ENC},
137429840Sbrian#endif
137528679Sbrian  {"escape", NULL, SetEscape, LOCAL_AUTH,
137628679Sbrian  "Set escape characters", "set escape hex-digit ..."},
137728679Sbrian  {"hangup", NULL, SetVariable, LOCAL_AUTH,
137828679Sbrian  "Set hangup script", "set hangup chat-script", (void *) VAR_HANGUP},
137928679Sbrian  {"ifaddr", NULL, SetInterfaceAddr, LOCAL_AUTH,
138028679Sbrian  "Set destination address", "set ifaddr [src-addr [dst-addr [netmask [trg-addr]]]]"},
138128679Sbrian  {"ifilter", NULL, SetIfilter, LOCAL_AUTH,
138228679Sbrian  "Set input filter", "set ifilter ..."},
138328679Sbrian  {"loopback", NULL, SetLoopback, LOCAL_AUTH,
138428679Sbrian  "Set loopback facility", "set loopback on|off"},
138528679Sbrian  {"log", NULL, SetLogLevel, LOCAL_AUTH,
138630913Sbrian  "Set log level", "set log [local] [+|-]value..."},
138728679Sbrian  {"login", NULL, SetVariable, LOCAL_AUTH,
138828679Sbrian  "Set login script", "set login chat-script", (void *) VAR_LOGIN},
138928679Sbrian  {"mru", NULL, SetInitialMRU, LOCAL_AUTH,
139028679Sbrian  "Set Initial MRU value", "set mru value"},
139128679Sbrian  {"mtu", NULL, SetPreferredMTU, LOCAL_AUTH,
139228679Sbrian  "Set Preferred MTU value", "set mtu value"},
139328679Sbrian  {"ofilter", NULL, SetOfilter, LOCAL_AUTH,
139428679Sbrian  "Set output filter", "set ofilter ..."},
139528679Sbrian  {"openmode", NULL, SetOpenMode, LOCAL_AUTH,
139628679Sbrian  "Set open mode", "set openmode [active|passive]"},
139728679Sbrian  {"parity", NULL, SetModemParity, LOCAL_AUTH,
139828679Sbrian  "Set modem parity", "set parity [odd|even|none]"},
139928679Sbrian  {"phone", NULL, SetVariable, LOCAL_AUTH,
140028679Sbrian  "Set telephone number(s)", "set phone phone1[:phone2[...]]", (void *) VAR_PHONE},
140128679Sbrian  {"reconnect", NULL, SetReconnect, LOCAL_AUTH,
140228679Sbrian  "Set Reconnect timeout", "set reconnect value ntries"},
140328679Sbrian  {"redial", NULL, SetRedialTimeout, LOCAL_AUTH,
140428679Sbrian  "Set Redial timeout", "set redial value|random[.value|random] [dial_attempts]"},
140528679Sbrian  {"stopped", NULL, SetStoppedTimeout, LOCAL_AUTH,
140628679Sbrian  "Set STOPPED timeouts", "set stopped [LCPseconds [IPCPseconds [CCPseconds]]]"},
140728679Sbrian  {"server", "socket", SetServer, LOCAL_AUTH,
140828679Sbrian  "Set server port", "set server|socket TcpPort|LocalName|none [mask]"},
140928679Sbrian  {"speed", NULL, SetModemSpeed, LOCAL_AUTH,
141028679Sbrian  "Set modem speed", "set speed value"},
141128679Sbrian  {"timeout", NULL, SetIdleTimeout, LOCAL_AUTH,
141228679Sbrian  "Set Idle timeout", "set timeout value"},
141326516Sbrian#ifndef NOMSEXT
141428679Sbrian  {"ns", NULL, SetNS, LOCAL_AUTH,
141528679Sbrian  "Set NameServer", "set ns pri-addr [sec-addr]"},
141628679Sbrian  {"nbns", NULL, SetNBNS, LOCAL_AUTH,
141728679Sbrian  "Set NetBIOS NameServer", "set nbns pri-addr [sec-addr]"},
141826516Sbrian#endif
141928679Sbrian  {"help", "?", HelpCommand, LOCAL_AUTH | LOCAL_NO_AUTH,
142028679Sbrian  "Display this message", "set help|? [command]", (void *) SetCommands},
142128679Sbrian  {NULL, NULL, NULL},
14226059Samurai};
14236059Samurai
14246059Samuraistatic int
142528679SbrianSetCommand(struct cmdtab const * list, int argc, char **argv)
14266059Samurai{
14276059Samurai  if (argc > 0)
142826516Sbrian    FindExec(SetCommands, argc, argv);
142926516Sbrian  else if (VarTerm)
143026516Sbrian    fprintf(VarTerm, "Use `set ?' to get a list or `set ? <var>' for"
143126516Sbrian	    " syntax help.\n");
14326059Samurai  else
143326516Sbrian    LogPrintf(LogWARN, "set command must have arguments\n");
143426516Sbrian
143526516Sbrian  return 0;
14366059Samurai}
14376059Samurai
14386059Samurai
14396059Samuraistatic int
144028679SbrianAddCommand(struct cmdtab const * list, int argc, char **argv)
14416059Samurai{
14426059Samurai  struct in_addr dest, gateway, netmask;
14436059Samurai
14446059Samurai  if (argc == 3) {
144527011Sbrian    if (strcasecmp(argv[0], "MYADDR") == 0)
144627011Sbrian      dest = IpcpInfo.want_ipaddr;
144727011Sbrian    else
144827011Sbrian      dest = GetIpAddr(argv[0]);
14496059Samurai    netmask = GetIpAddr(argv[1]);
145025566Sbrian    if (strcasecmp(argv[2], "HISADDR") == 0)
14516059Samurai      gateway = IpcpInfo.his_ipaddr;
14526059Samurai    else
14536059Samurai      gateway = GetIpAddr(argv[2]);
14546059Samurai    OsSetRoute(RTM_ADD, dest, gateway, netmask);
145526516Sbrian    return 0;
14566059Samurai  }
145726516Sbrian  return -1;
14586059Samurai}
14596059Samurai
14606059Samuraistatic int
146128679SbrianDeleteCommand(struct cmdtab const * list, int argc, char **argv)
14626059Samurai{
14636059Samurai  struct in_addr dest, gateway, netmask;
14646059Samurai
146526591Sbrian  if (argc == 1 && strcasecmp(argv[0], "all") == 0)
146626591Sbrian    DeleteIfRoutes(0);
146726591Sbrian  else if (argc > 0 && argc < 4) {
146827011Sbrian    if (strcasecmp(argv[0], "MYADDR") == 0)
146927011Sbrian      dest = IpcpInfo.want_ipaddr;
147027011Sbrian    else
147127011Sbrian      dest = GetIpAddr(argv[0]);
147226591Sbrian    netmask.s_addr = INADDR_ANY;
147326591Sbrian    if (argc > 1) {
147426591Sbrian      if (strcasecmp(argv[1], "HISADDR") == 0)
147528679Sbrian	gateway = IpcpInfo.his_ipaddr;
147626591Sbrian      else
147728679Sbrian	gateway = GetIpAddr(argv[1]);
147826591Sbrian      if (argc == 3) {
147928679Sbrian	if (inet_aton(argv[2], &netmask) == 0) {
148026591Sbrian	  LogPrintf(LogWARN, "Bad netmask value.\n");
148126591Sbrian	  return -1;
148228679Sbrian	}
14836059Samurai      }
148426591Sbrian    } else
148526591Sbrian      gateway.s_addr = INADDR_ANY;
14866059Samurai    OsSetRoute(RTM_DELETE, dest, gateway, netmask);
148726516Sbrian  } else
148826516Sbrian    return -1;
148926516Sbrian
149026516Sbrian  return 0;
14916059Samurai}
14926059Samurai
149326031Sbrianstatic struct cmdtab const AliasCommands[] =
149426031Sbrian{
149528679Sbrian  {"enable", NULL, AliasEnable, LOCAL_AUTH,
149628679Sbrian  "enable IP aliasing", "alias enable [yes|no]"},
149728679Sbrian  {"port", NULL, AliasRedirectPort, LOCAL_AUTH,
149828679Sbrian  "port redirection", "alias port [proto addr_local:port_local  port_alias]"},
149928679Sbrian  {"addr", NULL, AliasRedirectAddr, LOCAL_AUTH,
150028679Sbrian  "static address translation", "alias addr [addr_local addr_alias]"},
150128679Sbrian  {"deny_incoming", NULL, AliasOption, LOCAL_AUTH,
150228679Sbrian    "stop incoming connections", "alias deny_incoming [yes|no]",
150328679Sbrian  (void *) PKT_ALIAS_DENY_INCOMING},
150428679Sbrian  {"log", NULL, AliasOption, LOCAL_AUTH,
150528679Sbrian    "log aliasing link creation", "alias log [yes|no]",
150628679Sbrian  (void *) PKT_ALIAS_LOG},
150728679Sbrian  {"same_ports", NULL, AliasOption, LOCAL_AUTH,
150828679Sbrian    "try to leave port numbers unchanged", "alias same_ports [yes|no]",
150928679Sbrian  (void *) PKT_ALIAS_SAME_PORTS},
151028679Sbrian  {"use_sockets", NULL, AliasOption, LOCAL_AUTH,
151128679Sbrian    "allocate host sockets", "alias use_sockets [yes|no]",
151228679Sbrian  (void *) PKT_ALIAS_USE_SOCKETS},
151328679Sbrian  {"unregistered_only", NULL, AliasOption, LOCAL_AUTH,
151428679Sbrian    "alias unregistered (private) IP address space only",
151528679Sbrian    "alias unregistered_only [yes|no]",
151628679Sbrian  (void *) PKT_ALIAS_UNREGISTERED_ONLY},
151728679Sbrian  {"help", "?", HelpCommand, LOCAL_AUTH | LOCAL_NO_AUTH,
151828679Sbrian    "Display this message", "alias help|? [command]",
151928679Sbrian  (void *) AliasCommands},
152028679Sbrian  {NULL, NULL, NULL},
152126031Sbrian};
152226031Sbrian
152326031Sbrian
152426031Sbrianstatic int
152528679SbrianAliasCommand(struct cmdtab const * list, int argc, char **argv)
152626031Sbrian{
152726031Sbrian  if (argc > 0)
152826516Sbrian    FindExec(AliasCommands, argc, argv);
152926516Sbrian  else if (VarTerm)
153026516Sbrian    fprintf(VarTerm, "Use `alias help' to get a list or `alias help <option>'"
153126516Sbrian	    " for syntax help.\n");
153226031Sbrian  else
153326516Sbrian    LogPrintf(LogWARN, "alias command must have arguments\n");
153426516Sbrian
153526516Sbrian  return 0;
153626031Sbrian}
153726031Sbrian
153826031Sbrianstatic int
153928679SbrianAliasEnable(struct cmdtab const * list, int argc, char **argv)
154026031Sbrian{
154126516Sbrian  if (argc == 1)
154226516Sbrian    if (strcasecmp(argv[0], "yes") == 0) {
154326516Sbrian      if (!(mode & MODE_ALIAS)) {
154428679Sbrian	if (loadAliasHandlers(&VarAliasHandlers) == 0) {
154528679Sbrian	  mode |= MODE_ALIAS;
154628679Sbrian	  return 0;
154728679Sbrian	}
154828679Sbrian	LogPrintf(LogWARN, "Cannot load alias library\n");
154928679Sbrian	return 1;
155026516Sbrian      }
155126516Sbrian      return 0;
155226516Sbrian    } else if (strcasecmp(argv[0], "no") == 0) {
155326516Sbrian      if (mode & MODE_ALIAS) {
155428679Sbrian	unloadAliasHandlers();
155528679Sbrian	mode &= ~MODE_ALIAS;
155626516Sbrian      }
155726516Sbrian      return 0;
155826142Sbrian    }
155926516Sbrian  return -1;
156026031Sbrian}
156126031Sbrian
156226031Sbrian
156326031Sbrianstatic int
156428679SbrianAliasOption(struct cmdtab const * list, int argc, char **argv, void *param)
156526031Sbrian{
156628679Sbrian  if (argc == 1)
156728679Sbrian    if (strcasecmp(argv[0], "yes") == 0) {
156828679Sbrian      if (mode & MODE_ALIAS) {
156928679Sbrian	VarPacketAliasSetMode((unsigned) param, (unsigned) param);
157028679Sbrian	return 0;
157128679Sbrian      }
157228679Sbrian      LogPrintf(LogWARN, "alias not enabled\n");
157328679Sbrian    } else if (strcmp(argv[0], "no") == 0) {
157428679Sbrian      if (mode & MODE_ALIAS) {
157528679Sbrian	VarPacketAliasSetMode(0, (unsigned) param);
157628679Sbrian	return 0;
157728679Sbrian      }
157828679Sbrian      LogPrintf(LogWARN, "alias not enabled\n");
157928679Sbrian    }
158028679Sbrian  return -1;
158126031Sbrian}
158231121Sbrian
158331121Sbrianstatic struct cmdtab const AllowCommands[] = {
158431121Sbrian  {"users", "user", AllowUsers, LOCAL_AUTH,
158531121Sbrian  "Allow users access to ppp", "allow users logname..."},
158631121Sbrian  {"modes", "mode", AllowModes, LOCAL_AUTH,
158731121Sbrian  "Only allow certain ppp modes", "allow modes mode..."},
158831121Sbrian  {"help", "?", HelpCommand, LOCAL_AUTH | LOCAL_NO_AUTH,
158931121Sbrian  "Display this message", "allow help|? [command]", (void *)AllowCommands},
159031121Sbrian  {NULL, NULL, NULL},
159131121Sbrian};
159231121Sbrian
159331121Sbrianstatic int
159431121SbrianAllowCommand(struct cmdtab const *list, int argc, char **argv)
159531121Sbrian{
159631121Sbrian  if (argc > 0)
159731121Sbrian    FindExec(AllowCommands, argc, argv);
159831121Sbrian  else if (VarTerm)
159931121Sbrian    fprintf(VarTerm, "Use `allow ?' to get a list or `allow ? <cmd>' for"
160031121Sbrian	    " syntax help.\n");
160131121Sbrian  else
160231121Sbrian    LogPrintf(LogWARN, "allow command must have arguments\n");
160331121Sbrian
160431121Sbrian  return 0;
160531121Sbrian}
1606