xref: /freebsd/usr.sbin/ppp/command.c (revision 953a3198a35204535cc9d450f04da982a4fea59b)
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 
41 extern int  MakeArgs();
42 extern void Cleanup(), TtyTermMode(), PacketMode();
43 extern int  EnableCommand(), DisableCommand(), DisplayCommand();
44 extern int  AcceptCommand(), DenyCommand();
45 extern int  LocalAuthCommand();
46 extern int  LoadCommand(), SaveCommand();
47 extern int  ChangeParity(char *);
48 extern int  SelectSystem();
49 extern int  ShowRoute();
50 extern void TtyOldMode(), TtyCommandMode();
51 extern struct pppvars pppVars;
52 
53 struct in_addr ifnetmask;
54 
55 static int ShowCommand(), TerminalCommand(), QuitCommand();
56 static int CloseCommand(), DialCommand(), DownCommand();
57 static int SetCommand(), AddCommand(), DeleteCommand();
58 static int ShellCommand();
59 
60 static int
61 HelpCommand(list, argc, argv, plist)
62 struct cmdtab *list;
63 int argc;
64 char **argv;
65 struct 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 
93 int
94 IsInteractive()
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 
111 static int
112 DialCommand(cmdlist, argc, argv)
113 struct cmdtab *cmdlist;
114 int argc;
115 char **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 
150 static int
151 ShellCommand(cmdlist, argc, argv)
152 struct cmdtab *cmdlist;
153 int argc;
154 char **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 
210 static char StrOption[] = "option ..";
211 static char StrRemote[] = "[remote]";
212 char StrNull[] = "";
213 
214 struct 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 
256 extern int ReportCcpStatus();
257 extern int ReportLcpStatus();
258 extern int ReportIpcpStatus();
259 extern int ReportProtStatus();
260 extern int ReportCompress();
261 extern int ShowModemStatus();
262 extern int ReportHdlcStatus();
263 extern int ShowMemMap();
264 
265 static char *LogLevelName[] = {
266   LM_PHASE, LM_CHAT, LM_LQM,   LM_LCP,
267   LM_TCPIP, LM_HDLC, LM_ASYNC,
268 };
269 
270 static 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 
283 static 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 
302 static 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 
309 static int ShowAuthKey()
310 {
311   printf("AuthName = %s\n", VarAuthName);
312   printf("AuthKey  = %s\n", VarAuthKey);
313   return(1);
314 }
315 
316 static int ShowVersion()
317 {
318   extern char *VarVersion[];
319   extern char *VarLocalVersion[];
320 
321   printf("%s - %s \n", VarVersion, VarLocalVersion);
322   return(1);
323 }
324 
325 static int ShowLogList()
326 {
327   ListLog();
328   return(1);
329 }
330 
331 static 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 
351 extern int ShowIfilter(), ShowOfilter(), ShowDfilter(), ShowAfilter();
352 
353 struct 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 
399 struct cmdtab *
400 FindCommand(cmds, str, pmatch)
401 struct cmdtab *cmds;
402 char *str;
403 int *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 
423 int
424 FindExec(cmdlist, argc, argv)
425 struct cmdtab *cmdlist;
426 int argc;
427 char **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 
443 void
444 Prompt(flag)
445 int 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 
466 void
467 DecodeCommand(buff, nb, prompt)
468 char *buff;
469 int nb;
470 int 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 
494 static int
495 ShowCommand(list, argc, argv)
496 struct cmdtab *list;
497 int argc;
498 char **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 
509 static int
510 TerminalCommand()
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 
530 static int
531 QuitCommand(list, argc, argv)
532 struct cmdtab *list;
533 int argc;
534 char **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 
552 static int
553 CloseCommand()
554 {
555   LcpClose();
556   return(1);
557 }
558 
559 static int
560 DownCommand()
561 {
562   LcpDown();
563   return(1);
564 }
565 
566 static int SetModemSpeed(list, argc, argv)
567 struct cmdtab *list;
568 int argc;
569 char **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 
588 static int SetRedialTimeout(list, argc, argv)
589 struct cmdtab *list;
590 int argc;
591 char **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 
631 static int SetModemParity(list, argc, argv)
632 struct cmdtab *list;
633 int argc;
634 char **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 
648 static int
649 SetDebugLevel(list, argc, argv)
650 struct cmdtab *list;
651 int argc;
652 char **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 
677 static int
678 SetEscape(list, argc, argv)
679 struct cmdtab *list;
680 int argc;
681 char **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 
696 static int
697 SetInitialMRU(list, argc, argv)
698 struct cmdtab *list;
699 int argc;
700 char **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 
716 static int
717 SetIdleTimeout(list, argc, argv)
718 struct cmdtab *list;
719 int argc;
720 char **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 
738 struct in_addr
739 GetIpAddr(cp)
740 char *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 
753 static int
754 SetInterfaceAddr(list, argc, argv)
755 struct cmdtab *list;
756 int argc;
757 char **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 
807 static int
808 SetVariable(list, argc, argv, param)
809 struct cmdtab *list;
810 int argc;
811 char **argv;
812 int 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 
845 static int SetOpenMode(list, argc, argv)
846 struct cmdtab *list;
847 int argc;
848 char **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 
861 static char StrChatStr[] = "chat-script";
862 static char StrValue[] = "value";
863 
864 extern int SetIfilter(), SetOfilter(), SetDfilter(), SetAfilter();
865 
866 struct 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 
912 static int
913 SetCommand(list, argc, argv)
914 struct cmdtab *list;
915 int argc;
916 char **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 
928 static int
929 AddCommand(list, argc, argv)
930 struct cmdtab *list;
931 int argc;
932 char **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 
950 static int
951 DeleteCommand(list, argc, argv)
952 struct cmdtab *list;
953 int argc;
954 char **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