command.c revision 9448
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.7 1995/07/08 08:28:00 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
40extern int  MakeArgs();
41extern void Cleanup(), TtyTermMode(), PacketMode();
42extern int  EnableCommand(), DisableCommand(), DisplayCommand();
43extern int  AcceptCommand(), DenyCommand();
44extern int  LocalAuthCommand();
45extern int  LoadCommand(), SaveCommand();
46extern int  ChangeParity(char *);
47extern int  SelectSystem();
48extern int  ShowRoute();
49extern struct pppvars pppVars;
50
51struct in_addr ifnetmask;
52
53static int ShowCommand(), TerminalCommand(), QuitCommand();
54static int CloseCommand(), DialCommand(), DownCommand();
55static int SetCommand(), AddCommand(), DeleteCommand();
56
57static int
58HelpCommand(list, argc, argv, plist)
59struct cmdtab *list;
60int argc;
61char **argv;
62struct cmdtab *plist;
63{
64  struct cmdtab *cmd;
65  int n;
66  char c;
67
68  if (argc > 0) {
69    for (cmd = plist; cmd->name; cmd++) {
70      if (strcmp(cmd->name, *argv) == 0 && (cmd->lauth & VarLocalAuth)) {
71        printf("%s %s\n", cmd->name, cmd->syntax);
72        return(1);
73      }
74    }
75    return(1);
76  }
77  n = 0;
78  for (cmd = plist; cmd->func; cmd++) {
79    if (cmd->name && (cmd->lauth & VarLocalAuth)) {
80      c = (n & 1)? '\n' : '\t';
81      printf("  %-8s: %-20s%c", cmd->name, cmd->helpmes, c);
82      n++;
83    }
84  }
85  if (n & 1)
86    printf("\n");
87  return(1);
88}
89
90int
91IsInteractive()
92{
93  char *mes = NULL;
94
95  if (mode & MODE_AUTO)
96    mes = "Working as auto mode.";
97  else if (mode & MODE_DIRECT)
98    mes = "Working as direct mode.";
99  else if (mode & MODE_DEDICATED)
100    mes = "Workring as dedicated mode.";
101  if (mes) {
102    printf("%s\n", mes);
103    return(0);
104  }
105  return(1);
106}
107
108static int
109DialCommand(cmdlist, argc, argv)
110struct cmdtab *cmdlist;
111int argc;
112char **argv;
113{
114  if (LcpFsm.state > ST_CLOSED) {
115    printf("LCP state is [%s]\n", StateNames[LcpFsm.state]);
116    return(1);
117  }
118  if (!IsInteractive())
119    return(1);
120  if (argc > 0) {
121    if (SelectSystem(*argv, CONFFILE) < 0) {
122      printf("%s: not found.\n", *argv);
123      return(1);
124    }
125  }
126  modem = OpenModem(mode);
127  if (modem < 0) {
128    printf("failed to open modem.\n");
129    modem = 0;
130    return(1);
131  }
132  if (DialModem()) {
133    sleep(1);
134    ModemTimeout();
135    PacketMode();
136  }
137  return(1);
138}
139
140static char StrOption[] = "option ..";
141static char StrRemote[] = "[remote]";
142char StrNull[] = "";
143
144struct cmdtab Commands[] = {
145  { "accept",  NULL,    AcceptCommand,	LOCAL_AUTH,
146  	"accept option request",	StrOption},
147  { "add",     NULL,	AddCommand,	LOCAL_AUTH,
148	"add route",			"dest mask gateway"},
149  { "close",   NULL,    CloseCommand,	LOCAL_AUTH,
150	"Close connection",		StrNull},
151  { "delete",  NULL,    DeleteCommand,	LOCAL_AUTH,
152  	"delete route",			"dest gateway"},
153  { "deny",    NULL,    DenyCommand,	LOCAL_AUTH,
154  	"Deny option request",		StrOption},
155  { "dial",    "call",  DialCommand,	LOCAL_AUTH,
156  	"Dial and login",		StrRemote},
157  { "disable", NULL,    DisableCommand,	LOCAL_AUTH,
158  	"Disable option",		StrOption},
159  { "display", NULL,    DisplayCommand,	LOCAL_AUTH,
160  	"Display option configs",	StrNull},
161  { "enable",  NULL,    EnableCommand,	LOCAL_AUTH,
162  	"Enable option",		StrOption},
163  { "passwd",  NULL,	LocalAuthCommand,LOCAL_NO_AUTH,
164  	"Password for manipulation", StrOption},
165  { "load",    NULL,    LoadCommand,	LOCAL_AUTH,
166  	"Load settings",		StrRemote},
167  { "save",    NULL,    SaveCommand,	LOCAL_AUTH,
168  	"Save settings", StrNull},
169  { "set",     "setup", SetCommand,	LOCAL_AUTH,
170  	"Set parameters",  "var value"},
171  { "show",    NULL,    ShowCommand,	LOCAL_AUTH,
172  	"Show status and statictics", "var"},
173  { "term",    NULL,    TerminalCommand,LOCAL_AUTH,
174  	"Enter to terminal mode", StrNull},
175  { "quit",    "bye",   QuitCommand,	LOCAL_AUTH | LOCAL_NO_AUTH,
176  	"Quit PPP program", StrNull},
177  { "help",    "?",     HelpCommand,	LOCAL_AUTH | LOCAL_NO_AUTH,
178	"Display this message", "[command]", (void *)Commands },
179  { NULL,      "down",  DownCommand,	LOCAL_AUTH,
180  	"Generate down event",		StrNull},
181  { NULL,      NULL,    NULL },
182};
183
184extern int ReportCcpStatus();
185extern int ReportLcpStatus();
186extern int ReportIpcpStatus();
187extern int ReportProtStatus();
188extern int ReportCompress();
189extern int ShowModemStatus();
190extern int ReportHdlcStatus();
191extern int ShowMemMap();
192
193static char *LogLevelName[] = {
194  LM_PHASE, LM_CHAT, LM_LQM,   LM_LCP,
195  LM_TCPIP, LM_HDLC, LM_ASYNC,
196};
197
198static int ShowDebugLevel()
199{
200  int i;
201
202  printf("%02x: ", loglevel);
203  for (i = LOG_PHASE; i < MAXLOGLEVEL; i++) {
204    if (loglevel & (1 << i))
205      printf("%s ", LogLevelName[i]);
206  }
207  printf("\n");
208  return(1);
209}
210
211static int ShowEscape()
212{
213  int code, bit;
214
215  if (EscMap[32]) {
216    for (code = 0; code < 32; code++) {
217      if (EscMap[code]) {
218        for (bit = 0; bit < 8; bit++) {
219          if (EscMap[code] & (1<<bit)) {
220            printf(" 0x%02x", (code << 3) + bit);
221          }
222        }
223      }
224    }
225    printf("\n");
226  }
227  return(1);
228}
229
230static int ShowTimeout()
231{
232  printf(" Idle Timer: %d secs   LQR Timer: %d secs   Retry Timer: %d secs\n",
233    VarIdleTimeout, VarLqrTimeout, VarRetryTimeout);
234  return(1);
235}
236
237static int ShowAuthKey()
238{
239  printf("AuthName = %s\n", VarAuthName);
240  printf("AuthKey  = %s\n", VarAuthKey);
241  return(1);
242}
243
244static int ShowVersion()
245{
246  extern char *VarVersion[];
247  extern char *VarLocalVersion[];
248
249  printf("%s - %s \n", VarVersion, VarLocalVersion);
250  return(1);
251}
252
253static int ShowLogList()
254{
255  ListLog();
256  return(1);
257}
258
259extern int ShowIfilter(), ShowOfilter(), ShowDfilter(), ShowAfilter();
260
261struct cmdtab ShowCommands[] = {
262  { "afilter",  NULL,     ShowAfilter,		LOCAL_AUTH,
263	"Show keep Alive filters", StrOption},
264  { "auth",     NULL,     ShowAuthKey,		LOCAL_AUTH,
265	"Show auth name/key", StrNull},
266  { "ccp",      NULL,     ReportCcpStatus,	LOCAL_AUTH,
267	"Show CCP status", StrNull},
268  { "compress", NULL,     ReportCompress,	LOCAL_AUTH,
269	"Show compression statictics", StrNull},
270  { "debug",	NULL,	  ShowDebugLevel,	LOCAL_AUTH,
271	"Show current debug level", StrNull},
272  { "dfilter",  NULL,     ShowDfilter,		LOCAL_AUTH,
273	"Show Demand filters", StrOption},
274  { "escape",   NULL,     ShowEscape,		LOCAL_AUTH,
275	"Show escape characters", StrNull},
276  { "hdlc",	NULL,	  ReportHdlcStatus,	LOCAL_AUTH,
277	"Show HDLC error summary", StrNull},
278  { "ifilter",  NULL,     ShowIfilter,		LOCAL_AUTH,
279	"Show Input filters", StrOption},
280  { "ipcp",     NULL,     ReportIpcpStatus,	LOCAL_AUTH,
281	"Show IPCP status", StrNull},
282  { "lcp",      NULL,     ReportLcpStatus,	LOCAL_AUTH,
283	"Show LCP status", StrNull},
284  { "log",      NULL,     ShowLogList,		LOCAL_AUTH,
285	"Show log records", StrNull},
286  { "mem",      NULL,     ShowMemMap,		LOCAL_AUTH,
287	"Show memory map", StrNull},
288  { "modem",    NULL,     ShowModemStatus,	LOCAL_AUTH,
289	"Show modem setups", StrNull},
290  { "ofilter",  NULL,     ShowOfilter,		LOCAL_AUTH,
291	"Show Output filters", StrOption},
292  { "proto",    NULL,     ReportProtStatus,	LOCAL_AUTH,
293	"Show protocol summary", StrNull},
294  { "route",    NULL,     ShowRoute,		LOCAL_AUTH,
295	"Show routing table", StrNull},
296  { "timeout",  NULL,	  ShowTimeout,		LOCAL_AUTH,
297	"Show Idle timeout value", StrNull},
298  { "version",  NULL,	  ShowVersion,		LOCAL_NO_AUTH | LOCAL_AUTH,
299	"Show version string", StrNull},
300  { "help",     "?",      HelpCommand,		LOCAL_NO_AUTH | LOCAL_AUTH,
301	"Display this message", StrNull, (void *)ShowCommands},
302  { NULL,       NULL,     NULL },
303};
304
305struct cmdtab *
306FindCommand(cmds, str, pmatch)
307struct cmdtab *cmds;
308char *str;
309int *pmatch;
310{
311  int nmatch = 0;
312  int len = strlen(str);
313  struct cmdtab *found = NULL;
314
315  while (cmds->func) {
316    if (cmds->name && strncmp(str, cmds->name, len) == 0) {
317      nmatch++;
318      found = cmds;
319    } else if (cmds->alias && strncmp(str, cmds->alias, len) == 0) {
320      nmatch++;
321      found = cmds;
322    }
323    cmds++;
324  }
325  *pmatch = nmatch;
326  return(found);
327}
328
329int
330FindExec(cmdlist, argc, argv)
331struct cmdtab *cmdlist;
332int argc;
333char **argv;
334{
335  struct cmdtab *cmd;
336  int val = 1;
337  int nmatch;
338
339  cmd = FindCommand(cmdlist, *argv, &nmatch);
340  if (nmatch > 1)
341    printf("Ambiguous.\n");
342  else if (cmd && ( cmd->lauth & VarLocalAuth ) )
343    val = (cmd->func)(cmd, --argc, ++argv, cmd->args);
344  else
345    printf("what?\n");
346  return(val);
347}
348
349void
350Prompt(flag)
351int flag;
352{
353  char *pconnect, *pauth;
354
355  if (!(mode & MODE_INTER))
356    return;
357
358  if (flag) printf("\n");
359
360  if ( VarLocalAuth == LOCAL_AUTH )
361    pauth = " ON ";
362  else
363    pauth = " on ";
364  if (IpcpFsm.state == ST_OPENED && phase == PHASE_NETWORK)
365    pconnect = "PPP";
366  else
367    pconnect = "ppp";
368  printf("%s%s%s> ", pconnect, pauth, VarShortHost);
369  fflush(stdout);
370}
371
372void
373DecodeCommand(buff, nb, prompt)
374char *buff;
375int nb;
376int prompt;
377{
378  char *vector[20];
379  char **argv;
380  int argc, val;
381  char *cp;
382
383  val = 1;
384  if (nb > 0) {
385    cp = buff + strcspn(buff, "\r\n");
386    if (cp)
387      *cp = '\0';
388    {
389      argc = MakeArgs(buff, &vector);
390      argv = vector;
391
392      if (argc > 0)
393        val = FindExec(Commands, argc, argv);
394    }
395  }
396  if (val && prompt)
397    Prompt(0);
398}
399
400static int
401ShowCommand(list, argc, argv)
402struct cmdtab *list;
403int argc;
404char **argv;
405{
406  int val = 1;
407
408  if (argc > 0)
409    val = FindExec(ShowCommands, argc, argv);
410  else
411    printf("Use ``show ?'' to get a list.\n");
412  return(val);
413}
414
415static int
416TerminalCommand()
417{
418  if (LcpFsm.state > ST_CLOSED) {
419    printf("LCP state is [%s]\n", StateNames[LcpFsm.state]);
420    return(1);
421  }
422  if (!IsInteractive())
423    return(1);
424  modem = OpenModem(mode);
425  if (modem < 0) {
426    printf("failed to open modem.\n");
427    modem = 0;
428    return(1);
429  }
430  printf("Enter to terminal mode.\n");
431  printf("Type `~?' for help.\n");
432  TtyTermMode();
433  return(0);
434}
435
436static int
437QuitCommand(list, argc, argv)
438struct cmdtab *list;
439int argc;
440char **argv;
441{
442  if (mode & (MODE_DIRECT|MODE_DEDICATED|MODE_AUTO)) {
443    if (argc > 0 && (VarLocalAuth & LOCAL_AUTH)) {
444      Cleanup(EX_NORMAL);
445    } else {
446      VarLocalAuth = LOCAL_NO_AUTH;
447      close(netfd);
448      close(1);
449      dup2(2, 1);     /* Have to have something here or the modem will be 1 */
450      netfd = -1;
451      mode &= ~MODE_INTER;
452    }
453  } else
454    Cleanup(EX_NORMAL);
455  return(1);
456}
457
458static int
459CloseCommand()
460{
461  LcpClose();
462  return(1);
463}
464
465static int
466DownCommand()
467{
468  LcpDown();
469  return(1);
470}
471
472static int SetModemSpeed(list, argc, argv)
473struct cmdtab *list;
474int argc;
475char **argv;
476{
477  int speed;
478
479  if (argc > 0) {
480    if (strcmp(*argv, "sync") == 0) {
481      VarSpeed = 0;
482      return(1);
483    }
484    speed = atoi(*argv);
485    if (IntToSpeed(speed) != B0) {
486      VarSpeed = speed;
487      return(1);
488    }
489    printf("invalid speed.\n");
490  }
491  return(1);
492}
493
494static int SetModemParity(list, argc, argv)
495struct cmdtab *list;
496int argc;
497char **argv;
498{
499  int parity;
500
501  if (argc > 0) {
502    parity = ChangeParity(*argv);
503    if (parity < 0)
504      printf("Invalid parity.\n");
505    else
506      VarParity = parity;
507  }
508  return(1);
509}
510
511static int
512SetDebugLevel(list, argc, argv)
513struct cmdtab *list;
514int argc;
515char **argv;
516{
517  int level, w;
518
519  for (level = 0; argc-- > 0; argv++) {
520    if (isdigit(**argv)) {
521      w = atoi(*argv);
522      if (w < 0 || w >= MAXLOGLEVEL) {
523	printf("invalid log level.\n");
524	break;
525      } else
526	level |= (1 << w);
527    } else {
528      for (w = 0; w < MAXLOGLEVEL; w++) {
529	if (strcasecmp(*argv, LogLevelName[w]) == 0) {
530	  level |= (1 << w);
531	  continue;
532	}
533      }
534    }
535  }
536  loglevel = level;
537  return(1);
538}
539
540static int
541SetEscape(list, argc, argv)
542struct cmdtab *list;
543int argc;
544char **argv;
545{
546  int code;
547
548  for (code = 0; code < 33; code++)
549    EscMap[code] = 0;
550  while (argc-- > 0) {
551    sscanf(*argv++, "%x", &code);
552    code &= 0xff;
553    EscMap[code >> 3] |= (1 << (code&7));
554    EscMap[32] = 1;
555  }
556  return(1);
557}
558
559static int
560SetInitialMRU(list, argc, argv)
561struct cmdtab *list;
562int argc;
563char **argv;
564{
565  int mru;
566
567  if (argc > 0) {
568    mru = atoi(*argv);
569    if (mru < 100)
570      printf("given value is too small.\n");
571    else if (mru > MAX_MRU)
572      printf("given value is too big.\n");
573    else
574      VarMRU = mru;
575  }
576  return(1);
577}
578
579static int
580SetIdleTimeout(list, argc, argv)
581struct cmdtab *list;
582int argc;
583char **argv;
584{
585  if (argc-- > 0) {
586    VarIdleTimeout = atoi(*argv++);
587    if (argc-- > 0) {
588      VarLqrTimeout = atoi(*argv++);
589      if (VarLqrTimeout < 1)
590	VarLqrTimeout = 30;
591      if (argc > 0) {
592	VarRetryTimeout = atoi(*argv);
593	if (VarRetryTimeout < 1 || VarRetryTimeout > 10)
594	  VarRetryTimeout = 3;
595      }
596    }
597  }
598  return(1);
599}
600
601struct in_addr
602GetIpAddr(cp)
603char *cp;
604{
605  struct hostent *hp;
606  struct in_addr ipaddr;
607
608  hp = gethostbyname(cp);
609  if (hp && hp->h_addrtype == AF_INET)
610    bcopy(hp->h_addr, &ipaddr, hp->h_length);
611  else if (inet_aton(cp, &ipaddr) == 0)
612    ipaddr.s_addr = 0;
613  return(ipaddr);
614}
615
616static int
617SetInterfaceAddr(list, argc, argv)
618struct cmdtab *list;
619int argc;
620char **argv;
621{
622  int width;
623
624  DefMyAddress.ipaddr.s_addr = DefHisAddress.ipaddr.s_addr = 0L;
625  if (argc > 0) {
626    ParseAddr(argc, argv++,
627      &DefMyAddress.ipaddr, &DefMyAddress.mask, &DefMyAddress.width);
628    if (--argc > 0) {
629      ParseAddr(argc, argv++,
630	&DefHisAddress.ipaddr, &DefHisAddress.mask, &DefHisAddress.width);
631      if (--argc > 0) {
632        ifnetmask = GetIpAddr(*argv);
633    	if (--argc > 0) {
634      		ParseAddr(argc, argv++,
635		        &DefTriggerAddress.ipaddr,
636			&DefTriggerAddress.mask,
637			&DefTriggerAddress.width);
638	}
639      }
640    }
641  }
642  /*
643   * For backwards compatibility, 0.0.0.0 means any address.
644   */
645  if (DefMyAddress.ipaddr.s_addr == 0) {
646    DefMyAddress.mask.s_addr = 0;
647    DefMyAddress.width = 0;
648  }
649  if (DefHisAddress.ipaddr.s_addr == 0) {
650    DefHisAddress.mask.s_addr = 0;
651    DefHisAddress.width = 0;
652  }
653
654  if ((mode & MODE_AUTO) ||
655	((mode & MODE_DEDICATED) && dstsystem)) {
656    OsSetIpaddress(DefMyAddress.ipaddr, DefHisAddress.ipaddr, ifnetmask);
657  }
658  return(1);
659}
660
661
662#define	VAR_AUTHKEY	0
663#define	VAR_DIAL	1
664#define	VAR_LOGIN	2
665#define	VAR_AUTHNAME	3
666#define	VAR_DEVICE	4
667#define	VAR_ACCMAP	5
668#define	VAR_PHONE	6
669
670static int
671SetVariable(list, argc, argv, param)
672struct cmdtab *list;
673int argc;
674char **argv;
675int param;
676{
677  u_long map;
678
679  if (argc > 0) {
680    switch (param) {
681    case VAR_AUTHKEY:
682      strncpy(VarAuthKey, *argv, sizeof(VarAuthKey)-1);
683      break;
684    case VAR_AUTHNAME:
685      strncpy(VarAuthName, *argv, sizeof(VarAuthName)-1);
686      break;
687    case VAR_DIAL:
688      strncpy(VarDialScript, *argv, sizeof(VarDialScript)-1);
689      break;
690    case VAR_LOGIN:
691      strncpy(VarLoginScript, *argv, sizeof(VarDialScript)-1);
692      break;
693    case VAR_DEVICE:
694      strncpy(VarDevice, *argv, sizeof(VarDevice)-1);
695      break;
696    case VAR_ACCMAP:
697      sscanf(*argv, "%x", &map);
698      VarAccmap = map;
699      break;
700    case VAR_PHONE:
701      strncpy(VarPhone, *argv, sizeof(VarPhone)-1);
702      break;
703    }
704  }
705  return(1);
706}
707
708static int SetOpenMode(list, argc, argv)
709struct cmdtab *list;
710int argc;
711char **argv;
712{
713  if (argc > 0) {
714    if (strcmp(*argv, "active") == 0)
715      VarOpenMode = OPEN_ACTIVE;
716    else if (strcmp(*argv, "passive") == 0)
717      VarOpenMode = OPEN_PASSIVE;
718    else
719      printf("Invalid mode.\n");
720  }
721  return(1);
722}
723
724static char StrChatStr[] = "chat-script";
725static char StrValue[] = "value";
726
727extern int SetIfilter(), SetOfilter(), SetDfilter(), SetAfilter();
728
729struct cmdtab SetCommands[] = {
730  { "accmap",   NULL,	  SetVariable,		LOCAL_AUTH,
731	"Set accmap value", "hex-value", (void *)VAR_ACCMAP},
732  { "afilter",  NULL,     SetAfilter, 		LOCAL_AUTH,
733	"Set keep Alive filter", "..."},
734  { "authkey",  "key",     SetVariable,		LOCAL_AUTH,
735	"Set authentication key", "key", (void *)VAR_AUTHKEY},
736  { "authname", NULL,     SetVariable,		LOCAL_AUTH,
737	"Set authentication name", "name", (void *)VAR_AUTHNAME},
738  { "debug",    NULL,	  SetDebugLevel,	LOCAL_AUTH,
739	"Set debug level", StrValue},
740  { "device",     "line", SetVariable, 		LOCAL_AUTH,
741	"Set modem device name", "device-name",	(void *)VAR_DEVICE},
742  { "dfilter",  NULL,     SetDfilter,		 LOCAL_AUTH,
743	"Set demand filter", "..."},
744  { "dial",     NULL,     SetVariable, 		LOCAL_AUTH,
745	"Set dialing script", StrChatStr, (void *)VAR_DIAL},
746  { "escape",   NULL,	  SetEscape, 		LOCAL_AUTH,
747	"Set escape characters", "hex-digit ..."},
748  { "ifaddr",   NULL,   SetInterfaceAddr,	LOCAL_AUTH,
749	"Set destination address", "src-addr dst-addr netmask"},
750  { "ifilter",  NULL,     SetIfilter, 		LOCAL_AUTH,
751	"Set input filter", "..."},
752  { "login",    NULL,     SetVariable,		LOCAL_AUTH,
753	"Set login script", StrChatStr,	(void *)VAR_LOGIN },
754  { "mru",      "mtu",    SetInitialMRU,	LOCAL_AUTH,
755	"Set Initial MRU value", StrValue },
756  { "ofilter",  NULL,	  SetOfilter,		LOCAL_AUTH,
757	"Set output filter", "..." },
758  { "openmode", NULL,	  SetOpenMode,		LOCAL_AUTH,
759	"Set open mode", "[active|passive]"},
760  { "parity",   NULL,     SetModemParity,	LOCAL_AUTH,
761	"Set modem parity", "[odd|even|none]"},
762  { "phone",    NULL,     SetVariable,		LOCAL_AUTH,
763	"Set telephone number", "phone-number",	(void *)VAR_PHONE },
764  { "speed",    NULL,     SetModemSpeed,	LOCAL_AUTH,
765	"Set modem speed", "speed"},
766  { "timeout",  NULL,     SetIdleTimeout,	LOCAL_AUTH,
767	"Set Idle timeout", StrValue},
768  { "help",     "?",      HelpCommand,		LOCAL_AUTH | LOCAL_NO_AUTH,
769	"Display this message", StrNull, (void *)SetCommands},
770  { NULL,       NULL,     NULL },
771};
772
773static int
774SetCommand(list, argc, argv)
775struct cmdtab *list;
776int argc;
777char **argv;
778{
779  int val = 1;
780
781  if (argc > 0)
782    val = FindExec(SetCommands, argc, argv);
783  else
784    printf("Use ``set ?'' to get a list.\n");
785  return(val);
786}
787
788
789static int
790AddCommand(list, argc, argv)
791struct cmdtab *list;
792int argc;
793char **argv;
794{
795  struct in_addr dest, gateway, netmask;
796
797  if (argc == 3) {
798    dest = GetIpAddr(argv[0]);
799    netmask = GetIpAddr(argv[1]);
800    if (strcmp(argv[2], "HISADDR") == 0)
801      gateway = IpcpInfo.his_ipaddr;
802    else
803      gateway = GetIpAddr(argv[2]);
804    OsSetRoute(RTM_ADD, dest, gateway, netmask);
805  } else {
806    printf("Usage: %s %s\n", list->name, list->syntax);
807  }
808  return(1);
809}
810
811static int
812DeleteCommand(list, argc, argv)
813struct cmdtab *list;
814int argc;
815char **argv;
816{
817  struct in_addr dest, gateway, netmask;
818
819  if (argc >= 2) {
820    dest = GetIpAddr(argv[0]);
821    if (strcmp(argv[1], "HISADDR") == 0)
822      gateway = IpcpInfo.his_ipaddr;
823    else
824      gateway = GetIpAddr(argv[1]);
825    netmask.s_addr = 0;
826    if (argc == 3) {
827      if (inet_aton(argv[1], &netmask) == 0) {
828	printf("bad netmask value.\n");
829	return(1);
830      }
831    }
832    OsSetRoute(RTM_DELETE, dest, gateway, netmask);
833  } else if (argc == 1 && strcmp(argv[0], "ALL") == 0) {
834    DeleteIfRoutes(0);
835  } else {
836    printf("Usage: %s %s\n", list->name, list->syntax);
837  }
838  return(1);
839}
840
841