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