command.c revision 34536
1184870Syongari/*
2184870Syongari *		PPP User command processing module
3184870Syongari *
4184870Syongari *	    Written by Toshiharu OHNO (tony-o@iij.ad.jp)
5184870Syongari *
6184870Syongari *   Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd.
7184870Syongari *
8184870Syongari * Redistribution and use in source and binary forms are permitted
9184870Syongari * provided that the above copyright notice and this paragraph are
10184870Syongari * duplicated in all such forms and that any documentation,
11184870Syongari * advertising materials, and other materials related to such
12184870Syongari * distribution and use acknowledge that the software was developed
13184870Syongari * by the Internet Initiative Japan, Inc.  The name of the
14184870Syongari * IIJ may not be used to endorse or promote products derived
15184870Syongari * from this software without specific prior written permission.
16184870Syongari * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
17184870Syongari * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
18184870Syongari * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
19184870Syongari *
20184870Syongari * $Id: command.c,v 1.132 1998/03/12 02:23:35 brian Exp $
21184870Syongari *
22184870Syongari */
23184870Syongari#include <sys/param.h>
24184870Syongari#include <netinet/in_systm.h>
25184870Syongari#include <netinet/in.h>
26184870Syongari#include <netinet/ip.h>
27184870Syongari#include <arpa/inet.h>
28184870Syongari#include <sys/socket.h>
29184870Syongari#include <net/route.h>
30184870Syongari#include <netdb.h>
31184870Syongari
32184870Syongari#ifndef NOALIAS
33184870Syongari#include <alias.h>
34184870Syongari#endif
35184870Syongari#include <ctype.h>
36184870Syongari#include <errno.h>
37184870Syongari#include <fcntl.h>
38184870Syongari#include <paths.h>
39184870Syongari#include <stdio.h>
40184870Syongari#include <stdlib.h>
41184870Syongari#include <string.h>
42184870Syongari#include <sys/stat.h>
43184870Syongari#include <sys/wait.h>
44184870Syongari#include <termios.h>
45184870Syongari#include <time.h>
46184870Syongari#include <unistd.h>
47184870Syongari
48184870Syongari#include "command.h"
49184870Syongari#include "mbuf.h"
50184870Syongari#include "log.h"
51184870Syongari#include "defs.h"
52184870Syongari#include "timer.h"
53184870Syongari#include "fsm.h"
54184870Syongari#include "phase.h"
55184870Syongari#include "lcp.h"
56184870Syongari#include "iplist.h"
57184870Syongari#include "ipcp.h"
58184870Syongari#include "modem.h"
59184870Syongari#include "filter.h"
60184870Syongari#ifndef NOALIAS
61184870Syongari#include "alias_cmd.h"
62184870Syongari#endif
63184870Syongari#include "hdlc.h"
64184870Syongari#include "loadalias.h"
65184870Syongari#include "vars.h"
66184870Syongari#include "systems.h"
67184870Syongari#include "chat.h"
68184870Syongari#include "os.h"
69184870Syongari#include "server.h"
70184870Syongari#include "main.h"
71184870Syongari#include "route.h"
72184870Syongari#include "ccp.h"
73184870Syongari#include "ip.h"
74184870Syongari#include "slcompress.h"
75184870Syongari#include "auth.h"
76184870Syongari
77184870Syongaristruct in_addr ifnetmask;
78184870Syongaristatic const char *HIDDEN = "********";
79184870Syongari
80184870Syongaristatic int ShowCommand(struct cmdargs const *arg);
81184870Syongaristatic int TerminalCommand(struct cmdargs const *arg);
82184870Syongaristatic int QuitCommand(struct cmdargs const *arg);
83184870Syongaristatic int CloseCommand(struct cmdargs const *arg);
84184870Syongaristatic int DialCommand(struct cmdargs const *arg);
85184870Syongaristatic int DownCommand(struct cmdargs const *arg);
86184870Syongaristatic int AllowCommand(struct cmdargs const *arg);
87184870Syongaristatic int SetCommand(struct cmdargs const *arg);
88184870Syongaristatic int AddCommand(struct cmdargs const *arg);
89184870Syongaristatic int DeleteCommand(struct cmdargs const *arg);
90184870Syongaristatic int BgShellCommand(struct cmdargs const *arg);
91184870Syongaristatic int FgShellCommand(struct cmdargs const *arg);
92184870Syongari#ifndef NOALIAS
93184870Syongaristatic int AliasCommand(struct cmdargs const *arg);
94184870Syongaristatic int AliasEnable(struct cmdargs const *arg);
95184870Syongaristatic int AliasOption(struct cmdargs const *arg);
96184870Syongari#endif
97184870Syongari
98184870Syongaristatic int
99184870SyongariHelpCommand(struct cmdargs const *arg)
100184870Syongari{
101184870Syongari  struct cmdtab const *cmd;
102184870Syongari  int n, cmax, dmax, cols;
103184870Syongari
104184870Syongari  if (!VarTerm)
105184870Syongari    return 0;
106184870Syongari
107184870Syongari  if (arg->argc > 0) {
108184870Syongari    for (cmd = arg->cmd; cmd->name; cmd++)
109184870Syongari      if (strcasecmp(cmd->name, *arg->argv) == 0 &&
110184870Syongari          (cmd->lauth & VarLocalAuth)) {
111184870Syongari	fprintf(VarTerm, "%s\n", cmd->syntax);
112184870Syongari	return 0;
113184870Syongari      }
114184870Syongari    return -1;
115184870Syongari  }
116184870Syongari  cmax = dmax = 0;
117184870Syongari  for (cmd = arg->cmd; cmd->func; cmd++)
118184870Syongari    if (cmd->name && (cmd->lauth & VarLocalAuth)) {
119184870Syongari      if ((n = strlen(cmd->name)) > cmax)
120184870Syongari        cmax = n;
121184870Syongari      if ((n = strlen(cmd->helpmes)) > dmax)
122184870Syongari        dmax = n;
123184870Syongari    }
124184870Syongari
125184870Syongari  cols = 80 / (dmax + cmax + 3);
126184870Syongari  n = 0;
127184870Syongari  for (cmd = arg->cmd; cmd->func; cmd++)
128184870Syongari    if (cmd->name && (cmd->lauth & VarLocalAuth)) {
129184870Syongari      fprintf(VarTerm, " %-*.*s: %-*.*s",
130184870Syongari              cmax, cmax, cmd->name, dmax, dmax, cmd->helpmes);
131184870Syongari      if (++n % cols == 0)
132184870Syongari        fprintf(VarTerm, "\n");
133184870Syongari    }
134184870Syongari  if (n % cols != 0)
135184870Syongari    fprintf(VarTerm, "\n");
136184870Syongari
137184870Syongari  return 0;
138184870Syongari}
139216925Sjhb
140184870Syongariint
141184870SyongariIsInteractive(int Display)
142184870Syongari{
143184870Syongari  const char *m = NULL;
144184870Syongari
145184870Syongari  if (mode & MODE_DDIAL)
146184870Syongari    m = "direct dial";
147184870Syongari  else if (mode & MODE_BACKGROUND)
148184870Syongari    m = "background";
149184870Syongari  else if (mode & MODE_AUTO)
150184870Syongari    m = "auto";
151184870Syongari  else if (mode & MODE_DIRECT)
152184870Syongari    m = "direct";
153184870Syongari  else if (mode & MODE_DEDICATED)
154184870Syongari    m = "dedicated";
155184870Syongari  else if (mode & MODE_INTER)
156184870Syongari    m = "interactive";
157184870Syongari  if (m) {
158184870Syongari    if (Display && VarTerm)
159184870Syongari      fprintf(VarTerm, "Working in %s mode\n", m);
160184870Syongari  }
161184870Syongari  return mode & MODE_INTER;
162184870Syongari}
163184870Syongari
164184870Syongaristatic int
165184870SyongariDialCommand(struct cmdargs const *arg)
166184870Syongari{
167184870Syongari  int tries;
168184870Syongari  int res;
169184870Syongari
170184870Syongari  if (LcpFsm.state > ST_CLOSED) {
171184870Syongari    if (VarTerm)
172184870Syongari      fprintf(VarTerm, "LCP state is [%s]\n", StateNames[LcpFsm.state]);
173184870Syongari    return 0;
174184870Syongari  }
175184870Syongari
176184870Syongari  if ((mode & MODE_DAEMON) && !(mode & MODE_AUTO)) {
177184870Syongari    LogPrintf(LogWARN,
178184870Syongari              "Manual dial is only available in auto and interactive mode\n");
179184870Syongari    return 1;
180184870Syongari  }
181184870Syongari
182184870Syongari  if (arg->argc > 0 && (res = LoadCommand(arg)) != 0)
183184870Syongari    return res;
184184870Syongari
185184870Syongari  tries = 0;
186184870Syongari  do {
187184870Syongari    if (tries) {
188184870Syongari      LogPrintf(LogPHASE, "Enter pause (%d) for redialing.\n",
189184870Syongari                VarRedialNextTimeout);
190184870Syongari      nointr_sleep(VarRedialNextTimeout);
191184870Syongari    }
192184870Syongari    if (VarTerm)
193184870Syongari      fprintf(VarTerm, "Dial attempt %u of %d\n", ++tries, VarDialTries);
194184870Syongari    if (OpenModem() < 0) {
195184870Syongari      if (VarTerm)
196184870Syongari	fprintf(VarTerm, "Failed to open modem.\n");
197184870Syongari      break;
198184870Syongari    }
199184870Syongari    if ((res = DialModem()) == EX_DONE) {
200184870Syongari      ModemTimeout(NULL);
201184870Syongari      PacketMode(VarOpenMode);
202184870Syongari      break;
203184870Syongari    } else if (res == EX_SIG)
204184870Syongari      return 1;
205184870Syongari  } while (VarDialTries == 0 || tries < VarDialTries);
206184870Syongari
207184870Syongari  return 0;
208184870Syongari}
209184870Syongari
210184870Syongaristatic int
211184870SyongariSetLoopback(struct cmdargs const *arg)
212184870Syongari{
213184870Syongari  if (arg->argc == 1) {
214184870Syongari    if (!strcasecmp(*arg->argv, "on")) {
215184870Syongari      VarLoopback = 1;
216184870Syongari      return 0;
217184870Syongari    } else if (!strcasecmp(*arg->argv, "off")) {
218184870Syongari      VarLoopback = 0;
219184870Syongari      return 0;
220184870Syongari    }
221184870Syongari  }
222184870Syongari  return -1;
223184870Syongari}
224184870Syongari
225184870Syongaristatic int
226184870SyongariShellCommand(struct cmdargs const *arg, int bg)
227184870Syongari{
228184870Syongari  const char *shell;
229184870Syongari  pid_t shpid;
230184870Syongari  int argc;
231184870Syongari  char *argv[MAXARGS];
232184870Syongari
233184870Syongari#ifdef SHELL_ONLY_INTERACTIVELY
234184870Syongari  /* we're only allowed to shell when we run ppp interactively */
235184870Syongari  if (mode != MODE_INTER) {
236184870Syongari    LogPrintf(LogWARN, "Can only start a shell in interactive mode\n");
237184870Syongari    return 1;
238184870Syongari  }
239184870Syongari#endif
240184870Syongari#ifdef NO_SHELL_IN_AUTO_INTERACTIVE
241184870Syongari
242184870Syongari  /*
243184870Syongari   * we want to stop shell commands when we've got a telnet connection to an
244184870Syongari   * auto mode ppp
245184870Syongari   */
246184870Syongari  if (VarTerm && !(mode & MODE_INTER)) {
247184870Syongari    LogPrintf(LogWARN, "Shell is not allowed interactively in auto mode\n");
248184870Syongari    return 1;
249184870Syongari  }
250184870Syongari#endif
251184870Syongari
252184870Syongari  if (arg->argc == 0) {
253184870Syongari    if (!(mode & MODE_INTER)) {
254184870Syongari      if (VarTerm)
255184870Syongari        LogPrintf(LogWARN, "Can't start an interactive shell from"
256184870Syongari		  " a telnet session\n");
257184870Syongari      else
258184870Syongari        LogPrintf(LogWARN, "Can only start an interactive shell in"
259184870Syongari		  " interactive mode\n");
260184870Syongari      return 1;
261184870Syongari    } else if (bg) {
262184870Syongari      LogPrintf(LogWARN, "Can only start an interactive shell in"
263184870Syongari		" the foreground mode\n");
264184870Syongari      return 1;
265184870Syongari    }
266184870Syongari  }
267184870Syongari
268184870Syongari  if ((shell = getenv("SHELL")) == 0)
269184870Syongari    shell = _PATH_BSHELL;
270184870Syongari
271184870Syongari  if ((shpid = fork()) == 0) {
272184870Syongari    int dtablesize, i, fd;
273184870Syongari
274184870Syongari    TermTimerService();
275184870Syongari    signal(SIGINT, SIG_DFL);
276184870Syongari    signal(SIGQUIT, SIG_DFL);
277184870Syongari    signal(SIGTERM, SIG_DFL);
278184870Syongari    signal(SIGHUP, SIG_DFL);
279184870Syongari    signal(SIGALRM, SIG_DFL);
280184870Syongari
281184870Syongari    if (VarTerm)
282184870Syongari      fd = fileno(VarTerm);
283184870Syongari    else if ((fd = open("/dev/null", O_RDWR)) == -1) {
284184870Syongari      LogPrintf(LogALERT, "Failed to open /dev/null: %s\n", strerror(errno));
285184870Syongari      exit(1);
286184870Syongari    }
287184870Syongari    for (i = 0; i < 3; i++)
288184870Syongari      dup2(fd, i);
289184870Syongari
290184870Syongari    for (dtablesize = getdtablesize(), i = 3; i < dtablesize; i++)
291184870Syongari      close(i);
292184870Syongari
293184870Syongari    TtyOldMode();
294184870Syongari    setuid(geteuid());
295184870Syongari    if (arg->argc > 0) {
296184870Syongari      /* substitute pseudo args */
297184870Syongari      argv[0] = strdup(arg->argv[0]);
298184870Syongari      for (argc = 1; argc < arg->argc; argc++) {
299184870Syongari	if (strcasecmp(arg->argv[argc], "HISADDR") == 0)
300184870Syongari	  argv[argc] = strdup(inet_ntoa(IpcpInfo.his_ipaddr));
301184870Syongari	else if (strcasecmp(arg->argv[argc], "INTERFACE") == 0)
302184870Syongari	  argv[argc] = strdup(IfDevName);
303184870Syongari	else if (strcasecmp(arg->argv[argc], "MYADDR") == 0)
304184870Syongari	  argv[argc] = strdup(inet_ntoa(IpcpInfo.want_ipaddr));
305184870Syongari        else
306184870Syongari          argv[argc] = strdup(arg->argv[argc]);
307184870Syongari      }
308184870Syongari      argv[argc] = NULL;
309184870Syongari      if (bg) {
310184870Syongari	pid_t p;
311184870Syongari
312184870Syongari	p = getpid();
313184870Syongari	if (daemon(1, 1) == -1) {
314184870Syongari	  LogPrintf(LogERROR, "%d: daemon: %s\n", p, strerror(errno));
315184870Syongari	  exit(1);
316184870Syongari	}
317184870Syongari      } else if (VarTerm)
318184870Syongari        printf("ppp: Pausing until %s finishes\n", arg->argv[0]);
319184870Syongari      execvp(argv[0], argv);
320184870Syongari    } else {
321184870Syongari      if (VarTerm)
322184870Syongari        printf("ppp: Pausing until %s finishes\n", shell);
323184870Syongari      execl(shell, shell, NULL);
324184870Syongari    }
325184870Syongari
326184870Syongari    LogPrintf(LogWARN, "exec() of %s failed\n",
327184870Syongari              arg->argc > 0 ? arg->argv[0] : shell);
328184870Syongari    exit(255);
329184870Syongari  }
330184870Syongari  if (shpid == (pid_t) - 1) {
331184870Syongari    LogPrintf(LogERROR, "Fork failed: %s\n", strerror(errno));
332184870Syongari  } else {
333219902Sjhb    int status;
334184870Syongari
335184870Syongari    waitpid(shpid, &status, 0);
336184870Syongari  }
337184870Syongari
338184870Syongari  TtyCommandMode(0);
339184870Syongari
340184870Syongari  return (0);
341184870Syongari}
342184870Syongari
343184870Syongaristatic int
344184870SyongariBgShellCommand(struct cmdargs const *arg)
345184870Syongari{
346184870Syongari  if (arg->argc == 0)
347184870Syongari    return -1;
348184870Syongari  return ShellCommand(arg, 1);
349184870Syongari}
350184870Syongari
351184870Syongaristatic int
352184870SyongariFgShellCommand(struct cmdargs const *arg)
353184870Syongari{
354184870Syongari  return ShellCommand(arg, 0);
355184870Syongari}
356184870Syongari
357184870Syongaristatic struct cmdtab const Commands[] = {
358184870Syongari  {"accept", NULL, AcceptCommand, LOCAL_AUTH,
359184870Syongari  "accept option request", "accept option .."},
360184870Syongari  {"add", NULL, AddCommand, LOCAL_AUTH,
361184870Syongari  "add route", "add dest mask gateway", NULL},
362184870Syongari  {"add!", NULL, AddCommand, LOCAL_AUTH,
363184870Syongari  "add or change route", "add! dest mask gateway", (void *)1},
364184870Syongari  {"allow", "auth", AllowCommand, LOCAL_AUTH,
365184870Syongari  "Allow ppp access", "allow users|modes ...."},
366184870Syongari  {"bg", "!bg", BgShellCommand, LOCAL_AUTH,
367184870Syongari  "Run a background command", "[!]bg command"},
368184870Syongari  {"close", NULL, CloseCommand, LOCAL_AUTH,
369184870Syongari  "Close connection", "close"},
370184870Syongari  {"delete", NULL, DeleteCommand, LOCAL_AUTH,
371184870Syongari  "delete route", "delete dest", NULL},
372184870Syongari  {"delete!", NULL, DeleteCommand, LOCAL_AUTH,
373184870Syongari  "delete a route if it exists", "delete! dest", (void *)1},
374184870Syongari  {"deny", NULL, DenyCommand, LOCAL_AUTH,
375184870Syongari  "Deny option request", "deny option .."},
376184870Syongari  {"dial", "call", DialCommand, LOCAL_AUTH,
377184870Syongari  "Dial and login", "dial|call [remote]"},
378185576Syongari  {"disable", NULL, DisableCommand, LOCAL_AUTH,
379185576Syongari  "Disable option", "disable option .."},
380185576Syongari  {"display", NULL, DisplayCommand, LOCAL_AUTH,
381185576Syongari  "Display option configs", "display"},
382185576Syongari  {"enable", NULL, EnableCommand, LOCAL_AUTH,
383185576Syongari  "Enable option", "enable option .."},
384185576Syongari  {"passwd", NULL, LocalAuthCommand, LOCAL_NO_AUTH,
385185576Syongari  "Password for manipulation", "passwd LocalPassword"},
386185576Syongari  {"load", NULL, LoadCommand, LOCAL_AUTH,
387185576Syongari  "Load settings", "load [remote]"},
388185576Syongari  {"save", NULL, SaveCommand, LOCAL_AUTH,
389185576Syongari  "Save settings", "save"},
390185576Syongari  {"set", "setup", SetCommand, LOCAL_AUTH,
391185576Syongari  "Set parameters", "set[up] var value"},
392185576Syongari  {"shell", "!", FgShellCommand, LOCAL_AUTH,
393185576Syongari  "Run a subshell", "shell|! [sh command]"},
394185576Syongari  {"show", NULL, ShowCommand, LOCAL_AUTH,
395185576Syongari  "Show status and stats", "show var"},
396185576Syongari  {"term", NULL, TerminalCommand, LOCAL_AUTH,
397185576Syongari  "Enter terminal mode", "term"},
398185576Syongari#ifndef NOALIAS
399185576Syongari  {"alias", NULL, AliasCommand, LOCAL_AUTH,
400185576Syongari  "alias control", "alias option [yes|no]"},
401185576Syongari#endif
402185576Syongari  {"quit", "bye", QuitCommand, LOCAL_AUTH | LOCAL_NO_AUTH,
403185576Syongari  "Quit PPP program", "quit|bye [all]"},
404185576Syongari  {"help", "?", HelpCommand, LOCAL_AUTH | LOCAL_NO_AUTH,
405185576Syongari  "Display this message", "help|? [command]", Commands},
406185576Syongari  {NULL, "down", DownCommand, LOCAL_AUTH,
407185576Syongari  "Generate down event", "down"},
408185576Syongari  {NULL, NULL, NULL},
409185576Syongari};
410185576Syongari
411184870Syongaristatic int
412184870SyongariShowLoopback(struct cmdargs const *arg)
413184870Syongari{
414184870Syongari  if (VarTerm)
415184870Syongari    fprintf(VarTerm, "Local loopback is %s\n", VarLoopback ? "on" : "off");
416184870Syongari
417184870Syongari  return 0;
418184870Syongari}
419184870Syongari
420184870Syongaristatic int
421184870SyongariShowLogLevel(struct cmdargs const *arg)
422184870Syongari{
423184870Syongari  int i;
424184870Syongari
425184870Syongari  if (!VarTerm)
426184870Syongari    return 0;
427184870Syongari
428184870Syongari  fprintf(VarTerm, "Log:  ");
429184870Syongari  for (i = LogMIN; i <= LogMAX; i++)
430184870Syongari    if (LogIsKept(i) & LOG_KEPT_SYSLOG)
431184870Syongari      fprintf(VarTerm, " %s", LogName(i));
432184870Syongari
433184870Syongari  fprintf(VarTerm, "\nLocal:");
434184870Syongari  for (i = LogMIN; i <= LogMAX; i++)
435184870Syongari    if (LogIsKept(i) & LOG_KEPT_LOCAL)
436184870Syongari      fprintf(VarTerm, " %s", LogName(i));
437184870Syongari
438184870Syongari  fprintf(VarTerm, "\n");
439184870Syongari
440184870Syongari  return 0;
441184870Syongari}
442184870Syongari
443184870Syongaristatic int
444184870SyongariShowEscape(struct cmdargs const *arg)
445184870Syongari{
446184870Syongari  int code, bit;
447184870Syongari
448184870Syongari  if (!VarTerm)
449184870Syongari    return 0;
450184870Syongari  if (EscMap[32]) {
451184870Syongari    for (code = 0; code < 32; code++)
452184870Syongari      if (EscMap[code])
453184870Syongari	for (bit = 0; bit < 8; bit++)
454184870Syongari	  if (EscMap[code] & (1 << bit))
455184870Syongari	    fprintf(VarTerm, " 0x%02x", (code << 3) + bit);
456184870Syongari    fprintf(VarTerm, "\n");
457184870Syongari  }
458184870Syongari  return 0;
459184870Syongari}
460184870Syongari
461184870Syongaristatic int
462184870SyongariShowTimeout(struct cmdargs const *arg)
463184870Syongari{
464184870Syongari  if (VarTerm) {
465184870Syongari    int remaining;
466184870Syongari
467184870Syongari    fprintf(VarTerm, " Idle Timer: %d secs   LQR Timer: %d secs"
468184870Syongari	    "   Retry Timer: %d secs\n", VarIdleTimeout, VarLqrTimeout,
469184870Syongari	    VarRetryTimeout);
470184870Syongari    remaining = RemainingIdleTime();
471184870Syongari    if (remaining != -1)
472184870Syongari    fprintf(VarTerm, " %d secs remaining\n", remaining);
473184870Syongari  }
474184870Syongari  return 0;
475184870Syongari}
476184870Syongari
477184870Syongaristatic int
478184870SyongariShowStopped(struct cmdargs const *arg)
479184870Syongari{
480184870Syongari  if (!VarTerm)
481184870Syongari    return 0;
482184870Syongari
483184870Syongari  fprintf(VarTerm, " Stopped Timer:  LCP: ");
484184870Syongari  if (!LcpFsm.StoppedTimer.load)
485184870Syongari    fprintf(VarTerm, "Disabled");
486184870Syongari  else
487184870Syongari    fprintf(VarTerm, "%ld secs", LcpFsm.StoppedTimer.load / SECTICKS);
488184870Syongari
489184870Syongari  fprintf(VarTerm, ", IPCP: ");
490184870Syongari  if (!IpcpFsm.StoppedTimer.load)
491184870Syongari    fprintf(VarTerm, "Disabled");
492184870Syongari  else
493184870Syongari    fprintf(VarTerm, "%ld secs", IpcpFsm.StoppedTimer.load / SECTICKS);
494184870Syongari
495184870Syongari  fprintf(VarTerm, ", CCP: ");
496184870Syongari  if (!CcpFsm.StoppedTimer.load)
497184870Syongari    fprintf(VarTerm, "Disabled");
498184870Syongari  else
499184870Syongari    fprintf(VarTerm, "%ld secs", CcpFsm.StoppedTimer.load / SECTICKS);
500184870Syongari
501184870Syongari  fprintf(VarTerm, "\n");
502184870Syongari
503184870Syongari  return 0;
504184870Syongari}
505184870Syongari
506184870Syongaristatic int
507184870SyongariShowAuthKey(struct cmdargs const *arg)
508184870Syongari{
509184870Syongari  if (!VarTerm)
510184870Syongari    return 0;
511184870Syongari  fprintf(VarTerm, "AuthName = %s\n", VarAuthName);
512184870Syongari  fprintf(VarTerm, "AuthKey  = %s\n", HIDDEN);
513184870Syongari#ifdef HAVE_DES
514184870Syongari  fprintf(VarTerm, "Encrypt  = %s\n", VarMSChap ? "MSChap" : "MD5" );
515184870Syongari#endif
516184870Syongari  return 0;
517184870Syongari}
518184870Syongari
519184870Syongaristatic int
520184870SyongariShowVersion(struct cmdargs const *arg)
521184870Syongari{
522184870Syongari  if (VarTerm)
523184870Syongari    fprintf(VarTerm, "%s - %s \n", VarVersion, VarLocalVersion);
524184870Syongari  return 0;
525184870Syongari}
526184870Syongari
527184870Syongaristatic int
528184870SyongariShowInitialMRU(struct cmdargs const *arg)
529184870Syongari{
530184870Syongari  if (VarTerm)
531184870Syongari    fprintf(VarTerm, " Initial MRU: %d\n", VarMRU);
532184870Syongari  return 0;
533184870Syongari}
534184870Syongari
535184870Syongaristatic int
536184870SyongariShowPreferredMTU(struct cmdargs const *arg)
537184870Syongari{
538184870Syongari  if (VarTerm) {
539184870Syongari    if (VarPrefMTU)
540184870Syongari      fprintf(VarTerm, " Preferred MTU: %d\n", VarPrefMTU);
541184870Syongari    else
542184870Syongari      fprintf(VarTerm, " Preferred MTU: unspecified\n");
543184870Syongari  }
544184870Syongari  return 0;
545184870Syongari}
546184870Syongari
547219902Sjhbstatic int
548184870SyongariShowReconnect(struct cmdargs const *arg)
549184870Syongari{
550184870Syongari  if (VarTerm)
551184870Syongari    fprintf(VarTerm, " Reconnect Timer:  %d,  %d tries\n",
552184870Syongari	    VarReconnectTimer, VarReconnectTries);
553184870Syongari  return 0;
554184870Syongari}
555184870Syongari
556184870Syongaristatic int
557184870SyongariShowRedial(struct cmdargs const *arg)
558184870Syongari{
559184870Syongari  if (!VarTerm)
560184870Syongari    return 0;
561184870Syongari  fprintf(VarTerm, " Redial Timer: ");
562184870Syongari
563184870Syongari  if (VarRedialTimeout >= 0) {
564184870Syongari    fprintf(VarTerm, " %d seconds, ", VarRedialTimeout);
565184870Syongari  } else {
566184870Syongari    fprintf(VarTerm, " Random 0 - %d seconds, ", REDIAL_PERIOD);
567184870Syongari  }
568184870Syongari
569184870Syongari  fprintf(VarTerm, " Redial Next Timer: ");
570184870Syongari
571184870Syongari  if (VarRedialNextTimeout >= 0) {
572184870Syongari    fprintf(VarTerm, " %d seconds, ", VarRedialNextTimeout);
573184870Syongari  } else {
574184870Syongari    fprintf(VarTerm, " Random 0 - %d seconds, ", REDIAL_PERIOD);
575184870Syongari  }
576184870Syongari
577184870Syongari  if (VarDialTries)
578184870Syongari    fprintf(VarTerm, "%d dial tries", VarDialTries);
579184870Syongari
580184870Syongari  fprintf(VarTerm, "\n");
581184870Syongari
582184870Syongari  return 0;
583184870Syongari}
584184870Syongari
585184870Syongari#ifndef NOMSEXT
586184870Syongaristatic int
587184870SyongariShowMSExt(struct cmdargs const *arg)
588184870Syongari{
589184870Syongari  if (VarTerm) {
590184870Syongari    fprintf(VarTerm, " MS PPP extention values \n");
591184870Syongari    fprintf(VarTerm, "   Primary NS     : %s\n", inet_ntoa(ns_entries[0]));
592184870Syongari    fprintf(VarTerm, "   Secondary NS   : %s\n", inet_ntoa(ns_entries[1]));
593184870Syongari    fprintf(VarTerm, "   Primary NBNS   : %s\n", inet_ntoa(nbns_entries[0]));
594219902Sjhb    fprintf(VarTerm, "   Secondary NBNS : %s\n", inet_ntoa(nbns_entries[1]));
595184870Syongari  }
596184870Syongari  return 0;
597184870Syongari}
598184870Syongari
599184870Syongari#endif
600184870Syongari
601213893Smariusstatic struct cmdtab const ShowCommands[] = {
602213893Smarius  {"afilter", NULL, ShowAfilter, LOCAL_AUTH,
603213893Smarius  "Show keep-alive filters", "show afilter option .."},
604213893Smarius  {"auth", NULL, ShowAuthKey, LOCAL_AUTH,
605213893Smarius  "Show auth details", "show auth"},
606184870Syongari  {"ccp", NULL, ReportCcpStatus, LOCAL_AUTH,
607184870Syongari  "Show CCP status", "show cpp"},
608184870Syongari  {"compress", NULL, ReportCompress, LOCAL_AUTH,
609184870Syongari  "Show compression stats", "show compress"},
610184870Syongari  {"dfilter", NULL, ShowDfilter, LOCAL_AUTH,
611184870Syongari  "Show Demand filters", "show dfilteroption .."},
612204378Syongari  {"escape", NULL, ShowEscape, LOCAL_AUTH,
613204378Syongari  "Show escape characters", "show escape"},
614184870Syongari  {"hdlc", NULL, ReportHdlcStatus, LOCAL_AUTH,
615195153Syongari  "Show HDLC errors", "show hdlc"},
616195153Syongari  {"ifilter", NULL, ShowIfilter, LOCAL_AUTH,
617195153Syongari  "Show Input filters", "show ifilter option .."},
618195153Syongari  {"ipcp", NULL, ReportIpcpStatus, LOCAL_AUTH,
619195153Syongari  "Show IPCP status", "show ipcp"},
620195153Syongari  {"lcp", NULL, ReportLcpStatus, LOCAL_AUTH,
621195153Syongari  "Show LCP status", "show lcp"},
622195153Syongari  {"loopback", NULL, ShowLoopback, LOCAL_AUTH,
623184870Syongari  "Show loopback setting", "show loopback"},
624184870Syongari  {"log", NULL, ShowLogLevel, LOCAL_AUTH,
625184870Syongari  "Show log levels", "show log"},
626184870Syongari  {"mem", NULL, ShowMemMap, LOCAL_AUTH,
627184870Syongari  "Show memory map", "show mem"},
628184870Syongari  {"modem", NULL, ShowModemStatus, LOCAL_AUTH,
629184870Syongari  "Show modem setups", "show modem"},
630184870Syongari  {"mru", NULL, ShowInitialMRU, LOCAL_AUTH,
631184870Syongari  "Show Initial MRU", "show mru"},
632184870Syongari#ifndef NOMSEXT
633184870Syongari  {"msext", NULL, ShowMSExt, LOCAL_AUTH,
634184870Syongari  "Show MS PPP extentions", "show msext"},
635184870Syongari#endif
636184870Syongari  {"mtu", NULL, ShowPreferredMTU, LOCAL_AUTH,
637184870Syongari  "Show Preferred MTU", "show mtu"},
638184870Syongari  {"ofilter", NULL, ShowOfilter, LOCAL_AUTH,
639184870Syongari  "Show Output filters", "show ofilter option .."},
640184870Syongari  {"proto", NULL, ReportProtStatus, LOCAL_AUTH,
641184870Syongari  "Show protocol summary", "show proto"},
642184870Syongari  {"reconnect", NULL, ShowReconnect, LOCAL_AUTH,
643184870Syongari  "Show reconnect timer", "show reconnect"},
644184870Syongari  {"redial", NULL, ShowRedial, LOCAL_AUTH,
645184870Syongari  "Show Redial timeout", "show redial"},
646184870Syongari  {"route", NULL, ShowRoute, LOCAL_AUTH,
647184870Syongari  "Show routing table", "show route"},
648184870Syongari  {"timeout", NULL, ShowTimeout, LOCAL_AUTH,
649184870Syongari  "Show Idle timeout", "show timeout"},
650184870Syongari  {"stopped", NULL, ShowStopped, LOCAL_AUTH,
651184870Syongari  "Show STOPPED timeout", "show stopped"},
652184870Syongari  {"version", NULL, ShowVersion, LOCAL_NO_AUTH | LOCAL_AUTH,
653184870Syongari  "Show version string", "show version"},
654184870Syongari  {"vj", NULL, ShowInitVJ, LOCAL_AUTH,
655184870Syongari  "Show VJ values", "show vj"},
656184870Syongari  {"help", "?", HelpCommand, LOCAL_NO_AUTH | LOCAL_AUTH,
657184870Syongari  "Display this message", "show help|? [command]", ShowCommands},
658184870Syongari  {NULL, NULL, NULL},
659184870Syongari};
660184870Syongari
661184870Syongaristatic struct cmdtab const *
662184870SyongariFindCommand(struct cmdtab const *cmds, const char *str, int *pmatch)
663184870Syongari{
664184870Syongari  int nmatch;
665184870Syongari  int len;
666184870Syongari  struct cmdtab const *found;
667184870Syongari
668184870Syongari  found = NULL;
669184870Syongari  len = strlen(str);
670184870Syongari  nmatch = 0;
671184870Syongari  while (cmds->func) {
672184870Syongari    if (cmds->name && strncasecmp(str, cmds->name, len) == 0) {
673184870Syongari      if (cmds->name[len] == '\0') {
674184870Syongari	*pmatch = 1;
675184870Syongari	return cmds;
676184870Syongari      }
677184870Syongari      nmatch++;
678217542Sjhb      found = cmds;
679184870Syongari    } else if (cmds->alias && strncasecmp(str, cmds->alias, len) == 0) {
680184870Syongari      if (cmds->alias[len] == '\0') {
681184870Syongari	*pmatch = 1;
682184870Syongari	return cmds;
683184870Syongari      }
684184870Syongari      nmatch++;
685184870Syongari      found = cmds;
686184870Syongari    }
687184870Syongari    cmds++;
688184870Syongari  }
689184870Syongari  *pmatch = nmatch;
690184870Syongari  return found;
691184870Syongari}
692184870Syongari
693184870Syongaristatic int
694184870SyongariFindExec(struct cmdtab const *cmds, int argc, char const *const *argv,
695184870Syongari         const char *prefix)
696184870Syongari{
697184870Syongari  struct cmdtab const *cmd;
698184870Syongari  int val = 1;
699184870Syongari  int nmatch;
700184870Syongari  struct cmdargs arg;
701184870Syongari
702184870Syongari  cmd = FindCommand(cmds, *argv, &nmatch);
703184870Syongari  if (nmatch > 1)
704184870Syongari    LogPrintf(LogWARN, "%s%s: Ambiguous command\n", prefix, *argv);
705184870Syongari  else if (cmd && (cmd->lauth & VarLocalAuth)) {
706184870Syongari    arg.cmd = cmds;
707184870Syongari    arg.argc = argc-1;
708184870Syongari    arg.argv = argv+1;
709184870Syongari    arg.data = cmd->args;
710184870Syongari    val = (cmd->func) (&arg);
711184870Syongari  } else
712184870Syongari    LogPrintf(LogWARN, "%s%s: Invalid command\n", prefix, *argv);
713184870Syongari
714184870Syongari  if (val == -1)
715184870Syongari    LogPrintf(LogWARN, "Usage: %s\n", cmd->syntax);
716184870Syongari  else if (val)
717184870Syongari    LogPrintf(LogWARN, "%s%s: Failed %d\n", prefix, *argv, val);
718184870Syongari
719184870Syongari  return val;
720184870Syongari}
721184870Syongari
722184870Syongariint aft_cmd = 1;
723184870Syongari
724184870Syongarivoid
725184870SyongariPrompt()
726184870Syongari{
727184870Syongari  const char *pconnect, *pauth;
728184870Syongari
729184870Syongari  if (!VarTerm || TermMode)
730184870Syongari    return;
731217323Smdf
732184870Syongari  if (!aft_cmd)
733217323Smdf    fprintf(VarTerm, "\n");
734217323Smdf  else
735217323Smdf    aft_cmd = 0;
736184870Syongari
737184870Syongari  if (VarLocalAuth == LOCAL_AUTH)
738184870Syongari    pauth = " ON ";
739184870Syongari  else
740184870Syongari    pauth = " on ";
741184870Syongari  if (IpcpFsm.state == ST_OPENED && phase == PHASE_NETWORK)
742184870Syongari    pconnect = "PPP";
743184870Syongari  else
744184870Syongari    pconnect = "ppp";
745184870Syongari  fprintf(VarTerm, "%s%s%s> ", pconnect, pauth, VarShortHost);
746184870Syongari  fflush(VarTerm);
747184870Syongari}
748184870Syongari
749184870Syongarivoid
750184870SyongariInterpretCommand(char *buff, int nb, int *argc, char ***argv)
751184870Syongari{
752184870Syongari  static char *vector[MAXARGS];
753184870Syongari  char *cp;
754184870Syongari
755184870Syongari  if (nb > 0) {
756184870Syongari    cp = buff + strcspn(buff, "\r\n");
757184870Syongari    if (cp)
758184870Syongari      *cp = '\0';
759184870Syongari    *argc = MakeArgs(buff, vector, VECSIZE(vector));
760184870Syongari    *argv = vector;
761184870Syongari  } else
762184870Syongari    *argc = 0;
763184870Syongari}
764184870Syongari
765184870Syongaristatic int
766184870Syongariarghidden(int argc, char const *const *argv, int n)
767184870Syongari{
768184870Syongari  /* Is arg n of the given command to be hidden from the log ? */
769184870Syongari
770184870Syongari  /* set authkey xxxxx */
771184870Syongari  /* set key xxxxx */
772184870Syongari  if (n == 2 && !strncasecmp(argv[0], "se", 2) &&
773184870Syongari      (!strncasecmp(argv[1], "authk", 5) || !strncasecmp(argv[1], "ke", 2)))
774184870Syongari    return 1;
775184870Syongari
776184870Syongari  /* passwd xxxxx */
777184870Syongari  if (n == 1 && !strncasecmp(argv[0], "p", 1))
778184870Syongari    return 1;
779184870Syongari
780184870Syongari  return 0;
781184870Syongari}
782184870Syongari
783184870Syongarivoid
784184870SyongariRunCommand(int argc, char const *const *argv, const char *label)
785184870Syongari{
786184870Syongari  if (argc > 0) {
787184870Syongari    if (LogIsKept(LogCOMMAND)) {
788184870Syongari      static char buf[LINE_LEN];
789184870Syongari      int f, n;
790184870Syongari
791184870Syongari      *buf = '\0';
792184870Syongari      if (label) {
793184870Syongari        strncpy(buf, label, sizeof buf - 3);
794184870Syongari        buf[sizeof buf - 3] = '\0';
795184870Syongari        strcat(buf, ": ");
796184870Syongari      }
797184870Syongari      n = strlen(buf);
798184870Syongari      for (f = 0; f < argc; f++) {
799184870Syongari        if (n < sizeof buf - 1 && f)
800184870Syongari          buf[n++] = ' ';
801184870Syongari        if (arghidden(argc, argv, f))
802184870Syongari          strncpy(buf+n, HIDDEN, sizeof buf - n - 1);
803184870Syongari        else
804184870Syongari          strncpy(buf+n, argv[f], sizeof buf - n - 1);
805184870Syongari        n += strlen(buf+n);
806184870Syongari      }
807184870Syongari      LogPrintf(LogCOMMAND, "%s\n", buf);
808184870Syongari    }
809184870Syongari    FindExec(Commands, argc, argv, "");
810184870Syongari  }
811184870Syongari}
812184870Syongari
813184870Syongarivoid
814184870SyongariDecodeCommand(char *buff, int nb, const char *label)
815184870Syongari{
816184870Syongari  int argc;
817184870Syongari  char **argv;
818184870Syongari
819184870Syongari  InterpretCommand(buff, nb, &argc, &argv);
820184870Syongari  RunCommand(argc, (char const *const *)argv, label);
821184870Syongari}
822184870Syongari
823184870Syongaristatic int
824184870SyongariShowCommand(struct cmdargs const *arg)
825184870Syongari{
826184870Syongari  if (arg->argc > 0)
827184870Syongari    FindExec(ShowCommands, arg->argc, arg->argv, "show ");
828184870Syongari  else if (VarTerm)
829184870Syongari    fprintf(VarTerm, "Use ``show ?'' to get a arg->cmd.\n");
830184870Syongari  else
831184870Syongari    LogPrintf(LogWARN, "show command must have arguments\n");
832184870Syongari
833184870Syongari  return 0;
834184870Syongari}
835184870Syongari
836184870Syongaristatic int
837184870SyongariTerminalCommand(struct cmdargs const *arg)
838184870Syongari{
839184870Syongari  if (LcpFsm.state > ST_CLOSED) {
840184870Syongari    if (VarTerm)
841184870Syongari      fprintf(VarTerm, "LCP state is [%s]\n", StateNames[LcpFsm.state]);
842184870Syongari    return 1;
843184870Syongari  }
844184870Syongari  if (!IsInteractive(1))
845184870Syongari    return (1);
846184870Syongari  if (OpenModem() < 0) {
847184870Syongari    if (VarTerm)
848184870Syongari      fprintf(VarTerm, "Failed to open modem.\n");
849184870Syongari    return (1);
850184870Syongari  }
851184870Syongari  if (VarTerm) {
852184870Syongari    fprintf(VarTerm, "Entering terminal mode.\n");
853184870Syongari    fprintf(VarTerm, "Type `~?' for help.\n");
854184870Syongari  }
855184870Syongari  TtyTermMode();
856184870Syongari  return (0);
857184870Syongari}
858184870Syongari
859184870Syongaristatic int
860184870SyongariQuitCommand(struct cmdargs const *arg)
861184870Syongari{
862184870Syongari  if (VarTerm) {
863184870Syongari    DropClient(1);
864184870Syongari    if (mode & MODE_INTER)
865184870Syongari      Cleanup(EX_NORMAL);
866184870Syongari    else if (arg->argc > 0 && !strcasecmp(*arg->argv, "all") && VarLocalAuth&LOCAL_AUTH)
867184870Syongari      Cleanup(EX_NORMAL);
868184870Syongari  }
869184870Syongari
870184870Syongari  return 0;
871184870Syongari}
872184870Syongari
873184870Syongaristatic int
874184870SyongariCloseCommand(struct cmdargs const *arg)
875184870Syongari{
876184870Syongari  reconnect(RECON_FALSE);
877184870Syongari  LcpClose();
878184870Syongari  return 0;
879184870Syongari}
880184870Syongari
881184870Syongaristatic int
882184870SyongariDownCommand(struct cmdargs const *arg)
883184870Syongari{
884184870Syongari  LcpDown();
885184870Syongari  return 0;
886184870Syongari}
887184870Syongari
888184870Syongaristatic int
889184870SyongariSetModemSpeed(struct cmdargs const *arg)
890184870Syongari{
891184870Syongari  int speed;
892184870Syongari
893184870Syongari  if (arg->argc > 0) {
894184870Syongari    if (strcasecmp(*arg->argv, "sync") == 0) {
895184870Syongari      VarSpeed = 0;
896184870Syongari      return 0;
897184870Syongari    }
898184870Syongari    speed = atoi(*arg->argv);
899184870Syongari    if (IntToSpeed(speed) != B0) {
900184870Syongari      VarSpeed = speed;
901184870Syongari      return 0;
902184870Syongari    }
903184870Syongari    LogPrintf(LogWARN, "%s: Invalid speed\n", *arg->argv);
904184870Syongari  }
905184870Syongari  return -1;
906184870Syongari}
907184870Syongari
908184870Syongaristatic int
909184870SyongariSetReconnect(struct cmdargs const *arg)
910184870Syongari{
911184870Syongari  if (arg->argc == 2) {
912184870Syongari    VarReconnectTimer = atoi(arg->argv[0]);
913184870Syongari    VarReconnectTries = atoi(arg->argv[1]);
914184870Syongari    return 0;
915184870Syongari  }
916184870Syongari  return -1;
917184870Syongari}
918184870Syongari
919184870Syongaristatic int
920184870SyongariSetRedialTimeout(struct cmdargs const *arg)
921184870Syongari{
922184870Syongari  int timeout;
923184870Syongari  int tries;
924184870Syongari  char *dot;
925184870Syongari
926184870Syongari  if (arg->argc == 1 || arg->argc == 2) {
927184870Syongari    if (strncasecmp(arg->argv[0], "random", 6) == 0 &&
928184870Syongari	(arg->argv[0][6] == '\0' || arg->argv[0][6] == '.')) {
929184870Syongari      VarRedialTimeout = -1;
930184870Syongari      randinit();
931184870Syongari    } else {
932184870Syongari      timeout = atoi(arg->argv[0]);
933184870Syongari
934184870Syongari      if (timeout >= 0)
935184870Syongari	VarRedialTimeout = timeout;
936184870Syongari      else {
937184870Syongari	LogPrintf(LogWARN, "Invalid redial timeout\n");
938184870Syongari	return -1;
939184870Syongari      }
940184870Syongari    }
941184870Syongari
942184870Syongari    dot = strchr(arg->argv[0], '.');
943184870Syongari    if (dot) {
944184870Syongari      if (strcasecmp(++dot, "random") == 0) {
945184870Syongari	VarRedialNextTimeout = -1;
946184870Syongari	randinit();
947184870Syongari      } else {
948184870Syongari	timeout = atoi(dot);
949184870Syongari	if (timeout >= 0)
950184870Syongari	  VarRedialNextTimeout = timeout;
951184870Syongari	else {
952184870Syongari	  LogPrintf(LogWARN, "Invalid next redial timeout\n");
953184870Syongari	  return -1;
954184870Syongari	}
955184870Syongari      }
956184870Syongari    } else
957184870Syongari      VarRedialNextTimeout = NEXT_REDIAL_PERIOD;	/* Default next timeout */
958184870Syongari
959184870Syongari    if (arg->argc == 2) {
960184870Syongari      tries = atoi(arg->argv[1]);
961184870Syongari
962184870Syongari      if (tries >= 0) {
963184870Syongari	VarDialTries = tries;
964184870Syongari      } else {
965184870Syongari	LogPrintf(LogWARN, "Invalid retry value\n");
966184870Syongari	return 1;
967184870Syongari      }
968184870Syongari    }
969184870Syongari    return 0;
970184870Syongari  }
971184870Syongari  return -1;
972184870Syongari}
973184870Syongari
974184870Syongaristatic int
975184870SyongariSetStoppedTimeout(struct cmdargs const *arg)
976184870Syongari{
977184870Syongari  LcpFsm.StoppedTimer.load = 0;
978184870Syongari  IpcpFsm.StoppedTimer.load = 0;
979184870Syongari  CcpFsm.StoppedTimer.load = 0;
980184870Syongari  if (arg->argc <= 3) {
981184870Syongari    if (arg->argc > 0) {
982184870Syongari      LcpFsm.StoppedTimer.load = atoi(arg->argv[0]) * SECTICKS;
983184870Syongari      if (arg->argc > 1) {
984184870Syongari	IpcpFsm.StoppedTimer.load = atoi(arg->argv[1]) * SECTICKS;
985184870Syongari	if (arg->argc > 2)
986184870Syongari	  CcpFsm.StoppedTimer.load = atoi(arg->argv[2]) * SECTICKS;
987184870Syongari      }
988184870Syongari    }
989184870Syongari    return 0;
990184870Syongari  }
991184870Syongari  return -1;
992184870Syongari}
993184870Syongari
994184870Syongari#define ismask(x) \
995184870Syongari  (*x == '0' && strlen(x) == 4 && strspn(x+1, "0123456789.") == 3)
996184870Syongari
997184870Syongaristatic int
998184870SyongariSetServer(struct cmdargs const *arg)
999184870Syongari{
1000184870Syongari  int res = -1;
1001184870Syongari
1002184870Syongari  if (arg->argc > 0 && arg->argc < 4) {
1003184870Syongari    const char *port, *passwd, *mask;
1004184870Syongari
1005184870Syongari    /* What's what ? */
1006184870Syongari    port = arg->argv[0];
1007184870Syongari    if (arg->argc == 2) {
1008184870Syongari      if (ismask(arg->argv[1])) {
1009184870Syongari        passwd = NULL;
1010184870Syongari        mask = arg->argv[1];
1011184870Syongari      } else {
1012184870Syongari        passwd = arg->argv[1];
1013184870Syongari        mask = NULL;
1014184870Syongari      }
1015184870Syongari    } else if (arg->argc == 3) {
1016184870Syongari      passwd = arg->argv[1];
1017184870Syongari      mask = arg->argv[2];
1018184870Syongari      if (!ismask(mask))
1019184870Syongari        return -1;
1020184870Syongari    } else
1021184870Syongari      passwd = mask = NULL;
1022184870Syongari
1023184870Syongari    if (passwd == NULL)
1024184870Syongari      VarHaveLocalAuthKey = 0;
1025184870Syongari    else {
1026184870Syongari      strncpy(VarLocalAuthKey, passwd, sizeof VarLocalAuthKey - 1);
1027184870Syongari      VarLocalAuthKey[sizeof VarLocalAuthKey - 1] = '\0';
1028184870Syongari      VarHaveLocalAuthKey = 1;
1029184870Syongari    }
1030184870Syongari    LocalAuthInit();
1031184870Syongari
1032184870Syongari    if (strcasecmp(port, "none") == 0) {
1033184870Syongari      int oserver;
1034184870Syongari
1035184870Syongari      if (mask != NULL || passwd != NULL)
1036184870Syongari        return -1;
1037184870Syongari      oserver = server;
1038184870Syongari      ServerClose();
1039184870Syongari      if (oserver != -1)
1040184870Syongari        LogPrintf(LogPHASE, "Disabling server port.\n");
1041184870Syongari      res = 0;
1042184870Syongari    } else if (*port == '/') {
1043184870Syongari      mode_t imask;
1044184870Syongari
1045184870Syongari      if (mask != NULL) {
1046184870Syongari	unsigned m;
1047184870Syongari
1048184870Syongari	if (sscanf(mask, "%o", &m) == 1)
1049184870Syongari	  imask = m;
1050184870Syongari        else
1051184870Syongari          return -1;
1052184870Syongari      } else
1053184870Syongari        imask = (mode_t)-1;
1054184870Syongari      res = ServerLocalOpen(port, imask);
1055184870Syongari    } else {
1056184870Syongari      int iport;
1057184870Syongari
1058184870Syongari      if (mask != NULL)
1059184870Syongari        return -1;
1060184870Syongari
1061184870Syongari      if (strspn(port, "0123456789") != strlen(port)) {
1062184870Syongari        struct servent *s;
1063184870Syongari
1064184870Syongari        if ((s = getservbyname(port, "tcp")) == NULL) {
1065184870Syongari	  iport = 0;
1066184870Syongari	  LogPrintf(LogWARN, "%s: Invalid port or service\n", port);
1067184870Syongari	} else
1068184870Syongari	  iport = ntohs(s->s_port);
1069184870Syongari      } else
1070184870Syongari        iport = atoi(port);
1071184870Syongari      res = iport ? ServerTcpOpen(iport) : -1;
1072184870Syongari    }
1073184870Syongari  }
1074184870Syongari
1075184870Syongari  return res;
1076184870Syongari}
1077184870Syongari
1078184870Syongaristatic int
1079184870SyongariSetModemParity(struct cmdargs const *arg)
1080184870Syongari{
1081184870Syongari  return arg->argc > 0 ? ChangeParity(*arg->argv) : -1;
1082184870Syongari}
1083184870Syongari
1084184870Syongaristatic int
1085184870SyongariSetLogLevel(struct cmdargs const *arg)
1086184870Syongari{
1087184870Syongari  int i;
1088184870Syongari  int res;
1089184870Syongari  int argc;
1090184870Syongari  char const *const *argv, *argp;
1091184870Syongari  void (*Discard)(int), (*Keep)(int);
1092184870Syongari  void (*DiscardAll)(void);
1093184870Syongari
1094184870Syongari  argc = arg->argc;
1095184870Syongari  argv = arg->argv;
1096184870Syongari  res = 0;
1097184870Syongari  if (argc == 0 || strcasecmp(argv[0], "local")) {
1098184870Syongari    Discard = LogDiscard;
1099184870Syongari    Keep = LogKeep;
1100184870Syongari    DiscardAll = LogDiscardAll;
1101184870Syongari  } else {
1102184870Syongari    argc--;
1103184870Syongari    argv++;
1104184870Syongari    Discard = LogDiscardLocal;
1105184870Syongari    Keep = LogKeepLocal;
1106184870Syongari    DiscardAll = LogDiscardAllLocal;
1107184870Syongari  }
1108184870Syongari
1109184870Syongari  if (argc == 0 || (argv[0][0] != '+' && argv[0][0] != '-'))
1110184870Syongari    DiscardAll();
1111184870Syongari  while (argc--) {
1112184870Syongari    argp = **argv == '+' || **argv == '-' ? *argv + 1 : *argv;
1113184870Syongari    for (i = LogMIN; i <= LogMAX; i++)
1114184870Syongari      if (strcasecmp(argp, LogName(i)) == 0) {
1115184870Syongari	if (**argv == '-')
1116184870Syongari	  (*Discard)(i);
1117184870Syongari	else
1118184870Syongari	  (*Keep)(i);
1119184870Syongari	break;
1120184870Syongari      }
1121184870Syongari    if (i > LogMAX) {
1122184870Syongari      LogPrintf(LogWARN, "%s: Invalid log value\n", argp);
1123184870Syongari      res = -1;
1124184870Syongari    }
1125184870Syongari    argv++;
1126184870Syongari  }
1127184870Syongari  return res;
1128184870Syongari}
1129184870Syongari
1130184870Syongaristatic int
1131184870SyongariSetEscape(struct cmdargs const *arg)
1132184870Syongari{
1133184870Syongari  int code;
1134184870Syongari  int argc = arg->argc;
1135184870Syongari  char const *const *argv = arg->argv;
1136184870Syongari
1137184870Syongari  for (code = 0; code < 33; code++)
1138184870Syongari    EscMap[code] = 0;
1139184870Syongari
1140184870Syongari  while (argc-- > 0) {
1141184870Syongari    sscanf(*argv++, "%x", &code);
1142184870Syongari    code &= 0xff;
1143184870Syongari    EscMap[code >> 3] |= (1 << (code & 7));
1144184870Syongari    EscMap[32] = 1;
1145184870Syongari  }
1146184870Syongari  return 0;
1147184870Syongari}
1148184870Syongari
1149184870Syongaristatic int
1150184870SyongariSetInitialMRU(struct cmdargs const *arg)
1151184870Syongari{
1152184870Syongari  long mru;
1153184870Syongari  const char *err;
1154184870Syongari
1155184870Syongari  if (arg->argc > 0) {
1156184870Syongari    mru = atol(*arg->argv);
1157184870Syongari    if (mru < MIN_MRU)
1158184870Syongari      err = "Given MRU value (%ld) is too small.\n";
1159184870Syongari    else if (mru > MAX_MRU)
1160184870Syongari      err = "Given MRU value (%ld) is too big.\n";
1161184870Syongari    else {
1162184870Syongari      VarMRU = mru;
1163184870Syongari      return 0;
1164184870Syongari    }
1165184870Syongari    LogPrintf(LogWARN, err, mru);
1166184870Syongari  }
1167184870Syongari  return -1;
1168184870Syongari}
1169184870Syongari
1170184870Syongaristatic int
1171184870SyongariSetPreferredMTU(struct cmdargs const *arg)
1172184870Syongari{
1173184870Syongari  long mtu;
1174184870Syongari  const char *err;
1175184870Syongari
1176184870Syongari  if (arg->argc > 0) {
1177184870Syongari    mtu = atol(*arg->argv);
1178184870Syongari    if (mtu == 0) {
1179184870Syongari      VarPrefMTU = 0;
1180184870Syongari      return 0;
1181184870Syongari    } else if (mtu < MIN_MTU)
1182184870Syongari      err = "Given MTU value (%ld) is too small.\n";
1183184870Syongari    else if (mtu > MAX_MTU)
1184184870Syongari      err = "Given MTU value (%ld) is too big.\n";
1185184870Syongari    else {
1186184870Syongari      VarPrefMTU = mtu;
1187184870Syongari      return 0;
1188184870Syongari    }
1189184870Syongari    LogPrintf(LogWARN, err, mtu);
1190184870Syongari  }
1191184870Syongari  return -1;
1192184870Syongari}
1193184870Syongari
1194184870Syongaristatic int
1195184870SyongariSetTimeout(struct cmdargs const *arg)
1196184870Syongari{
1197184870Syongari  if (arg->argc > 0) {
1198184870Syongari    VarIdleTimeout = atoi(arg->argv[0]);
1199184870Syongari    UpdateIdleTimer();		/* If we're connected, restart the idle timer */
1200184870Syongari    if (arg->argc > 1) {
1201184870Syongari      VarLqrTimeout = atoi(arg->argv[1]);
1202184870Syongari      if (VarLqrTimeout < 1)
1203184870Syongari	VarLqrTimeout = 30;
1204184870Syongari      if (arg->argc > 2) {
1205184870Syongari	VarRetryTimeout = atoi(arg->argv[2]);
1206184870Syongari	if (VarRetryTimeout < 1 || VarRetryTimeout > 10)
1207184870Syongari	  VarRetryTimeout = 3;
1208184870Syongari      }
1209184870Syongari    }
1210184870Syongari    return 0;
1211184870Syongari  }
1212184870Syongari  return -1;
1213184870Syongari}
1214184870Syongari
1215184870Syongaristatic struct in_addr
1216184870SyongariGetIpAddr(const char *cp)
1217184870Syongari{
1218184870Syongari  struct hostent *hp;
1219184870Syongari  struct in_addr ipaddr;
1220184870Syongari
1221184870Syongari  if (inet_aton(cp, &ipaddr) == 0) {
1222184870Syongari    hp = gethostbyname(cp);
1223184870Syongari    if (hp && hp->h_addrtype == AF_INET)
1224184870Syongari      memcpy(&ipaddr, hp->h_addr, hp->h_length);
1225184870Syongari    else
1226184870Syongari      ipaddr.s_addr = 0;
1227184870Syongari  }
1228184870Syongari  return (ipaddr);
1229184870Syongari}
1230184870Syongari
1231184870Syongaristatic int
1232184870SyongariSetInterfaceAddr(struct cmdargs const *arg)
1233184870Syongari{
1234184870Syongari  const char *hisaddr;
1235184870Syongari
1236184870Syongari  hisaddr = NULL;
1237184870Syongari  DefMyAddress.ipaddr.s_addr = DefHisAddress.ipaddr.s_addr = 0L;
1238184870Syongari
1239184870Syongari  if (arg->argc > 4)
1240184870Syongari    return -1;
1241184870Syongari
1242184870Syongari  HaveTriggerAddress = 0;
1243184870Syongari  ifnetmask.s_addr = 0;
1244184870Syongari  iplist_reset(&DefHisChoice);
1245184870Syongari
1246184870Syongari  if (arg->argc > 0) {
1247184870Syongari    if (!ParseAddr(arg->argc, arg->argv, &DefMyAddress.ipaddr,
1248184870Syongari		   &DefMyAddress.mask, &DefMyAddress.width))
1249184870Syongari      return 1;
1250184870Syongari    if (arg->argc > 1) {
1251184870Syongari      hisaddr = arg->argv[1];
1252184870Syongari      if (arg->argc > 2) {
1253184870Syongari	ifnetmask = GetIpAddr(arg->argv[2]);
1254184870Syongari	if (arg->argc > 3) {
1255184870Syongari	  TriggerAddress = GetIpAddr(arg->argv[3]);
1256184870Syongari	  HaveTriggerAddress = 1;
1257184870Syongari	}
1258184870Syongari      }
1259184870Syongari    }
1260184870Syongari  }
1261184870Syongari
1262184870Syongari  /*
1263184870Syongari   * For backwards compatibility, 0.0.0.0 means any address.
1264184870Syongari   */
1265184870Syongari  if (DefMyAddress.ipaddr.s_addr == 0) {
1266184870Syongari    DefMyAddress.mask.s_addr = 0;
1267184870Syongari    DefMyAddress.width = 0;
1268184870Syongari  }
1269184870Syongari  IpcpInfo.want_ipaddr.s_addr = DefMyAddress.ipaddr.s_addr;
1270184870Syongari  if (DefHisAddress.ipaddr.s_addr == 0) {
1271184870Syongari    DefHisAddress.mask.s_addr = 0;
1272184870Syongari    DefHisAddress.width = 0;
1273184870Syongari  }
1274184870Syongari
1275184870Syongari  if (hisaddr && !UseHisaddr(hisaddr, mode & MODE_AUTO))
1276184870Syongari    return 4;
1277184870Syongari
1278184870Syongari  return 0;
1279184870Syongari}
1280184870Syongari
1281184870Syongari#ifndef NOMSEXT
1282184870Syongari
1283184870Syongaristatic void
1284184870SyongariSetMSEXT(struct in_addr * pri_addr,
1285184870Syongari	 struct in_addr * sec_addr,
1286184870Syongari	 int argc,
1287184870Syongari	 char const *const *argv)
1288184870Syongari{
1289184870Syongari  int dummyint;
1290184870Syongari  struct in_addr dummyaddr;
1291184870Syongari
1292184870Syongari  pri_addr->s_addr = sec_addr->s_addr = 0L;
1293184870Syongari
1294184870Syongari  if (argc > 0) {
1295184870Syongari    ParseAddr(argc, argv++, pri_addr, &dummyaddr, &dummyint);
1296184870Syongari    if (--argc > 0)
1297184870Syongari      ParseAddr(argc, argv++, sec_addr, &dummyaddr, &dummyint);
1298184870Syongari    else
1299184870Syongari      sec_addr->s_addr = pri_addr->s_addr;
1300184870Syongari  }
1301184870Syongari
1302184870Syongari  /*
1303184870Syongari   * if the primary/secondary ns entries are 0.0.0.0 we should set them to
1304184870Syongari   * either the localhost's ip, or the values in /etc/resolv.conf ??
1305184870Syongari   *
1306184870Syongari   * up to you if you want to implement this...
1307184870Syongari   */
1308184870Syongari
1309184870Syongari}
1310184870Syongari
1311184870Syongaristatic int
1312184870SyongariSetNS(struct cmdargs const *arg)
1313184870Syongari{
1314184870Syongari  SetMSEXT(&ns_entries[0], &ns_entries[1], arg->argc, arg->argv);
1315184870Syongari  return 0;
1316184870Syongari}
1317184870Syongari
1318184870Syongaristatic int
1319184870SyongariSetNBNS(struct cmdargs const *arg)
1320184870Syongari{
1321184870Syongari  SetMSEXT(&nbns_entries[0], &nbns_entries[1], arg->argc, arg->argv);
1322184870Syongari  return 0;
1323184870Syongari}
1324184870Syongari
1325184870Syongari#endif				/* MS_EXT */
1326184870Syongari
1327184870Syongariint
1328184870SyongariSetVariable(struct cmdargs const *arg)
1329184870Syongari{
1330184870Syongari  u_long map;
1331184870Syongari  const char *argp;
1332184870Syongari  int param = (int)arg->data;
1333184870Syongari
1334184870Syongari  if (arg->argc > 0)
1335184870Syongari    argp = *arg->argv;
1336184870Syongari  else
1337184870Syongari    argp = "";
1338184870Syongari
1339184870Syongari  switch (param) {
1340184870Syongari  case VAR_AUTHKEY:
1341184870Syongari    strncpy(VarAuthKey, argp, sizeof VarAuthKey - 1);
1342184870Syongari    VarAuthKey[sizeof VarAuthKey - 1] = '\0';
1343184870Syongari    break;
1344184870Syongari  case VAR_AUTHNAME:
1345184870Syongari    strncpy(VarAuthName, argp, sizeof VarAuthName - 1);
1346184870Syongari    VarAuthName[sizeof VarAuthName - 1] = '\0';
1347184870Syongari    break;
1348184870Syongari  case VAR_DIAL:
1349184870Syongari    strncpy(VarDialScript, argp, sizeof VarDialScript - 1);
1350184870Syongari    VarDialScript[sizeof VarDialScript - 1] = '\0';
1351184870Syongari    break;
1352184870Syongari  case VAR_LOGIN:
1353184870Syongari    strncpy(VarLoginScript, argp, sizeof VarLoginScript - 1);
1354184870Syongari    VarLoginScript[sizeof VarLoginScript - 1] = '\0';
1355184870Syongari    break;
1356184870Syongari  case VAR_DEVICE:
1357184870Syongari    if (mode & MODE_INTER)
1358184870Syongari      HangupModem(0);
1359184870Syongari    if (modem != -1)
1360184870Syongari      LogPrintf(LogWARN, "Cannot change device to \"%s\" when \"%s\" is open\n",
1361184870Syongari                argp, VarDevice);
1362184870Syongari    else {
1363184870Syongari      strncpy(VarDeviceList, argp, sizeof VarDeviceList - 1);
1364184870Syongari      VarDeviceList[sizeof VarDeviceList - 1] = '\0';
1365184870Syongari    }
1366184870Syongari    break;
1367184870Syongari  case VAR_ACCMAP:
1368184870Syongari    sscanf(argp, "%lx", &map);
1369184870Syongari    VarAccmap = map;
1370184870Syongari    break;
1371184870Syongari  case VAR_PHONE:
1372184870Syongari    strncpy(VarPhoneList, argp, sizeof VarPhoneList - 1);
1373184870Syongari    VarPhoneList[sizeof VarPhoneList - 1] = '\0';
1374184870Syongari    strncpy(VarPhoneCopy, VarPhoneList, sizeof VarPhoneCopy - 1);
1375184870Syongari    VarPhoneCopy[sizeof VarPhoneCopy - 1] = '\0';
1376184870Syongari    VarNextPhone = VarPhoneCopy;
1377184870Syongari    VarAltPhone = NULL;
1378184870Syongari    break;
1379184870Syongari  case VAR_HANGUP:
1380184870Syongari    strncpy(VarHangupScript, argp, sizeof VarHangupScript - 1);
1381184870Syongari    VarHangupScript[sizeof VarHangupScript - 1] = '\0';
1382184870Syongari    break;
1383184870Syongari#ifdef HAVE_DES
1384184870Syongari  case VAR_ENC:
1385184870Syongari    VarMSChap = !strcasecmp(argp, "mschap");
1386184870Syongari    break;
1387184870Syongari#endif
1388184870Syongari  }
1389184870Syongari  return 0;
1390184870Syongari}
1391184870Syongari
1392184870Syongaristatic int
1393184870SyongariSetCtsRts(struct cmdargs const *arg)
1394184870Syongari{
1395184870Syongari  if (arg->argc > 0) {
1396184870Syongari    if (strcmp(*arg->argv, "on") == 0)
1397184870Syongari      VarCtsRts = 1;
1398184870Syongari    else if (strcmp(*arg->argv, "off") == 0)
1399184870Syongari      VarCtsRts = 0;
1400184870Syongari    else
1401184870Syongari      return -1;
1402184870Syongari    return 0;
1403184870Syongari  }
1404184870Syongari  return -1;
1405184870Syongari}
1406184870Syongari
1407184870Syongari
1408184870Syongaristatic int
1409184870SyongariSetOpenMode(struct cmdargs const *arg)
1410184870Syongari{
1411184870Syongari  if (arg->argc > 0) {
1412184870Syongari    if (strcasecmp(*arg->argv, "active") == 0)
1413184870Syongari      VarOpenMode = arg->argc > 1 ? atoi(arg->argv[1]) : 1;
1414184870Syongari    else if (strcasecmp(*arg->argv, "passive") == 0)
1415184870Syongari      VarOpenMode = OPEN_PASSIVE;
1416184870Syongari    else
1417184870Syongari      return -1;
1418184870Syongari    return 0;
1419184870Syongari  }
1420184870Syongari  return -1;
1421184870Syongari}
1422184870Syongari
1423184870Syongaristatic struct cmdtab const SetCommands[] = {
1424184870Syongari  {"accmap", NULL, SetVariable, LOCAL_AUTH,
1425184870Syongari  "Set accmap value", "set accmap hex-value", (const void *) VAR_ACCMAP},
1426184870Syongari  {"afilter", NULL, SetAfilter, LOCAL_AUTH,
1427184870Syongari  "Set keep Alive filter", "set afilter ..."},
1428184870Syongari  {"authkey", "key", SetVariable, LOCAL_AUTH,
1429184870Syongari  "Set authentication key", "set authkey|key key", (const void *) VAR_AUTHKEY},
1430184870Syongari  {"authname", NULL, SetVariable, LOCAL_AUTH,
1431184870Syongari  "Set authentication name", "set authname name", (const void *) VAR_AUTHNAME},
1432184870Syongari  {"ctsrts", NULL, SetCtsRts, LOCAL_AUTH,
1433184870Syongari  "Use CTS/RTS modem signalling", "set ctsrts [on|off]"},
1434184870Syongari  {"device", "line", SetVariable, LOCAL_AUTH, "Set modem device name",
1435184870Syongari  "set device|line device-name[,device-name]", (const void *) VAR_DEVICE},
1436184870Syongari  {"dfilter", NULL, SetDfilter, LOCAL_AUTH,
1437184870Syongari  "Set demand filter", "set dfilter ..."},
1438184870Syongari  {"dial", NULL, SetVariable, LOCAL_AUTH,
1439184870Syongari  "Set dialing script", "set dial chat-script", (const void *) VAR_DIAL},
1440184870Syongari#ifdef HAVE_DES
1441184870Syongari  {"encrypt", NULL, SetVariable, LOCAL_AUTH, "Set CHAP encryption algorithm",
1442184870Syongari  "set encrypt MSChap|MD5", (const void *) VAR_ENC},
1443184870Syongari#endif
1444184870Syongari  {"escape", NULL, SetEscape, LOCAL_AUTH,
1445184870Syongari  "Set escape characters", "set escape hex-digit ..."},
1446184870Syongari  {"hangup", NULL, SetVariable, LOCAL_AUTH,
1447184870Syongari  "Set hangup script", "set hangup chat-script", (const void *) VAR_HANGUP},
1448184870Syongari  {"ifaddr", NULL, SetInterfaceAddr, LOCAL_AUTH, "Set destination address",
1449184870Syongari  "set ifaddr [src-addr [dst-addr [netmask [trg-addr]]]]"},
1450184870Syongari  {"ifilter", NULL, SetIfilter, LOCAL_AUTH,
1451184870Syongari  "Set input filter", "set ifilter ..."},
1452184870Syongari  {"loopback", NULL, SetLoopback, LOCAL_AUTH,
1453184870Syongari  "Set loopback facility", "set loopback on|off"},
1454184870Syongari  {"log", NULL, SetLogLevel, LOCAL_AUTH,
1455184870Syongari  "Set log level", "set log [local] [+|-]value..."},
1456184870Syongari  {"login", NULL, SetVariable, LOCAL_AUTH,
1457184870Syongari  "Set login script", "set login chat-script", (const void *) VAR_LOGIN},
1458184870Syongari  {"mru", NULL, SetInitialMRU, LOCAL_AUTH,
1459184870Syongari  "Set Initial MRU value", "set mru value"},
1460184870Syongari  {"mtu", NULL, SetPreferredMTU, LOCAL_AUTH,
1461184870Syongari  "Set Preferred MTU value", "set mtu value"},
1462184870Syongari#ifndef NOMSEXT
1463184870Syongari  {"nbns", NULL, SetNBNS, LOCAL_AUTH,
1464184870Syongari  "Set NetBIOS NameServer", "set nbns pri-addr [sec-addr]"},
1465184870Syongari  {"ns", NULL, SetNS, LOCAL_AUTH,
1466184870Syongari  "Set NameServer", "set ns pri-addr [sec-addr]"},
1467184870Syongari#endif
1468184870Syongari  {"ofilter", NULL, SetOfilter, LOCAL_AUTH,
1469184870Syongari  "Set output filter", "set ofilter ..."},
1470184870Syongari  {"openmode", NULL, SetOpenMode, LOCAL_AUTH,
1471184870Syongari  "Set open mode", "set openmode [active|passive]"},
1472219902Sjhb  {"parity", NULL, SetModemParity, LOCAL_AUTH,
1473184870Syongari  "Set modem parity", "set parity [odd|even|none]"},
1474184870Syongari  {"phone", NULL, SetVariable, LOCAL_AUTH, "Set telephone number(s)",
1475184870Syongari  "set phone phone1[:phone2[...]]", (const void *) VAR_PHONE},
1476184870Syongari  {"reconnect", NULL, SetReconnect, LOCAL_AUTH,
1477184870Syongari  "Set Reconnect timeout", "set reconnect value ntries"},
1478184870Syongari  {"redial", NULL, SetRedialTimeout, LOCAL_AUTH, "Set Redial timeout",
1479184870Syongari  "set redial value|random[.value|random] [dial_attempts]"},
1480184870Syongari  {"stopped", NULL, SetStoppedTimeout, LOCAL_AUTH, "Set STOPPED timeouts",
1481184870Syongari  "set stopped [LCPseconds [IPCPseconds [CCPseconds]]]"},
1482184870Syongari  {"server", "socket", SetServer, LOCAL_AUTH,
1483184870Syongari  "Set server port", "set server|socket TcpPort|LocalName|none [mask]"},
1484184870Syongari  {"speed", NULL, SetModemSpeed, LOCAL_AUTH,
1485184870Syongari  "Set modem speed", "set speed value"},
1486184870Syongari  {"timeout", NULL, SetTimeout, LOCAL_AUTH,
1487184870Syongari  "Set Idle timeout", "set timeout idle LQR FSM-resend"},
1488184870Syongari  {"vj", NULL, SetInitVJ, LOCAL_AUTH,
1489184870Syongari  "Set vj values", "set vj slots|slotcomp"},
1490184870Syongari  {"help", "?", HelpCommand, LOCAL_AUTH | LOCAL_NO_AUTH,
1491184870Syongari  "Display this message", "set help|? [command]", SetCommands},
1492184870Syongari  {NULL, NULL, NULL},
1493184870Syongari};
1494184870Syongari
1495184870Syongaristatic int
1496184870SyongariSetCommand(struct cmdargs const *arg)
1497184870Syongari{
1498184870Syongari  if (arg->argc > 0)
1499184870Syongari    FindExec(SetCommands, arg->argc, arg->argv, "set ");
1500184870Syongari  else if (VarTerm)
1501184870Syongari    fprintf(VarTerm, "Use `set ?' to get a arg->cmd or `set ? <var>' for"
1502184870Syongari	    " syntax help.\n");
1503184870Syongari  else
1504184870Syongari    LogPrintf(LogWARN, "set command must have arguments\n");
1505184870Syongari
1506184870Syongari  return 0;
1507184870Syongari}
1508184870Syongari
1509184870Syongari
1510184870Syongaristatic int
1511184870SyongariAddCommand(struct cmdargs const *arg)
1512184870Syongari{
1513184870Syongari  struct in_addr dest, gateway, netmask;
1514184870Syongari  int gw;
1515184870Syongari
1516184870Syongari  if (arg->argc != 3 && arg->argc != 2)
1517184870Syongari    return -1;
1518184870Syongari
1519184870Syongari  if (arg->argc == 2) {
1520184870Syongari    if (strcasecmp(arg->argv[0], "default"))
1521184870Syongari      return -1;
1522184870Syongari    else {
1523184870Syongari      dest.s_addr = netmask.s_addr = INADDR_ANY;
1524184870Syongari      gw = 1;
1525184870Syongari    }
1526184870Syongari  } else {
1527184870Syongari    if (strcasecmp(arg->argv[0], "MYADDR") == 0)
1528184870Syongari      dest = IpcpInfo.want_ipaddr;
1529184870Syongari    else if (strcasecmp(arg->argv[0], "HISADDR") == 0)
1530184870Syongari      dest = IpcpInfo.his_ipaddr;
1531184870Syongari    else
1532184870Syongari      dest = GetIpAddr(arg->argv[0]);
1533184870Syongari    netmask = GetIpAddr(arg->argv[1]);
1534184870Syongari    gw = 2;
1535184870Syongari  }
1536184870Syongari  if (strcasecmp(arg->argv[gw], "HISADDR") == 0)
1537184870Syongari    gateway = IpcpInfo.his_ipaddr;
1538184870Syongari  else if (strcasecmp(arg->argv[gw], "INTERFACE") == 0)
1539184870Syongari    gateway.s_addr = INADDR_ANY;
1540184870Syongari  else
1541184870Syongari    gateway = GetIpAddr(arg->argv[gw]);
1542184870Syongari  OsSetRoute(RTM_ADD, dest, gateway, netmask, arg->data ? 1 : 0);
1543184870Syongari  return 0;
1544184870Syongari}
1545184870Syongari
1546189379Syongaristatic int
1547184870SyongariDeleteCommand(struct cmdargs const *arg)
1548184870Syongari{
1549184870Syongari  struct in_addr dest, none;
1550184870Syongari
1551219902Sjhb  if (arg->argc == 1) {
1552184870Syongari    if(strcasecmp(arg->argv[0], "all") == 0)
1553184870Syongari      DeleteIfRoutes(0);
1554184870Syongari    else {
1555184870Syongari      if (strcasecmp(arg->argv[0], "MYADDR") == 0)
1556184870Syongari        dest = IpcpInfo.want_ipaddr;
1557184870Syongari      else if (strcasecmp(arg->argv[0], "default") == 0)
1558184870Syongari        dest.s_addr = INADDR_ANY;
1559184870Syongari      else
1560184870Syongari        dest = GetIpAddr(arg->argv[0]);
1561184870Syongari      none.s_addr = INADDR_ANY;
1562184870Syongari      OsSetRoute(RTM_DELETE, dest, none, none, arg->data ? 1 : 0);
1563184870Syongari    }
1564184870Syongari  } else
1565184870Syongari    return -1;
1566184870Syongari
1567184870Syongari  return 0;
1568184870Syongari}
1569184870Syongari
1570184870Syongari#ifndef NOALIAS
1571184870Syongaristatic struct cmdtab const AliasCommands[] =
1572184870Syongari{
1573184870Syongari  {"enable", NULL, AliasEnable, LOCAL_AUTH,
1574184870Syongari  "enable IP aliasing", "alias enable [yes|no]"},
1575184870Syongari  {"port", NULL, AliasRedirectPort, LOCAL_AUTH,
1576184870Syongari  "port redirection", "alias port [proto addr_local:port_local  port_alias]"},
1577184870Syongari  {"addr", NULL, AliasRedirectAddr, LOCAL_AUTH,
1578184870Syongari  "static address translation", "alias addr [addr_local addr_alias]"},
1579184870Syongari  {"deny_incoming", NULL, AliasOption, LOCAL_AUTH,
1580184870Syongari    "stop incoming connections", "alias deny_incoming [yes|no]",
1581184870Syongari  (const void *) PKT_ALIAS_DENY_INCOMING},
1582184870Syongari  {"log", NULL, AliasOption, LOCAL_AUTH,
1583207251Syongari    "log aliasing link creation", "alias log [yes|no]",
1584184870Syongari  (const void *) PKT_ALIAS_LOG},
1585184870Syongari  {"same_ports", NULL, AliasOption, LOCAL_AUTH,
1586184870Syongari    "try to leave port numbers unchanged", "alias same_ports [yes|no]",
1587184870Syongari  (const void *) PKT_ALIAS_SAME_PORTS},
1588184870Syongari  {"use_sockets", NULL, AliasOption, LOCAL_AUTH,
1589184870Syongari    "allocate host sockets", "alias use_sockets [yes|no]",
1590184870Syongari  (const void *) PKT_ALIAS_USE_SOCKETS},
1591184870Syongari  {"unregistered_only", NULL, AliasOption, LOCAL_AUTH,
1592184870Syongari    "alias unregistered (private) IP address space only",
1593184870Syongari    "alias unregistered_only [yes|no]",
1594184870Syongari  (const void *) PKT_ALIAS_UNREGISTERED_ONLY},
1595184870Syongari  {"help", "?", HelpCommand, LOCAL_AUTH | LOCAL_NO_AUTH,
1596184870Syongari    "Display this message", "alias help|? [command]", AliasCommands},
1597184870Syongari  {NULL, NULL, NULL},
1598184870Syongari};
1599184870Syongari
1600184870Syongari
1601184870Syongaristatic int
1602184870SyongariAliasCommand(struct cmdargs const *arg)
1603184870Syongari{
1604184870Syongari  if (arg->argc > 0)
1605184870Syongari    FindExec(AliasCommands, arg->argc, arg->argv, "alias ");
1606184870Syongari  else if (VarTerm)
1607184870Syongari    fprintf(VarTerm, "Use `alias help' to get a arg->cmd or `alias help <option>'"
1608184870Syongari	    " for syntax help.\n");
1609184870Syongari  else
1610184870Syongari    LogPrintf(LogWARN, "alias command must have arguments\n");
1611184870Syongari
1612184870Syongari  return 0;
1613184870Syongari}
1614184870Syongari
1615184870Syongaristatic int
1616184870SyongariAliasEnable(struct cmdargs const *arg)
1617184870Syongari{
1618184870Syongari  if (arg->argc == 1)
1619184870Syongari    if (strcasecmp(arg->argv[0], "yes") == 0) {
1620184870Syongari      if (!(mode & MODE_ALIAS)) {
1621184870Syongari	if (loadAliasHandlers(&VarAliasHandlers) == 0) {
1622184870Syongari	  mode |= MODE_ALIAS;
1623184870Syongari	  return 0;
1624184870Syongari	}
1625184870Syongari	LogPrintf(LogWARN, "Cannot load alias library\n");
1626184870Syongari	return 1;
1627184870Syongari      }
1628184870Syongari      return 0;
1629184870Syongari    } else if (strcasecmp(arg->argv[0], "no") == 0) {
1630184870Syongari      if (mode & MODE_ALIAS) {
1631184870Syongari	unloadAliasHandlers();
1632184870Syongari	mode &= ~MODE_ALIAS;
1633184870Syongari      }
1634184870Syongari      return 0;
1635184870Syongari    }
1636184870Syongari  return -1;
1637184870Syongari}
1638184870Syongari
1639184870Syongari
1640184870Syongaristatic int
1641184870SyongariAliasOption(struct cmdargs const *arg)
1642184870Syongari{
1643184870Syongari  unsigned param = (unsigned)arg->data;
1644184870Syongari  if (arg->argc == 1)
1645184870Syongari    if (strcasecmp(arg->argv[0], "yes") == 0) {
1646184870Syongari      if (mode & MODE_ALIAS) {
1647184870Syongari	VarPacketAliasSetMode(param, param);
1648184870Syongari	return 0;
1649184870Syongari      }
1650184870Syongari      LogPrintf(LogWARN, "alias not enabled\n");
1651184870Syongari    } else if (strcmp(arg->argv[0], "no") == 0) {
1652184870Syongari      if (mode & MODE_ALIAS) {
1653184870Syongari	VarPacketAliasSetMode(0, param);
1654184870Syongari	return 0;
1655184870Syongari      }
1656184870Syongari      LogPrintf(LogWARN, "alias not enabled\n");
1657184870Syongari    }
1658184870Syongari  return -1;
1659184870Syongari}
1660184870Syongari#endif /* #ifndef NOALIAS */
1661184870Syongari
1662184870Syongaristatic struct cmdtab const AllowCommands[] = {
1663184870Syongari  {"users", "user", AllowUsers, LOCAL_AUTH,
1664184870Syongari  "Allow users access to ppp", "allow users logname..."},
1665184870Syongari  {"modes", "mode", AllowModes, LOCAL_AUTH,
1666184870Syongari  "Only allow certain ppp modes", "allow modes mode..."},
1667184870Syongari  {"help", "?", HelpCommand, LOCAL_AUTH | LOCAL_NO_AUTH,
1668184870Syongari  "Display this message", "allow help|? [command]", AllowCommands},
1669184870Syongari  {NULL, NULL, NULL},
1670184870Syongari};
1671184870Syongari
1672184870Syongaristatic int
1673184870SyongariAllowCommand(struct cmdargs const *arg)
1674184870Syongari{
1675213844Syongari  if (arg->argc > 0)
1676184870Syongari    FindExec(AllowCommands, arg->argc, arg->argv, "allow ");
1677207251Syongari  else if (VarTerm)
1678207251Syongari    fprintf(VarTerm, "Use `allow ?' to get a arg->cmd or `allow ? <cmd>' for"
1679207251Syongari	    " syntax help.\n");
1680207251Syongari  else
1681207251Syongari    LogPrintf(LogWARN, "allow command must have arguments\n");
1682184870Syongari
1683184870Syongari  return 0;
1684184870Syongari}
1685184870Syongari