Deleted Added
full compact
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.74 1997/08/21 17:07:30 brian Exp $
20 * $Id: command.c,v 1.75 1997/08/25 00:29:08 brian Exp $
21 *
22 */
23#include <sys/types.h>
24#include <sys/stat.h>
25#include <ctype.h>
26#include <termios.h>
27#include <sys/wait.h>
28#include <time.h>
29#include <netdb.h>
30#include <sys/socket.h>
31#include <netinet/in.h>
32#include <arpa/inet.h>
33#include <net/route.h>
34#include <paths.h>
35#include <alias.h>
36#include <fcntl.h>
37#include <errno.h>
38#include "fsm.h"
39#include "phase.h"
40#include "lcp.h"
41#include "ipcp.h"
42#include "modem.h"
43#include "filter.h"
44#include "command.h"
45#include "alias_cmd.h"
46#include "hdlc.h"
47#include "loadalias.h"
48#include "vars.h"
49#include "systems.h"
50#include "chat.h"
51#include "os.h"
52#include "timeout.h"
53#include "server.h"
54
55extern void Cleanup(), TtyTermMode(), PacketMode();
56extern int EnableCommand(), DisableCommand(), DisplayCommand();
57extern int AcceptCommand(), DenyCommand();
58static int AliasCommand();
59extern int LocalAuthCommand();
60extern int LoadCommand(), SaveCommand();
61extern int ChangeParity(char *);
62extern int SelectSystem();
63extern int ShowRoute();
64extern void TtyOldMode(), TtyCommandMode();
65extern struct pppvars pppVars;
66extern struct cmdtab const SetCommands[];
67
68extern char *IfDevName;
69
70struct in_addr ifnetmask;
71int randinit;
72
73static int ShowCommand(struct cmdtab const *, int, char **);
74static int TerminalCommand(struct cmdtab const *, int, char **);
75static int QuitCommand(struct cmdtab const *, int, char **);
76static int CloseCommand(struct cmdtab const *, int, char **);
77static int DialCommand(struct cmdtab const *, int, char **);
78static int DownCommand(struct cmdtab const *, int, char **);
79static int SetCommand(struct cmdtab const *, int, char **);
80static int AddCommand(struct cmdtab const *, int, char **);
81static int DeleteCommand(struct cmdtab const *, int, char **);
82static int BgShellCommand(struct cmdtab const *, int, char **);
83static int FgShellCommand(struct cmdtab const *, int, char **);
84static int ShellCommand(struct cmdtab const *, int, char **, int);
85
86static int
87HelpCommand(struct cmdtab const * list,
88 int argc,
89 char **argv,
90 struct cmdtab const * plist)
91{
92 struct cmdtab const *cmd;
93 int n;
94
95 if (!VarTerm)
96 return 0;
97
98 if (argc > 0) {
99 for (cmd = plist; cmd->name; cmd++)
100 if (strcasecmp(cmd->name, *argv) == 0 && (cmd->lauth & VarLocalAuth)) {
101 fprintf(VarTerm, "%s\n", cmd->syntax);
102 return 0;
103 }
104 return -1;
105 }
106 n = 0;
107 for (cmd = plist; cmd->func; cmd++)
108 if (cmd->name && (cmd->lauth & VarLocalAuth)) {
109 fprintf(VarTerm, " %-9s: %-20s\n", cmd->name, cmd->helpmes);
110 n++;
111 }
112 if (n & 1)
113 fprintf(VarTerm, "\n");
114
115 return 0;
116}
117
118int
119IsInteractive()
120{
121 char *mes = NULL;
122
123 if (mode & MODE_DDIAL)
124 mes = "Working in dedicated dial mode.";
125 else if (mode & MODE_BACKGROUND)
126 mes = "Working in background mode.";
127 else if (mode & MODE_AUTO)
128 mes = "Working in auto mode.";
129 else if (mode & MODE_DIRECT)
130 mes = "Working in direct mode.";
131 else if (mode & MODE_DEDICATED)
132 mes = "Working in dedicated mode.";
133 if (mes) {
134 if (VarTerm)
135 fprintf(VarTerm, "%s\n", mes);
136 return 0;
137 }
138 return 1;
139}
140
141static int
142DialCommand(struct cmdtab const * cmdlist, int argc, char **argv)
143{
144 int tries;
145 int res;
146
147 if (LcpFsm.state > ST_CLOSED) {
148 if (VarTerm)
149 fprintf(VarTerm, "LCP state is [%s]\n", StateNames[LcpFsm.state]);
150 return 0;
151 }
152 if (!IsInteractive())
153 return (1);
154
155 if (argc > 0) {
156 if (SelectSystem(*argv, CONFFILE) < 0) {
157 if (VarTerm)
158 fprintf(VarTerm, "%s: not found.\n", *argv);
159 return -1;
160 }
161 }
162 tries = 0;
163 do {
164 if (VarTerm)
165 fprintf(VarTerm, "Dial attempt %u of %d\n", ++tries, VarDialTries);
166 modem = OpenModem(mode);
167 if (modem < 0) {
168 if (VarTerm)
169 fprintf(VarTerm, "Failed to open modem.\n");
170 break;
171 }
172 if ((res = DialModem()) == EX_DONE) {
173 sleep(1);
174 ModemTimeout();
175 PacketMode();
176 break;
177 } else if (res == EX_SIG)
178 return 1;
179 } while (VarDialTries == 0 || tries < VarDialTries);
180
181 return 0;
182}
183
184static int
185SetLoopback(struct cmdtab const * cmdlist, int argc, char **argv)
186{
187 if (argc == 1)
188 if (!strcasecmp(*argv, "on"))
189 VarLoopback = 1;
190 else if (!strcasecmp(*argv, "off"))
191 VarLoopback = 0;
192 return -1;
193}
194
195static int
196BgShellCommand(struct cmdtab const * cmdlist, int argc, char **argv)
197{
198 if (argc == 0)
199 return -1;
200 return ShellCommand(cmdlist, argc, argv, 1);
201}
202
203static int
204FgShellCommand(struct cmdtab const * cmdlist, int argc, char **argv)
205{
206 return ShellCommand(cmdlist, argc, argv, 0);
207}
208
209static int
210ShellCommand(struct cmdtab const * cmdlist, int argc, char **argv, int bg)
211{
212 const char *shell;
213 pid_t shpid;
214 FILE *oVarTerm;
215
216#ifdef SHELL_ONLY_INTERACTIVELY
217 /* we're only allowed to shell when we run ppp interactively */
218 if (mode != MODE_INTER) {
219 LogPrintf(LogWARN, "Can only start a shell in interactive mode\n");
220 return 1;
221 }
222#endif
223#ifdef NO_SHELL_IN_AUTO_INTERACTIVE
224
225 /*
226 * we want to stop shell commands when we've got a telnet connection to an
227 * auto mode ppp
228 */
229 if ((mode & (MODE_AUTO | MODE_INTER)) == (MODE_AUTO | MODE_INTER)) {
230 LogPrintf(LogWARN, "Shell is not allowed interactively in auto mode\n");
231 return 1;
232 }
233#endif
234
235 if (argc == 0)
236 if (!(mode & MODE_INTER)) {
237 LogPrintf(LogWARN, "Can only start an interactive shell in"
238 " interactive mode\n");
239 return 1;
240 } else if (bg) {
241 LogPrintf(LogWARN, "Can only start an interactive shell in"
242 " the foreground mode\n");
243 return 1;
244 }
245 if ((shell = getenv("SHELL")) == 0)
246 shell = _PATH_BSHELL;
247
248 if ((shpid = fork()) == 0) {
249 int dtablesize, i, fd;
250
251 if (VarTerm)
252 fd = fileno(VarTerm);
253 else if ((fd = open("/dev/null", O_RDWR)) == -1) {
254 LogPrintf(LogALERT, "Failed to open /dev/null: %s\n", strerror(errno));
255 exit(1);
256 }
257 for (i = 0; i < 3; i++)
258 dup2(fd, i);
259
260 if (fd > 2)
261 if (VarTerm) {
262 oVarTerm = VarTerm;
263 VarTerm = 0;
264 if (oVarTerm && oVarTerm != stdout)
265 fclose(oVarTerm);
266 } else
267 close(fd);
268
269 for (dtablesize = getdtablesize(), i = 3; i < dtablesize; i++)
270 (void) close(i);
271
272 /*
273 * We are running setuid, we should change to real user for avoiding
274 * security problems.
275 */
276 if (setgid(getgid()) < 0) {
277 LogPrintf(LogERROR, "setgid: %s\n", strerror(errno));
278 exit(1);
279 }
280 if (setuid(getuid()) < 0) {
281 LogPrintf(LogERROR, "setuid: %s\n", strerror(errno));
282 exit(1);
283 }
284 TtyOldMode();
285 if (argc > 0) {
286 /* substitute pseudo args */
287 for (i = 1; i < argc; i++)
288 if (strcasecmp(argv[i], "HISADDR") == 0)
289 argv[i] = strdup(inet_ntoa(IpcpInfo.his_ipaddr));
290 else if (strcasecmp(argv[i], "INTERFACE") == 0)
291 argv[i] = strdup(IfDevName);
292 else if (strcasecmp(argv[i], "MYADDR") == 0)
293 argv[i] = strdup(inet_ntoa(IpcpInfo.want_ipaddr));
294 if (bg) {
295 pid_t p;
296
297 p = getpid();
298 if (daemon(1, 1) == -1) {
299 LogPrintf(LogERROR, "%d: daemon: %s", p, strerror(errno));
299 LogPrintf(LogERROR, "%d: daemon: %s\n", p, strerror(errno));
300 exit(1);
301 }
302 }
303 (void) execvp(argv[0], argv);
304 } else
305 (void) execl(shell, shell, NULL);
306
307 LogPrintf(LogWARN, "exec() of %s failed\n", argc > 0 ? argv[0] : shell);
308 exit(255);
309 }
310 if (shpid == (pid_t) - 1) {
311 LogPrintf(LogERROR, "Fork failed: %s\n", strerror(errno));
312 } else {
313 int status;
314
315 (void) waitpid(shpid, &status, 0);
316 }
317
318 TtyCommandMode(1);
319
320 return (0);
321}
322
323struct cmdtab const Commands[] = {
324 {"accept", NULL, AcceptCommand, LOCAL_AUTH,
325 "accept option request", "accept option .."},
326 {"add", NULL, AddCommand, LOCAL_AUTH,
327 "add route", "add dest mask gateway"},
328 {"bg", "!bg", BgShellCommand, LOCAL_AUTH,
329 "Run a command in the background", "[!]bg command"},
330 {"close", NULL, CloseCommand, LOCAL_AUTH,
331 "Close connection", "close"},
332 {"delete", NULL, DeleteCommand, LOCAL_AUTH,
333 "delete route", "delete ALL | dest [gateway [mask]]"},
334 {"deny", NULL, DenyCommand, LOCAL_AUTH,
335 "Deny option request", "deny option .."},
336 {"dial", "call", DialCommand, LOCAL_AUTH,
337 "Dial and login", "dial|call [remote]"},
338 {"disable", NULL, DisableCommand, LOCAL_AUTH,
339 "Disable option", "disable option .."},
340 {"display", NULL, DisplayCommand, LOCAL_AUTH,
341 "Display option configs", "display"},
342 {"enable", NULL, EnableCommand, LOCAL_AUTH,
343 "Enable option", "enable option .."},
344 {"passwd", NULL, LocalAuthCommand, LOCAL_NO_AUTH,
345 "Password for manipulation", "passwd option .."},
346 {"load", NULL, LoadCommand, LOCAL_AUTH,
347 "Load settings", "load [remote]"},
348 {"save", NULL, SaveCommand, LOCAL_AUTH,
349 "Save settings", "save"},
350 {"set", "setup", SetCommand, LOCAL_AUTH,
351 "Set parameters", "set[up] var value"},
352 {"shell", "!", FgShellCommand, LOCAL_AUTH,
353 "Run a subshell", "shell|! [sh command]"},
354 {"show", NULL, ShowCommand, LOCAL_AUTH,
355 "Show status and statictics", "show var"},
356 {"term", NULL, TerminalCommand, LOCAL_AUTH,
357 "Enter to terminal mode", "term"},
358 {"alias", NULL, AliasCommand, LOCAL_AUTH,
359 "alias control", "alias option [yes|no]"},
360 {"quit", "bye", QuitCommand, LOCAL_AUTH | LOCAL_NO_AUTH,
361 "Quit PPP program", "quit|bye [all]"},
362 {"help", "?", HelpCommand, LOCAL_AUTH | LOCAL_NO_AUTH,
363 "Display this message", "help|? [command]", (void *) Commands},
364 {NULL, "down", DownCommand, LOCAL_AUTH,
365 "Generate down event", "down"},
366 {NULL, NULL, NULL},
367};
368
369extern int ReportCcpStatus();
370extern int ReportLcpStatus();
371extern int ReportIpcpStatus();
372extern int ReportProtStatus();
373extern int ReportCompress();
374extern int ShowModemStatus();
375extern int ReportHdlcStatus();
376extern int ShowMemMap();
377
378static int
379ShowLoopback()
380{
381 if (VarTerm)
382 fprintf(VarTerm, "Local loopback is %s\n", VarLoopback ? "on" : "off");
383
384 return 0;
385}
386
387static int
388ShowLogLevel()
389{
390 int i;
391
392 if (!VarTerm)
393 return 0;
394 fprintf(VarTerm, "Log:");
395 for (i = LogMIN; i < LogMAXCONF; i++) {
396 if (LogIsKept(i))
397 fprintf(VarTerm, " %s", LogName(i));
398 }
399 fprintf(VarTerm, "\n");
400
401 return 0;
402}
403
404static int
405ShowEscape()
406{
407 int code, bit;
408
409 if (!VarTerm)
410 return 0;
411 if (EscMap[32]) {
412 for (code = 0; code < 32; code++)
413 if (EscMap[code])
414 for (bit = 0; bit < 8; bit++)
415 if (EscMap[code] & (1 << bit))
416 fprintf(VarTerm, " 0x%02x", (code << 3) + bit);
417 fprintf(VarTerm, "\n");
418 }
419 return 1;
420}
421
422static int
423ShowTimeout()
424{
425 if (!VarTerm)
426 return 0;
427 fprintf(VarTerm, " Idle Timer: %d secs LQR Timer: %d secs"
428 " Retry Timer: %d secs\n", VarIdleTimeout, VarLqrTimeout,
429 VarRetryTimeout);
430 return 1;
431}
432
433static int
434ShowStopped()
435{
436 if (!VarTerm)
437 return 0;
438
439 fprintf(VarTerm, " Stopped Timer: LCP: ");
440 if (!LcpFsm.StoppedTimer.load)
441 fprintf(VarTerm, "Disabled");
442 else
443 fprintf(VarTerm, "%ld secs", LcpFsm.StoppedTimer.load / SECTICKS);
444
445 fprintf(VarTerm, ", IPCP: ");
446 if (!IpcpFsm.StoppedTimer.load)
447 fprintf(VarTerm, "Disabled");
448 else
449 fprintf(VarTerm, "%ld secs", IpcpFsm.StoppedTimer.load / SECTICKS);
450
451 fprintf(VarTerm, ", CCP: ");
452 if (!CcpFsm.StoppedTimer.load)
453 fprintf(VarTerm, "Disabled");
454 else
455 fprintf(VarTerm, "%ld secs", CcpFsm.StoppedTimer.load / SECTICKS);
456
457 fprintf(VarTerm, "\n");
458
459 return 1;
460}
461
462static int
463ShowAuthKey()
464{
465 if (!VarTerm)
466 return 0;
467 fprintf(VarTerm, "AuthName = %s\n", VarAuthName);
468 fprintf(VarTerm, "AuthKey = %s\n", VarAuthKey);
469 return 1;
470}
471
472static int
473ShowVersion()
474{
475 extern char VarVersion[];
476 extern char VarLocalVersion[];
477
478 if (!VarTerm)
479 return 0;
480 fprintf(VarTerm, "%s - %s \n", VarVersion, VarLocalVersion);
481 return 1;
482}
483
484static int
485ShowInitialMRU()
486{
487 if (!VarTerm)
488 return 0;
489 fprintf(VarTerm, " Initial MRU: %ld\n", VarMRU);
490 return 1;
491}
492
493static int
494ShowPreferredMTU()
495{
496 if (!VarTerm)
497 return 0;
498 if (VarPrefMTU)
499 fprintf(VarTerm, " Preferred MTU: %ld\n", VarPrefMTU);
500 else
501 fprintf(VarTerm, " Preferred MTU: unspecified\n");
502 return 1;
503}
504
505static int
506ShowReconnect()
507{
508 if (!VarTerm)
509 return 0;
510 fprintf(VarTerm, " Reconnect Timer: %d, %d tries\n",
511 VarReconnectTimer, VarReconnectTries);
512 return 1;
513}
514
515static int
516ShowRedial()
517{
518 if (!VarTerm)
519 return 0;
520 fprintf(VarTerm, " Redial Timer: ");
521
522 if (VarRedialTimeout >= 0) {
523 fprintf(VarTerm, " %d seconds, ", VarRedialTimeout);
524 } else {
525 fprintf(VarTerm, " Random 0 - %d seconds, ", REDIAL_PERIOD);
526 }
527
528 fprintf(VarTerm, " Redial Next Timer: ");
529
530 if (VarRedialNextTimeout >= 0) {
531 fprintf(VarTerm, " %d seconds, ", VarRedialNextTimeout);
532 } else {
533 fprintf(VarTerm, " Random 0 - %d seconds, ", REDIAL_PERIOD);
534 }
535
536 if (VarDialTries)
537 fprintf(VarTerm, "%d dial tries", VarDialTries);
538
539 fprintf(VarTerm, "\n");
540
541 return 1;
542}
543
544#ifndef NOMSEXT
545static int
546ShowMSExt()
547{
548 if (!VarTerm)
549 return 0;
550 fprintf(VarTerm, " MS PPP extention values \n");
551 fprintf(VarTerm, " Primary NS : %s\n", inet_ntoa(ns_entries[0]));
552 fprintf(VarTerm, " Secondary NS : %s\n", inet_ntoa(ns_entries[1]));
553 fprintf(VarTerm, " Primary NBNS : %s\n", inet_ntoa(nbns_entries[0]));
554 fprintf(VarTerm, " Secondary NBNS : %s\n", inet_ntoa(nbns_entries[1]));
555 return 1;
556}
557
558#endif
559
560extern int ShowIfilter(), ShowOfilter(), ShowDfilter(), ShowAfilter();
561
562struct cmdtab const ShowCommands[] = {
563 {"afilter", NULL, ShowAfilter, LOCAL_AUTH,
564 "Show keep Alive filters", "show afilter option .."},
565 {"auth", NULL, ShowAuthKey, LOCAL_AUTH,
566 "Show auth name/key", "show auth"},
567 {"ccp", NULL, ReportCcpStatus, LOCAL_AUTH,
568 "Show CCP status", "show cpp"},
569 {"compress", NULL, ReportCompress, LOCAL_AUTH,
570 "Show compression statictics", "show compress"},
571 {"dfilter", NULL, ShowDfilter, LOCAL_AUTH,
572 "Show Demand filters", "show dfilteroption .."},
573 {"escape", NULL, ShowEscape, LOCAL_AUTH,
574 "Show escape characters", "show escape"},
575 {"hdlc", NULL, ReportHdlcStatus, LOCAL_AUTH,
576 "Show HDLC error summary", "show hdlc"},
577 {"ifilter", NULL, ShowIfilter, LOCAL_AUTH,
578 "Show Input filters", "show ifilter option .."},
579 {"ipcp", NULL, ReportIpcpStatus, LOCAL_AUTH,
580 "Show IPCP status", "show ipcp"},
581 {"lcp", NULL, ReportLcpStatus, LOCAL_AUTH,
582 "Show LCP status", "show lcp"},
583 {"loopback", NULL, ShowLoopback, LOCAL_AUTH,
584 "Show current loopback setting", "show loopback"},
585 {"log", NULL, ShowLogLevel, LOCAL_AUTH,
586 "Show current log level", "show log"},
587 {"mem", NULL, ShowMemMap, LOCAL_AUTH,
588 "Show memory map", "show mem"},
589 {"modem", NULL, ShowModemStatus, LOCAL_AUTH,
590 "Show modem setups", "show modem"},
591 {"mru", NULL, ShowInitialMRU, LOCAL_AUTH,
592 "Show Initial MRU", "show mru"},
593 {"mtu", NULL, ShowPreferredMTU, LOCAL_AUTH,
594 "Show Preferred MTU", "show mtu"},
595 {"ofilter", NULL, ShowOfilter, LOCAL_AUTH,
596 "Show Output filters", "show ofilter option .."},
597 {"proto", NULL, ReportProtStatus, LOCAL_AUTH,
598 "Show protocol summary", "show proto"},
599 {"reconnect", NULL, ShowReconnect, LOCAL_AUTH,
600 "Show Reconnect timer,tries", "show reconnect"},
601 {"redial", NULL, ShowRedial, LOCAL_AUTH,
602 "Show Redial timeout value", "show redial"},
603 {"route", NULL, ShowRoute, LOCAL_AUTH,
604 "Show routing table", "show route"},
605 {"timeout", NULL, ShowTimeout, LOCAL_AUTH,
606 "Show Idle timeout value", "show timeout"},
607 {"stopped", NULL, ShowStopped, LOCAL_AUTH,
608 "Show STOPPED timeout value", "show stopped"},
609#ifndef NOMSEXT
610 {"msext", NULL, ShowMSExt, LOCAL_AUTH,
611 "Show MS PPP extentions", "show msext"},
612#endif
613 {"version", NULL, ShowVersion, LOCAL_NO_AUTH | LOCAL_AUTH,
614 "Show version string", "show version"},
615 {"help", "?", HelpCommand, LOCAL_NO_AUTH | LOCAL_AUTH,
616 "Display this message", "show help|? [command]", (void *) ShowCommands},
617 {NULL, NULL, NULL},
618};
619
620struct cmdtab const *
621FindCommand(struct cmdtab const * cmds, char *str, int *pmatch)
622{
623 int nmatch;
624 int len;
625 struct cmdtab const *found;
626
627 found = NULL;
628 len = strlen(str);
629 nmatch = 0;
630 while (cmds->func) {
631 if (cmds->name && strncasecmp(str, cmds->name, len) == 0) {
632 if (cmds->name[len] == '\0') {
633 *pmatch = 1;
634 return cmds;
635 }
636 nmatch++;
637 found = cmds;
638 } else if (cmds->alias && strncasecmp(str, cmds->alias, len) == 0) {
639 if (cmds->alias[len] == '\0') {
640 *pmatch = 1;
641 return cmds;
642 }
643 nmatch++;
644 found = cmds;
645 }
646 cmds++;
647 }
648 *pmatch = nmatch;
649 return found;
650}
651
652int
653FindExec(struct cmdtab const * cmdlist, int argc, char **argv)
654{
655 struct cmdtab const *cmd;
656 int val = 1;
657 int nmatch;
658
659 cmd = FindCommand(cmdlist, *argv, &nmatch);
660 if (nmatch > 1)
661 LogPrintf(LogWARN, "%s: Ambiguous command\n", *argv);
662 else if (cmd && (cmd->lauth & VarLocalAuth))
663 val = (cmd->func) (cmd, --argc, ++argv, cmd->args);
664 else
665 LogPrintf(LogWARN, "%s: Invalid command\n", *argv);
666
667 if (val == -1)
668 LogPrintf(LogWARN, "Usage: %s\n", cmd->syntax);
669 else if (val)
670 LogPrintf(LogCOMMAND, "%s: Failed %d\n", *argv, val);
671
672 return val;
673}
674
675int aft_cmd = 1;
676extern int TermMode;
677
678void
679Prompt()
680{
681 char *pconnect, *pauth;
682
683 if (!(mode & MODE_INTER) || !VarTerm || TermMode)
684 return;
685
686 if (!aft_cmd)
687 fprintf(VarTerm, "\n");
688 else
689 aft_cmd = 0;
690
691 if (VarLocalAuth == LOCAL_AUTH)
692 pauth = " ON ";
693 else
694 pauth = " on ";
695 if (IpcpFsm.state == ST_OPENED && phase == PHASE_NETWORK)
696 pconnect = "PPP";
697 else
698 pconnect = "ppp";
699 fprintf(VarTerm, "%s%s%s> ", pconnect, pauth, VarShortHost);
700 fflush(VarTerm);
701}
702
703void
704DecodeCommand(char *buff, int nb, int prompt)
705{
706 char *vector[20];
707 char **argv;
708 int argc;
709 char *cp;
710
711 if (nb > 0) {
712 cp = buff + strcspn(buff, "\r\n");
713 if (cp)
714 *cp = '\0';
715 argc = MakeArgs(buff, vector, VECSIZE(vector));
716 argv = vector;
717
718 if (argc > 0)
719 FindExec(Commands, argc, argv);
720 }
721 if (prompt)
722 Prompt();
723}
724
725static int
726ShowCommand(struct cmdtab const * list, int argc, char **argv)
727{
728 if (argc > 0)
729 FindExec(ShowCommands, argc, argv);
730 else if (VarTerm)
731 fprintf(VarTerm, "Use ``show ?'' to get a list.\n");
732 else
733 LogPrintf(LogWARN, "show command must have arguments\n");
734
735 return 0;
736}
737
738static int
739TerminalCommand(struct cmdtab const * list, int argc, char **argv)
740{
741 if (LcpFsm.state > ST_CLOSED) {
742 if (VarTerm)
743 fprintf(VarTerm, "LCP state is [%s]\n", StateNames[LcpFsm.state]);
744 return 1;
745 }
746 if (!IsInteractive())
747 return (1);
748 modem = OpenModem(mode);
749 if (modem < 0) {
750 if (VarTerm)
751 fprintf(VarTerm, "Failed to open modem.\n");
752 return (1);
753 }
754 if (VarTerm) {
755 fprintf(VarTerm, "Enter to terminal mode.\n");
756 fprintf(VarTerm, "Type `~?' for help.\n");
757 }
758 TtyTermMode();
759 return (0);
760}
761
762static int
763QuitCommand(struct cmdtab const * list, int argc, char **argv)
764{
765 FILE *oVarTerm;
766
767 if (mode & (MODE_DIRECT | MODE_DEDICATED | MODE_AUTO)) {
768 if (argc > 0 && (VarLocalAuth & LOCAL_AUTH)) {
769 Cleanup(EX_NORMAL);
770 mode &= ~MODE_INTER;
771 oVarTerm = VarTerm;
772 VarTerm = 0;
773 if (oVarTerm && oVarTerm != stdout)
774 fclose(oVarTerm);
775 } else {
776 LogPrintf(LogPHASE, "Client connection closed.\n");
777 VarLocalAuth = LOCAL_NO_AUTH;
778 mode &= ~MODE_INTER;
779 oVarTerm = VarTerm;
780 VarTerm = 0;
781 if (oVarTerm && oVarTerm != stdout)
782 fclose(oVarTerm);
783 close(netfd);
784 netfd = -1;
785 }
786 } else
787 Cleanup(EX_NORMAL);
788
789 return 0;
790}
791
792static int
793CloseCommand(struct cmdtab const * list, int argc, char **argv)
794{
795 reconnect(RECON_FALSE);
796 LcpClose();
797 if (mode & MODE_BACKGROUND)
798 Cleanup(EX_NORMAL);
799 return 0;
800}
801
802static int
803DownCommand(struct cmdtab const * list, int argc, char **argv)
804{
805 LcpDown();
806 return 0;
807}
808
809static int
810SetModemSpeed(struct cmdtab const * list, int argc, char **argv)
811{
812 int speed;
813
814 if (argc > 0) {
815 if (strcmp(*argv, "sync") == 0) {
816 VarSpeed = 0;
817 return 0;
818 }
819 speed = atoi(*argv);
820 if (IntToSpeed(speed) != B0) {
821 VarSpeed = speed;
822 return 0;
823 }
824 LogPrintf(LogWARN, "%s: Invalid speed\n", *argv);
825 }
826 return -1;
827}
828
829static int
830SetReconnect(struct cmdtab const * list, int argc, char **argv)
831{
832 if (argc == 2) {
833 VarReconnectTimer = atoi(argv[0]);
834 VarReconnectTries = atoi(argv[1]);
835 return 0;
836 }
837 return -1;
838}
839
840static int
841SetRedialTimeout(struct cmdtab const * list, int argc, char **argv)
842{
843 int timeout;
844 int tries;
845 char *dot;
846
847 if (argc == 1 || argc == 2) {
848 if (strncasecmp(argv[0], "random", 6) == 0 &&
849 (argv[0][6] == '\0' || argv[0][6] == '.')) {
850 VarRedialTimeout = -1;
851 if (!randinit) {
852 randinit = 1;
853 srandomdev();
854 }
855 } else {
856 timeout = atoi(argv[0]);
857
858 if (timeout >= 0)
859 VarRedialTimeout = timeout;
860 else {
861 LogPrintf(LogWARN, "Invalid redial timeout\n");
862 return -1;
863 }
864 }
865
866 dot = index(argv[0], '.');
867 if (dot) {
868 if (strcasecmp(++dot, "random") == 0) {
869 VarRedialNextTimeout = -1;
870 if (!randinit) {
871 randinit = 1;
872 srandomdev();
873 }
874 } else {
875 timeout = atoi(dot);
876 if (timeout >= 0)
877 VarRedialNextTimeout = timeout;
878 else {
879 LogPrintf(LogWARN, "Invalid next redial timeout\n");
880 return -1;
881 }
882 }
883 } else
884 VarRedialNextTimeout = NEXT_REDIAL_PERIOD; /* Default next timeout */
885
886 if (argc == 2) {
887 tries = atoi(argv[1]);
888
889 if (tries >= 0) {
890 VarDialTries = tries;
891 } else {
892 LogPrintf(LogWARN, "Invalid retry value\n");
893 return 1;
894 }
895 }
896 return 0;
897 }
898 return -1;
899}
900
901static int
902SetStoppedTimeout(struct cmdtab const * list, int argc, char **argv)
903{
904 LcpFsm.StoppedTimer.load = 0;
905 IpcpFsm.StoppedTimer.load = 0;
906 CcpFsm.StoppedTimer.load = 0;
907 if (argc <= 3) {
908 if (argc > 0) {
909 LcpFsm.StoppedTimer.load = atoi(argv[0]) * SECTICKS;
910 if (argc > 1) {
911 IpcpFsm.StoppedTimer.load = atoi(argv[1]) * SECTICKS;
912 if (argc > 2)
913 CcpFsm.StoppedTimer.load = atoi(argv[2]) * SECTICKS;
914 }
915 }
916 return 0;
917 }
918 return -1;
919}
920
921static int
922SetServer(struct cmdtab const * list, int argc, char **argv)
923{
924 int res = -1;
925
926 if (argc > 0 && argc < 3)
927 if (strcasecmp(argv[0], "none") == 0) {
928 ServerClose();
929 LogPrintf(LogPHASE, "Disabling server port.\n");
930 res = 0;
931 } else if (*argv[0] == '/') {
932 mode_t mask;
933
934 umask(mask = umask(0));
935 if (argc == 2) {
936 unsigned m;
937
938 if (sscanf(argv[1], "%o", &m) == 1)
939 mask = m;
940 }
941 res = ServerLocalOpen(argv[0], mask);
942 } else {
943 int port;
944
945 if (strspn(argv[0], "0123456789") != strlen(argv[0])) {
946 struct servent *s;
947
948 if ((s = getservbyname(argv[0], "tcp")) == NULL) {
949 port = 0;
950 LogPrintf(LogWARN, "%s: Invalid port or service\n", argv[0]);
951 } else
952 port = ntohs(s->s_port);
953 } else
954 port = atoi(argv[0]);
955 if (port)
956 res = ServerTcpOpen(port);
957 }
958
959 return res;
960}
961
962static int
963SetModemParity(struct cmdtab const * list, int argc, char **argv)
964{
965 return argc > 0 ? ChangeParity(*argv) : -1;
966}
967
968static int
969SetLogLevel(struct cmdtab const * list, int argc, char **argv)
970{
971 int i;
972 int res;
973 char *arg;
974
975 res = 0;
976 if (argc == 0 || (argv[0][0] != '+' && argv[0][0] != '-'))
977 LogDiscardAll();
978 while (argc--) {
979 arg = **argv == '+' || **argv == '-' ? *argv + 1 : *argv;
980 for (i = LogMIN; i <= LogMAX; i++)
981 if (strcasecmp(arg, LogName(i)) == 0) {
982 if (**argv == '-')
983 LogDiscard(i);
984 else
985 LogKeep(i);
986 break;
987 }
988 if (i > LogMAX) {
989 LogPrintf(LogWARN, "%s: Invalid log value\n", arg);
990 res = -1;
991 }
992 argv++;
993 }
994 return res;
995}
996
997static int
998SetEscape(struct cmdtab const * list, int argc, char **argv)
999{
1000 int code;
1001
1002 for (code = 0; code < 33; code++)
1003 EscMap[code] = 0;
1004 while (argc-- > 0) {
1005 sscanf(*argv++, "%x", &code);
1006 code &= 0xff;
1007 EscMap[code >> 3] |= (1 << (code & 7));
1008 EscMap[32] = 1;
1009 }
1010 return 0;
1011}
1012
1013static int
1014SetInitialMRU(struct cmdtab const * list, int argc, char **argv)
1015{
1016 long mru;
1017 char *err;
1018
1019 if (argc > 0) {
1020 mru = atol(*argv);
1021 if (mru < MIN_MRU)
1022 err = "Given MRU value (%ld) is too small.\n";
1023 else if (mru > MAX_MRU)
1024 err = "Given MRU value (%ld) is too big.\n";
1025 else {
1026 VarMRU = mru;
1027 return 0;
1028 }
1029 LogPrintf(LogWARN, err, mru);
1030 }
1031 return -1;
1032}
1033
1034static int
1035SetPreferredMTU(struct cmdtab const * list, int argc, char **argv)
1036{
1037 long mtu;
1038 char *err;
1039
1040 if (argc > 0) {
1041 mtu = atol(*argv);
1042 if (mtu == 0) {
1043 VarPrefMTU = 0;
1044 return 0;
1045 } else if (mtu < MIN_MTU)
1046 err = "Given MTU value (%ld) is too small.\n";
1047 else if (mtu > MAX_MTU)
1048 err = "Given MTU value (%ld) is too big.\n";
1049 else {
1050 VarPrefMTU = mtu;
1051 return 0;
1052 }
1053 LogPrintf(LogWARN, err, mtu);
1054 }
1055 return -1;
1056}
1057
1058static int
1059SetIdleTimeout(struct cmdtab const * list, int argc, char **argv)
1060{
1061 if (argc-- > 0) {
1062 VarIdleTimeout = atoi(*argv++);
1063 UpdateIdleTimer(); /* If we're connected, restart the idle timer */
1064 if (argc-- > 0) {
1065 VarLqrTimeout = atoi(*argv++);
1066 if (VarLqrTimeout < 1)
1067 VarLqrTimeout = 30;
1068 if (argc > 0) {
1069 VarRetryTimeout = atoi(*argv);
1070 if (VarRetryTimeout < 1 || VarRetryTimeout > 10)
1071 VarRetryTimeout = 3;
1072 }
1073 }
1074 return 0;
1075 }
1076 return -1;
1077}
1078
1079struct in_addr
1080GetIpAddr(char *cp)
1081{
1082 struct hostent *hp;
1083 struct in_addr ipaddr;
1084
1085 hp = gethostbyname(cp);
1086 if (hp && hp->h_addrtype == AF_INET)
1087 bcopy(hp->h_addr, &ipaddr, hp->h_length);
1088 else if (inet_aton(cp, &ipaddr) == 0)
1089 ipaddr.s_addr = 0;
1090 return (ipaddr);
1091}
1092
1093static int
1094SetInterfaceAddr(struct cmdtab const * list, int argc, char **argv)
1095{
1096 DefMyAddress.ipaddr.s_addr = DefHisAddress.ipaddr.s_addr = 0L;
1097
1098 if (argc > 4)
1099 return -1;
1100
1101 HaveTriggerAddress = 0;
1102 ifnetmask.s_addr = 0;
1103
1104 if (argc > 0) {
1105 if (ParseAddr(argc, argv++,
1106 &DefMyAddress.ipaddr,
1107 &DefMyAddress.mask,
1108 &DefMyAddress.width) == 0)
1109 return 1;
1110 if (--argc > 0) {
1111 if (ParseAddr(argc, argv++,
1112 &DefHisAddress.ipaddr,
1113 &DefHisAddress.mask,
1114 &DefHisAddress.width) == 0)
1115 return 2;
1116 if (--argc > 0) {
1117 ifnetmask = GetIpAddr(*argv);
1118 if (--argc > 0) {
1119 TriggerAddress = GetIpAddr(*argv);
1120 HaveTriggerAddress = 1;
1121 }
1122 }
1123 }
1124 }
1125
1126 /*
1127 * For backwards compatibility, 0.0.0.0 means any address.
1128 */
1129 if (DefMyAddress.ipaddr.s_addr == 0) {
1130 DefMyAddress.mask.s_addr = 0;
1131 DefMyAddress.width = 0;
1132 }
1133 if (DefHisAddress.ipaddr.s_addr == 0) {
1134 DefHisAddress.mask.s_addr = 0;
1135 DefHisAddress.width = 0;
1136 }
1137 IpcpInfo.want_ipaddr.s_addr = DefMyAddress.ipaddr.s_addr;
1138 IpcpInfo.his_ipaddr.s_addr = DefHisAddress.ipaddr.s_addr;
1139
1140 if ((mode & MODE_AUTO) ||
1141 ((mode & MODE_DEDICATED) && dstsystem)) {
1142 if (OsSetIpaddress(DefMyAddress.ipaddr, DefHisAddress.ipaddr, ifnetmask) < 0)
1143 return 4;
1144 }
1145 return 0;
1146}
1147
1148#ifndef NOMSEXT
1149
1150void
1151SetMSEXT(struct in_addr * pri_addr,
1152 struct in_addr * sec_addr,
1153 int argc,
1154 char **argv)
1155{
1156 int dummyint;
1157 struct in_addr dummyaddr;
1158
1159 pri_addr->s_addr = sec_addr->s_addr = 0L;
1160
1161 if (argc > 0) {
1162 ParseAddr(argc, argv++, pri_addr, &dummyaddr, &dummyint);
1163 if (--argc > 0)
1164 ParseAddr(argc, argv++, sec_addr, &dummyaddr, &dummyint);
1165 else
1166 sec_addr->s_addr = pri_addr->s_addr;
1167 }
1168
1169 /*
1170 * if the primary/secondary ns entries are 0.0.0.0 we should set them to
1171 * either the localhost's ip, or the values in /etc/resolv.conf ??
1172 *
1173 * up to you if you want to implement this...
1174 */
1175
1176}
1177
1178static int
1179SetNS(struct cmdtab const * list, int argc, char **argv)
1180{
1181 SetMSEXT(&ns_entries[0], &ns_entries[1], argc, argv);
1182 return 0;
1183}
1184
1185static int
1186SetNBNS(struct cmdtab const * list, int argc, char **argv)
1187{
1188 SetMSEXT(&nbns_entries[0], &nbns_entries[1], argc, argv);
1189 return 0;
1190}
1191
1192#endif /* MS_EXT */
1193
1194#define VAR_AUTHKEY 0
1195#define VAR_DIAL 1
1196#define VAR_LOGIN 2
1197#define VAR_AUTHNAME 3
1198#define VAR_DEVICE 4
1199#define VAR_ACCMAP 5
1200#define VAR_PHONE 6
1201#define VAR_HANGUP 7
1202
1203static int
1204SetVariable(struct cmdtab const * list, int argc, char **argv, int param)
1205{
1206 u_long map;
1207 char *arg;
1208
1209 if (argc > 0)
1210 arg = *argv;
1211 else
1212 arg = "";
1213
1214 switch (param) {
1215 case VAR_AUTHKEY:
1216 strncpy(VarAuthKey, arg, sizeof(VarAuthKey) - 1);
1217 VarAuthKey[sizeof(VarAuthKey) - 1] = '\0';
1218 break;
1219 case VAR_AUTHNAME:
1220 strncpy(VarAuthName, arg, sizeof(VarAuthName) - 1);
1221 VarAuthName[sizeof(VarAuthName) - 1] = '\0';
1222 break;
1223 case VAR_DIAL:
1224 strncpy(VarDialScript, arg, sizeof(VarDialScript) - 1);
1225 VarDialScript[sizeof(VarDialScript) - 1] = '\0';
1226 break;
1227 case VAR_LOGIN:
1228 strncpy(VarLoginScript, arg, sizeof(VarLoginScript) - 1);
1229 VarLoginScript[sizeof(VarLoginScript) - 1] = '\0';
1230 break;
1231 case VAR_DEVICE:
1232 CloseModem();
1233 strncpy(VarDevice, arg, sizeof(VarDevice) - 1);
1234 VarDevice[sizeof(VarDevice) - 1] = '\0';
1235 VarBaseDevice = rindex(VarDevice, '/');
1236 VarBaseDevice = VarBaseDevice ? VarBaseDevice + 1 : "";
1237 break;
1238 case VAR_ACCMAP:
1239 sscanf(arg, "%lx", &map);
1240 VarAccmap = map;
1241 break;
1242 case VAR_PHONE:
1243 strncpy(VarPhoneList, arg, sizeof(VarPhoneList) - 1);
1244 VarPhoneList[sizeof(VarPhoneList) - 1] = '\0';
1245 strcpy(VarPhoneCopy, VarPhoneList);
1246 VarNextPhone = VarPhoneCopy;
1247 break;
1248 case VAR_HANGUP:
1249 strncpy(VarHangupScript, arg, sizeof(VarHangupScript) - 1);
1250 VarHangupScript[sizeof(VarHangupScript) - 1] = '\0';
1251 break;
1252 }
1253 return 0;
1254}
1255
1256static int
1257SetCtsRts(struct cmdtab const * list, int argc, char **argv)
1258{
1259 if (argc > 0) {
1260 if (strcmp(*argv, "on") == 0)
1261 VarCtsRts = TRUE;
1262 else if (strcmp(*argv, "off") == 0)
1263 VarCtsRts = FALSE;
1264 else
1265 return -1;
1266 return 0;
1267 }
1268 return -1;
1269}
1270
1271
1272static int
1273SetOpenMode(struct cmdtab const * list, int argc, char **argv)
1274{
1275 if (argc > 0) {
1276 if (strcmp(*argv, "active") == 0)
1277 VarOpenMode = OPEN_ACTIVE;
1278 else if (strcmp(*argv, "passive") == 0)
1279 VarOpenMode = OPEN_PASSIVE;
1280 else
1281 return -1;
1282 return 0;
1283 }
1284 return -1;
1285}
1286
1287extern int SetIfilter(), SetOfilter(), SetDfilter(), SetAfilter();
1288
1289struct cmdtab const SetCommands[] = {
1290 {"accmap", NULL, SetVariable, LOCAL_AUTH,
1291 "Set accmap value", "set accmap hex-value", (void *) VAR_ACCMAP},
1292 {"afilter", NULL, SetAfilter, LOCAL_AUTH,
1293 "Set keep Alive filter", "set afilter ..."},
1294 {"authkey", "key", SetVariable, LOCAL_AUTH,
1295 "Set authentication key", "set authkey|key key", (void *) VAR_AUTHKEY},
1296 {"authname", NULL, SetVariable, LOCAL_AUTH,
1297 "Set authentication name", "set authname name", (void *) VAR_AUTHNAME},
1298 {"ctsrts", NULL, SetCtsRts, LOCAL_AUTH,
1299 "Use CTS/RTS modem signalling", "set ctsrts [on|off]"},
1300 {"device", "line", SetVariable, LOCAL_AUTH,
1301 "Set modem device name", "set device|line device-name", (void *) VAR_DEVICE},
1302 {"dfilter", NULL, SetDfilter, LOCAL_AUTH,
1303 "Set demand filter", "set dfilter ..."},
1304 {"dial", NULL, SetVariable, LOCAL_AUTH,
1305 "Set dialing script", "set dial chat-script", (void *) VAR_DIAL},
1306 {"escape", NULL, SetEscape, LOCAL_AUTH,
1307 "Set escape characters", "set escape hex-digit ..."},
1308 {"hangup", NULL, SetVariable, LOCAL_AUTH,
1309 "Set hangup script", "set hangup chat-script", (void *) VAR_HANGUP},
1310 {"ifaddr", NULL, SetInterfaceAddr, LOCAL_AUTH,
1311 "Set destination address", "set ifaddr [src-addr [dst-addr [netmask [trg-addr]]]]"},
1312 {"ifilter", NULL, SetIfilter, LOCAL_AUTH,
1313 "Set input filter", "set ifilter ..."},
1314 {"loopback", NULL, SetLoopback, LOCAL_AUTH,
1315 "Set loopback facility", "set loopback on|off"},
1316 {"log", NULL, SetLogLevel, LOCAL_AUTH,
1317 "Set log level", "set log [+|-]value..."},
1318 {"login", NULL, SetVariable, LOCAL_AUTH,
1319 "Set login script", "set login chat-script", (void *) VAR_LOGIN},
1320 {"mru", NULL, SetInitialMRU, LOCAL_AUTH,
1321 "Set Initial MRU value", "set mru value"},
1322 {"mtu", NULL, SetPreferredMTU, LOCAL_AUTH,
1323 "Set Preferred MTU value", "set mtu value"},
1324 {"ofilter", NULL, SetOfilter, LOCAL_AUTH,
1325 "Set output filter", "set ofilter ..."},
1326 {"openmode", NULL, SetOpenMode, LOCAL_AUTH,
1327 "Set open mode", "set openmode [active|passive]"},
1328 {"parity", NULL, SetModemParity, LOCAL_AUTH,
1329 "Set modem parity", "set parity [odd|even|none]"},
1330 {"phone", NULL, SetVariable, LOCAL_AUTH,
1331 "Set telephone number(s)", "set phone phone1[:phone2[...]]", (void *) VAR_PHONE},
1332 {"reconnect", NULL, SetReconnect, LOCAL_AUTH,
1333 "Set Reconnect timeout", "set reconnect value ntries"},
1334 {"redial", NULL, SetRedialTimeout, LOCAL_AUTH,
1335 "Set Redial timeout", "set redial value|random[.value|random] [dial_attempts]"},
1336 {"stopped", NULL, SetStoppedTimeout, LOCAL_AUTH,
1337 "Set STOPPED timeouts", "set stopped [LCPseconds [IPCPseconds [CCPseconds]]]"},
1338 {"server", "socket", SetServer, LOCAL_AUTH,
1339 "Set server port", "set server|socket TcpPort|LocalName|none [mask]"},
1340 {"speed", NULL, SetModemSpeed, LOCAL_AUTH,
1341 "Set modem speed", "set speed value"},
1342 {"timeout", NULL, SetIdleTimeout, LOCAL_AUTH,
1343 "Set Idle timeout", "set timeout value"},
1344#ifndef NOMSEXT
1345 {"ns", NULL, SetNS, LOCAL_AUTH,
1346 "Set NameServer", "set ns pri-addr [sec-addr]"},
1347 {"nbns", NULL, SetNBNS, LOCAL_AUTH,
1348 "Set NetBIOS NameServer", "set nbns pri-addr [sec-addr]"},
1349#endif
1350 {"help", "?", HelpCommand, LOCAL_AUTH | LOCAL_NO_AUTH,
1351 "Display this message", "set help|? [command]", (void *) SetCommands},
1352 {NULL, NULL, NULL},
1353};
1354
1355static int
1356SetCommand(struct cmdtab const * list, int argc, char **argv)
1357{
1358 if (argc > 0)
1359 FindExec(SetCommands, argc, argv);
1360 else if (VarTerm)
1361 fprintf(VarTerm, "Use `set ?' to get a list or `set ? <var>' for"
1362 " syntax help.\n");
1363 else
1364 LogPrintf(LogWARN, "set command must have arguments\n");
1365
1366 return 0;
1367}
1368
1369
1370static int
1371AddCommand(struct cmdtab const * list, int argc, char **argv)
1372{
1373 struct in_addr dest, gateway, netmask;
1374
1375 if (argc == 3) {
1376 if (strcasecmp(argv[0], "MYADDR") == 0)
1377 dest = IpcpInfo.want_ipaddr;
1378 else
1379 dest = GetIpAddr(argv[0]);
1380 netmask = GetIpAddr(argv[1]);
1381 if (strcasecmp(argv[2], "HISADDR") == 0)
1382 gateway = IpcpInfo.his_ipaddr;
1383 else
1384 gateway = GetIpAddr(argv[2]);
1385 OsSetRoute(RTM_ADD, dest, gateway, netmask);
1386 return 0;
1387 }
1388 return -1;
1389}
1390
1391static int
1392DeleteCommand(struct cmdtab const * list, int argc, char **argv)
1393{
1394 struct in_addr dest, gateway, netmask;
1395
1396 if (argc == 1 && strcasecmp(argv[0], "all") == 0)
1397 DeleteIfRoutes(0);
1398 else if (argc > 0 && argc < 4) {
1399 if (strcasecmp(argv[0], "MYADDR") == 0)
1400 dest = IpcpInfo.want_ipaddr;
1401 else
1402 dest = GetIpAddr(argv[0]);
1403 netmask.s_addr = INADDR_ANY;
1404 if (argc > 1) {
1405 if (strcasecmp(argv[1], "HISADDR") == 0)
1406 gateway = IpcpInfo.his_ipaddr;
1407 else
1408 gateway = GetIpAddr(argv[1]);
1409 if (argc == 3) {
1410 if (inet_aton(argv[2], &netmask) == 0) {
1411 LogPrintf(LogWARN, "Bad netmask value.\n");
1412 return -1;
1413 }
1414 }
1415 } else
1416 gateway.s_addr = INADDR_ANY;
1417 OsSetRoute(RTM_DELETE, dest, gateway, netmask);
1418 } else
1419 return -1;
1420
1421 return 0;
1422}
1423
1424static int AliasEnable();
1425static int AliasOption();
1426
1427static struct cmdtab const AliasCommands[] =
1428{
1429 {"enable", NULL, AliasEnable, LOCAL_AUTH,
1430 "enable IP aliasing", "alias enable [yes|no]"},
1431 {"port", NULL, AliasRedirectPort, LOCAL_AUTH,
1432 "port redirection", "alias port [proto addr_local:port_local port_alias]"},
1433 {"addr", NULL, AliasRedirectAddr, LOCAL_AUTH,
1434 "static address translation", "alias addr [addr_local addr_alias]"},
1435 {"deny_incoming", NULL, AliasOption, LOCAL_AUTH,
1436 "stop incoming connections", "alias deny_incoming [yes|no]",
1437 (void *) PKT_ALIAS_DENY_INCOMING},
1438 {"log", NULL, AliasOption, LOCAL_AUTH,
1439 "log aliasing link creation", "alias log [yes|no]",
1440 (void *) PKT_ALIAS_LOG},
1441 {"same_ports", NULL, AliasOption, LOCAL_AUTH,
1442 "try to leave port numbers unchanged", "alias same_ports [yes|no]",
1443 (void *) PKT_ALIAS_SAME_PORTS},
1444 {"use_sockets", NULL, AliasOption, LOCAL_AUTH,
1445 "allocate host sockets", "alias use_sockets [yes|no]",
1446 (void *) PKT_ALIAS_USE_SOCKETS},
1447 {"unregistered_only", NULL, AliasOption, LOCAL_AUTH,
1448 "alias unregistered (private) IP address space only",
1449 "alias unregistered_only [yes|no]",
1450 (void *) PKT_ALIAS_UNREGISTERED_ONLY},
1451 {"help", "?", HelpCommand, LOCAL_AUTH | LOCAL_NO_AUTH,
1452 "Display this message", "alias help|? [command]",
1453 (void *) AliasCommands},
1454 {NULL, NULL, NULL},
1455};
1456
1457
1458static int
1459AliasCommand(struct cmdtab const * list, int argc, char **argv)
1460{
1461 if (argc > 0)
1462 FindExec(AliasCommands, argc, argv);
1463 else if (VarTerm)
1464 fprintf(VarTerm, "Use `alias help' to get a list or `alias help <option>'"
1465 " for syntax help.\n");
1466 else
1467 LogPrintf(LogWARN, "alias command must have arguments\n");
1468
1469 return 0;
1470}
1471
1472static int
1473AliasEnable(struct cmdtab const * list, int argc, char **argv)
1474{
1475 if (argc == 1)
1476 if (strcasecmp(argv[0], "yes") == 0) {
1477 if (!(mode & MODE_ALIAS)) {
1478 if (loadAliasHandlers(&VarAliasHandlers) == 0) {
1479 mode |= MODE_ALIAS;
1480 return 0;
1481 }
1482 LogPrintf(LogWARN, "Cannot load alias library\n");
1483 return 1;
1484 }
1485 return 0;
1486 } else if (strcasecmp(argv[0], "no") == 0) {
1487 if (mode & MODE_ALIAS) {
1488 unloadAliasHandlers();
1489 mode &= ~MODE_ALIAS;
1490 }
1491 return 0;
1492 }
1493 return -1;
1494}
1495
1496
1497static int
1498AliasOption(struct cmdtab const * list, int argc, char **argv, void *param)
1499{
1500 if (argc == 1)
1501 if (strcasecmp(argv[0], "yes") == 0) {
1502 if (mode & MODE_ALIAS) {
1503 VarPacketAliasSetMode((unsigned) param, (unsigned) param);
1504 return 0;
1505 }
1506 LogPrintf(LogWARN, "alias not enabled\n");
1507 } else if (strcmp(argv[0], "no") == 0) {
1508 if (mode & MODE_ALIAS) {
1509 VarPacketAliasSetMode(0, (unsigned) param);
1510 return 0;
1511 }
1512 LogPrintf(LogWARN, "alias not enabled\n");
1513 }
1514 return -1;
1515}