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