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