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.3 2007/05/17 08:19:03 swildner 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
, (char *)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 InterpretArg(buff
, buff2
);
1111 strncpy(buff
, buff2
, LINE_LEN
- offset
- 1);
1112 buff
[LINE_LEN
- offset
- 1] = '\0';
1114 return command_Interpret(buff
, nb
, argv
);
1118 command_Interpret(char *buff
, int nb
, char *argv
[MAXARGS
])
1123 cp
= buff
+ strcspn(buff
, "\r\n");
1126 return MakeArgs(buff
, argv
, MAXARGS
, PARSE_REDUCE
);
1132 arghidden(int argc
, char const *const *argv
, int n
)
1134 /* Is arg n of the given command to be hidden from the log ? */
1136 /* set authkey xxxxx */
1138 if (n
== 2 && !strncasecmp(argv
[0], "se", 2) &&
1139 (!strncasecmp(argv
[1], "authk", 5) || !strncasecmp(argv
[1], "ke", 2)))
1143 if (n
== 1 && !strncasecmp(argv
[0], "p", 1))
1146 /* set server port xxxxx .... */
1147 if (n
== 3 && !strncasecmp(argv
[0], "se", 2) &&
1148 !strncasecmp(argv
[1], "se", 2))
1155 command_Run(struct bundle
*bundle
, int argc
, char const *const *argv
,
1156 struct prompt
*prompt
, const char *label
, struct datalink
*cx
)
1159 if (log_IsKept(LogCOMMAND
)) {
1164 strncpy(buf
, label
, sizeof buf
- 3);
1165 buf
[sizeof buf
- 3] = '\0';
1172 buf
[sizeof buf
- 1] = '\0'; /* In case we run out of room in buf */
1174 for (f
= 0; f
< argc
; f
++) {
1175 if (n
< sizeof buf
- 1 && f
)
1177 if (arghidden(argc
, argv
, f
))
1178 strncpy(buf
+n
, "********", sizeof buf
- n
- 1);
1180 strncpy(buf
+n
, argv
[f
], sizeof buf
- n
- 1);
1183 log_Printf(LogCOMMAND
, "%s\n", buf
);
1185 FindExec(bundle
, Commands
, argc
, 0, argv
, prompt
, cx
);
1190 command_Decode(struct bundle
*bundle
, char *buff
, int nb
, struct prompt
*prompt
,
1194 char *argv
[MAXARGS
];
1196 if ((argc
= command_Expand_Interpret(buff
, nb
, argv
, 0)) < 0)
1199 command_Run(bundle
, argc
, (char const *const *)argv
, prompt
, label
, NULL
);
1204 ShowCommand(struct cmdargs
const *arg
)
1207 log_Printf(LogWARN
, "show: Cannot show without a prompt\n");
1208 else if (arg
->argc
> arg
->argn
)
1209 FindExec(arg
->bundle
, ShowCommands
, arg
->argc
, arg
->argn
, arg
->argv
,
1210 arg
->prompt
, arg
->cx
);
1212 prompt_Printf(arg
->prompt
, "Use ``show ?'' to get a list.\n");
1218 TerminalCommand(struct cmdargs
const *arg
)
1221 log_Printf(LogWARN
, "term: Need a prompt\n");
1225 if (arg
->cx
->physical
->link
.lcp
.fsm
.state
> ST_CLOSED
) {
1226 prompt_Printf(arg
->prompt
, "LCP state is [%s]\n",
1227 State2Nam(arg
->cx
->physical
->link
.lcp
.fsm
.state
));
1231 datalink_Up(arg
->cx
, 0, 0);
1232 prompt_TtyTermMode(arg
->prompt
, arg
->cx
);
1237 QuitCommand(struct cmdargs
const *arg
)
1239 if (!arg
->prompt
|| prompt_IsController(arg
->prompt
) ||
1240 (arg
->argc
> arg
->argn
&& !strcasecmp(arg
->argv
[arg
->argn
], "all") &&
1241 (arg
->prompt
->auth
& LOCAL_AUTH
)))
1244 prompt_Destroy(arg
->prompt
, 1);
1250 OpenCommand(struct cmdargs
const *arg
)
1252 if (arg
->argc
== arg
->argn
)
1253 bundle_Open(arg
->bundle
, arg
->cx
? arg
->cx
->name
: NULL
, PHYS_ALL
, 1);
1254 else if (arg
->argc
== arg
->argn
+ 1) {
1255 if (!strcasecmp(arg
->argv
[arg
->argn
], "lcp")) {
1256 struct datalink
*cx
= arg
->cx
?
1257 arg
->cx
: bundle2datalink(arg
->bundle
, NULL
);
1259 if (cx
->physical
->link
.lcp
.fsm
.state
== ST_OPENED
)
1260 fsm_Reopen(&cx
->physical
->link
.lcp
.fsm
);
1262 bundle_Open(arg
->bundle
, cx
->name
, PHYS_ALL
, 1);
1264 log_Printf(LogWARN
, "open lcp: You must specify a link\n");
1265 } else if (!strcasecmp(arg
->argv
[arg
->argn
], "ccp")) {
1268 fp
= &command_ChooseLink(arg
)->ccp
.fsm
;
1269 if (fp
->link
->lcp
.fsm
.state
!= ST_OPENED
)
1270 log_Printf(LogWARN
, "open: LCP must be open before opening CCP\n");
1271 else if (fp
->state
== ST_OPENED
)
1274 fp
->open_mode
= 0; /* Not passive any more */
1275 if (fp
->state
== ST_STOPPED
) {
1283 } else if (!strcasecmp(arg
->argv
[arg
->argn
], "ipcp")) {
1285 log_Printf(LogWARN
, "open ipcp: You need not specify a link\n");
1286 if (arg
->bundle
->ncp
.ipcp
.fsm
.state
== ST_OPENED
)
1287 fsm_Reopen(&arg
->bundle
->ncp
.ipcp
.fsm
);
1289 bundle_Open(arg
->bundle
, NULL
, PHYS_ALL
, 1);
1299 CloseCommand(struct cmdargs
const *arg
)
1301 if (arg
->argc
== arg
->argn
)
1302 bundle_Close(arg
->bundle
, arg
->cx
? arg
->cx
->name
: NULL
, CLOSE_STAYDOWN
);
1303 else if (arg
->argc
== arg
->argn
+ 1) {
1304 if (!strcasecmp(arg
->argv
[arg
->argn
], "lcp"))
1305 bundle_Close(arg
->bundle
, arg
->cx
? arg
->cx
->name
: NULL
, CLOSE_LCP
);
1306 else if (!strcasecmp(arg
->argv
[arg
->argn
], "ccp") ||
1307 !strcasecmp(arg
->argv
[arg
->argn
], "ccp!")) {
1310 fp
= &command_ChooseLink(arg
)->ccp
.fsm
;
1311 if (fp
->state
== ST_OPENED
) {
1313 if (arg
->argv
[arg
->argn
][3] == '!')
1314 fp
->open_mode
= 0; /* Stay ST_CLOSED */
1316 fp
->open_mode
= OPEN_PASSIVE
; /* Wait for the peer to start */
1327 DownCommand(struct cmdargs
const *arg
)
1329 if (arg
->argc
== arg
->argn
) {
1331 datalink_Down(arg
->cx
, CLOSE_STAYDOWN
);
1333 bundle_Down(arg
->bundle
, CLOSE_STAYDOWN
);
1334 } else if (arg
->argc
== arg
->argn
+ 1) {
1335 if (!strcasecmp(arg
->argv
[arg
->argn
], "lcp")) {
1337 datalink_Down(arg
->cx
, CLOSE_LCP
);
1339 bundle_Down(arg
->bundle
, CLOSE_LCP
);
1340 } else if (!strcasecmp(arg
->argv
[arg
->argn
], "ccp")) {
1341 struct fsm
*fp
= arg
->cx
? &arg
->cx
->physical
->link
.ccp
.fsm
:
1342 &arg
->bundle
->ncp
.mp
.link
.ccp
.fsm
;
1353 SetModemSpeed(struct cmdargs
const *arg
)
1358 if (arg
->argc
> arg
->argn
&& *arg
->argv
[arg
->argn
]) {
1359 if (arg
->argc
> arg
->argn
+1) {
1360 log_Printf(LogWARN
, "SetModemSpeed: Too many arguments\n");
1363 if (strcasecmp(arg
->argv
[arg
->argn
], "sync") == 0) {
1364 physical_SetSync(arg
->cx
->physical
);
1368 speed
= strtol(arg
->argv
[arg
->argn
], &end
, 10);
1370 log_Printf(LogWARN
, "SetModemSpeed: Bad argument \"%s\"",
1371 arg
->argv
[arg
->argn
]);
1374 if (physical_SetSpeed(arg
->cx
->physical
, speed
))
1376 log_Printf(LogWARN
, "%s: Invalid speed\n", arg
->argv
[arg
->argn
]);
1378 log_Printf(LogWARN
, "SetModemSpeed: No speed specified\n");
1384 SetStoppedTimeout(struct cmdargs
const *arg
)
1386 struct link
*l
= &arg
->cx
->physical
->link
;
1388 l
->lcp
.fsm
.StoppedTimer
.load
= 0;
1389 l
->ccp
.fsm
.StoppedTimer
.load
= 0;
1390 if (arg
->argc
<= arg
->argn
+2) {
1391 if (arg
->argc
> arg
->argn
) {
1392 l
->lcp
.fsm
.StoppedTimer
.load
= atoi(arg
->argv
[arg
->argn
]) * SECTICKS
;
1393 if (arg
->argc
> arg
->argn
+1)
1394 l
->ccp
.fsm
.StoppedTimer
.load
= atoi(arg
->argv
[arg
->argn
+1]) * SECTICKS
;
1402 SetServer(struct cmdargs
const *arg
)
1406 if (arg
->argc
> arg
->argn
&& arg
->argc
< arg
->argn
+4) {
1407 const char *port
, *passwd
, *mask
;
1411 port
= arg
->argv
[arg
->argn
];
1412 if (arg
->argc
== arg
->argn
+ 2) {
1413 passwd
= arg
->argv
[arg
->argn
+1];
1415 } else if (arg
->argc
== arg
->argn
+ 3) {
1416 passwd
= arg
->argv
[arg
->argn
+1];
1417 mask
= arg
->argv
[arg
->argn
+2];
1418 mlen
= strlen(mask
);
1419 if (mlen
== 0 || mlen
> 4 || strspn(mask
, "01234567") != mlen
||
1420 (mlen
== 4 && *mask
!= '0')) {
1421 log_Printf(LogWARN
, "%s %s: %s: Invalid mask\n",
1422 arg
->argv
[arg
->argn
- 2], arg
->argv
[arg
->argn
- 1], mask
);
1425 } else if (arg
->argc
!= arg
->argn
+ 1)
1427 else if (strcasecmp(port
, "none") == 0) {
1428 if (server_Clear(arg
->bundle
))
1429 log_Printf(LogPHASE
, "Disabled server socket\n");
1431 } else if (strcasecmp(port
, "open") == 0) {
1432 switch (server_Reopen(arg
->bundle
)) {
1436 log_Printf(LogWARN
, "Failed to reopen server port\n");
1439 log_Printf(LogWARN
, "Cannot reopen unset server socket\n");
1445 } else if (strcasecmp(port
, "closed") == 0) {
1446 if (server_Close(arg
->bundle
))
1447 log_Printf(LogPHASE
, "Closed server socket\n");
1449 log_Printf(LogWARN
, "Server socket not open\n");
1455 strncpy(server
.cfg
.passwd
, passwd
, sizeof server
.cfg
.passwd
- 1);
1456 server
.cfg
.passwd
[sizeof server
.cfg
.passwd
- 1] = '\0';
1460 char *ptr
, name
[LINE_LEN
+ 12];
1464 else for (imask
= mlen
= 0; mask
[mlen
]; mlen
++)
1465 imask
= (imask
* 8) + mask
[mlen
] - '0';
1467 ptr
= strstr(port
, "%d");
1469 snprintf(name
, sizeof name
, "%.*s%d%s",
1470 (int)(ptr
- port
), port
, arg
->bundle
->unit
, ptr
+ 2);
1473 res
= server_LocalOpen(arg
->bundle
, port
, imask
);
1484 if (strspn(port
, "0123456789") != strlen(port
)) {
1487 if ((s
= getservbyname(port
, "tcp")) == NULL
) {
1489 log_Printf(LogWARN
, "%s: Invalid port or service\n", port
);
1491 iport
= ntohs(s
->s_port
);
1497 iport
+= arg
->bundle
->unit
;
1498 res
= server_TcpOpen(arg
->bundle
, iport
);
1508 SetEscape(struct cmdargs
const *arg
)
1511 int argc
= arg
->argc
- arg
->argn
;
1512 char const *const *argv
= arg
->argv
+ arg
->argn
;
1514 for (code
= 0; code
< 33; code
++)
1515 arg
->cx
->physical
->async
.cfg
.EscMap
[code
] = 0;
1517 while (argc
-- > 0) {
1518 sscanf(*argv
++, "%x", &code
);
1520 arg
->cx
->physical
->async
.cfg
.EscMap
[code
>> 3] |= (1 << (code
& 7));
1521 arg
->cx
->physical
->async
.cfg
.EscMap
[32] = 1;
1527 SetInterfaceAddr(struct cmdargs
const *arg
)
1529 struct ncp
*ncp
= &arg
->bundle
->ncp
;
1530 struct ncpaddr ncpaddr
;
1531 const char *hisaddr
;
1533 if (arg
->argc
> arg
->argn
+ 4)
1537 memset(&ncp
->ipcp
.cfg
.my_range
, '\0', sizeof ncp
->ipcp
.cfg
.my_range
);
1538 memset(&ncp
->ipcp
.cfg
.peer_range
, '\0', sizeof ncp
->ipcp
.cfg
.peer_range
);
1539 ncp
->ipcp
.cfg
.HaveTriggerAddress
= 0;
1540 ncp
->ipcp
.cfg
.netmask
.s_addr
= INADDR_ANY
;
1541 iplist_reset(&ncp
->ipcp
.cfg
.peer_list
);
1543 if (arg
->argc
> arg
->argn
) {
1544 if (!ncprange_aton(&ncp
->ipcp
.cfg
.my_range
, ncp
, arg
->argv
[arg
->argn
]))
1546 if (arg
->argc
> arg
->argn
+1) {
1547 hisaddr
= arg
->argv
[arg
->argn
+1];
1548 if (arg
->argc
> arg
->argn
+2) {
1549 ncp
->ipcp
.ifmask
= ncp
->ipcp
.cfg
.netmask
=
1550 GetIpAddr(arg
->argv
[arg
->argn
+2]);
1551 if (arg
->argc
> arg
->argn
+3) {
1552 ncp
->ipcp
.cfg
.TriggerAddress
= GetIpAddr(arg
->argv
[arg
->argn
+3]);
1553 ncp
->ipcp
.cfg
.HaveTriggerAddress
= 1;
1559 /* 0.0.0.0 means any address (0 bits) */
1560 ncpaddr_getip4(&ncpaddr
, &ncp
->ipcp
.my_ip
);
1561 ncprange_getaddr(&ncp
->ipcp
.cfg
.my_range
, &ncpaddr
);
1562 if (ncp
->ipcp
.my_ip
.s_addr
== INADDR_ANY
)
1563 ncprange_setwidth(&ncp
->ipcp
.cfg
.my_range
, 0);
1564 bundle_AdjustFilters(arg
->bundle
, &ncpaddr
, NULL
);
1566 if (hisaddr
&& !ipcp_UseHisaddr(arg
->bundle
, hisaddr
,
1567 arg
->bundle
->phys_type
.all
& PHYS_AUTO
))
1574 SetRetry(int argc
, char const *const *argv
, u_int
*timeout
, u_int
*maxreq
,
1575 u_int
*maxtrm
, int def
)
1578 *timeout
= DEF_FSMRETRY
;
1583 long l
= atol(argv
[0]);
1585 if (l
< MIN_FSMRETRY
) {
1586 log_Printf(LogWARN
, "%ld: Invalid FSM retry period - min %d\n",
1595 log_Printf(LogWARN
, "%ld: Invalid FSM REQ tries - changed to 1\n", l
);
1600 if (argc
> 2 && maxtrm
!= NULL
) {
1603 log_Printf(LogWARN
, "%ld: Invalid FSM TRM tries - changed to 1\n", l
);
1615 SetVariable(struct cmdargs
const *arg
)
1617 long long_val
, param
= (long)arg
->cmd
->args
;
1618 int mode
, dummyint
, f
, first
, res
;
1621 struct datalink
*cx
= arg
->cx
; /* LOCAL_CX uses this */
1622 struct link
*l
= command_ChooseLink(arg
); /* LOCAL_CX_OPT uses this */
1623 struct in_addr
*ipaddr
;
1624 struct ncpaddr ncpaddr
[2];
1626 if (arg
->argc
> arg
->argn
)
1627 argp
= arg
->argv
[arg
->argn
];
1633 if ((arg
->cmd
->lauth
& LOCAL_CX
) && !cx
) {
1634 log_Printf(LogWARN
, "set %s: No context (use the `link' command)\n",
1637 } else if (cx
&& !(arg
->cmd
->lauth
& (LOCAL_CX
|LOCAL_CX_OPT
))) {
1638 log_Printf(LogWARN
, "set %s: Redundant context (%s) ignored\n",
1639 arg
->cmd
->name
, cx
->name
);
1645 strncpy(arg
->bundle
->cfg
.auth
.key
, argp
,
1646 sizeof arg
->bundle
->cfg
.auth
.key
- 1);
1647 arg
->bundle
->cfg
.auth
.key
[sizeof arg
->bundle
->cfg
.auth
.key
- 1] = '\0';
1651 switch (bundle_Phase(arg
->bundle
)) {
1653 log_Printf(LogWARN
, "Altering authname while at phase %s\n",
1654 bundle_PhaseName(arg
->bundle
));
1657 case PHASE_ESTABLISH
:
1658 strncpy(arg
->bundle
->cfg
.auth
.name
, argp
,
1659 sizeof arg
->bundle
->cfg
.auth
.name
- 1);
1660 arg
->bundle
->cfg
.auth
.name
[sizeof arg
->bundle
->cfg
.auth
.name
-1] = '\0';
1666 if (arg
->argc
== arg
->argn
+ 3) {
1670 v1
= strtol(arg
->argv
[arg
->argn
], &end
, 0);
1671 if (v1
< 0 || *end
) {
1672 log_Printf(LogWARN
, "autoload: %s: Invalid min percentage\n",
1673 arg
->argv
[arg
->argn
]);
1678 v2
= strtol(arg
->argv
[arg
->argn
+ 1], &end
, 0);
1679 if (v2
< 0 || *end
) {
1680 log_Printf(LogWARN
, "autoload: %s: Invalid max percentage\n",
1681 arg
->argv
[arg
->argn
+ 1]);
1691 v3
= strtol(arg
->argv
[arg
->argn
+ 2], &end
, 0);
1692 if (v3
<= 0 || *end
) {
1693 log_Printf(LogWARN
, "autoload: %s: Invalid throughput period\n",
1694 arg
->argv
[arg
->argn
+ 2]);
1699 arg
->bundle
->ncp
.mp
.cfg
.autoload
.min
= v1
;
1700 arg
->bundle
->ncp
.mp
.cfg
.autoload
.max
= v2
;
1701 arg
->bundle
->ncp
.mp
.cfg
.autoload
.period
= v3
;
1702 mp_RestartAutoloadTimer(&arg
->bundle
->ncp
.mp
);
1704 log_Printf(LogWARN
, "Set autoload requires three arguments\n");
1710 strncpy(cx
->cfg
.script
.dial
, argp
, sizeof cx
->cfg
.script
.dial
- 1);
1711 cx
->cfg
.script
.dial
[sizeof cx
->cfg
.script
.dial
- 1] = '\0';
1715 strncpy(cx
->cfg
.script
.login
, argp
, sizeof cx
->cfg
.script
.login
- 1);
1716 cx
->cfg
.script
.login
[sizeof cx
->cfg
.script
.login
- 1] = '\0';
1720 if (arg
->argc
> arg
->argn
) {
1721 l
->ccp
.cfg
.deflate
.out
.winsize
= atoi(arg
->argv
[arg
->argn
]);
1722 if (l
->ccp
.cfg
.deflate
.out
.winsize
< 8 ||
1723 l
->ccp
.cfg
.deflate
.out
.winsize
> 15) {
1724 log_Printf(LogWARN
, "%d: Invalid outgoing window size\n",
1725 l
->ccp
.cfg
.deflate
.out
.winsize
);
1726 l
->ccp
.cfg
.deflate
.out
.winsize
= 15;
1728 if (arg
->argc
> arg
->argn
+1) {
1729 l
->ccp
.cfg
.deflate
.in
.winsize
= atoi(arg
->argv
[arg
->argn
+1]);
1730 if (l
->ccp
.cfg
.deflate
.in
.winsize
< 8 ||
1731 l
->ccp
.cfg
.deflate
.in
.winsize
> 15) {
1732 log_Printf(LogWARN
, "%d: Invalid incoming window size\n",
1733 l
->ccp
.cfg
.deflate
.in
.winsize
);
1734 l
->ccp
.cfg
.deflate
.in
.winsize
= 15;
1737 l
->ccp
.cfg
.deflate
.in
.winsize
= 0;
1739 log_Printf(LogWARN
, "No window size specified\n");
1746 if (arg
->argc
> arg
->argn
+ 2) {
1751 if (arg
->argc
== arg
->argn
) {
1752 l
->ccp
.cfg
.mppe
.keybits
= 0;
1753 l
->ccp
.cfg
.mppe
.state
= MPPE_ANYSTATE
;
1754 l
->ccp
.cfg
.mppe
.required
= 0;
1758 if (!strcmp(argp
, "*"))
1761 long_val
= atol(argp
);
1762 if (long_val
!= 40 && long_val
!= 56 && long_val
!= 128) {
1763 log_Printf(LogWARN
, "%s: Invalid bits value\n", argp
);
1769 if (arg
->argc
== arg
->argn
+ 2) {
1770 if (!strcmp(arg
->argv
[arg
->argn
+ 1], "*"))
1771 l
->ccp
.cfg
.mppe
.state
= MPPE_ANYSTATE
;
1772 else if (!strcasecmp(arg
->argv
[arg
->argn
+ 1], "stateless"))
1773 l
->ccp
.cfg
.mppe
.state
= MPPE_STATELESS
;
1774 else if (!strcasecmp(arg
->argv
[arg
->argn
+ 1], "stateful"))
1775 l
->ccp
.cfg
.mppe
.state
= MPPE_STATEFUL
;
1777 log_Printf(LogWARN
, "%s: Invalid state value\n",
1778 arg
->argv
[arg
->argn
+ 1]);
1783 l
->ccp
.cfg
.mppe
.state
= MPPE_ANYSTATE
;
1784 l
->ccp
.cfg
.mppe
.keybits
= long_val
;
1785 l
->ccp
.cfg
.mppe
.required
= 1;
1790 physical_SetDeviceList(cx
->physical
, arg
->argc
- arg
->argn
,
1791 arg
->argv
+ arg
->argn
);
1795 if (arg
->argc
> arg
->argn
) {
1797 sscanf(argp
, "%lx", &ulong_val
);
1798 cx
->physical
->link
.lcp
.cfg
.accmap
= (u_int32_t
)ulong_val
;
1800 log_Printf(LogWARN
, "No accmap specified\n");
1806 mode
= Nam2mode(argp
);
1807 if (mode
== PHYS_NONE
|| mode
== PHYS_ALL
) {
1808 log_Printf(LogWARN
, "%s: Invalid mode\n", argp
);
1812 bundle_SetMode(arg
->bundle
, cx
, mode
);
1816 switch (bundle_Phase(arg
->bundle
)) {
1819 case PHASE_ESTABLISH
:
1820 /* Make sure none of our links are DATALINK_LCP or greater */
1821 if (bundle_HighestState(arg
->bundle
) >= DATALINK_LCP
) {
1822 log_Printf(LogWARN
, "mrru: Only changeable before LCP negotiations\n");
1828 log_Printf(LogWARN
, "mrru: Only changeable at phase DEAD/ESTABLISH\n");
1834 long_val
= atol(argp
);
1835 if (long_val
&& long_val
< MIN_MRU
) {
1836 log_Printf(LogWARN
, "MRRU %ld: too small - min %d\n", long_val
, MIN_MRU
);
1839 } else if (long_val
> MAX_MRU
) {
1840 log_Printf(LogWARN
, "MRRU %ld: too big - max %d\n", long_val
, MAX_MRU
);
1844 arg
->bundle
->ncp
.mp
.cfg
.mrru
= long_val
;
1848 long_val
= 0; /* silence gcc */
1849 change
= NULL
; /* silence gcc */
1850 switch(arg
->argc
- arg
->argn
) {
1852 if (argp
[strspn(argp
, "0123456789")] != '\0') {
1858 long_val
= atol(argp
);
1859 change
= &l
->lcp
.cfg
.mru
;
1860 if (long_val
> l
->lcp
.cfg
.max_mru
) {
1861 log_Printf(LogWARN
, "MRU %ld: too large - max set to %d\n", long_val
,
1862 l
->lcp
.cfg
.max_mru
);
1868 if (strcasecmp(argp
, "max") && strcasecmp(argp
, "maximum")) {
1872 long_val
= atol(arg
->argv
[arg
->argn
+ 1]);
1873 change
= &l
->lcp
.cfg
.max_mru
;
1874 if (long_val
> MAX_MRU
) {
1875 log_Printf(LogWARN
, "MRU %ld: too large - maximum is %d\n", long_val
,
1890 else if (long_val
< MIN_MRU
) {
1891 log_Printf(LogWARN
, "MRU %ld: too small - min %d\n", long_val
, MIN_MRU
);
1894 } else if (long_val
> MAX_MRU
) {
1895 log_Printf(LogWARN
, "MRU %ld: too big - max %d\n", long_val
, MAX_MRU
);
1900 if (l
->lcp
.cfg
.mru
> *change
)
1901 l
->lcp
.cfg
.mru
= *change
;
1905 long_val
= 0; /* silence gcc */
1906 change
= NULL
; /* silence gcc */
1907 switch(arg
->argc
- arg
->argn
) {
1909 if (argp
[strspn(argp
, "0123456789")] != '\0') {
1915 long_val
= atol(argp
);
1916 change
= &l
->lcp
.cfg
.mtu
;
1917 if (long_val
> l
->lcp
.cfg
.max_mtu
) {
1918 log_Printf(LogWARN
, "MTU %ld: too large - max set to %d\n", long_val
,
1919 l
->lcp
.cfg
.max_mtu
);
1925 if (strcasecmp(argp
, "max") && strcasecmp(argp
, "maximum")) {
1929 long_val
= atol(arg
->argv
[arg
->argn
+ 1]);
1930 change
= &l
->lcp
.cfg
.max_mtu
;
1931 if (long_val
> MAX_MTU
) {
1932 log_Printf(LogWARN
, "MTU %ld: too large - maximum is %d\n", long_val
,
1946 if (long_val
&& long_val
< MIN_MTU
) {
1947 log_Printf(LogWARN
, "MTU %ld: too small - min %d\n", long_val
, MIN_MTU
);
1950 } else if (long_val
> MAX_MTU
) {
1951 log_Printf(LogWARN
, "MTU %ld: too big - max %d\n", long_val
, MAX_MTU
);
1956 if (l
->lcp
.cfg
.mtu
> *change
)
1957 l
->lcp
.cfg
.mtu
= *change
;
1961 if (strcasecmp(argp
, "active") == 0)
1962 cx
->physical
->link
.lcp
.cfg
.openmode
= arg
->argc
> arg
->argn
+1 ?
1963 atoi(arg
->argv
[arg
->argn
+1]) : 1;
1964 else if (strcasecmp(argp
, "passive") == 0)
1965 cx
->physical
->link
.lcp
.cfg
.openmode
= OPEN_PASSIVE
;
1967 log_Printf(LogWARN
, "%s: Invalid openmode\n", argp
);
1973 strncpy(cx
->cfg
.phone
.list
, argp
, sizeof cx
->cfg
.phone
.list
- 1);
1974 cx
->cfg
.phone
.list
[sizeof cx
->cfg
.phone
.list
- 1] = '\0';
1975 cx
->phone
.alt
= cx
->phone
.next
= NULL
;
1979 strncpy(cx
->cfg
.script
.hangup
, argp
, sizeof cx
->cfg
.script
.hangup
- 1);
1980 cx
->cfg
.script
.hangup
[sizeof cx
->cfg
.script
.hangup
- 1] = '\0';
1984 long_val
= atol(argp
);
1985 arg
->bundle
->cfg
.ifqueue
= long_val
< 0 ? 0 : long_val
;
1989 strncpy(cx
->cfg
.script
.logout
, argp
, sizeof cx
->cfg
.script
.logout
- 1);
1990 cx
->cfg
.script
.logout
[sizeof cx
->cfg
.script
.logout
- 1] = '\0';
1993 case VAR_IDLETIMEOUT
:
1994 if (arg
->argc
> arg
->argn
+2) {
1995 log_Printf(LogWARN
, "Too many idle timeout values\n");
1997 } else if (arg
->argc
== arg
->argn
) {
1998 log_Printf(LogWARN
, "Too few idle timeout values\n");
2003 timeout
= atoi(argp
);
2004 min
= arg
->argc
== arg
->argn
+ 2 ? atoi(arg
->argv
[arg
->argn
+ 1]) : -1;
2005 bundle_SetIdleTimer(arg
->bundle
, timeout
, min
);
2010 long_val
= atol(argp
);
2011 if (long_val
< MIN_LQRPERIOD
) {
2012 log_Printf(LogWARN
, "%ld: Invalid lqr period - min %d\n",
2013 long_val
, MIN_LQRPERIOD
);
2016 l
->lcp
.cfg
.lqrperiod
= long_val
;
2020 res
= SetRetry(arg
->argc
- arg
->argn
, arg
->argv
+ arg
->argn
,
2021 &cx
->physical
->link
.lcp
.cfg
.fsm
.timeout
,
2022 &cx
->physical
->link
.lcp
.cfg
.fsm
.maxreq
,
2023 &cx
->physical
->link
.lcp
.cfg
.fsm
.maxtrm
, DEF_FSMTRIES
);
2027 res
= SetRetry(arg
->argc
- arg
->argn
, arg
->argv
+ arg
->argn
,
2028 &cx
->chap
.auth
.cfg
.fsm
.timeout
,
2029 &cx
->chap
.auth
.cfg
.fsm
.maxreq
, NULL
, DEF_FSMAUTHTRIES
);
2033 res
= SetRetry(arg
->argc
- arg
->argn
, arg
->argv
+ arg
->argn
,
2034 &cx
->pap
.cfg
.fsm
.timeout
, &cx
->pap
.cfg
.fsm
.maxreq
,
2035 NULL
, DEF_FSMAUTHTRIES
);
2039 res
= SetRetry(arg
->argc
- arg
->argn
, arg
->argv
+ arg
->argn
,
2040 &l
->ccp
.cfg
.fsm
.timeout
, &l
->ccp
.cfg
.fsm
.maxreq
,
2041 &l
->ccp
.cfg
.fsm
.maxtrm
, DEF_FSMTRIES
);
2045 res
= SetRetry(arg
->argc
- arg
->argn
, arg
->argv
+ arg
->argn
,
2046 &arg
->bundle
->ncp
.ipcp
.cfg
.fsm
.timeout
,
2047 &arg
->bundle
->ncp
.ipcp
.cfg
.fsm
.maxreq
,
2048 &arg
->bundle
->ncp
.ipcp
.cfg
.fsm
.maxtrm
, DEF_FSMTRIES
);
2052 case VAR_IPV6CPRETRY
:
2053 res
= SetRetry(arg
->argc
- arg
->argn
, arg
->argv
+ arg
->argn
,
2054 &arg
->bundle
->ncp
.ipv6cp
.cfg
.fsm
.timeout
,
2055 &arg
->bundle
->ncp
.ipv6cp
.cfg
.fsm
.maxreq
,
2056 &arg
->bundle
->ncp
.ipv6cp
.cfg
.fsm
.maxtrm
, DEF_FSMTRIES
);
2062 if (param
== VAR_DNS
) {
2063 ipaddr
= arg
->bundle
->ncp
.ipcp
.cfg
.ns
.dns
;
2064 ipaddr
[0].s_addr
= ipaddr
[1].s_addr
= INADDR_NONE
;
2066 ipaddr
= arg
->bundle
->ncp
.ipcp
.cfg
.ns
.nbns
;
2067 ipaddr
[0].s_addr
= ipaddr
[1].s_addr
= INADDR_ANY
;
2070 if (arg
->argc
> arg
->argn
) {
2071 ncpaddr_aton(ncpaddr
, &arg
->bundle
->ncp
, arg
->argv
[arg
->argn
]);
2072 if (!ncpaddr_getip4(ncpaddr
, ipaddr
))
2074 if (arg
->argc
> arg
->argn
+1) {
2075 ncpaddr_aton(ncpaddr
+ 1, &arg
->bundle
->ncp
, arg
->argv
[arg
->argn
+ 1]);
2076 if (!ncpaddr_getip4(ncpaddr
+ 1, ipaddr
+ 1))
2080 if (ipaddr
[0].s_addr
== INADDR_ANY
) {
2081 ipaddr
[0] = ipaddr
[1];
2082 ipaddr
[1].s_addr
= INADDR_ANY
;
2084 if (ipaddr
[0].s_addr
== INADDR_NONE
) {
2085 ipaddr
[0] = ipaddr
[1];
2086 ipaddr
[1].s_addr
= INADDR_NONE
;
2092 cx
->cfg
.callback
.opmask
= 0;
2093 for (dummyint
= arg
->argn
; dummyint
< arg
->argc
; dummyint
++) {
2094 if (!strcasecmp(arg
->argv
[dummyint
], "auth"))
2095 cx
->cfg
.callback
.opmask
|= CALLBACK_BIT(CALLBACK_AUTH
);
2096 else if (!strcasecmp(arg
->argv
[dummyint
], "cbcp"))
2097 cx
->cfg
.callback
.opmask
|= CALLBACK_BIT(CALLBACK_CBCP
);
2098 else if (!strcasecmp(arg
->argv
[dummyint
], "e.164")) {
2099 if (dummyint
== arg
->argc
- 1)
2100 log_Printf(LogWARN
, "No E.164 arg (E.164 ignored) !\n");
2102 cx
->cfg
.callback
.opmask
|= CALLBACK_BIT(CALLBACK_E164
);
2103 strncpy(cx
->cfg
.callback
.msg
, arg
->argv
[++dummyint
],
2104 sizeof cx
->cfg
.callback
.msg
- 1);
2105 cx
->cfg
.callback
.msg
[sizeof cx
->cfg
.callback
.msg
- 1] = '\0';
2107 } else if (!strcasecmp(arg
->argv
[dummyint
], "none"))
2108 cx
->cfg
.callback
.opmask
|= CALLBACK_BIT(CALLBACK_NONE
);
2114 if (cx
->cfg
.callback
.opmask
== CALLBACK_BIT(CALLBACK_NONE
))
2115 cx
->cfg
.callback
.opmask
= 0;
2119 cx
->cfg
.cbcp
.delay
= 0;
2120 *cx
->cfg
.cbcp
.phone
= '\0';
2121 cx
->cfg
.cbcp
.fsmretry
= DEF_FSMRETRY
;
2122 if (arg
->argc
> arg
->argn
) {
2123 strncpy(cx
->cfg
.cbcp
.phone
, arg
->argv
[arg
->argn
],
2124 sizeof cx
->cfg
.cbcp
.phone
- 1);
2125 cx
->cfg
.cbcp
.phone
[sizeof cx
->cfg
.cbcp
.phone
- 1] = '\0';
2126 if (arg
->argc
> arg
->argn
+ 1) {
2127 cx
->cfg
.cbcp
.delay
= atoi(arg
->argv
[arg
->argn
+ 1]);
2128 if (arg
->argc
> arg
->argn
+ 2) {
2129 long_val
= atol(arg
->argv
[arg
->argn
+ 2]);
2130 if (long_val
< MIN_FSMRETRY
)
2131 log_Printf(LogWARN
, "%ld: Invalid CBCP FSM retry period - min %d\n",
2132 long_val
, MIN_FSMRETRY
);
2134 cx
->cfg
.cbcp
.fsmretry
= long_val
;
2141 arg
->bundle
->cfg
.choked
.timeout
= atoi(argp
);
2142 if (arg
->bundle
->cfg
.choked
.timeout
<= 0)
2143 arg
->bundle
->cfg
.choked
.timeout
= CHOKED_TIMEOUT
;
2147 long_val
= atol(argp
);
2148 arg
->bundle
->ncp
.cfg
.sendpipe
= long_val
;
2152 long_val
= atol(argp
);
2153 arg
->bundle
->ncp
.cfg
.recvpipe
= long_val
;
2159 *arg
->bundle
->radius
.cfg
.file
= '\0';
2160 else if (access(argp
, R_OK
)) {
2161 log_Printf(LogWARN
, "%s: %s\n", argp
, strerror(errno
));
2165 strncpy(arg
->bundle
->radius
.cfg
.file
, argp
,
2166 sizeof arg
->bundle
->radius
.cfg
.file
- 1);
2167 arg
->bundle
->radius
.cfg
.file
2168 [sizeof arg
->bundle
->radius
.cfg
.file
- 1] = '\0';
2175 if (strcasecmp(argp
, "off")) {
2176 long_val
= atol(argp
);
2179 cx
->physical
->cfg
.cd
.delay
= long_val
;
2180 cx
->physical
->cfg
.cd
.necessity
= argp
[strlen(argp
)-1] == '!' ?
2181 CD_REQUIRED
: CD_VARIABLE
;
2183 cx
->physical
->cfg
.cd
.necessity
= CD_NOTREQUIRED
;
2185 cx
->physical
->cfg
.cd
.delay
= 0;
2186 cx
->physical
->cfg
.cd
.necessity
= CD_DEFAULT
;
2191 if (arg
->argc
== arg
->argn
+ 1)
2192 res
= physical_SetParity(arg
->cx
->physical
, argp
);
2194 log_Printf(LogWARN
, "Parity value must be odd, even or none\n");
2200 if (strcasecmp(argp
, "on") == 0)
2201 physical_SetRtsCts(arg
->cx
->physical
, 1);
2202 else if (strcasecmp(argp
, "off") == 0)
2203 physical_SetRtsCts(arg
->cx
->physical
, 0);
2205 log_Printf(LogWARN
, "RTS/CTS value must be on or off\n");
2210 case VAR_URGENTPORTS
:
2211 if (arg
->argn
== arg
->argc
) {
2212 ncp_SetUrgentTOS(&arg
->bundle
->ncp
);
2213 ncp_ClearUrgentTcpPorts(&arg
->bundle
->ncp
);
2214 ncp_ClearUrgentUdpPorts(&arg
->bundle
->ncp
);
2215 } else if (!strcasecmp(arg
->argv
[arg
->argn
], "udp")) {
2216 ncp_SetUrgentTOS(&arg
->bundle
->ncp
);
2217 if (arg
->argn
== arg
->argc
- 1)
2218 ncp_ClearUrgentUdpPorts(&arg
->bundle
->ncp
);
2219 else for (f
= arg
->argn
+ 1; f
< arg
->argc
; f
++)
2220 if (*arg
->argv
[f
] == '+')
2221 ncp_AddUrgentUdpPort(&arg
->bundle
->ncp
, atoi(arg
->argv
[f
] + 1));
2222 else if (*arg
->argv
[f
] == '-')
2223 ncp_RemoveUrgentUdpPort(&arg
->bundle
->ncp
, atoi(arg
->argv
[f
] + 1));
2226 ncp_ClearUrgentUdpPorts(&arg
->bundle
->ncp
);
2227 ncp_AddUrgentUdpPort(&arg
->bundle
->ncp
, atoi(arg
->argv
[f
]));
2229 } else if (arg
->argn
== arg
->argc
- 1 &&
2230 !strcasecmp(arg
->argv
[arg
->argn
], "none")) {
2231 ncp_ClearUrgentTcpPorts(&arg
->bundle
->ncp
);
2232 ncp_ClearUrgentUdpPorts(&arg
->bundle
->ncp
);
2233 ncp_ClearUrgentTOS(&arg
->bundle
->ncp
);
2235 ncp_SetUrgentTOS(&arg
->bundle
->ncp
);
2237 if (!strcasecmp(arg
->argv
[first
], "tcp") && ++first
== arg
->argc
)
2238 ncp_ClearUrgentTcpPorts(&arg
->bundle
->ncp
);
2240 for (f
= first
; f
< arg
->argc
; f
++)
2241 if (*arg
->argv
[f
] == '+')
2242 ncp_AddUrgentTcpPort(&arg
->bundle
->ncp
, atoi(arg
->argv
[f
] + 1));
2243 else if (*arg
->argv
[f
] == '-')
2244 ncp_RemoveUrgentTcpPort(&arg
->bundle
->ncp
, atoi(arg
->argv
[f
] + 1));
2247 ncp_ClearUrgentTcpPorts(&arg
->bundle
->ncp
);
2248 ncp_AddUrgentTcpPort(&arg
->bundle
->ncp
, atoi(arg
->argv
[f
]));
2257 static struct cmdtab
const SetCommands
[] = {
2258 {"accmap", NULL
, SetVariable
, LOCAL_AUTH
| LOCAL_CX
,
2259 "accmap value", "set accmap hex-value", (const void *)VAR_ACCMAP
},
2260 {"authkey", "key", SetVariable
, LOCAL_AUTH
,
2261 "authentication key", "set authkey|key key", (const void *)VAR_AUTHKEY
},
2262 {"authname", NULL
, SetVariable
, LOCAL_AUTH
,
2263 "authentication name", "set authname name", (const void *)VAR_AUTHNAME
},
2264 {"autoload", NULL
, SetVariable
, LOCAL_AUTH
,
2265 "auto link [de]activation", "set autoload maxtime maxload mintime minload",
2266 (const void *)VAR_AUTOLOAD
},
2267 {"bandwidth", NULL
, mp_SetDatalinkBandwidth
, LOCAL_AUTH
| LOCAL_CX
,
2268 "datalink bandwidth", "set bandwidth value"},
2269 {"callback", NULL
, SetVariable
, LOCAL_AUTH
| LOCAL_CX
,
2270 "callback control", "set callback [none|auth|cbcp|"
2271 "E.164 *|number[,number]...]...", (const void *)VAR_CALLBACK
},
2272 {"cbcp", NULL
, SetVariable
, LOCAL_AUTH
| LOCAL_CX
,
2273 "CBCP control", "set cbcp [*|phone[,phone...] [delay [timeout]]]",
2274 (const void *)VAR_CBCP
},
2275 {"ccpretry", "ccpretries", SetVariable
, LOCAL_AUTH
| LOCAL_CX_OPT
,
2276 "CCP retries", "set ccpretry value [attempts]", (const void *)VAR_CCPRETRY
},
2277 {"cd", NULL
, SetVariable
, LOCAL_AUTH
| LOCAL_CX
, "Carrier delay requirement",
2278 "set cd value[!]", (const void *)VAR_CD
},
2279 {"chapretry", "chapretries", SetVariable
, LOCAL_AUTH
| LOCAL_CX
,
2280 "CHAP retries", "set chapretry value [attempts]",
2281 (const void *)VAR_CHAPRETRY
},
2282 {"choked", NULL
, SetVariable
, LOCAL_AUTH
,
2283 "choked timeout", "set choked [secs]", (const void *)VAR_CHOKED
},
2284 {"ctsrts", "crtscts", SetVariable
, LOCAL_AUTH
| LOCAL_CX
,
2285 "Use hardware flow control", "set ctsrts [on|off]",
2286 (const char *)VAR_CRTSCTS
},
2287 {"deflate", NULL
, SetVariable
, LOCAL_AUTH
| LOCAL_CX_OPT
,
2288 "deflate window sizes", "set deflate out-winsize in-winsize",
2289 (const void *) VAR_WINSIZE
},
2291 {"mppe", NULL
, SetVariable
, LOCAL_AUTH
| LOCAL_CX_OPT
,
2292 "MPPE key size and state", "set mppe [40|56|128|* [stateful|stateless|*]]",
2293 (const void *) VAR_MPPE
},
2295 {"device", "line", SetVariable
, LOCAL_AUTH
| LOCAL_CX
,
2296 "physical device name", "set device|line device-name[,device-name]",
2297 (const void *) VAR_DEVICE
},
2298 {"dial", NULL
, SetVariable
, LOCAL_AUTH
| LOCAL_CX
,
2299 "dialing script", "set dial chat-script", (const void *) VAR_DIAL
},
2300 {"dns", NULL
, SetVariable
, LOCAL_AUTH
, "Domain Name Server",
2301 "set dns pri-addr [sec-addr]", (const void *)VAR_DNS
},
2302 {"enddisc", NULL
, mp_SetEnddisc
, LOCAL_AUTH
,
2303 "Endpoint Discriminator", "set enddisc [IP|magic|label|psn value]"},
2304 {"escape", NULL
, SetEscape
, LOCAL_AUTH
| LOCAL_CX
,
2305 "escape characters", "set escape hex-digit ..."},
2306 {"filter", NULL
, filter_Set
, LOCAL_AUTH
,
2307 "packet filters", "set filter alive|dial|in|out rule-no permit|deny "
2308 "[src_addr[/width]] [dst_addr[/width]] [proto "
2309 "[src [lt|eq|gt port]] [dst [lt|eq|gt port]] [estab] [syn] [finrst]]"},
2310 {"hangup", NULL
, SetVariable
, LOCAL_AUTH
| LOCAL_CX
,
2311 "hangup script", "set hangup chat-script", (const void *) VAR_HANGUP
},
2312 {"ifaddr", NULL
, SetInterfaceAddr
, LOCAL_AUTH
, "destination address",
2313 "set ifaddr [src-addr [dst-addr [netmask [trg-addr]]]]"},
2314 {"ifqueue", NULL
, SetVariable
, LOCAL_AUTH
, "interface queue",
2315 "set ifqueue packets", (const void *)VAR_IFQUEUE
},
2316 {"ipcpretry", "ipcpretries", SetVariable
, LOCAL_AUTH
, "IPCP retries",
2317 "set ipcpretry value [attempts]", (const void *)VAR_IPCPRETRY
},
2318 {"ipv6cpretry", "ipv6cpretries", SetVariable
, LOCAL_AUTH
, "IPV6CP retries",
2319 "set ipv6cpretry value [attempts]", (const void *)VAR_IPV6CPRETRY
},
2320 {"lcpretry", "lcpretries", SetVariable
, LOCAL_AUTH
| LOCAL_CX
, "LCP retries",
2321 "set lcpretry value [attempts]", (const void *)VAR_LCPRETRY
},
2322 {"log", NULL
, log_SetLevel
, LOCAL_AUTH
, "log level",
2323 "set log [local] [+|-]all|async|cbcp|ccp|chat|command|connect|debug|dns|hdlc|"
2324 "id0|ipcp|lcp|lqm|phase|physical|sync|tcp/ip|timer|tun..."},
2325 {"login", NULL
, SetVariable
, LOCAL_AUTH
| LOCAL_CX
,
2326 "login script", "set login chat-script", (const void *) VAR_LOGIN
},
2327 {"logout", NULL
, SetVariable
, LOCAL_AUTH
| LOCAL_CX
,
2328 "logout script", "set logout chat-script", (const void *) VAR_LOGOUT
},
2329 {"lqrperiod", NULL
, SetVariable
, LOCAL_AUTH
| LOCAL_CX_OPT
,
2330 "LQR period", "set lqrperiod value", (const void *)VAR_LQRPERIOD
},
2331 {"mode", NULL
, SetVariable
, LOCAL_AUTH
| LOCAL_CX
, "mode value",
2332 "set mode interactive|auto|ddial|background", (const void *)VAR_MODE
},
2333 {"mrru", NULL
, SetVariable
, LOCAL_AUTH
, "MRRU value",
2334 "set mrru value", (const void *)VAR_MRRU
},
2335 {"mru", NULL
, SetVariable
, LOCAL_AUTH
| LOCAL_CX
,
2336 "MRU value", "set mru [max[imum]] [value]", (const void *)VAR_MRU
},
2337 {"mtu", NULL
, SetVariable
, LOCAL_AUTH
| LOCAL_CX
,
2338 "interface MTU value", "set mtu [max[imum]] [value]", (const void *)VAR_MTU
},
2339 {"nbns", NULL
, SetVariable
, LOCAL_AUTH
, "NetBIOS Name Server",
2340 "set nbns pri-addr [sec-addr]", (const void *)VAR_NBNS
},
2341 {"openmode", NULL
, SetVariable
, LOCAL_AUTH
| LOCAL_CX
, "open mode",
2342 "set openmode active|passive [secs]", (const void *)VAR_OPENMODE
},
2343 {"papretry", "papretries", SetVariable
, LOCAL_AUTH
| LOCAL_CX
, "PAP retries",
2344 "set papretry value [attempts]", (const void *)VAR_PAPRETRY
},
2345 {"parity", NULL
, SetVariable
, LOCAL_AUTH
| LOCAL_CX
, "serial parity",
2346 "set parity [odd|even|none]", (const void *)VAR_PARITY
},
2347 {"phone", NULL
, SetVariable
, LOCAL_AUTH
| LOCAL_CX
, "telephone number(s)",
2348 "set phone phone1[:phone2[...]]", (const void *)VAR_PHONE
},
2349 {"proctitle", "title", SetProcTitle
, LOCAL_AUTH
,
2350 "Process title", "set proctitle [value]"},
2352 {"radius", NULL
, SetVariable
, LOCAL_AUTH
,
2353 "RADIUS Config", "set radius cfgfile", (const void *)VAR_RADIUS
},
2355 {"reconnect", NULL
, datalink_SetReconnect
, LOCAL_AUTH
| LOCAL_CX
,
2356 "Reconnect timeout", "set reconnect value ntries"},
2357 {"recvpipe", NULL
, SetVariable
, LOCAL_AUTH
,
2358 "RECVPIPE value", "set recvpipe value", (const void *)VAR_RECVPIPE
},
2359 {"redial", NULL
, datalink_SetRedial
, LOCAL_AUTH
| LOCAL_CX
,
2360 "Redial timeout", "set redial secs[+inc[-incmax]][.next] [attempts]"},
2361 {"sendpipe", NULL
, SetVariable
, LOCAL_AUTH
,
2362 "SENDPIPE value", "set sendpipe value", (const void *)VAR_SENDPIPE
},
2363 {"server", "socket", SetServer
, LOCAL_AUTH
, "diagnostic port",
2364 "set server|socket TcpPort|LocalName|none|open|closed [password [mask]]"},
2365 {"speed", NULL
, SetModemSpeed
, LOCAL_AUTH
| LOCAL_CX
,
2366 "physical speed", "set speed value|sync"},
2367 {"stopped", NULL
, SetStoppedTimeout
, LOCAL_AUTH
| LOCAL_CX
,
2368 "STOPPED timeouts", "set stopped [LCPseconds [CCPseconds]]"},
2369 {"timeout", NULL
, SetVariable
, LOCAL_AUTH
, "Idle timeout",
2370 "set timeout idletime", (const void *)VAR_IDLETIMEOUT
},
2371 {"urgent", NULL
, SetVariable
, LOCAL_AUTH
, "urgent ports",
2372 "set urgent [tcp|udp] [+|-]port...", (const void *)VAR_URGENTPORTS
},
2373 {"vj", NULL
, ipcp_vjset
, LOCAL_AUTH
,
2374 "vj values", "set vj slots|slotcomp [value]"},
2375 {"help", "?", HelpCommand
, LOCAL_AUTH
| LOCAL_NO_AUTH
,
2376 "Display this message", "set help|? [command]", SetCommands
},
2381 SetCommand(struct cmdargs
const *arg
)
2383 if (arg
->argc
> arg
->argn
)
2384 FindExec(arg
->bundle
, SetCommands
, arg
->argc
, arg
->argn
, arg
->argv
,
2385 arg
->prompt
, arg
->cx
);
2386 else if (arg
->prompt
)
2387 prompt_Printf(arg
->prompt
, "Use `set ?' to get a list or `set ? <var>' for"
2390 log_Printf(LogWARN
, "set command must have arguments\n");
2396 AddCommand(struct cmdargs
const *arg
)
2399 struct ncprange dest
;
2400 struct in_addr host
;
2402 struct in6_addr host6
;
2404 int dest_default
, gw_arg
, addrs
;
2406 if (arg
->argc
!= arg
->argn
+3 && arg
->argc
!= arg
->argn
+2)
2411 if (arg
->argc
== arg
->argn
+ 2) {
2412 if (!strcasecmp(arg
->argv
[arg
->argn
], "default"))
2415 if (!ncprange_aton(&dest
, &arg
->bundle
->ncp
, arg
->argv
[arg
->argn
]))
2417 if (!strncasecmp(arg
->argv
[arg
->argn
], "MYADDR", 6))
2418 addrs
= ROUTE_DSTMYADDR
;
2419 else if (!strncasecmp(arg
->argv
[arg
->argn
], "MYADDR6", 7))
2420 addrs
= ROUTE_DSTMYADDR6
;
2421 else if (!strncasecmp(arg
->argv
[arg
->argn
], "HISADDR", 7))
2422 addrs
= ROUTE_DSTHISADDR
;
2423 else if (!strncasecmp(arg
->argv
[arg
->argn
], "HISADDR6", 8))
2424 addrs
= ROUTE_DSTHISADDR6
;
2425 else if (!strncasecmp(arg
->argv
[arg
->argn
], "DNS0", 4))
2426 addrs
= ROUTE_DSTDNS0
;
2427 else if (!strncasecmp(arg
->argv
[arg
->argn
], "DNS1", 4))
2428 addrs
= ROUTE_DSTDNS1
;
2432 if (strcasecmp(arg
->argv
[arg
->argn
], "MYADDR") == 0) {
2433 addrs
= ROUTE_DSTMYADDR
;
2434 host
= arg
->bundle
->ncp
.ipcp
.my_ip
;
2435 } else if (strcasecmp(arg
->argv
[arg
->argn
], "HISADDR") == 0) {
2436 addrs
= ROUTE_DSTHISADDR
;
2437 host
= arg
->bundle
->ncp
.ipcp
.peer_ip
;
2438 } else if (strcasecmp(arg
->argv
[arg
->argn
], "DNS0") == 0) {
2439 addrs
= ROUTE_DSTDNS0
;
2440 host
= arg
->bundle
->ncp
.ipcp
.ns
.dns
[0];
2441 } else if (strcasecmp(arg
->argv
[arg
->argn
], "DNS1") == 0) {
2442 addrs
= ROUTE_DSTDNS1
;
2443 host
= arg
->bundle
->ncp
.ipcp
.ns
.dns
[1];
2445 host
= GetIpAddr(arg
->argv
[arg
->argn
]);
2446 if (host
.s_addr
== INADDR_NONE
) {
2447 log_Printf(LogWARN
, "%s: Invalid destination address\n",
2448 arg
->argv
[arg
->argn
]);
2452 ncprange_setip4(&dest
, host
, GetIpAddr(arg
->argv
[arg
->argn
+ 1]));
2456 if (strcasecmp(arg
->argv
[arg
->argn
+ gw_arg
], "HISADDR") == 0) {
2457 ncpaddr_setip4(&gw
, arg
->bundle
->ncp
.ipcp
.peer_ip
);
2458 addrs
|= ROUTE_GWHISADDR
;
2460 } else if (strcasecmp(arg
->argv
[arg
->argn
+ gw_arg
], "HISADDR6") == 0) {
2461 if (!ncpaddr_getip6(&arg
->bundle
->ncp
.ipv6cp
.hisaddr
, &host6
))
2462 memset(&host6
, '\0', sizeof host6
);
2463 ncpaddr_setip6(&gw
, &host6
);
2464 addrs
|= ROUTE_GWHISADDR6
;
2467 if (!ncpaddr_aton(&gw
, &arg
->bundle
->ncp
, arg
->argv
[arg
->argn
+ gw_arg
])) {
2468 log_Printf(LogWARN
, "%s: Invalid gateway address\n",
2469 arg
->argv
[arg
->argn
+ gw_arg
]);
2475 ncprange_setdefault(&dest
, ncpaddr_family(&gw
));
2477 if (rt_Set(arg
->bundle
, RTM_ADD
, &dest
, &gw
, arg
->cmd
->args
? 1 : 0,
2478 ((addrs
& ROUTE_GWHISADDR
) || (addrs
& ROUTE_GWHISADDR6
)) ? 1 : 0)
2479 && addrs
!= ROUTE_STATIC
)
2480 route_Add(&arg
->bundle
->ncp
.route
, addrs
, &dest
, &gw
);
2486 DeleteCommand(struct cmdargs
const *arg
)
2488 struct ncprange dest
;
2491 if (arg
->argc
== arg
->argn
+1) {
2492 if(strcasecmp(arg
->argv
[arg
->argn
], "all") == 0) {
2493 route_IfDelete(arg
->bundle
, 0);
2494 route_DeleteAll(&arg
->bundle
->ncp
.route
);
2497 if (strcasecmp(arg
->argv
[arg
->argn
], "MYADDR") == 0) {
2498 ncprange_setip4host(&dest
, arg
->bundle
->ncp
.ipcp
.my_ip
);
2499 addrs
= ROUTE_DSTMYADDR
;
2501 } else if (strcasecmp(arg
->argv
[arg
->argn
], "MYADDR6") == 0) {
2502 ncprange_sethost(&dest
, &arg
->bundle
->ncp
.ipv6cp
.myaddr
);
2503 addrs
= ROUTE_DSTMYADDR6
;
2505 } else if (strcasecmp(arg
->argv
[arg
->argn
], "HISADDR") == 0) {
2506 ncprange_setip4host(&dest
, arg
->bundle
->ncp
.ipcp
.peer_ip
);
2507 addrs
= ROUTE_DSTHISADDR
;
2509 } else if (strcasecmp(arg
->argv
[arg
->argn
], "HISADDR6") == 0) {
2510 ncprange_sethost(&dest
, &arg
->bundle
->ncp
.ipv6cp
.hisaddr
);
2511 addrs
= ROUTE_DSTHISADDR6
;
2513 } else if (strcasecmp(arg
->argv
[arg
->argn
], "DNS0") == 0) {
2514 ncprange_setip4host(&dest
, arg
->bundle
->ncp
.ipcp
.ns
.dns
[0]);
2515 addrs
= ROUTE_DSTDNS0
;
2516 } else if (strcasecmp(arg
->argv
[arg
->argn
], "DNS1") == 0) {
2517 ncprange_setip4host(&dest
, arg
->bundle
->ncp
.ipcp
.ns
.dns
[1]);
2518 addrs
= ROUTE_DSTDNS1
;
2520 ncprange_aton(&dest
, &arg
->bundle
->ncp
, arg
->argv
[arg
->argn
]);
2521 addrs
= ROUTE_STATIC
;
2523 rt_Set(arg
->bundle
, RTM_DELETE
, &dest
, NULL
, arg
->cmd
->args
? 1 : 0, 0);
2524 route_Delete(&arg
->bundle
->ncp
.route
, addrs
, &dest
);
2534 NatEnable(struct cmdargs
const *arg
)
2536 if (arg
->argc
== arg
->argn
+1) {
2537 if (strcasecmp(arg
->argv
[arg
->argn
], "yes") == 0) {
2538 if (!arg
->bundle
->NatEnabled
) {
2539 if (arg
->bundle
->ncp
.ipcp
.fsm
.state
== ST_OPENED
)
2540 PacketAliasSetAddress(arg
->bundle
->ncp
.ipcp
.my_ip
);
2541 arg
->bundle
->NatEnabled
= 1;
2544 } else if (strcasecmp(arg
->argv
[arg
->argn
], "no") == 0) {
2545 arg
->bundle
->NatEnabled
= 0;
2546 arg
->bundle
->cfg
.opt
&= ~OPT_IFACEALIAS
;
2547 /* Don't iface_Clear() - there may be manually configured addresses */
2557 NatOption(struct cmdargs
const *arg
)
2559 long param
= (long)arg
->cmd
->args
;
2561 if (arg
->argc
== arg
->argn
+1) {
2562 if (strcasecmp(arg
->argv
[arg
->argn
], "yes") == 0) {
2563 if (arg
->bundle
->NatEnabled
) {
2564 PacketAliasSetMode(param
, param
);
2567 log_Printf(LogWARN
, "nat not enabled\n");
2568 } else if (strcmp(arg
->argv
[arg
->argn
], "no") == 0) {
2569 if (arg
->bundle
->NatEnabled
) {
2570 PacketAliasSetMode(0, param
);
2573 log_Printf(LogWARN
, "nat not enabled\n");
2578 #endif /* #ifndef NONAT */
2581 LinkCommand(struct cmdargs
const *arg
)
2583 if (arg
->argc
> arg
->argn
+1) {
2584 char namelist
[LINE_LEN
];
2585 struct datalink
*cx
;
2589 if (!strcmp(arg
->argv
[arg
->argn
], "*")) {
2590 struct datalink
*dl
;
2592 cx
= arg
->bundle
->links
;
2594 /* Watch it, the command could be a ``remove'' */
2596 FindExec(arg
->bundle
, Commands
, arg
->argc
, arg
->argn
+1, arg
->argv
,
2598 for (cx
= arg
->bundle
->links
; cx
; cx
= cx
->next
)
2600 break; /* Pointer's still valid ! */
2603 strncpy(namelist
, arg
->argv
[arg
->argn
], sizeof namelist
- 1);
2604 namelist
[sizeof namelist
- 1] = '\0';
2605 for(name
= strtok(namelist
, ", "); name
; name
= strtok(NULL
,", "))
2606 if (!bundle2datalink(arg
->bundle
, name
)) {
2607 log_Printf(LogWARN
, "link: %s: Invalid link name\n", name
);
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 cx
= bundle2datalink(arg
->bundle
, name
);
2616 FindExec(arg
->bundle
, Commands
, arg
->argc
, arg
->argn
+1, arg
->argv
,
2619 log_Printf(LogWARN
, "link: %s: Invalidated link name !\n", name
);
2627 log_Printf(LogWARN
, "usage: %s\n", arg
->cmd
->syntax
);
2632 command_ChooseLink(struct cmdargs
const *arg
)
2635 return &arg
->cx
->physical
->link
;
2636 else if (!arg
->bundle
->ncp
.mp
.cfg
.mrru
) {
2637 struct datalink
*dl
= bundle2datalink(arg
->bundle
, NULL
);
2639 return &dl
->physical
->link
;
2641 return &arg
->bundle
->ncp
.mp
.link
;
2645 ident_cmd(const char *cmd
, unsigned *keep
, unsigned *add
)
2654 *add
= NEG_ACCEPTED
;
2668 *keep
= NEG_HISMASK
;
2678 *keep
= NEG_HISMASK
;
2689 OptSet(struct cmdargs
const *arg
)
2691 int bit
= (int)(long)arg
->cmd
->args
;
2692 unsigned keep
; /* Keep these bits */
2693 unsigned add
; /* Add these bits */
2695 if (ident_cmd(arg
->argv
[arg
->argn
- 2], &keep
, &add
) == NULL
)
2699 if (add
== NEG_ENABLED
&& bit
== OPT_IPV6CP
&& !probe
.ipv6_available
) {
2700 log_Printf(LogWARN
, "IPv6 is not available on this machine\n");
2706 arg
->bundle
->cfg
.opt
|= bit
;
2708 arg
->bundle
->cfg
.opt
&= ~bit
;
2714 IfaceAliasOptSet(struct cmdargs
const *arg
)
2716 unsigned save
= arg
->bundle
->cfg
.opt
;
2717 int result
= OptSet(arg
);
2720 if (Enabled(arg
->bundle
, OPT_IFACEALIAS
) && !arg
->bundle
->NatEnabled
) {
2721 arg
->bundle
->cfg
.opt
= save
;
2722 log_Printf(LogWARN
, "Cannot enable iface-alias without NAT\n");
2730 NegotiateSet(struct cmdargs
const *arg
)
2732 long param
= (long)arg
->cmd
->args
;
2733 struct link
*l
= command_ChooseLink(arg
); /* LOCAL_CX_OPT uses this */
2734 struct datalink
*cx
= arg
->cx
; /* LOCAL_CX uses this */
2736 unsigned keep
; /* Keep these bits */
2737 unsigned add
; /* Add these bits */
2739 if ((cmd
= ident_cmd(arg
->argv
[arg
->argn
-2], &keep
, &add
)) == NULL
)
2742 if ((arg
->cmd
->lauth
& LOCAL_CX
) && !cx
) {
2743 log_Printf(LogWARN
, "%s %s: No context (use the `link' command)\n",
2744 cmd
, arg
->cmd
->name
);
2746 } else if (cx
&& !(arg
->cmd
->lauth
& (LOCAL_CX
|LOCAL_CX_OPT
))) {
2747 log_Printf(LogWARN
, "%s %s: Redundant context (%s) ignored\n",
2748 cmd
, arg
->cmd
->name
, cx
->name
);
2754 cx
->physical
->link
.lcp
.cfg
.acfcomp
&= keep
;
2755 cx
->physical
->link
.lcp
.cfg
.acfcomp
|= add
;
2758 cx
->physical
->link
.lcp
.cfg
.chap05
&= keep
;
2759 cx
->physical
->link
.lcp
.cfg
.chap05
|= add
;
2763 cx
->physical
->link
.lcp
.cfg
.chap80nt
&= keep
;
2764 cx
->physical
->link
.lcp
.cfg
.chap80nt
|= add
;
2767 cx
->physical
->link
.lcp
.cfg
.chap80lm
&= keep
;
2768 cx
->physical
->link
.lcp
.cfg
.chap80lm
|= add
;
2771 cx
->physical
->link
.lcp
.cfg
.chap81
&= keep
;
2772 cx
->physical
->link
.lcp
.cfg
.chap81
|= add
;
2775 l
->ccp
.cfg
.neg
[CCP_NEG_MPPE
] &= keep
;
2776 l
->ccp
.cfg
.neg
[CCP_NEG_MPPE
] |= add
;
2780 l
->ccp
.cfg
.neg
[CCP_NEG_DEFLATE
] &= keep
;
2781 l
->ccp
.cfg
.neg
[CCP_NEG_DEFLATE
] |= add
;
2784 arg
->bundle
->ncp
.ipcp
.cfg
.ns
.dns_neg
&= keep
;
2785 arg
->bundle
->ncp
.ipcp
.cfg
.ns
.dns_neg
|= add
;
2788 arg
->bundle
->ncp
.mp
.cfg
.negenddisc
&= keep
;
2789 arg
->bundle
->ncp
.mp
.cfg
.negenddisc
|= add
;
2792 cx
->physical
->link
.lcp
.cfg
.lqr
&= keep
;
2793 cx
->physical
->link
.lcp
.cfg
.lqr
|= add
;
2796 cx
->physical
->link
.lcp
.cfg
.pap
&= keep
;
2797 cx
->physical
->link
.lcp
.cfg
.pap
|= add
;
2799 case NEG_PPPDDEFLATE
:
2800 l
->ccp
.cfg
.neg
[CCP_NEG_DEFLATE24
] &= keep
;
2801 l
->ccp
.cfg
.neg
[CCP_NEG_DEFLATE24
] |= add
;
2804 l
->ccp
.cfg
.neg
[CCP_NEG_PRED1
] &= keep
;
2805 l
->ccp
.cfg
.neg
[CCP_NEG_PRED1
] |= add
;
2808 cx
->physical
->link
.lcp
.cfg
.protocomp
&= keep
;
2809 cx
->physical
->link
.lcp
.cfg
.protocomp
|= add
;
2812 switch (bundle_Phase(arg
->bundle
)) {
2815 case PHASE_ESTABLISH
:
2816 /* Make sure none of our links are DATALINK_LCP or greater */
2817 if (bundle_HighestState(arg
->bundle
) >= DATALINK_LCP
) {
2818 log_Printf(LogWARN
, "shortseq: Only changeable before"
2819 " LCP negotiations\n");
2824 log_Printf(LogWARN
, "shortseq: Only changeable at phase"
2825 " DEAD/ESTABLISH\n");
2828 arg
->bundle
->ncp
.mp
.cfg
.shortseq
&= keep
;
2829 arg
->bundle
->ncp
.mp
.cfg
.shortseq
|= add
;
2832 arg
->bundle
->ncp
.ipcp
.cfg
.vj
.neg
&= keep
;
2833 arg
->bundle
->ncp
.ipcp
.cfg
.vj
.neg
|= add
;
2840 static struct cmdtab
const NegotiateCommands
[] = {
2841 {"filter-decapsulation", NULL
, OptSet
, LOCAL_AUTH
,
2842 "filter on PPPoUDP payloads", "disable|enable",
2843 (const void *)OPT_FILTERDECAP
},
2844 {"idcheck", NULL
, OptSet
, LOCAL_AUTH
, "Check FSM reply ids",
2845 "disable|enable", (const void *)OPT_IDCHECK
},
2846 {"iface-alias", NULL
, IfaceAliasOptSet
, LOCAL_AUTH
,
2847 "retain interface addresses", "disable|enable",
2848 (const void *)OPT_IFACEALIAS
},
2850 {"ipcp", NULL
, OptSet
, LOCAL_AUTH
, "IP Network Control Protocol",
2851 "disable|enable", (const void *)OPT_IPCP
},
2852 {"ipv6cp", NULL
, OptSet
, LOCAL_AUTH
, "IPv6 Network Control Protocol",
2853 "disable|enable", (const void *)OPT_IPV6CP
},
2855 {"keep-session", NULL
, OptSet
, LOCAL_AUTH
, "Retain device session leader",
2856 "disable|enable", (const void *)OPT_KEEPSESSION
},
2857 {"loopback", NULL
, OptSet
, LOCAL_AUTH
, "Loop packets for local iface",
2858 "disable|enable", (const void *)OPT_LOOPBACK
},
2859 {"passwdauth", NULL
, OptSet
, LOCAL_AUTH
, "Use passwd file",
2860 "disable|enable", (const void *)OPT_PASSWDAUTH
},
2861 {"proxy", NULL
, OptSet
, LOCAL_AUTH
, "Create a proxy ARP entry",
2862 "disable|enable", (const void *)OPT_PROXY
},
2863 {"proxyall", NULL
, OptSet
, LOCAL_AUTH
, "Proxy ARP for all remote hosts",
2864 "disable|enable", (const void *)OPT_PROXYALL
},
2865 {"sroutes", NULL
, OptSet
, LOCAL_AUTH
, "Use sticky routes",
2866 "disable|enable", (const void *)OPT_SROUTES
},
2867 {"tcpmssfixup", "mssfixup", OptSet
, LOCAL_AUTH
, "Modify MSS options",
2868 "disable|enable", (const void *)OPT_TCPMSSFIXUP
},
2869 {"throughput", NULL
, OptSet
, LOCAL_AUTH
, "Rolling throughput",
2870 "disable|enable", (const void *)OPT_THROUGHPUT
},
2871 {"utmp", NULL
, OptSet
, LOCAL_AUTH
, "Log connections in utmp",
2872 "disable|enable", (const void *)OPT_UTMP
},
2875 #define OPT_MAX 13 /* accept/deny allowed below and not above */
2880 {"acfcomp", NULL
, NegotiateSet
, LOCAL_AUTH
| LOCAL_CX
,
2881 "Address & Control field compression", "accept|deny|disable|enable",
2882 (const void *)NEG_ACFCOMP
},
2883 {"chap", "chap05", NegotiateSet
, LOCAL_AUTH
| LOCAL_CX
,
2884 "Challenge Handshake Authentication Protocol", "accept|deny|disable|enable",
2885 (const void *)NEG_CHAP05
},
2887 {"mschap", "chap80nt", NegotiateSet
, LOCAL_AUTH
| LOCAL_CX
,
2888 "Microsoft (NT) CHAP", "accept|deny|disable|enable",
2889 (const void *)NEG_CHAP80
},
2890 {"LANMan", "chap80lm", NegotiateSet
, LOCAL_AUTH
| LOCAL_CX
,
2891 "Microsoft (NT) CHAP", "accept|deny|disable|enable",
2892 (const void *)NEG_CHAP80LM
},
2893 {"mschapv2", "chap81", NegotiateSet
, LOCAL_AUTH
| LOCAL_CX
,
2894 "Microsoft CHAP v2", "accept|deny|disable|enable",
2895 (const void *)NEG_CHAP81
},
2896 {"mppe", NULL
, NegotiateSet
, LOCAL_AUTH
| LOCAL_CX_OPT
,
2897 "MPPE encryption", "accept|deny|disable|enable",
2898 (const void *)NEG_MPPE
},
2900 {"deflate", NULL
, NegotiateSet
, LOCAL_AUTH
| LOCAL_CX_OPT
,
2901 "Deflate compression", "accept|deny|disable|enable",
2902 (const void *)NEG_DEFLATE
},
2903 {"deflate24", NULL
, NegotiateSet
, LOCAL_AUTH
| LOCAL_CX_OPT
,
2904 "Deflate (type 24) compression", "accept|deny|disable|enable",
2905 (const void *)NEG_PPPDDEFLATE
},
2906 {"dns", NULL
, NegotiateSet
, LOCAL_AUTH
,
2907 "DNS specification", "accept|deny|disable|enable", (const void *)NEG_DNS
},
2908 {"enddisc", NULL
, NegotiateSet
, LOCAL_AUTH
, "ENDDISC negotiation",
2909 "accept|deny|disable|enable", (const void *)NEG_ENDDISC
},
2910 {"lqr", NULL
, NegotiateSet
, LOCAL_AUTH
| LOCAL_CX
,
2911 "Link Quality Reports", "accept|deny|disable|enable",
2912 (const void *)NEG_LQR
},
2913 {"pap", NULL
, NegotiateSet
, LOCAL_AUTH
| LOCAL_CX
,
2914 "Password Authentication protocol", "accept|deny|disable|enable",
2915 (const void *)NEG_PAP
},
2916 {"pred1", "predictor1", NegotiateSet
, LOCAL_AUTH
| LOCAL_CX_OPT
,
2917 "Predictor 1 compression", "accept|deny|disable|enable",
2918 (const void *)NEG_PRED1
},
2919 {"protocomp", NULL
, NegotiateSet
, LOCAL_AUTH
| LOCAL_CX
,
2920 "Protocol field compression", "accept|deny|disable|enable",
2921 (const void *)NEG_PROTOCOMP
},
2922 {"shortseq", NULL
, NegotiateSet
, LOCAL_AUTH
,
2923 "MP Short Sequence Numbers", "accept|deny|disable|enable",
2924 (const void *)NEG_SHORTSEQ
},
2925 {"vjcomp", NULL
, NegotiateSet
, LOCAL_AUTH
,
2926 "Van Jacobson header compression", "accept|deny|disable|enable",
2927 (const void *)NEG_VJCOMP
},
2928 {"help", "?", HelpCommand
, LOCAL_AUTH
| LOCAL_NO_AUTH
,
2929 "Display this message", "accept|deny|disable|enable help|? [value]",
2935 NegotiateCommand(struct cmdargs
const *arg
)
2937 if (arg
->argc
> arg
->argn
) {
2938 char const *argv
[3];
2942 if ((argv
[0] = ident_cmd(arg
->argv
[arg
->argn
-1], &keep
, &add
)) == NULL
)
2946 for (n
= arg
->argn
; n
< arg
->argc
; n
++) {
2947 argv
[1] = arg
->argv
[n
];
2948 FindExec(arg
->bundle
, NegotiateCommands
+ (keep
== NEG_HISMASK
?
2949 0 : OPT_MAX
), 2, 1, argv
, arg
->prompt
, arg
->cx
);
2951 } else if (arg
->prompt
)
2952 prompt_Printf(arg
->prompt
, "Use `%s ?' to get a list.\n",
2953 arg
->argv
[arg
->argn
-1]);
2955 log_Printf(LogWARN
, "%s command must have arguments\n",
2956 arg
->argv
[arg
->argn
] );
2962 command_ShowNegval(unsigned val
)
2965 case 1: return "disabled & accepted";
2966 case 2: return "enabled & denied";
2967 case 3: return "enabled & accepted";
2969 return "disabled & denied";
2973 ClearCommand(struct cmdargs
const *arg
)
2975 struct pppThroughput
*t
;
2976 struct datalink
*cx
;
2979 if (arg
->argc
< arg
->argn
+ 1)
2982 if (strcasecmp(arg
->argv
[arg
->argn
], "physical") == 0) {
2985 cx
= bundle2datalink(arg
->bundle
, NULL
);
2987 log_Printf(LogWARN
, "A link must be specified for ``clear physical''\n");
2990 t
= &cx
->physical
->link
.stats
.total
;
2991 } else if (strcasecmp(arg
->argv
[arg
->argn
], "ipcp") == 0)
2992 t
= &arg
->bundle
->ncp
.ipcp
.throughput
;
2994 else if (strcasecmp(arg
->argv
[arg
->argn
], "ipv6cp") == 0)
2995 t
= &arg
->bundle
->ncp
.ipv6cp
.throughput
;
3000 if (arg
->argc
> arg
->argn
+ 1) {
3002 for (i
= arg
->argn
+ 1; i
< arg
->argc
; i
++)
3003 if (strcasecmp(arg
->argv
[i
], "overall") == 0)
3004 clear_type
|= THROUGHPUT_OVERALL
;
3005 else if (strcasecmp(arg
->argv
[i
], "current") == 0)
3006 clear_type
|= THROUGHPUT_CURRENT
;
3007 else if (strcasecmp(arg
->argv
[i
], "peak") == 0)
3008 clear_type
|= THROUGHPUT_PEAK
;
3012 clear_type
= THROUGHPUT_ALL
;
3014 throughput_clear(t
, clear_type
, arg
->prompt
);
3019 RunListCommand(struct cmdargs
const *arg
)
3021 const char *cmd
= arg
->argc
? arg
->argv
[arg
->argc
- 1] : "???";
3024 if (arg
->cmd
->args
== NatCommands
&&
3025 tolower(*arg
->argv
[arg
->argn
- 1]) == 'a') {
3027 prompt_Printf(arg
->prompt
, "The alias command is deprecated\n");
3029 log_Printf(LogWARN
, "The alias command is deprecated\n");
3033 if (arg
->argc
> arg
->argn
)
3034 FindExec(arg
->bundle
, arg
->cmd
->args
, arg
->argc
, arg
->argn
, arg
->argv
,
3035 arg
->prompt
, arg
->cx
);
3036 else if (arg
->prompt
)
3037 prompt_Printf(arg
->prompt
, "Use `%s help' to get a list or `%s help"
3038 " <option>' for syntax help.\n", cmd
, cmd
);
3040 log_Printf(LogWARN
, "%s command must have arguments\n", cmd
);
3046 IfaceAddCommand(struct cmdargs
const *arg
)
3048 struct ncpaddr peer
, addr
;
3049 struct ncprange ifa
;
3050 struct in_addr mask
;
3053 if (arg
->argc
== arg
->argn
+ 1) {
3054 if (!ncprange_aton(&ifa
, NULL
, arg
->argv
[arg
->argn
]))
3056 ncpaddr_init(&peer
);
3058 if (arg
->argc
== arg
->argn
+ 2) {
3059 if (!ncprange_aton(&ifa
, NULL
, arg
->argv
[arg
->argn
]))
3062 } else if (arg
->argc
== arg
->argn
+ 3) {
3063 if (!ncpaddr_aton(&addr
, NULL
, arg
->argv
[arg
->argn
]))
3065 if (ncpaddr_family(&addr
) != AF_INET
)
3067 ncprange_sethost(&ifa
, &addr
);
3068 if (!ncpaddr_aton(&addr
, NULL
, arg
->argv
[arg
->argn
+ 1]))
3070 if (!ncpaddr_getip4(&addr
, &mask
))
3072 if (!ncprange_setip4mask(&ifa
, mask
))
3078 if (!ncpaddr_aton(&peer
, NULL
, arg
->argv
[arg
->argn
+ n
]))
3081 if (ncprange_family(&ifa
) != ncpaddr_family(&peer
)) {
3082 log_Printf(LogWARN
, "IfaceAddCommand: src and dst address families"
3088 how
= IFACE_ADD_LAST
;
3090 how
|= IFACE_FORCE_ADD
;
3092 return !iface_Add(arg
->bundle
->iface
, &arg
->bundle
->ncp
, &ifa
, &peer
, how
);
3096 IfaceDeleteCommand(struct cmdargs
const *arg
)
3099 struct in_addr ifa4
;
3102 if (arg
->argc
!= arg
->argn
+ 1)
3105 if (!ncpaddr_aton(&ifa
, NULL
, arg
->argv
[arg
->argn
]))
3108 if (arg
->bundle
->ncp
.ipcp
.fsm
.state
== ST_OPENED
&&
3109 ncpaddr_getip4(&ifa
, &ifa4
) &&
3110 arg
->bundle
->ncp
.ipcp
.my_ip
.s_addr
== ifa4
.s_addr
) {
3111 log_Printf(LogWARN
, "%s: Cannot remove active interface address\n",
3112 ncpaddr_ntoa(&ifa
));
3116 ok
= iface_Delete(arg
->bundle
->iface
, &arg
->bundle
->ncp
, &ifa
);
3120 else if (arg
->prompt
)
3121 prompt_Printf(arg
->prompt
, "%s: No such interface address\n",
3122 ncpaddr_ntoa(&ifa
));
3124 log_Printf(LogWARN
, "%s: No such interface address\n",
3125 ncpaddr_ntoa(&ifa
));
3132 IfaceClearCommand(struct cmdargs
const *arg
)
3137 if (arg
->argc
== arg
->argn
+ 1) {
3138 if (strcasecmp(arg
->argv
[arg
->argn
], "inet") == 0)
3141 else if (strcasecmp(arg
->argv
[arg
->argn
], "inet6") == 0)
3146 } else if (arg
->argc
!= arg
->argn
)
3149 how
= arg
->bundle
->ncp
.ipcp
.fsm
.state
== ST_OPENED
||
3150 arg
->bundle
->phys_type
.all
& PHYS_AUTO
?
3151 IFACE_CLEAR_ALIASES
: IFACE_CLEAR_ALL
;
3152 iface_Clear(arg
->bundle
->iface
, &arg
->bundle
->ncp
, family
, how
);
3158 SetProcTitle(struct cmdargs
const *arg
)
3160 static char title
[LINE_LEN
];
3161 char *argv
[MAXARGS
];
3162 int argc
= arg
->argc
- arg
->argn
;
3164 if (arg
->argc
== arg
->argn
) {
3169 if (argc
>= sizeof argv
/ sizeof argv
[0]) {
3170 argc
= sizeof argv
/ sizeof argv
[0] - 1;
3171 log_Printf(LogWARN
, "Truncating proc title to %d args\n", argc
);
3173 command_Expand(argv
, argc
, arg
->argv
+ arg
->argn
, arg
->bundle
, 1, getpid());
3174 Concatinate(title
, sizeof title
, argc
, (const char *const *)argv
);
3176 command_Free(argc
, argv
);