command.c revision 31962
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 *
2031962Sbrian * $Id: command.c,v 1.117 1997/12/23 22:38:52 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
3231343Sbrian#ifndef NOALIAS
3326031Sbrian#include <alias.h>
3431343Sbrian#endif
3530715Sbrian#include <ctype.h>
3630715Sbrian#include <errno.h>
3726516Sbrian#include <fcntl.h>
3830715Sbrian#include <paths.h>
3930715Sbrian#include <stdio.h>
4030715Sbrian#include <stdlib.h>
4130715Sbrian#include <string.h>
4230715Sbrian#include <sys/stat.h>
4330715Sbrian#include <sys/wait.h>
4430715Sbrian#include <termios.h>
4530715Sbrian#include <time.h>
4630715Sbrian#include <unistd.h>
4730715Sbrian
4831343Sbrian#include "command.h"
4930715Sbrian#include "mbuf.h"
5030715Sbrian#include "log.h"
5130715Sbrian#include "defs.h"
5230715Sbrian#include "timer.h"
536059Samurai#include "fsm.h"
546059Samurai#include "phase.h"
556059Samurai#include "lcp.h"
5631690Sbrian#include "iplist.h"
576059Samurai#include "ipcp.h"
586059Samurai#include "modem.h"
5913389Sphk#include "filter.h"
6031343Sbrian#ifndef NOALIAS
6126031Sbrian#include "alias_cmd.h"
6231343Sbrian#endif
636059Samurai#include "hdlc.h"
6426142Sbrian#include "loadalias.h"
656059Samurai#include "vars.h"
6625630Sbrian#include "systems.h"
6725630Sbrian#include "chat.h"
686059Samurai#include "os.h"
6926940Sbrian#include "server.h"
7030715Sbrian#include "main.h"
7130715Sbrian#include "route.h"
7230715Sbrian#include "ccp.h"
7330733Sbrian#include "ip.h"
7430715Sbrian#include "slcompress.h"
7531080Sbrian#include "auth.h"
766059Samurai
776059Samuraistruct in_addr ifnetmask;
7831822Sbrianstatic const char *HIDDEN = "********";
796059Samurai
8031343Sbrianstatic int ShowCommand(struct cmdargs const *arg);
8131343Sbrianstatic int TerminalCommand(struct cmdargs const *arg);
8231343Sbrianstatic int QuitCommand(struct cmdargs const *arg);
8331343Sbrianstatic int CloseCommand(struct cmdargs const *arg);
8431343Sbrianstatic int DialCommand(struct cmdargs const *arg);
8531343Sbrianstatic int DownCommand(struct cmdargs const *arg);
8631343Sbrianstatic int AllowCommand(struct cmdargs const *arg);
8731343Sbrianstatic int SetCommand(struct cmdargs const *arg);
8831343Sbrianstatic int AddCommand(struct cmdargs const *arg);
8931343Sbrianstatic int DeleteCommand(struct cmdargs const *arg);
9031343Sbrianstatic int BgShellCommand(struct cmdargs const *arg);
9131343Sbrianstatic int FgShellCommand(struct cmdargs const *arg);
9231343Sbrian#ifndef NOALIAS
9331343Sbrianstatic int AliasCommand(struct cmdargs const *arg);
9431343Sbrianstatic int AliasEnable(struct cmdargs const *arg);
9531343Sbrianstatic int AliasOption(struct cmdargs const *arg);
9631343Sbrian#endif
976059Samurai
986059Samuraistatic int
9931343SbrianHelpCommand(struct cmdargs const *arg)
1006059Samurai{
10128679Sbrian  struct cmdtab const *cmd;
10231372Sbrian  int n, cmax, dmax, cols;
1036059Samurai
10426516Sbrian  if (!VarTerm)
10526516Sbrian    return 0;
10626516Sbrian
10731343Sbrian  if (arg->argc > 0) {
10831343Sbrian    for (cmd = arg->cmd; cmd->name; cmd++)
10931372Sbrian      if (strcasecmp(cmd->name, *arg->argv) == 0 &&
11031372Sbrian          (cmd->lauth & VarLocalAuth)) {
11128679Sbrian	fprintf(VarTerm, "%s\n", cmd->syntax);
11228679Sbrian	return 0;
1136059Samurai      }
11426516Sbrian    return -1;
1156059Samurai  }
11631372Sbrian  cmax = dmax = 0;
11731372Sbrian  for (cmd = arg->cmd; cmd->func; cmd++)
11831372Sbrian    if (cmd->name && (cmd->lauth & VarLocalAuth)) {
11931372Sbrian      if ((n = strlen(cmd->name)) > cmax)
12031372Sbrian        cmax = n;
12131372Sbrian      if ((n = strlen(cmd->helpmes)) > dmax)
12231372Sbrian        dmax = n;
12331372Sbrian    }
12431372Sbrian
12531372Sbrian  cols = 80 / (dmax + cmax + 3);
1266059Samurai  n = 0;
12731343Sbrian  for (cmd = arg->cmd; cmd->func; cmd++)
1286764Samurai    if (cmd->name && (cmd->lauth & VarLocalAuth)) {
12931372Sbrian      fprintf(VarTerm, " %-*.*s: %-*.*s",
13031372Sbrian              cmax, cmax, cmd->name, dmax, dmax, cmd->helpmes);
13131372Sbrian      if (++n % cols == 0)
13231372Sbrian        fprintf(VarTerm, "\n");
1336059Samurai    }
13431372Sbrian  if (n % cols != 0)
13526516Sbrian    fprintf(VarTerm, "\n");
13626516Sbrian
13726516Sbrian  return 0;
1386059Samurai}
1396059Samurai
1406059Samuraiint
14130913SbrianIsInteractive(int Display)
1426059Samurai{
14331343Sbrian  const char *mes = NULL;
1446059Samurai
14520120Snate  if (mode & MODE_DDIAL)
14620120Snate    mes = "Working in dedicated dial mode.";
14725908Sbrian  else if (mode & MODE_BACKGROUND)
14825908Sbrian    mes = "Working in background mode.";
14920120Snate  else if (mode & MODE_AUTO)
15010528Samurai    mes = "Working in auto mode.";
1516059Samurai  else if (mode & MODE_DIRECT)
15210528Samurai    mes = "Working in direct mode.";
1536059Samurai  else if (mode & MODE_DEDICATED)
15410528Samurai    mes = "Working in dedicated mode.";
1556059Samurai  if (mes) {
15630913Sbrian    if (Display && VarTerm)
15726516Sbrian      fprintf(VarTerm, "%s\n", mes);
15826516Sbrian    return 0;
1596059Samurai  }
16026516Sbrian  return 1;
1616059Samurai}
1626059Samurai
1636059Samuraistatic int
16431343SbrianDialCommand(struct cmdargs const *arg)
1656059Samurai{
16611336Samurai  int tries;
16726858Sbrian  int res;
16811336Samurai
1696059Samurai  if (LcpFsm.state > ST_CLOSED) {
17026516Sbrian    if (VarTerm)
17126516Sbrian      fprintf(VarTerm, "LCP state is [%s]\n", StateNames[LcpFsm.state]);
17226516Sbrian    return 0;
1736059Samurai  }
17426516Sbrian
17531343Sbrian  if (arg->argc > 0 && (res = LoadCommand(arg)) != 0)
17631140Sbrian    return res;
17731121Sbrian
17811336Samurai  tries = 0;
17911336Samurai  do {
18026516Sbrian    if (VarTerm)
18126516Sbrian      fprintf(VarTerm, "Dial attempt %u of %d\n", ++tries, VarDialTries);
18231034Sbrian    if (OpenModem() < 0) {
18326516Sbrian      if (VarTerm)
18428679Sbrian	fprintf(VarTerm, "Failed to open modem.\n");
18511336Samurai      break;
18611336Samurai    }
18726858Sbrian    if ((res = DialModem()) == EX_DONE) {
18830697Sbrian      nointr_sleep(1);
18931343Sbrian      ModemTimeout(NULL);
19011336Samurai      PacketMode();
19111336Samurai      break;
19226858Sbrian    } else if (res == EX_SIG)
19326858Sbrian      return 1;
19411336Samurai  } while (VarDialTries == 0 || tries < VarDialTries);
19526516Sbrian
19626516Sbrian  return 0;
1976059Samurai}
1986059Samurai
19910528Samuraistatic int
20031343SbrianSetLoopback(struct cmdargs const *arg)
20128536Sbrian{
20231343Sbrian  if (arg->argc == 1)
20331343Sbrian    if (!strcasecmp(*arg->argv, "on")) {
20428536Sbrian      VarLoopback = 1;
20531141Sbrian      return 0;
20631141Sbrian    }
20731343Sbrian    else if (!strcasecmp(*arg->argv, "off")) {
20828536Sbrian      VarLoopback = 0;
20931141Sbrian      return 0;
21031141Sbrian    }
21128536Sbrian  return -1;
21228536Sbrian}
21328536Sbrian
21428536Sbrianstatic int
21531343SbrianShellCommand(struct cmdargs const *arg, int bg)
21610528Samurai{
21710528Samurai  const char *shell;
21810528Samurai  pid_t shpid;
21926516Sbrian  FILE *oVarTerm;
22031343Sbrian  int argc;
22131343Sbrian  char *argv[MAXARGS];
22220813Sjkh
22318856Ssos#ifdef SHELL_ONLY_INTERACTIVELY
22426911Sbrian  /* we're only allowed to shell when we run ppp interactively */
22526516Sbrian  if (mode != MODE_INTER) {
22626516Sbrian    LogPrintf(LogWARN, "Can only start a shell in interactive mode\n");
22726516Sbrian    return 1;
22810528Samurai  }
22926911Sbrian#endif
23026911Sbrian#ifdef NO_SHELL_IN_AUTO_INTERACTIVE
23128679Sbrian
23226911Sbrian  /*
23328679Sbrian   * we want to stop shell commands when we've got a telnet connection to an
23428679Sbrian   * auto mode ppp
23526911Sbrian   */
23631121Sbrian  if (VarTerm && !(mode & MODE_INTER)) {
23728679Sbrian    LogPrintf(LogWARN, "Shell is not allowed interactively in auto mode\n");
23826516Sbrian    return 1;
23926516Sbrian  }
24026516Sbrian#endif
24126516Sbrian
24231343Sbrian  if (arg->argc == 0)
24328381Sbrian    if (!(mode & MODE_INTER)) {
24431121Sbrian      if (VarTerm)
24531121Sbrian        LogPrintf(LogWARN, "Can't start an interactive shell from"
24631121Sbrian		  " a telnet session\n");
24731121Sbrian      else
24831121Sbrian        LogPrintf(LogWARN, "Can only start an interactive shell in"
24931121Sbrian		  " interactive mode\n");
25028381Sbrian      return 1;
25128381Sbrian    } else if (bg) {
25228381Sbrian      LogPrintf(LogWARN, "Can only start an interactive shell in"
25328679Sbrian		" the foreground mode\n");
25428381Sbrian      return 1;
25528381Sbrian    }
25628679Sbrian  if ((shell = getenv("SHELL")) == 0)
25726516Sbrian    shell = _PATH_BSHELL;
25826516Sbrian
25928679Sbrian  if ((shpid = fork()) == 0) {
26028679Sbrian    int dtablesize, i, fd;
26118531Sbde
26228679Sbrian    if (VarTerm)
26328679Sbrian      fd = fileno(VarTerm);
26428679Sbrian    else if ((fd = open("/dev/null", O_RDWR)) == -1) {
26528679Sbrian      LogPrintf(LogALERT, "Failed to open /dev/null: %s\n", strerror(errno));
26628679Sbrian      exit(1);
26728679Sbrian    }
26828679Sbrian    for (i = 0; i < 3; i++)
26928679Sbrian      dup2(fd, i);
27026516Sbrian
27128679Sbrian    if (fd > 2)
27228679Sbrian      if (VarTerm) {
27328679Sbrian	oVarTerm = VarTerm;
27428679Sbrian	VarTerm = 0;
27528679Sbrian	if (oVarTerm && oVarTerm != stdout)
27628679Sbrian	  fclose(oVarTerm);
27728679Sbrian      } else
27828679Sbrian	close(fd);
27926516Sbrian
28028679Sbrian    for (dtablesize = getdtablesize(), i = 3; i < dtablesize; i++)
28131343Sbrian      close(i);
28226516Sbrian
28328679Sbrian    TtyOldMode();
28431061Sbrian    setuid(geteuid());
28531343Sbrian    if (arg->argc > 0) {
28628679Sbrian      /* substitute pseudo args */
28731343Sbrian      argv[0] = strdup(arg->argv[0]);
28831343Sbrian      for (argc = 1; argc < arg->argc; argc++) {
28931343Sbrian	if (strcasecmp(arg->argv[argc], "HISADDR") == 0)
29031343Sbrian	  argv[argc] = strdup(inet_ntoa(IpcpInfo.his_ipaddr));
29131343Sbrian	else if (strcasecmp(arg->argv[argc], "INTERFACE") == 0)
29231343Sbrian	  argv[argc] = strdup(IfDevName);
29331343Sbrian	else if (strcasecmp(arg->argv[argc], "MYADDR") == 0)
29431343Sbrian	  argv[argc] = strdup(inet_ntoa(IpcpInfo.want_ipaddr));
29531343Sbrian        else
29631343Sbrian          argv[argc] = strdup(arg->argv[argc]);
29731343Sbrian      }
29831343Sbrian      argv[argc] = NULL;
29928679Sbrian      if (bg) {
30028679Sbrian	pid_t p;
30110528Samurai
30228679Sbrian	p = getpid();
30328679Sbrian	if (daemon(1, 1) == -1) {
30428974Sbrian	  LogPrintf(LogERROR, "%d: daemon: %s\n", p, strerror(errno));
30528679Sbrian	  exit(1);
30628679Sbrian	}
30731125Sbrian      } else if (VarTerm)
30831343Sbrian        fprintf(VarTerm, "ppp: Pausing until %s finishes\n", arg->argv[0]);
30931343Sbrian      execvp(argv[0], argv);
31030316Sbrian    } else {
31130316Sbrian      if (VarTerm)
31230316Sbrian        fprintf(VarTerm, "ppp: Pausing until %s finishes\n", shell);
31331343Sbrian      execl(shell, shell, NULL);
31430316Sbrian    }
31520813Sjkh
31631343Sbrian    LogPrintf(LogWARN, "exec() of %s failed\n", arg->argc > 0 ? arg->argv[0] : shell);
31728679Sbrian    exit(255);
31810528Samurai  }
31928679Sbrian  if (shpid == (pid_t) - 1) {
32026516Sbrian    LogPrintf(LogERROR, "Fork failed: %s\n", strerror(errno));
32110528Samurai  } else {
32210528Samurai    int status;
32328679Sbrian
32431343Sbrian    waitpid(shpid, &status, 0);
32510528Samurai  }
32620813Sjkh
32710528Samurai  TtyCommandMode(1);
32820813Sjkh
32928679Sbrian  return (0);
33010528Samurai}
33110528Samurai
33231343Sbrianstatic int
33331343SbrianBgShellCommand(struct cmdargs const *arg)
33431343Sbrian{
33531343Sbrian  if (arg->argc == 0)
33631343Sbrian    return -1;
33731343Sbrian  return ShellCommand(arg, 1);
33831343Sbrian}
33931343Sbrian
34031343Sbrianstatic int
34131343SbrianFgShellCommand(struct cmdargs const *arg)
34231343Sbrian{
34331343Sbrian  return ShellCommand(arg, 0);
34431343Sbrian}
34531343Sbrian
34630715Sbrianstatic struct cmdtab const Commands[] = {
34728679Sbrian  {"accept", NULL, AcceptCommand, LOCAL_AUTH,
34828679Sbrian  "accept option request", "accept option .."},
34928679Sbrian  {"add", NULL, AddCommand, LOCAL_AUTH,
35028679Sbrian  "add route", "add dest mask gateway"},
35131121Sbrian  {"allow", "auth", AllowCommand, LOCAL_AUTH,
35231121Sbrian  "Allow ppp access", "allow users|modes ...."},
35328679Sbrian  {"bg", "!bg", BgShellCommand, LOCAL_AUTH,
35431372Sbrian  "Run a background command", "[!]bg command"},
35528679Sbrian  {"close", NULL, CloseCommand, LOCAL_AUTH,
35628679Sbrian  "Close connection", "close"},
35728679Sbrian  {"delete", NULL, DeleteCommand, LOCAL_AUTH,
35831631Sbrian  "delete route", "delete dest"},
35928679Sbrian  {"deny", NULL, DenyCommand, LOCAL_AUTH,
36028679Sbrian  "Deny option request", "deny option .."},
36128679Sbrian  {"dial", "call", DialCommand, LOCAL_AUTH,
36228679Sbrian  "Dial and login", "dial|call [remote]"},
36328679Sbrian  {"disable", NULL, DisableCommand, LOCAL_AUTH,
36428679Sbrian  "Disable option", "disable option .."},
36528679Sbrian  {"display", NULL, DisplayCommand, LOCAL_AUTH,
36628679Sbrian  "Display option configs", "display"},
36728679Sbrian  {"enable", NULL, EnableCommand, LOCAL_AUTH,
36828679Sbrian  "Enable option", "enable option .."},
36928679Sbrian  {"passwd", NULL, LocalAuthCommand, LOCAL_NO_AUTH,
37029083Sbrian  "Password for manipulation", "passwd LocalPassword"},
37128679Sbrian  {"load", NULL, LoadCommand, LOCAL_AUTH,
37228679Sbrian  "Load settings", "load [remote]"},
37328679Sbrian  {"save", NULL, SaveCommand, LOCAL_AUTH,
37428679Sbrian  "Save settings", "save"},
37528679Sbrian  {"set", "setup", SetCommand, LOCAL_AUTH,
37628679Sbrian  "Set parameters", "set[up] var value"},
37728679Sbrian  {"shell", "!", FgShellCommand, LOCAL_AUTH,
37828679Sbrian  "Run a subshell", "shell|! [sh command]"},
37928679Sbrian  {"show", NULL, ShowCommand, LOCAL_AUTH,
38031372Sbrian  "Show status and stats", "show var"},
38128679Sbrian  {"term", NULL, TerminalCommand, LOCAL_AUTH,
38231372Sbrian  "Enter terminal mode", "term"},
38331343Sbrian#ifndef NOALIAS
38428679Sbrian  {"alias", NULL, AliasCommand, LOCAL_AUTH,
38528679Sbrian  "alias control", "alias option [yes|no]"},
38631343Sbrian#endif
38728679Sbrian  {"quit", "bye", QuitCommand, LOCAL_AUTH | LOCAL_NO_AUTH,
38828679Sbrian  "Quit PPP program", "quit|bye [all]"},
38928679Sbrian  {"help", "?", HelpCommand, LOCAL_AUTH | LOCAL_NO_AUTH,
39031343Sbrian  "Display this message", "help|? [command]", Commands},
39128679Sbrian  {NULL, "down", DownCommand, LOCAL_AUTH,
39228679Sbrian  "Generate down event", "down"},
39328679Sbrian  {NULL, NULL, NULL},
3946059Samurai};
3956059Samurai
39628536Sbrianstatic int
39731343SbrianShowLoopback(struct cmdargs const *arg)
39828536Sbrian{
39928536Sbrian  if (VarTerm)
40028536Sbrian    fprintf(VarTerm, "Local loopback is %s\n", VarLoopback ? "on" : "off");
40128536Sbrian
40228536Sbrian  return 0;
40328536Sbrian}
40428536Sbrian
40528679Sbrianstatic int
40631343SbrianShowLogLevel(struct cmdargs const *arg)
4076059Samurai{
4086059Samurai  int i;
4096059Samurai
41026516Sbrian  if (!VarTerm)
41126516Sbrian    return 0;
41230913Sbrian
41330913Sbrian  fprintf(VarTerm, "Log:  ");
41430913Sbrian  for (i = LogMIN; i <= LogMAX; i++)
41530913Sbrian    if (LogIsKept(i) & LOG_KEPT_SYSLOG)
41626516Sbrian      fprintf(VarTerm, " %s", LogName(i));
41730913Sbrian
41830913Sbrian  fprintf(VarTerm, "\nLocal:");
41930913Sbrian  for (i = LogMIN; i <= LogMAX; i++)
42030913Sbrian    if (LogIsKept(i) & LOG_KEPT_LOCAL)
42130913Sbrian      fprintf(VarTerm, " %s", LogName(i));
42230913Sbrian
42326516Sbrian  fprintf(VarTerm, "\n");
42426516Sbrian
42526516Sbrian  return 0;
4266059Samurai}
4276059Samurai
42828679Sbrianstatic int
42931343SbrianShowEscape(struct cmdargs const *arg)
4306059Samurai{
4316059Samurai  int code, bit;
4326059Samurai
43326516Sbrian  if (!VarTerm)
43426516Sbrian    return 0;
4356059Samurai  if (EscMap[32]) {
43626516Sbrian    for (code = 0; code < 32; code++)
43726516Sbrian      if (EscMap[code])
43828679Sbrian	for (bit = 0; bit < 8; bit++)
43928679Sbrian	  if (EscMap[code] & (1 << bit))
44028679Sbrian	    fprintf(VarTerm, " 0x%02x", (code << 3) + bit);
44126516Sbrian    fprintf(VarTerm, "\n");
4426059Samurai  }
44331077Sbrian  return 0;
4446059Samurai}
4456059Samurai
44628679Sbrianstatic int
44731343SbrianShowTimeout(struct cmdargs const *arg)
4486059Samurai{
44931077Sbrian  if (VarTerm)
45031077Sbrian    fprintf(VarTerm, " Idle Timer: %d secs   LQR Timer: %d secs"
45131077Sbrian	    "   Retry Timer: %d secs\n", VarIdleTimeout, VarLqrTimeout,
45231077Sbrian	    VarRetryTimeout);
45331077Sbrian  return 0;
4546059Samurai}
4556059Samurai
45628679Sbrianstatic int
45731343SbrianShowStopped(struct cmdargs const *arg)
45828327Sbrian{
45928327Sbrian  if (!VarTerm)
46028327Sbrian    return 0;
46128461Sbrian
46228461Sbrian  fprintf(VarTerm, " Stopped Timer:  LCP: ");
46328461Sbrian  if (!LcpFsm.StoppedTimer.load)
46428461Sbrian    fprintf(VarTerm, "Disabled");
46528327Sbrian  else
46628461Sbrian    fprintf(VarTerm, "%ld secs", LcpFsm.StoppedTimer.load / SECTICKS);
46728461Sbrian
46828461Sbrian  fprintf(VarTerm, ", IPCP: ");
46928461Sbrian  if (!IpcpFsm.StoppedTimer.load)
47028461Sbrian    fprintf(VarTerm, "Disabled");
47128461Sbrian  else
47228461Sbrian    fprintf(VarTerm, "%ld secs", IpcpFsm.StoppedTimer.load / SECTICKS);
47328461Sbrian
47428461Sbrian  fprintf(VarTerm, ", CCP: ");
47528461Sbrian  if (!CcpFsm.StoppedTimer.load)
47628461Sbrian    fprintf(VarTerm, "Disabled");
47728461Sbrian  else
47828461Sbrian    fprintf(VarTerm, "%ld secs", CcpFsm.StoppedTimer.load / SECTICKS);
47928461Sbrian
48028461Sbrian  fprintf(VarTerm, "\n");
48128461Sbrian
48231077Sbrian  return 0;
48328327Sbrian}
48428327Sbrian
48528679Sbrianstatic int
48631343SbrianShowAuthKey(struct cmdargs const *arg)
4876059Samurai{
48826516Sbrian  if (!VarTerm)
48926516Sbrian    return 0;
49026516Sbrian  fprintf(VarTerm, "AuthName = %s\n", VarAuthName);
49131822Sbrian  fprintf(VarTerm, "AuthKey  = %s\n", HIDDEN);
49229840Sbrian#ifdef HAVE_DES
49329840Sbrian  fprintf(VarTerm, "Encrypt  = %s\n", VarMSChap ? "MSChap" : "MD5" );
49429840Sbrian#endif
49531077Sbrian  return 0;
4966059Samurai}
4976059Samurai
49828679Sbrianstatic int
49931343SbrianShowVersion(struct cmdargs const *arg)
5006059Samurai{
50131077Sbrian  if (VarTerm)
50231077Sbrian    fprintf(VarTerm, "%s - %s \n", VarVersion, VarLocalVersion);
50331077Sbrian  return 0;
5046059Samurai}
5056059Samurai
50628679Sbrianstatic int
50731343SbrianShowInitialMRU(struct cmdargs const *arg)
50826326Sbrian{
50931077Sbrian  if (VarTerm)
51031077Sbrian    fprintf(VarTerm, " Initial MRU: %ld\n", VarMRU);
51131077Sbrian  return 0;
51226326Sbrian}
51326326Sbrian
51428679Sbrianstatic int
51531343SbrianShowPreferredMTU(struct cmdargs const *arg)
51626326Sbrian{
51731077Sbrian  if (VarTerm)
51831077Sbrian    if (VarPrefMTU)
51931077Sbrian      fprintf(VarTerm, " Preferred MTU: %ld\n", VarPrefMTU);
52031077Sbrian    else
52131077Sbrian      fprintf(VarTerm, " Preferred MTU: unspecified\n");
52231077Sbrian  return 0;
52326326Sbrian}
52426326Sbrian
52528679Sbrianstatic int
52631343SbrianShowReconnect(struct cmdargs const *arg)
52725067Sbrian{
52831077Sbrian  if (VarTerm)
52931077Sbrian    fprintf(VarTerm, " Reconnect Timer:  %d,  %d tries\n",
53031077Sbrian	    VarReconnectTimer, VarReconnectTries);
53131077Sbrian  return 0;
53225067Sbrian}
53325067Sbrian
53428679Sbrianstatic int
53531343SbrianShowRedial(struct cmdargs const *arg)
53611336Samurai{
53726516Sbrian  if (!VarTerm)
53826516Sbrian    return 0;
53926516Sbrian  fprintf(VarTerm, " Redial Timer: ");
54011336Samurai
54111336Samurai  if (VarRedialTimeout >= 0) {
54226516Sbrian    fprintf(VarTerm, " %d seconds, ", VarRedialTimeout);
54328679Sbrian  } else {
54426516Sbrian    fprintf(VarTerm, " Random 0 - %d seconds, ", REDIAL_PERIOD);
54511336Samurai  }
54611336Samurai
54726516Sbrian  fprintf(VarTerm, " Redial Next Timer: ");
54824939Sbrian
54924939Sbrian  if (VarRedialNextTimeout >= 0) {
55026516Sbrian    fprintf(VarTerm, " %d seconds, ", VarRedialNextTimeout);
55128679Sbrian  } else {
55226516Sbrian    fprintf(VarTerm, " Random 0 - %d seconds, ", REDIAL_PERIOD);
55324939Sbrian  }
55424939Sbrian
55511336Samurai  if (VarDialTries)
55628679Sbrian    fprintf(VarTerm, "%d dial tries", VarDialTries);
55711336Samurai
55826516Sbrian  fprintf(VarTerm, "\n");
55911336Samurai
56031077Sbrian  return 0;
56111336Samurai}
56211336Samurai
56326516Sbrian#ifndef NOMSEXT
56428679Sbrianstatic int
56531343SbrianShowMSExt(struct cmdargs const *arg)
56618752Sjkh{
56731077Sbrian  if (VarTerm) {
56831077Sbrian    fprintf(VarTerm, " MS PPP extention values \n");
56931077Sbrian    fprintf(VarTerm, "   Primary NS     : %s\n", inet_ntoa(ns_entries[0]));
57031077Sbrian    fprintf(VarTerm, "   Secondary NS   : %s\n", inet_ntoa(ns_entries[1]));
57131077Sbrian    fprintf(VarTerm, "   Primary NBNS   : %s\n", inet_ntoa(nbns_entries[0]));
57231077Sbrian    fprintf(VarTerm, "   Secondary NBNS : %s\n", inet_ntoa(nbns_entries[1]));
57331077Sbrian  }
57431077Sbrian  return 0;
57518752Sjkh}
57628679Sbrian
57726516Sbrian#endif
57818752Sjkh
57930715Sbrianstatic struct cmdtab const ShowCommands[] = {
58028679Sbrian  {"afilter", NULL, ShowAfilter, LOCAL_AUTH,
58131372Sbrian  "Show keep-alive filters", "show afilter option .."},
58228679Sbrian  {"auth", NULL, ShowAuthKey, LOCAL_AUTH,
58331372Sbrian  "Show auth details", "show auth"},
58428679Sbrian  {"ccp", NULL, ReportCcpStatus, LOCAL_AUTH,
58528679Sbrian  "Show CCP status", "show cpp"},
58628679Sbrian  {"compress", NULL, ReportCompress, LOCAL_AUTH,
58731372Sbrian  "Show compression stats", "show compress"},
58828679Sbrian  {"dfilter", NULL, ShowDfilter, LOCAL_AUTH,
58928679Sbrian  "Show Demand filters", "show dfilteroption .."},
59028679Sbrian  {"escape", NULL, ShowEscape, LOCAL_AUTH,
59128679Sbrian  "Show escape characters", "show escape"},
59228679Sbrian  {"hdlc", NULL, ReportHdlcStatus, LOCAL_AUTH,
59331372Sbrian  "Show HDLC errors", "show hdlc"},
59428679Sbrian  {"ifilter", NULL, ShowIfilter, LOCAL_AUTH,
59528679Sbrian  "Show Input filters", "show ifilter option .."},
59628679Sbrian  {"ipcp", NULL, ReportIpcpStatus, LOCAL_AUTH,
59728679Sbrian  "Show IPCP status", "show ipcp"},
59828679Sbrian  {"lcp", NULL, ReportLcpStatus, LOCAL_AUTH,
59928679Sbrian  "Show LCP status", "show lcp"},
60028679Sbrian  {"loopback", NULL, ShowLoopback, LOCAL_AUTH,
60131372Sbrian  "Show loopback setting", "show loopback"},
60228679Sbrian  {"log", NULL, ShowLogLevel, LOCAL_AUTH,
60331372Sbrian  "Show log levels", "show log"},
60428679Sbrian  {"mem", NULL, ShowMemMap, LOCAL_AUTH,
60528679Sbrian  "Show memory map", "show mem"},
60628679Sbrian  {"modem", NULL, ShowModemStatus, LOCAL_AUTH,
60728679Sbrian  "Show modem setups", "show modem"},
60828679Sbrian  {"mru", NULL, ShowInitialMRU, LOCAL_AUTH,
60928679Sbrian  "Show Initial MRU", "show mru"},
61028679Sbrian  {"mtu", NULL, ShowPreferredMTU, LOCAL_AUTH,
61128679Sbrian  "Show Preferred MTU", "show mtu"},
61228679Sbrian  {"ofilter", NULL, ShowOfilter, LOCAL_AUTH,
61328679Sbrian  "Show Output filters", "show ofilter option .."},
61428679Sbrian  {"proto", NULL, ReportProtStatus, LOCAL_AUTH,
61528679Sbrian  "Show protocol summary", "show proto"},
61628679Sbrian  {"reconnect", NULL, ShowReconnect, LOCAL_AUTH,
61731372Sbrian  "Show reconnect timer", "show reconnect"},
61828679Sbrian  {"redial", NULL, ShowRedial, LOCAL_AUTH,
61931372Sbrian  "Show Redial timeout", "show redial"},
62028679Sbrian  {"route", NULL, ShowRoute, LOCAL_AUTH,
62128679Sbrian  "Show routing table", "show route"},
62228679Sbrian  {"timeout", NULL, ShowTimeout, LOCAL_AUTH,
62331372Sbrian  "Show Idle timeout", "show timeout"},
62428679Sbrian  {"stopped", NULL, ShowStopped, LOCAL_AUTH,
62531372Sbrian  "Show STOPPED timeout", "show stopped"},
62626516Sbrian#ifndef NOMSEXT
62728679Sbrian  {"msext", NULL, ShowMSExt, LOCAL_AUTH,
62828679Sbrian  "Show MS PPP extentions", "show msext"},
62926516Sbrian#endif
63028679Sbrian  {"version", NULL, ShowVersion, LOCAL_NO_AUTH | LOCAL_AUTH,
63128679Sbrian  "Show version string", "show version"},
63228679Sbrian  {"help", "?", HelpCommand, LOCAL_NO_AUTH | LOCAL_AUTH,
63331343Sbrian  "Display this message", "show help|? [command]", ShowCommands},
63428679Sbrian  {NULL, NULL, NULL},
6356059Samurai};
6366059Samurai
63730715Sbrianstatic struct cmdtab const *
63831343SbrianFindCommand(struct cmdtab const *cmds, const char *str, int *pmatch)
6396059Samurai{
64026516Sbrian  int nmatch;
64126516Sbrian  int len;
64228679Sbrian  struct cmdtab const *found;
6436059Samurai
64426516Sbrian  found = NULL;
64526516Sbrian  len = strlen(str);
64626516Sbrian  nmatch = 0;
6476059Samurai  while (cmds->func) {
64825566Sbrian    if (cmds->name && strncasecmp(str, cmds->name, len) == 0) {
64926516Sbrian      if (cmds->name[len] == '\0') {
65028679Sbrian	*pmatch = 1;
65128679Sbrian	return cmds;
65226516Sbrian      }
6536059Samurai      nmatch++;
6546059Samurai      found = cmds;
65528679Sbrian    } else if (cmds->alias && strncasecmp(str, cmds->alias, len) == 0) {
65626516Sbrian      if (cmds->alias[len] == '\0') {
65728679Sbrian	*pmatch = 1;
65828679Sbrian	return cmds;
65926516Sbrian      }
6606059Samurai      nmatch++;
6616059Samurai      found = cmds;
6626059Samurai    }
6636059Samurai    cmds++;
6646059Samurai  }
6656059Samurai  *pmatch = nmatch;
66626516Sbrian  return found;
6676059Samurai}
6686059Samurai
66930715Sbrianstatic int
67031822SbrianFindExec(struct cmdtab const *cmds, int argc, char const *const *argv,
67131822Sbrian         const char *prefix)
6726059Samurai{
67328679Sbrian  struct cmdtab const *cmd;
6746059Samurai  int val = 1;
6756059Samurai  int nmatch;
67631343Sbrian  struct cmdargs arg;
6776059Samurai
67831343Sbrian  cmd = FindCommand(cmds, *argv, &nmatch);
6796059Samurai  if (nmatch > 1)
68031822Sbrian    LogPrintf(LogWARN, "%s%s: Ambiguous command\n", prefix, *argv);
68131343Sbrian  else if (cmd && (cmd->lauth & VarLocalAuth)) {
68231372Sbrian    arg.cmd = cmds;
68331343Sbrian    arg.argc = argc-1;
68431343Sbrian    arg.argv = argv+1;
68531343Sbrian    arg.data = cmd->args;
68631343Sbrian    val = (cmd->func) (&arg);
68731343Sbrian  } else
68831822Sbrian    LogPrintf(LogWARN, "%s%s: Invalid command\n", prefix, *argv);
68926516Sbrian
69026516Sbrian  if (val == -1)
69126516Sbrian    LogPrintf(LogWARN, "Usage: %s\n", cmd->syntax);
69228679Sbrian  else if (val)
69331822Sbrian    LogPrintf(LogWARN, "%s%s: Failed %d\n", prefix, *argv, val);
69426516Sbrian
69526516Sbrian  return val;
6966059Samurai}
6976059Samurai
69818885Sjkhint aft_cmd = 1;
69918885Sjkh
7006059Samuraivoid
70118885SjkhPrompt()
7026059Samurai{
70331343Sbrian  const char *pconnect, *pauth;
7046735Samurai
70531121Sbrian  if (!VarTerm || TermMode)
7066059Samurai    return;
7076735Samurai
70818885Sjkh  if (!aft_cmd)
70926516Sbrian    fprintf(VarTerm, "\n");
71018885Sjkh  else
71118885Sjkh    aft_cmd = 0;
7126735Samurai
71328679Sbrian  if (VarLocalAuth == LOCAL_AUTH)
7146735Samurai    pauth = " ON ";
7156735Samurai  else
7166735Samurai    pauth = " on ";
7176059Samurai  if (IpcpFsm.state == ST_OPENED && phase == PHASE_NETWORK)
7186735Samurai    pconnect = "PPP";
7196059Samurai  else
7206735Samurai    pconnect = "ppp";
72126516Sbrian  fprintf(VarTerm, "%s%s%s> ", pconnect, pauth, VarShortHost);
72226516Sbrian  fflush(VarTerm);
7236059Samurai}
7246059Samurai
7256059Samuraivoid
72631121SbrianInterpretCommand(char *buff, int nb, int *argc, char ***argv)
7276059Samurai{
72831343Sbrian  static char *vector[MAXARGS];
7296059Samurai  char *cp;
7306059Samurai
7316059Samurai  if (nb > 0) {
7326059Samurai    cp = buff + strcspn(buff, "\r\n");
7336059Samurai    if (cp)
7346059Samurai      *cp = '\0';
73531121Sbrian    *argc = MakeArgs(buff, vector, VECSIZE(vector));
73631121Sbrian    *argv = vector;
73731121Sbrian  } else
73831121Sbrian    *argc = 0;
73931121Sbrian}
7406059Samurai
74131822Sbrianstatic int
74231822Sbrianarghidden(int argc, char const *const *argv, int n)
74331822Sbrian{
74431822Sbrian  /* Is arg n of the given command to be hidden from the log ? */
74531828Sbrian
74631828Sbrian  /* set authkey xxxxx */
74731828Sbrian  /* set key xxxxx */
74831822Sbrian  if (n == 2 && !strncasecmp(argv[0], "se", 2) &&
74931822Sbrian      (!strncasecmp(argv[1], "authk", 5) || !strncasecmp(argv[1], "ke", 2)))
75031822Sbrian    return 1;
75131822Sbrian
75231828Sbrian  /* passwd xxxxx */
75331828Sbrian  if (n == 1 && !strncasecmp(argv[0], "p", 1))
75431828Sbrian    return 1;
75531828Sbrian
75631822Sbrian  return 0;
75731822Sbrian}
75831822Sbrian
75931121Sbrianvoid
76031343SbrianRunCommand(int argc, char const *const *argv, const char *label)
76131121Sbrian{
76231156Sbrian  if (argc > 0) {
76331156Sbrian    if (LogIsKept(LogCOMMAND)) {
76431156Sbrian      static char buf[LINE_LEN];
76531156Sbrian      int f, n;
76631156Sbrian
76731156Sbrian      *buf = '\0';
76831156Sbrian      if (label) {
76931962Sbrian        strncpy(buf, label, sizeof buf - 3);
77031962Sbrian        buf[sizeof buf - 3] = '\0';
77131156Sbrian        strcat(buf, ": ");
77231156Sbrian      }
77331156Sbrian      n = strlen(buf);
77431156Sbrian      for (f = 0; f < argc; f++) {
77531962Sbrian        if (n < sizeof buf - 1 && f)
77631156Sbrian          buf[n++] = ' ';
77731822Sbrian        if (arghidden(argc, argv, f))
77831962Sbrian          strncpy(buf+n, HIDDEN, sizeof buf - n - 1);
77931822Sbrian        else
78031962Sbrian          strncpy(buf+n, argv[f], sizeof buf - n - 1);
78131156Sbrian        n += strlen(buf+n);
78231156Sbrian      }
78331156Sbrian      LogPrintf(LogCOMMAND, "%s\n", buf);
78431156Sbrian    }
78531822Sbrian    FindExec(Commands, argc, argv, "");
78631156Sbrian  }
7876059Samurai}
7886059Samurai
78931121Sbrianvoid
79031156SbrianDecodeCommand(char *buff, int nb, const char *label)
79131121Sbrian{
79231121Sbrian  int argc;
79331121Sbrian  char **argv;
79431121Sbrian
79531121Sbrian  InterpretCommand(buff, nb, &argc, &argv);
79631343Sbrian  RunCommand(argc, (char const *const *)argv, label);
79731121Sbrian}
79831121Sbrian
7996059Samuraistatic int
80031343SbrianShowCommand(struct cmdargs const *arg)
8016059Samurai{
80231343Sbrian  if (arg->argc > 0)
80331822Sbrian    FindExec(ShowCommands, arg->argc, arg->argv, "show ");
80426516Sbrian  else if (VarTerm)
80531343Sbrian    fprintf(VarTerm, "Use ``show ?'' to get a arg->cmd.\n");
8066059Samurai  else
80726516Sbrian    LogPrintf(LogWARN, "show command must have arguments\n");
80826516Sbrian
80926516Sbrian  return 0;
8106059Samurai}
8116059Samurai
8126059Samuraistatic int
81331343SbrianTerminalCommand(struct cmdargs const *arg)
8146059Samurai{
8156059Samurai  if (LcpFsm.state > ST_CLOSED) {
81626516Sbrian    if (VarTerm)
81726516Sbrian      fprintf(VarTerm, "LCP state is [%s]\n", StateNames[LcpFsm.state]);
81826516Sbrian    return 1;
8196059Samurai  }
82030913Sbrian  if (!IsInteractive(1))
82128679Sbrian    return (1);
82231034Sbrian  if (OpenModem() < 0) {
82326516Sbrian    if (VarTerm)
82426516Sbrian      fprintf(VarTerm, "Failed to open modem.\n");
82528679Sbrian    return (1);
8266059Samurai  }
82726516Sbrian  if (VarTerm) {
82826516Sbrian    fprintf(VarTerm, "Enter to terminal mode.\n");
82926516Sbrian    fprintf(VarTerm, "Type `~?' for help.\n");
83026516Sbrian  }
8316059Samurai  TtyTermMode();
83228679Sbrian  return (0);
8336059Samurai}
8346059Samurai
8356059Samuraistatic int
83631343SbrianQuitCommand(struct cmdargs const *arg)
8376059Samurai{
83831203Sbrian  if (VarTerm) {
83931203Sbrian    DropClient();
84031203Sbrian    if (mode & MODE_INTER)
84131203Sbrian      Cleanup(EX_NORMAL);
84231343Sbrian    else if (arg->argc > 0 && !strcasecmp(*arg->argv, "all") && VarLocalAuth&LOCAL_AUTH)
84331203Sbrian      Cleanup(EX_NORMAL);
84431121Sbrian  }
84526516Sbrian
84626516Sbrian  return 0;
8476059Samurai}
8486059Samurai
8496059Samuraistatic int
85031343SbrianCloseCommand(struct cmdargs const *arg)
8516059Samurai{
85226098Sbrian  reconnect(RECON_FALSE);
8536059Samurai  LcpClose();
85426516Sbrian  return 0;
8556059Samurai}
8566059Samurai
8576059Samuraistatic int
85831343SbrianDownCommand(struct cmdargs const *arg)
8596059Samurai{
8606059Samurai  LcpDown();
86126516Sbrian  return 0;
8626059Samurai}
8636059Samurai
86425067Sbrianstatic int
86531343SbrianSetModemSpeed(struct cmdargs const *arg)
8666059Samurai{
8676059Samurai  int speed;
8686059Samurai
86931343Sbrian  if (arg->argc > 0) {
87031343Sbrian    if (strcasecmp(*arg->argv, "sync") == 0) {
8716735Samurai      VarSpeed = 0;
87226516Sbrian      return 0;
8736735Samurai    }
87431343Sbrian    speed = atoi(*arg->argv);
8756735Samurai    if (IntToSpeed(speed) != B0) {
8766735Samurai      VarSpeed = speed;
87726516Sbrian      return 0;
8786059Samurai    }
87931343Sbrian    LogPrintf(LogWARN, "%s: Invalid speed\n", *arg->argv);
8806059Samurai  }
88126516Sbrian  return -1;
8826059Samurai}
8836059Samurai
88425067Sbrianstatic int
88531343SbrianSetReconnect(struct cmdargs const *arg)
88611336Samurai{
88731343Sbrian  if (arg->argc == 2) {
88831343Sbrian    VarReconnectTimer = atoi(arg->argv[0]);
88931343Sbrian    VarReconnectTries = atoi(arg->argv[1]);
89026516Sbrian    return 0;
89126516Sbrian  }
89226516Sbrian  return -1;
89325067Sbrian}
89425067Sbrian
89525067Sbrianstatic int
89631343SbrianSetRedialTimeout(struct cmdargs const *arg)
89725067Sbrian{
89811336Samurai  int timeout;
89911336Samurai  int tries;
90024939Sbrian  char *dot;
90111336Samurai
90231343Sbrian  if (arg->argc == 1 || arg->argc == 2) {
90331343Sbrian    if (strncasecmp(arg->argv[0], "random", 6) == 0 &&
90431343Sbrian	(arg->argv[0][6] == '\0' || arg->argv[0][6] == '.')) {
90511336Samurai      VarRedialTimeout = -1;
90630715Sbrian      randinit();
90726516Sbrian    } else {
90831343Sbrian      timeout = atoi(arg->argv[0]);
90911336Samurai
91026516Sbrian      if (timeout >= 0)
91111336Samurai	VarRedialTimeout = timeout;
91211336Samurai      else {
91326516Sbrian	LogPrintf(LogWARN, "Invalid redial timeout\n");
91428679Sbrian	return -1;
91511336Samurai      }
91611336Samurai    }
91724939Sbrian
91831343Sbrian    dot = strchr(arg->argv[0], '.');
91924939Sbrian    if (dot) {
92024939Sbrian      if (strcasecmp(++dot, "random") == 0) {
92128679Sbrian	VarRedialNextTimeout = -1;
92230715Sbrian	randinit();
92328679Sbrian      } else {
92428679Sbrian	timeout = atoi(dot);
92528679Sbrian	if (timeout >= 0)
92628679Sbrian	  VarRedialNextTimeout = timeout;
92728679Sbrian	else {
92828679Sbrian	  LogPrintf(LogWARN, "Invalid next redial timeout\n");
92926516Sbrian	  return -1;
93028679Sbrian	}
93124939Sbrian      }
93228679Sbrian    } else
93328679Sbrian      VarRedialNextTimeout = NEXT_REDIAL_PERIOD;	/* Default next timeout */
93424939Sbrian
93531343Sbrian    if (arg->argc == 2) {
93631343Sbrian      tries = atoi(arg->argv[1]);
93711336Samurai
93811336Samurai      if (tries >= 0) {
93926516Sbrian	VarDialTries = tries;
94026516Sbrian      } else {
94126516Sbrian	LogPrintf(LogWARN, "Invalid retry value\n");
94226516Sbrian	return 1;
94311336Samurai      }
94411336Samurai    }
94526516Sbrian    return 0;
94611336Samurai  }
94726516Sbrian  return -1;
94811336Samurai}
94911336Samurai
95025067Sbrianstatic int
95131343SbrianSetStoppedTimeout(struct cmdargs const *arg)
95228327Sbrian{
95328461Sbrian  LcpFsm.StoppedTimer.load = 0;
95428461Sbrian  IpcpFsm.StoppedTimer.load = 0;
95528461Sbrian  CcpFsm.StoppedTimer.load = 0;
95631343Sbrian  if (arg->argc <= 3) {
95731343Sbrian    if (arg->argc > 0) {
95831343Sbrian      LcpFsm.StoppedTimer.load = atoi(arg->argv[0]) * SECTICKS;
95931343Sbrian      if (arg->argc > 1) {
96031343Sbrian	IpcpFsm.StoppedTimer.load = atoi(arg->argv[1]) * SECTICKS;
96131343Sbrian	if (arg->argc > 2)
96231343Sbrian	  CcpFsm.StoppedTimer.load = atoi(arg->argv[2]) * SECTICKS;
96328461Sbrian      }
96428461Sbrian    }
96528327Sbrian    return 0;
96628327Sbrian  }
96728327Sbrian  return -1;
96828327Sbrian}
96928327Sbrian
97031081Sbrian#define ismask(x) \
97131081Sbrian  (*x == '0' && strlen(x) == 4 && strspn(x+1, "0123456789.") == 3)
97231081Sbrian
97328327Sbrianstatic int
97431343SbrianSetServer(struct cmdargs const *arg)
97526940Sbrian{
97626940Sbrian  int res = -1;
97726940Sbrian
97831343Sbrian  if (arg->argc > 0 && arg->argc < 4) {
97931081Sbrian    const char *port, *passwd, *mask;
98031081Sbrian
98131081Sbrian    /* What's what ? */
98231343Sbrian    port = arg->argv[0];
98331343Sbrian    if (arg->argc == 2)
98431343Sbrian      if (ismask(arg->argv[1])) {
98531081Sbrian        passwd = NULL;
98631343Sbrian        mask = arg->argv[1];
98731081Sbrian      } else {
98831343Sbrian        passwd = arg->argv[1];
98931081Sbrian        mask = NULL;
99031081Sbrian      }
99131343Sbrian    else if (arg->argc == 3) {
99231343Sbrian      passwd = arg->argv[1];
99331343Sbrian      mask = arg->argv[2];
99431081Sbrian      if (!ismask(mask))
99531081Sbrian        return -1;
99631081Sbrian    } else
99731081Sbrian      passwd = mask = NULL;
99831081Sbrian
99931081Sbrian    if (passwd == NULL)
100031081Sbrian      VarHaveLocalAuthKey = 0;
100131081Sbrian    else {
100231962Sbrian      strncpy(VarLocalAuthKey, passwd, sizeof VarLocalAuthKey - 1);
100331081Sbrian      VarLocalAuthKey[sizeof VarLocalAuthKey - 1] = '\0';
100431081Sbrian      VarHaveLocalAuthKey = 1;
100531081Sbrian    }
100631081Sbrian    LocalAuthInit();
100731081Sbrian
100831081Sbrian    if (strcasecmp(port, "none") == 0) {
100931081Sbrian      int oserver;
101031081Sbrian
101131081Sbrian      if (mask != NULL || passwd != NULL)
101231081Sbrian        return -1;
101331081Sbrian      oserver = server;
101426940Sbrian      ServerClose();
101531081Sbrian      if (oserver != -1)
101631081Sbrian        LogPrintf(LogPHASE, "Disabling server port.\n");
101726940Sbrian      res = 0;
101831081Sbrian    } else if (*port == '/') {
101931081Sbrian      mode_t imask;
102028679Sbrian
102131081Sbrian      if (mask != NULL) {
102228679Sbrian	unsigned m;
102328679Sbrian
102431081Sbrian	if (sscanf(mask, "%o", &m) == 1)
102531081Sbrian	  imask = m;
102631081Sbrian        else
102731081Sbrian          return -1;
102831081Sbrian      } else
102931081Sbrian        imask = (mode_t)-1;
103031081Sbrian      res = ServerLocalOpen(port, imask);
103127346Sbrian    } else {
103231081Sbrian      int iport;
103328679Sbrian
103431081Sbrian      if (mask != NULL)
103531081Sbrian        return -1;
103628679Sbrian
103731081Sbrian      if (strspn(port, "0123456789") != strlen(port)) {
103831081Sbrian        struct servent *s;
103931081Sbrian
104031081Sbrian        if ((s = getservbyname(port, "tcp")) == NULL) {
104131081Sbrian	  iport = 0;
104231081Sbrian	  LogPrintf(LogWARN, "%s: Invalid port or service\n", port);
104328679Sbrian	} else
104431081Sbrian	  iport = ntohs(s->s_port);
104527346Sbrian      } else
104631081Sbrian        iport = atoi(port);
104731081Sbrian      res = iport ? ServerTcpOpen(iport) : -1;
104827346Sbrian    }
104931081Sbrian  }
105026940Sbrian
105126940Sbrian  return res;
105226940Sbrian}
105326940Sbrian
105426940Sbrianstatic int
105531343SbrianSetModemParity(struct cmdargs const *arg)
10566059Samurai{
105731343Sbrian  return arg->argc > 0 ? ChangeParity(*arg->argv) : -1;
10586059Samurai}
10596059Samurai
10606059Samuraistatic int
106131343SbrianSetLogLevel(struct cmdargs const *arg)
10626059Samurai{
106326516Sbrian  int i;
106426516Sbrian  int res;
106531343Sbrian  int argc;
106631343Sbrian  char const *const *argv, *argp;
106730913Sbrian  void (*Discard)(int), (*Keep)(int);
106830913Sbrian  void (*DiscardAll)(void);
10696059Samurai
107031343Sbrian  argc = arg->argc;
107131343Sbrian  argv = arg->argv;
107226516Sbrian  res = 0;
107331288Sbrian  if (argc == 0 || strcasecmp(argv[0], "local")) {
107430913Sbrian    Discard = LogDiscard;
107530913Sbrian    Keep = LogKeep;
107630913Sbrian    DiscardAll = LogDiscardAll;
107730913Sbrian  } else {
107830913Sbrian    argc--;
107930913Sbrian    argv++;
108030913Sbrian    Discard = LogDiscardLocal;
108130913Sbrian    Keep = LogKeepLocal;
108230913Sbrian    DiscardAll = LogDiscardAllLocal;
108330913Sbrian  }
108430913Sbrian
108526516Sbrian  if (argc == 0 || (argv[0][0] != '+' && argv[0][0] != '-'))
108631343Sbrian    DiscardAll();
108726516Sbrian  while (argc--) {
108831343Sbrian    argp = **argv == '+' || **argv == '-' ? *argv + 1 : *argv;
108926516Sbrian    for (i = LogMIN; i <= LogMAX; i++)
109031343Sbrian      if (strcasecmp(argp, LogName(i)) == 0) {
109128679Sbrian	if (**argv == '-')
109230913Sbrian	  (*Discard)(i);
109328679Sbrian	else
109430913Sbrian	  (*Keep)(i);
10956059Samurai	break;
10966059Samurai      }
109726516Sbrian    if (i > LogMAX) {
109831343Sbrian      LogPrintf(LogWARN, "%s: Invalid log value\n", argp);
109926516Sbrian      res = -1;
11006059Samurai    }
110126516Sbrian    argv++;
11026059Samurai  }
110326516Sbrian  return res;
11046059Samurai}
11056059Samurai
11066059Samuraistatic int
110731343SbrianSetEscape(struct cmdargs const *arg)
11086059Samurai{
11096059Samurai  int code;
111031343Sbrian  int argc = arg->argc;
111131343Sbrian  char const *const *argv = arg->argv;
11126059Samurai
11136059Samurai  for (code = 0; code < 33; code++)
11146059Samurai    EscMap[code] = 0;
111531343Sbrian
11166059Samurai  while (argc-- > 0) {
11176059Samurai    sscanf(*argv++, "%x", &code);
11186059Samurai    code &= 0xff;
111928679Sbrian    EscMap[code >> 3] |= (1 << (code & 7));
11206059Samurai    EscMap[32] = 1;
11216059Samurai  }
112226516Sbrian  return 0;
11236059Samurai}
11246059Samurai
11256059Samuraistatic int
112631343SbrianSetInitialMRU(struct cmdargs const *arg)
11276059Samurai{
112826326Sbrian  long mru;
112931343Sbrian  const char *err;
11306059Samurai
113131343Sbrian  if (arg->argc > 0) {
113231343Sbrian    mru = atol(*arg->argv);
113326326Sbrian    if (mru < MIN_MRU)
113426516Sbrian      err = "Given MRU value (%ld) is too small.\n";
11356059Samurai    else if (mru > MAX_MRU)
113626516Sbrian      err = "Given MRU value (%ld) is too big.\n";
113726516Sbrian    else {
11386059Samurai      VarMRU = mru;
113926516Sbrian      return 0;
114026516Sbrian    }
114126516Sbrian    LogPrintf(LogWARN, err, mru);
114226516Sbrian  }
114326516Sbrian  return -1;
11446059Samurai}
11456059Samurai
11466059Samuraistatic int
114731343SbrianSetPreferredMTU(struct cmdargs const *arg)
114826326Sbrian{
114926326Sbrian  long mtu;
115031343Sbrian  const char *err;
115126326Sbrian
115231343Sbrian  if (arg->argc > 0) {
115331343Sbrian    mtu = atol(*arg->argv);
115426516Sbrian    if (mtu == 0) {
115526326Sbrian      VarPrefMTU = 0;
115626516Sbrian      return 0;
115726516Sbrian    } else if (mtu < MIN_MTU)
115826516Sbrian      err = "Given MTU value (%ld) is too small.\n";
115926326Sbrian    else if (mtu > MAX_MTU)
116026516Sbrian      err = "Given MTU value (%ld) is too big.\n";
116126516Sbrian    else {
116226326Sbrian      VarPrefMTU = mtu;
116326516Sbrian      return 0;
116426516Sbrian    }
116526516Sbrian    LogPrintf(LogWARN, err, mtu);
116626516Sbrian  }
116726516Sbrian  return -1;
116826326Sbrian}
116926326Sbrian
117026326Sbrianstatic int
117131343SbrianSetIdleTimeout(struct cmdargs const *arg)
11726059Samurai{
117331343Sbrian  if (arg->argc > 0) {
117431343Sbrian    VarIdleTimeout = atoi(arg->argv[0]);
117528679Sbrian    UpdateIdleTimer();		/* If we're connected, restart the idle timer */
117631343Sbrian    if (arg->argc > 1) {
117731343Sbrian      VarLqrTimeout = atoi(arg->argv[1]);
11786735Samurai      if (VarLqrTimeout < 1)
11796735Samurai	VarLqrTimeout = 30;
118031343Sbrian      if (arg->argc > 2) {
118131343Sbrian	VarRetryTimeout = atoi(arg->argv[2]);
11826735Samurai	if (VarRetryTimeout < 1 || VarRetryTimeout > 10)
11836735Samurai	  VarRetryTimeout = 3;
11846735Samurai      }
11856735Samurai    }
118626516Sbrian    return 0;
11876059Samurai  }
118826516Sbrian  return -1;
11896059Samurai}
11906059Samurai
119130715Sbrianstatic struct in_addr
119231343SbrianGetIpAddr(const char *cp)
11936059Samurai{
11946059Samurai  struct hostent *hp;
11956059Samurai  struct in_addr ipaddr;
11966059Samurai
11976059Samurai  hp = gethostbyname(cp);
11986059Samurai  if (hp && hp->h_addrtype == AF_INET)
119930715Sbrian    memcpy(&ipaddr, hp->h_addr, hp->h_length);
12006059Samurai  else if (inet_aton(cp, &ipaddr) == 0)
12016059Samurai    ipaddr.s_addr = 0;
120228679Sbrian  return (ipaddr);
12036059Samurai}
12046059Samurai
12056059Samuraistatic int
120631343SbrianSetInterfaceAddr(struct cmdargs const *arg)
12076059Samurai{
120828394Sbrian  DefMyAddress.ipaddr.s_addr = DefHisAddress.ipaddr.s_addr = 0L;
12096059Samurai
121031343Sbrian  if (arg->argc > 4)
121128679Sbrian    return -1;
121226516Sbrian
121328394Sbrian  HaveTriggerAddress = 0;
121428394Sbrian  ifnetmask.s_addr = 0;
121531690Sbrian  iplist_reset(&DefHisChoice);
121628394Sbrian
121731343Sbrian  if (arg->argc > 0) {
121831690Sbrian    if (!ParseAddr(arg->argc, arg->argv, &DefMyAddress.ipaddr,
121931690Sbrian		   &DefMyAddress.mask, &DefMyAddress.width))
122028679Sbrian      return 1;
122131343Sbrian    if (arg->argc > 1) {
122231690Sbrian      if (strpbrk(arg->argv[1], ",-"))
122331690Sbrian        iplist_setsrc(&DefHisChoice, arg->argv[1]);
122431690Sbrian      else if (!ParseAddr(arg->argc, arg->argv+1, &DefHisAddress.ipaddr,
122531690Sbrian		            &DefHisAddress.mask, &DefHisAddress.width))
122628679Sbrian	return 2;
122731343Sbrian      if (arg->argc > 2) {
122831343Sbrian	ifnetmask = GetIpAddr(arg->argv[2]);
122931343Sbrian	if (arg->argc > 3) {
123031343Sbrian	  TriggerAddress = GetIpAddr(arg->argv[3]);
123128679Sbrian	  HaveTriggerAddress = 1;
12329440Samurai	}
12336059Samurai      }
12346059Samurai    }
12356059Samurai  }
123628394Sbrian
12376059Samurai  /*
12386059Samurai   * For backwards compatibility, 0.0.0.0 means any address.
12396059Samurai   */
12406059Samurai  if (DefMyAddress.ipaddr.s_addr == 0) {
12416059Samurai    DefMyAddress.mask.s_addr = 0;
12426059Samurai    DefMyAddress.width = 0;
12436059Samurai  }
12446059Samurai  if (DefHisAddress.ipaddr.s_addr == 0) {
12456059Samurai    DefHisAddress.mask.s_addr = 0;
12466059Samurai    DefHisAddress.width = 0;
12476059Samurai  }
124828537Sbrian  IpcpInfo.want_ipaddr.s_addr = DefMyAddress.ipaddr.s_addr;
124931690Sbrian  if (iplist_isvalid(&DefHisChoice)) {
125031690Sbrian    iplist_setrandpos(&DefHisChoice);
125131690Sbrian    IpcpInfo.his_ipaddr = ChooseHisAddr(IpcpInfo.want_ipaddr);
125231690Sbrian    if (IpcpInfo.his_ipaddr.s_addr == INADDR_ANY) {
125331690Sbrian      LogPrintf(LogWARN, "%s: None available !\n", DefHisChoice.src);
125431690Sbrian      return 3;
125531690Sbrian    }
125631690Sbrian    DefHisAddress.ipaddr.s_addr = IpcpInfo.his_ipaddr.s_addr;
125731690Sbrian    DefHisAddress.mask.s_addr = 0xffffffff;
125831690Sbrian    DefHisAddress.width = 32;
125931690Sbrian  } else {
126031690Sbrian    IpcpInfo.his_ipaddr.s_addr = DefHisAddress.ipaddr.s_addr;
126128537Sbrian
126231690Sbrian    if ((mode & MODE_AUTO) &&
126331858Sbrian        OsSetIpaddress(DefMyAddress.ipaddr, DefHisAddress.ipaddr) < 0) {
126431858Sbrian      DefMyAddress.ipaddr.s_addr = DefHisAddress.ipaddr.s_addr = 0L;
126531690Sbrian      return 4;
126631858Sbrian    }
126731690Sbrian  }
126831121Sbrian
126926516Sbrian  return 0;
12706059Samurai}
12716059Samurai
127226516Sbrian#ifndef NOMSEXT
12736059Samurai
127430715Sbrianstatic void
127528679SbrianSetMSEXT(struct in_addr * pri_addr,
127628679Sbrian	 struct in_addr * sec_addr,
127728679Sbrian	 int argc,
127831343Sbrian	 char const *const *argv)
127918752Sjkh{
128018752Sjkh  int dummyint;
128118752Sjkh  struct in_addr dummyaddr;
128218752Sjkh
128318752Sjkh  pri_addr->s_addr = sec_addr->s_addr = 0L;
128418752Sjkh
128528679Sbrian  if (argc > 0) {
128618752Sjkh    ParseAddr(argc, argv++, pri_addr, &dummyaddr, &dummyint);
128728679Sbrian    if (--argc > 0)
128818752Sjkh      ParseAddr(argc, argv++, sec_addr, &dummyaddr, &dummyint);
128918752Sjkh    else
129018752Sjkh      sec_addr->s_addr = pri_addr->s_addr;
129118752Sjkh  }
129218752Sjkh
129328679Sbrian  /*
129428679Sbrian   * if the primary/secondary ns entries are 0.0.0.0 we should set them to
129528679Sbrian   * either the localhost's ip, or the values in /etc/resolv.conf ??
129628679Sbrian   *
129728679Sbrian   * up to you if you want to implement this...
129828679Sbrian   */
129918752Sjkh
130018752Sjkh}
130118752Sjkh
130218752Sjkhstatic int
130331343SbrianSetNS(struct cmdargs const *arg)
130418752Sjkh{
130531343Sbrian  SetMSEXT(&ns_entries[0], &ns_entries[1], arg->argc, arg->argv);
130626516Sbrian  return 0;
130718752Sjkh}
130818752Sjkh
130918752Sjkhstatic int
131031343SbrianSetNBNS(struct cmdargs const *arg)
131118752Sjkh{
131231343Sbrian  SetMSEXT(&nbns_entries[0], &nbns_entries[1], arg->argc, arg->argv);
131326516Sbrian  return 0;
131418752Sjkh}
131518752Sjkh
131628679Sbrian#endif				/* MS_EXT */
131718752Sjkh
131829696Sbrianint
131931343SbrianSetVariable(struct cmdargs const *arg)
13206059Samurai{
13216059Samurai  u_long map;
132231343Sbrian  const char *argp;
132331343Sbrian  int param = (int)arg->data;
13246059Samurai
132531343Sbrian  if (arg->argc > 0)
132631343Sbrian    argp = *arg->argv;
132726551Sbrian  else
132831343Sbrian    argp = "";
132926551Sbrian
133026551Sbrian  switch (param) {
133128679Sbrian  case VAR_AUTHKEY:
133231962Sbrian    strncpy(VarAuthKey, argp, sizeof VarAuthKey - 1);
133331962Sbrian    VarAuthKey[sizeof VarAuthKey - 1] = '\0';
133428679Sbrian    break;
133528679Sbrian  case VAR_AUTHNAME:
133631962Sbrian    strncpy(VarAuthName, argp, sizeof VarAuthName - 1);
133731962Sbrian    VarAuthName[sizeof VarAuthName - 1] = '\0';
133828679Sbrian    break;
133928679Sbrian  case VAR_DIAL:
134031962Sbrian    strncpy(VarDialScript, argp, sizeof VarDialScript - 1);
134131962Sbrian    VarDialScript[sizeof VarDialScript - 1] = '\0';
134228679Sbrian    break;
134328679Sbrian  case VAR_LOGIN:
134431962Sbrian    strncpy(VarLoginScript, argp, sizeof VarLoginScript - 1);
134531962Sbrian    VarLoginScript[sizeof VarLoginScript - 1] = '\0';
134628679Sbrian    break;
134728679Sbrian  case VAR_DEVICE:
134829696Sbrian    if (modem != -1)
134929696Sbrian      LogPrintf(LogWARN, "Cannot change device to \"%s\" when \"%s\" is open\n",
135031343Sbrian                argp, VarDevice);
135129696Sbrian    else {
135231962Sbrian      strncpy(VarDeviceList, argp, sizeof VarDeviceList - 1);
135331962Sbrian      VarDeviceList[sizeof VarDeviceList - 1] = '\0';
135429696Sbrian    }
135528679Sbrian    break;
135628679Sbrian  case VAR_ACCMAP:
135731343Sbrian    sscanf(argp, "%lx", &map);
135828679Sbrian    VarAccmap = map;
135928679Sbrian    break;
136028679Sbrian  case VAR_PHONE:
136131962Sbrian    strncpy(VarPhoneList, argp, sizeof VarPhoneList - 1);
136231962Sbrian    VarPhoneList[sizeof VarPhoneList - 1] = '\0';
136331962Sbrian    strncpy(VarPhoneCopy, VarPhoneList, sizeof VarPhoneCopy - 1);
136431962Sbrian    VarPhoneCopy[sizeof VarPhoneCopy - 1] = '\0';
136528679Sbrian    VarNextPhone = VarPhoneCopy;
136631082Sbrian    VarAltPhone = NULL;
136728679Sbrian    break;
136828679Sbrian  case VAR_HANGUP:
136931962Sbrian    strncpy(VarHangupScript, argp, sizeof VarHangupScript - 1);
137031962Sbrian    VarHangupScript[sizeof VarHangupScript - 1] = '\0';
137128679Sbrian    break;
137229840Sbrian#ifdef HAVE_DES
137329549Sbrian  case VAR_ENC:
137431343Sbrian    VarMSChap = !strcasecmp(argp, "mschap");
137529549Sbrian    break;
137629840Sbrian#endif
13776059Samurai  }
137826516Sbrian  return 0;
13796059Samurai}
13806059Samurai
138128679Sbrianstatic int
138231343SbrianSetCtsRts(struct cmdargs const *arg)
138320812Sjkh{
138431343Sbrian  if (arg->argc > 0) {
138531343Sbrian    if (strcmp(*arg->argv, "on") == 0)
138630715Sbrian      VarCtsRts = 1;
138731343Sbrian    else if (strcmp(*arg->argv, "off") == 0)
138830715Sbrian      VarCtsRts = 0;
138920812Sjkh    else
139026516Sbrian      return -1;
139126516Sbrian    return 0;
139220812Sjkh  }
139326516Sbrian  return -1;
139420812Sjkh}
139520812Sjkh
139620812Sjkh
139728679Sbrianstatic int
139831343SbrianSetOpenMode(struct cmdargs const *arg)
13996059Samurai{
140031343Sbrian  if (arg->argc > 0) {
140131343Sbrian    if (strcmp(*arg->argv, "active") == 0)
14026059Samurai      VarOpenMode = OPEN_ACTIVE;
140331343Sbrian    else if (strcmp(*arg->argv, "passive") == 0)
14046059Samurai      VarOpenMode = OPEN_PASSIVE;
14056059Samurai    else
140626516Sbrian      return -1;
140726516Sbrian    return 0;
14086059Samurai  }
140926516Sbrian  return -1;
14106059Samurai}
14116059Samurai
141230715Sbrianstatic struct cmdtab const SetCommands[] = {
141328679Sbrian  {"accmap", NULL, SetVariable, LOCAL_AUTH,
141431343Sbrian  "Set accmap value", "set accmap hex-value", (const void *) VAR_ACCMAP},
141528679Sbrian  {"afilter", NULL, SetAfilter, LOCAL_AUTH,
141628679Sbrian  "Set keep Alive filter", "set afilter ..."},
141728679Sbrian  {"authkey", "key", SetVariable, LOCAL_AUTH,
141831343Sbrian  "Set authentication key", "set authkey|key key", (const void *) VAR_AUTHKEY},
141928679Sbrian  {"authname", NULL, SetVariable, LOCAL_AUTH,
142031343Sbrian  "Set authentication name", "set authname name", (const void *) VAR_AUTHNAME},
142128679Sbrian  {"ctsrts", NULL, SetCtsRts, LOCAL_AUTH,
142228679Sbrian  "Use CTS/RTS modem signalling", "set ctsrts [on|off]"},
142331343Sbrian  {"device", "line", SetVariable, LOCAL_AUTH, "Set modem device name",
142431917Sbrian  "set device|line device-name[,device-name]", (const void *) VAR_DEVICE},
142528679Sbrian  {"dfilter", NULL, SetDfilter, LOCAL_AUTH,
142628679Sbrian  "Set demand filter", "set dfilter ..."},
142728679Sbrian  {"dial", NULL, SetVariable, LOCAL_AUTH,
142831343Sbrian  "Set dialing script", "set dial chat-script", (const void *) VAR_DIAL},
142929840Sbrian#ifdef HAVE_DES
143031343Sbrian  {"encrypt", NULL, SetVariable, LOCAL_AUTH, "Set CHAP encryption algorithm",
143131343Sbrian  "set encrypt MSChap|MD5", (const void *) VAR_ENC},
143229840Sbrian#endif
143328679Sbrian  {"escape", NULL, SetEscape, LOCAL_AUTH,
143428679Sbrian  "Set escape characters", "set escape hex-digit ..."},
143528679Sbrian  {"hangup", NULL, SetVariable, LOCAL_AUTH,
143631343Sbrian  "Set hangup script", "set hangup chat-script", (const void *) VAR_HANGUP},
143731343Sbrian  {"ifaddr", NULL, SetInterfaceAddr, LOCAL_AUTH, "Set destination address",
143831343Sbrian  "set ifaddr [src-addr [dst-addr [netmask [trg-addr]]]]"},
143928679Sbrian  {"ifilter", NULL, SetIfilter, LOCAL_AUTH,
144028679Sbrian  "Set input filter", "set ifilter ..."},
144128679Sbrian  {"loopback", NULL, SetLoopback, LOCAL_AUTH,
144228679Sbrian  "Set loopback facility", "set loopback on|off"},
144328679Sbrian  {"log", NULL, SetLogLevel, LOCAL_AUTH,
144430913Sbrian  "Set log level", "set log [local] [+|-]value..."},
144528679Sbrian  {"login", NULL, SetVariable, LOCAL_AUTH,
144631343Sbrian  "Set login script", "set login chat-script", (const void *) VAR_LOGIN},
144728679Sbrian  {"mru", NULL, SetInitialMRU, LOCAL_AUTH,
144828679Sbrian  "Set Initial MRU value", "set mru value"},
144928679Sbrian  {"mtu", NULL, SetPreferredMTU, LOCAL_AUTH,
145028679Sbrian  "Set Preferred MTU value", "set mtu value"},
145128679Sbrian  {"ofilter", NULL, SetOfilter, LOCAL_AUTH,
145228679Sbrian  "Set output filter", "set ofilter ..."},
145328679Sbrian  {"openmode", NULL, SetOpenMode, LOCAL_AUTH,
145428679Sbrian  "Set open mode", "set openmode [active|passive]"},
145528679Sbrian  {"parity", NULL, SetModemParity, LOCAL_AUTH,
145628679Sbrian  "Set modem parity", "set parity [odd|even|none]"},
145731343Sbrian  {"phone", NULL, SetVariable, LOCAL_AUTH, "Set telephone number(s)",
145831343Sbrian  "set phone phone1[:phone2[...]]", (const void *) VAR_PHONE},
145928679Sbrian  {"reconnect", NULL, SetReconnect, LOCAL_AUTH,
146028679Sbrian  "Set Reconnect timeout", "set reconnect value ntries"},
146131343Sbrian  {"redial", NULL, SetRedialTimeout, LOCAL_AUTH, "Set Redial timeout",
146231343Sbrian  "set redial value|random[.value|random] [dial_attempts]"},
146331343Sbrian  {"stopped", NULL, SetStoppedTimeout, LOCAL_AUTH, "Set STOPPED timeouts",
146431343Sbrian  "set stopped [LCPseconds [IPCPseconds [CCPseconds]]]"},
146528679Sbrian  {"server", "socket", SetServer, LOCAL_AUTH,
146628679Sbrian  "Set server port", "set server|socket TcpPort|LocalName|none [mask]"},
146728679Sbrian  {"speed", NULL, SetModemSpeed, LOCAL_AUTH,
146828679Sbrian  "Set modem speed", "set speed value"},
146928679Sbrian  {"timeout", NULL, SetIdleTimeout, LOCAL_AUTH,
147028679Sbrian  "Set Idle timeout", "set timeout value"},
147126516Sbrian#ifndef NOMSEXT
147228679Sbrian  {"ns", NULL, SetNS, LOCAL_AUTH,
147328679Sbrian  "Set NameServer", "set ns pri-addr [sec-addr]"},
147428679Sbrian  {"nbns", NULL, SetNBNS, LOCAL_AUTH,
147528679Sbrian  "Set NetBIOS NameServer", "set nbns pri-addr [sec-addr]"},
147626516Sbrian#endif
147728679Sbrian  {"help", "?", HelpCommand, LOCAL_AUTH | LOCAL_NO_AUTH,
147831343Sbrian  "Display this message", "set help|? [command]", SetCommands},
147928679Sbrian  {NULL, NULL, NULL},
14806059Samurai};
14816059Samurai
14826059Samuraistatic int
148331343SbrianSetCommand(struct cmdargs const *arg)
14846059Samurai{
148531343Sbrian  if (arg->argc > 0)
148631822Sbrian    FindExec(SetCommands, arg->argc, arg->argv, "set ");
148726516Sbrian  else if (VarTerm)
148831343Sbrian    fprintf(VarTerm, "Use `set ?' to get a arg->cmd or `set ? <var>' for"
148926516Sbrian	    " syntax help.\n");
14906059Samurai  else
149126516Sbrian    LogPrintf(LogWARN, "set command must have arguments\n");
149226516Sbrian
149326516Sbrian  return 0;
14946059Samurai}
14956059Samurai
14966059Samurai
14976059Samuraistatic int
149831343SbrianAddCommand(struct cmdargs const *arg)
14996059Samurai{
15006059Samurai  struct in_addr dest, gateway, netmask;
150131598Sbrian  int gw;
15026059Samurai
150331598Sbrian  if (arg->argc != 3 && arg->argc != 2)
150431598Sbrian    return -1;
150531598Sbrian
150631598Sbrian  if (arg->argc == 2)
150731598Sbrian    if (strcasecmp(arg->argv[0], "default"))
150831598Sbrian      return -1;
150931598Sbrian    else {
151031598Sbrian      dest.s_addr = netmask.s_addr = INADDR_ANY;
151131598Sbrian      gw = 1;
151231598Sbrian    }
151331598Sbrian  else {
151431343Sbrian    if (strcasecmp(arg->argv[0], "MYADDR") == 0)
151527011Sbrian      dest = IpcpInfo.want_ipaddr;
151627011Sbrian    else
151731343Sbrian      dest = GetIpAddr(arg->argv[0]);
151831343Sbrian    netmask = GetIpAddr(arg->argv[1]);
151931598Sbrian    gw = 2;
15206059Samurai  }
152131598Sbrian  if (strcasecmp(arg->argv[gw], "HISADDR") == 0)
152231598Sbrian    gateway = IpcpInfo.his_ipaddr;
152331598Sbrian  else if (strcasecmp(arg->argv[gw], "INTERFACE") == 0)
152431598Sbrian    gateway.s_addr = INADDR_ANY;
152531598Sbrian  else
152631598Sbrian    gateway = GetIpAddr(arg->argv[gw]);
152731598Sbrian  OsSetRoute(RTM_ADD, dest, gateway, netmask);
152831598Sbrian  return 0;
15296059Samurai}
15306059Samurai
15316059Samuraistatic int
153231343SbrianDeleteCommand(struct cmdargs const *arg)
15336059Samurai{
153431598Sbrian  struct in_addr dest, none;
15356059Samurai
153631598Sbrian  if (arg->argc == 1)
153731598Sbrian    if(strcasecmp(arg->argv[0], "all") == 0)
153831598Sbrian      DeleteIfRoutes(0);
153931598Sbrian    else {
154031598Sbrian      if (strcasecmp(arg->argv[0], "MYADDR") == 0)
154131598Sbrian        dest = IpcpInfo.want_ipaddr;
154231598Sbrian      else if (strcasecmp(arg->argv[0], "default") == 0)
154331598Sbrian        dest.s_addr = INADDR_ANY;
154426591Sbrian      else
154531598Sbrian        dest = GetIpAddr(arg->argv[0]);
154631598Sbrian      none.s_addr = INADDR_ANY;
154731598Sbrian      OsSetRoute(RTM_DELETE, dest, none, none);
154831598Sbrian    }
154931598Sbrian  else
155026516Sbrian    return -1;
155126516Sbrian
155226516Sbrian  return 0;
15536059Samurai}
15546059Samurai
155531343Sbrian#ifndef NOALIAS
155626031Sbrianstatic struct cmdtab const AliasCommands[] =
155726031Sbrian{
155828679Sbrian  {"enable", NULL, AliasEnable, LOCAL_AUTH,
155928679Sbrian  "enable IP aliasing", "alias enable [yes|no]"},
156028679Sbrian  {"port", NULL, AliasRedirectPort, LOCAL_AUTH,
156128679Sbrian  "port redirection", "alias port [proto addr_local:port_local  port_alias]"},
156228679Sbrian  {"addr", NULL, AliasRedirectAddr, LOCAL_AUTH,
156328679Sbrian  "static address translation", "alias addr [addr_local addr_alias]"},
156428679Sbrian  {"deny_incoming", NULL, AliasOption, LOCAL_AUTH,
156528679Sbrian    "stop incoming connections", "alias deny_incoming [yes|no]",
156631343Sbrian  (const void *) PKT_ALIAS_DENY_INCOMING},
156728679Sbrian  {"log", NULL, AliasOption, LOCAL_AUTH,
156828679Sbrian    "log aliasing link creation", "alias log [yes|no]",
156931343Sbrian  (const void *) PKT_ALIAS_LOG},
157028679Sbrian  {"same_ports", NULL, AliasOption, LOCAL_AUTH,
157128679Sbrian    "try to leave port numbers unchanged", "alias same_ports [yes|no]",
157231343Sbrian  (const void *) PKT_ALIAS_SAME_PORTS},
157328679Sbrian  {"use_sockets", NULL, AliasOption, LOCAL_AUTH,
157428679Sbrian    "allocate host sockets", "alias use_sockets [yes|no]",
157531343Sbrian  (const void *) PKT_ALIAS_USE_SOCKETS},
157628679Sbrian  {"unregistered_only", NULL, AliasOption, LOCAL_AUTH,
157728679Sbrian    "alias unregistered (private) IP address space only",
157828679Sbrian    "alias unregistered_only [yes|no]",
157931343Sbrian  (const void *) PKT_ALIAS_UNREGISTERED_ONLY},
158028679Sbrian  {"help", "?", HelpCommand, LOCAL_AUTH | LOCAL_NO_AUTH,
158131343Sbrian    "Display this message", "alias help|? [command]", AliasCommands},
158228679Sbrian  {NULL, NULL, NULL},
158326031Sbrian};
158426031Sbrian
158526031Sbrian
158626031Sbrianstatic int
158731343SbrianAliasCommand(struct cmdargs const *arg)
158826031Sbrian{
158931343Sbrian  if (arg->argc > 0)
159031822Sbrian    FindExec(AliasCommands, arg->argc, arg->argv, "alias ");
159126516Sbrian  else if (VarTerm)
159231343Sbrian    fprintf(VarTerm, "Use `alias help' to get a arg->cmd or `alias help <option>'"
159326516Sbrian	    " for syntax help.\n");
159426031Sbrian  else
159526516Sbrian    LogPrintf(LogWARN, "alias command must have arguments\n");
159626516Sbrian
159726516Sbrian  return 0;
159826031Sbrian}
159926031Sbrian
160026031Sbrianstatic int
160131343SbrianAliasEnable(struct cmdargs const *arg)
160226031Sbrian{
160331343Sbrian  if (arg->argc == 1)
160431343Sbrian    if (strcasecmp(arg->argv[0], "yes") == 0) {
160526516Sbrian      if (!(mode & MODE_ALIAS)) {
160628679Sbrian	if (loadAliasHandlers(&VarAliasHandlers) == 0) {
160728679Sbrian	  mode |= MODE_ALIAS;
160828679Sbrian	  return 0;
160928679Sbrian	}
161028679Sbrian	LogPrintf(LogWARN, "Cannot load alias library\n");
161128679Sbrian	return 1;
161226516Sbrian      }
161326516Sbrian      return 0;
161431343Sbrian    } else if (strcasecmp(arg->argv[0], "no") == 0) {
161526516Sbrian      if (mode & MODE_ALIAS) {
161628679Sbrian	unloadAliasHandlers();
161728679Sbrian	mode &= ~MODE_ALIAS;
161826516Sbrian      }
161926516Sbrian      return 0;
162026142Sbrian    }
162126516Sbrian  return -1;
162226031Sbrian}
162326031Sbrian
162426031Sbrian
162526031Sbrianstatic int
162631343SbrianAliasOption(struct cmdargs const *arg)
162726031Sbrian{
162831343Sbrian  unsigned param = (unsigned)arg->data;
162931343Sbrian  if (arg->argc == 1)
163031343Sbrian    if (strcasecmp(arg->argv[0], "yes") == 0) {
163128679Sbrian      if (mode & MODE_ALIAS) {
163231343Sbrian	VarPacketAliasSetMode(param, param);
163328679Sbrian	return 0;
163428679Sbrian      }
163528679Sbrian      LogPrintf(LogWARN, "alias not enabled\n");
163631343Sbrian    } else if (strcmp(arg->argv[0], "no") == 0) {
163728679Sbrian      if (mode & MODE_ALIAS) {
163831343Sbrian	VarPacketAliasSetMode(0, param);
163928679Sbrian	return 0;
164028679Sbrian      }
164128679Sbrian      LogPrintf(LogWARN, "alias not enabled\n");
164228679Sbrian    }
164328679Sbrian  return -1;
164426031Sbrian}
164531343Sbrian#endif /* #ifndef NOALIAS */
164631121Sbrian
164731121Sbrianstatic struct cmdtab const AllowCommands[] = {
164831121Sbrian  {"users", "user", AllowUsers, LOCAL_AUTH,
164931121Sbrian  "Allow users access to ppp", "allow users logname..."},
165031121Sbrian  {"modes", "mode", AllowModes, LOCAL_AUTH,
165131121Sbrian  "Only allow certain ppp modes", "allow modes mode..."},
165231121Sbrian  {"help", "?", HelpCommand, LOCAL_AUTH | LOCAL_NO_AUTH,
165331343Sbrian  "Display this message", "allow help|? [command]", AllowCommands},
165431121Sbrian  {NULL, NULL, NULL},
165531121Sbrian};
165631121Sbrian
165731121Sbrianstatic int
165831343SbrianAllowCommand(struct cmdargs const *arg)
165931121Sbrian{
166031343Sbrian  if (arg->argc > 0)
166131822Sbrian    FindExec(AllowCommands, arg->argc, arg->argv, "allow ");
166231121Sbrian  else if (VarTerm)
166331343Sbrian    fprintf(VarTerm, "Use `allow ?' to get a arg->cmd or `allow ? <cmd>' for"
166431121Sbrian	    " syntax help.\n");
166531121Sbrian  else
166631121Sbrian    LogPrintf(LogWARN, "allow command must have arguments\n");
166731121Sbrian
166831121Sbrian  return 0;
166931121Sbrian}
1670