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 $
29 * $DragonFly: src/usr.sbin/ppp/command.c,v 1.4 2008/03/11 10:53:07 hasso Exp $
32 #include <sys/param.h>
33 #include <netinet/in_systm.h>
34 #include <netinet/in.h>
35 #include <netinet/ip.h>
36 #include <arpa/inet.h>
37 #include <sys/socket.h>
38 #include <net/route.h>
70 #include "throughput.h"
71 #include "slcompress.h"
82 #include "descriptor.h"
102 #include "datalink.h"
108 #define VAR_AUTHKEY 0
111 #define VAR_AUTHNAME 3
112 #define VAR_AUTOLOAD 4
113 #define VAR_WINSIZE 5
119 #define VAR_OPENMODE 11
121 #define VAR_HANGUP 13
122 #define VAR_IDLETIMEOUT 14
123 #define VAR_LQRPERIOD 15
124 #define VAR_LCPRETRY 16
125 #define VAR_CHAPRETRY 17
126 #define VAR_PAPRETRY 18
127 #define VAR_CCPRETRY 19
128 #define VAR_IPCPRETRY 20
132 #define VAR_CALLBACK 24
134 #define VAR_CHOKED 26
135 #define VAR_SENDPIPE 27
136 #define VAR_RECVPIPE 28
137 #define VAR_RADIUS 29
139 #define VAR_PARITY 31
140 #define VAR_CRTSCTS 32
141 #define VAR_URGENTPORTS 33
142 #define VAR_LOGOUT 34
143 #define VAR_IFQUEUE 35
145 #define VAR_IPV6CPRETRY 37
147 /* ``accept|deny|disable|enable'' masks */
148 #define NEG_HISMASK (1)
149 #define NEG_MYMASK (2)
151 /* ``accept|deny|disable|enable'' values */
152 #define NEG_ACFCOMP 40
153 #define NEG_CHAP05 41
154 #define NEG_CHAP80 42
155 #define NEG_CHAP80LM 43
156 #define NEG_DEFLATE 44
158 #define NEG_ENDDISC 46
161 #define NEG_PPPDDEFLATE 49
163 #define NEG_PROTOCOMP 51
164 #define NEG_SHORTSEQ 52
165 #define NEG_VJCOMP 53
167 #define NEG_CHAP81 55
169 const char Version
[] = "3.1";
171 static int ShowCommand(struct cmdargs
const *);
172 static int TerminalCommand(struct cmdargs
const *);
173 static int QuitCommand(struct cmdargs
const *);
174 static int OpenCommand(struct cmdargs
const *);
175 static int CloseCommand(struct cmdargs
const *);
176 static int DownCommand(struct cmdargs
const *);
177 static int SetCommand(struct cmdargs
const *);
178 static int LinkCommand(struct cmdargs
const *);
179 static int AddCommand(struct cmdargs
const *);
180 static int DeleteCommand(struct cmdargs
const *);
181 static int NegotiateCommand(struct cmdargs
const *);
182 static int ClearCommand(struct cmdargs
const *);
183 static int RunListCommand(struct cmdargs
const *);
184 static int IfaceAddCommand(struct cmdargs
const *);
185 static int IfaceDeleteCommand(struct cmdargs
const *);
186 static int IfaceClearCommand(struct cmdargs
const *);
187 static int SetProcTitle(struct cmdargs
const *);
189 static int NatEnable(struct cmdargs
const *);
190 static int NatOption(struct cmdargs
const *);
194 showcx(struct cmdtab
const *cmd
)
196 if (cmd
->lauth
& LOCAL_CX
)
198 else if (cmd
->lauth
& LOCAL_CX_OPT
)
205 HelpCommand(struct cmdargs
const *arg
)
207 struct cmdtab
const *cmd
;
208 int n
, cmax
, dmax
, cols
, cxlen
;
212 log_Printf(LogWARN
, "help: Cannot help without a prompt\n");
216 if (arg
->argc
> arg
->argn
) {
217 for (cmd
= arg
->cmdtab
; cmd
->name
|| cmd
->alias
; cmd
++)
218 if ((cmd
->lauth
& arg
->prompt
->auth
) &&
219 ((cmd
->name
&& !strcasecmp(cmd
->name
, arg
->argv
[arg
->argn
])) ||
220 (cmd
->alias
&& !strcasecmp(cmd
->alias
, arg
->argv
[arg
->argn
])))) {
221 prompt_Printf(arg
->prompt
, "%s %s\n", cmd
->syntax
, showcx(cmd
));
228 for (cmd
= arg
->cmdtab
; cmd
->func
; cmd
++)
229 if (cmd
->name
&& (cmd
->lauth
& arg
->prompt
->auth
)) {
230 if ((n
= strlen(cmd
->name
) + strlen(showcx(cmd
))) > cmax
)
232 if ((n
= strlen(cmd
->helpmes
)) > dmax
)
236 cols
= 80 / (dmax
+ cmax
+ 3);
238 prompt_Printf(arg
->prompt
, "(o) = Optional context,"
239 " (c) = Context required\n");
240 for (cmd
= arg
->cmdtab
; cmd
->func
; cmd
++)
241 if (cmd
->name
&& (cmd
->lauth
& arg
->prompt
->auth
)) {
243 cxlen
= cmax
- strlen(cmd
->name
);
245 prompt_Printf(arg
->prompt
, " ");
246 prompt_Printf(arg
->prompt
, "%s%-*.*s: %-*.*s",
247 cmd
->name
, cxlen
, cxlen
, cx
, dmax
, dmax
, cmd
->helpmes
);
249 prompt_Printf(arg
->prompt
, "\n");
252 prompt_Printf(arg
->prompt
, "\n");
258 IdentCommand(struct cmdargs
const *arg
)
260 Concatinate(arg
->cx
->physical
->link
.lcp
.cfg
.ident
,
261 sizeof arg
->cx
->physical
->link
.lcp
.cfg
.ident
,
262 arg
->argc
- arg
->argn
, arg
->argv
+ arg
->argn
);
267 SendIdentification(struct cmdargs
const *arg
)
269 if (arg
->cx
->state
< DATALINK_LCP
) {
270 log_Printf(LogWARN
, "sendident: link has not reached LCP\n");
273 return lcp_SendIdentification(&arg
->cx
->physical
->link
.lcp
) ? 0 : 1;
277 CloneCommand(struct cmdargs
const *arg
)
279 char namelist
[LINE_LEN
];
283 if (arg
->argc
== arg
->argn
)
286 namelist
[sizeof namelist
- 1] = '\0';
287 for (f
= arg
->argn
; f
< arg
->argc
; f
++) {
288 strncpy(namelist
, arg
->argv
[f
], sizeof namelist
- 1);
289 for(name
= strtok(namelist
, ", "); name
; name
= strtok(NULL
,", "))
290 bundle_DatalinkClone(arg
->bundle
, arg
->cx
, name
);
297 RemoveCommand(struct cmdargs
const *arg
)
299 if (arg
->argc
!= arg
->argn
)
302 if (arg
->cx
->state
!= DATALINK_CLOSED
) {
303 log_Printf(LogWARN
, "remove: Cannot delete links that aren't closed\n");
307 bundle_DatalinkRemove(arg
->bundle
, arg
->cx
);
312 RenameCommand(struct cmdargs
const *arg
)
314 if (arg
->argc
!= arg
->argn
+ 1)
317 if (bundle_RenameDatalink(arg
->bundle
, arg
->cx
, arg
->argv
[arg
->argn
]))
320 log_Printf(LogWARN
, "%s -> %s: target name already exists\n",
321 arg
->cx
->name
, arg
->argv
[arg
->argn
]);
326 LoadCommand(struct cmdargs
const *arg
)
331 mode
= arg
->bundle
->phys_type
.all
;
333 if (arg
->argn
< arg
->argc
) {
334 for (n
= arg
->argn
; n
< arg
->argc
; n
++)
335 if ((err
= system_IsValid(arg
->argv
[n
], arg
->prompt
, mode
)) != NULL
) {
336 log_Printf(LogWARN
, "%s: %s\n", arg
->argv
[n
], err
);
340 for (n
= arg
->argn
; n
< arg
->argc
; n
++) {
341 bundle_SetLabel(arg
->bundle
, arg
->argv
[arg
->argc
- 1]);
342 system_Select(arg
->bundle
, arg
->argv
[n
], CONFFILE
, arg
->prompt
, arg
->cx
);
344 bundle_SetLabel(arg
->bundle
, arg
->argv
[arg
->argc
- 1]);
345 } else if ((err
= system_IsValid("default", arg
->prompt
, mode
)) != NULL
) {
346 log_Printf(LogWARN
, "default: %s\n", err
);
349 bundle_SetLabel(arg
->bundle
, "default");
350 system_Select(arg
->bundle
, "default", CONFFILE
, arg
->prompt
, arg
->cx
);
351 bundle_SetLabel(arg
->bundle
, "default");
358 LogCommand(struct cmdargs
const *arg
)
362 if (arg
->argn
< arg
->argc
) {
364 int argc
= arg
->argc
- arg
->argn
;
366 if (argc
>= sizeof argv
/ sizeof argv
[0]) {
367 argc
= sizeof argv
/ sizeof argv
[0] - 1;
368 log_Printf(LogWARN
, "Truncating log command to %d args\n", argc
);
370 command_Expand(argv
, argc
, arg
->argv
+ arg
->argn
, arg
->bundle
, 1, getpid());
371 Concatinate(buf
, sizeof buf
, argc
, (const char *const *)argv
);
372 log_Printf(LogLOG
, "%s\n", buf
);
373 command_Free(argc
, argv
);
381 SaveCommand(struct cmdargs
const *arg
)
383 log_Printf(LogWARN
, "save command is not yet implemented.\n");
388 DialCommand(struct cmdargs
const *arg
)
392 if ((arg
->cx
&& !(arg
->cx
->physical
->type
& (PHYS_INTERACTIVE
|PHYS_AUTO
)))
394 (arg
->bundle
->phys_type
.all
& ~(PHYS_INTERACTIVE
|PHYS_AUTO
)))) {
395 log_Printf(LogWARN
, "Manual dial is only available for auto and"
396 " interactive links\n");
400 if (arg
->argc
> arg
->argn
&& (res
= LoadCommand(arg
)) != 0)
403 bundle_Open(arg
->bundle
, arg
->cx
? arg
->cx
->name
: NULL
, PHYS_ALL
, 1);
408 #define isinword(ch) (isalnum(ch) || (ch) == '_')
411 strstrword(char *big
, const char *little
)
413 /* Get the first occurance of the word ``little'' in ``big'' */
418 len
= strlen(little
);
420 while ((pos
= strstr(pos
, little
)) != NULL
)
421 if ((pos
!= big
&& isinword(pos
[-1])) || isinword(pos
[len
]))
423 else if (pos
!= big
&& pos
[-1] == '\\')
424 memmove(pos
- 1, pos
, strlen(pos
) + 1);
432 subst(char *tgt
, const char *oldstr
, const char *newstr
)
434 /* tgt is a malloc()d area... realloc() as necessary */
436 int ltgt
, loldstr
, lnewstr
, pos
;
438 if ((word
= strstrword(tgt
, oldstr
)) == NULL
)
441 ltgt
= strlen(tgt
) + 1;
442 loldstr
= strlen(oldstr
);
443 lnewstr
= strlen(newstr
);
446 if (loldstr
> lnewstr
)
447 bcopy(word
+ loldstr
, word
+ lnewstr
, ltgt
- pos
- loldstr
);
448 if (loldstr
!= lnewstr
) {
449 ntgt
= realloc(tgt
, ltgt
+= lnewstr
- loldstr
);
451 break; /* Oh wonderful ! */
455 if (lnewstr
> loldstr
)
456 bcopy(word
+ loldstr
, word
+ lnewstr
, ltgt
- pos
- loldstr
);
457 bcopy(newstr
, word
, lnewstr
);
458 } while ((word
= strstrword(word
, oldstr
)));
464 substip(char *tgt
, const char *oldstr
, struct in_addr ip
)
466 return subst(tgt
, oldstr
, inet_ntoa(ip
));
470 substlong(char *tgt
, const char *oldstr
, long l
)
474 snprintf(buf
, sizeof buf
, "%ld", l
);
476 return subst(tgt
, oldstr
, buf
);
480 substull(char *tgt
, const char *oldstr
, unsigned long long ull
)
484 snprintf(buf
, sizeof buf
, "%llu", ull
);
486 return subst(tgt
, oldstr
, buf
);
492 substipv6(char *tgt
, const char *oldstr
, const struct ncpaddr
*ip
)
494 return subst(tgt
, oldstr
, ncpaddr_ntoa(ip
));
499 command_Expand(char **nargv
, int argc
, char const *const *oargv
,
500 struct bundle
*bundle
, int inc0
, pid_t pid
)
504 unsigned long long oin
, oout
, pin
, pout
;
507 arg
= 0; /* Start at arg 0 */
509 nargv
[0] = strdup(oargv
[0]);
513 secs
= bundle_Uptime(bundle
);
514 snprintf(uptime
, sizeof uptime
, "%d:%02d:%02d",
515 secs
/ 3600, (secs
/ 60) % 60, secs
% 60);
516 oin
= bundle
->ncp
.ipcp
.throughput
.OctetsIn
;
517 oout
= bundle
->ncp
.ipcp
.throughput
.OctetsOut
;
518 pin
= bundle
->ncp
.ipcp
.throughput
.PacketsIn
;
519 pout
= bundle
->ncp
.ipcp
.throughput
.PacketsOut
;
521 oin
+= bundle
->ncp
.ipv6cp
.throughput
.OctetsIn
;
522 oout
+= bundle
->ncp
.ipv6cp
.throughput
.OctetsOut
;
523 pin
+= bundle
->ncp
.ipv6cp
.throughput
.PacketsIn
;
524 pout
+= bundle
->ncp
.ipv6cp
.throughput
.PacketsOut
;
527 for (; arg
< argc
; arg
++) {
528 nargv
[arg
] = strdup(oargv
[arg
]);
529 nargv
[arg
] = subst(nargv
[arg
], "AUTHNAME", bundle
->cfg
.auth
.name
);
530 nargv
[arg
] = subst(nargv
[arg
], "COMPILATIONDATE", __DATE__
);
531 nargv
[arg
] = substip(nargv
[arg
], "DNS0", bundle
->ncp
.ipcp
.ns
.dns
[0]);
532 nargv
[arg
] = substip(nargv
[arg
], "DNS1", bundle
->ncp
.ipcp
.ns
.dns
[1]);
533 nargv
[arg
] = subst(nargv
[arg
], "ENDDISC",
534 mp_Enddisc(bundle
->ncp
.mp
.cfg
.enddisc
.class,
535 bundle
->ncp
.mp
.cfg
.enddisc
.address
,
536 bundle
->ncp
.mp
.cfg
.enddisc
.len
));
537 nargv
[arg
] = substip(nargv
[arg
], "HISADDR", bundle
->ncp
.ipcp
.peer_ip
);
539 nargv
[arg
] = substipv6(nargv
[arg
], "HISADDR6", &bundle
->ncp
.ipv6cp
.hisaddr
);
541 nargv
[arg
] = subst(nargv
[arg
], "INTERFACE", bundle
->iface
->name
);
542 nargv
[arg
] = substull(nargv
[arg
], "IPOCTETSIN",
543 bundle
->ncp
.ipcp
.throughput
.OctetsIn
);
544 nargv
[arg
] = substull(nargv
[arg
], "IPOCTETSOUT",
545 bundle
->ncp
.ipcp
.throughput
.OctetsOut
);
546 nargv
[arg
] = substull(nargv
[arg
], "IPPACKETSIN",
547 bundle
->ncp
.ipcp
.throughput
.PacketsIn
);
548 nargv
[arg
] = substull(nargv
[arg
], "IPPACKETSOUT",
549 bundle
->ncp
.ipcp
.throughput
.PacketsOut
);
551 nargv
[arg
] = substull(nargv
[arg
], "IPV6OCTETSIN",
552 bundle
->ncp
.ipv6cp
.throughput
.OctetsIn
);
553 nargv
[arg
] = substull(nargv
[arg
], "IPV6OCTETSOUT",
554 bundle
->ncp
.ipv6cp
.throughput
.OctetsOut
);
555 nargv
[arg
] = substull(nargv
[arg
], "IPV6PACKETSIN",
556 bundle
->ncp
.ipv6cp
.throughput
.PacketsIn
);
557 nargv
[arg
] = substull(nargv
[arg
], "IPV6PACKETSOUT",
558 bundle
->ncp
.ipv6cp
.throughput
.PacketsOut
);
560 nargv
[arg
] = subst(nargv
[arg
], "LABEL", bundle_GetLabel(bundle
));
561 nargv
[arg
] = substip(nargv
[arg
], "MYADDR", bundle
->ncp
.ipcp
.my_ip
);
563 nargv
[arg
] = substipv6(nargv
[arg
], "MYADDR6", &bundle
->ncp
.ipv6cp
.myaddr
);
565 nargv
[arg
] = substull(nargv
[arg
], "OCTETSIN", oin
);
566 nargv
[arg
] = substull(nargv
[arg
], "OCTETSOUT", oout
);
567 nargv
[arg
] = substull(nargv
[arg
], "PACKETSIN", pin
);
568 nargv
[arg
] = substull(nargv
[arg
], "PACKETSOUT", pout
);
569 nargv
[arg
] = subst(nargv
[arg
], "PEER_ENDDISC",
570 mp_Enddisc(bundle
->ncp
.mp
.peer
.enddisc
.class,
571 bundle
->ncp
.mp
.peer
.enddisc
.address
,
572 bundle
->ncp
.mp
.peer
.enddisc
.len
));
573 nargv
[arg
] = substlong(nargv
[arg
], "PROCESSID", pid
);
575 nargv
[arg
] = substlong(nargv
[arg
], "SOCKNAME", server
.cfg
.port
);
577 nargv
[arg
] = subst(nargv
[arg
], "SOCKNAME", server
.cfg
.sockname
);
578 nargv
[arg
] = subst(nargv
[arg
], "UPTIME", uptime
);
579 nargv
[arg
] = subst(nargv
[arg
], "USER", bundle
->ncp
.mp
.peer
.authname
);
580 nargv
[arg
] = subst(nargv
[arg
], "VERSION", Version
);
586 command_Free(int argc
, char **argv
)
596 ShellCommand(struct cmdargs
const *arg
, int bg
)
601 #ifdef SHELL_ONLY_INTERACTIVELY
602 /* we're only allowed to shell when we run ppp interactively */
603 if (arg
->prompt
&& arg
->prompt
->owner
) {
604 log_Printf(LogWARN
, "Can't start a shell from a network connection\n");
609 if (arg
->argc
== arg
->argn
) {
611 log_Printf(LogWARN
, "Can't start an interactive shell from"
614 } else if (arg
->prompt
->owner
) {
615 log_Printf(LogWARN
, "Can't start an interactive shell from"
616 " a socket connection\n");
619 log_Printf(LogWARN
, "Can only start an interactive shell in"
620 " the foreground mode\n");
626 if ((shpid
= fork()) == 0) {
629 if ((shell
= getenv("SHELL")) == 0)
630 shell
= _PATH_BSHELL
;
635 fd
= arg
->prompt
->fd_out
;
636 else if ((fd
= open(_PATH_DEVNULL
, O_RDWR
)) == -1) {
637 log_Printf(LogALERT
, "Failed to open %s: %s\n",
638 _PATH_DEVNULL
, strerror(errno
));
641 dup2(fd
, STDIN_FILENO
);
642 dup2(fd
, STDOUT_FILENO
);
643 dup2(fd
, STDERR_FILENO
);
644 for (i
= getdtablesize(); i
> STDERR_FILENO
; i
--)
645 fcntl(i
, F_SETFD
, 1);
648 setuid(ID0realuid());
650 if (arg
->argc
> arg
->argn
) {
651 /* substitute pseudo args */
653 int argc
= arg
->argc
- arg
->argn
;
655 if (argc
>= sizeof argv
/ sizeof argv
[0]) {
656 argc
= sizeof argv
/ sizeof argv
[0] - 1;
657 log_Printf(LogWARN
, "Truncating shell command to %d args\n", argc
);
659 command_Expand(argv
, argc
, arg
->argv
+ arg
->argn
, arg
->bundle
, 0, pid
);
664 if (daemon(1, 1) == -1) {
665 log_Printf(LogERROR
, "%ld: daemon: %s\n", (long)p
, strerror(errno
));
668 } else if (arg
->prompt
)
669 printf("ppp: Pausing until %s finishes\n", arg
->argv
[arg
->argn
]);
670 execvp(argv
[0], argv
);
673 printf("ppp: Pausing until %s finishes\n", shell
);
674 prompt_TtyOldMode(arg
->prompt
);
675 execl(shell
, shell
, NULL
);
678 log_Printf(LogWARN
, "exec() of %s failed: %s\n",
679 arg
->argc
> arg
->argn
? arg
->argv
[arg
->argn
] : shell
,
684 if (shpid
== (pid_t
)-1)
685 log_Printf(LogERROR
, "Fork failed: %s\n", strerror(errno
));
688 waitpid(shpid
, &status
, 0);
691 if (arg
->prompt
&& !arg
->prompt
->owner
)
692 prompt_TtyCommandMode(arg
->prompt
);
698 BgShellCommand(struct cmdargs
const *arg
)
700 if (arg
->argc
== arg
->argn
)
702 return ShellCommand(arg
, 1);
706 FgShellCommand(struct cmdargs
const *arg
)
708 return ShellCommand(arg
, 0);
712 ResolvCommand(struct cmdargs
const *arg
)
714 if (arg
->argc
== arg
->argn
+ 1) {
715 if (!strcasecmp(arg
->argv
[arg
->argn
], "reload"))
716 ipcp_LoadDNS(&arg
->bundle
->ncp
.ipcp
);
717 else if (!strcasecmp(arg
->argv
[arg
->argn
], "restore"))
718 ipcp_RestoreDNS(&arg
->bundle
->ncp
.ipcp
);
719 else if (!strcasecmp(arg
->argv
[arg
->argn
], "rewrite"))
720 ipcp_WriteDNS(&arg
->bundle
->ncp
.ipcp
);
721 else if (!strcasecmp(arg
->argv
[arg
->argn
], "readonly"))
722 arg
->bundle
->ncp
.ipcp
.ns
.writable
= 0;
723 else if (!strcasecmp(arg
->argv
[arg
->argn
], "writable"))
724 arg
->bundle
->ncp
.ipcp
.ns
.writable
= 1;
735 static struct cmdtab
const NatCommands
[] =
737 {"addr", NULL
, nat_RedirectAddr
, LOCAL_AUTH
,
738 "static address translation", "nat addr [addr_local addr_alias]"},
739 {"deny_incoming", NULL
, NatOption
, LOCAL_AUTH
,
740 "stop incoming connections", "nat deny_incoming yes|no",
741 (const void *) PKT_ALIAS_DENY_INCOMING
},
742 {"enable", NULL
, NatEnable
, LOCAL_AUTH
,
743 "enable NAT", "nat enable yes|no"},
744 {"log", NULL
, NatOption
, LOCAL_AUTH
,
745 "log NAT link creation", "nat log yes|no",
746 (const void *) PKT_ALIAS_LOG
},
747 {"port", NULL
, nat_RedirectPort
, LOCAL_AUTH
, "port redirection",
748 "nat port proto localaddr:port[-port] aliasport[-aliasport]"},
749 {"proto", NULL
, nat_RedirectProto
, LOCAL_AUTH
, "protocol redirection",
750 "nat proto proto localIP [publicIP [remoteIP]]"},
751 {"proxy", NULL
, nat_ProxyRule
, LOCAL_AUTH
,
752 "proxy control", "nat proxy server host[:port] ..."},
754 {"punch_fw", NULL
, nat_PunchFW
, LOCAL_AUTH
,
755 "firewall control", "nat punch_fw [base count]"},
757 {"same_ports", NULL
, NatOption
, LOCAL_AUTH
,
758 "try to leave port numbers unchanged", "nat same_ports yes|no",
759 (const void *) PKT_ALIAS_SAME_PORTS
},
760 {"target", NULL
, nat_SetTarget
, LOCAL_AUTH
,
761 "Default address for incoming connections", "nat target addr" },
762 {"unregistered_only", NULL
, NatOption
, LOCAL_AUTH
,
763 "translate unregistered (private) IP address space only",
764 "nat unregistered_only yes|no",
765 (const void *) PKT_ALIAS_UNREGISTERED_ONLY
},
766 {"use_sockets", NULL
, NatOption
, LOCAL_AUTH
,
767 "allocate host sockets", "nat use_sockets yes|no",
768 (const void *) PKT_ALIAS_USE_SOCKETS
},
769 {"help", "?", HelpCommand
, LOCAL_AUTH
| LOCAL_NO_AUTH
,
770 "Display this message", "nat help|? [command]", NatCommands
},
775 static struct cmdtab
const AllowCommands
[] = {
776 {"modes", "mode", AllowModes
, LOCAL_AUTH
,
777 "Only allow certain ppp modes", "allow modes mode..."},
778 {"users", "user", AllowUsers
, LOCAL_AUTH
,
779 "Only allow ppp access to certain users", "allow users logname..."},
780 {"help", "?", HelpCommand
, LOCAL_AUTH
| LOCAL_NO_AUTH
,
781 "Display this message", "allow help|? [command]", AllowCommands
},
785 static struct cmdtab
const IfaceCommands
[] =
787 {"add", NULL
, IfaceAddCommand
, LOCAL_AUTH
,
788 "Add iface address", "iface add addr[/bits| mask] peer", NULL
},
789 {NULL
, "add!", IfaceAddCommand
, LOCAL_AUTH
,
790 "Add or change an iface address", "iface add! addr[/bits| mask] peer",
792 {"clear", NULL
, IfaceClearCommand
, LOCAL_AUTH
,
793 "Clear iface address(es)", "iface clear [INET | INET6]"},
794 {"delete", "rm", IfaceDeleteCommand
, LOCAL_AUTH
,
795 "Delete iface address", "iface delete addr", NULL
},
796 {NULL
, "rm!", IfaceDeleteCommand
, LOCAL_AUTH
,
797 "Delete iface address", "iface delete addr", (void *)1},
798 {NULL
, "delete!", IfaceDeleteCommand
, LOCAL_AUTH
,
799 "Delete iface address", "iface delete addr", (void *)1},
800 {"show", NULL
, iface_Show
, LOCAL_AUTH
,
801 "Show iface address(es)", "iface show"},
802 {"help", "?", HelpCommand
, LOCAL_AUTH
| LOCAL_NO_AUTH
,
803 "Display this message", "nat help|? [command]", IfaceCommands
},
807 static struct cmdtab
const Commands
[] = {
808 {"accept", NULL
, NegotiateCommand
, LOCAL_AUTH
| LOCAL_CX_OPT
,
809 "accept option request", "accept option .."},
810 {"add", NULL
, AddCommand
, LOCAL_AUTH
,
811 "add route", "add dest mask gateway", NULL
},
812 {NULL
, "add!", AddCommand
, LOCAL_AUTH
,
813 "add or change route", "add! dest mask gateway", (void *)1},
814 {"allow", "auth", RunListCommand
, LOCAL_AUTH
,
815 "Allow ppp access", "allow users|modes ....", AllowCommands
},
816 {"bg", "!bg", BgShellCommand
, LOCAL_AUTH
,
817 "Run a background command", "[!]bg command"},
818 {"clear", NULL
, ClearCommand
, LOCAL_AUTH
| LOCAL_CX_OPT
,
819 "Clear throughput statistics",
820 "clear ipcp|ipv6cp|physical [current|overall|peak]..."},
821 {"clone", NULL
, CloneCommand
, LOCAL_AUTH
| LOCAL_CX
,
822 "Clone a link", "clone newname..."},
823 {"close", NULL
, CloseCommand
, LOCAL_AUTH
| LOCAL_CX_OPT
,
824 "Close an FSM", "close [lcp|ccp]"},
825 {"delete", NULL
, DeleteCommand
, LOCAL_AUTH
,
826 "delete route", "delete dest", NULL
},
827 {NULL
, "delete!", DeleteCommand
, LOCAL_AUTH
,
828 "delete a route if it exists", "delete! dest", (void *)1},
829 {"deny", NULL
, NegotiateCommand
, LOCAL_AUTH
| LOCAL_CX_OPT
,
830 "Deny option request", "deny option .."},
831 {"dial", "call", DialCommand
, LOCAL_AUTH
| LOCAL_CX_OPT
,
832 "Dial and login", "dial|call [system ...]", NULL
},
833 {"disable", NULL
, NegotiateCommand
, LOCAL_AUTH
| LOCAL_CX_OPT
,
834 "Disable option", "disable option .."},
835 {"down", NULL
, DownCommand
, LOCAL_AUTH
| LOCAL_CX_OPT
,
836 "Generate a down event", "down [ccp|lcp]"},
837 {"enable", NULL
, NegotiateCommand
, LOCAL_AUTH
| LOCAL_CX_OPT
,
838 "Enable option", "enable option .."},
839 {"ident", NULL
, IdentCommand
, LOCAL_AUTH
| LOCAL_CX
,
840 "Set the link identity", "ident text..."},
841 {"iface", "interface", RunListCommand
, LOCAL_AUTH
,
842 "interface control", "iface option ...", IfaceCommands
},
843 {"link", "datalink", LinkCommand
, LOCAL_AUTH
,
844 "Link specific commands", "link name command ..."},
845 {"load", NULL
, LoadCommand
, LOCAL_AUTH
| LOCAL_CX_OPT
,
846 "Load settings", "load [system ...]"},
847 {"log", NULL
, LogCommand
, LOCAL_AUTH
| LOCAL_CX_OPT
,
848 "log information", "log word ..."},
850 {"nat", "alias", RunListCommand
, LOCAL_AUTH
,
851 "NAT control", "nat option yes|no", NatCommands
},
853 {"open", NULL
, OpenCommand
, LOCAL_AUTH
| LOCAL_CX_OPT
,
854 "Open an FSM", "open! [lcp|ccp|ipcp]", (void *)1},
855 {"passwd", NULL
, PasswdCommand
, LOCAL_NO_AUTH
,
856 "Password for manipulation", "passwd LocalPassword"},
857 {"quit", "bye", QuitCommand
, LOCAL_AUTH
| LOCAL_NO_AUTH
,
858 "Quit PPP program", "quit|bye [all]"},
859 {"remove", "rm", RemoveCommand
, LOCAL_AUTH
| LOCAL_CX
,
860 "Remove a link", "remove"},
861 {"rename", "mv", RenameCommand
, LOCAL_AUTH
| LOCAL_CX
,
862 "Rename a link", "rename name"},
863 {"resolv", NULL
, ResolvCommand
, LOCAL_AUTH
,
864 "Manipulate resolv.conf", "resolv readonly|reload|restore|rewrite|writable"},
865 {"save", NULL
, SaveCommand
, LOCAL_AUTH
,
866 "Save settings", "save"},
867 {"sendident", NULL
, SendIdentification
, LOCAL_AUTH
| LOCAL_CX
,
868 "Transmit the link identity", "sendident"},
869 {"set", "setup", SetCommand
, LOCAL_AUTH
| LOCAL_CX_OPT
,
870 "Set parameters", "set[up] var value"},
871 {"shell", "!", FgShellCommand
, LOCAL_AUTH
,
872 "Run a subshell", "shell|! [sh command]"},
873 {"show", NULL
, ShowCommand
, LOCAL_AUTH
| LOCAL_CX_OPT
,
874 "Show status and stats", "show var"},
875 {"term", NULL
, TerminalCommand
, LOCAL_AUTH
| LOCAL_CX
,
876 "Enter terminal mode", "term"},
877 {"help", "?", HelpCommand
, LOCAL_AUTH
| LOCAL_NO_AUTH
,
878 "Display this message", "help|? [command]", Commands
},
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"},
950 {"ccp", NULL
, ccp_ReportStatus
, LOCAL_AUTH
| LOCAL_CX_OPT
,
951 "CCP status", "show cpp"},
952 {"compress", NULL
, sl_Show
, LOCAL_AUTH
,
953 "VJ compression stats", "show compress"},
954 {"escape", NULL
, ShowEscape
, LOCAL_AUTH
| LOCAL_CX
,
955 "escape characters", "show escape"},
956 {"filter", NULL
, filter_Show
, LOCAL_AUTH
,
957 "packet filters", "show filter [in|out|dial|alive]"},
958 {"hdlc", NULL
, hdlc_ReportStatus
, LOCAL_AUTH
| LOCAL_CX
,
959 "HDLC errors", "show hdlc"},
960 {"iface", "interface", iface_Show
, LOCAL_AUTH
,
961 "Interface status", "show iface"},
962 {"ipcp", NULL
, ipcp_Show
, LOCAL_AUTH
,
963 "IPCP status", "show ipcp"},
965 {"ipv6cp", NULL
, ipv6cp_Show
, LOCAL_AUTH
,
966 "IPV6CP status", "show ipv6cp"},
968 {"layers", NULL
, link_ShowLayers
, LOCAL_AUTH
| LOCAL_CX_OPT
,
969 "Protocol layers", "show layers"},
970 {"lcp", NULL
, lcp_ReportStatus
, LOCAL_AUTH
| LOCAL_CX
,
971 "LCP status", "show lcp"},
972 {"link", "datalink", datalink_Show
, LOCAL_AUTH
| LOCAL_CX
,
973 "(high-level) link info", "show link"},
974 {"links", NULL
, bundle_ShowLinks
, LOCAL_AUTH
,
975 "available link names", "show links"},
976 {"log", NULL
, log_ShowLevel
, LOCAL_AUTH
,
977 "log levels", "show log"},
978 {"mem", NULL
, mbuf_Show
, LOCAL_AUTH
,
979 "mbuf allocations", "show mem"},
980 {"ncp", NULL
, ncp_Show
, LOCAL_AUTH
,
981 "NCP status", "show ncp"},
982 {"physical", NULL
, physical_ShowStatus
, LOCAL_AUTH
| LOCAL_CX
,
983 "(low-level) link info", "show physical"},
984 {"mp", "multilink", mp_ShowStatus
, LOCAL_AUTH
,
985 "multilink setup", "show mp"},
986 {"proto", NULL
, ShowProtocolStats
, LOCAL_AUTH
| LOCAL_CX_OPT
,
987 "protocol summary", "show proto"},
988 {"route", NULL
, route_Show
, LOCAL_AUTH
,
989 "routing table", "show route"},
990 {"stopped", NULL
, ShowStopped
, LOCAL_AUTH
| LOCAL_CX
,
991 "STOPPED timeout", "show stopped"},
992 {"timers", NULL
, ShowTimerList
, LOCAL_AUTH
,
993 "alarm timers", "show timers"},
994 {"version", NULL
, ShowVersion
, LOCAL_NO_AUTH
| LOCAL_AUTH
,
995 "version string", "show version"},
996 {"who", NULL
, log_ShowWho
, LOCAL_AUTH
,
997 "client list", "show who"},
998 {"help", "?", HelpCommand
, LOCAL_NO_AUTH
| LOCAL_AUTH
,
999 "Display this message", "show help|? [command]", ShowCommands
},
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(int argc
, 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
)) {
1168 strncpy(buf
, label
, sizeof buf
- 3);
1169 buf
[sizeof buf
- 3] = '\0';
1176 buf
[sizeof buf
- 1] = '\0'; /* In case we run out of room in buf */
1178 for (f
= 0; f
< argc
; f
++) {
1179 if (n
< sizeof buf
- 1 && f
)
1181 if (arghidden(argc
, argv
, f
))
1182 strncpy(buf
+n
, "********", sizeof buf
- n
- 1);
1184 strncpy(buf
+n
, argv
[f
], sizeof buf
- n
- 1);
1187 log_Printf(LogCOMMAND
, "%s\n", buf
);
1189 FindExec(bundle
, Commands
, argc
, 0, argv
, prompt
, cx
);
1194 command_Decode(struct bundle
*bundle
, char *buff
, int nb
, struct prompt
*prompt
,
1198 char *argv
[MAXARGS
];
1200 if ((argc
= command_Expand_Interpret(buff
, nb
, argv
, 0)) < 0)
1203 command_Run(bundle
, argc
, (char const *const *)argv
, prompt
, label
, NULL
);
1208 ShowCommand(struct cmdargs
const *arg
)
1211 log_Printf(LogWARN
, "show: Cannot show without a prompt\n");
1212 else if (arg
->argc
> arg
->argn
)
1213 FindExec(arg
->bundle
, ShowCommands
, arg
->argc
, arg
->argn
, arg
->argv
,
1214 arg
->prompt
, arg
->cx
);
1216 prompt_Printf(arg
->prompt
, "Use ``show ?'' to get a list.\n");
1222 TerminalCommand(struct cmdargs
const *arg
)
1225 log_Printf(LogWARN
, "term: Need a prompt\n");
1229 if (arg
->cx
->physical
->link
.lcp
.fsm
.state
> ST_CLOSED
) {
1230 prompt_Printf(arg
->prompt
, "LCP state is [%s]\n",
1231 State2Nam(arg
->cx
->physical
->link
.lcp
.fsm
.state
));
1235 datalink_Up(arg
->cx
, 0, 0);
1236 prompt_TtyTermMode(arg
->prompt
, arg
->cx
);
1241 QuitCommand(struct cmdargs
const *arg
)
1243 if (!arg
->prompt
|| prompt_IsController(arg
->prompt
) ||
1244 (arg
->argc
> arg
->argn
&& !strcasecmp(arg
->argv
[arg
->argn
], "all") &&
1245 (arg
->prompt
->auth
& LOCAL_AUTH
)))
1248 prompt_Destroy(arg
->prompt
, 1);
1254 OpenCommand(struct cmdargs
const *arg
)
1256 if (arg
->argc
== arg
->argn
)
1257 bundle_Open(arg
->bundle
, arg
->cx
? arg
->cx
->name
: NULL
, PHYS_ALL
, 1);
1258 else if (arg
->argc
== arg
->argn
+ 1) {
1259 if (!strcasecmp(arg
->argv
[arg
->argn
], "lcp")) {
1260 struct datalink
*cx
= arg
->cx
?
1261 arg
->cx
: bundle2datalink(arg
->bundle
, NULL
);
1263 if (cx
->physical
->link
.lcp
.fsm
.state
== ST_OPENED
)
1264 fsm_Reopen(&cx
->physical
->link
.lcp
.fsm
);
1266 bundle_Open(arg
->bundle
, cx
->name
, PHYS_ALL
, 1);
1268 log_Printf(LogWARN
, "open lcp: You must specify a link\n");
1269 } else if (!strcasecmp(arg
->argv
[arg
->argn
], "ccp")) {
1272 fp
= &command_ChooseLink(arg
)->ccp
.fsm
;
1273 if (fp
->link
->lcp
.fsm
.state
!= ST_OPENED
)
1274 log_Printf(LogWARN
, "open: LCP must be open before opening CCP\n");
1275 else if (fp
->state
== ST_OPENED
)
1278 fp
->open_mode
= 0; /* Not passive any more */
1279 if (fp
->state
== ST_STOPPED
) {
1287 } else if (!strcasecmp(arg
->argv
[arg
->argn
], "ipcp")) {
1289 log_Printf(LogWARN
, "open ipcp: You need not specify a link\n");
1290 if (arg
->bundle
->ncp
.ipcp
.fsm
.state
== ST_OPENED
)
1291 fsm_Reopen(&arg
->bundle
->ncp
.ipcp
.fsm
);
1293 bundle_Open(arg
->bundle
, NULL
, PHYS_ALL
, 1);
1303 CloseCommand(struct cmdargs
const *arg
)
1305 if (arg
->argc
== arg
->argn
)
1306 bundle_Close(arg
->bundle
, arg
->cx
? arg
->cx
->name
: NULL
, CLOSE_STAYDOWN
);
1307 else if (arg
->argc
== arg
->argn
+ 1) {
1308 if (!strcasecmp(arg
->argv
[arg
->argn
], "lcp"))
1309 bundle_Close(arg
->bundle
, arg
->cx
? arg
->cx
->name
: NULL
, CLOSE_LCP
);
1310 else if (!strcasecmp(arg
->argv
[arg
->argn
], "ccp") ||
1311 !strcasecmp(arg
->argv
[arg
->argn
], "ccp!")) {
1314 fp
= &command_ChooseLink(arg
)->ccp
.fsm
;
1315 if (fp
->state
== ST_OPENED
) {
1317 if (arg
->argv
[arg
->argn
][3] == '!')
1318 fp
->open_mode
= 0; /* Stay ST_CLOSED */
1320 fp
->open_mode
= OPEN_PASSIVE
; /* Wait for the peer to start */
1331 DownCommand(struct cmdargs
const *arg
)
1333 if (arg
->argc
== arg
->argn
) {
1335 datalink_Down(arg
->cx
, CLOSE_STAYDOWN
);
1337 bundle_Down(arg
->bundle
, CLOSE_STAYDOWN
);
1338 } else if (arg
->argc
== arg
->argn
+ 1) {
1339 if (!strcasecmp(arg
->argv
[arg
->argn
], "lcp")) {
1341 datalink_Down(arg
->cx
, CLOSE_LCP
);
1343 bundle_Down(arg
->bundle
, CLOSE_LCP
);
1344 } else if (!strcasecmp(arg
->argv
[arg
->argn
], "ccp")) {
1345 struct fsm
*fp
= arg
->cx
? &arg
->cx
->physical
->link
.ccp
.fsm
:
1346 &arg
->bundle
->ncp
.mp
.link
.ccp
.fsm
;
1357 SetModemSpeed(struct cmdargs
const *arg
)
1362 if (arg
->argc
> arg
->argn
&& *arg
->argv
[arg
->argn
]) {
1363 if (arg
->argc
> arg
->argn
+1) {
1364 log_Printf(LogWARN
, "SetModemSpeed: Too many arguments\n");
1367 if (strcasecmp(arg
->argv
[arg
->argn
], "sync") == 0) {
1368 physical_SetSync(arg
->cx
->physical
);
1372 speed
= strtol(arg
->argv
[arg
->argn
], &end
, 10);
1374 log_Printf(LogWARN
, "SetModemSpeed: Bad argument \"%s\"",
1375 arg
->argv
[arg
->argn
]);
1378 if (physical_SetSpeed(arg
->cx
->physical
, speed
))
1380 log_Printf(LogWARN
, "%s: Invalid speed\n", arg
->argv
[arg
->argn
]);
1382 log_Printf(LogWARN
, "SetModemSpeed: No speed specified\n");
1388 SetStoppedTimeout(struct cmdargs
const *arg
)
1390 struct link
*l
= &arg
->cx
->physical
->link
;
1392 l
->lcp
.fsm
.StoppedTimer
.load
= 0;
1393 l
->ccp
.fsm
.StoppedTimer
.load
= 0;
1394 if (arg
->argc
<= arg
->argn
+2) {
1395 if (arg
->argc
> arg
->argn
) {
1396 l
->lcp
.fsm
.StoppedTimer
.load
= atoi(arg
->argv
[arg
->argn
]) * SECTICKS
;
1397 if (arg
->argc
> arg
->argn
+1)
1398 l
->ccp
.fsm
.StoppedTimer
.load
= atoi(arg
->argv
[arg
->argn
+1]) * SECTICKS
;
1406 SetServer(struct cmdargs
const *arg
)
1410 if (arg
->argc
> arg
->argn
&& arg
->argc
< arg
->argn
+4) {
1411 const char *port
, *passwd
, *mask
;
1415 port
= arg
->argv
[arg
->argn
];
1416 if (arg
->argc
== arg
->argn
+ 2) {
1417 passwd
= arg
->argv
[arg
->argn
+1];
1419 } else if (arg
->argc
== arg
->argn
+ 3) {
1420 passwd
= arg
->argv
[arg
->argn
+1];
1421 mask
= arg
->argv
[arg
->argn
+2];
1422 mlen
= strlen(mask
);
1423 if (mlen
== 0 || mlen
> 4 || strspn(mask
, "01234567") != mlen
||
1424 (mlen
== 4 && *mask
!= '0')) {
1425 log_Printf(LogWARN
, "%s %s: %s: Invalid mask\n",
1426 arg
->argv
[arg
->argn
- 2], arg
->argv
[arg
->argn
- 1], mask
);
1429 } else if (arg
->argc
!= arg
->argn
+ 1)
1431 else if (strcasecmp(port
, "none") == 0) {
1432 if (server_Clear(arg
->bundle
))
1433 log_Printf(LogPHASE
, "Disabled server socket\n");
1435 } else if (strcasecmp(port
, "open") == 0) {
1436 switch (server_Reopen(arg
->bundle
)) {
1440 log_Printf(LogWARN
, "Failed to reopen server port\n");
1443 log_Printf(LogWARN
, "Cannot reopen unset server socket\n");
1449 } else if (strcasecmp(port
, "closed") == 0) {
1450 if (server_Close(arg
->bundle
))
1451 log_Printf(LogPHASE
, "Closed server socket\n");
1453 log_Printf(LogWARN
, "Server socket not open\n");
1459 strncpy(server
.cfg
.passwd
, passwd
, sizeof server
.cfg
.passwd
- 1);
1460 server
.cfg
.passwd
[sizeof server
.cfg
.passwd
- 1] = '\0';
1464 char *ptr
, name
[LINE_LEN
+ 12];
1468 else for (imask
= mlen
= 0; mask
[mlen
]; mlen
++)
1469 imask
= (imask
* 8) + mask
[mlen
] - '0';
1471 ptr
= strstr(port
, "%d");
1473 snprintf(name
, sizeof name
, "%.*s%d%s",
1474 (int)(ptr
- port
), port
, arg
->bundle
->unit
, ptr
+ 2);
1477 res
= server_LocalOpen(arg
->bundle
, port
, imask
);
1488 if (strspn(port
, "0123456789") != strlen(port
)) {
1491 if ((s
= getservbyname(port
, "tcp")) == NULL
) {
1493 log_Printf(LogWARN
, "%s: Invalid port or service\n", port
);
1495 iport
= ntohs(s
->s_port
);
1501 iport
+= arg
->bundle
->unit
;
1502 res
= server_TcpOpen(arg
->bundle
, iport
);
1512 SetEscape(struct cmdargs
const *arg
)
1515 int argc
= arg
->argc
- arg
->argn
;
1516 char const *const *argv
= arg
->argv
+ arg
->argn
;
1518 for (code
= 0; code
< 33; code
++)
1519 arg
->cx
->physical
->async
.cfg
.EscMap
[code
] = 0;
1521 while (argc
-- > 0) {
1522 sscanf(*argv
++, "%x", &code
);
1524 arg
->cx
->physical
->async
.cfg
.EscMap
[code
>> 3] |= (1 << (code
& 7));
1525 arg
->cx
->physical
->async
.cfg
.EscMap
[32] = 1;
1531 SetInterfaceAddr(struct cmdargs
const *arg
)
1533 struct ncp
*ncp
= &arg
->bundle
->ncp
;
1534 struct ncpaddr ncpaddr
;
1535 const char *hisaddr
;
1537 if (arg
->argc
> arg
->argn
+ 4)
1541 memset(&ncp
->ipcp
.cfg
.my_range
, '\0', sizeof ncp
->ipcp
.cfg
.my_range
);
1542 memset(&ncp
->ipcp
.cfg
.peer_range
, '\0', sizeof ncp
->ipcp
.cfg
.peer_range
);
1543 ncp
->ipcp
.cfg
.HaveTriggerAddress
= 0;
1544 ncp
->ipcp
.cfg
.netmask
.s_addr
= INADDR_ANY
;
1545 iplist_reset(&ncp
->ipcp
.cfg
.peer_list
);
1547 if (arg
->argc
> arg
->argn
) {
1548 if (!ncprange_aton(&ncp
->ipcp
.cfg
.my_range
, ncp
, arg
->argv
[arg
->argn
]))
1550 if (arg
->argc
> arg
->argn
+1) {
1551 hisaddr
= arg
->argv
[arg
->argn
+1];
1552 if (arg
->argc
> arg
->argn
+2) {
1553 ncp
->ipcp
.ifmask
= ncp
->ipcp
.cfg
.netmask
=
1554 GetIpAddr(arg
->argv
[arg
->argn
+2]);
1555 if (arg
->argc
> arg
->argn
+3) {
1556 ncp
->ipcp
.cfg
.TriggerAddress
= GetIpAddr(arg
->argv
[arg
->argn
+3]);
1557 ncp
->ipcp
.cfg
.HaveTriggerAddress
= 1;
1563 /* 0.0.0.0 means any address (0 bits) */
1564 ncpaddr_getip4(&ncpaddr
, &ncp
->ipcp
.my_ip
);
1565 ncprange_getaddr(&ncp
->ipcp
.cfg
.my_range
, &ncpaddr
);
1566 if (ncp
->ipcp
.my_ip
.s_addr
== INADDR_ANY
)
1567 ncprange_setwidth(&ncp
->ipcp
.cfg
.my_range
, 0);
1568 bundle_AdjustFilters(arg
->bundle
, &ncpaddr
, NULL
);
1570 if (hisaddr
&& !ipcp_UseHisaddr(arg
->bundle
, hisaddr
,
1571 arg
->bundle
->phys_type
.all
& PHYS_AUTO
))
1578 SetRetry(int argc
, char const *const *argv
, u_int
*timeout
, u_int
*maxreq
,
1579 u_int
*maxtrm
, int def
)
1582 *timeout
= DEF_FSMRETRY
;
1587 long l
= atol(argv
[0]);
1589 if (l
< MIN_FSMRETRY
) {
1590 log_Printf(LogWARN
, "%ld: Invalid FSM retry period - min %d\n",
1599 log_Printf(LogWARN
, "%ld: Invalid FSM REQ tries - changed to 1\n", l
);
1604 if (argc
> 2 && maxtrm
!= NULL
) {
1607 log_Printf(LogWARN
, "%ld: Invalid FSM TRM tries - changed to 1\n", l
);
1619 SetVariable(struct cmdargs
const *arg
)
1621 long long_val
, param
= (long)arg
->cmd
->args
;
1622 int mode
, dummyint
, f
, first
, res
;
1625 struct datalink
*cx
= arg
->cx
; /* LOCAL_CX uses this */
1626 struct link
*l
= command_ChooseLink(arg
); /* LOCAL_CX_OPT uses this */
1627 struct in_addr
*ipaddr
;
1628 struct ncpaddr ncpaddr
[2];
1630 if (arg
->argc
> arg
->argn
)
1631 argp
= arg
->argv
[arg
->argn
];
1637 if ((arg
->cmd
->lauth
& LOCAL_CX
) && !cx
) {
1638 log_Printf(LogWARN
, "set %s: No context (use the `link' command)\n",
1641 } else if (cx
&& !(arg
->cmd
->lauth
& (LOCAL_CX
|LOCAL_CX_OPT
))) {
1642 log_Printf(LogWARN
, "set %s: Redundant context (%s) ignored\n",
1643 arg
->cmd
->name
, cx
->name
);
1649 strncpy(arg
->bundle
->cfg
.auth
.key
, argp
,
1650 sizeof arg
->bundle
->cfg
.auth
.key
- 1);
1651 arg
->bundle
->cfg
.auth
.key
[sizeof arg
->bundle
->cfg
.auth
.key
- 1] = '\0';
1655 switch (bundle_Phase(arg
->bundle
)) {
1657 log_Printf(LogWARN
, "Altering authname while at phase %s\n",
1658 bundle_PhaseName(arg
->bundle
));
1661 case PHASE_ESTABLISH
:
1662 strncpy(arg
->bundle
->cfg
.auth
.name
, argp
,
1663 sizeof arg
->bundle
->cfg
.auth
.name
- 1);
1664 arg
->bundle
->cfg
.auth
.name
[sizeof arg
->bundle
->cfg
.auth
.name
-1] = '\0';
1670 if (arg
->argc
== arg
->argn
+ 3) {
1674 v1
= strtol(arg
->argv
[arg
->argn
], &end
, 0);
1675 if (v1
< 0 || *end
) {
1676 log_Printf(LogWARN
, "autoload: %s: Invalid min percentage\n",
1677 arg
->argv
[arg
->argn
]);
1682 v2
= strtol(arg
->argv
[arg
->argn
+ 1], &end
, 0);
1683 if (v2
< 0 || *end
) {
1684 log_Printf(LogWARN
, "autoload: %s: Invalid max percentage\n",
1685 arg
->argv
[arg
->argn
+ 1]);
1695 v3
= strtol(arg
->argv
[arg
->argn
+ 2], &end
, 0);
1696 if (v3
<= 0 || *end
) {
1697 log_Printf(LogWARN
, "autoload: %s: Invalid throughput period\n",
1698 arg
->argv
[arg
->argn
+ 2]);
1703 arg
->bundle
->ncp
.mp
.cfg
.autoload
.min
= v1
;
1704 arg
->bundle
->ncp
.mp
.cfg
.autoload
.max
= v2
;
1705 arg
->bundle
->ncp
.mp
.cfg
.autoload
.period
= v3
;
1706 mp_RestartAutoloadTimer(&arg
->bundle
->ncp
.mp
);
1708 log_Printf(LogWARN
, "Set autoload requires three arguments\n");
1714 strncpy(cx
->cfg
.script
.dial
, argp
, sizeof cx
->cfg
.script
.dial
- 1);
1715 cx
->cfg
.script
.dial
[sizeof cx
->cfg
.script
.dial
- 1] = '\0';
1719 strncpy(cx
->cfg
.script
.login
, argp
, sizeof cx
->cfg
.script
.login
- 1);
1720 cx
->cfg
.script
.login
[sizeof cx
->cfg
.script
.login
- 1] = '\0';
1724 if (arg
->argc
> arg
->argn
) {
1725 l
->ccp
.cfg
.deflate
.out
.winsize
= atoi(arg
->argv
[arg
->argn
]);
1726 if (l
->ccp
.cfg
.deflate
.out
.winsize
< 8 ||
1727 l
->ccp
.cfg
.deflate
.out
.winsize
> 15) {
1728 log_Printf(LogWARN
, "%d: Invalid outgoing window size\n",
1729 l
->ccp
.cfg
.deflate
.out
.winsize
);
1730 l
->ccp
.cfg
.deflate
.out
.winsize
= 15;
1732 if (arg
->argc
> arg
->argn
+1) {
1733 l
->ccp
.cfg
.deflate
.in
.winsize
= atoi(arg
->argv
[arg
->argn
+1]);
1734 if (l
->ccp
.cfg
.deflate
.in
.winsize
< 8 ||
1735 l
->ccp
.cfg
.deflate
.in
.winsize
> 15) {
1736 log_Printf(LogWARN
, "%d: Invalid incoming window size\n",
1737 l
->ccp
.cfg
.deflate
.in
.winsize
);
1738 l
->ccp
.cfg
.deflate
.in
.winsize
= 15;
1741 l
->ccp
.cfg
.deflate
.in
.winsize
= 0;
1743 log_Printf(LogWARN
, "No window size specified\n");
1750 if (arg
->argc
> arg
->argn
+ 2) {
1755 if (arg
->argc
== arg
->argn
) {
1756 l
->ccp
.cfg
.mppe
.keybits
= 0;
1757 l
->ccp
.cfg
.mppe
.state
= MPPE_ANYSTATE
;
1758 l
->ccp
.cfg
.mppe
.required
= 0;
1762 if (!strcmp(argp
, "*"))
1765 long_val
= atol(argp
);
1766 if (long_val
!= 40 && long_val
!= 56 && long_val
!= 128) {
1767 log_Printf(LogWARN
, "%s: Invalid bits value\n", argp
);
1773 if (arg
->argc
== arg
->argn
+ 2) {
1774 if (!strcmp(arg
->argv
[arg
->argn
+ 1], "*"))
1775 l
->ccp
.cfg
.mppe
.state
= MPPE_ANYSTATE
;
1776 else if (!strcasecmp(arg
->argv
[arg
->argn
+ 1], "stateless"))
1777 l
->ccp
.cfg
.mppe
.state
= MPPE_STATELESS
;
1778 else if (!strcasecmp(arg
->argv
[arg
->argn
+ 1], "stateful"))
1779 l
->ccp
.cfg
.mppe
.state
= MPPE_STATEFUL
;
1781 log_Printf(LogWARN
, "%s: Invalid state value\n",
1782 arg
->argv
[arg
->argn
+ 1]);
1787 l
->ccp
.cfg
.mppe
.state
= MPPE_ANYSTATE
;
1788 l
->ccp
.cfg
.mppe
.keybits
= long_val
;
1789 l
->ccp
.cfg
.mppe
.required
= 1;
1794 physical_SetDeviceList(cx
->physical
, arg
->argc
- arg
->argn
,
1795 arg
->argv
+ arg
->argn
);
1799 if (arg
->argc
> arg
->argn
) {
1801 sscanf(argp
, "%lx", &ulong_val
);
1802 cx
->physical
->link
.lcp
.cfg
.accmap
= (u_int32_t
)ulong_val
;
1804 log_Printf(LogWARN
, "No accmap specified\n");
1810 mode
= Nam2mode(argp
);
1811 if (mode
== PHYS_NONE
|| mode
== PHYS_ALL
) {
1812 log_Printf(LogWARN
, "%s: Invalid mode\n", argp
);
1816 bundle_SetMode(arg
->bundle
, cx
, mode
);
1820 switch (bundle_Phase(arg
->bundle
)) {
1823 case PHASE_ESTABLISH
:
1824 /* Make sure none of our links are DATALINK_LCP or greater */
1825 if (bundle_HighestState(arg
->bundle
) >= DATALINK_LCP
) {
1826 log_Printf(LogWARN
, "mrru: Only changeable before LCP negotiations\n");
1832 log_Printf(LogWARN
, "mrru: Only changeable at phase DEAD/ESTABLISH\n");
1838 long_val
= atol(argp
);
1839 if (long_val
&& long_val
< MIN_MRU
) {
1840 log_Printf(LogWARN
, "MRRU %ld: too small - min %d\n", long_val
, MIN_MRU
);
1843 } else if (long_val
> MAX_MRU
) {
1844 log_Printf(LogWARN
, "MRRU %ld: too big - max %d\n", long_val
, MAX_MRU
);
1848 arg
->bundle
->ncp
.mp
.cfg
.mrru
= long_val
;
1852 long_val
= 0; /* silence gcc */
1853 change
= NULL
; /* silence gcc */
1854 switch(arg
->argc
- arg
->argn
) {
1856 if (argp
[strspn(argp
, "0123456789")] != '\0') {
1862 long_val
= atol(argp
);
1863 change
= &l
->lcp
.cfg
.mru
;
1864 if (long_val
> l
->lcp
.cfg
.max_mru
) {
1865 log_Printf(LogWARN
, "MRU %ld: too large - max set to %d\n", long_val
,
1866 l
->lcp
.cfg
.max_mru
);
1872 if (strcasecmp(argp
, "max") && strcasecmp(argp
, "maximum")) {
1876 long_val
= atol(arg
->argv
[arg
->argn
+ 1]);
1877 change
= &l
->lcp
.cfg
.max_mru
;
1878 if (long_val
> MAX_MRU
) {
1879 log_Printf(LogWARN
, "MRU %ld: too large - maximum is %d\n", long_val
,
1894 else if (long_val
< MIN_MRU
) {
1895 log_Printf(LogWARN
, "MRU %ld: too small - min %d\n", long_val
, MIN_MRU
);
1898 } else if (long_val
> MAX_MRU
) {
1899 log_Printf(LogWARN
, "MRU %ld: too big - max %d\n", long_val
, MAX_MRU
);
1904 if (l
->lcp
.cfg
.mru
> *change
)
1905 l
->lcp
.cfg
.mru
= *change
;
1909 long_val
= 0; /* silence gcc */
1910 change
= NULL
; /* silence gcc */
1911 switch(arg
->argc
- arg
->argn
) {
1913 if (argp
[strspn(argp
, "0123456789")] != '\0') {
1919 long_val
= atol(argp
);
1920 change
= &l
->lcp
.cfg
.mtu
;
1921 if (long_val
> l
->lcp
.cfg
.max_mtu
) {
1922 log_Printf(LogWARN
, "MTU %ld: too large - max set to %d\n", long_val
,
1923 l
->lcp
.cfg
.max_mtu
);
1929 if (strcasecmp(argp
, "max") && strcasecmp(argp
, "maximum")) {
1933 long_val
= atol(arg
->argv
[arg
->argn
+ 1]);
1934 change
= &l
->lcp
.cfg
.max_mtu
;
1935 if (long_val
> MAX_MTU
) {
1936 log_Printf(LogWARN
, "MTU %ld: too large - maximum is %d\n", long_val
,
1950 if (long_val
&& long_val
< MIN_MTU
) {
1951 log_Printf(LogWARN
, "MTU %ld: too small - min %d\n", long_val
, MIN_MTU
);
1954 } else if (long_val
> MAX_MTU
) {
1955 log_Printf(LogWARN
, "MTU %ld: too big - max %d\n", long_val
, MAX_MTU
);
1960 if (l
->lcp
.cfg
.mtu
> *change
)
1961 l
->lcp
.cfg
.mtu
= *change
;
1965 if (strcasecmp(argp
, "active") == 0)
1966 cx
->physical
->link
.lcp
.cfg
.openmode
= arg
->argc
> arg
->argn
+1 ?
1967 atoi(arg
->argv
[arg
->argn
+1]) : 1;
1968 else if (strcasecmp(argp
, "passive") == 0)
1969 cx
->physical
->link
.lcp
.cfg
.openmode
= OPEN_PASSIVE
;
1971 log_Printf(LogWARN
, "%s: Invalid openmode\n", argp
);
1977 strncpy(cx
->cfg
.phone
.list
, argp
, sizeof cx
->cfg
.phone
.list
- 1);
1978 cx
->cfg
.phone
.list
[sizeof cx
->cfg
.phone
.list
- 1] = '\0';
1979 cx
->phone
.alt
= cx
->phone
.next
= NULL
;
1983 strncpy(cx
->cfg
.script
.hangup
, argp
, sizeof cx
->cfg
.script
.hangup
- 1);
1984 cx
->cfg
.script
.hangup
[sizeof cx
->cfg
.script
.hangup
- 1] = '\0';
1988 long_val
= atol(argp
);
1989 arg
->bundle
->cfg
.ifqueue
= long_val
< 0 ? 0 : long_val
;
1993 strncpy(cx
->cfg
.script
.logout
, argp
, sizeof cx
->cfg
.script
.logout
- 1);
1994 cx
->cfg
.script
.logout
[sizeof cx
->cfg
.script
.logout
- 1] = '\0';
1997 case VAR_IDLETIMEOUT
:
1998 if (arg
->argc
> arg
->argn
+2) {
1999 log_Printf(LogWARN
, "Too many idle timeout values\n");
2001 } else if (arg
->argc
== arg
->argn
) {
2002 log_Printf(LogWARN
, "Too few idle timeout values\n");
2007 timeout
= atoi(argp
);
2008 min
= arg
->argc
== arg
->argn
+ 2 ? atoi(arg
->argv
[arg
->argn
+ 1]) : -1;
2009 bundle_SetIdleTimer(arg
->bundle
, timeout
, min
);
2014 long_val
= atol(argp
);
2015 if (long_val
< MIN_LQRPERIOD
) {
2016 log_Printf(LogWARN
, "%ld: Invalid lqr period - min %d\n",
2017 long_val
, MIN_LQRPERIOD
);
2020 l
->lcp
.cfg
.lqrperiod
= long_val
;
2024 res
= SetRetry(arg
->argc
- arg
->argn
, arg
->argv
+ arg
->argn
,
2025 &cx
->physical
->link
.lcp
.cfg
.fsm
.timeout
,
2026 &cx
->physical
->link
.lcp
.cfg
.fsm
.maxreq
,
2027 &cx
->physical
->link
.lcp
.cfg
.fsm
.maxtrm
, DEF_FSMTRIES
);
2031 res
= SetRetry(arg
->argc
- arg
->argn
, arg
->argv
+ arg
->argn
,
2032 &cx
->chap
.auth
.cfg
.fsm
.timeout
,
2033 &cx
->chap
.auth
.cfg
.fsm
.maxreq
, NULL
, DEF_FSMAUTHTRIES
);
2037 res
= SetRetry(arg
->argc
- arg
->argn
, arg
->argv
+ arg
->argn
,
2038 &cx
->pap
.cfg
.fsm
.timeout
, &cx
->pap
.cfg
.fsm
.maxreq
,
2039 NULL
, DEF_FSMAUTHTRIES
);
2043 res
= SetRetry(arg
->argc
- arg
->argn
, arg
->argv
+ arg
->argn
,
2044 &l
->ccp
.cfg
.fsm
.timeout
, &l
->ccp
.cfg
.fsm
.maxreq
,
2045 &l
->ccp
.cfg
.fsm
.maxtrm
, DEF_FSMTRIES
);
2049 res
= SetRetry(arg
->argc
- arg
->argn
, arg
->argv
+ arg
->argn
,
2050 &arg
->bundle
->ncp
.ipcp
.cfg
.fsm
.timeout
,
2051 &arg
->bundle
->ncp
.ipcp
.cfg
.fsm
.maxreq
,
2052 &arg
->bundle
->ncp
.ipcp
.cfg
.fsm
.maxtrm
, DEF_FSMTRIES
);
2056 case VAR_IPV6CPRETRY
:
2057 res
= SetRetry(arg
->argc
- arg
->argn
, arg
->argv
+ arg
->argn
,
2058 &arg
->bundle
->ncp
.ipv6cp
.cfg
.fsm
.timeout
,
2059 &arg
->bundle
->ncp
.ipv6cp
.cfg
.fsm
.maxreq
,
2060 &arg
->bundle
->ncp
.ipv6cp
.cfg
.fsm
.maxtrm
, DEF_FSMTRIES
);
2066 if (param
== VAR_DNS
) {
2067 ipaddr
= arg
->bundle
->ncp
.ipcp
.cfg
.ns
.dns
;
2068 ipaddr
[0].s_addr
= ipaddr
[1].s_addr
= INADDR_NONE
;
2070 ipaddr
= arg
->bundle
->ncp
.ipcp
.cfg
.ns
.nbns
;
2071 ipaddr
[0].s_addr
= ipaddr
[1].s_addr
= INADDR_ANY
;
2074 if (arg
->argc
> arg
->argn
) {
2075 ncpaddr_aton(ncpaddr
, &arg
->bundle
->ncp
, arg
->argv
[arg
->argn
]);
2076 if (!ncpaddr_getip4(ncpaddr
, ipaddr
))
2078 if (arg
->argc
> arg
->argn
+1) {
2079 ncpaddr_aton(ncpaddr
+ 1, &arg
->bundle
->ncp
, arg
->argv
[arg
->argn
+ 1]);
2080 if (!ncpaddr_getip4(ncpaddr
+ 1, ipaddr
+ 1))
2084 if (ipaddr
[0].s_addr
== INADDR_ANY
) {
2085 ipaddr
[0] = ipaddr
[1];
2086 ipaddr
[1].s_addr
= INADDR_ANY
;
2088 if (ipaddr
[0].s_addr
== INADDR_NONE
) {
2089 ipaddr
[0] = ipaddr
[1];
2090 ipaddr
[1].s_addr
= INADDR_NONE
;
2096 cx
->cfg
.callback
.opmask
= 0;
2097 for (dummyint
= arg
->argn
; dummyint
< arg
->argc
; dummyint
++) {
2098 if (!strcasecmp(arg
->argv
[dummyint
], "auth"))
2099 cx
->cfg
.callback
.opmask
|= CALLBACK_BIT(CALLBACK_AUTH
);
2100 else if (!strcasecmp(arg
->argv
[dummyint
], "cbcp"))
2101 cx
->cfg
.callback
.opmask
|= CALLBACK_BIT(CALLBACK_CBCP
);
2102 else if (!strcasecmp(arg
->argv
[dummyint
], "e.164")) {
2103 if (dummyint
== arg
->argc
- 1)
2104 log_Printf(LogWARN
, "No E.164 arg (E.164 ignored) !\n");
2106 cx
->cfg
.callback
.opmask
|= CALLBACK_BIT(CALLBACK_E164
);
2107 strncpy(cx
->cfg
.callback
.msg
, arg
->argv
[++dummyint
],
2108 sizeof cx
->cfg
.callback
.msg
- 1);
2109 cx
->cfg
.callback
.msg
[sizeof cx
->cfg
.callback
.msg
- 1] = '\0';
2111 } else if (!strcasecmp(arg
->argv
[dummyint
], "none"))
2112 cx
->cfg
.callback
.opmask
|= CALLBACK_BIT(CALLBACK_NONE
);
2118 if (cx
->cfg
.callback
.opmask
== CALLBACK_BIT(CALLBACK_NONE
))
2119 cx
->cfg
.callback
.opmask
= 0;
2123 cx
->cfg
.cbcp
.delay
= 0;
2124 *cx
->cfg
.cbcp
.phone
= '\0';
2125 cx
->cfg
.cbcp
.fsmretry
= DEF_FSMRETRY
;
2126 if (arg
->argc
> arg
->argn
) {
2127 strncpy(cx
->cfg
.cbcp
.phone
, arg
->argv
[arg
->argn
],
2128 sizeof cx
->cfg
.cbcp
.phone
- 1);
2129 cx
->cfg
.cbcp
.phone
[sizeof cx
->cfg
.cbcp
.phone
- 1] = '\0';
2130 if (arg
->argc
> arg
->argn
+ 1) {
2131 cx
->cfg
.cbcp
.delay
= atoi(arg
->argv
[arg
->argn
+ 1]);
2132 if (arg
->argc
> arg
->argn
+ 2) {
2133 long_val
= atol(arg
->argv
[arg
->argn
+ 2]);
2134 if (long_val
< MIN_FSMRETRY
)
2135 log_Printf(LogWARN
, "%ld: Invalid CBCP FSM retry period - min %d\n",
2136 long_val
, MIN_FSMRETRY
);
2138 cx
->cfg
.cbcp
.fsmretry
= long_val
;
2145 arg
->bundle
->cfg
.choked
.timeout
= atoi(argp
);
2146 if (arg
->bundle
->cfg
.choked
.timeout
<= 0)
2147 arg
->bundle
->cfg
.choked
.timeout
= CHOKED_TIMEOUT
;
2151 long_val
= atol(argp
);
2152 arg
->bundle
->ncp
.cfg
.sendpipe
= long_val
;
2156 long_val
= atol(argp
);
2157 arg
->bundle
->ncp
.cfg
.recvpipe
= long_val
;
2163 *arg
->bundle
->radius
.cfg
.file
= '\0';
2164 else if (access(argp
, R_OK
)) {
2165 log_Printf(LogWARN
, "%s: %s\n", argp
, strerror(errno
));
2169 strncpy(arg
->bundle
->radius
.cfg
.file
, argp
,
2170 sizeof arg
->bundle
->radius
.cfg
.file
- 1);
2171 arg
->bundle
->radius
.cfg
.file
2172 [sizeof arg
->bundle
->radius
.cfg
.file
- 1] = '\0';
2179 if (strcasecmp(argp
, "off")) {
2180 long_val
= atol(argp
);
2183 cx
->physical
->cfg
.cd
.delay
= long_val
;
2184 cx
->physical
->cfg
.cd
.necessity
= argp
[strlen(argp
)-1] == '!' ?
2185 CD_REQUIRED
: CD_VARIABLE
;
2187 cx
->physical
->cfg
.cd
.necessity
= CD_NOTREQUIRED
;
2189 cx
->physical
->cfg
.cd
.delay
= 0;
2190 cx
->physical
->cfg
.cd
.necessity
= CD_DEFAULT
;
2195 if (arg
->argc
== arg
->argn
+ 1)
2196 res
= physical_SetParity(arg
->cx
->physical
, argp
);
2198 log_Printf(LogWARN
, "Parity value must be odd, even or none\n");
2204 if (strcasecmp(argp
, "on") == 0)
2205 physical_SetRtsCts(arg
->cx
->physical
, 1);
2206 else if (strcasecmp(argp
, "off") == 0)
2207 physical_SetRtsCts(arg
->cx
->physical
, 0);
2209 log_Printf(LogWARN
, "RTS/CTS value must be on or off\n");
2214 case VAR_URGENTPORTS
:
2215 if (arg
->argn
== arg
->argc
) {
2216 ncp_SetUrgentTOS(&arg
->bundle
->ncp
);
2217 ncp_ClearUrgentTcpPorts(&arg
->bundle
->ncp
);
2218 ncp_ClearUrgentUdpPorts(&arg
->bundle
->ncp
);
2219 } else if (!strcasecmp(arg
->argv
[arg
->argn
], "udp")) {
2220 ncp_SetUrgentTOS(&arg
->bundle
->ncp
);
2221 if (arg
->argn
== arg
->argc
- 1)
2222 ncp_ClearUrgentUdpPorts(&arg
->bundle
->ncp
);
2223 else for (f
= arg
->argn
+ 1; f
< arg
->argc
; f
++)
2224 if (*arg
->argv
[f
] == '+')
2225 ncp_AddUrgentUdpPort(&arg
->bundle
->ncp
, atoi(arg
->argv
[f
] + 1));
2226 else if (*arg
->argv
[f
] == '-')
2227 ncp_RemoveUrgentUdpPort(&arg
->bundle
->ncp
, atoi(arg
->argv
[f
] + 1));
2230 ncp_ClearUrgentUdpPorts(&arg
->bundle
->ncp
);
2231 ncp_AddUrgentUdpPort(&arg
->bundle
->ncp
, atoi(arg
->argv
[f
]));
2233 } else if (arg
->argn
== arg
->argc
- 1 &&
2234 !strcasecmp(arg
->argv
[arg
->argn
], "none")) {
2235 ncp_ClearUrgentTcpPorts(&arg
->bundle
->ncp
);
2236 ncp_ClearUrgentUdpPorts(&arg
->bundle
->ncp
);
2237 ncp_ClearUrgentTOS(&arg
->bundle
->ncp
);
2239 ncp_SetUrgentTOS(&arg
->bundle
->ncp
);
2241 if (!strcasecmp(arg
->argv
[first
], "tcp") && ++first
== arg
->argc
)
2242 ncp_ClearUrgentTcpPorts(&arg
->bundle
->ncp
);
2244 for (f
= first
; f
< arg
->argc
; f
++)
2245 if (*arg
->argv
[f
] == '+')
2246 ncp_AddUrgentTcpPort(&arg
->bundle
->ncp
, atoi(arg
->argv
[f
] + 1));
2247 else if (*arg
->argv
[f
] == '-')
2248 ncp_RemoveUrgentTcpPort(&arg
->bundle
->ncp
, atoi(arg
->argv
[f
] + 1));
2251 ncp_ClearUrgentTcpPorts(&arg
->bundle
->ncp
);
2252 ncp_AddUrgentTcpPort(&arg
->bundle
->ncp
, atoi(arg
->argv
[f
]));
2261 static struct cmdtab
const SetCommands
[] = {
2262 {"accmap", NULL
, SetVariable
, LOCAL_AUTH
| LOCAL_CX
,
2263 "accmap value", "set accmap hex-value", (const void *)VAR_ACCMAP
},
2264 {"authkey", "key", SetVariable
, LOCAL_AUTH
,
2265 "authentication key", "set authkey|key key", (const void *)VAR_AUTHKEY
},
2266 {"authname", NULL
, SetVariable
, LOCAL_AUTH
,
2267 "authentication name", "set authname name", (const void *)VAR_AUTHNAME
},
2268 {"autoload", NULL
, SetVariable
, LOCAL_AUTH
,
2269 "auto link [de]activation", "set autoload maxtime maxload mintime minload",
2270 (const void *)VAR_AUTOLOAD
},
2271 {"bandwidth", NULL
, mp_SetDatalinkBandwidth
, LOCAL_AUTH
| LOCAL_CX
,
2272 "datalink bandwidth", "set bandwidth value"},
2273 {"callback", NULL
, SetVariable
, LOCAL_AUTH
| LOCAL_CX
,
2274 "callback control", "set callback [none|auth|cbcp|"
2275 "E.164 *|number[,number]...]...", (const void *)VAR_CALLBACK
},
2276 {"cbcp", NULL
, SetVariable
, LOCAL_AUTH
| LOCAL_CX
,
2277 "CBCP control", "set cbcp [*|phone[,phone...] [delay [timeout]]]",
2278 (const void *)VAR_CBCP
},
2279 {"ccpretry", "ccpretries", SetVariable
, LOCAL_AUTH
| LOCAL_CX_OPT
,
2280 "CCP retries", "set ccpretry value [attempts]", (const void *)VAR_CCPRETRY
},
2281 {"cd", NULL
, SetVariable
, LOCAL_AUTH
| LOCAL_CX
, "Carrier delay requirement",
2282 "set cd value[!]", (const void *)VAR_CD
},
2283 {"chapretry", "chapretries", SetVariable
, LOCAL_AUTH
| LOCAL_CX
,
2284 "CHAP retries", "set chapretry value [attempts]",
2285 (const void *)VAR_CHAPRETRY
},
2286 {"choked", NULL
, SetVariable
, LOCAL_AUTH
,
2287 "choked timeout", "set choked [secs]", (const void *)VAR_CHOKED
},
2288 {"ctsrts", "crtscts", SetVariable
, LOCAL_AUTH
| LOCAL_CX
,
2289 "Use hardware flow control", "set ctsrts [on|off]",
2290 (const char *)VAR_CRTSCTS
},
2291 {"deflate", NULL
, SetVariable
, LOCAL_AUTH
| LOCAL_CX_OPT
,
2292 "deflate window sizes", "set deflate out-winsize in-winsize",
2293 (const void *) VAR_WINSIZE
},
2295 {"mppe", NULL
, SetVariable
, LOCAL_AUTH
| LOCAL_CX_OPT
,
2296 "MPPE key size and state", "set mppe [40|56|128|* [stateful|stateless|*]]",
2297 (const void *) VAR_MPPE
},
2299 {"device", "line", SetVariable
, LOCAL_AUTH
| LOCAL_CX
,
2300 "physical device name", "set device|line device-name[,device-name]",
2301 (const void *) VAR_DEVICE
},
2302 {"dial", NULL
, SetVariable
, LOCAL_AUTH
| LOCAL_CX
,
2303 "dialing script", "set dial chat-script", (const void *) VAR_DIAL
},
2304 {"dns", NULL
, SetVariable
, LOCAL_AUTH
, "Domain Name Server",
2305 "set dns pri-addr [sec-addr]", (const void *)VAR_DNS
},
2306 {"enddisc", NULL
, mp_SetEnddisc
, LOCAL_AUTH
,
2307 "Endpoint Discriminator", "set enddisc [IP|magic|label|psn value]"},
2308 {"escape", NULL
, SetEscape
, LOCAL_AUTH
| LOCAL_CX
,
2309 "escape characters", "set escape hex-digit ..."},
2310 {"filter", NULL
, filter_Set
, LOCAL_AUTH
,
2311 "packet filters", "set filter alive|dial|in|out rule-no permit|deny "
2312 "[src_addr[/width]] [dst_addr[/width]] [proto "
2313 "[src [lt|eq|gt port]] [dst [lt|eq|gt port]] [estab] [syn] [finrst]]"},
2314 {"hangup", NULL
, SetVariable
, LOCAL_AUTH
| LOCAL_CX
,
2315 "hangup script", "set hangup chat-script", (const void *) VAR_HANGUP
},
2316 {"ifaddr", NULL
, SetInterfaceAddr
, LOCAL_AUTH
, "destination address",
2317 "set ifaddr [src-addr [dst-addr [netmask [trg-addr]]]]"},
2318 {"ifqueue", NULL
, SetVariable
, LOCAL_AUTH
, "interface queue",
2319 "set ifqueue packets", (const void *)VAR_IFQUEUE
},
2320 {"ipcpretry", "ipcpretries", SetVariable
, LOCAL_AUTH
, "IPCP retries",
2321 "set ipcpretry value [attempts]", (const void *)VAR_IPCPRETRY
},
2322 {"ipv6cpretry", "ipv6cpretries", SetVariable
, LOCAL_AUTH
, "IPV6CP retries",
2323 "set ipv6cpretry value [attempts]", (const void *)VAR_IPV6CPRETRY
},
2324 {"lcpretry", "lcpretries", SetVariable
, LOCAL_AUTH
| LOCAL_CX
, "LCP retries",
2325 "set lcpretry value [attempts]", (const void *)VAR_LCPRETRY
},
2326 {"log", NULL
, log_SetLevel
, LOCAL_AUTH
, "log level",
2327 "set log [local] [+|-]all|async|cbcp|ccp|chat|command|connect|debug|dns|hdlc|"
2328 "id0|ipcp|lcp|lqm|phase|physical|sync|tcp/ip|timer|tun..."},
2329 {"login", NULL
, SetVariable
, LOCAL_AUTH
| LOCAL_CX
,
2330 "login script", "set login chat-script", (const void *) VAR_LOGIN
},
2331 {"logout", NULL
, SetVariable
, LOCAL_AUTH
| LOCAL_CX
,
2332 "logout script", "set logout chat-script", (const void *) VAR_LOGOUT
},
2333 {"lqrperiod", NULL
, SetVariable
, LOCAL_AUTH
| LOCAL_CX_OPT
,
2334 "LQR period", "set lqrperiod value", (const void *)VAR_LQRPERIOD
},
2335 {"mode", NULL
, SetVariable
, LOCAL_AUTH
| LOCAL_CX
, "mode value",
2336 "set mode interactive|auto|ddial|background", (const void *)VAR_MODE
},
2337 {"mrru", NULL
, SetVariable
, LOCAL_AUTH
, "MRRU value",
2338 "set mrru value", (const void *)VAR_MRRU
},
2339 {"mru", NULL
, SetVariable
, LOCAL_AUTH
| LOCAL_CX
,
2340 "MRU value", "set mru [max[imum]] [value]", (const void *)VAR_MRU
},
2341 {"mtu", NULL
, SetVariable
, LOCAL_AUTH
| LOCAL_CX
,
2342 "interface MTU value", "set mtu [max[imum]] [value]", (const void *)VAR_MTU
},
2343 {"nbns", NULL
, SetVariable
, LOCAL_AUTH
, "NetBIOS Name Server",
2344 "set nbns pri-addr [sec-addr]", (const void *)VAR_NBNS
},
2345 {"openmode", NULL
, SetVariable
, LOCAL_AUTH
| LOCAL_CX
, "open mode",
2346 "set openmode active|passive [secs]", (const void *)VAR_OPENMODE
},
2347 {"papretry", "papretries", SetVariable
, LOCAL_AUTH
| LOCAL_CX
, "PAP retries",
2348 "set papretry value [attempts]", (const void *)VAR_PAPRETRY
},
2349 {"parity", NULL
, SetVariable
, LOCAL_AUTH
| LOCAL_CX
, "serial parity",
2350 "set parity [odd|even|none]", (const void *)VAR_PARITY
},
2351 {"phone", NULL
, SetVariable
, LOCAL_AUTH
| LOCAL_CX
, "telephone number(s)",
2352 "set phone phone1[:phone2[...]]", (const void *)VAR_PHONE
},
2353 {"proctitle", "title", SetProcTitle
, LOCAL_AUTH
,
2354 "Process title", "set proctitle [value]"},
2356 {"radius", NULL
, SetVariable
, LOCAL_AUTH
,
2357 "RADIUS Config", "set radius cfgfile", (const void *)VAR_RADIUS
},
2359 {"reconnect", NULL
, datalink_SetReconnect
, LOCAL_AUTH
| LOCAL_CX
,
2360 "Reconnect timeout", "set reconnect value ntries"},
2361 {"recvpipe", NULL
, SetVariable
, LOCAL_AUTH
,
2362 "RECVPIPE value", "set recvpipe value", (const void *)VAR_RECVPIPE
},
2363 {"redial", NULL
, datalink_SetRedial
, LOCAL_AUTH
| LOCAL_CX
,
2364 "Redial timeout", "set redial secs[+inc[-incmax]][.next] [attempts]"},
2365 {"sendpipe", NULL
, SetVariable
, LOCAL_AUTH
,
2366 "SENDPIPE value", "set sendpipe value", (const void *)VAR_SENDPIPE
},
2367 {"server", "socket", SetServer
, LOCAL_AUTH
, "diagnostic port",
2368 "set server|socket TcpPort|LocalName|none|open|closed [password [mask]]"},
2369 {"speed", NULL
, SetModemSpeed
, LOCAL_AUTH
| LOCAL_CX
,
2370 "physical speed", "set speed value|sync"},
2371 {"stopped", NULL
, SetStoppedTimeout
, LOCAL_AUTH
| LOCAL_CX
,
2372 "STOPPED timeouts", "set stopped [LCPseconds [CCPseconds]]"},
2373 {"timeout", NULL
, SetVariable
, LOCAL_AUTH
, "Idle timeout",
2374 "set timeout idletime", (const void *)VAR_IDLETIMEOUT
},
2375 {"urgent", NULL
, SetVariable
, LOCAL_AUTH
, "urgent ports",
2376 "set urgent [tcp|udp] [+|-]port...", (const void *)VAR_URGENTPORTS
},
2377 {"vj", NULL
, ipcp_vjset
, LOCAL_AUTH
,
2378 "vj values", "set vj slots|slotcomp [value]"},
2379 {"help", "?", HelpCommand
, LOCAL_AUTH
| LOCAL_NO_AUTH
,
2380 "Display this message", "set help|? [command]", SetCommands
},
2385 SetCommand(struct cmdargs
const *arg
)
2387 if (arg
->argc
> arg
->argn
)
2388 FindExec(arg
->bundle
, SetCommands
, arg
->argc
, arg
->argn
, arg
->argv
,
2389 arg
->prompt
, arg
->cx
);
2390 else if (arg
->prompt
)
2391 prompt_Printf(arg
->prompt
, "Use `set ?' to get a list or `set ? <var>' for"
2394 log_Printf(LogWARN
, "set command must have arguments\n");
2400 AddCommand(struct cmdargs
const *arg
)
2403 struct ncprange dest
;
2404 struct in_addr host
;
2406 struct in6_addr host6
;
2408 int dest_default
, gw_arg
, addrs
;
2410 if (arg
->argc
!= arg
->argn
+3 && arg
->argc
!= arg
->argn
+2)
2415 if (arg
->argc
== arg
->argn
+ 2) {
2416 if (!strcasecmp(arg
->argv
[arg
->argn
], "default"))
2419 if (!ncprange_aton(&dest
, &arg
->bundle
->ncp
, arg
->argv
[arg
->argn
]))
2421 if (!strncasecmp(arg
->argv
[arg
->argn
], "MYADDR", 6))
2422 addrs
= ROUTE_DSTMYADDR
;
2423 else if (!strncasecmp(arg
->argv
[arg
->argn
], "MYADDR6", 7))
2424 addrs
= ROUTE_DSTMYADDR6
;
2425 else if (!strncasecmp(arg
->argv
[arg
->argn
], "HISADDR", 7))
2426 addrs
= ROUTE_DSTHISADDR
;
2427 else if (!strncasecmp(arg
->argv
[arg
->argn
], "HISADDR6", 8))
2428 addrs
= ROUTE_DSTHISADDR6
;
2429 else if (!strncasecmp(arg
->argv
[arg
->argn
], "DNS0", 4))
2430 addrs
= ROUTE_DSTDNS0
;
2431 else if (!strncasecmp(arg
->argv
[arg
->argn
], "DNS1", 4))
2432 addrs
= ROUTE_DSTDNS1
;
2436 if (strcasecmp(arg
->argv
[arg
->argn
], "MYADDR") == 0) {
2437 addrs
= ROUTE_DSTMYADDR
;
2438 host
= arg
->bundle
->ncp
.ipcp
.my_ip
;
2439 } else if (strcasecmp(arg
->argv
[arg
->argn
], "HISADDR") == 0) {
2440 addrs
= ROUTE_DSTHISADDR
;
2441 host
= arg
->bundle
->ncp
.ipcp
.peer_ip
;
2442 } else if (strcasecmp(arg
->argv
[arg
->argn
], "DNS0") == 0) {
2443 addrs
= ROUTE_DSTDNS0
;
2444 host
= arg
->bundle
->ncp
.ipcp
.ns
.dns
[0];
2445 } else if (strcasecmp(arg
->argv
[arg
->argn
], "DNS1") == 0) {
2446 addrs
= ROUTE_DSTDNS1
;
2447 host
= arg
->bundle
->ncp
.ipcp
.ns
.dns
[1];
2449 host
= GetIpAddr(arg
->argv
[arg
->argn
]);
2450 if (host
.s_addr
== INADDR_NONE
) {
2451 log_Printf(LogWARN
, "%s: Invalid destination address\n",
2452 arg
->argv
[arg
->argn
]);
2456 ncprange_setip4(&dest
, host
, GetIpAddr(arg
->argv
[arg
->argn
+ 1]));
2460 if (strcasecmp(arg
->argv
[arg
->argn
+ gw_arg
], "HISADDR") == 0) {
2461 ncpaddr_setip4(&gw
, arg
->bundle
->ncp
.ipcp
.peer_ip
);
2462 addrs
|= ROUTE_GWHISADDR
;
2464 } else if (strcasecmp(arg
->argv
[arg
->argn
+ gw_arg
], "HISADDR6") == 0) {
2465 if (!ncpaddr_getip6(&arg
->bundle
->ncp
.ipv6cp
.hisaddr
, &host6
))
2466 memset(&host6
, '\0', sizeof host6
);
2467 ncpaddr_setip6(&gw
, &host6
);
2468 addrs
|= ROUTE_GWHISADDR6
;
2471 if (!ncpaddr_aton(&gw
, &arg
->bundle
->ncp
, arg
->argv
[arg
->argn
+ gw_arg
])) {
2472 log_Printf(LogWARN
, "%s: Invalid gateway address\n",
2473 arg
->argv
[arg
->argn
+ gw_arg
]);
2479 ncprange_setdefault(&dest
, ncpaddr_family(&gw
));
2481 if (rt_Set(arg
->bundle
, RTM_ADD
, &dest
, &gw
, arg
->cmd
->args
? 1 : 0,
2482 ((addrs
& ROUTE_GWHISADDR
) || (addrs
& ROUTE_GWHISADDR6
)) ? 1 : 0)
2483 && addrs
!= ROUTE_STATIC
)
2484 route_Add(&arg
->bundle
->ncp
.route
, addrs
, &dest
, &gw
);
2490 DeleteCommand(struct cmdargs
const *arg
)
2492 struct ncprange dest
;
2495 if (arg
->argc
== arg
->argn
+1) {
2496 if(strcasecmp(arg
->argv
[arg
->argn
], "all") == 0) {
2497 route_IfDelete(arg
->bundle
, 0);
2498 route_DeleteAll(&arg
->bundle
->ncp
.route
);
2501 if (strcasecmp(arg
->argv
[arg
->argn
], "MYADDR") == 0) {
2502 ncprange_setip4host(&dest
, arg
->bundle
->ncp
.ipcp
.my_ip
);
2503 addrs
= ROUTE_DSTMYADDR
;
2505 } else if (strcasecmp(arg
->argv
[arg
->argn
], "MYADDR6") == 0) {
2506 ncprange_sethost(&dest
, &arg
->bundle
->ncp
.ipv6cp
.myaddr
);
2507 addrs
= ROUTE_DSTMYADDR6
;
2509 } else if (strcasecmp(arg
->argv
[arg
->argn
], "HISADDR") == 0) {
2510 ncprange_setip4host(&dest
, arg
->bundle
->ncp
.ipcp
.peer_ip
);
2511 addrs
= ROUTE_DSTHISADDR
;
2513 } else if (strcasecmp(arg
->argv
[arg
->argn
], "HISADDR6") == 0) {
2514 ncprange_sethost(&dest
, &arg
->bundle
->ncp
.ipv6cp
.hisaddr
);
2515 addrs
= ROUTE_DSTHISADDR6
;
2517 } else if (strcasecmp(arg
->argv
[arg
->argn
], "DNS0") == 0) {
2518 ncprange_setip4host(&dest
, arg
->bundle
->ncp
.ipcp
.ns
.dns
[0]);
2519 addrs
= ROUTE_DSTDNS0
;
2520 } else if (strcasecmp(arg
->argv
[arg
->argn
], "DNS1") == 0) {
2521 ncprange_setip4host(&dest
, arg
->bundle
->ncp
.ipcp
.ns
.dns
[1]);
2522 addrs
= ROUTE_DSTDNS1
;
2524 ncprange_aton(&dest
, &arg
->bundle
->ncp
, arg
->argv
[arg
->argn
]);
2525 addrs
= ROUTE_STATIC
;
2527 rt_Set(arg
->bundle
, RTM_DELETE
, &dest
, NULL
, arg
->cmd
->args
? 1 : 0, 0);
2528 route_Delete(&arg
->bundle
->ncp
.route
, addrs
, &dest
);
2538 NatEnable(struct cmdargs
const *arg
)
2540 if (arg
->argc
== arg
->argn
+1) {
2541 if (strcasecmp(arg
->argv
[arg
->argn
], "yes") == 0) {
2542 if (!arg
->bundle
->NatEnabled
) {
2543 if (arg
->bundle
->ncp
.ipcp
.fsm
.state
== ST_OPENED
)
2544 PacketAliasSetAddress(arg
->bundle
->ncp
.ipcp
.my_ip
);
2545 arg
->bundle
->NatEnabled
= 1;
2548 } else if (strcasecmp(arg
->argv
[arg
->argn
], "no") == 0) {
2549 arg
->bundle
->NatEnabled
= 0;
2550 arg
->bundle
->cfg
.opt
&= ~OPT_IFACEALIAS
;
2551 /* Don't iface_Clear() - there may be manually configured addresses */
2561 NatOption(struct cmdargs
const *arg
)
2563 long param
= (long)arg
->cmd
->args
;
2565 if (arg
->argc
== arg
->argn
+1) {
2566 if (strcasecmp(arg
->argv
[arg
->argn
], "yes") == 0) {
2567 if (arg
->bundle
->NatEnabled
) {
2568 PacketAliasSetMode(param
, param
);
2571 log_Printf(LogWARN
, "nat not enabled\n");
2572 } else if (strcmp(arg
->argv
[arg
->argn
], "no") == 0) {
2573 if (arg
->bundle
->NatEnabled
) {
2574 PacketAliasSetMode(0, param
);
2577 log_Printf(LogWARN
, "nat not enabled\n");
2582 #endif /* #ifndef NONAT */
2585 LinkCommand(struct cmdargs
const *arg
)
2587 if (arg
->argc
> arg
->argn
+1) {
2588 char namelist
[LINE_LEN
];
2589 struct datalink
*cx
;
2593 if (!strcmp(arg
->argv
[arg
->argn
], "*")) {
2594 struct datalink
*dl
;
2596 cx
= arg
->bundle
->links
;
2598 /* Watch it, the command could be a ``remove'' */
2600 FindExec(arg
->bundle
, Commands
, arg
->argc
, arg
->argn
+1, arg
->argv
,
2602 for (cx
= arg
->bundle
->links
; cx
; cx
= cx
->next
)
2604 break; /* Pointer's still valid ! */
2607 strncpy(namelist
, arg
->argv
[arg
->argn
], sizeof namelist
- 1);
2608 namelist
[sizeof namelist
- 1] = '\0';
2609 for(name
= strtok(namelist
, ", "); name
; name
= strtok(NULL
,", "))
2610 if (!bundle2datalink(arg
->bundle
, name
)) {
2611 log_Printf(LogWARN
, "link: %s: Invalid link name\n", name
);
2615 strncpy(namelist
, arg
->argv
[arg
->argn
], sizeof namelist
- 1);
2616 namelist
[sizeof namelist
- 1] = '\0';
2617 for(name
= strtok(namelist
, ", "); name
; name
= strtok(NULL
,", ")) {
2618 cx
= bundle2datalink(arg
->bundle
, name
);
2620 FindExec(arg
->bundle
, Commands
, arg
->argc
, arg
->argn
+1, arg
->argv
,
2623 log_Printf(LogWARN
, "link: %s: Invalidated link name !\n", name
);
2631 log_Printf(LogWARN
, "usage: %s\n", arg
->cmd
->syntax
);
2636 command_ChooseLink(struct cmdargs
const *arg
)
2639 return &arg
->cx
->physical
->link
;
2640 else if (!arg
->bundle
->ncp
.mp
.cfg
.mrru
) {
2641 struct datalink
*dl
= bundle2datalink(arg
->bundle
, NULL
);
2643 return &dl
->physical
->link
;
2645 return &arg
->bundle
->ncp
.mp
.link
;
2649 ident_cmd(const char *cmd
, unsigned *keep
, unsigned *add
)
2658 *add
= NEG_ACCEPTED
;
2672 *keep
= NEG_HISMASK
;
2682 *keep
= NEG_HISMASK
;
2693 OptSet(struct cmdargs
const *arg
)
2695 int bit
= (int)(long)arg
->cmd
->args
;
2696 unsigned keep
; /* Keep these bits */
2697 unsigned add
; /* Add these bits */
2699 if (ident_cmd(arg
->argv
[arg
->argn
- 2], &keep
, &add
) == NULL
)
2703 if (add
== NEG_ENABLED
&& bit
== OPT_IPV6CP
&& !probe
.ipv6_available
) {
2704 log_Printf(LogWARN
, "IPv6 is not available on this machine\n");
2710 arg
->bundle
->cfg
.opt
|= bit
;
2712 arg
->bundle
->cfg
.opt
&= ~bit
;
2718 IfaceAliasOptSet(struct cmdargs
const *arg
)
2720 unsigned save
= arg
->bundle
->cfg
.opt
;
2721 int result
= OptSet(arg
);
2724 if (Enabled(arg
->bundle
, OPT_IFACEALIAS
) && !arg
->bundle
->NatEnabled
) {
2725 arg
->bundle
->cfg
.opt
= save
;
2726 log_Printf(LogWARN
, "Cannot enable iface-alias without NAT\n");
2734 NegotiateSet(struct cmdargs
const *arg
)
2736 long param
= (long)arg
->cmd
->args
;
2737 struct link
*l
= command_ChooseLink(arg
); /* LOCAL_CX_OPT uses this */
2738 struct datalink
*cx
= arg
->cx
; /* LOCAL_CX uses this */
2740 unsigned keep
; /* Keep these bits */
2741 unsigned add
; /* Add these bits */
2743 if ((cmd
= ident_cmd(arg
->argv
[arg
->argn
-2], &keep
, &add
)) == NULL
)
2746 if ((arg
->cmd
->lauth
& LOCAL_CX
) && !cx
) {
2747 log_Printf(LogWARN
, "%s %s: No context (use the `link' command)\n",
2748 cmd
, arg
->cmd
->name
);
2750 } else if (cx
&& !(arg
->cmd
->lauth
& (LOCAL_CX
|LOCAL_CX_OPT
))) {
2751 log_Printf(LogWARN
, "%s %s: Redundant context (%s) ignored\n",
2752 cmd
, arg
->cmd
->name
, cx
->name
);
2758 cx
->physical
->link
.lcp
.cfg
.acfcomp
&= keep
;
2759 cx
->physical
->link
.lcp
.cfg
.acfcomp
|= add
;
2762 cx
->physical
->link
.lcp
.cfg
.chap05
&= keep
;
2763 cx
->physical
->link
.lcp
.cfg
.chap05
|= add
;
2767 cx
->physical
->link
.lcp
.cfg
.chap80nt
&= keep
;
2768 cx
->physical
->link
.lcp
.cfg
.chap80nt
|= add
;
2771 cx
->physical
->link
.lcp
.cfg
.chap80lm
&= keep
;
2772 cx
->physical
->link
.lcp
.cfg
.chap80lm
|= add
;
2775 cx
->physical
->link
.lcp
.cfg
.chap81
&= keep
;
2776 cx
->physical
->link
.lcp
.cfg
.chap81
|= add
;
2779 l
->ccp
.cfg
.neg
[CCP_NEG_MPPE
] &= keep
;
2780 l
->ccp
.cfg
.neg
[CCP_NEG_MPPE
] |= add
;
2784 l
->ccp
.cfg
.neg
[CCP_NEG_DEFLATE
] &= keep
;
2785 l
->ccp
.cfg
.neg
[CCP_NEG_DEFLATE
] |= add
;
2788 arg
->bundle
->ncp
.ipcp
.cfg
.ns
.dns_neg
&= keep
;
2789 arg
->bundle
->ncp
.ipcp
.cfg
.ns
.dns_neg
|= add
;
2792 arg
->bundle
->ncp
.mp
.cfg
.negenddisc
&= keep
;
2793 arg
->bundle
->ncp
.mp
.cfg
.negenddisc
|= add
;
2796 cx
->physical
->link
.lcp
.cfg
.lqr
&= keep
;
2797 cx
->physical
->link
.lcp
.cfg
.lqr
|= add
;
2800 cx
->physical
->link
.lcp
.cfg
.pap
&= keep
;
2801 cx
->physical
->link
.lcp
.cfg
.pap
|= add
;
2803 case NEG_PPPDDEFLATE
:
2804 l
->ccp
.cfg
.neg
[CCP_NEG_DEFLATE24
] &= keep
;
2805 l
->ccp
.cfg
.neg
[CCP_NEG_DEFLATE24
] |= add
;
2808 l
->ccp
.cfg
.neg
[CCP_NEG_PRED1
] &= keep
;
2809 l
->ccp
.cfg
.neg
[CCP_NEG_PRED1
] |= add
;
2812 cx
->physical
->link
.lcp
.cfg
.protocomp
&= keep
;
2813 cx
->physical
->link
.lcp
.cfg
.protocomp
|= add
;
2816 switch (bundle_Phase(arg
->bundle
)) {
2819 case PHASE_ESTABLISH
:
2820 /* Make sure none of our links are DATALINK_LCP or greater */
2821 if (bundle_HighestState(arg
->bundle
) >= DATALINK_LCP
) {
2822 log_Printf(LogWARN
, "shortseq: Only changeable before"
2823 " LCP negotiations\n");
2828 log_Printf(LogWARN
, "shortseq: Only changeable at phase"
2829 " DEAD/ESTABLISH\n");
2832 arg
->bundle
->ncp
.mp
.cfg
.shortseq
&= keep
;
2833 arg
->bundle
->ncp
.mp
.cfg
.shortseq
|= add
;
2836 arg
->bundle
->ncp
.ipcp
.cfg
.vj
.neg
&= keep
;
2837 arg
->bundle
->ncp
.ipcp
.cfg
.vj
.neg
|= add
;
2844 static struct cmdtab
const NegotiateCommands
[] = {
2845 {"filter-decapsulation", NULL
, OptSet
, LOCAL_AUTH
,
2846 "filter on PPPoUDP payloads", "disable|enable",
2847 (const void *)OPT_FILTERDECAP
},
2848 {"idcheck", NULL
, OptSet
, LOCAL_AUTH
, "Check FSM reply ids",
2849 "disable|enable", (const void *)OPT_IDCHECK
},
2850 {"iface-alias", NULL
, IfaceAliasOptSet
, LOCAL_AUTH
,
2851 "retain interface addresses", "disable|enable",
2852 (const void *)OPT_IFACEALIAS
},
2854 {"ipcp", NULL
, OptSet
, LOCAL_AUTH
, "IP Network Control Protocol",
2855 "disable|enable", (const void *)OPT_IPCP
},
2856 {"ipv6cp", NULL
, OptSet
, LOCAL_AUTH
, "IPv6 Network Control Protocol",
2857 "disable|enable", (const void *)OPT_IPV6CP
},
2859 {"keep-session", NULL
, OptSet
, LOCAL_AUTH
, "Retain device session leader",
2860 "disable|enable", (const void *)OPT_KEEPSESSION
},
2861 {"loopback", NULL
, OptSet
, LOCAL_AUTH
, "Loop packets for local iface",
2862 "disable|enable", (const void *)OPT_LOOPBACK
},
2863 {"passwdauth", NULL
, OptSet
, LOCAL_AUTH
, "Use passwd file",
2864 "disable|enable", (const void *)OPT_PASSWDAUTH
},
2865 {"proxy", NULL
, OptSet
, LOCAL_AUTH
, "Create a proxy ARP entry",
2866 "disable|enable", (const void *)OPT_PROXY
},
2867 {"proxyall", NULL
, OptSet
, LOCAL_AUTH
, "Proxy ARP for all remote hosts",
2868 "disable|enable", (const void *)OPT_PROXYALL
},
2869 {"sroutes", NULL
, OptSet
, LOCAL_AUTH
, "Use sticky routes",
2870 "disable|enable", (const void *)OPT_SROUTES
},
2871 {"tcpmssfixup", "mssfixup", OptSet
, LOCAL_AUTH
, "Modify MSS options",
2872 "disable|enable", (const void *)OPT_TCPMSSFIXUP
},
2873 {"throughput", NULL
, OptSet
, LOCAL_AUTH
, "Rolling throughput",
2874 "disable|enable", (const void *)OPT_THROUGHPUT
},
2875 {"utmp", NULL
, OptSet
, LOCAL_AUTH
, "Log connections in utmp",
2876 "disable|enable", (const void *)OPT_UTMP
},
2879 #define OPT_MAX 13 /* accept/deny allowed below and not above */
2884 {"acfcomp", NULL
, NegotiateSet
, LOCAL_AUTH
| LOCAL_CX
,
2885 "Address & Control field compression", "accept|deny|disable|enable",
2886 (const void *)NEG_ACFCOMP
},
2887 {"chap", "chap05", NegotiateSet
, LOCAL_AUTH
| LOCAL_CX
,
2888 "Challenge Handshake Authentication Protocol", "accept|deny|disable|enable",
2889 (const void *)NEG_CHAP05
},
2891 {"mschap", "chap80nt", NegotiateSet
, LOCAL_AUTH
| LOCAL_CX
,
2892 "Microsoft (NT) CHAP", "accept|deny|disable|enable",
2893 (const void *)NEG_CHAP80
},
2894 {"LANMan", "chap80lm", NegotiateSet
, LOCAL_AUTH
| LOCAL_CX
,
2895 "Microsoft (NT) CHAP", "accept|deny|disable|enable",
2896 (const void *)NEG_CHAP80LM
},
2897 {"mschapv2", "chap81", NegotiateSet
, LOCAL_AUTH
| LOCAL_CX
,
2898 "Microsoft CHAP v2", "accept|deny|disable|enable",
2899 (const void *)NEG_CHAP81
},
2900 {"mppe", NULL
, NegotiateSet
, LOCAL_AUTH
| LOCAL_CX_OPT
,
2901 "MPPE encryption", "accept|deny|disable|enable",
2902 (const void *)NEG_MPPE
},
2904 {"deflate", NULL
, NegotiateSet
, LOCAL_AUTH
| LOCAL_CX_OPT
,
2905 "Deflate compression", "accept|deny|disable|enable",
2906 (const void *)NEG_DEFLATE
},
2907 {"deflate24", NULL
, NegotiateSet
, LOCAL_AUTH
| LOCAL_CX_OPT
,
2908 "Deflate (type 24) compression", "accept|deny|disable|enable",
2909 (const void *)NEG_PPPDDEFLATE
},
2910 {"dns", NULL
, NegotiateSet
, LOCAL_AUTH
,
2911 "DNS specification", "accept|deny|disable|enable", (const void *)NEG_DNS
},
2912 {"enddisc", NULL
, NegotiateSet
, LOCAL_AUTH
, "ENDDISC negotiation",
2913 "accept|deny|disable|enable", (const void *)NEG_ENDDISC
},
2914 {"lqr", NULL
, NegotiateSet
, LOCAL_AUTH
| LOCAL_CX
,
2915 "Link Quality Reports", "accept|deny|disable|enable",
2916 (const void *)NEG_LQR
},
2917 {"pap", NULL
, NegotiateSet
, LOCAL_AUTH
| LOCAL_CX
,
2918 "Password Authentication protocol", "accept|deny|disable|enable",
2919 (const void *)NEG_PAP
},
2920 {"pred1", "predictor1", NegotiateSet
, LOCAL_AUTH
| LOCAL_CX_OPT
,
2921 "Predictor 1 compression", "accept|deny|disable|enable",
2922 (const void *)NEG_PRED1
},
2923 {"protocomp", NULL
, NegotiateSet
, LOCAL_AUTH
| LOCAL_CX
,
2924 "Protocol field compression", "accept|deny|disable|enable",
2925 (const void *)NEG_PROTOCOMP
},
2926 {"shortseq", NULL
, NegotiateSet
, LOCAL_AUTH
,
2927 "MP Short Sequence Numbers", "accept|deny|disable|enable",
2928 (const void *)NEG_SHORTSEQ
},
2929 {"vjcomp", NULL
, NegotiateSet
, LOCAL_AUTH
,
2930 "Van Jacobson header compression", "accept|deny|disable|enable",
2931 (const void *)NEG_VJCOMP
},
2932 {"help", "?", HelpCommand
, LOCAL_AUTH
| LOCAL_NO_AUTH
,
2933 "Display this message", "accept|deny|disable|enable help|? [value]",
2939 NegotiateCommand(struct cmdargs
const *arg
)
2941 if (arg
->argc
> arg
->argn
) {
2942 char const *argv
[3];
2946 if ((argv
[0] = ident_cmd(arg
->argv
[arg
->argn
-1], &keep
, &add
)) == NULL
)
2950 for (n
= arg
->argn
; n
< arg
->argc
; n
++) {
2951 argv
[1] = arg
->argv
[n
];
2952 FindExec(arg
->bundle
, NegotiateCommands
+ (keep
== NEG_HISMASK
?
2953 0 : OPT_MAX
), 2, 1, argv
, arg
->prompt
, arg
->cx
);
2955 } else if (arg
->prompt
)
2956 prompt_Printf(arg
->prompt
, "Use `%s ?' to get a list.\n",
2957 arg
->argv
[arg
->argn
-1]);
2959 log_Printf(LogWARN
, "%s command must have arguments\n",
2960 arg
->argv
[arg
->argn
] );
2966 command_ShowNegval(unsigned val
)
2969 case 1: return "disabled & accepted";
2970 case 2: return "enabled & denied";
2971 case 3: return "enabled & accepted";
2973 return "disabled & denied";
2977 ClearCommand(struct cmdargs
const *arg
)
2979 struct pppThroughput
*t
;
2980 struct datalink
*cx
;
2983 if (arg
->argc
< arg
->argn
+ 1)
2986 if (strcasecmp(arg
->argv
[arg
->argn
], "physical") == 0) {
2989 cx
= bundle2datalink(arg
->bundle
, NULL
);
2991 log_Printf(LogWARN
, "A link must be specified for ``clear physical''\n");
2994 t
= &cx
->physical
->link
.stats
.total
;
2995 } else if (strcasecmp(arg
->argv
[arg
->argn
], "ipcp") == 0)
2996 t
= &arg
->bundle
->ncp
.ipcp
.throughput
;
2998 else if (strcasecmp(arg
->argv
[arg
->argn
], "ipv6cp") == 0)
2999 t
= &arg
->bundle
->ncp
.ipv6cp
.throughput
;
3004 if (arg
->argc
> arg
->argn
+ 1) {
3006 for (i
= arg
->argn
+ 1; i
< arg
->argc
; i
++)
3007 if (strcasecmp(arg
->argv
[i
], "overall") == 0)
3008 clear_type
|= THROUGHPUT_OVERALL
;
3009 else if (strcasecmp(arg
->argv
[i
], "current") == 0)
3010 clear_type
|= THROUGHPUT_CURRENT
;
3011 else if (strcasecmp(arg
->argv
[i
], "peak") == 0)
3012 clear_type
|= THROUGHPUT_PEAK
;
3016 clear_type
= THROUGHPUT_ALL
;
3018 throughput_clear(t
, clear_type
, arg
->prompt
);
3023 RunListCommand(struct cmdargs
const *arg
)
3025 const char *cmd
= arg
->argc
? arg
->argv
[arg
->argc
- 1] : "???";
3028 if (arg
->cmd
->args
== NatCommands
&&
3029 tolower(*arg
->argv
[arg
->argn
- 1]) == 'a') {
3031 prompt_Printf(arg
->prompt
, "The alias command is deprecated\n");
3033 log_Printf(LogWARN
, "The alias command is deprecated\n");
3037 if (arg
->argc
> arg
->argn
)
3038 FindExec(arg
->bundle
, arg
->cmd
->args
, arg
->argc
, arg
->argn
, arg
->argv
,
3039 arg
->prompt
, arg
->cx
);
3040 else if (arg
->prompt
)
3041 prompt_Printf(arg
->prompt
, "Use `%s help' to get a list or `%s help"
3042 " <option>' for syntax help.\n", cmd
, cmd
);
3044 log_Printf(LogWARN
, "%s command must have arguments\n", cmd
);
3050 IfaceAddCommand(struct cmdargs
const *arg
)
3052 struct ncpaddr peer
, addr
;
3053 struct ncprange ifa
;
3054 struct in_addr mask
;
3057 if (arg
->argc
== arg
->argn
+ 1) {
3058 if (!ncprange_aton(&ifa
, NULL
, arg
->argv
[arg
->argn
]))
3060 ncpaddr_init(&peer
);
3062 if (arg
->argc
== arg
->argn
+ 2) {
3063 if (!ncprange_aton(&ifa
, NULL
, arg
->argv
[arg
->argn
]))
3066 } else if (arg
->argc
== arg
->argn
+ 3) {
3067 if (!ncpaddr_aton(&addr
, NULL
, arg
->argv
[arg
->argn
]))
3069 if (ncpaddr_family(&addr
) != AF_INET
)
3071 ncprange_sethost(&ifa
, &addr
);
3072 if (!ncpaddr_aton(&addr
, NULL
, arg
->argv
[arg
->argn
+ 1]))
3074 if (!ncpaddr_getip4(&addr
, &mask
))
3076 if (!ncprange_setip4mask(&ifa
, mask
))
3082 if (!ncpaddr_aton(&peer
, NULL
, arg
->argv
[arg
->argn
+ n
]))
3085 if (ncprange_family(&ifa
) != ncpaddr_family(&peer
)) {
3086 log_Printf(LogWARN
, "IfaceAddCommand: src and dst address families"
3092 how
= IFACE_ADD_LAST
;
3094 how
|= IFACE_FORCE_ADD
;
3096 return !iface_Add(arg
->bundle
->iface
, &arg
->bundle
->ncp
, &ifa
, &peer
, how
);
3100 IfaceDeleteCommand(struct cmdargs
const *arg
)
3103 struct in_addr ifa4
;
3106 if (arg
->argc
!= arg
->argn
+ 1)
3109 if (!ncpaddr_aton(&ifa
, NULL
, arg
->argv
[arg
->argn
]))
3112 if (arg
->bundle
->ncp
.ipcp
.fsm
.state
== ST_OPENED
&&
3113 ncpaddr_getip4(&ifa
, &ifa4
) &&
3114 arg
->bundle
->ncp
.ipcp
.my_ip
.s_addr
== ifa4
.s_addr
) {
3115 log_Printf(LogWARN
, "%s: Cannot remove active interface address\n",
3116 ncpaddr_ntoa(&ifa
));
3120 ok
= iface_Delete(arg
->bundle
->iface
, &arg
->bundle
->ncp
, &ifa
);
3124 else if (arg
->prompt
)
3125 prompt_Printf(arg
->prompt
, "%s: No such interface address\n",
3126 ncpaddr_ntoa(&ifa
));
3128 log_Printf(LogWARN
, "%s: No such interface address\n",
3129 ncpaddr_ntoa(&ifa
));
3136 IfaceClearCommand(struct cmdargs
const *arg
)
3141 if (arg
->argc
== arg
->argn
+ 1) {
3142 if (strcasecmp(arg
->argv
[arg
->argn
], "inet") == 0)
3145 else if (strcasecmp(arg
->argv
[arg
->argn
], "inet6") == 0)
3150 } else if (arg
->argc
!= arg
->argn
)
3153 how
= arg
->bundle
->ncp
.ipcp
.fsm
.state
== ST_OPENED
||
3154 arg
->bundle
->phys_type
.all
& PHYS_AUTO
?
3155 IFACE_CLEAR_ALIASES
: IFACE_CLEAR_ALL
;
3156 iface_Clear(arg
->bundle
->iface
, &arg
->bundle
->ncp
, family
, how
);
3162 SetProcTitle(struct cmdargs
const *arg
)
3164 static char title
[LINE_LEN
];
3165 char *argv
[MAXARGS
];
3166 int argc
= arg
->argc
- arg
->argn
;
3168 if (arg
->argc
== arg
->argn
) {
3173 if (argc
>= sizeof argv
/ sizeof argv
[0]) {
3174 argc
= sizeof argv
/ sizeof argv
[0] - 1;
3175 log_Printf(LogWARN
, "Truncating proc title to %d args\n", argc
);
3177 command_Expand(argv
, argc
, arg
->argv
+ arg
->argn
, arg
->bundle
, 1, getpid());
3178 Concatinate(title
, sizeof title
, argc
, (const char *const *)argv
);
3180 command_Free(argc
, argv
);