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