command.c revision 11336
1/*
2 *		PPP User command processing module
3 *
4 *	    Written by Toshiharu OHNO (tony-o@iij.ad.jp)
5 *
6 *   Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd.
7 *
8 * Redistribution and use in source and binary forms are permitted
9 * provided that the above copyright notice and this paragraph are
10 * duplicated in all such forms and that any documentation,
11 * advertising materials, and other materials related to such
12 * distribution and use acknowledge that the software was developed
13 * by the Internet Initiative Japan, Inc.  The name of the
14 * IIJ may not be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
18 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
19 *
20 * $Id: command.c,v 1.9 1995/09/02 17:20:50 amurai Exp $
21 *
22 */
23#include <ctype.h>
24#include <termios.h>
25#include "fsm.h"
26#include "phase.h"
27#include "lcp.h"
28#include "ipcp.h"
29#include "modem.h"
30#include "command.h"
31#include "hdlc.h"
32#include "vars.h"
33#include "auth.h"
34#include <netdb.h>
35#include <sys/socket.h>
36#include <arpa/inet.h>
37#include <net/route.h>
38#include "os.h"
39#include <paths.h>
40
41extern int  MakeArgs();
42extern void Cleanup(), TtyTermMode(), PacketMode();
43extern int  EnableCommand(), DisableCommand(), DisplayCommand();
44extern int  AcceptCommand(), DenyCommand();
45extern int  LocalAuthCommand();
46extern int  LoadCommand(), SaveCommand();
47extern int  ChangeParity(char *);
48extern int  SelectSystem();
49extern int  ShowRoute();
50extern void TtyOldMode(), TtyCommandMode();
51extern struct pppvars pppVars;
52
53struct in_addr ifnetmask;
54
55static int ShowCommand(), TerminalCommand(), QuitCommand();
56static int CloseCommand(), DialCommand(), DownCommand();
57static int SetCommand(), AddCommand(), DeleteCommand();
58static int ShellCommand();
59
60static int
61HelpCommand(list, argc, argv, plist)
62struct cmdtab *list;
63int argc;
64char **argv;
65struct cmdtab *plist;
66{
67  struct cmdtab *cmd;
68  int n;
69  char c;
70
71  if (argc > 0) {
72    for (cmd = plist; cmd->name; cmd++) {
73      if (strcmp(cmd->name, *argv) == 0 && (cmd->lauth & VarLocalAuth)) {
74        printf("%s %s\n", cmd->name, cmd->syntax);
75        return(1);
76      }
77    }
78    return(1);
79  }
80  n = 0;
81  for (cmd = plist; cmd->func; cmd++) {
82    if (cmd->name && (cmd->lauth & VarLocalAuth)) {
83      c = (n & 1)? '\n' : '\t';
84      printf("  %-8s: %-20s%c", cmd->name, cmd->helpmes, c);
85      n++;
86    }
87  }
88  if (n & 1)
89    printf("\n");
90  return(1);
91}
92
93int
94IsInteractive()
95{
96  char *mes = NULL;
97
98  if (mode & MODE_AUTO)
99    mes = "Working in auto mode.";
100  else if (mode & MODE_DIRECT)
101    mes = "Working in direct mode.";
102  else if (mode & MODE_DEDICATED)
103    mes = "Working in dedicated mode.";
104  if (mes) {
105    printf("%s\n", mes);
106    return(0);
107  }
108  return(1);
109}
110
111static int
112DialCommand(cmdlist, argc, argv)
113struct cmdtab *cmdlist;
114int argc;
115char **argv;
116{
117  int tries;
118
119  if (LcpFsm.state > ST_CLOSED) {
120    printf("LCP state is [%s]\n", StateNames[LcpFsm.state]);
121    return(1);
122  }
123  if (!IsInteractive())
124    return(1);
125  if (argc > 0) {
126    if (SelectSystem(*argv, CONFFILE) < 0) {
127      printf("%s: not found.\n", *argv);
128      return(1);
129    }
130  }
131  tries = 0;
132  do {
133    printf("Dial attempt %u\n", ++tries);
134    modem = OpenModem(mode);
135    if (modem < 0) {
136      printf("failed to open modem.\n");
137      modem = 0;
138      break;
139    }
140    if (DialModem()) {
141      sleep(1);
142      ModemTimeout();
143      PacketMode();
144      break;
145    }
146  } while (VarDialTries == 0 || tries < VarDialTries);
147  return(1);
148}
149
150static int
151ShellCommand(cmdlist, argc, argv)
152struct cmdtab *cmdlist;
153int argc;
154char **argv;
155{
156  const char *shell;
157  pid_t shpid;
158
159  if((shell = getenv("SHELL")) == 0) {
160    shell = _PATH_BSHELL;
161  }
162
163#ifndef HAVE_SHELL_CMD_WITH_ANY_MODE
164  if( mode != MODE_INTER) {
165     fprintf(stdout,
166             "Can start an shell only in interactive mode\n");
167     return(1);
168  }
169#else
170  if(argc == 0 && !(mode & MODE_INTER)) {
171      fprintf(stderr,
172             "Can start an interactive shell only in interactive mode\n");
173      return(1);
174  }
175#endif /* HAVE_SHELL_CMD_WITH_ANY_MODE */
176
177  if((shpid = fork()) == 0) {
178     int i;
179     for(i = 3; i < getdtablesize(); i++)
180	(void)close(i);
181
182     /*
183      * We are running setuid, we should change to
184      * real user for avoiding security problems.
185      */
186     setgid( getgid() );
187     setuid( getuid() );
188
189     TtyOldMode();
190     if(argc > 0)
191       execvp(argv[0], argv);
192     else
193       execl(shell, shell, NULL);
194
195     fprintf(stdout, "exec() of %s failed\n", argc > 0? argv[0]: shell);
196     exit(255);
197  }
198  if( shpid == (pid_t)-1 ) {
199    fprintf(stdout, "Fork failed\n");
200  } else {
201    int status;
202    (void)waitpid(shpid, &status, 0);
203  }
204
205  TtyCommandMode(1);
206
207  return(0);
208}
209
210static char StrOption[] = "option ..";
211static char StrRemote[] = "[remote]";
212char StrNull[] = "";
213
214struct cmdtab Commands[] = {
215  { "accept",  NULL,    AcceptCommand,	LOCAL_AUTH,
216  	"accept option request",	StrOption},
217  { "add",     NULL,	AddCommand,	LOCAL_AUTH,
218	"add route",			"dest mask gateway"},
219  { "close",   NULL,    CloseCommand,	LOCAL_AUTH,
220	"Close connection",		StrNull},
221  { "delete",  NULL,    DeleteCommand,	LOCAL_AUTH,
222  	"delete route",			"dest gateway"},
223  { "deny",    NULL,    DenyCommand,	LOCAL_AUTH,
224  	"Deny option request",		StrOption},
225  { "dial",    "call",  DialCommand,	LOCAL_AUTH,
226  	"Dial and login",		StrRemote},
227  { "disable", NULL,    DisableCommand,	LOCAL_AUTH,
228  	"Disable option",		StrOption},
229  { "display", NULL,    DisplayCommand,	LOCAL_AUTH,
230  	"Display option configs",	StrNull},
231  { "enable",  NULL,    EnableCommand,	LOCAL_AUTH,
232  	"Enable option",		StrOption},
233  { "passwd",  NULL,	LocalAuthCommand,LOCAL_NO_AUTH,
234  	"Password for manipulation", StrOption},
235  { "load",    NULL,    LoadCommand,	LOCAL_AUTH,
236  	"Load settings",		StrRemote},
237  { "save",    NULL,    SaveCommand,	LOCAL_AUTH,
238  	"Save settings", StrNull},
239  { "set",     "setup", SetCommand,	LOCAL_AUTH,
240  	"Set parameters",  "var value"},
241  { "shell",   "!",     ShellCommand,   LOCAL_AUTH,
242	"Run a subshell",  "[sh command]"},
243  { "show",    NULL,    ShowCommand,	LOCAL_AUTH,
244  	"Show status and statictics", "var"},
245  { "term",    NULL,    TerminalCommand,LOCAL_AUTH,
246  	"Enter to terminal mode", StrNull},
247  { "quit",    "bye",   QuitCommand,	LOCAL_AUTH | LOCAL_NO_AUTH,
248  	"Quit PPP program", StrNull},
249  { "help",    "?",     HelpCommand,	LOCAL_AUTH | LOCAL_NO_AUTH,
250	"Display this message", "[command]", (void *)Commands },
251  { NULL,      "down",  DownCommand,	LOCAL_AUTH,
252  	"Generate down event",		StrNull},
253  { NULL,      NULL,    NULL },
254};
255
256extern int ReportCcpStatus();
257extern int ReportLcpStatus();
258extern int ReportIpcpStatus();
259extern int ReportProtStatus();
260extern int ReportCompress();
261extern int ShowModemStatus();
262extern int ReportHdlcStatus();
263extern int ShowMemMap();
264
265static char *LogLevelName[] = {
266  LM_PHASE, LM_CHAT, LM_LQM,   LM_LCP,
267  LM_TCPIP, LM_HDLC, LM_ASYNC,
268};
269
270static int ShowDebugLevel()
271{
272  int i;
273
274  printf("%02x: ", loglevel);
275  for (i = LOG_PHASE; i < MAXLOGLEVEL; i++) {
276    if (loglevel & (1 << i))
277      printf("%s ", LogLevelName[i]);
278  }
279  printf("\n");
280  return(1);
281}
282
283static int ShowEscape()
284{
285  int code, bit;
286
287  if (EscMap[32]) {
288    for (code = 0; code < 32; code++) {
289      if (EscMap[code]) {
290        for (bit = 0; bit < 8; bit++) {
291          if (EscMap[code] & (1<<bit)) {
292            printf(" 0x%02x", (code << 3) + bit);
293          }
294        }
295      }
296    }
297    printf("\n");
298  }
299  return(1);
300}
301
302static int ShowTimeout()
303{
304  printf(" Idle Timer: %d secs   LQR Timer: %d secs   Retry Timer: %d secs\n",
305    VarIdleTimeout, VarLqrTimeout, VarRetryTimeout);
306  return(1);
307}
308
309static int ShowAuthKey()
310{
311  printf("AuthName = %s\n", VarAuthName);
312  printf("AuthKey  = %s\n", VarAuthKey);
313  return(1);
314}
315
316static int ShowVersion()
317{
318  extern char *VarVersion[];
319  extern char *VarLocalVersion[];
320
321  printf("%s - %s \n", VarVersion, VarLocalVersion);
322  return(1);
323}
324
325static int ShowLogList()
326{
327  ListLog();
328  return(1);
329}
330
331static int ShowRedial()
332{
333  printf(" Redial Timer: ");
334
335  if (VarRedialTimeout >= 0) {
336    printf(" %d seconds, ", VarRedialTimeout);
337  }
338  else {
339    printf(" Random 0 - %d seconds, ", REDIAL_PERIOD);
340  }
341
342  if (VarDialTries)
343      printf("%d dial tries", VarDialTries);
344
345  printf("\n");
346
347  return(1);
348}
349
350
351extern int ShowIfilter(), ShowOfilter(), ShowDfilter(), ShowAfilter();
352
353struct cmdtab ShowCommands[] = {
354  { "afilter",  NULL,     ShowAfilter,		LOCAL_AUTH,
355	"Show keep Alive filters", StrOption},
356  { "auth",     NULL,     ShowAuthKey,		LOCAL_AUTH,
357	"Show auth name/key", StrNull},
358  { "ccp",      NULL,     ReportCcpStatus,	LOCAL_AUTH,
359	"Show CCP status", StrNull},
360  { "compress", NULL,     ReportCompress,	LOCAL_AUTH,
361	"Show compression statictics", StrNull},
362  { "debug",	NULL,	  ShowDebugLevel,	LOCAL_AUTH,
363	"Show current debug level", StrNull},
364  { "dfilter",  NULL,     ShowDfilter,		LOCAL_AUTH,
365	"Show Demand filters", StrOption},
366  { "escape",   NULL,     ShowEscape,		LOCAL_AUTH,
367	"Show escape characters", StrNull},
368  { "hdlc",	NULL,	  ReportHdlcStatus,	LOCAL_AUTH,
369	"Show HDLC error summary", StrNull},
370  { "ifilter",  NULL,     ShowIfilter,		LOCAL_AUTH,
371	"Show Input filters", StrOption},
372  { "ipcp",     NULL,     ReportIpcpStatus,	LOCAL_AUTH,
373	"Show IPCP status", StrNull},
374  { "lcp",      NULL,     ReportLcpStatus,	LOCAL_AUTH,
375	"Show LCP status", StrNull},
376  { "log",      NULL,     ShowLogList,		LOCAL_AUTH,
377	"Show log records", StrNull},
378  { "mem",      NULL,     ShowMemMap,		LOCAL_AUTH,
379	"Show memory map", StrNull},
380  { "modem",    NULL,     ShowModemStatus,	LOCAL_AUTH,
381	"Show modem setups", StrNull},
382  { "ofilter",  NULL,     ShowOfilter,		LOCAL_AUTH,
383	"Show Output filters", StrOption},
384  { "proto",    NULL,     ReportProtStatus,	LOCAL_AUTH,
385	"Show protocol summary", StrNull},
386  { "route",    NULL,     ShowRoute,		LOCAL_AUTH,
387	"Show routing table", StrNull},
388  { "timeout",  NULL,	  ShowTimeout,		LOCAL_AUTH,
389	"Show Idle timeout value", StrNull},
390  { "redial",   NULL,	  ShowRedial,		LOCAL_AUTH,
391	"Show Redial timeout value", StrNull},
392  { "version",  NULL,	  ShowVersion,		LOCAL_NO_AUTH | LOCAL_AUTH,
393	"Show version string", StrNull},
394  { "help",     "?",      HelpCommand,		LOCAL_NO_AUTH | LOCAL_AUTH,
395	"Display this message", StrNull, (void *)ShowCommands},
396  { NULL,       NULL,     NULL },
397};
398
399struct cmdtab *
400FindCommand(cmds, str, pmatch)
401struct cmdtab *cmds;
402char *str;
403int *pmatch;
404{
405  int nmatch = 0;
406  int len = strlen(str);
407  struct cmdtab *found = NULL;
408
409  while (cmds->func) {
410    if (cmds->name && strncmp(str, cmds->name, len) == 0) {
411      nmatch++;
412      found = cmds;
413    } else if (cmds->alias && strncmp(str, cmds->alias, len) == 0) {
414      nmatch++;
415      found = cmds;
416    }
417    cmds++;
418  }
419  *pmatch = nmatch;
420  return(found);
421}
422
423int
424FindExec(cmdlist, argc, argv)
425struct cmdtab *cmdlist;
426int argc;
427char **argv;
428{
429  struct cmdtab *cmd;
430  int val = 1;
431  int nmatch;
432
433  cmd = FindCommand(cmdlist, *argv, &nmatch);
434  if (nmatch > 1)
435    printf("Ambiguous.\n");
436  else if (cmd && ( cmd->lauth & VarLocalAuth ) )
437    val = (cmd->func)(cmd, --argc, ++argv, cmd->args);
438  else
439    printf("what?\n");
440  return(val);
441}
442
443void
444Prompt(flag)
445int flag;
446{
447  char *pconnect, *pauth;
448
449  if (!(mode & MODE_INTER))
450    return;
451
452  if (flag) printf("\n");
453
454  if ( VarLocalAuth == LOCAL_AUTH )
455    pauth = " ON ";
456  else
457    pauth = " on ";
458  if (IpcpFsm.state == ST_OPENED && phase == PHASE_NETWORK)
459    pconnect = "PPP";
460  else
461    pconnect = "ppp";
462  printf("%s%s%s> ", pconnect, pauth, VarShortHost);
463  fflush(stdout);
464}
465
466void
467DecodeCommand(buff, nb, prompt)
468char *buff;
469int nb;
470int prompt;
471{
472  char *vector[20];
473  char **argv;
474  int argc, val;
475  char *cp;
476
477  val = 1;
478  if (nb > 0) {
479    cp = buff + strcspn(buff, "\r\n");
480    if (cp)
481      *cp = '\0';
482    {
483      argc = MakeArgs(buff, &vector);
484      argv = vector;
485
486      if (argc > 0)
487        val = FindExec(Commands, argc, argv);
488    }
489  }
490  if (val && prompt)
491    Prompt(0);
492}
493
494static int
495ShowCommand(list, argc, argv)
496struct cmdtab *list;
497int argc;
498char **argv;
499{
500  int val = 1;
501
502  if (argc > 0)
503    val = FindExec(ShowCommands, argc, argv);
504  else
505    printf("Use ``show ?'' to get a list.\n");
506  return(val);
507}
508
509static int
510TerminalCommand()
511{
512  if (LcpFsm.state > ST_CLOSED) {
513    printf("LCP state is [%s]\n", StateNames[LcpFsm.state]);
514    return(1);
515  }
516  if (!IsInteractive())
517    return(1);
518  modem = OpenModem(mode);
519  if (modem < 0) {
520    printf("failed to open modem.\n");
521    modem = 0;
522    return(1);
523  }
524  printf("Enter to terminal mode.\n");
525  printf("Type `~?' for help.\n");
526  TtyTermMode();
527  return(0);
528}
529
530static int
531QuitCommand(list, argc, argv)
532struct cmdtab *list;
533int argc;
534char **argv;
535{
536  if (mode & (MODE_DIRECT|MODE_DEDICATED|MODE_AUTO)) {
537    if (argc > 0 && (VarLocalAuth & LOCAL_AUTH)) {
538      Cleanup(EX_NORMAL);
539    } else {
540      VarLocalAuth = LOCAL_NO_AUTH;
541      close(netfd);
542      close(1);
543      dup2(2, 1);     /* Have to have something here or the modem will be 1 */
544      netfd = -1;
545      mode &= ~MODE_INTER;
546    }
547  } else
548    Cleanup(EX_NORMAL);
549  return(1);
550}
551
552static int
553CloseCommand()
554{
555  LcpClose();
556  return(1);
557}
558
559static int
560DownCommand()
561{
562  LcpDown();
563  return(1);
564}
565
566static int SetModemSpeed(list, argc, argv)
567struct cmdtab *list;
568int argc;
569char **argv;
570{
571  int speed;
572
573  if (argc > 0) {
574    if (strcmp(*argv, "sync") == 0) {
575      VarSpeed = 0;
576      return(1);
577    }
578    speed = atoi(*argv);
579    if (IntToSpeed(speed) != B0) {
580      VarSpeed = speed;
581      return(1);
582    }
583    printf("invalid speed.\n");
584  }
585  return(1);
586}
587
588static int SetRedialTimeout(list, argc, argv)
589struct cmdtab *list;
590int argc;
591char **argv;
592{
593  int timeout;
594  int tries;
595
596  if (argc == 1 || argc == 2 ) {
597    if (strcasecmp(argv[0], "random") == 0) {
598      VarRedialTimeout = -1;
599      printf("Using random redial timeout.\n");
600      srandom(time(0));
601    }
602    else {
603      timeout = atoi(argv[0]);
604
605      if (timeout >= 0) {
606	VarRedialTimeout = timeout;
607      }
608      else {
609	printf("invalid redial timeout\n");
610	printf("Usage: %s %s\n", list->name, list->syntax);
611      }
612    }
613    if (argc == 2) {
614      tries = atoi(argv[1]);
615
616      if (tries >= 0) {
617	  VarDialTries = tries;
618      }
619      else {
620	printf("invalid retry value\n");
621	printf("Usage: %s %s\n", list->name, list->syntax);
622      }
623    }
624  }
625  else {
626    printf("Usage: %s %s\n", list->name, list->syntax);
627  }
628  return(1);
629}
630
631static int SetModemParity(list, argc, argv)
632struct cmdtab *list;
633int argc;
634char **argv;
635{
636  int parity;
637
638  if (argc > 0) {
639    parity = ChangeParity(*argv);
640    if (parity < 0)
641      printf("Invalid parity.\n");
642    else
643      VarParity = parity;
644  }
645  return(1);
646}
647
648static int
649SetDebugLevel(list, argc, argv)
650struct cmdtab *list;
651int argc;
652char **argv;
653{
654  int level, w;
655
656  for (level = 0; argc-- > 0; argv++) {
657    if (isdigit(**argv)) {
658      w = atoi(*argv);
659      if (w < 0 || w >= MAXLOGLEVEL) {
660	printf("invalid log level.\n");
661	break;
662      } else
663	level |= (1 << w);
664    } else {
665      for (w = 0; w < MAXLOGLEVEL; w++) {
666	if (strcasecmp(*argv, LogLevelName[w]) == 0) {
667	  level |= (1 << w);
668	  continue;
669	}
670      }
671    }
672  }
673  loglevel = level;
674  return(1);
675}
676
677static int
678SetEscape(list, argc, argv)
679struct cmdtab *list;
680int argc;
681char **argv;
682{
683  int code;
684
685  for (code = 0; code < 33; code++)
686    EscMap[code] = 0;
687  while (argc-- > 0) {
688    sscanf(*argv++, "%x", &code);
689    code &= 0xff;
690    EscMap[code >> 3] |= (1 << (code&7));
691    EscMap[32] = 1;
692  }
693  return(1);
694}
695
696static int
697SetInitialMRU(list, argc, argv)
698struct cmdtab *list;
699int argc;
700char **argv;
701{
702  int mru;
703
704  if (argc > 0) {
705    mru = atoi(*argv);
706    if (mru < 100)
707      printf("given value is too small.\n");
708    else if (mru > MAX_MRU)
709      printf("given value is too big.\n");
710    else
711      VarMRU = mru;
712  }
713  return(1);
714}
715
716static int
717SetIdleTimeout(list, argc, argv)
718struct cmdtab *list;
719int argc;
720char **argv;
721{
722  if (argc-- > 0) {
723    VarIdleTimeout = atoi(*argv++);
724    if (argc-- > 0) {
725      VarLqrTimeout = atoi(*argv++);
726      if (VarLqrTimeout < 1)
727	VarLqrTimeout = 30;
728      if (argc > 0) {
729	VarRetryTimeout = atoi(*argv);
730	if (VarRetryTimeout < 1 || VarRetryTimeout > 10)
731	  VarRetryTimeout = 3;
732      }
733    }
734  }
735  return(1);
736}
737
738struct in_addr
739GetIpAddr(cp)
740char *cp;
741{
742  struct hostent *hp;
743  struct in_addr ipaddr;
744
745  hp = gethostbyname(cp);
746  if (hp && hp->h_addrtype == AF_INET)
747    bcopy(hp->h_addr, &ipaddr, hp->h_length);
748  else if (inet_aton(cp, &ipaddr) == 0)
749    ipaddr.s_addr = 0;
750  return(ipaddr);
751}
752
753static int
754SetInterfaceAddr(list, argc, argv)
755struct cmdtab *list;
756int argc;
757char **argv;
758{
759  int width;
760
761  DefMyAddress.ipaddr.s_addr = DefHisAddress.ipaddr.s_addr = 0L;
762  if (argc > 0) {
763    ParseAddr(argc, argv++,
764      &DefMyAddress.ipaddr, &DefMyAddress.mask, &DefMyAddress.width);
765    if (--argc > 0) {
766      ParseAddr(argc, argv++,
767	&DefHisAddress.ipaddr, &DefHisAddress.mask, &DefHisAddress.width);
768      if (--argc > 0) {
769        ifnetmask = GetIpAddr(*argv);
770    	if (--argc > 0) {
771      		ParseAddr(argc, argv++,
772		        &DefTriggerAddress.ipaddr,
773			&DefTriggerAddress.mask,
774			&DefTriggerAddress.width);
775	}
776      }
777    }
778  }
779  /*
780   * For backwards compatibility, 0.0.0.0 means any address.
781   */
782  if (DefMyAddress.ipaddr.s_addr == 0) {
783    DefMyAddress.mask.s_addr = 0;
784    DefMyAddress.width = 0;
785  }
786  if (DefHisAddress.ipaddr.s_addr == 0) {
787    DefHisAddress.mask.s_addr = 0;
788    DefHisAddress.width = 0;
789  }
790
791  if ((mode & MODE_AUTO) ||
792	((mode & MODE_DEDICATED) && dstsystem)) {
793    OsSetIpaddress(DefMyAddress.ipaddr, DefHisAddress.ipaddr, ifnetmask);
794  }
795  return(1);
796}
797
798
799#define	VAR_AUTHKEY	0
800#define	VAR_DIAL	1
801#define	VAR_LOGIN	2
802#define	VAR_AUTHNAME	3
803#define	VAR_DEVICE	4
804#define	VAR_ACCMAP	5
805#define	VAR_PHONE	6
806
807static int
808SetVariable(list, argc, argv, param)
809struct cmdtab *list;
810int argc;
811char **argv;
812int param;
813{
814  u_long map;
815
816  if (argc > 0) {
817    switch (param) {
818    case VAR_AUTHKEY:
819      strncpy(VarAuthKey, *argv, sizeof(VarAuthKey)-1);
820      break;
821    case VAR_AUTHNAME:
822      strncpy(VarAuthName, *argv, sizeof(VarAuthName)-1);
823      break;
824    case VAR_DIAL:
825      strncpy(VarDialScript, *argv, sizeof(VarDialScript)-1);
826      break;
827    case VAR_LOGIN:
828      strncpy(VarLoginScript, *argv, sizeof(VarDialScript)-1);
829      break;
830    case VAR_DEVICE:
831      strncpy(VarDevice, *argv, sizeof(VarDevice)-1);
832      break;
833    case VAR_ACCMAP:
834      sscanf(*argv, "%x", &map);
835      VarAccmap = map;
836      break;
837    case VAR_PHONE:
838      strncpy(VarPhone, *argv, sizeof(VarPhone)-1);
839      break;
840    }
841  }
842  return(1);
843}
844
845static int SetOpenMode(list, argc, argv)
846struct cmdtab *list;
847int argc;
848char **argv;
849{
850  if (argc > 0) {
851    if (strcmp(*argv, "active") == 0)
852      VarOpenMode = OPEN_ACTIVE;
853    else if (strcmp(*argv, "passive") == 0)
854      VarOpenMode = OPEN_PASSIVE;
855    else
856      printf("Invalid mode.\n");
857  }
858  return(1);
859}
860
861static char StrChatStr[] = "chat-script";
862static char StrValue[] = "value";
863
864extern int SetIfilter(), SetOfilter(), SetDfilter(), SetAfilter();
865
866struct cmdtab SetCommands[] = {
867  { "accmap",   NULL,	  SetVariable,		LOCAL_AUTH,
868	"Set accmap value", "hex-value", (void *)VAR_ACCMAP},
869  { "afilter",  NULL,     SetAfilter, 		LOCAL_AUTH,
870	"Set keep Alive filter", "..."},
871  { "authkey",  "key",     SetVariable,		LOCAL_AUTH,
872	"Set authentication key", "key", (void *)VAR_AUTHKEY},
873  { "authname", NULL,     SetVariable,		LOCAL_AUTH,
874	"Set authentication name", "name", (void *)VAR_AUTHNAME},
875  { "debug",    NULL,	  SetDebugLevel,	LOCAL_AUTH,
876	"Set debug level", StrValue},
877  { "device",     "line", SetVariable, 		LOCAL_AUTH,
878	"Set modem device name", "device-name",	(void *)VAR_DEVICE},
879  { "dfilter",  NULL,     SetDfilter,		 LOCAL_AUTH,
880	"Set demand filter", "..."},
881  { "dial",     NULL,     SetVariable, 		LOCAL_AUTH,
882	"Set dialing script", StrChatStr, (void *)VAR_DIAL},
883  { "escape",   NULL,	  SetEscape, 		LOCAL_AUTH,
884	"Set escape characters", "hex-digit ..."},
885  { "ifaddr",   NULL,   SetInterfaceAddr,	LOCAL_AUTH,
886	"Set destination address", "src-addr dst-addr netmask"},
887  { "ifilter",  NULL,     SetIfilter, 		LOCAL_AUTH,
888	"Set input filter", "..."},
889  { "login",    NULL,     SetVariable,		LOCAL_AUTH,
890	"Set login script", StrChatStr,	(void *)VAR_LOGIN },
891  { "mru",      "mtu",    SetInitialMRU,	LOCAL_AUTH,
892	"Set Initial MRU value", StrValue },
893  { "ofilter",  NULL,	  SetOfilter,		LOCAL_AUTH,
894	"Set output filter", "..." },
895  { "openmode", NULL,	  SetOpenMode,		LOCAL_AUTH,
896	"Set open mode", "[active|passive]"},
897  { "parity",   NULL,     SetModemParity,	LOCAL_AUTH,
898	"Set modem parity", "[odd|even|none]"},
899  { "phone",    NULL,     SetVariable,		LOCAL_AUTH,
900	"Set telephone number", "phone-number",	(void *)VAR_PHONE },
901  { "speed",    NULL,     SetModemSpeed,	LOCAL_AUTH,
902	"Set modem speed", "speed"},
903  { "timeout",  NULL,     SetIdleTimeout,	LOCAL_AUTH,
904	"Set Idle timeout", StrValue},
905  { "redial",   NULL,     SetRedialTimeout,	LOCAL_AUTH,
906	"Set Redial timeout", "value|random [dial_attempts]"},
907  { "help",     "?",      HelpCommand,		LOCAL_AUTH | LOCAL_NO_AUTH,
908	"Display this message", StrNull, (void *)SetCommands},
909  { NULL,       NULL,     NULL },
910};
911
912static int
913SetCommand(list, argc, argv)
914struct cmdtab *list;
915int argc;
916char **argv;
917{
918  int val = 1;
919
920  if (argc > 0)
921    val = FindExec(SetCommands, argc, argv);
922  else
923    printf("Use ``set ?'' to get a list.\n");
924  return(val);
925}
926
927
928static int
929AddCommand(list, argc, argv)
930struct cmdtab *list;
931int argc;
932char **argv;
933{
934  struct in_addr dest, gateway, netmask;
935
936  if (argc == 3) {
937    dest = GetIpAddr(argv[0]);
938    netmask = GetIpAddr(argv[1]);
939    if (strcmp(argv[2], "HISADDR") == 0)
940      gateway = IpcpInfo.his_ipaddr;
941    else
942      gateway = GetIpAddr(argv[2]);
943    OsSetRoute(RTM_ADD, dest, gateway, netmask);
944  } else {
945    printf("Usage: %s %s\n", list->name, list->syntax);
946  }
947  return(1);
948}
949
950static int
951DeleteCommand(list, argc, argv)
952struct cmdtab *list;
953int argc;
954char **argv;
955{
956  struct in_addr dest, gateway, netmask;
957
958  if (argc >= 2) {
959    dest = GetIpAddr(argv[0]);
960    if (strcmp(argv[1], "HISADDR") == 0)
961      gateway = IpcpInfo.his_ipaddr;
962    else
963      gateway = GetIpAddr(argv[1]);
964    netmask.s_addr = 0;
965    if (argc == 3) {
966      if (inet_aton(argv[1], &netmask) == 0) {
967	printf("bad netmask value.\n");
968	return(1);
969      }
970    }
971    OsSetRoute(RTM_DELETE, dest, gateway, netmask);
972  } else if (argc == 1 && strcmp(argv[0], "ALL") == 0) {
973    DeleteIfRoutes(0);
974  } else {
975    printf("Usage: %s %s\n", list->name, list->syntax);
976  }
977  return(1);
978}
979
980