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