command.c revision 26326
1224135Sdim/*
2224135Sdim *		PPP User command processing module
3224135Sdim *
4224135Sdim *	    Written by Toshiharu OHNO (tony-o@iij.ad.jp)
5224135Sdim *
6224135Sdim *   Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd.
7224135Sdim *
8224135Sdim * Redistribution and use in source and binary forms are permitted
9224135Sdim * provided that the above copyright notice and this paragraph are
10224135Sdim * duplicated in all such forms and that any documentation,
11224135Sdim * advertising materials, and other materials related to such
12224135Sdim * distribution and use acknowledge that the software was developed
13224135Sdim * by the Internet Initiative Japan, Inc.  The name of the
14224135Sdim * IIJ may not be used to endorse or promote products derived
15224135Sdim * from this software without specific prior written permission.
16224135Sdim * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
17224135Sdim * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
18224135Sdim * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
19224135Sdim *
20224135Sdim * $Id: command.c,v 1.52 1997/05/31 16:37:19 brian Exp $
21224135Sdim *
22224135Sdim */
23224135Sdim#include <sys/types.h>
24224135Sdim#include <ctype.h>
25224135Sdim#include <termios.h>
26224135Sdim#include <sys/wait.h>
27224135Sdim#include <time.h>
28224135Sdim#include <netdb.h>
29224135Sdim#include <sys/socket.h>
30224135Sdim#include <netinet/in.h>
31224135Sdim#include <arpa/inet.h>
32224135Sdim#include <net/route.h>
33224135Sdim#include <paths.h>
34224135Sdim#include <alias.h>
35224135Sdim#include "fsm.h"
36224135Sdim#include "phase.h"
37224135Sdim#include "lcp.h"
38224135Sdim#include "ipcp.h"
39224135Sdim#include "modem.h"
40224135Sdim#include "filter.h"
41224135Sdim#include "command.h"
42224135Sdim#include "alias_cmd.h"
43224135Sdim#include "hdlc.h"
44224135Sdim#include "loadalias.h"
45224135Sdim#include "vars.h"
46224135Sdim#include "systems.h"
47224135Sdim#include "chat.h"
48224135Sdim#include "os.h"
49224135Sdim
50224135Sdimextern void Cleanup(), TtyTermMode(), PacketMode();
51224135Sdimextern int  EnableCommand(), DisableCommand(), DisplayCommand();
52224135Sdimextern int  AcceptCommand(), DenyCommand();
53224135Sdimstatic int  AliasCommand();
54224135Sdimextern int  LocalAuthCommand();
55224135Sdimextern int  LoadCommand(), SaveCommand();
56224135Sdimextern int  ChangeParity(char *);
57224135Sdimextern int  SelectSystem();
58224135Sdimextern int  ShowRoute();
59224135Sdimextern void TtyOldMode(), TtyCommandMode();
60224135Sdimextern struct pppvars pppVars;
61224135Sdimextern struct cmdtab const SetCommands[];
62224135Sdim
63224135Sdimextern char *IfDevName;
64224135Sdim
65224135Sdimstruct in_addr ifnetmask;
66224135Sdimint randinit;
67224135Sdim
68224135Sdimstatic int ShowCommand(), TerminalCommand(), QuitCommand();
69224135Sdimstatic int CloseCommand(), DialCommand(), DownCommand();
70224135Sdimstatic int SetCommand(), AddCommand(), DeleteCommand();
71224135Sdimstatic int ShellCommand();
72224135Sdim
73224135Sdimstatic int
74224135SdimHelpCommand(list, argc, argv, plist)
75224135Sdimstruct cmdtab *list;
76224135Sdimint argc;
77224135Sdimchar **argv;
78224135Sdimstruct cmdtab *plist;
79224135Sdim{
80224135Sdim  struct cmdtab *cmd;
81224135Sdim  int n;
82224135Sdim
83224135Sdim  if (argc > 0) {
84224135Sdim    for (cmd = plist; cmd->name; cmd++) {
85224135Sdim      if (strcasecmp(cmd->name, *argv) == 0 && (cmd->lauth & VarLocalAuth)) {
86224135Sdim	if (plist == SetCommands)
87224135Sdim		printf("set ");
88224135Sdim        printf("%s %s\n", cmd->name, cmd->syntax);
89224135Sdim        return(1);
90224135Sdim      }
91224135Sdim    }
92224135Sdim    return(1);
93224135Sdim  }
94224135Sdim  n = 0;
95224135Sdim  for (cmd = plist; cmd->func; cmd++) {
96224135Sdim    if (cmd->name && (cmd->lauth & VarLocalAuth)) {
97224135Sdim      printf("  %-8s: %-20s\n", cmd->name, cmd->helpmes);
98224135Sdim      n++;
99224135Sdim    }
100224135Sdim  }
101224135Sdim  if (n & 1)
102224135Sdim    printf("\n");
103224135Sdim  return(1);
104224135Sdim}
105224135Sdim
106224135Sdimint
107224135SdimIsInteractive()
108224135Sdim{
109224135Sdim  char *mes = NULL;
110224135Sdim
111224135Sdim  if (mode & MODE_DDIAL)
112224135Sdim    mes = "Working in dedicated dial mode.";
113224135Sdim  else if (mode & MODE_BACKGROUND)
114224135Sdim    mes = "Working in background mode.";
115224135Sdim  else if (mode & MODE_AUTO)
116224135Sdim    mes = "Working in auto mode.";
117224135Sdim  else if (mode & MODE_DIRECT)
118224135Sdim    mes = "Working in direct mode.";
119224135Sdim  else if (mode & MODE_DEDICATED)
120224135Sdim    mes = "Working in dedicated mode.";
121224135Sdim  if (mes) {
122224135Sdim    printf("%s\n", mes);
123224135Sdim    return(0);
124224135Sdim  }
125224135Sdim  return(1);
126224135Sdim}
127224135Sdim
128224135Sdimstatic int
129224135SdimDialCommand(cmdlist, argc, argv)
130224135Sdimstruct cmdtab *cmdlist;
131224135Sdimint argc;
132224135Sdimchar **argv;
133224135Sdim{
134224135Sdim  int tries;
135224135Sdim
136224135Sdim  if (LcpFsm.state > ST_CLOSED) {
137224135Sdim    printf("LCP state is [%s]\n", StateNames[LcpFsm.state]);
138224135Sdim    return(1);
139224135Sdim  }
140224135Sdim  if (!IsInteractive())
141224135Sdim    return(1);
142224135Sdim  if (argc > 0) {
143224135Sdim    if (SelectSystem(*argv, CONFFILE) < 0) {
144224135Sdim      printf("%s: not found.\n", *argv);
145224135Sdim      return(1);
146224135Sdim    }
147224135Sdim  }
148224135Sdim  tries = 0;
149224135Sdim  do {
150224135Sdim    printf("Dial attempt %u of %d\n", ++tries, VarDialTries);
151224135Sdim    modem = OpenModem(mode);
152224135Sdim    if (modem < 0) {
153224135Sdim      printf("failed to open modem.\n");
154224135Sdim      break;
155224135Sdim    }
156224135Sdim    if (DialModem() == EX_DONE) {
157224135Sdim      sleep(1);
158224135Sdim      ModemTimeout();
159224135Sdim      PacketMode();
160224135Sdim      break;
161224135Sdim    }
162224135Sdim  } while (VarDialTries == 0 || tries < VarDialTries);
163224135Sdim  return(1);
164224135Sdim}
165224135Sdim
166224135Sdimstatic int
167224135SdimShellCommand(cmdlist, argc, argv)
168224135Sdimstruct cmdtab *cmdlist;
169224135Sdimint argc;
170224135Sdimchar **argv;
171224135Sdim{
172224135Sdim  const char *shell;
173224135Sdim  pid_t shpid;
174224135Sdim
175224135Sdim  if((shell = getenv("SHELL")) == 0) {
176224135Sdim    shell = _PATH_BSHELL;
177224135Sdim  }
178224135Sdim#ifdef SHELL_ONLY_INTERACTIVELY
179224135Sdim#ifndef HAVE_SHELL_CMD_WITH_ANY_MODE
180224135Sdim  if( mode != MODE_INTER) {
181224135Sdim     fprintf(stdout,
182224135Sdim             "Can only start a shell in interactive mode\n");
183224135Sdim     return(1);
184224135Sdim  }
185224135Sdim#else
186224135Sdim  if(argc == 0 && !(mode & MODE_INTER)) {
187224135Sdim      fprintf(stderr,
188224135Sdim             "Can only start an interactive shell in interactive mode\n");
189224135Sdim      return(1);
190224135Sdim  }
191224135Sdim#endif /* HAVE_SHELL_CMD_WITH_ANY_MODE */
192224135Sdim#else
193224135Sdim  if ((mode & (MODE_AUTO|MODE_INTER)) == (MODE_AUTO|MODE_INTER)) {
194224135Sdim     fprintf(stdout,
195224135Sdim             "Shell is not allowed interactively in auto mode\n");
196224135Sdim     return(1);
197224135Sdim  }
198224135Sdim#endif /* SHELL_ONLY_INTERACTIVELY */
199224135Sdim  if((shpid = fork()) == 0) {
200224135Sdim     int dtablesize, i ;
201224135Sdim
202224135Sdim     for (dtablesize = getdtablesize(), i = 3; i < dtablesize; i++)
203224135Sdim	(void)close(i);
204224135Sdim
205224135Sdim     /*
206224135Sdim      * We are running setuid, we should change to
207224135Sdim      * real user for avoiding security problems.
208224135Sdim      */
209224135Sdim     if (setgid(getgid()) < 0) {
210224135Sdim	perror("setgid");
211224135Sdim	exit(1);
212224135Sdim     }
213224135Sdim     if (setuid(getuid()) < 0) {
214224135Sdim	perror("setuid");
215224135Sdim	exit(1);
216224135Sdim     }
217224135Sdim     TtyOldMode();
218224135Sdim     if(argc > 0) {
219224135Sdim       /* substitute pseudo args */
220224135Sdim       for (i=1; i<argc; i++) {
221224135Sdim         if (strcasecmp(argv[i], "HISADDR") == 0) {
222224135Sdim           argv[i] = strdup(inet_ntoa(IpcpInfo.his_ipaddr));
223224135Sdim         }
224224135Sdim         if (strcasecmp(argv[i], "INTERFACE") == 0) {
225224135Sdim           argv[i] = strdup(IfDevName);
226224135Sdim         }
227224135Sdim         if (strcasecmp(argv[i], "MYADDR") == 0) {
228224135Sdim           argv[i] = strdup(inet_ntoa(IpcpInfo.want_ipaddr));
229224135Sdim         }
230224135Sdim       }
231224135Sdim       (void)execvp(argv[0], argv);
232224135Sdim     }
233224135Sdim     else
234224135Sdim       (void)execl(shell, shell, NULL);
235224135Sdim
236224135Sdim     fprintf(stdout, "exec() of %s failed\n", argc > 0? argv[0]: shell);
237224135Sdim     exit(255);
238224135Sdim  }
239224135Sdim  if( shpid == (pid_t)-1 ) {
240224135Sdim    fprintf(stdout, "Fork failed\n");
241224135Sdim  } else {
242224135Sdim    int status;
243224135Sdim    (void)waitpid(shpid, &status, 0);
244224135Sdim  }
245224135Sdim
246224135Sdim  TtyCommandMode(1);
247224135Sdim
248224135Sdim  return(0);
249224135Sdim}
250224135Sdim
251224135Sdimstatic char StrOption[] = "option ..";
252224135Sdimstatic char StrRemote[] = "[remote]";
253224135Sdimchar StrNull[] = "";
254224135Sdim
255224135Sdimstruct cmdtab const Commands[] = {
256224135Sdim  { "accept",  NULL,    AcceptCommand,	LOCAL_AUTH,
257224135Sdim  	"accept option request",	StrOption},
258224135Sdim  { "add",     NULL,	AddCommand,	LOCAL_AUTH,
259224135Sdim	"add route",			"dest mask gateway"},
260224135Sdim  { "close",   NULL,    CloseCommand,	LOCAL_AUTH,
261224135Sdim	"Close connection",		StrNull},
262224135Sdim  { "delete",  NULL,    DeleteCommand,	LOCAL_AUTH,
263224135Sdim	"delete route",                 "ALL | dest gateway [mask]"},
264224135Sdim  { "deny",    NULL,    DenyCommand,	LOCAL_AUTH,
265224135Sdim  	"Deny option request",		StrOption},
266224135Sdim  { "dial",    "call",  DialCommand,	LOCAL_AUTH,
267224135Sdim  	"Dial and login",		StrRemote},
268224135Sdim  { "disable", NULL,    DisableCommand,	LOCAL_AUTH,
269224135Sdim  	"Disable option",		StrOption},
270224135Sdim  { "display", NULL,    DisplayCommand,	LOCAL_AUTH,
271224135Sdim  	"Display option configs",	StrNull},
272224135Sdim  { "enable",  NULL,    EnableCommand,	LOCAL_AUTH,
273224135Sdim  	"Enable option",		StrOption},
274224135Sdim  { "passwd",  NULL,	LocalAuthCommand,LOCAL_NO_AUTH,
275224135Sdim  	"Password for manipulation", StrOption},
276224135Sdim  { "load",    NULL,    LoadCommand,	LOCAL_AUTH,
277224135Sdim  	"Load settings",		StrRemote},
278224135Sdim  { "save",    NULL,    SaveCommand,	LOCAL_AUTH,
279224135Sdim  	"Save settings", StrNull},
280224135Sdim  { "set",     "setup", SetCommand,	LOCAL_AUTH,
281224135Sdim  	"Set parameters",  "var value"},
282224135Sdim  { "shell",   "!",     ShellCommand,   LOCAL_AUTH,
283224135Sdim	"Run a subshell",  "[sh command]"},
284224135Sdim  { "show",    NULL,    ShowCommand,	LOCAL_AUTH,
285224135Sdim  	"Show status and statictics", "var"},
286224135Sdim  { "term",    NULL,    TerminalCommand,LOCAL_AUTH,
287224135Sdim  	"Enter to terminal mode", StrNull},
288224135Sdim  { "alias",   NULL,    AliasCommand,   LOCAL_AUTH,
289224135Sdim        "alias control",        "option [yes|no]"},
290224135Sdim  { "quit",    "bye",   QuitCommand,	LOCAL_AUTH | LOCAL_NO_AUTH,
291224135Sdim	"Quit PPP program", "[all]"},
292224135Sdim  { "help",    "?",     HelpCommand,	LOCAL_AUTH | LOCAL_NO_AUTH,
293224135Sdim	"Display this message", "[command]", (void *)Commands },
294224135Sdim  { NULL,      "down",  DownCommand,	LOCAL_AUTH,
295224135Sdim  	"Generate down event",		StrNull},
296224135Sdim  { NULL,      NULL,    NULL },
297224135Sdim};
298224135Sdim
299224135Sdimextern int ReportCcpStatus();
300224135Sdimextern int ReportLcpStatus();
301224135Sdimextern int ReportIpcpStatus();
302224135Sdimextern int ReportProtStatus();
303224135Sdimextern int ReportCompress();
304224135Sdimextern int ShowModemStatus();
305224135Sdimextern int ReportHdlcStatus();
306224135Sdimextern int ShowMemMap();
307224135Sdim
308224135Sdimstatic char *LogLevelName[] = {
309224135Sdim  LM_PHASE,   LM_CHAT,    LM_LQM,   LM_LCP,
310224135Sdim  LM_TCPIP,   LM_HDLC,    LM_ASYNC, LM_LINK,
311224135Sdim  LM_CONNECT, LM_CARRIER,
312224135Sdim};
313224135Sdim
314224135Sdimstatic int ShowDebugLevel()
315224135Sdim{
316224135Sdim  int i;
317224135Sdim
318224135Sdim  printf("%02x: ", loglevel);
319224135Sdim  for (i = LOG_PHASE; i < MAXLOGLEVEL; i++) {
320224135Sdim    if (loglevel & (1 << i))
321224135Sdim      printf("%s ", LogLevelName[i]);
322224135Sdim  }
323224135Sdim  printf("\n");
324224135Sdim  return(1);
325224135Sdim}
326224135Sdim
327224135Sdimstatic int ShowEscape()
328224135Sdim{
329224135Sdim  int code, bit;
330224135Sdim
331224135Sdim  if (EscMap[32]) {
332224135Sdim    for (code = 0; code < 32; code++) {
333224135Sdim      if (EscMap[code]) {
334224135Sdim        for (bit = 0; bit < 8; bit++) {
335224135Sdim          if (EscMap[code] & (1<<bit)) {
336224135Sdim            printf(" 0x%02x", (code << 3) + bit);
337224135Sdim          }
338224135Sdim        }
339224135Sdim      }
340224135Sdim    }
341224135Sdim    printf("\n");
342224135Sdim  }
343224135Sdim  return(1);
344224135Sdim}
345224135Sdim
346224135Sdimstatic int ShowTimeout()
347224135Sdim{
348224135Sdim  printf(" Idle Timer: %d secs   LQR Timer: %d secs   Retry Timer: %d secs\n",
349224135Sdim    VarIdleTimeout, VarLqrTimeout, VarRetryTimeout);
350224135Sdim  return(1);
351224135Sdim}
352224135Sdim
353224135Sdimstatic int ShowAuthKey()
354224135Sdim{
355224135Sdim  printf("AuthName = %s\n", VarAuthName);
356224135Sdim  printf("AuthKey  = %s\n", VarAuthKey);
357224135Sdim  return(1);
358224135Sdim}
359224135Sdim
360224135Sdimstatic int ShowVersion()
361224135Sdim{
362224135Sdim  extern char VarVersion[];
363224135Sdim  extern char VarLocalVersion[];
364224135Sdim
365224135Sdim  printf("%s - %s \n", VarVersion, VarLocalVersion);
366224135Sdim  return(1);
367224135Sdim}
368224135Sdim
369224135Sdimstatic int ShowLogList()
370224135Sdim{
371224135Sdim  ListLog();
372224135Sdim  return(1);
373224135Sdim}
374224135Sdim
375224135Sdimstatic int ShowInitialMRU()
376224135Sdim{
377224135Sdim  printf(" Initial MRU: %ld\n", VarMRU);
378224135Sdim  return(1);
379224135Sdim}
380224135Sdim
381224135Sdimstatic int ShowPreferredMTU()
382224135Sdim{
383224135Sdim  if (VarPrefMTU)
384224135Sdim    printf(" Preferred MTU: %ld\n", VarPrefMTU);
385224135Sdim  else
386224135Sdim    printf(" Preferred MTU: unspecified\n");
387224135Sdim  return(1);
388224135Sdim}
389224135Sdim
390224135Sdimstatic int ShowReconnect()
391224135Sdim{
392224135Sdim  printf(" Reconnect Timer:  %d,  %d tries\n",
393224135Sdim         VarReconnectTimer, VarReconnectTries);
394224135Sdim  return(1);
395224135Sdim}
396224135Sdim
397224135Sdimstatic int ShowRedial()
398224135Sdim{
399224135Sdim  printf(" Redial Timer: ");
400224135Sdim
401224135Sdim  if (VarRedialTimeout >= 0) {
402224135Sdim    printf(" %d seconds, ", VarRedialTimeout);
403224135Sdim  }
404224135Sdim  else {
405224135Sdim    printf(" Random 0 - %d seconds, ", REDIAL_PERIOD);
406224135Sdim  }
407224135Sdim
408224135Sdim  printf(" Redial Next Timer: ");
409224135Sdim
410224135Sdim  if (VarRedialNextTimeout >= 0) {
411224135Sdim    printf(" %d seconds, ", VarRedialNextTimeout);
412224135Sdim  }
413224135Sdim  else {
414224135Sdim    printf(" Random 0 - %d seconds, ", REDIAL_PERIOD);
415224135Sdim  }
416224135Sdim
417224135Sdim  if (VarDialTries)
418224135Sdim      printf("%d dial tries", VarDialTries);
419224135Sdim
420224135Sdim  printf("\n");
421224135Sdim
422224135Sdim  return(1);
423224135Sdim}
424224135Sdim
425224135Sdim#ifdef MSEXT
426224135Sdimstatic int ShowMSExt()
427224135Sdim{
428224135Sdim  printf(" MS PPP extention values \n" );
429224135Sdim  printf("   Primary NS     : %s\n", inet_ntoa( ns_entries[0] ));
430224135Sdim  printf("   Secondary NS   : %s\n", inet_ntoa( ns_entries[1] ));
431224135Sdim  printf("   Primary NBNS   : %s\n", inet_ntoa( nbns_entries[0] ));
432224135Sdim  printf("   Secondary NBNS : %s\n", inet_ntoa( nbns_entries[1] ));
433224135Sdim
434224135Sdim  return(1);
435224135Sdim}
436224135Sdim#endif /* MSEXT */
437224135Sdim
438224135Sdimextern int ShowIfilter(), ShowOfilter(), ShowDfilter(), ShowAfilter();
439224135Sdim
440224135Sdimstruct cmdtab const ShowCommands[] = {
441224135Sdim  { "afilter",  NULL,     ShowAfilter,		LOCAL_AUTH,
442224135Sdim	"Show keep Alive filters", StrOption},
443224135Sdim  { "auth",     NULL,     ShowAuthKey,		LOCAL_AUTH,
444224135Sdim	"Show auth name/key", StrNull},
445224135Sdim  { "ccp",      NULL,     ReportCcpStatus,	LOCAL_AUTH,
446224135Sdim	"Show CCP status", StrNull},
447224135Sdim  { "compress", NULL,     ReportCompress,	LOCAL_AUTH,
448224135Sdim	"Show compression statictics", StrNull},
449224135Sdim  { "debug",	NULL,	  ShowDebugLevel,	LOCAL_AUTH,
450224135Sdim	"Show current debug level", StrNull},
451224135Sdim  { "dfilter",  NULL,     ShowDfilter,		LOCAL_AUTH,
452224135Sdim	"Show Demand filters", StrOption},
453224135Sdim  { "escape",   NULL,     ShowEscape,		LOCAL_AUTH,
454224135Sdim	"Show escape characters", StrNull},
455224135Sdim  { "hdlc",	NULL,	  ReportHdlcStatus,	LOCAL_AUTH,
456224135Sdim	"Show HDLC error summary", StrNull},
457224135Sdim  { "ifilter",  NULL,     ShowIfilter,		LOCAL_AUTH,
458224135Sdim	"Show Input filters", StrOption},
459224135Sdim  { "ipcp",     NULL,     ReportIpcpStatus,	LOCAL_AUTH,
460224135Sdim	"Show IPCP status", StrNull},
461224135Sdim  { "lcp",      NULL,     ReportLcpStatus,	LOCAL_AUTH,
462224135Sdim	"Show LCP status", StrNull},
463224135Sdim  { "log",      NULL,     ShowLogList,		LOCAL_AUTH,
464224135Sdim	"Show log records", StrNull},
465224135Sdim  { "mem",      NULL,     ShowMemMap,		LOCAL_AUTH,
466224135Sdim	"Show memory map", StrNull},
467224135Sdim  { "modem",    NULL,     ShowModemStatus,	LOCAL_AUTH,
468224135Sdim	"Show modem setups", StrNull},
469224135Sdim  { "mru",      NULL,     ShowInitialMRU,	LOCAL_AUTH,
470224135Sdim	"Show Initial MRU", StrNull},
471224135Sdim  { "mtu",      NULL,     ShowPreferredMTU,	LOCAL_AUTH,
472224135Sdim	"Show Preferred MTU", StrNull},
473224135Sdim  { "ofilter",  NULL,     ShowOfilter,		LOCAL_AUTH,
474224135Sdim	"Show Output filters", StrOption},
475224135Sdim  { "proto",    NULL,     ReportProtStatus,	LOCAL_AUTH,
476224135Sdim	"Show protocol summary", StrNull},
477224135Sdim  { "reconnect",NULL,	  ShowReconnect,	LOCAL_AUTH,
478224135Sdim	"Show Reconnect timer,tries", StrNull},
479224135Sdim  { "redial",   NULL,	  ShowRedial,		LOCAL_AUTH,
480224135Sdim	"Show Redial timeout value", StrNull},
481224135Sdim  { "route",    NULL,     ShowRoute,		LOCAL_AUTH,
482224135Sdim	"Show routing table", StrNull},
483224135Sdim  { "timeout",  NULL,	  ShowTimeout,		LOCAL_AUTH,
484224135Sdim	"Show Idle timeout value", StrNull},
485224135Sdim#ifdef MSEXT
486224135Sdim  { "msext", 	NULL,	  ShowMSExt,		LOCAL_AUTH,
487224135Sdim	"Show MS PPP extentions", StrNull},
488224135Sdim#endif /* MSEXT */
489224135Sdim  { "version",  NULL,	  ShowVersion,		LOCAL_NO_AUTH | LOCAL_AUTH,
490224135Sdim	"Show version string", StrNull},
491224135Sdim  { "help",     "?",      HelpCommand,		LOCAL_NO_AUTH | LOCAL_AUTH,
492224135Sdim	"Display this message", StrNull, (void *)ShowCommands},
493224135Sdim  { NULL,       NULL,     NULL },
494224135Sdim};
495224135Sdim
496224135Sdimstruct cmdtab *
497224135SdimFindCommand(cmds, str, pmatch)
498224135Sdimstruct cmdtab *cmds;
499224135Sdimchar *str;
500224135Sdimint *pmatch;
501224135Sdim{
502224135Sdim  int nmatch = 0;
503224135Sdim  int len = strlen(str);
504224135Sdim  struct cmdtab *found = NULL;
505224135Sdim
506224135Sdim  while (cmds->func) {
507224135Sdim    if (cmds->name && strncasecmp(str, cmds->name, len) == 0) {
508224135Sdim      nmatch++;
509224135Sdim      found = cmds;
510224135Sdim    } else if (cmds->alias && strncasecmp(str, cmds->alias, len) == 0) {
511224135Sdim      nmatch++;
512224135Sdim      found = cmds;
513224135Sdim    }
514224135Sdim    cmds++;
515224135Sdim  }
516224135Sdim  *pmatch = nmatch;
517224135Sdim  return(found);
518224135Sdim}
519224135Sdim
520224135Sdimint
521224135SdimFindExec(cmdlist, argc, argv)
522224135Sdimstruct cmdtab *cmdlist;
523224135Sdimint argc;
524224135Sdimchar **argv;
525224135Sdim{
526224135Sdim  struct cmdtab *cmd;
527224135Sdim  int val = 1;
528224135Sdim  int nmatch;
529224135Sdim
530224135Sdim  cmd = FindCommand(cmdlist, *argv, &nmatch);
531224135Sdim  if (nmatch > 1)
532224135Sdim    printf("Ambiguous.\n");
533224135Sdim  else if (cmd && ( cmd->lauth & VarLocalAuth ) )
534224135Sdim    val = (cmd->func)(cmd, --argc, ++argv, cmd->args);
535224135Sdim  else
536224135Sdim    printf("what?\n");
537224135Sdim  return(val);
538224135Sdim}
539224135Sdim
540224135Sdimint aft_cmd = 1;
541224135Sdim
542void
543Prompt()
544{
545  char *pconnect, *pauth;
546
547  if (!(mode & MODE_INTER))
548    return;
549
550  if (!aft_cmd)
551    printf("\n");
552  else
553    aft_cmd = 0;
554
555  if ( VarLocalAuth == LOCAL_AUTH )
556    pauth = " ON ";
557  else
558    pauth = " on ";
559  if (IpcpFsm.state == ST_OPENED && phase == PHASE_NETWORK)
560    pconnect = "PPP";
561  else
562    pconnect = "ppp";
563  printf("%s%s%s> ", pconnect, pauth, VarShortHost);
564  fflush(stdout);
565}
566
567void
568DecodeCommand(buff, nb, prompt)
569char *buff;
570int nb;
571int prompt;
572{
573  char *vector[20];
574  char **argv;
575  int argc, val;
576  char *cp;
577
578  val = 1;
579  if (nb > 0) {
580    cp = buff + strcspn(buff, "\r\n");
581    if (cp)
582      *cp = '\0';
583    {
584      argc = MakeArgs(buff, vector, VECSIZE(vector));
585      argv = vector;
586
587      if (argc > 0)
588        val = FindExec(Commands, argc, argv);
589    }
590  }
591  if (val && prompt)
592    Prompt();
593}
594
595static int
596ShowCommand(list, argc, argv)
597struct cmdtab *list;
598int argc;
599char **argv;
600{
601  int val = 1;
602
603  if (argc > 0)
604    val = FindExec(ShowCommands, argc, argv);
605  else
606    printf("Use ``show ?'' to get a list.\n");
607  return(val);
608}
609
610static int
611TerminalCommand()
612{
613  if (LcpFsm.state > ST_CLOSED) {
614    printf("LCP state is [%s]\n", StateNames[LcpFsm.state]);
615    return(1);
616  }
617  if (!IsInteractive())
618    return(1);
619  modem = OpenModem(mode);
620  if (modem < 0) {
621    printf("failed to open modem.\n");
622    return(1);
623  }
624  printf("Enter to terminal mode.\n");
625  printf("Type `~?' for help.\n");
626  TtyTermMode();
627  return(0);
628}
629
630static int
631QuitCommand(list, argc, argv)
632struct cmdtab *list;
633int argc;
634char **argv;
635{
636  if (mode & (MODE_DIRECT|MODE_DEDICATED|MODE_AUTO)) {
637    if (argc > 0 && (VarLocalAuth & LOCAL_AUTH)) {
638      Cleanup(EX_NORMAL);
639      mode &= ~MODE_INTER;
640    } else {
641      LogPrintf(LOG_PHASE_BIT, "client connection closed.\n");
642      VarLocalAuth = LOCAL_NO_AUTH;
643      close(netfd);
644      close(1);
645      dup2(2, 1);     /* Have to have something here or the modem will be 1 */
646      netfd = -1;
647      mode &= ~MODE_INTER;
648    }
649  } else
650    Cleanup(EX_NORMAL);
651  return(1);
652}
653
654static int
655CloseCommand()
656{
657  reconnect(RECON_FALSE);
658  LcpClose();
659  if (mode & MODE_BACKGROUND)
660      Cleanup(EX_NORMAL);
661  return(1);
662}
663
664static int
665DownCommand()
666{
667  LcpDown();
668  return(1);
669}
670
671static int
672SetModemSpeed(list, argc, argv)
673struct cmdtab *list;
674int argc;
675char **argv;
676{
677  int speed;
678
679  if (argc > 0) {
680    if (strcmp(*argv, "sync") == 0) {
681      VarSpeed = 0;
682      return(1);
683    }
684    speed = atoi(*argv);
685    if (IntToSpeed(speed) != B0) {
686      VarSpeed = speed;
687      return(1);
688    }
689    printf("invalid speed.\n");
690  }
691  return(1);
692}
693
694static int
695SetReconnect(list, argc, argv)
696struct cmdtab *list;
697int argc;
698char **argv;
699{
700  if (argc == 2) {
701    VarReconnectTimer = atoi(argv[0]);
702    VarReconnectTries = atoi(argv[1]);
703  } else
704    printf("Usage: %s %s\n", list->name, list->syntax);
705  return(1);
706}
707
708static int
709SetRedialTimeout(list, argc, argv)
710struct cmdtab *list;
711int argc;
712char **argv;
713{
714  int timeout;
715  int tries;
716  char *dot;
717
718  if (argc == 1 || argc == 2 ) {
719    if (strncasecmp(argv[0], "random", 6) == 0 &&
720	(argv[0][6] == '\0' || argv[0][6] == '.')) {
721      VarRedialTimeout = -1;
722      printf("Using random redial timeout.\n");
723      if (!randinit) {
724	randinit = 1;
725	if (srandomdev() < 0)
726	  srandom((unsigned long)(time(NULL) ^ getpid()));
727      }
728    }
729    else {
730      timeout = atoi(argv[0]);
731
732      if (timeout >= 0) {
733	VarRedialTimeout = timeout;
734      }
735      else {
736	printf("invalid redial timeout\n");
737	printf("Usage: %s %s\n", list->name, list->syntax);
738      }
739    }
740
741    dot = index(argv[0],'.');
742    if (dot) {
743      if (strcasecmp(++dot, "random") == 0) {
744        VarRedialNextTimeout = -1;
745        printf("Using random next redial timeout.\n");
746        if (!randinit) {
747          randinit = 1;
748          if (srandomdev() < 0)
749            srandom((unsigned long)(time(NULL) ^ getpid()));
750        }
751      }
752      else {
753        timeout = atoi(dot);
754        if (timeout >= 0) {
755          VarRedialNextTimeout = timeout;
756        }
757        else {
758          printf("invalid next redial timeout\n");
759          printf("Usage: %s %s\n", list->name, list->syntax);
760        }
761      }
762    }
763    else
764      VarRedialNextTimeout = NEXT_REDIAL_PERIOD;   /* Default next timeout */
765
766    if (argc == 2) {
767      tries = atoi(argv[1]);
768
769      if (tries >= 0) {
770	  VarDialTries = tries;
771      }
772      else {
773	printf("invalid retry value\n");
774	printf("Usage: %s %s\n", list->name, list->syntax);
775      }
776    }
777  }
778  else {
779    printf("Usage: %s %s\n", list->name, list->syntax);
780  }
781  return(1);
782}
783
784static int
785SetModemParity(list, argc, argv)
786struct cmdtab *list;
787int argc;
788char **argv;
789{
790  int parity;
791
792  if (argc > 0) {
793    parity = ChangeParity(*argv);
794    if (parity < 0)
795      printf("Invalid parity.\n");
796    else
797      VarParity = parity;
798  }
799  return(1);
800}
801
802static int
803SetDebugLevel(list, argc, argv)
804struct cmdtab *list;
805int argc;
806char **argv;
807{
808  int level, w;
809
810  for (level = 0; argc-- > 0; argv++) {
811    if (isdigit(**argv)) {
812      w = atoi(*argv);
813      if (w < 0 || w >= MAXLOGLEVEL) {
814	printf("invalid log level.\n");
815	break;
816      } else
817	level |= (1 << w);
818    } else {
819      for (w = 0; w < MAXLOGLEVEL; w++) {
820	if (strcasecmp(*argv, LogLevelName[w]) == 0) {
821	  level |= (1 << w);
822	  continue;
823	}
824      }
825    }
826  }
827  loglevel = level;
828  return(1);
829}
830
831static int
832SetEscape(list, argc, argv)
833struct cmdtab *list;
834int argc;
835char **argv;
836{
837  int code;
838
839  for (code = 0; code < 33; code++)
840    EscMap[code] = 0;
841  while (argc-- > 0) {
842    sscanf(*argv++, "%x", &code);
843    code &= 0xff;
844    EscMap[code >> 3] |= (1 << (code&7));
845    EscMap[32] = 1;
846  }
847  return(1);
848}
849
850static int
851SetInitialMRU(list, argc, argv)
852struct cmdtab *list;
853int argc;
854char **argv;
855{
856  long mru;
857
858  if (argc > 0) {
859    mru = atol(*argv);
860    if (mru < MIN_MRU)
861      printf("Given MRU value (%ld) is too small.\n", mru);
862    else if (mru > MAX_MRU)
863      printf("Given MRU value (%ld) is too big.\n", mru);
864    else
865      VarMRU = mru;
866  } else
867    printf("Usage: %s %s\n", list->name, list->syntax);
868
869  return(1);
870}
871
872static int
873SetPreferredMTU(list, argc, argv)
874struct cmdtab *list;
875int argc;
876char **argv;
877{
878  long mtu;
879
880  if (argc > 0) {
881    mtu = atol(*argv);
882    if (mtu == 0)
883      VarPrefMTU = 0;
884    else if (mtu < MIN_MTU)
885      printf("Given MTU value (%ld) is too small.\n", mtu);
886    else if (mtu > MAX_MTU)
887      printf("Given MTU value (%ld) is too big.\n", mtu);
888    else
889      VarPrefMTU = mtu;
890  } else
891    printf("Usage: %s %s\n", list->name, list->syntax);
892
893  return(1);
894}
895
896static int
897SetIdleTimeout(list, argc, argv)
898struct cmdtab *list;
899int argc;
900char **argv;
901{
902  if (argc-- > 0) {
903    VarIdleTimeout = atoi(*argv++);
904    if (argc-- > 0) {
905      VarLqrTimeout = atoi(*argv++);
906      if (VarLqrTimeout < 1)
907	VarLqrTimeout = 30;
908      if (argc > 0) {
909	VarRetryTimeout = atoi(*argv);
910	if (VarRetryTimeout < 1 || VarRetryTimeout > 10)
911	  VarRetryTimeout = 3;
912      }
913    }
914  }
915  return(1);
916}
917
918struct in_addr
919GetIpAddr(cp)
920char *cp;
921{
922  struct hostent *hp;
923  struct in_addr ipaddr;
924
925  hp = gethostbyname(cp);
926  if (hp && hp->h_addrtype == AF_INET)
927    bcopy(hp->h_addr, &ipaddr, hp->h_length);
928  else if (inet_aton(cp, &ipaddr) == 0)
929    ipaddr.s_addr = 0;
930  return(ipaddr);
931}
932
933static int
934SetInterfaceAddr(list, argc, argv)
935struct cmdtab *list;
936int argc;
937char **argv;
938{
939
940  DefMyAddress.ipaddr.s_addr = DefHisAddress.ipaddr.s_addr = 0L;
941  if (argc > 4) {
942     printf("set ifaddr: too many arguments (%d > 4)\n", argc);
943     return(0);
944  }
945  if (argc > 0) {
946    if (ParseAddr(argc, argv++,
947            &DefMyAddress.ipaddr,
948	    &DefMyAddress.mask,
949	    &DefMyAddress.width) == 0)
950       return(0);
951    if (--argc > 0) {
952      if (ParseAddr(argc, argv++,
953		    &DefHisAddress.ipaddr,
954		    &DefHisAddress.mask,
955		    &DefHisAddress.width) == 0)
956	 return(0);
957      if (--argc > 0) {
958        ifnetmask = GetIpAddr(*argv);
959    	if (--argc > 0) {
960	   if (ParseAddr(argc, argv++,
961			 &DefTriggerAddress.ipaddr,
962			 &DefTriggerAddress.mask,
963			 &DefTriggerAddress.width) == 0)
964	      return(0);
965	}
966      }
967    }
968  }
969  /*
970   * For backwards compatibility, 0.0.0.0 means any address.
971   */
972  if (DefMyAddress.ipaddr.s_addr == 0) {
973    DefMyAddress.mask.s_addr = 0;
974    DefMyAddress.width = 0;
975  }
976  if (DefHisAddress.ipaddr.s_addr == 0) {
977    DefHisAddress.mask.s_addr = 0;
978    DefHisAddress.width = 0;
979  }
980
981  if ((mode & MODE_AUTO) ||
982	((mode & MODE_DEDICATED) && dstsystem)) {
983    if (OsSetIpaddress(DefMyAddress.ipaddr, DefHisAddress.ipaddr, ifnetmask) < 0)
984       return(0);
985  }
986  return(1);
987}
988
989#ifdef MSEXT
990
991void
992SetMSEXT(pri_addr, sec_addr, argc, argv)
993struct in_addr *pri_addr;
994struct in_addr *sec_addr;
995int argc;
996char **argv;
997{
998  int dummyint;
999  struct in_addr dummyaddr;
1000
1001  pri_addr->s_addr = sec_addr->s_addr = 0L;
1002
1003  if( argc > 0 ) {
1004    ParseAddr(argc, argv++, pri_addr, &dummyaddr, &dummyint);
1005    if( --argc > 0 )
1006      ParseAddr(argc, argv++, sec_addr, &dummyaddr, &dummyint);
1007    else
1008      sec_addr->s_addr = pri_addr->s_addr;
1009  }
1010
1011 /*
1012  * if the primary/secondary ns entries are 0.0.0.0 we should
1013  * set them to either the localhost's ip, or the values in
1014  * /etc/resolv.conf ??
1015  *
1016  * up to you if you want to implement this...
1017  */
1018
1019}
1020
1021static int
1022SetNS(list, argc, argv)
1023struct cmdtab *list;
1024int argc;
1025char **argv;
1026{
1027  SetMSEXT(&ns_entries[0], &ns_entries[1], argc, argv);
1028  return(1);
1029}
1030
1031static int
1032SetNBNS(list, argc, argv)
1033struct cmdtab *list;
1034int argc;
1035char **argv;
1036{
1037  SetMSEXT(&nbns_entries[0], &nbns_entries[1], argc, argv);
1038  return(1);
1039}
1040
1041#endif /* MS_EXT */
1042
1043#define	VAR_AUTHKEY	0
1044#define	VAR_DIAL	1
1045#define	VAR_LOGIN	2
1046#define	VAR_AUTHNAME	3
1047#define	VAR_DEVICE	4
1048#define	VAR_ACCMAP	5
1049#define	VAR_PHONE	6
1050
1051static int
1052SetVariable(list, argc, argv, param)
1053struct cmdtab *list;
1054int argc;
1055char **argv;
1056int param;
1057{
1058  u_long map;
1059
1060  if (argc > 0) {
1061    switch (param) {
1062    case VAR_AUTHKEY:
1063      strncpy(VarAuthKey, *argv, sizeof(VarAuthKey)-1);
1064      VarAuthKey[sizeof(VarAuthKey)-1] = '\0';
1065      break;
1066    case VAR_AUTHNAME:
1067      strncpy(VarAuthName, *argv, sizeof(VarAuthName)-1);
1068      VarAuthName[sizeof(VarAuthName)-1] = '\0';
1069      break;
1070    case VAR_DIAL:
1071      strncpy(VarDialScript, *argv, sizeof(VarDialScript)-1);
1072      VarDialScript[sizeof(VarDialScript)-1] = '\0';
1073      break;
1074    case VAR_LOGIN:
1075      strncpy(VarLoginScript, *argv, sizeof(VarLoginScript)-1);
1076      VarLoginScript[sizeof(VarLoginScript)-1] = '\0';
1077      break;
1078    case VAR_DEVICE:
1079      strncpy(VarDevice, *argv, sizeof(VarDevice)-1);
1080      VarDevice[sizeof(VarDevice)-1] = '\0';
1081      VarBaseDevice = rindex(VarDevice, '/');
1082      VarBaseDevice = VarBaseDevice ? VarBaseDevice + 1 : "";
1083      break;
1084    case VAR_ACCMAP:
1085      sscanf(*argv, "%lx", &map);
1086      VarAccmap = map;
1087      break;
1088    case VAR_PHONE:
1089      strncpy(VarPhoneList, *argv, sizeof(VarPhoneList)-1);
1090      VarPhoneList[sizeof(VarPhoneList)-1] = '\0';
1091      strcpy(VarPhoneCopy, VarPhoneList);
1092      VarNextPhone = VarPhoneCopy;
1093      break;
1094    }
1095  }
1096  return(1);
1097}
1098
1099static int SetCtsRts(list, argc, argv)
1100struct cmdtab *list;
1101int argc;
1102char **argv;
1103{
1104  if (argc > 0) {
1105    if (strcmp(*argv, "on") == 0)
1106      VarCtsRts = TRUE;
1107    else if (strcmp(*argv, "off") == 0)
1108      VarCtsRts = FALSE;
1109    else
1110      printf("usage: set ctsrts [on|off].\n");
1111  }
1112  return(1);
1113}
1114
1115
1116static int SetOpenMode(list, argc, argv)
1117struct cmdtab *list;
1118int argc;
1119char **argv;
1120{
1121  if (argc > 0) {
1122    if (strcmp(*argv, "active") == 0)
1123      VarOpenMode = OPEN_ACTIVE;
1124    else if (strcmp(*argv, "passive") == 0)
1125      VarOpenMode = OPEN_PASSIVE;
1126    else
1127      printf("Invalid mode.\n");
1128  }
1129  return(1);
1130}
1131static char StrChatStr[] = "chat-script";
1132static char StrValue[] = "value";
1133
1134extern int SetIfilter(), SetOfilter(), SetDfilter(), SetAfilter();
1135
1136struct cmdtab const SetCommands[] = {
1137  { "accmap",   NULL,	  SetVariable,		LOCAL_AUTH,
1138	"Set accmap value", "hex-value", (void *)VAR_ACCMAP},
1139  { "afilter",  NULL,     SetAfilter, 		LOCAL_AUTH,
1140	"Set keep Alive filter", "..."},
1141  { "authkey",  "key",     SetVariable,		LOCAL_AUTH,
1142	"Set authentication key", "key", (void *)VAR_AUTHKEY},
1143  { "authname", NULL,     SetVariable,		LOCAL_AUTH,
1144	"Set authentication name", "name", (void *)VAR_AUTHNAME},
1145  { "ctsrts", NULL,	  SetCtsRts,		LOCAL_AUTH,
1146	"Use CTS/RTS modem signalling", "[on|off]"},
1147  { "debug",    NULL,	  SetDebugLevel,	LOCAL_AUTH,
1148	"Set debug level", StrValue},
1149  { "device",     "line", SetVariable, 		LOCAL_AUTH,
1150	"Set modem device name", "device-name",	(void *)VAR_DEVICE},
1151  { "dfilter",  NULL,     SetDfilter,		 LOCAL_AUTH,
1152	"Set demand filter", "..."},
1153  { "dial",     NULL,     SetVariable, 		LOCAL_AUTH,
1154	"Set dialing script", StrChatStr, (void *)VAR_DIAL},
1155  { "escape",   NULL,	  SetEscape, 		LOCAL_AUTH,
1156	"Set escape characters", "hex-digit ..."},
1157  { "ifaddr",   NULL,   SetInterfaceAddr,	LOCAL_AUTH,
1158	"Set destination address", "[src-addr [dst-addr [netmask [trg-addr]]]]"},
1159  { "ifilter",  NULL,     SetIfilter, 		LOCAL_AUTH,
1160	"Set input filter", "..."},
1161  { "login",    NULL,     SetVariable,		LOCAL_AUTH,
1162	"Set login script", StrChatStr,	(void *)VAR_LOGIN },
1163  { "mru",      NULL,     SetInitialMRU,	LOCAL_AUTH,
1164	"Set Initial MRU value", StrValue },
1165  { "mtu",      NULL,     SetPreferredMTU,	LOCAL_AUTH,
1166	"Set Preferred MTU value", StrValue },
1167  { "ofilter",  NULL,	  SetOfilter,		LOCAL_AUTH,
1168	"Set output filter", "..." },
1169  { "openmode", NULL,	  SetOpenMode,		LOCAL_AUTH,
1170	"Set open mode", "[active|passive]"},
1171  { "parity",   NULL,     SetModemParity,	LOCAL_AUTH,
1172	"Set modem parity", "[odd|even|none]"},
1173  { "phone",    NULL,     SetVariable,		LOCAL_AUTH,
1174	"Set telephone number(s)", "phone1[:phone2[...]]", (void *)VAR_PHONE },
1175  { "reconnect",NULL,     SetReconnect,		LOCAL_AUTH,
1176	"Set Reconnect timeout", "value ntries"},
1177  { "redial",   NULL,     SetRedialTimeout,	LOCAL_AUTH,
1178	"Set Redial timeout", "value|random[.value|random] [dial_attempts]"},
1179  { "speed",    NULL,     SetModemSpeed,	LOCAL_AUTH,
1180	"Set modem speed", "speed"},
1181  { "timeout",  NULL,     SetIdleTimeout,	LOCAL_AUTH,
1182	"Set Idle timeout", StrValue},
1183#ifdef MSEXT
1184  { "ns",	NULL,	  SetNS,		LOCAL_AUTH,
1185	"Set NameServer", "pri-addr [sec-addr]"},
1186  { "nbns",	NULL,	  SetNBNS,		LOCAL_AUTH,
1187	"Set NetBIOS NameServer", "pri-addr [sec-addr]"},
1188#endif /* MSEXT */
1189  { "help",     "?",      HelpCommand,		LOCAL_AUTH | LOCAL_NO_AUTH,
1190	"Display this message", StrNull, (void *)SetCommands},
1191  { NULL,       NULL,     NULL },
1192};
1193
1194static int
1195SetCommand(list, argc, argv)
1196struct cmdtab *list;
1197int argc;
1198char **argv;
1199{
1200  int val = 1;
1201
1202  if (argc > 0)
1203    val = FindExec(SetCommands, argc, argv);
1204  else
1205    printf("Use `set ?' to get a list or `set ? <var>' for syntax help.\n");
1206  return(val);
1207}
1208
1209
1210static int
1211AddCommand(list, argc, argv)
1212struct cmdtab *list;
1213int argc;
1214char **argv;
1215{
1216  struct in_addr dest, gateway, netmask;
1217
1218  if (argc == 3) {
1219    dest = GetIpAddr(argv[0]);
1220    netmask = GetIpAddr(argv[1]);
1221    if (strcasecmp(argv[2], "HISADDR") == 0)
1222      gateway = IpcpInfo.his_ipaddr;
1223    else
1224      gateway = GetIpAddr(argv[2]);
1225    OsSetRoute(RTM_ADD, dest, gateway, netmask);
1226  } else {
1227    printf("Usage: %s %s\n", list->name, list->syntax);
1228  }
1229  return(1);
1230}
1231
1232static int
1233DeleteCommand(list, argc, argv)
1234struct cmdtab *list;
1235int argc;
1236char **argv;
1237{
1238  struct in_addr dest, gateway, netmask;
1239
1240  if (argc >= 2) {
1241    dest = GetIpAddr(argv[0]);
1242    if (strcasecmp(argv[1], "HISADDR") == 0)
1243      gateway = IpcpInfo.his_ipaddr;
1244    else
1245      gateway = GetIpAddr(argv[1]);
1246    netmask.s_addr = 0;
1247    if (argc == 3) {
1248      if (inet_aton(argv[1], &netmask) == 0) {
1249	printf("bad netmask value.\n");
1250	return(1);
1251      }
1252    }
1253    OsSetRoute(RTM_DELETE, dest, gateway, netmask);
1254  } else if (argc == 1 && strcasecmp(argv[0], "ALL") == 0) {
1255    DeleteIfRoutes(0);
1256  } else {
1257    printf("Usage: %s %s\n", list->name, list->syntax);
1258  }
1259  return(1);
1260}
1261
1262
1263static int AliasEnable();
1264static int AliasOption();
1265
1266
1267static struct cmdtab const AliasCommands[] =
1268{
1269  { "enable",   NULL,     AliasEnable,          LOCAL_AUTH,
1270        "enable IP aliasing", "[yes|no]"},
1271  { "port",   NULL,     AliasRedirectPort,          LOCAL_AUTH,
1272        "port redirection", "[proto  addr_local:port_local  port_alias]"},
1273  { "addr",   NULL,     AliasRedirectAddr,          LOCAL_AUTH,
1274        "static address translation", "[addr_local  addr_alias]"},
1275  { "deny_incoming",  NULL,    AliasOption,     LOCAL_AUTH,
1276        "stop incoming connections",   "[yes|no]",
1277        (void*)PKT_ALIAS_DENY_INCOMING},
1278  { "log",  NULL,     AliasOption,              LOCAL_AUTH,
1279        "log aliasing link creation",           "[yes|no]",
1280        (void*)PKT_ALIAS_LOG},
1281  { "same_ports", NULL,     AliasOption,        LOCAL_AUTH,
1282        "try to leave port numbers unchanged", "[yes|no]",
1283        (void*)PKT_ALIAS_SAME_PORTS},
1284  { "use_sockets", NULL,     AliasOption,       LOCAL_AUTH,
1285        "allocate host sockets", "[yes|no]",
1286        (void*)PKT_ALIAS_USE_SOCKETS },
1287  { "unregistered_only", NULL,     AliasOption, LOCAL_AUTH,
1288        "alias unregistered (private) IP address space only", "[yes|no]",
1289        (void*)PKT_ALIAS_UNREGISTERED_ONLY},
1290  { "help",     "?",      HelpCommand,          LOCAL_AUTH | LOCAL_NO_AUTH,
1291        "Display this message", StrNull,
1292        (void *)AliasCommands},
1293  { NULL,       NULL,     NULL },
1294};
1295
1296
1297static int
1298AliasCommand(list, argc, argv)
1299struct cmdtab *list;
1300int argc;
1301char **argv;
1302{
1303  int val = 1;
1304
1305  if (argc > 0)
1306    val = FindExec(AliasCommands, argc, argv);
1307  else
1308    printf("Use `alias help' to get a list or `alias help <option>' for syntax h
1309elp.\n");
1310  return(val);
1311}
1312
1313
1314static int
1315AliasEnable(list, argc, argv)
1316struct cmdtab *list;
1317int argc;
1318char **argv;
1319{
1320    if (argc == 1 && strcmp(argv[0], "yes") == 0) {
1321        if (!(mode & MODE_ALIAS))
1322            if (loadAliasHandlers(&VarAliasHandlers) == 0)
1323                mode |= MODE_ALIAS;
1324            else
1325                printf("Cannot load alias library\n");
1326    } else if (argc == 1 && strcmp(argv[0], "no") == 0) {
1327        if (mode & MODE_ALIAS) {
1328            unloadAliasHandlers();
1329            mode &= ~MODE_ALIAS;
1330        }
1331    } else {
1332        printf("Usage: alias %s %s\n", list->name, list->syntax);
1333    }
1334    return(1);
1335}
1336
1337
1338static int
1339AliasOption(list, argc, argv, param)
1340struct cmdtab *list;
1341int argc;
1342char **argv;
1343void* param;
1344{
1345   if (argc == 1 && strcmp(argv[0], "yes") == 0) {
1346      if (mode & MODE_ALIAS)
1347         VarSetPacketAliasMode((unsigned)param, (unsigned)param);
1348      else
1349         printf("alias not enabled\n");
1350   } else if (argc == 1 && strcmp(argv[0], "no") == 0) {
1351      if (mode & MODE_ALIAS)
1352         VarSetPacketAliasMode(0, (unsigned)param);
1353      else
1354         printf("alias not enabled\n");
1355   } else {
1356      printf("Usage: alias %s %s\n", list->name, list->syntax);
1357   }
1358   return(1);
1359}
1360