2 * Copyright (c) 1996 - 2001 Brian Somers <brian@Awfulhak.org>
3 * based on work by Toshiharu OHNO <tony-o@iij.ad.jp>
4 * Internet Initiative Japan, Inc (IIJ)
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * $FreeBSD: src/usr.sbin/ppp/command.c,v 1.230.2.18 2003/04/05 10:48:08 ume Exp $
31 #include <sys/param.h>
32 #include <netinet/in_systm.h>
33 #include <netinet/in.h>
34 #include <netinet/ip.h>
35 #include <arpa/inet.h>
36 #include <sys/socket.h>
37 #include <net/route.h>
69 #include "throughput.h"
70 #include "slcompress.h"
81 #include "descriptor.h"
101 #include "datalink.h"
107 #define VAR_AUTHKEY 0
110 #define VAR_AUTHNAME 3
111 #define VAR_AUTOLOAD 4
112 #define VAR_WINSIZE 5
118 #define VAR_OPENMODE 11
120 #define VAR_HANGUP 13
121 #define VAR_IDLETIMEOUT 14
122 #define VAR_LQRPERIOD 15
123 #define VAR_LCPRETRY 16
124 #define VAR_CHAPRETRY 17
125 #define VAR_PAPRETRY 18
126 #define VAR_CCPRETRY 19
127 #define VAR_IPCPRETRY 20
131 #define VAR_CALLBACK 24
133 #define VAR_CHOKED 26
134 #define VAR_SENDPIPE 27
135 #define VAR_RECVPIPE 28
136 #define VAR_RADIUS 29
138 #define VAR_PARITY 31
139 #define VAR_CRTSCTS 32
140 #define VAR_URGENTPORTS 33
141 #define VAR_LOGOUT 34
142 #define VAR_IFQUEUE 35
144 #define VAR_IPV6CPRETRY 37
146 /* ``accept|deny|disable|enable'' masks */
147 #define NEG_HISMASK (1)
148 #define NEG_MYMASK (2)
150 /* ``accept|deny|disable|enable'' values */
151 #define NEG_ACFCOMP 40
152 #define NEG_CHAP05 41
153 #define NEG_CHAP80 42
154 #define NEG_CHAP80LM 43
155 #define NEG_DEFLATE 44
157 #define NEG_ENDDISC 46
160 #define NEG_PPPDDEFLATE 49
162 #define NEG_PROTOCOMP 51
163 #define NEG_SHORTSEQ 52
164 #define NEG_VJCOMP 53
166 #define NEG_CHAP81 55
168 const char Version
[] = "3.3";
170 static int ShowCommand(struct cmdargs
const *);
171 static int TerminalCommand(struct cmdargs
const *);
172 static int QuitCommand(struct cmdargs
const *);
173 static int OpenCommand(struct cmdargs
const *);
174 static int CloseCommand(struct cmdargs
const *);
175 static int DownCommand(struct cmdargs
const *);
176 static int SetCommand(struct cmdargs
const *);
177 static int LinkCommand(struct cmdargs
const *);
178 static int AddCommand(struct cmdargs
const *);
179 static int DeleteCommand(struct cmdargs
const *);
180 static int NegotiateCommand(struct cmdargs
const *);
181 static int ClearCommand(struct cmdargs
const *);
182 static int RunListCommand(struct cmdargs
const *);
183 static int IfaceAddCommand(struct cmdargs
const *);
184 static int IfaceDeleteCommand(struct cmdargs
const *);
185 static int IfaceClearCommand(struct cmdargs
const *);
186 static int SetProcTitle(struct cmdargs
const *);
188 static int NatEnable(struct cmdargs
const *);
189 static int NatOption(struct cmdargs
const *);
193 showcx(struct cmdtab
const *cmd
)
195 if (cmd
->lauth
& LOCAL_CX
)
197 else if (cmd
->lauth
& LOCAL_CX_OPT
)
204 HelpCommand(struct cmdargs
const *arg
)
206 struct cmdtab
const *cmd
;
207 int n
, cmax
, dmax
, cols
, cxlen
;
211 log_Printf(LogWARN
, "help: Cannot help without a prompt\n");
215 if (arg
->argc
> arg
->argn
) {
216 for (cmd
= arg
->cmdtab
; cmd
->name
|| cmd
->alias
; cmd
++)
217 if ((cmd
->lauth
& arg
->prompt
->auth
) &&
218 ((cmd
->name
&& !strcasecmp(cmd
->name
, arg
->argv
[arg
->argn
])) ||
219 (cmd
->alias
&& !strcasecmp(cmd
->alias
, arg
->argv
[arg
->argn
])))) {
220 prompt_Printf(arg
->prompt
, "%s %s\n", cmd
->syntax
, showcx(cmd
));
227 for (cmd
= arg
->cmdtab
; cmd
->func
; cmd
++)
228 if (cmd
->name
&& (cmd
->lauth
& arg
->prompt
->auth
)) {
229 if ((n
= strlen(cmd
->name
) + strlen(showcx(cmd
))) > cmax
)
231 if ((n
= strlen(cmd
->helpmes
)) > dmax
)
235 cols
= 80 / (dmax
+ cmax
+ 3);
237 prompt_Printf(arg
->prompt
, "(o) = Optional context,"
238 " (c) = Context required\n");
239 for (cmd
= arg
->cmdtab
; cmd
->func
; cmd
++)
240 if (cmd
->name
&& (cmd
->lauth
& arg
->prompt
->auth
)) {
242 cxlen
= cmax
- strlen(cmd
->name
);
244 prompt_Printf(arg
->prompt
, " ");
245 prompt_Printf(arg
->prompt
, "%s%-*.*s: %-*.*s",
246 cmd
->name
, cxlen
, cxlen
, cx
, dmax
, dmax
, cmd
->helpmes
);
248 prompt_Printf(arg
->prompt
, "\n");
251 prompt_Printf(arg
->prompt
, "\n");
257 IdentCommand(struct cmdargs
const *arg
)
259 Concatinate(arg
->cx
->physical
->link
.lcp
.cfg
.ident
,
260 sizeof arg
->cx
->physical
->link
.lcp
.cfg
.ident
,
261 arg
->argc
- arg
->argn
, arg
->argv
+ arg
->argn
);
266 SendIdentification(struct cmdargs
const *arg
)
268 if (arg
->cx
->state
< DATALINK_LCP
) {
269 log_Printf(LogWARN
, "sendident: link has not reached LCP\n");
272 return lcp_SendIdentification(&arg
->cx
->physical
->link
.lcp
) ? 0 : 1;
276 CloneCommand(struct cmdargs
const *arg
)
278 char namelist
[LINE_LEN
];
282 if (arg
->argc
== arg
->argn
)
285 namelist
[sizeof namelist
- 1] = '\0';
286 for (f
= arg
->argn
; f
< arg
->argc
; f
++) {
287 strncpy(namelist
, arg
->argv
[f
], sizeof namelist
- 1);
288 for(name
= strtok(namelist
, ", "); name
; name
= strtok(NULL
,", "))
289 bundle_DatalinkClone(arg
->bundle
, arg
->cx
, name
);
296 RemoveCommand(struct cmdargs
const *arg
)
298 if (arg
->argc
!= arg
->argn
)
301 if (arg
->cx
->state
!= DATALINK_CLOSED
) {
302 log_Printf(LogWARN
, "remove: Cannot delete links that aren't closed\n");
306 bundle_DatalinkRemove(arg
->bundle
, arg
->cx
);
311 RenameCommand(struct cmdargs
const *arg
)
313 if (arg
->argc
!= arg
->argn
+ 1)
316 if (bundle_RenameDatalink(arg
->bundle
, arg
->cx
, arg
->argv
[arg
->argn
]))
319 log_Printf(LogWARN
, "%s -> %s: target name already exists\n",
320 arg
->cx
->name
, arg
->argv
[arg
->argn
]);
325 LoadCommand(struct cmdargs
const *arg
)
330 mode
= arg
->bundle
->phys_type
.all
;
332 if (arg
->argn
< arg
->argc
) {
333 for (n
= arg
->argn
; n
< arg
->argc
; n
++)
334 if ((err
= system_IsValid(arg
->argv
[n
], arg
->prompt
, mode
)) != NULL
) {
335 log_Printf(LogWARN
, "%s: %s\n", arg
->argv
[n
], err
);
339 for (n
= arg
->argn
; n
< arg
->argc
; n
++) {
340 bundle_SetLabel(arg
->bundle
, arg
->argv
[arg
->argc
- 1]);
341 system_Select(arg
->bundle
, arg
->argv
[n
], CONFFILE
, arg
->prompt
, arg
->cx
);
343 bundle_SetLabel(arg
->bundle
, arg
->argv
[arg
->argc
- 1]);
344 } else if ((err
= system_IsValid("default", arg
->prompt
, mode
)) != NULL
) {
345 log_Printf(LogWARN
, "default: %s\n", err
);
348 bundle_SetLabel(arg
->bundle
, "default");
349 system_Select(arg
->bundle
, "default", CONFFILE
, arg
->prompt
, arg
->cx
);
350 bundle_SetLabel(arg
->bundle
, "default");
357 LogCommand(struct cmdargs
const *arg
)
361 if (arg
->argn
< arg
->argc
) {
363 int argc
= arg
->argc
- arg
->argn
;
365 if (argc
>= (int)(sizeof argv
/ sizeof argv
[0])) {
366 argc
= sizeof argv
/ sizeof argv
[0] - 1;
367 log_Printf(LogWARN
, "Truncating log command to %d args\n", argc
);
369 command_Expand(argv
, argc
, arg
->argv
+ arg
->argn
, arg
->bundle
, 1, getpid());
370 Concatinate(buf
, sizeof buf
, argc
, (const char *const *)argv
);
371 log_Printf(LogLOG
, "%s\n", buf
);
372 command_Free(argc
, argv
);
380 SaveCommand(struct cmdargs
const *arg __unused
)
382 log_Printf(LogWARN
, "save command is not yet implemented.\n");
387 DialCommand(struct cmdargs
const *arg
)
391 if ((arg
->cx
&& !(arg
->cx
->physical
->type
& (PHYS_INTERACTIVE
|PHYS_AUTO
)))
393 (arg
->bundle
->phys_type
.all
& ~(PHYS_INTERACTIVE
|PHYS_AUTO
)))) {
394 log_Printf(LogWARN
, "Manual dial is only available for auto and"
395 " interactive links\n");
399 if (arg
->argc
> arg
->argn
&& (res
= LoadCommand(arg
)) != 0)
402 bundle_Open(arg
->bundle
, arg
->cx
? arg
->cx
->name
: NULL
, PHYS_ALL
, 1);
407 #define isinword(ch) (isalnum(ch) || (ch) == '_')
410 strstrword(char *big
, const char *little
)
412 /* Get the first occurance of the word ``little'' in ``big'' */
417 len
= strlen(little
);
419 while ((pos
= strstr(pos
, little
)) != NULL
)
420 if ((pos
!= big
&& isinword(pos
[-1])) || isinword(pos
[len
]))
422 else if (pos
!= big
&& pos
[-1] == '\\')
423 memmove(pos
- 1, pos
, strlen(pos
) + 1);
431 subst(char *tgt
, const char *oldstr
, const char *newstr
)
433 /* tgt is a malloc()d area... realloc() as necessary */
435 int ltgt
, loldstr
, lnewstr
, pos
;
437 if ((word
= strstrword(tgt
, oldstr
)) == NULL
)
440 ltgt
= strlen(tgt
) + 1;
441 loldstr
= strlen(oldstr
);
442 lnewstr
= strlen(newstr
);
445 if (loldstr
> lnewstr
)
446 bcopy(word
+ loldstr
, word
+ lnewstr
, ltgt
- pos
- loldstr
);
447 if (loldstr
!= lnewstr
) {
448 ntgt
= realloc(tgt
, ltgt
+= lnewstr
- loldstr
);
450 break; /* Oh wonderful ! */
454 if (lnewstr
> loldstr
)
455 bcopy(word
+ loldstr
, word
+ lnewstr
, ltgt
- pos
- loldstr
);
456 bcopy(newstr
, word
, lnewstr
);
457 } while ((word
= strstrword(word
, oldstr
)));
463 substip(char *tgt
, const char *oldstr
, struct in_addr ip
)
465 return subst(tgt
, oldstr
, inet_ntoa(ip
));
469 substlong(char *tgt
, const char *oldstr
, long l
)
473 snprintf(buf
, sizeof buf
, "%ld", l
);
475 return subst(tgt
, oldstr
, buf
);
479 substull(char *tgt
, const char *oldstr
, unsigned long long ull
)
483 snprintf(buf
, sizeof buf
, "%llu", ull
);
485 return subst(tgt
, oldstr
, buf
);
491 substipv6(char *tgt
, const char *oldstr
, const struct ncpaddr
*ip
)
493 return subst(tgt
, oldstr
, ncpaddr_ntoa(ip
));
498 command_Expand(char **nargv
, int argc
, char const *const *oargv
,
499 struct bundle
*bundle
, int inc0
, pid_t pid
)
503 unsigned long long oin
, oout
, pin
, pout
;
506 arg
= 0; /* Start at arg 0 */
508 nargv
[0] = strdup(oargv
[0]);
512 secs
= bundle_Uptime(bundle
);
513 snprintf(uptime
, sizeof uptime
, "%d:%02d:%02d",
514 secs
/ 3600, (secs
/ 60) % 60, secs
% 60);
515 oin
= bundle
->ncp
.ipcp
.throughput
.OctetsIn
;
516 oout
= bundle
->ncp
.ipcp
.throughput
.OctetsOut
;
517 pin
= bundle
->ncp
.ipcp
.throughput
.PacketsIn
;
518 pout
= bundle
->ncp
.ipcp
.throughput
.PacketsOut
;
520 oin
+= bundle
->ncp
.ipv6cp
.throughput
.OctetsIn
;
521 oout
+= bundle
->ncp
.ipv6cp
.throughput
.OctetsOut
;
522 pin
+= bundle
->ncp
.ipv6cp
.throughput
.PacketsIn
;
523 pout
+= bundle
->ncp
.ipv6cp
.throughput
.PacketsOut
;
526 for (; arg
< argc
; arg
++) {
527 nargv
[arg
] = strdup(oargv
[arg
]);
528 nargv
[arg
] = subst(nargv
[arg
], "AUTHNAME", bundle
->cfg
.auth
.name
);
529 nargv
[arg
] = subst(nargv
[arg
], "COMPILATIONDATE", __DATE__
);
530 nargv
[arg
] = substip(nargv
[arg
], "DNS0", bundle
->ncp
.ipcp
.ns
.dns
[0]);
531 nargv
[arg
] = substip(nargv
[arg
], "DNS1", bundle
->ncp
.ipcp
.ns
.dns
[1]);
532 nargv
[arg
] = subst(nargv
[arg
], "ENDDISC",
533 mp_Enddisc(bundle
->ncp
.mp
.cfg
.enddisc
.class,
534 bundle
->ncp
.mp
.cfg
.enddisc
.address
,
535 bundle
->ncp
.mp
.cfg
.enddisc
.len
));
536 nargv
[arg
] = substip(nargv
[arg
], "HISADDR", bundle
->ncp
.ipcp
.peer_ip
);
538 nargv
[arg
] = substipv6(nargv
[arg
], "HISADDR6", &bundle
->ncp
.ipv6cp
.hisaddr
);
540 nargv
[arg
] = subst(nargv
[arg
], "INTERFACE", bundle
->iface
->name
);
541 nargv
[arg
] = substull(nargv
[arg
], "IPOCTETSIN",
542 bundle
->ncp
.ipcp
.throughput
.OctetsIn
);
543 nargv
[arg
] = substull(nargv
[arg
], "IPOCTETSOUT",
544 bundle
->ncp
.ipcp
.throughput
.OctetsOut
);
545 nargv
[arg
] = substull(nargv
[arg
], "IPPACKETSIN",
546 bundle
->ncp
.ipcp
.throughput
.PacketsIn
);
547 nargv
[arg
] = substull(nargv
[arg
], "IPPACKETSOUT",
548 bundle
->ncp
.ipcp
.throughput
.PacketsOut
);
550 nargv
[arg
] = substull(nargv
[arg
], "IPV6OCTETSIN",
551 bundle
->ncp
.ipv6cp
.throughput
.OctetsIn
);
552 nargv
[arg
] = substull(nargv
[arg
], "IPV6OCTETSOUT",
553 bundle
->ncp
.ipv6cp
.throughput
.OctetsOut
);
554 nargv
[arg
] = substull(nargv
[arg
], "IPV6PACKETSIN",
555 bundle
->ncp
.ipv6cp
.throughput
.PacketsIn
);
556 nargv
[arg
] = substull(nargv
[arg
], "IPV6PACKETSOUT",
557 bundle
->ncp
.ipv6cp
.throughput
.PacketsOut
);
559 nargv
[arg
] = subst(nargv
[arg
], "LABEL", bundle_GetLabel(bundle
));
560 nargv
[arg
] = substip(nargv
[arg
], "MYADDR", bundle
->ncp
.ipcp
.my_ip
);
562 nargv
[arg
] = substipv6(nargv
[arg
], "MYADDR6", &bundle
->ncp
.ipv6cp
.myaddr
);
564 nargv
[arg
] = substull(nargv
[arg
], "OCTETSIN", oin
);
565 nargv
[arg
] = substull(nargv
[arg
], "OCTETSOUT", oout
);
566 nargv
[arg
] = substull(nargv
[arg
], "PACKETSIN", pin
);
567 nargv
[arg
] = substull(nargv
[arg
], "PACKETSOUT", pout
);
568 nargv
[arg
] = subst(nargv
[arg
], "PEER_ENDDISC",
569 mp_Enddisc(bundle
->ncp
.mp
.peer
.enddisc
.class,
570 bundle
->ncp
.mp
.peer
.enddisc
.address
,
571 bundle
->ncp
.mp
.peer
.enddisc
.len
));
572 nargv
[arg
] = substlong(nargv
[arg
], "PROCESSID", pid
);
574 nargv
[arg
] = substlong(nargv
[arg
], "SOCKNAME", server
.cfg
.port
);
576 nargv
[arg
] = subst(nargv
[arg
], "SOCKNAME", server
.cfg
.sockname
);
577 nargv
[arg
] = subst(nargv
[arg
], "UPTIME", uptime
);
578 nargv
[arg
] = subst(nargv
[arg
], "USER", bundle
->ncp
.mp
.peer
.authname
);
579 nargv
[arg
] = subst(nargv
[arg
], "VERSION", Version
);
585 command_Free(int argc
, char **argv
)
595 ShellCommand(struct cmdargs
const *arg
, int bg
)
600 #ifdef SHELL_ONLY_INTERACTIVELY
601 /* we're only allowed to shell when we run ppp interactively */
602 if (arg
->prompt
&& arg
->prompt
->owner
) {
603 log_Printf(LogWARN
, "Can't start a shell from a network connection\n");
608 if (arg
->argc
== arg
->argn
) {
610 log_Printf(LogWARN
, "Can't start an interactive shell from"
613 } else if (arg
->prompt
->owner
) {
614 log_Printf(LogWARN
, "Can't start an interactive shell from"
615 " a socket connection\n");
618 log_Printf(LogWARN
, "Can only start an interactive shell in"
619 " the foreground mode\n");
625 if ((shpid
= fork()) == 0) {
628 if ((shell
= getenv("SHELL")) == NULL
)
629 shell
= _PATH_BSHELL
;
634 fd
= arg
->prompt
->fd_out
;
635 else if ((fd
= open(_PATH_DEVNULL
, O_RDWR
)) == -1) {
636 log_Printf(LogALERT
, "Failed to open %s: %s\n",
637 _PATH_DEVNULL
, strerror(errno
));
640 dup2(fd
, STDIN_FILENO
);
641 dup2(fd
, STDOUT_FILENO
);
642 dup2(fd
, STDERR_FILENO
);
643 for (i
= getdtablesize(); i
> STDERR_FILENO
; i
--)
644 fcntl(i
, F_SETFD
, 1);
647 setuid(ID0realuid());
649 if (arg
->argc
> arg
->argn
) {
650 /* substitute pseudo args */
652 int argc
= arg
->argc
- arg
->argn
;
654 if (argc
>= (int)(sizeof argv
/ sizeof argv
[0])) {
655 argc
= sizeof argv
/ sizeof argv
[0] - 1;
656 log_Printf(LogWARN
, "Truncating shell command to %d args\n", argc
);
658 command_Expand(argv
, argc
, arg
->argv
+ arg
->argn
, arg
->bundle
, 0, pid
);
663 if (daemon(1, 1) == -1) {
664 log_Printf(LogERROR
, "%ld: daemon: %s\n", (long)p
, strerror(errno
));
667 } else if (arg
->prompt
)
668 printf("ppp: Pausing until %s finishes\n", arg
->argv
[arg
->argn
]);
669 execvp(argv
[0], argv
);
672 printf("ppp: Pausing until %s finishes\n", shell
);
673 prompt_TtyOldMode(arg
->prompt
);
674 execl(shell
, shell
, NULL
);
677 log_Printf(LogWARN
, "exec() of %s failed: %s\n",
678 arg
->argc
> arg
->argn
? arg
->argv
[arg
->argn
] : shell
,
683 if (shpid
== (pid_t
)-1)
684 log_Printf(LogERROR
, "Fork failed: %s\n", strerror(errno
));
687 waitpid(shpid
, &status
, 0);
690 if (arg
->prompt
&& !arg
->prompt
->owner
)
691 prompt_TtyCommandMode(arg
->prompt
);
697 BgShellCommand(struct cmdargs
const *arg
)
699 if (arg
->argc
== arg
->argn
)
701 return ShellCommand(arg
, 1);
705 FgShellCommand(struct cmdargs
const *arg
)
707 return ShellCommand(arg
, 0);
711 ResolvCommand(struct cmdargs
const *arg
)
713 if (arg
->argc
== arg
->argn
+ 1) {
714 if (!strcasecmp(arg
->argv
[arg
->argn
], "reload"))
715 ipcp_LoadDNS(&arg
->bundle
->ncp
.ipcp
);
716 else if (!strcasecmp(arg
->argv
[arg
->argn
], "restore"))
717 ipcp_RestoreDNS(&arg
->bundle
->ncp
.ipcp
);
718 else if (!strcasecmp(arg
->argv
[arg
->argn
], "rewrite"))
719 ipcp_WriteDNS(&arg
->bundle
->ncp
.ipcp
);
720 else if (!strcasecmp(arg
->argv
[arg
->argn
], "readonly"))
721 arg
->bundle
->ncp
.ipcp
.ns
.writable
= 0;
722 else if (!strcasecmp(arg
->argv
[arg
->argn
], "writable"))
723 arg
->bundle
->ncp
.ipcp
.ns
.writable
= 1;
734 static struct cmdtab
const NatCommands
[] =
736 {"addr", NULL
, nat_RedirectAddr
, LOCAL_AUTH
,
737 "static address translation", "nat addr [addr_local addr_alias]", NULL
},
738 {"deny_incoming", NULL
, NatOption
, LOCAL_AUTH
,
739 "stop incoming connections", "nat deny_incoming yes|no",
740 (const void *) PKT_ALIAS_DENY_INCOMING
},
741 {"enable", NULL
, NatEnable
, LOCAL_AUTH
,
742 "enable NAT", "nat enable yes|no", NULL
},
743 {"log", NULL
, NatOption
, LOCAL_AUTH
,
744 "log NAT link creation", "nat log yes|no",
745 (const void *) PKT_ALIAS_LOG
},
746 {"port", NULL
, nat_RedirectPort
, LOCAL_AUTH
, "port redirection",
747 "nat port proto localaddr:port[-port] aliasport[-aliasport]", NULL
},
748 {"proto", NULL
, nat_RedirectProto
, LOCAL_AUTH
, "protocol redirection",
749 "nat proto proto localIP [publicIP [remoteIP]]", NULL
},
750 {"proxy", NULL
, nat_ProxyRule
, LOCAL_AUTH
,
751 "proxy control", "nat proxy server host[:port] ...", NULL
},
753 {"punch_fw", NULL
, nat_PunchFW
, LOCAL_AUTH
,
754 "firewall control", "nat punch_fw [base count]", NULL
},
756 {"same_ports", NULL
, NatOption
, LOCAL_AUTH
,
757 "try to leave port numbers unchanged", "nat same_ports yes|no",
758 (const void *) PKT_ALIAS_SAME_PORTS
},
759 {"target", NULL
, nat_SetTarget
, LOCAL_AUTH
,
760 "Default address for incoming connections", "nat target addr", NULL
},
761 {"unregistered_only", NULL
, NatOption
, LOCAL_AUTH
,
762 "translate unregistered (private) IP address space only",
763 "nat unregistered_only yes|no",
764 (const void *) PKT_ALIAS_UNREGISTERED_ONLY
},
765 {"use_sockets", NULL
, NatOption
, LOCAL_AUTH
,
766 "allocate host sockets", "nat use_sockets yes|no",
767 (const void *) PKT_ALIAS_USE_SOCKETS
},
768 {"help", "?", HelpCommand
, LOCAL_AUTH
| LOCAL_NO_AUTH
,
769 "Display this message", "nat help|? [command]", NatCommands
},
770 {NULL
, NULL
, NULL
, 0, NULL
, NULL
, NULL
},
774 static struct cmdtab
const AllowCommands
[] = {
775 {"modes", "mode", AllowModes
, LOCAL_AUTH
,
776 "Only allow certain ppp modes", "allow modes mode...", NULL
},
777 {"users", "user", AllowUsers
, LOCAL_AUTH
,
778 "Only allow ppp access to certain users", "allow users logname...", NULL
},
779 {"help", "?", HelpCommand
, LOCAL_AUTH
| LOCAL_NO_AUTH
,
780 "Display this message", "allow help|? [command]", AllowCommands
},
781 {NULL
, NULL
, NULL
, 0, NULL
, NULL
, NULL
},
784 static struct cmdtab
const IfaceCommands
[] =
786 {"add", NULL
, IfaceAddCommand
, LOCAL_AUTH
,
787 "Add iface address", "iface add addr[/bits| mask] peer", NULL
},
788 {NULL
, "add!", IfaceAddCommand
, LOCAL_AUTH
,
789 "Add or change an iface address", "iface add! addr[/bits| mask] peer",
791 {"clear", NULL
, IfaceClearCommand
, LOCAL_AUTH
,
792 "Clear iface address(es)", "iface clear [INET | INET6]", NULL
},
793 {"delete", "rm", IfaceDeleteCommand
, LOCAL_AUTH
,
794 "Delete iface address", "iface delete addr", NULL
},
795 {NULL
, "rm!", IfaceDeleteCommand
, LOCAL_AUTH
,
796 "Delete iface address", "iface delete addr", (void *)1},
797 {NULL
, "delete!", IfaceDeleteCommand
, LOCAL_AUTH
,
798 "Delete iface address", "iface delete addr", (void *)1},
799 {"show", NULL
, iface_Show
, LOCAL_AUTH
,
800 "Show iface address(es)", "iface show", NULL
},
801 {"help", "?", HelpCommand
, LOCAL_AUTH
| LOCAL_NO_AUTH
,
802 "Display this message", "nat help|? [command]", IfaceCommands
},
803 {NULL
, NULL
, NULL
, 0, NULL
, NULL
, NULL
},
806 static struct cmdtab
const Commands
[] = {
807 {"accept", NULL
, NegotiateCommand
, LOCAL_AUTH
| LOCAL_CX_OPT
,
808 "accept option request", "accept option ..", NULL
},
809 {"add", NULL
, AddCommand
, LOCAL_AUTH
,
810 "add route", "add dest mask gateway", NULL
},
811 {NULL
, "add!", AddCommand
, LOCAL_AUTH
,
812 "add or change route", "add! dest mask gateway", (void *)1},
813 {"allow", "auth", RunListCommand
, LOCAL_AUTH
,
814 "Allow ppp access", "allow users|modes ....", AllowCommands
},
815 {"bg", "!bg", BgShellCommand
, LOCAL_AUTH
,
816 "Run a background command", "[!]bg command", NULL
},
817 {"clear", NULL
, ClearCommand
, LOCAL_AUTH
| LOCAL_CX_OPT
,
818 "Clear throughput statistics",
819 "clear ipcp|ipv6cp|physical [current|overall|peak]...", NULL
},
820 {"clone", NULL
, CloneCommand
, LOCAL_AUTH
| LOCAL_CX
,
821 "Clone a link", "clone newname...", NULL
},
822 {"close", NULL
, CloseCommand
, LOCAL_AUTH
| LOCAL_CX_OPT
,
823 "Close an FSM", "close [lcp|ccp]", NULL
},
824 {"delete", NULL
, DeleteCommand
, LOCAL_AUTH
,
825 "delete route", "delete dest", NULL
},
826 {NULL
, "delete!", DeleteCommand
, LOCAL_AUTH
,
827 "delete a route if it exists", "delete! dest", (void *)1},
828 {"deny", NULL
, NegotiateCommand
, LOCAL_AUTH
| LOCAL_CX_OPT
,
829 "Deny option request", "deny option ..", NULL
},
830 {"dial", "call", DialCommand
, LOCAL_AUTH
| LOCAL_CX_OPT
,
831 "Dial and login", "dial|call [system ...]", NULL
},
832 {"disable", NULL
, NegotiateCommand
, LOCAL_AUTH
| LOCAL_CX_OPT
,
833 "Disable option", "disable option ..", NULL
},
834 {"down", NULL
, DownCommand
, LOCAL_AUTH
| LOCAL_CX_OPT
,
835 "Generate a down event", "down [ccp|lcp]", NULL
},
836 {"enable", NULL
, NegotiateCommand
, LOCAL_AUTH
| LOCAL_CX_OPT
,
837 "Enable option", "enable option ..", NULL
},
838 {"ident", NULL
, IdentCommand
, LOCAL_AUTH
| LOCAL_CX
,
839 "Set the link identity", "ident text...", NULL
},
840 {"iface", "interface", RunListCommand
, LOCAL_AUTH
,
841 "interface control", "iface option ...", IfaceCommands
},
842 {"link", "datalink", LinkCommand
, LOCAL_AUTH
,
843 "Link specific commands", "link name command ...", NULL
},
844 {"load", NULL
, LoadCommand
, LOCAL_AUTH
| LOCAL_CX_OPT
,
845 "Load settings", "load [system ...]", NULL
},
846 {"log", NULL
, LogCommand
, LOCAL_AUTH
| LOCAL_CX_OPT
,
847 "log information", "log word ...", NULL
},
849 {"nat", "alias", RunListCommand
, LOCAL_AUTH
,
850 "NAT control", "nat option yes|no", NatCommands
},
852 {"open", NULL
, OpenCommand
, LOCAL_AUTH
| LOCAL_CX_OPT
,
853 "Open an FSM", "open! [lcp|ccp|ipcp]", (void *)1},
854 {"passwd", NULL
, PasswdCommand
, LOCAL_NO_AUTH
,
855 "Password for manipulation", "passwd LocalPassword", NULL
},
856 {"quit", "bye", QuitCommand
, LOCAL_AUTH
| LOCAL_NO_AUTH
,
857 "Quit PPP program", "quit|bye [all]", NULL
},
858 {"remove", "rm", RemoveCommand
, LOCAL_AUTH
| LOCAL_CX
,
859 "Remove a link", "remove", NULL
},
860 {"rename", "mv", RenameCommand
, LOCAL_AUTH
| LOCAL_CX
,
861 "Rename a link", "rename name", NULL
},
862 {"resolv", NULL
, ResolvCommand
, LOCAL_AUTH
,
863 "Manipulate resolv.conf", "resolv readonly|reload|restore|rewrite|writable",
865 {"save", NULL
, SaveCommand
, LOCAL_AUTH
,
866 "Save settings", "save", NULL
},
867 {"sendident", NULL
, SendIdentification
, LOCAL_AUTH
| LOCAL_CX
,
868 "Transmit the link identity", "sendident", NULL
},
869 {"set", "setup", SetCommand
, LOCAL_AUTH
| LOCAL_CX_OPT
,
870 "Set parameters", "set[up] var value", NULL
},
871 {"shell", "!", FgShellCommand
, LOCAL_AUTH
,
872 "Run a subshell", "shell|! [sh command]", NULL
},
873 {"show", NULL
, ShowCommand
, LOCAL_AUTH
| LOCAL_CX_OPT
,
874 "Show status and stats", "show var", NULL
},
875 {"term", NULL
, TerminalCommand
, LOCAL_AUTH
| LOCAL_CX
,
876 "Enter terminal mode", "term", NULL
},
877 {"help", "?", HelpCommand
, LOCAL_AUTH
| LOCAL_NO_AUTH
,
878 "Display this message", "help|? [command]", Commands
},
879 {NULL
, NULL
, NULL
, 0, NULL
, NULL
, NULL
},
883 ShowEscape(struct cmdargs
const *arg
)
885 if (arg
->cx
->physical
->async
.cfg
.EscMap
[32]) {
887 const char *sep
= "";
889 for (code
= 0; code
< 32; code
++)
890 if (arg
->cx
->physical
->async
.cfg
.EscMap
[code
])
891 for (bit
= 0; bit
< 8; bit
++)
892 if (arg
->cx
->physical
->async
.cfg
.EscMap
[code
] & (1 << bit
)) {
893 prompt_Printf(arg
->prompt
, "%s0x%02x", sep
, (code
<< 3) + bit
);
896 prompt_Printf(arg
->prompt
, "\n");
902 ShowTimerList(struct cmdargs
const *arg
)
904 timer_Show(0, arg
->prompt
);
909 ShowStopped(struct cmdargs
const *arg
)
911 prompt_Printf(arg
->prompt
, " Stopped Timer: LCP: ");
912 if (!arg
->cx
->physical
->link
.lcp
.fsm
.StoppedTimer
.load
)
913 prompt_Printf(arg
->prompt
, "Disabled");
915 prompt_Printf(arg
->prompt
, "%ld secs",
916 arg
->cx
->physical
->link
.lcp
.fsm
.StoppedTimer
.load
/ SECTICKS
);
918 prompt_Printf(arg
->prompt
, ", CCP: ");
919 if (!arg
->cx
->physical
->link
.ccp
.fsm
.StoppedTimer
.load
)
920 prompt_Printf(arg
->prompt
, "Disabled");
922 prompt_Printf(arg
->prompt
, "%ld secs",
923 arg
->cx
->physical
->link
.ccp
.fsm
.StoppedTimer
.load
/ SECTICKS
);
925 prompt_Printf(arg
->prompt
, "\n");
931 ShowVersion(struct cmdargs
const *arg
)
933 prompt_Printf(arg
->prompt
, "PPP Version %s - %s\n", Version
, __DATE__
);
938 ShowProtocolStats(struct cmdargs
const *arg
)
940 struct link
*l
= command_ChooseLink(arg
);
942 prompt_Printf(arg
->prompt
, "%s:\n", l
->name
);
943 link_ReportProtocolStatus(l
, arg
->prompt
);
947 static struct cmdtab
const ShowCommands
[] = {
948 {"bundle", NULL
, bundle_ShowStatus
, LOCAL_AUTH
,
949 "bundle details", "show bundle", NULL
},
950 {"ccp", NULL
, ccp_ReportStatus
, LOCAL_AUTH
| LOCAL_CX_OPT
,
951 "CCP status", "show cpp", NULL
},
952 {"compress", NULL
, sl_Show
, LOCAL_AUTH
,
953 "VJ compression stats", "show compress", NULL
},
954 {"escape", NULL
, ShowEscape
, LOCAL_AUTH
| LOCAL_CX
,
955 "escape characters", "show escape", NULL
},
956 {"filter", NULL
, filter_Show
, LOCAL_AUTH
,
957 "packet filters", "show filter [in|out|dial|alive]", NULL
},
958 {"hdlc", NULL
, hdlc_ReportStatus
, LOCAL_AUTH
| LOCAL_CX
,
959 "HDLC errors", "show hdlc", NULL
},
960 {"iface", "interface", iface_Show
, LOCAL_AUTH
,
961 "Interface status", "show iface", NULL
},
962 {"ipcp", NULL
, ipcp_Show
, LOCAL_AUTH
,
963 "IPCP status", "show ipcp", NULL
},
965 {"ipv6cp", NULL
, ipv6cp_Show
, LOCAL_AUTH
,
966 "IPV6CP status", "show ipv6cp", NULL
},
968 {"layers", NULL
, link_ShowLayers
, LOCAL_AUTH
| LOCAL_CX_OPT
,
969 "Protocol layers", "show layers", NULL
},
970 {"lcp", NULL
, lcp_ReportStatus
, LOCAL_AUTH
| LOCAL_CX
,
971 "LCP status", "show lcp", NULL
},
972 {"link", "datalink", datalink_Show
, LOCAL_AUTH
| LOCAL_CX
,
973 "(high-level) link info", "show link", NULL
},
974 {"links", NULL
, bundle_ShowLinks
, LOCAL_AUTH
,
975 "available link names", "show links", NULL
},
976 {"log", NULL
, log_ShowLevel
, LOCAL_AUTH
,
977 "log levels", "show log", NULL
},
978 {"mem", NULL
, mbuf_Show
, LOCAL_AUTH
,
979 "mbuf allocations", "show mem", NULL
},
980 {"ncp", NULL
, ncp_Show
, LOCAL_AUTH
,
981 "NCP status", "show ncp", NULL
},
982 {"physical", NULL
, physical_ShowStatus
, LOCAL_AUTH
| LOCAL_CX
,
983 "(low-level) link info", "show physical", NULL
},
984 {"mp", "multilink", mp_ShowStatus
, LOCAL_AUTH
,
985 "multilink setup", "show mp", NULL
},
986 {"proto", NULL
, ShowProtocolStats
, LOCAL_AUTH
| LOCAL_CX_OPT
,
987 "protocol summary", "show proto", NULL
},
988 {"route", NULL
, route_Show
, LOCAL_AUTH
,
989 "routing table", "show route", NULL
},
990 {"stopped", NULL
, ShowStopped
, LOCAL_AUTH
| LOCAL_CX
,
991 "STOPPED timeout", "show stopped", NULL
},
992 {"timers", NULL
, ShowTimerList
, LOCAL_AUTH
,
993 "alarm timers", "show timers", NULL
},
994 {"version", NULL
, ShowVersion
, LOCAL_NO_AUTH
| LOCAL_AUTH
,
995 "version string", "show version", NULL
},
996 {"who", NULL
, log_ShowWho
, LOCAL_AUTH
,
997 "client list", "show who", NULL
},
998 {"help", "?", HelpCommand
, LOCAL_NO_AUTH
| LOCAL_AUTH
,
999 "Display this message", "show help|? [command]", ShowCommands
},
1000 {NULL
, NULL
, NULL
, 0, NULL
, NULL
, NULL
},
1003 static struct cmdtab
const *
1004 FindCommand(struct cmdtab
const *cmds
, const char *str
, int *pmatch
)
1008 struct cmdtab
const *found
;
1013 while (cmds
->func
) {
1014 if (cmds
->name
&& strncasecmp(str
, cmds
->name
, len
) == 0) {
1015 if (cmds
->name
[len
] == '\0') {
1021 } else if (cmds
->alias
&& strncasecmp(str
, cmds
->alias
, len
) == 0) {
1022 if (cmds
->alias
[len
] == '\0') {
1036 mkPrefix(int argc
, char const *const *argv
, char *tgt
, int sz
)
1041 for (f
= 0; f
< argc
&& tlen
< sz
- 2; f
++) {
1044 len
= strlen(argv
[f
]);
1045 if (len
> sz
- tlen
- 1)
1046 len
= sz
- tlen
- 1;
1047 strncpy(tgt
+tlen
, argv
[f
], len
);
1055 FindExec(struct bundle
*bundle
, struct cmdtab
const *cmds
, int argc
, int argn
,
1056 char const *const *argv
, struct prompt
*prompt
, struct datalink
*cx
)
1058 struct cmdtab
const *cmd
;
1064 cmd
= FindCommand(cmds
, argv
[argn
], &nmatch
);
1066 log_Printf(LogWARN
, "%s: Ambiguous command\n",
1067 mkPrefix(argn
+1, argv
, prefix
, sizeof prefix
));
1068 else if (cmd
&& (!prompt
|| (cmd
->lauth
& prompt
->auth
))) {
1069 if ((cmd
->lauth
& LOCAL_CX
) && !cx
)
1070 /* We've got no context, but we require it */
1071 cx
= bundle2datalink(bundle
, NULL
);
1073 if ((cmd
->lauth
& LOCAL_CX
) && !cx
)
1074 log_Printf(LogWARN
, "%s: No context (use the `link' command)\n",
1075 mkPrefix(argn
+1, argv
, prefix
, sizeof prefix
));
1077 if (cx
&& !(cmd
->lauth
& (LOCAL_CX
|LOCAL_CX_OPT
))) {
1078 log_Printf(LogWARN
, "%s: Redundant context (%s) ignored\n",
1079 mkPrefix(argn
+1, argv
, prefix
, sizeof prefix
), cx
->name
);
1087 arg
.bundle
= bundle
;
1089 arg
.prompt
= prompt
;
1090 val
= (*cmd
->func
) (&arg
);
1093 log_Printf(LogWARN
, "%s: Invalid command\n",
1094 mkPrefix(argn
+1, argv
, prefix
, sizeof prefix
));
1097 log_Printf(LogWARN
, "usage: %s\n", cmd
->syntax
);
1099 log_Printf(LogWARN
, "%s: Failed %d\n",
1100 mkPrefix(argn
+1, argv
, prefix
, sizeof prefix
), val
);
1106 command_Expand_Interpret(char *buff
, int nb
, char *argv
[MAXARGS
], int offset
)
1108 char buff2
[LINE_LEN
-offset
];
1110 if (InterpretArg(buff
, buff2
, sizeof buff2
) == NULL
) {
1111 log_Printf(LogWARN
, "Failed to expand command '%s': too long for the "
1112 "destination buffer\n", buff
);
1115 strncpy(buff
, buff2
, LINE_LEN
- offset
- 1);
1116 buff
[LINE_LEN
- offset
- 1] = '\0';
1118 return command_Interpret(buff
, nb
, argv
);
1122 command_Interpret(char *buff
, int nb
, char *argv
[MAXARGS
])
1127 cp
= buff
+ strcspn(buff
, "\r\n");
1130 return MakeArgs(buff
, argv
, MAXARGS
, PARSE_REDUCE
);
1136 arghidden(char const *const *argv
, int n
)
1138 /* Is arg n of the given command to be hidden from the log ? */
1140 /* set authkey xxxxx */
1142 if (n
== 2 && !strncasecmp(argv
[0], "se", 2) &&
1143 (!strncasecmp(argv
[1], "authk", 5) || !strncasecmp(argv
[1], "ke", 2)))
1147 if (n
== 1 && !strncasecmp(argv
[0], "p", 1))
1150 /* set server port xxxxx .... */
1151 if (n
== 3 && !strncasecmp(argv
[0], "se", 2) &&
1152 !strncasecmp(argv
[1], "se", 2))
1159 command_Run(struct bundle
*bundle
, int argc
, char const *const *argv
,
1160 struct prompt
*prompt
, const char *label
, struct datalink
*cx
)
1163 if (log_IsKept(LogCOMMAND
)) {
1169 strncpy(buf
, label
, sizeof buf
- 3);
1170 buf
[sizeof buf
- 3] = '\0';
1177 buf
[sizeof buf
- 1] = '\0'; /* In case we run out of room in buf */
1179 for (f
= 0; f
< argc
; f
++) {
1180 if (n
< sizeof buf
- 1 && f
)
1182 if (arghidden(argv
, f
))
1183 strncpy(buf
+n
, "********", sizeof buf
- n
- 1);
1185 strncpy(buf
+n
, argv
[f
], sizeof buf
- n
- 1);
1188 log_Printf(LogCOMMAND
, "%s\n", buf
);
1190 FindExec(bundle
, Commands
, argc
, 0, argv
, prompt
, cx
);
1195 command_Decode(struct bundle
*bundle
, char *buff
, int nb
, struct prompt
*prompt
,
1199 char *argv
[MAXARGS
];
1201 if ((argc
= command_Expand_Interpret(buff
, nb
, argv
, 0)) < 0)
1204 command_Run(bundle
, argc
, (char const *const *)argv
, prompt
, label
, NULL
);
1209 ShowCommand(struct cmdargs
const *arg
)
1212 log_Printf(LogWARN
, "show: Cannot show without a prompt\n");
1213 else if (arg
->argc
> arg
->argn
)
1214 FindExec(arg
->bundle
, ShowCommands
, arg
->argc
, arg
->argn
, arg
->argv
,
1215 arg
->prompt
, arg
->cx
);
1217 prompt_Printf(arg
->prompt
, "Use ``show ?'' to get a list.\n");
1223 TerminalCommand(struct cmdargs
const *arg
)
1226 log_Printf(LogWARN
, "term: Need a prompt\n");
1230 if (arg
->cx
->physical
->link
.lcp
.fsm
.state
> ST_CLOSED
) {
1231 prompt_Printf(arg
->prompt
, "LCP state is [%s]\n",
1232 State2Nam(arg
->cx
->physical
->link
.lcp
.fsm
.state
));
1236 datalink_Up(arg
->cx
, 0, 0);
1237 prompt_TtyTermMode(arg
->prompt
, arg
->cx
);
1242 QuitCommand(struct cmdargs
const *arg
)
1244 if (!arg
->prompt
|| prompt_IsController(arg
->prompt
) ||
1245 (arg
->argc
> arg
->argn
&& !strcasecmp(arg
->argv
[arg
->argn
], "all") &&
1246 (arg
->prompt
->auth
& LOCAL_AUTH
)))
1249 prompt_Destroy(arg
->prompt
, 1);
1255 OpenCommand(struct cmdargs
const *arg
)
1257 if (arg
->argc
== arg
->argn
)
1258 bundle_Open(arg
->bundle
, arg
->cx
? arg
->cx
->name
: NULL
, PHYS_ALL
, 1);
1259 else if (arg
->argc
== arg
->argn
+ 1) {
1260 if (!strcasecmp(arg
->argv
[arg
->argn
], "lcp")) {
1261 struct datalink
*cx
= arg
->cx
?
1262 arg
->cx
: bundle2datalink(arg
->bundle
, NULL
);
1264 if (cx
->physical
->link
.lcp
.fsm
.state
== ST_OPENED
)
1265 fsm_Reopen(&cx
->physical
->link
.lcp
.fsm
);
1267 bundle_Open(arg
->bundle
, cx
->name
, PHYS_ALL
, 1);
1269 log_Printf(LogWARN
, "open lcp: You must specify a link\n");
1270 } else if (!strcasecmp(arg
->argv
[arg
->argn
], "ccp")) {
1273 fp
= &command_ChooseLink(arg
)->ccp
.fsm
;
1274 if (fp
->link
->lcp
.fsm
.state
!= ST_OPENED
)
1275 log_Printf(LogWARN
, "open: LCP must be open before opening CCP\n");
1276 else if (fp
->state
== ST_OPENED
)
1279 fp
->open_mode
= 0; /* Not passive any more */
1280 if (fp
->state
== ST_STOPPED
) {
1288 } else if (!strcasecmp(arg
->argv
[arg
->argn
], "ipcp")) {
1290 log_Printf(LogWARN
, "open ipcp: You need not specify a link\n");
1291 if (arg
->bundle
->ncp
.ipcp
.fsm
.state
== ST_OPENED
)
1292 fsm_Reopen(&arg
->bundle
->ncp
.ipcp
.fsm
);
1294 bundle_Open(arg
->bundle
, NULL
, PHYS_ALL
, 1);
1304 CloseCommand(struct cmdargs
const *arg
)
1306 if (arg
->argc
== arg
->argn
)
1307 bundle_Close(arg
->bundle
, arg
->cx
? arg
->cx
->name
: NULL
, CLOSE_STAYDOWN
);
1308 else if (arg
->argc
== arg
->argn
+ 1) {
1309 if (!strcasecmp(arg
->argv
[arg
->argn
], "lcp"))
1310 bundle_Close(arg
->bundle
, arg
->cx
? arg
->cx
->name
: NULL
, CLOSE_LCP
);
1311 else if (!strcasecmp(arg
->argv
[arg
->argn
], "ccp") ||
1312 !strcasecmp(arg
->argv
[arg
->argn
], "ccp!")) {
1315 fp
= &command_ChooseLink(arg
)->ccp
.fsm
;
1316 if (fp
->state
== ST_OPENED
) {
1318 if (arg
->argv
[arg
->argn
][3] == '!')
1319 fp
->open_mode
= 0; /* Stay ST_CLOSED */
1321 fp
->open_mode
= OPEN_PASSIVE
; /* Wait for the peer to start */
1332 DownCommand(struct cmdargs
const *arg
)
1334 if (arg
->argc
== arg
->argn
) {
1336 datalink_Down(arg
->cx
, CLOSE_STAYDOWN
);
1338 bundle_Down(arg
->bundle
, CLOSE_STAYDOWN
);
1339 } else if (arg
->argc
== arg
->argn
+ 1) {
1340 if (!strcasecmp(arg
->argv
[arg
->argn
], "lcp")) {
1342 datalink_Down(arg
->cx
, CLOSE_LCP
);
1344 bundle_Down(arg
->bundle
, CLOSE_LCP
);
1345 } else if (!strcasecmp(arg
->argv
[arg
->argn
], "ccp")) {
1346 struct fsm
*fp
= arg
->cx
? &arg
->cx
->physical
->link
.ccp
.fsm
:
1347 &arg
->bundle
->ncp
.mp
.link
.ccp
.fsm
;
1358 SetModemSpeed(struct cmdargs
const *arg
)
1363 if (arg
->argc
> arg
->argn
&& *arg
->argv
[arg
->argn
]) {
1364 if (arg
->argc
> arg
->argn
+1) {
1365 log_Printf(LogWARN
, "SetModemSpeed: Too many arguments\n");
1368 if (strcasecmp(arg
->argv
[arg
->argn
], "sync") == 0) {
1369 physical_SetSync(arg
->cx
->physical
);
1373 speed
= strtol(arg
->argv
[arg
->argn
], &end
, 10);
1374 if (*end
|| speed
< 0) {
1375 log_Printf(LogWARN
, "SetModemSpeed: Bad argument \"%s\"",
1376 arg
->argv
[arg
->argn
]);
1379 if (physical_SetSpeed(arg
->cx
->physical
, speed
))
1381 log_Printf(LogWARN
, "%s: Invalid speed\n", arg
->argv
[arg
->argn
]);
1383 log_Printf(LogWARN
, "SetModemSpeed: No speed specified\n");
1389 SetStoppedTimeout(struct cmdargs
const *arg
)
1391 struct link
*l
= &arg
->cx
->physical
->link
;
1393 l
->lcp
.fsm
.StoppedTimer
.load
= 0;
1394 l
->ccp
.fsm
.StoppedTimer
.load
= 0;
1395 if (arg
->argc
<= arg
->argn
+2) {
1396 if (arg
->argc
> arg
->argn
) {
1397 l
->lcp
.fsm
.StoppedTimer
.load
= atoi(arg
->argv
[arg
->argn
]) * SECTICKS
;
1398 if (arg
->argc
> arg
->argn
+1)
1399 l
->ccp
.fsm
.StoppedTimer
.load
= atoi(arg
->argv
[arg
->argn
+1]) * SECTICKS
;
1407 SetServer(struct cmdargs
const *arg
)
1411 if (arg
->argc
> arg
->argn
&& arg
->argc
< arg
->argn
+4) {
1412 const char *port
, *passwd
, *mask
;
1416 port
= arg
->argv
[arg
->argn
];
1417 if (arg
->argc
== arg
->argn
+ 2) {
1418 passwd
= arg
->argv
[arg
->argn
+1];
1420 } else if (arg
->argc
== arg
->argn
+ 3) {
1421 passwd
= arg
->argv
[arg
->argn
+1];
1422 mask
= arg
->argv
[arg
->argn
+2];
1423 mlen
= strlen(mask
);
1424 if (mlen
== 0 || mlen
> 4 || strspn(mask
, "01234567") != mlen
||
1425 (mlen
== 4 && *mask
!= '0')) {
1426 log_Printf(LogWARN
, "%s %s: %s: Invalid mask\n",
1427 arg
->argv
[arg
->argn
- 2], arg
->argv
[arg
->argn
- 1], mask
);
1430 } else if (arg
->argc
!= arg
->argn
+ 1)
1432 else if (strcasecmp(port
, "none") == 0) {
1433 if (server_Clear(arg
->bundle
))
1434 log_Printf(LogPHASE
, "Disabled server socket\n");
1436 } else if (strcasecmp(port
, "open") == 0) {
1437 switch (server_Reopen(arg
->bundle
)) {
1441 log_Printf(LogWARN
, "Failed to reopen server port\n");
1444 log_Printf(LogWARN
, "Cannot reopen unset server socket\n");
1450 } else if (strcasecmp(port
, "closed") == 0) {
1451 if (server_Close(arg
->bundle
))
1452 log_Printf(LogPHASE
, "Closed server socket\n");
1454 log_Printf(LogWARN
, "Server socket not open\n");
1460 strncpy(server
.cfg
.passwd
, passwd
, sizeof server
.cfg
.passwd
- 1);
1461 server
.cfg
.passwd
[sizeof server
.cfg
.passwd
- 1] = '\0';
1465 char *ptr
, name
[LINE_LEN
+ 12];
1469 else for (imask
= mlen
= 0; mask
[mlen
]; mlen
++)
1470 imask
= (imask
* 8) + mask
[mlen
] - '0';
1472 ptr
= strstr(port
, "%d");
1474 snprintf(name
, sizeof name
, "%.*s%d%s",
1475 (int)(ptr
- port
), port
, arg
->bundle
->unit
, ptr
+ 2);
1478 res
= server_LocalOpen(arg
->bundle
, port
, imask
);
1489 if (strspn(port
, "0123456789") != strlen(port
)) {
1492 if ((s
= getservbyname(port
, "tcp")) == NULL
) {
1494 log_Printf(LogWARN
, "%s: Invalid port or service\n", port
);
1496 iport
= ntohs(s
->s_port
);
1502 iport
+= arg
->bundle
->unit
;
1503 res
= server_TcpOpen(arg
->bundle
, iport
);
1513 SetEscape(struct cmdargs
const *arg
)
1516 int argc
= arg
->argc
- arg
->argn
;
1517 char const *const *argv
= arg
->argv
+ arg
->argn
;
1519 for (code
= 0; code
< 33; code
++)
1520 arg
->cx
->physical
->async
.cfg
.EscMap
[code
] = 0;
1522 while (argc
-- > 0) {
1523 sscanf(*argv
++, "%x", &code
);
1525 arg
->cx
->physical
->async
.cfg
.EscMap
[code
>> 3] |= (1 << (code
& 7));
1526 arg
->cx
->physical
->async
.cfg
.EscMap
[32] = 1;
1532 SetInterfaceAddr(struct cmdargs
const *arg
)
1534 struct ncp
*ncp
= &arg
->bundle
->ncp
;
1535 struct ncpaddr ncpaddr
;
1536 const char *hisaddr
;
1538 if (arg
->argc
> arg
->argn
+ 4)
1542 memset(&ncp
->ipcp
.cfg
.my_range
, '\0', sizeof ncp
->ipcp
.cfg
.my_range
);
1543 memset(&ncp
->ipcp
.cfg
.peer_range
, '\0', sizeof ncp
->ipcp
.cfg
.peer_range
);
1544 ncp
->ipcp
.cfg
.HaveTriggerAddress
= 0;
1545 ncp
->ipcp
.cfg
.netmask
.s_addr
= INADDR_ANY
;
1546 iplist_reset(&ncp
->ipcp
.cfg
.peer_list
);
1548 if (arg
->argc
> arg
->argn
) {
1549 if (!ncprange_aton(&ncp
->ipcp
.cfg
.my_range
, ncp
, arg
->argv
[arg
->argn
]))
1551 if (arg
->argc
> arg
->argn
+1) {
1552 hisaddr
= arg
->argv
[arg
->argn
+1];
1553 if (arg
->argc
> arg
->argn
+2) {
1554 ncp
->ipcp
.ifmask
= ncp
->ipcp
.cfg
.netmask
=
1555 GetIpAddr(arg
->argv
[arg
->argn
+2]);
1556 if (arg
->argc
> arg
->argn
+3) {
1557 ncp
->ipcp
.cfg
.TriggerAddress
= GetIpAddr(arg
->argv
[arg
->argn
+3]);
1558 ncp
->ipcp
.cfg
.HaveTriggerAddress
= 1;
1564 /* 0.0.0.0 means any address (0 bits) */
1565 ncpaddr_getip4(&ncpaddr
, &ncp
->ipcp
.my_ip
);
1566 ncprange_getaddr(&ncp
->ipcp
.cfg
.my_range
, &ncpaddr
);
1567 if (ncp
->ipcp
.my_ip
.s_addr
== INADDR_ANY
)
1568 ncprange_setwidth(&ncp
->ipcp
.cfg
.my_range
, 0);
1569 bundle_AdjustFilters(arg
->bundle
, &ncpaddr
, NULL
);
1571 if (hisaddr
&& !ipcp_UseHisaddr(arg
->bundle
, hisaddr
,
1572 arg
->bundle
->phys_type
.all
& PHYS_AUTO
))
1579 SetRetry(int argc
, char const *const *argv
, u_int
*timeout
, u_int
*maxreq
,
1580 u_int
*maxtrm
, int def
)
1583 *timeout
= DEF_FSMRETRY
;
1588 long l
= atol(argv
[0]);
1590 if (l
< MIN_FSMRETRY
) {
1591 log_Printf(LogWARN
, "%ld: Invalid FSM retry period - min %d\n",
1600 log_Printf(LogWARN
, "%ld: Invalid FSM REQ tries - changed to 1\n", l
);
1605 if (argc
> 2 && maxtrm
!= NULL
) {
1608 log_Printf(LogWARN
, "%ld: Invalid FSM TRM tries - changed to 1\n", l
);
1620 SetVariable(struct cmdargs
const *arg
)
1622 long long_val
, param
= (long)arg
->cmd
->args
;
1623 int mode
, dummyint
, f
, first
, res
;
1626 struct datalink
*cx
= arg
->cx
; /* LOCAL_CX uses this */
1627 struct link
*l
= command_ChooseLink(arg
); /* LOCAL_CX_OPT uses this */
1628 struct in_addr
*ipaddr
;
1629 struct ncpaddr ncpaddr
[2];
1631 if (arg
->argc
> arg
->argn
)
1632 argp
= arg
->argv
[arg
->argn
];
1638 if ((arg
->cmd
->lauth
& LOCAL_CX
) && !cx
) {
1639 log_Printf(LogWARN
, "set %s: No context (use the `link' command)\n",
1642 } else if (cx
&& !(arg
->cmd
->lauth
& (LOCAL_CX
|LOCAL_CX_OPT
))) {
1643 log_Printf(LogWARN
, "set %s: Redundant context (%s) ignored\n",
1644 arg
->cmd
->name
, cx
->name
);
1650 strncpy(arg
->bundle
->cfg
.auth
.key
, argp
,
1651 sizeof arg
->bundle
->cfg
.auth
.key
- 1);
1652 arg
->bundle
->cfg
.auth
.key
[sizeof arg
->bundle
->cfg
.auth
.key
- 1] = '\0';
1656 switch (bundle_Phase(arg
->bundle
)) {
1658 log_Printf(LogWARN
, "Altering authname while at phase %s\n",
1659 bundle_PhaseName(arg
->bundle
));
1662 case PHASE_ESTABLISH
:
1663 strncpy(arg
->bundle
->cfg
.auth
.name
, argp
,
1664 sizeof arg
->bundle
->cfg
.auth
.name
- 1);
1665 arg
->bundle
->cfg
.auth
.name
[sizeof arg
->bundle
->cfg
.auth
.name
-1] = '\0';
1671 if (arg
->argc
== arg
->argn
+ 3) {
1675 v1
= strtol(arg
->argv
[arg
->argn
], &end
, 0);
1676 if (v1
< 0 || *end
) {
1677 log_Printf(LogWARN
, "autoload: %s: Invalid min percentage\n",
1678 arg
->argv
[arg
->argn
]);
1683 v2
= strtol(arg
->argv
[arg
->argn
+ 1], &end
, 0);
1684 if (v2
< 0 || *end
) {
1685 log_Printf(LogWARN
, "autoload: %s: Invalid max percentage\n",
1686 arg
->argv
[arg
->argn
+ 1]);
1696 v3
= strtol(arg
->argv
[arg
->argn
+ 2], &end
, 0);
1697 if (v3
<= 0 || *end
) {
1698 log_Printf(LogWARN
, "autoload: %s: Invalid throughput period\n",
1699 arg
->argv
[arg
->argn
+ 2]);
1704 arg
->bundle
->ncp
.mp
.cfg
.autoload
.min
= v1
;
1705 arg
->bundle
->ncp
.mp
.cfg
.autoload
.max
= v2
;
1706 arg
->bundle
->ncp
.mp
.cfg
.autoload
.period
= v3
;
1707 mp_RestartAutoloadTimer(&arg
->bundle
->ncp
.mp
);
1709 log_Printf(LogWARN
, "Set autoload requires three arguments\n");
1715 strncpy(cx
->cfg
.script
.dial
, argp
, sizeof cx
->cfg
.script
.dial
- 1);
1716 cx
->cfg
.script
.dial
[sizeof cx
->cfg
.script
.dial
- 1] = '\0';
1720 strncpy(cx
->cfg
.script
.login
, argp
, sizeof cx
->cfg
.script
.login
- 1);
1721 cx
->cfg
.script
.login
[sizeof cx
->cfg
.script
.login
- 1] = '\0';
1725 if (arg
->argc
> arg
->argn
) {
1726 l
->ccp
.cfg
.deflate
.out
.winsize
= atoi(arg
->argv
[arg
->argn
]);
1727 if (l
->ccp
.cfg
.deflate
.out
.winsize
< 8 ||
1728 l
->ccp
.cfg
.deflate
.out
.winsize
> 15) {
1729 log_Printf(LogWARN
, "%d: Invalid outgoing window size\n",
1730 l
->ccp
.cfg
.deflate
.out
.winsize
);
1731 l
->ccp
.cfg
.deflate
.out
.winsize
= 15;
1733 if (arg
->argc
> arg
->argn
+1) {
1734 l
->ccp
.cfg
.deflate
.in
.winsize
= atoi(arg
->argv
[arg
->argn
+1]);
1735 if (l
->ccp
.cfg
.deflate
.in
.winsize
< 8 ||
1736 l
->ccp
.cfg
.deflate
.in
.winsize
> 15) {
1737 log_Printf(LogWARN
, "%d: Invalid incoming window size\n",
1738 l
->ccp
.cfg
.deflate
.in
.winsize
);
1739 l
->ccp
.cfg
.deflate
.in
.winsize
= 15;
1742 l
->ccp
.cfg
.deflate
.in
.winsize
= 0;
1744 log_Printf(LogWARN
, "No window size specified\n");
1751 if (arg
->argc
> arg
->argn
+ 2) {
1756 if (arg
->argc
== arg
->argn
) {
1757 l
->ccp
.cfg
.mppe
.keybits
= 0;
1758 l
->ccp
.cfg
.mppe
.state
= MPPE_ANYSTATE
;
1759 l
->ccp
.cfg
.mppe
.required
= 0;
1763 if (!strcmp(argp
, "*"))
1766 long_val
= atol(argp
);
1767 if (long_val
!= 40 && long_val
!= 56 && long_val
!= 128) {
1768 log_Printf(LogWARN
, "%s: Invalid bits value\n", argp
);
1774 if (arg
->argc
== arg
->argn
+ 2) {
1775 if (!strcmp(arg
->argv
[arg
->argn
+ 1], "*"))
1776 l
->ccp
.cfg
.mppe
.state
= MPPE_ANYSTATE
;
1777 else if (!strcasecmp(arg
->argv
[arg
->argn
+ 1], "stateless"))
1778 l
->ccp
.cfg
.mppe
.state
= MPPE_STATELESS
;
1779 else if (!strcasecmp(arg
->argv
[arg
->argn
+ 1], "stateful"))
1780 l
->ccp
.cfg
.mppe
.state
= MPPE_STATEFUL
;
1782 log_Printf(LogWARN
, "%s: Invalid state value\n",
1783 arg
->argv
[arg
->argn
+ 1]);
1788 l
->ccp
.cfg
.mppe
.state
= MPPE_ANYSTATE
;
1789 l
->ccp
.cfg
.mppe
.keybits
= long_val
;
1790 l
->ccp
.cfg
.mppe
.required
= 1;
1795 physical_SetDeviceList(cx
->physical
, arg
->argc
- arg
->argn
,
1796 arg
->argv
+ arg
->argn
);
1800 if (arg
->argc
> arg
->argn
) {
1802 sscanf(argp
, "%lx", &ulong_val
);
1803 cx
->physical
->link
.lcp
.cfg
.accmap
= (u_int32_t
)ulong_val
;
1805 log_Printf(LogWARN
, "No accmap specified\n");
1811 mode
= Nam2mode(argp
);
1812 if (mode
== PHYS_NONE
|| mode
== PHYS_ALL
) {
1813 log_Printf(LogWARN
, "%s: Invalid mode\n", argp
);
1817 bundle_SetMode(arg
->bundle
, cx
, mode
);
1821 switch (bundle_Phase(arg
->bundle
)) {
1824 case PHASE_ESTABLISH
:
1825 /* Make sure none of our links are DATALINK_LCP or greater */
1826 if (bundle_HighestState(arg
->bundle
) >= DATALINK_LCP
) {
1827 log_Printf(LogWARN
, "mrru: Only changeable before LCP negotiations\n");
1833 log_Printf(LogWARN
, "mrru: Only changeable at phase DEAD/ESTABLISH\n");
1839 long_val
= atol(argp
);
1840 if (long_val
&& long_val
< MIN_MRU
) {
1841 log_Printf(LogWARN
, "MRRU %ld: too small - min %d\n", long_val
, MIN_MRU
);
1844 } else if (long_val
> MAX_MRU
) {
1845 log_Printf(LogWARN
, "MRRU %ld: too big - max %d\n", long_val
, MAX_MRU
);
1849 arg
->bundle
->ncp
.mp
.cfg
.mrru
= long_val
;
1853 long_val
= 0; /* silence gcc */
1854 change
= NULL
; /* silence gcc */
1855 switch(arg
->argc
- arg
->argn
) {
1857 if (argp
[strspn(argp
, "0123456789")] != '\0') {
1863 long_val
= atol(argp
);
1864 change
= &l
->lcp
.cfg
.mru
;
1865 if (long_val
> l
->lcp
.cfg
.max_mru
) {
1866 log_Printf(LogWARN
, "MRU %ld: too large - max set to %d\n", long_val
,
1867 l
->lcp
.cfg
.max_mru
);
1873 if (strcasecmp(argp
, "max") && strcasecmp(argp
, "maximum")) {
1877 long_val
= atol(arg
->argv
[arg
->argn
+ 1]);
1878 change
= &l
->lcp
.cfg
.max_mru
;
1879 if (long_val
> MAX_MRU
) {
1880 log_Printf(LogWARN
, "MRU %ld: too large - maximum is %d\n", long_val
,
1895 else if (long_val
< MIN_MRU
) {
1896 log_Printf(LogWARN
, "MRU %ld: too small - min %d\n", long_val
, MIN_MRU
);
1899 } else if (long_val
> MAX_MRU
) {
1900 log_Printf(LogWARN
, "MRU %ld: too big - max %d\n", long_val
, MAX_MRU
);
1905 if (l
->lcp
.cfg
.mru
> *change
)
1906 l
->lcp
.cfg
.mru
= *change
;
1910 long_val
= 0; /* silence gcc */
1911 change
= NULL
; /* silence gcc */
1912 switch(arg
->argc
- arg
->argn
) {
1914 if (argp
[strspn(argp
, "0123456789")] != '\0') {
1920 long_val
= atol(argp
);
1921 change
= &l
->lcp
.cfg
.mtu
;
1922 if (long_val
> l
->lcp
.cfg
.max_mtu
) {
1923 log_Printf(LogWARN
, "MTU %ld: too large - max set to %d\n", long_val
,
1924 l
->lcp
.cfg
.max_mtu
);
1930 if (strcasecmp(argp
, "max") && strcasecmp(argp
, "maximum")) {
1934 long_val
= atol(arg
->argv
[arg
->argn
+ 1]);
1935 change
= &l
->lcp
.cfg
.max_mtu
;
1936 if (long_val
> MAX_MTU
) {
1937 log_Printf(LogWARN
, "MTU %ld: too large - maximum is %d\n", long_val
,
1951 if (long_val
&& long_val
< MIN_MTU
) {
1952 log_Printf(LogWARN
, "MTU %ld: too small - min %d\n", long_val
, MIN_MTU
);
1955 } else if (long_val
> MAX_MTU
) {
1956 log_Printf(LogWARN
, "MTU %ld: too big - max %d\n", long_val
, MAX_MTU
);
1961 if (l
->lcp
.cfg
.mtu
> *change
)
1962 l
->lcp
.cfg
.mtu
= *change
;
1966 if (strcasecmp(argp
, "active") == 0)
1967 cx
->physical
->link
.lcp
.cfg
.openmode
= arg
->argc
> arg
->argn
+1 ?
1968 atoi(arg
->argv
[arg
->argn
+1]) : 1;
1969 else if (strcasecmp(argp
, "passive") == 0)
1970 cx
->physical
->link
.lcp
.cfg
.openmode
= OPEN_PASSIVE
;
1972 log_Printf(LogWARN
, "%s: Invalid openmode\n", argp
);
1978 strncpy(cx
->cfg
.phone
.list
, argp
, sizeof cx
->cfg
.phone
.list
- 1);
1979 cx
->cfg
.phone
.list
[sizeof cx
->cfg
.phone
.list
- 1] = '\0';
1980 cx
->phone
.alt
= cx
->phone
.next
= NULL
;
1984 strncpy(cx
->cfg
.script
.hangup
, argp
, sizeof cx
->cfg
.script
.hangup
- 1);
1985 cx
->cfg
.script
.hangup
[sizeof cx
->cfg
.script
.hangup
- 1] = '\0';
1989 long_val
= atol(argp
);
1990 arg
->bundle
->cfg
.ifqueue
= long_val
< 0 ? 0 : long_val
;
1994 strncpy(cx
->cfg
.script
.logout
, argp
, sizeof cx
->cfg
.script
.logout
- 1);
1995 cx
->cfg
.script
.logout
[sizeof cx
->cfg
.script
.logout
- 1] = '\0';
1998 case VAR_IDLETIMEOUT
:
1999 if (arg
->argc
> arg
->argn
+2) {
2000 log_Printf(LogWARN
, "Too many idle timeout values\n");
2002 } else if (arg
->argc
== arg
->argn
) {
2003 log_Printf(LogWARN
, "Too few idle timeout values\n");
2006 unsigned long timeout
, min
;
2008 timeout
= strtoul(argp
, NULL
, 10);
2009 min
= arg
->bundle
->cfg
.idle
.min_timeout
;
2010 if (arg
->argc
== arg
->argn
+ 2)
2011 min
= strtoul(arg
->argv
[arg
->argn
+ 1], NULL
, 10);
2012 bundle_SetIdleTimer(arg
->bundle
, timeout
, min
);
2017 long_val
= atol(argp
);
2018 if (long_val
< MIN_LQRPERIOD
) {
2019 log_Printf(LogWARN
, "%ld: Invalid lqr period - min %d\n",
2020 long_val
, MIN_LQRPERIOD
);
2023 l
->lcp
.cfg
.lqrperiod
= long_val
;
2027 res
= SetRetry(arg
->argc
- arg
->argn
, arg
->argv
+ arg
->argn
,
2028 &cx
->physical
->link
.lcp
.cfg
.fsm
.timeout
,
2029 &cx
->physical
->link
.lcp
.cfg
.fsm
.maxreq
,
2030 &cx
->physical
->link
.lcp
.cfg
.fsm
.maxtrm
, DEF_FSMTRIES
);
2034 res
= SetRetry(arg
->argc
- arg
->argn
, arg
->argv
+ arg
->argn
,
2035 &cx
->chap
.auth
.cfg
.fsm
.timeout
,
2036 &cx
->chap
.auth
.cfg
.fsm
.maxreq
, NULL
, DEF_FSMAUTHTRIES
);
2040 res
= SetRetry(arg
->argc
- arg
->argn
, arg
->argv
+ arg
->argn
,
2041 &cx
->pap
.cfg
.fsm
.timeout
, &cx
->pap
.cfg
.fsm
.maxreq
,
2042 NULL
, DEF_FSMAUTHTRIES
);
2046 res
= SetRetry(arg
->argc
- arg
->argn
, arg
->argv
+ arg
->argn
,
2047 &l
->ccp
.cfg
.fsm
.timeout
, &l
->ccp
.cfg
.fsm
.maxreq
,
2048 &l
->ccp
.cfg
.fsm
.maxtrm
, DEF_FSMTRIES
);
2052 res
= SetRetry(arg
->argc
- arg
->argn
, arg
->argv
+ arg
->argn
,
2053 &arg
->bundle
->ncp
.ipcp
.cfg
.fsm
.timeout
,
2054 &arg
->bundle
->ncp
.ipcp
.cfg
.fsm
.maxreq
,
2055 &arg
->bundle
->ncp
.ipcp
.cfg
.fsm
.maxtrm
, DEF_FSMTRIES
);
2059 case VAR_IPV6CPRETRY
:
2060 res
= SetRetry(arg
->argc
- arg
->argn
, arg
->argv
+ arg
->argn
,
2061 &arg
->bundle
->ncp
.ipv6cp
.cfg
.fsm
.timeout
,
2062 &arg
->bundle
->ncp
.ipv6cp
.cfg
.fsm
.maxreq
,
2063 &arg
->bundle
->ncp
.ipv6cp
.cfg
.fsm
.maxtrm
, DEF_FSMTRIES
);
2069 if (param
== VAR_DNS
) {
2070 ipaddr
= arg
->bundle
->ncp
.ipcp
.cfg
.ns
.dns
;
2071 ipaddr
[0].s_addr
= ipaddr
[1].s_addr
= INADDR_NONE
;
2073 ipaddr
= arg
->bundle
->ncp
.ipcp
.cfg
.ns
.nbns
;
2074 ipaddr
[0].s_addr
= ipaddr
[1].s_addr
= INADDR_ANY
;
2077 if (arg
->argc
> arg
->argn
) {
2078 ncpaddr_aton(ncpaddr
, &arg
->bundle
->ncp
, arg
->argv
[arg
->argn
]);
2079 if (!ncpaddr_getip4(ncpaddr
, ipaddr
))
2081 if (arg
->argc
> arg
->argn
+1) {
2082 ncpaddr_aton(ncpaddr
+ 1, &arg
->bundle
->ncp
, arg
->argv
[arg
->argn
+ 1]);
2083 if (!ncpaddr_getip4(ncpaddr
+ 1, ipaddr
+ 1))
2087 if (ipaddr
[0].s_addr
== INADDR_ANY
) {
2088 ipaddr
[0] = ipaddr
[1];
2089 ipaddr
[1].s_addr
= INADDR_ANY
;
2091 if (ipaddr
[0].s_addr
== INADDR_NONE
) {
2092 ipaddr
[0] = ipaddr
[1];
2093 ipaddr
[1].s_addr
= INADDR_NONE
;
2099 cx
->cfg
.callback
.opmask
= 0;
2100 for (dummyint
= arg
->argn
; dummyint
< arg
->argc
; dummyint
++) {
2101 if (!strcasecmp(arg
->argv
[dummyint
], "auth"))
2102 cx
->cfg
.callback
.opmask
|= CALLBACK_BIT(CALLBACK_AUTH
);
2103 else if (!strcasecmp(arg
->argv
[dummyint
], "cbcp"))
2104 cx
->cfg
.callback
.opmask
|= CALLBACK_BIT(CALLBACK_CBCP
);
2105 else if (!strcasecmp(arg
->argv
[dummyint
], "e.164")) {
2106 if (dummyint
== arg
->argc
- 1)
2107 log_Printf(LogWARN
, "No E.164 arg (E.164 ignored) !\n");
2109 cx
->cfg
.callback
.opmask
|= CALLBACK_BIT(CALLBACK_E164
);
2110 strncpy(cx
->cfg
.callback
.msg
, arg
->argv
[++dummyint
],
2111 sizeof cx
->cfg
.callback
.msg
- 1);
2112 cx
->cfg
.callback
.msg
[sizeof cx
->cfg
.callback
.msg
- 1] = '\0';
2114 } else if (!strcasecmp(arg
->argv
[dummyint
], "none"))
2115 cx
->cfg
.callback
.opmask
|= CALLBACK_BIT(CALLBACK_NONE
);
2121 if (cx
->cfg
.callback
.opmask
== CALLBACK_BIT(CALLBACK_NONE
))
2122 cx
->cfg
.callback
.opmask
= 0;
2126 cx
->cfg
.cbcp
.delay
= 0;
2127 *cx
->cfg
.cbcp
.phone
= '\0';
2128 cx
->cfg
.cbcp
.fsmretry
= DEF_FSMRETRY
;
2129 if (arg
->argc
> arg
->argn
) {
2130 strncpy(cx
->cfg
.cbcp
.phone
, arg
->argv
[arg
->argn
],
2131 sizeof cx
->cfg
.cbcp
.phone
- 1);
2132 cx
->cfg
.cbcp
.phone
[sizeof cx
->cfg
.cbcp
.phone
- 1] = '\0';
2133 if (arg
->argc
> arg
->argn
+ 1) {
2134 cx
->cfg
.cbcp
.delay
= atoi(arg
->argv
[arg
->argn
+ 1]);
2135 if (arg
->argc
> arg
->argn
+ 2) {
2136 long_val
= atol(arg
->argv
[arg
->argn
+ 2]);
2137 if (long_val
< MIN_FSMRETRY
)
2138 log_Printf(LogWARN
, "%ld: Invalid CBCP FSM retry period - min %d\n",
2139 long_val
, MIN_FSMRETRY
);
2141 cx
->cfg
.cbcp
.fsmretry
= long_val
;
2148 arg
->bundle
->cfg
.choked
.timeout
= atoi(argp
);
2149 if (arg
->bundle
->cfg
.choked
.timeout
<= 0)
2150 arg
->bundle
->cfg
.choked
.timeout
= CHOKED_TIMEOUT
;
2154 long_val
= atol(argp
);
2155 arg
->bundle
->ncp
.cfg
.sendpipe
= long_val
;
2159 long_val
= atol(argp
);
2160 arg
->bundle
->ncp
.cfg
.recvpipe
= long_val
;
2166 *arg
->bundle
->radius
.cfg
.file
= '\0';
2167 else if (access(argp
, R_OK
)) {
2168 log_Printf(LogWARN
, "%s: %s\n", argp
, strerror(errno
));
2172 strncpy(arg
->bundle
->radius
.cfg
.file
, argp
,
2173 sizeof arg
->bundle
->radius
.cfg
.file
- 1);
2174 arg
->bundle
->radius
.cfg
.file
2175 [sizeof arg
->bundle
->radius
.cfg
.file
- 1] = '\0';
2182 if (strcasecmp(argp
, "off")) {
2183 long_val
= atol(argp
);
2186 cx
->physical
->cfg
.cd
.delay
= long_val
;
2187 cx
->physical
->cfg
.cd
.necessity
= argp
[strlen(argp
)-1] == '!' ?
2188 CD_REQUIRED
: CD_VARIABLE
;
2190 cx
->physical
->cfg
.cd
.necessity
= CD_NOTREQUIRED
;
2192 cx
->physical
->cfg
.cd
.delay
= 0;
2193 cx
->physical
->cfg
.cd
.necessity
= CD_DEFAULT
;
2198 if (arg
->argc
== arg
->argn
+ 1)
2199 res
= physical_SetParity(arg
->cx
->physical
, argp
);
2201 log_Printf(LogWARN
, "Parity value must be odd, even or none\n");
2207 if (strcasecmp(argp
, "on") == 0)
2208 physical_SetRtsCts(arg
->cx
->physical
, 1);
2209 else if (strcasecmp(argp
, "off") == 0)
2210 physical_SetRtsCts(arg
->cx
->physical
, 0);
2212 log_Printf(LogWARN
, "RTS/CTS value must be on or off\n");
2217 case VAR_URGENTPORTS
:
2218 if (arg
->argn
== arg
->argc
) {
2219 ncp_SetUrgentTOS(&arg
->bundle
->ncp
);
2220 ncp_ClearUrgentTcpPorts(&arg
->bundle
->ncp
);
2221 ncp_ClearUrgentUdpPorts(&arg
->bundle
->ncp
);
2222 } else if (!strcasecmp(arg
->argv
[arg
->argn
], "udp")) {
2223 ncp_SetUrgentTOS(&arg
->bundle
->ncp
);
2224 if (arg
->argn
== arg
->argc
- 1)
2225 ncp_ClearUrgentUdpPorts(&arg
->bundle
->ncp
);
2226 else for (f
= arg
->argn
+ 1; f
< arg
->argc
; f
++)
2227 if (*arg
->argv
[f
] == '+')
2228 ncp_AddUrgentUdpPort(&arg
->bundle
->ncp
, atoi(arg
->argv
[f
] + 1));
2229 else if (*arg
->argv
[f
] == '-')
2230 ncp_RemoveUrgentUdpPort(&arg
->bundle
->ncp
, atoi(arg
->argv
[f
] + 1));
2233 ncp_ClearUrgentUdpPorts(&arg
->bundle
->ncp
);
2234 ncp_AddUrgentUdpPort(&arg
->bundle
->ncp
, atoi(arg
->argv
[f
]));
2236 } else if (arg
->argn
== arg
->argc
- 1 &&
2237 !strcasecmp(arg
->argv
[arg
->argn
], "none")) {
2238 ncp_ClearUrgentTcpPorts(&arg
->bundle
->ncp
);
2239 ncp_ClearUrgentUdpPorts(&arg
->bundle
->ncp
);
2240 ncp_ClearUrgentTOS(&arg
->bundle
->ncp
);
2242 ncp_SetUrgentTOS(&arg
->bundle
->ncp
);
2244 if (!strcasecmp(arg
->argv
[first
], "tcp") && ++first
== arg
->argc
)
2245 ncp_ClearUrgentTcpPorts(&arg
->bundle
->ncp
);
2247 for (f
= first
; f
< arg
->argc
; f
++)
2248 if (*arg
->argv
[f
] == '+')
2249 ncp_AddUrgentTcpPort(&arg
->bundle
->ncp
, atoi(arg
->argv
[f
] + 1));
2250 else if (*arg
->argv
[f
] == '-')
2251 ncp_RemoveUrgentTcpPort(&arg
->bundle
->ncp
, atoi(arg
->argv
[f
] + 1));
2254 ncp_ClearUrgentTcpPorts(&arg
->bundle
->ncp
);
2255 ncp_AddUrgentTcpPort(&arg
->bundle
->ncp
, atoi(arg
->argv
[f
]));
2264 static struct cmdtab
const SetCommands
[] = {
2265 {"accmap", NULL
, SetVariable
, LOCAL_AUTH
| LOCAL_CX
,
2266 "accmap value", "set accmap hex-value", (const void *)VAR_ACCMAP
},
2267 {"authkey", "key", SetVariable
, LOCAL_AUTH
,
2268 "authentication key", "set authkey|key key", (const void *)VAR_AUTHKEY
},
2269 {"authname", NULL
, SetVariable
, LOCAL_AUTH
,
2270 "authentication name", "set authname name", (const void *)VAR_AUTHNAME
},
2271 {"autoload", NULL
, SetVariable
, LOCAL_AUTH
,
2272 "auto link [de]activation", "set autoload maxtime maxload mintime minload",
2273 (const void *)VAR_AUTOLOAD
},
2274 {"bandwidth", NULL
, mp_SetDatalinkBandwidth
, LOCAL_AUTH
| LOCAL_CX
,
2275 "datalink bandwidth", "set bandwidth value", NULL
},
2276 {"callback", NULL
, SetVariable
, LOCAL_AUTH
| LOCAL_CX
,
2277 "callback control", "set callback [none|auth|cbcp|"
2278 "E.164 *|number[,number]...]...", (const void *)VAR_CALLBACK
},
2279 {"cbcp", NULL
, SetVariable
, LOCAL_AUTH
| LOCAL_CX
,
2280 "CBCP control", "set cbcp [*|phone[,phone...] [delay [timeout]]]",
2281 (const void *)VAR_CBCP
},
2282 {"ccpretry", "ccpretries", SetVariable
, LOCAL_AUTH
| LOCAL_CX_OPT
,
2283 "CCP retries", "set ccpretry value [attempts]", (const void *)VAR_CCPRETRY
},
2284 {"cd", NULL
, SetVariable
, LOCAL_AUTH
| LOCAL_CX
, "Carrier delay requirement",
2285 "set cd value[!]", (const void *)VAR_CD
},
2286 {"chapretry", "chapretries", SetVariable
, LOCAL_AUTH
| LOCAL_CX
,
2287 "CHAP retries", "set chapretry value [attempts]",
2288 (const void *)VAR_CHAPRETRY
},
2289 {"choked", NULL
, SetVariable
, LOCAL_AUTH
,
2290 "choked timeout", "set choked [secs]", (const void *)VAR_CHOKED
},
2291 {"ctsrts", "crtscts", SetVariable
, LOCAL_AUTH
| LOCAL_CX
,
2292 "Use hardware flow control", "set ctsrts [on|off]",
2293 (const char *)VAR_CRTSCTS
},
2294 {"deflate", NULL
, SetVariable
, LOCAL_AUTH
| LOCAL_CX_OPT
,
2295 "deflate window sizes", "set deflate out-winsize in-winsize",
2296 (const void *) VAR_WINSIZE
},
2298 {"mppe", NULL
, SetVariable
, LOCAL_AUTH
| LOCAL_CX_OPT
,
2299 "MPPE key size and state", "set mppe [40|56|128|* [stateful|stateless|*]]",
2300 (const void *) VAR_MPPE
},
2302 {"device", "line", SetVariable
, LOCAL_AUTH
| LOCAL_CX
,
2303 "physical device name", "set device|line device-name[,device-name]",
2304 (const void *) VAR_DEVICE
},
2305 {"dial", NULL
, SetVariable
, LOCAL_AUTH
| LOCAL_CX
,
2306 "dialing script", "set dial chat-script", (const void *) VAR_DIAL
},
2307 {"dns", NULL
, SetVariable
, LOCAL_AUTH
, "Domain Name Server",
2308 "set dns pri-addr [sec-addr]", (const void *)VAR_DNS
},
2309 {"enddisc", NULL
, mp_SetEnddisc
, LOCAL_AUTH
,
2310 "Endpoint Discriminator", "set enddisc [IP|magic|label|psn value]", NULL
},
2311 {"escape", NULL
, SetEscape
, LOCAL_AUTH
| LOCAL_CX
,
2312 "escape characters", "set escape hex-digit ...", NULL
},
2313 {"filter", NULL
, filter_Set
, LOCAL_AUTH
,
2314 "packet filters", "set filter alive|dial|in|out rule-no permit|deny "
2315 "[src_addr[/width]] [dst_addr[/width]] [proto "
2316 "[src [lt|eq|gt port]] [dst [lt|eq|gt port]] [estab] [syn] [finrst]]", NULL
},
2317 {"hangup", NULL
, SetVariable
, LOCAL_AUTH
| LOCAL_CX
,
2318 "hangup script", "set hangup chat-script", (const void *) VAR_HANGUP
},
2319 {"ifaddr", NULL
, SetInterfaceAddr
, LOCAL_AUTH
, "destination address",
2320 "set ifaddr [src-addr [dst-addr [netmask [trg-addr]]]]", NULL
},
2321 {"ifqueue", NULL
, SetVariable
, LOCAL_AUTH
, "interface queue",
2322 "set ifqueue packets", (const void *)VAR_IFQUEUE
},
2323 {"ipcpretry", "ipcpretries", SetVariable
, LOCAL_AUTH
, "IPCP retries",
2324 "set ipcpretry value [attempts]", (const void *)VAR_IPCPRETRY
},
2325 {"ipv6cpretry", "ipv6cpretries", SetVariable
, LOCAL_AUTH
, "IPV6CP retries",
2326 "set ipv6cpretry value [attempts]", (const void *)VAR_IPV6CPRETRY
},
2327 {"lcpretry", "lcpretries", SetVariable
, LOCAL_AUTH
| LOCAL_CX
, "LCP retries",
2328 "set lcpretry value [attempts]", (const void *)VAR_LCPRETRY
},
2329 {"log", NULL
, log_SetLevel
, LOCAL_AUTH
, "log level",
2330 "set log [local] [+|-]all|async|cbcp|ccp|chat|command|connect|debug|dns|hdlc|"
2331 "id0|ipcp|lcp|lqm|phase|physical|sync|tcp/ip|timer|tun...", NULL
},
2332 {"login", NULL
, SetVariable
, LOCAL_AUTH
| LOCAL_CX
,
2333 "login script", "set login chat-script", (const void *) VAR_LOGIN
},
2334 {"logout", NULL
, SetVariable
, LOCAL_AUTH
| LOCAL_CX
,
2335 "logout script", "set logout chat-script", (const void *) VAR_LOGOUT
},
2336 {"lqrperiod", NULL
, SetVariable
, LOCAL_AUTH
| LOCAL_CX_OPT
,
2337 "LQR period", "set lqrperiod value", (const void *)VAR_LQRPERIOD
},
2338 {"mode", NULL
, SetVariable
, LOCAL_AUTH
| LOCAL_CX
, "mode value",
2339 "set mode interactive|auto|ddial|background", (const void *)VAR_MODE
},
2340 {"mrru", NULL
, SetVariable
, LOCAL_AUTH
, "MRRU value",
2341 "set mrru value", (const void *)VAR_MRRU
},
2342 {"mru", NULL
, SetVariable
, LOCAL_AUTH
| LOCAL_CX
,
2343 "MRU value", "set mru [max[imum]] [value]", (const void *)VAR_MRU
},
2344 {"mtu", NULL
, SetVariable
, LOCAL_AUTH
| LOCAL_CX
,
2345 "interface MTU value", "set mtu [max[imum]] [value]", (const void *)VAR_MTU
},
2346 {"nbns", NULL
, SetVariable
, LOCAL_AUTH
, "NetBIOS Name Server",
2347 "set nbns pri-addr [sec-addr]", (const void *)VAR_NBNS
},
2348 {"openmode", NULL
, SetVariable
, LOCAL_AUTH
| LOCAL_CX
, "open mode",
2349 "set openmode active|passive [secs]", (const void *)VAR_OPENMODE
},
2350 {"papretry", "papretries", SetVariable
, LOCAL_AUTH
| LOCAL_CX
, "PAP retries",
2351 "set papretry value [attempts]", (const void *)VAR_PAPRETRY
},
2352 {"parity", NULL
, SetVariable
, LOCAL_AUTH
| LOCAL_CX
, "serial parity",
2353 "set parity [odd|even|none]", (const void *)VAR_PARITY
},
2354 {"phone", NULL
, SetVariable
, LOCAL_AUTH
| LOCAL_CX
, "telephone number(s)",
2355 "set phone phone1[:phone2[...]]", (const void *)VAR_PHONE
},
2356 {"proctitle", "title", SetProcTitle
, LOCAL_AUTH
,
2357 "Process title", "set proctitle [value]", NULL
},
2359 {"radius", NULL
, SetVariable
, LOCAL_AUTH
,
2360 "RADIUS Config", "set radius cfgfile", (const void *)VAR_RADIUS
},
2362 {"reconnect", NULL
, datalink_SetReconnect
, LOCAL_AUTH
| LOCAL_CX
,
2363 "Reconnect timeout", "set reconnect value ntries", NULL
},
2364 {"recvpipe", NULL
, SetVariable
, LOCAL_AUTH
,
2365 "RECVPIPE value", "set recvpipe value", (const void *)VAR_RECVPIPE
},
2366 {"redial", NULL
, datalink_SetRedial
, LOCAL_AUTH
| LOCAL_CX
,
2367 "Redial timeout", "set redial secs[+inc[-incmax]][.next] [attempts]", NULL
},
2368 {"sendpipe", NULL
, SetVariable
, LOCAL_AUTH
,
2369 "SENDPIPE value", "set sendpipe value", (const void *)VAR_SENDPIPE
},
2370 {"server", "socket", SetServer
, LOCAL_AUTH
, "diagnostic port",
2371 "set server|socket TcpPort|LocalName|none|open|closed [password [mask]]",
2373 {"speed", NULL
, SetModemSpeed
, LOCAL_AUTH
| LOCAL_CX
,
2374 "physical speed", "set speed value|sync", NULL
},
2375 {"stopped", NULL
, SetStoppedTimeout
, LOCAL_AUTH
| LOCAL_CX
,
2376 "STOPPED timeouts", "set stopped [LCPseconds [CCPseconds]]", NULL
},
2377 {"timeout", NULL
, SetVariable
, LOCAL_AUTH
, "Idle timeout",
2378 "set timeout idletime", (const void *)VAR_IDLETIMEOUT
},
2379 {"urgent", NULL
, SetVariable
, LOCAL_AUTH
, "urgent ports",
2380 "set urgent [tcp|udp] [+|-]port...", (const void *)VAR_URGENTPORTS
},
2381 {"vj", NULL
, ipcp_vjset
, LOCAL_AUTH
,
2382 "vj values", "set vj slots|slotcomp [value]", NULL
},
2383 {"help", "?", HelpCommand
, LOCAL_AUTH
| LOCAL_NO_AUTH
,
2384 "Display this message", "set help|? [command]", SetCommands
},
2385 {NULL
, NULL
, NULL
, 0, NULL
, NULL
, NULL
},
2389 SetCommand(struct cmdargs
const *arg
)
2391 if (arg
->argc
> arg
->argn
)
2392 FindExec(arg
->bundle
, SetCommands
, arg
->argc
, arg
->argn
, arg
->argv
,
2393 arg
->prompt
, arg
->cx
);
2394 else if (arg
->prompt
)
2395 prompt_Printf(arg
->prompt
, "Use `set ?' to get a list or `set ? <var>' for"
2398 log_Printf(LogWARN
, "set command must have arguments\n");
2404 AddCommand(struct cmdargs
const *arg
)
2407 struct ncprange dest
;
2408 struct in_addr host
;
2410 struct in6_addr host6
;
2412 int dest_default
, gw_arg
, addrs
;
2414 if (arg
->argc
!= arg
->argn
+3 && arg
->argc
!= arg
->argn
+2)
2419 if (arg
->argc
== arg
->argn
+ 2) {
2420 if (!strcasecmp(arg
->argv
[arg
->argn
], "default"))
2423 if (!ncprange_aton(&dest
, &arg
->bundle
->ncp
, arg
->argv
[arg
->argn
]))
2425 if (!strncasecmp(arg
->argv
[arg
->argn
], "MYADDR", 6))
2426 addrs
= ROUTE_DSTMYADDR
;
2427 else if (!strncasecmp(arg
->argv
[arg
->argn
], "MYADDR6", 7))
2428 addrs
= ROUTE_DSTMYADDR6
;
2429 else if (!strncasecmp(arg
->argv
[arg
->argn
], "HISADDR", 7))
2430 addrs
= ROUTE_DSTHISADDR
;
2431 else if (!strncasecmp(arg
->argv
[arg
->argn
], "HISADDR6", 8))
2432 addrs
= ROUTE_DSTHISADDR6
;
2433 else if (!strncasecmp(arg
->argv
[arg
->argn
], "DNS0", 4))
2434 addrs
= ROUTE_DSTDNS0
;
2435 else if (!strncasecmp(arg
->argv
[arg
->argn
], "DNS1", 4))
2436 addrs
= ROUTE_DSTDNS1
;
2440 if (strcasecmp(arg
->argv
[arg
->argn
], "MYADDR") == 0) {
2441 addrs
= ROUTE_DSTMYADDR
;
2442 host
= arg
->bundle
->ncp
.ipcp
.my_ip
;
2443 } else if (strcasecmp(arg
->argv
[arg
->argn
], "HISADDR") == 0) {
2444 addrs
= ROUTE_DSTHISADDR
;
2445 host
= arg
->bundle
->ncp
.ipcp
.peer_ip
;
2446 } else if (strcasecmp(arg
->argv
[arg
->argn
], "DNS0") == 0) {
2447 addrs
= ROUTE_DSTDNS0
;
2448 host
= arg
->bundle
->ncp
.ipcp
.ns
.dns
[0];
2449 } else if (strcasecmp(arg
->argv
[arg
->argn
], "DNS1") == 0) {
2450 addrs
= ROUTE_DSTDNS1
;
2451 host
= arg
->bundle
->ncp
.ipcp
.ns
.dns
[1];
2453 host
= GetIpAddr(arg
->argv
[arg
->argn
]);
2454 if (host
.s_addr
== INADDR_NONE
) {
2455 log_Printf(LogWARN
, "%s: Invalid destination address\n",
2456 arg
->argv
[arg
->argn
]);
2460 ncprange_setip4(&dest
, host
, GetIpAddr(arg
->argv
[arg
->argn
+ 1]));
2464 if (strcasecmp(arg
->argv
[arg
->argn
+ gw_arg
], "HISADDR") == 0) {
2465 ncpaddr_setip4(&gw
, arg
->bundle
->ncp
.ipcp
.peer_ip
);
2466 addrs
|= ROUTE_GWHISADDR
;
2468 } else if (strcasecmp(arg
->argv
[arg
->argn
+ gw_arg
], "HISADDR6") == 0) {
2469 if (!ncpaddr_getip6(&arg
->bundle
->ncp
.ipv6cp
.hisaddr
, &host6
))
2470 memset(&host6
, '\0', sizeof host6
);
2471 ncpaddr_setip6(&gw
, &host6
);
2472 addrs
|= ROUTE_GWHISADDR6
;
2475 if (!ncpaddr_aton(&gw
, &arg
->bundle
->ncp
, arg
->argv
[arg
->argn
+ gw_arg
])) {
2476 log_Printf(LogWARN
, "%s: Invalid gateway address\n",
2477 arg
->argv
[arg
->argn
+ gw_arg
]);
2483 ncprange_setdefault(&dest
, ncpaddr_family(&gw
));
2485 if (rt_Set(arg
->bundle
, RTM_ADD
, &dest
, &gw
, arg
->cmd
->args
? 1 : 0,
2486 ((addrs
& ROUTE_GWHISADDR
) || (addrs
& ROUTE_GWHISADDR6
)) ? 1 : 0)
2487 && addrs
!= ROUTE_STATIC
)
2488 route_Add(&arg
->bundle
->ncp
.route
, addrs
, &dest
, &gw
);
2494 DeleteCommand(struct cmdargs
const *arg
)
2496 struct ncprange dest
;
2499 if (arg
->argc
== arg
->argn
+1) {
2500 if(strcasecmp(arg
->argv
[arg
->argn
], "all") == 0) {
2501 route_IfDelete(arg
->bundle
, 0);
2502 route_DeleteAll(&arg
->bundle
->ncp
.route
);
2505 if (strcasecmp(arg
->argv
[arg
->argn
], "MYADDR") == 0) {
2506 ncprange_setip4host(&dest
, arg
->bundle
->ncp
.ipcp
.my_ip
);
2507 addrs
= ROUTE_DSTMYADDR
;
2509 } else if (strcasecmp(arg
->argv
[arg
->argn
], "MYADDR6") == 0) {
2510 ncprange_sethost(&dest
, &arg
->bundle
->ncp
.ipv6cp
.myaddr
);
2511 addrs
= ROUTE_DSTMYADDR6
;
2513 } else if (strcasecmp(arg
->argv
[arg
->argn
], "HISADDR") == 0) {
2514 ncprange_setip4host(&dest
, arg
->bundle
->ncp
.ipcp
.peer_ip
);
2515 addrs
= ROUTE_DSTHISADDR
;
2517 } else if (strcasecmp(arg
->argv
[arg
->argn
], "HISADDR6") == 0) {
2518 ncprange_sethost(&dest
, &arg
->bundle
->ncp
.ipv6cp
.hisaddr
);
2519 addrs
= ROUTE_DSTHISADDR6
;
2521 } else if (strcasecmp(arg
->argv
[arg
->argn
], "DNS0") == 0) {
2522 ncprange_setip4host(&dest
, arg
->bundle
->ncp
.ipcp
.ns
.dns
[0]);
2523 addrs
= ROUTE_DSTDNS0
;
2524 } else if (strcasecmp(arg
->argv
[arg
->argn
], "DNS1") == 0) {
2525 ncprange_setip4host(&dest
, arg
->bundle
->ncp
.ipcp
.ns
.dns
[1]);
2526 addrs
= ROUTE_DSTDNS1
;
2528 ncprange_aton(&dest
, &arg
->bundle
->ncp
, arg
->argv
[arg
->argn
]);
2529 addrs
= ROUTE_STATIC
;
2531 rt_Set(arg
->bundle
, RTM_DELETE
, &dest
, NULL
, arg
->cmd
->args
? 1 : 0, 0);
2532 route_Delete(&arg
->bundle
->ncp
.route
, addrs
, &dest
);
2542 NatEnable(struct cmdargs
const *arg
)
2544 if (arg
->argc
== arg
->argn
+1) {
2545 if (strcasecmp(arg
->argv
[arg
->argn
], "yes") == 0) {
2546 if (!arg
->bundle
->NatEnabled
) {
2547 if (arg
->bundle
->ncp
.ipcp
.fsm
.state
== ST_OPENED
)
2548 PacketAliasSetAddress(arg
->bundle
->ncp
.ipcp
.my_ip
);
2549 arg
->bundle
->NatEnabled
= 1;
2552 } else if (strcasecmp(arg
->argv
[arg
->argn
], "no") == 0) {
2553 arg
->bundle
->NatEnabled
= 0;
2554 arg
->bundle
->cfg
.opt
&= ~OPT_IFACEALIAS
;
2555 /* Don't iface_Clear() - there may be manually configured addresses */
2565 NatOption(struct cmdargs
const *arg
)
2567 long param
= (long)arg
->cmd
->args
;
2569 if (arg
->argc
== arg
->argn
+1) {
2570 if (strcasecmp(arg
->argv
[arg
->argn
], "yes") == 0) {
2571 if (arg
->bundle
->NatEnabled
) {
2572 PacketAliasSetMode(param
, param
);
2575 log_Printf(LogWARN
, "nat not enabled\n");
2576 } else if (strcmp(arg
->argv
[arg
->argn
], "no") == 0) {
2577 if (arg
->bundle
->NatEnabled
) {
2578 PacketAliasSetMode(0, param
);
2581 log_Printf(LogWARN
, "nat not enabled\n");
2586 #endif /* #ifndef NONAT */
2589 LinkCommand(struct cmdargs
const *arg
)
2591 if (arg
->argc
> arg
->argn
+1) {
2592 char namelist
[LINE_LEN
];
2593 struct datalink
*cx
;
2597 if (!strcmp(arg
->argv
[arg
->argn
], "*")) {
2598 struct datalink
*dl
;
2600 cx
= arg
->bundle
->links
;
2602 /* Watch it, the command could be a ``remove'' */
2604 FindExec(arg
->bundle
, Commands
, arg
->argc
, arg
->argn
+1, arg
->argv
,
2606 for (cx
= arg
->bundle
->links
; cx
; cx
= cx
->next
)
2608 break; /* Pointer's still valid ! */
2611 strncpy(namelist
, arg
->argv
[arg
->argn
], sizeof namelist
- 1);
2612 namelist
[sizeof namelist
- 1] = '\0';
2613 for(name
= strtok(namelist
, ", "); name
; name
= strtok(NULL
,", "))
2614 if (!bundle2datalink(arg
->bundle
, name
)) {
2615 log_Printf(LogWARN
, "link: %s: Invalid link name\n", name
);
2619 strncpy(namelist
, arg
->argv
[arg
->argn
], sizeof namelist
- 1);
2620 namelist
[sizeof namelist
- 1] = '\0';
2621 for(name
= strtok(namelist
, ", "); name
; name
= strtok(NULL
,", ")) {
2622 cx
= bundle2datalink(arg
->bundle
, name
);
2624 FindExec(arg
->bundle
, Commands
, arg
->argc
, arg
->argn
+1, arg
->argv
,
2627 log_Printf(LogWARN
, "link: %s: Invalidated link name !\n", name
);
2635 log_Printf(LogWARN
, "usage: %s\n", arg
->cmd
->syntax
);
2640 command_ChooseLink(struct cmdargs
const *arg
)
2643 return &arg
->cx
->physical
->link
;
2644 else if (!arg
->bundle
->ncp
.mp
.cfg
.mrru
) {
2645 struct datalink
*dl
= bundle2datalink(arg
->bundle
, NULL
);
2647 return &dl
->physical
->link
;
2649 return &arg
->bundle
->ncp
.mp
.link
;
2653 ident_cmd(const char *cmd
, unsigned *keep
, unsigned *add
)
2662 *add
= NEG_ACCEPTED
;
2676 *keep
= NEG_HISMASK
;
2686 *keep
= NEG_HISMASK
;
2697 OptSet(struct cmdargs
const *arg
)
2699 int bit
= (int)(long)arg
->cmd
->args
;
2700 unsigned keep
; /* Keep these bits */
2701 unsigned add
; /* Add these bits */
2703 if (ident_cmd(arg
->argv
[arg
->argn
- 2], &keep
, &add
) == NULL
)
2707 if (add
== NEG_ENABLED
&& bit
== OPT_IPV6CP
&& !probe
.ipv6_available
) {
2708 log_Printf(LogWARN
, "IPv6 is not available on this machine\n");
2714 arg
->bundle
->cfg
.opt
|= bit
;
2716 arg
->bundle
->cfg
.opt
&= ~bit
;
2722 IfaceAliasOptSet(struct cmdargs
const *arg
)
2724 unsigned save
= arg
->bundle
->cfg
.opt
;
2725 int result
= OptSet(arg
);
2728 if (Enabled(arg
->bundle
, OPT_IFACEALIAS
) && !arg
->bundle
->NatEnabled
) {
2729 arg
->bundle
->cfg
.opt
= save
;
2730 log_Printf(LogWARN
, "Cannot enable iface-alias without NAT\n");
2738 NegotiateSet(struct cmdargs
const *arg
)
2740 long param
= (long)arg
->cmd
->args
;
2741 struct link
*l
= command_ChooseLink(arg
); /* LOCAL_CX_OPT uses this */
2742 struct datalink
*cx
= arg
->cx
; /* LOCAL_CX uses this */
2744 unsigned keep
; /* Keep these bits */
2745 unsigned add
; /* Add these bits */
2747 if ((cmd
= ident_cmd(arg
->argv
[arg
->argn
-2], &keep
, &add
)) == NULL
)
2750 if ((arg
->cmd
->lauth
& LOCAL_CX
) && !cx
) {
2751 log_Printf(LogWARN
, "%s %s: No context (use the `link' command)\n",
2752 cmd
, arg
->cmd
->name
);
2754 } else if (cx
&& !(arg
->cmd
->lauth
& (LOCAL_CX
|LOCAL_CX_OPT
))) {
2755 log_Printf(LogWARN
, "%s %s: Redundant context (%s) ignored\n",
2756 cmd
, arg
->cmd
->name
, cx
->name
);
2762 cx
->physical
->link
.lcp
.cfg
.acfcomp
&= keep
;
2763 cx
->physical
->link
.lcp
.cfg
.acfcomp
|= add
;
2766 cx
->physical
->link
.lcp
.cfg
.chap05
&= keep
;
2767 cx
->physical
->link
.lcp
.cfg
.chap05
|= add
;
2771 cx
->physical
->link
.lcp
.cfg
.chap80nt
&= keep
;
2772 cx
->physical
->link
.lcp
.cfg
.chap80nt
|= add
;
2775 cx
->physical
->link
.lcp
.cfg
.chap80lm
&= keep
;
2776 cx
->physical
->link
.lcp
.cfg
.chap80lm
|= add
;
2779 cx
->physical
->link
.lcp
.cfg
.chap81
&= keep
;
2780 cx
->physical
->link
.lcp
.cfg
.chap81
|= add
;
2783 l
->ccp
.cfg
.neg
[CCP_NEG_MPPE
] &= keep
;
2784 l
->ccp
.cfg
.neg
[CCP_NEG_MPPE
] |= add
;
2788 l
->ccp
.cfg
.neg
[CCP_NEG_DEFLATE
] &= keep
;
2789 l
->ccp
.cfg
.neg
[CCP_NEG_DEFLATE
] |= add
;
2792 arg
->bundle
->ncp
.ipcp
.cfg
.ns
.dns_neg
&= keep
;
2793 arg
->bundle
->ncp
.ipcp
.cfg
.ns
.dns_neg
|= add
;
2796 arg
->bundle
->ncp
.mp
.cfg
.negenddisc
&= keep
;
2797 arg
->bundle
->ncp
.mp
.cfg
.negenddisc
|= add
;
2800 cx
->physical
->link
.lcp
.cfg
.lqr
&= keep
;
2801 cx
->physical
->link
.lcp
.cfg
.lqr
|= add
;
2804 cx
->physical
->link
.lcp
.cfg
.pap
&= keep
;
2805 cx
->physical
->link
.lcp
.cfg
.pap
|= add
;
2807 case NEG_PPPDDEFLATE
:
2808 l
->ccp
.cfg
.neg
[CCP_NEG_DEFLATE24
] &= keep
;
2809 l
->ccp
.cfg
.neg
[CCP_NEG_DEFLATE24
] |= add
;
2812 l
->ccp
.cfg
.neg
[CCP_NEG_PRED1
] &= keep
;
2813 l
->ccp
.cfg
.neg
[CCP_NEG_PRED1
] |= add
;
2816 cx
->physical
->link
.lcp
.cfg
.protocomp
&= keep
;
2817 cx
->physical
->link
.lcp
.cfg
.protocomp
|= add
;
2820 switch (bundle_Phase(arg
->bundle
)) {
2823 case PHASE_ESTABLISH
:
2824 /* Make sure none of our links are DATALINK_LCP or greater */
2825 if (bundle_HighestState(arg
->bundle
) >= DATALINK_LCP
) {
2826 log_Printf(LogWARN
, "shortseq: Only changeable before"
2827 " LCP negotiations\n");
2832 log_Printf(LogWARN
, "shortseq: Only changeable at phase"
2833 " DEAD/ESTABLISH\n");
2836 arg
->bundle
->ncp
.mp
.cfg
.shortseq
&= keep
;
2837 arg
->bundle
->ncp
.mp
.cfg
.shortseq
|= add
;
2840 arg
->bundle
->ncp
.ipcp
.cfg
.vj
.neg
&= keep
;
2841 arg
->bundle
->ncp
.ipcp
.cfg
.vj
.neg
|= add
;
2848 static struct cmdtab
const NegotiateCommands
[] = {
2849 {"filter-decapsulation", NULL
, OptSet
, LOCAL_AUTH
,
2850 "filter on PPPoUDP payloads", "disable|enable",
2851 (const void *)OPT_FILTERDECAP
},
2852 {"idcheck", NULL
, OptSet
, LOCAL_AUTH
, "Check FSM reply ids",
2853 "disable|enable", (const void *)OPT_IDCHECK
},
2854 {"iface-alias", NULL
, IfaceAliasOptSet
, LOCAL_AUTH
,
2855 "retain interface addresses", "disable|enable",
2856 (const void *)OPT_IFACEALIAS
},
2858 {"ipcp", NULL
, OptSet
, LOCAL_AUTH
, "IP Network Control Protocol",
2859 "disable|enable", (const void *)OPT_IPCP
},
2860 {"ipv6cp", NULL
, OptSet
, LOCAL_AUTH
, "IPv6 Network Control Protocol",
2861 "disable|enable", (const void *)OPT_IPV6CP
},
2863 {"keep-session", NULL
, OptSet
, LOCAL_AUTH
, "Retain device session leader",
2864 "disable|enable", (const void *)OPT_KEEPSESSION
},
2865 {"loopback", NULL
, OptSet
, LOCAL_AUTH
, "Loop packets for local iface",
2866 "disable|enable", (const void *)OPT_LOOPBACK
},
2867 {"passwdauth", NULL
, OptSet
, LOCAL_AUTH
, "Use passwd file",
2868 "disable|enable", (const void *)OPT_PASSWDAUTH
},
2869 {"proxy", NULL
, OptSet
, LOCAL_AUTH
, "Create a proxy ARP entry",
2870 "disable|enable", (const void *)OPT_PROXY
},
2871 {"proxyall", NULL
, OptSet
, LOCAL_AUTH
, "Proxy ARP for all remote hosts",
2872 "disable|enable", (const void *)OPT_PROXYALL
},
2873 {"sroutes", NULL
, OptSet
, LOCAL_AUTH
, "Use sticky routes",
2874 "disable|enable", (const void *)OPT_SROUTES
},
2875 {"tcpmssfixup", "mssfixup", OptSet
, LOCAL_AUTH
, "Modify MSS options",
2876 "disable|enable", (const void *)OPT_TCPMSSFIXUP
},
2877 {"throughput", NULL
, OptSet
, LOCAL_AUTH
, "Rolling throughput",
2878 "disable|enable", (const void *)OPT_THROUGHPUT
},
2879 {"utmp", NULL
, OptSet
, LOCAL_AUTH
, "Log connections in utmp",
2880 "disable|enable", (const void *)OPT_UTMP
},
2883 #define OPT_MAX 13 /* accept/deny allowed below and not above */
2888 {"acfcomp", NULL
, NegotiateSet
, LOCAL_AUTH
| LOCAL_CX
,
2889 "Address & Control field compression", "accept|deny|disable|enable",
2890 (const void *)NEG_ACFCOMP
},
2891 {"chap", "chap05", NegotiateSet
, LOCAL_AUTH
| LOCAL_CX
,
2892 "Challenge Handshake Authentication Protocol", "accept|deny|disable|enable",
2893 (const void *)NEG_CHAP05
},
2895 {"mschap", "chap80nt", NegotiateSet
, LOCAL_AUTH
| LOCAL_CX
,
2896 "Microsoft (NT) CHAP", "accept|deny|disable|enable",
2897 (const void *)NEG_CHAP80
},
2898 {"LANMan", "chap80lm", NegotiateSet
, LOCAL_AUTH
| LOCAL_CX
,
2899 "Microsoft (NT) CHAP", "accept|deny|disable|enable",
2900 (const void *)NEG_CHAP80LM
},
2901 {"mschapv2", "chap81", NegotiateSet
, LOCAL_AUTH
| LOCAL_CX
,
2902 "Microsoft CHAP v2", "accept|deny|disable|enable",
2903 (const void *)NEG_CHAP81
},
2904 {"mppe", NULL
, NegotiateSet
, LOCAL_AUTH
| LOCAL_CX_OPT
,
2905 "MPPE encryption", "accept|deny|disable|enable",
2906 (const void *)NEG_MPPE
},
2908 {"deflate", NULL
, NegotiateSet
, LOCAL_AUTH
| LOCAL_CX_OPT
,
2909 "Deflate compression", "accept|deny|disable|enable",
2910 (const void *)NEG_DEFLATE
},
2911 {"deflate24", NULL
, NegotiateSet
, LOCAL_AUTH
| LOCAL_CX_OPT
,
2912 "Deflate (type 24) compression", "accept|deny|disable|enable",
2913 (const void *)NEG_PPPDDEFLATE
},
2914 {"dns", NULL
, NegotiateSet
, LOCAL_AUTH
,
2915 "DNS specification", "accept|deny|disable|enable", (const void *)NEG_DNS
},
2916 {"enddisc", NULL
, NegotiateSet
, LOCAL_AUTH
, "ENDDISC negotiation",
2917 "accept|deny|disable|enable", (const void *)NEG_ENDDISC
},
2918 {"lqr", NULL
, NegotiateSet
, LOCAL_AUTH
| LOCAL_CX
,
2919 "Link Quality Reports", "accept|deny|disable|enable",
2920 (const void *)NEG_LQR
},
2921 {"pap", NULL
, NegotiateSet
, LOCAL_AUTH
| LOCAL_CX
,
2922 "Password Authentication protocol", "accept|deny|disable|enable",
2923 (const void *)NEG_PAP
},
2924 {"pred1", "predictor1", NegotiateSet
, LOCAL_AUTH
| LOCAL_CX_OPT
,
2925 "Predictor 1 compression", "accept|deny|disable|enable",
2926 (const void *)NEG_PRED1
},
2927 {"protocomp", NULL
, NegotiateSet
, LOCAL_AUTH
| LOCAL_CX
,
2928 "Protocol field compression", "accept|deny|disable|enable",
2929 (const void *)NEG_PROTOCOMP
},
2930 {"shortseq", NULL
, NegotiateSet
, LOCAL_AUTH
,
2931 "MP Short Sequence Numbers", "accept|deny|disable|enable",
2932 (const void *)NEG_SHORTSEQ
},
2933 {"vjcomp", NULL
, NegotiateSet
, LOCAL_AUTH
,
2934 "Van Jacobson header compression", "accept|deny|disable|enable",
2935 (const void *)NEG_VJCOMP
},
2936 {"help", "?", HelpCommand
, LOCAL_AUTH
| LOCAL_NO_AUTH
,
2937 "Display this message", "accept|deny|disable|enable help|? [value]",
2939 {NULL
, NULL
, NULL
, 0, NULL
, NULL
, NULL
},
2943 NegotiateCommand(struct cmdargs
const *arg
)
2945 if (arg
->argc
> arg
->argn
) {
2946 char const *argv
[3];
2950 if ((argv
[0] = ident_cmd(arg
->argv
[arg
->argn
-1], &keep
, &add
)) == NULL
)
2954 for (n
= arg
->argn
; n
< arg
->argc
; n
++) {
2955 argv
[1] = arg
->argv
[n
];
2956 FindExec(arg
->bundle
, NegotiateCommands
+ (keep
== NEG_HISMASK
?
2957 0 : OPT_MAX
), 2, 1, argv
, arg
->prompt
, arg
->cx
);
2959 } else if (arg
->prompt
)
2960 prompt_Printf(arg
->prompt
, "Use `%s ?' to get a list.\n",
2961 arg
->argv
[arg
->argn
-1]);
2963 log_Printf(LogWARN
, "%s command must have arguments\n",
2964 arg
->argv
[arg
->argn
] );
2970 command_ShowNegval(unsigned val
)
2973 case 1: return "disabled & accepted";
2974 case 2: return "enabled & denied";
2975 case 3: return "enabled & accepted";
2977 return "disabled & denied";
2981 ClearCommand(struct cmdargs
const *arg
)
2983 struct pppThroughput
*t
;
2984 struct datalink
*cx
;
2987 if (arg
->argc
< arg
->argn
+ 1)
2990 if (strcasecmp(arg
->argv
[arg
->argn
], "physical") == 0) {
2993 cx
= bundle2datalink(arg
->bundle
, NULL
);
2995 log_Printf(LogWARN
, "A link must be specified for ``clear physical''\n");
2998 t
= &cx
->physical
->link
.stats
.total
;
2999 } else if (strcasecmp(arg
->argv
[arg
->argn
], "ipcp") == 0)
3000 t
= &arg
->bundle
->ncp
.ipcp
.throughput
;
3002 else if (strcasecmp(arg
->argv
[arg
->argn
], "ipv6cp") == 0)
3003 t
= &arg
->bundle
->ncp
.ipv6cp
.throughput
;
3008 if (arg
->argc
> arg
->argn
+ 1) {
3010 for (i
= arg
->argn
+ 1; i
< arg
->argc
; i
++)
3011 if (strcasecmp(arg
->argv
[i
], "overall") == 0)
3012 clear_type
|= THROUGHPUT_OVERALL
;
3013 else if (strcasecmp(arg
->argv
[i
], "current") == 0)
3014 clear_type
|= THROUGHPUT_CURRENT
;
3015 else if (strcasecmp(arg
->argv
[i
], "peak") == 0)
3016 clear_type
|= THROUGHPUT_PEAK
;
3020 clear_type
= THROUGHPUT_ALL
;
3022 throughput_clear(t
, clear_type
, arg
->prompt
);
3027 RunListCommand(struct cmdargs
const *arg
)
3029 const char *cmd
= arg
->argc
? arg
->argv
[arg
->argc
- 1] : "???";
3032 if (arg
->cmd
->args
== NatCommands
&&
3033 tolower(*arg
->argv
[arg
->argn
- 1]) == 'a') {
3035 prompt_Printf(arg
->prompt
, "The alias command is deprecated\n");
3037 log_Printf(LogWARN
, "The alias command is deprecated\n");
3041 if (arg
->argc
> arg
->argn
)
3042 FindExec(arg
->bundle
, arg
->cmd
->args
, arg
->argc
, arg
->argn
, arg
->argv
,
3043 arg
->prompt
, arg
->cx
);
3044 else if (arg
->prompt
)
3045 prompt_Printf(arg
->prompt
, "Use `%s help' to get a list or `%s help"
3046 " <option>' for syntax help.\n", cmd
, cmd
);
3048 log_Printf(LogWARN
, "%s command must have arguments\n", cmd
);
3054 IfaceAddCommand(struct cmdargs
const *arg
)
3056 struct ncpaddr peer
, addr
;
3057 struct ncprange ifa
;
3058 struct in_addr mask
;
3061 if (arg
->argc
== arg
->argn
+ 1) {
3062 if (!ncprange_aton(&ifa
, NULL
, arg
->argv
[arg
->argn
]))
3064 ncpaddr_init(&peer
);
3066 if (arg
->argc
== arg
->argn
+ 2) {
3067 if (!ncprange_aton(&ifa
, NULL
, arg
->argv
[arg
->argn
]))
3070 } else if (arg
->argc
== arg
->argn
+ 3) {
3071 if (!ncpaddr_aton(&addr
, NULL
, arg
->argv
[arg
->argn
]))
3073 if (ncpaddr_family(&addr
) != AF_INET
)
3075 ncprange_sethost(&ifa
, &addr
);
3076 if (!ncpaddr_aton(&addr
, NULL
, arg
->argv
[arg
->argn
+ 1]))
3078 if (!ncpaddr_getip4(&addr
, &mask
))
3080 if (!ncprange_setip4mask(&ifa
, mask
))
3086 if (!ncpaddr_aton(&peer
, NULL
, arg
->argv
[arg
->argn
+ n
]))
3089 if (ncprange_family(&ifa
) != ncpaddr_family(&peer
)) {
3090 log_Printf(LogWARN
, "IfaceAddCommand: src and dst address families"
3096 how
= IFACE_ADD_LAST
;
3098 how
|= IFACE_FORCE_ADD
;
3100 return !iface_Add(arg
->bundle
->iface
, &arg
->bundle
->ncp
, &ifa
, &peer
, how
);
3104 IfaceDeleteCommand(struct cmdargs
const *arg
)
3107 struct in_addr ifa4
;
3110 if (arg
->argc
!= arg
->argn
+ 1)
3113 if (!ncpaddr_aton(&ifa
, NULL
, arg
->argv
[arg
->argn
]))
3116 if (arg
->bundle
->ncp
.ipcp
.fsm
.state
== ST_OPENED
&&
3117 ncpaddr_getip4(&ifa
, &ifa4
) &&
3118 arg
->bundle
->ncp
.ipcp
.my_ip
.s_addr
== ifa4
.s_addr
) {
3119 log_Printf(LogWARN
, "%s: Cannot remove active interface address\n",
3120 ncpaddr_ntoa(&ifa
));
3124 ok
= iface_Delete(arg
->bundle
->iface
, &arg
->bundle
->ncp
, &ifa
);
3128 else if (arg
->prompt
)
3129 prompt_Printf(arg
->prompt
, "%s: No such interface address\n",
3130 ncpaddr_ntoa(&ifa
));
3132 log_Printf(LogWARN
, "%s: No such interface address\n",
3133 ncpaddr_ntoa(&ifa
));
3140 IfaceClearCommand(struct cmdargs
const *arg
)
3145 if (arg
->argc
== arg
->argn
+ 1) {
3146 if (strcasecmp(arg
->argv
[arg
->argn
], "inet") == 0)
3149 else if (strcasecmp(arg
->argv
[arg
->argn
], "inet6") == 0)
3154 } else if (arg
->argc
!= arg
->argn
)
3157 how
= arg
->bundle
->ncp
.ipcp
.fsm
.state
== ST_OPENED
||
3158 arg
->bundle
->phys_type
.all
& PHYS_AUTO
?
3159 IFACE_CLEAR_ALIASES
: IFACE_CLEAR_ALL
;
3160 iface_Clear(arg
->bundle
->iface
, &arg
->bundle
->ncp
, family
, how
);
3166 SetProcTitle(struct cmdargs
const *arg
)
3168 static char title
[LINE_LEN
];
3169 char *argv
[MAXARGS
];
3170 int argc
= arg
->argc
- arg
->argn
;
3172 if (arg
->argc
<= arg
->argn
) {
3177 if ((unsigned)argc
>= sizeof argv
/ sizeof argv
[0]) {
3178 argc
= sizeof argv
/ sizeof argv
[0] - 1;
3179 log_Printf(LogWARN
, "Truncating proc title to %d args\n", argc
);
3181 command_Expand(argv
, argc
, arg
->argv
+ arg
->argn
, arg
->bundle
, 1, getpid());
3182 Concatinate(title
, sizeof title
, argc
, (const char *const *)argv
);
3184 command_Free(argc
, argv
);