Annotation of embedaddon/mpd/src/command.c, revision 1.1.1.4
1.1 misho 1:
2: /*
3: * command.c
4: *
5: * Written by Toshiharu OHNO <tony-o@iij.ad.jp>
6: * Copyright (c) 1993, Internet Initiative Japan, Inc. All rights reserved.
7: * See ``COPYRIGHT.iij''
8: *
9: * Rewritten by Archie Cobbs <archie@freebsd.org>
10: * Copyright (c) 1995-1999 Whistle Communications, Inc. All rights reserved.
11: * See ``COPYRIGHT.whistle''
12: */
13:
1.1.1.2 misho 14: #include "msg.h"
1.1 misho 15: #include "ppp.h"
16: #include "console.h"
17: #ifndef NOWEB
18: #include "web.h"
19: #endif
20: #include "radsrv.h"
21: #include "command.h"
22: #include "ccp.h"
23: #include "iface.h"
24: #include "radius.h"
25: #include "bund.h"
26: #include "link.h"
27: #include "lcp.h"
28: #ifdef USE_NG_NAT
29: #include "nat.h"
30: #endif
31: #include "ipcp.h"
32: #include "ip.h"
33: #include "ippool.h"
34: #include "devices.h"
35: #include "netgraph.h"
36: #include "ngfunc.h"
37: #ifdef CCP_MPPC
38: #include "ccp_mppc.h"
39: #endif
40: #include "util.h"
41: #ifdef USE_FETCH
42: #include <fetch.h>
43: #endif
1.1.1.2 misho 44: #ifdef USE_NG_NETFLOW
45: #include <netgraph/netflow/ng_netflow.h>
46: #endif
1.1 misho 47:
48: /*
49: * DEFINITIONS
50: */
51:
52: struct layer {
53: const char *name;
54: int (*opener)(Context ctx);
55: int (*closer)(Context ctx);
56: int (*admit)(Context ctx, CmdTab cmd);
57: const char *desc;
58: };
59: typedef struct layer *Layer;
60:
61: #define DEFAULT_OPEN_LAYER "link"
62:
63: /* Set menu options */
64: enum {
65: SET_ENABLE,
66: SET_DISABLE,
67: #ifdef USE_IPFW
68: SET_RULE,
69: SET_QUEUE,
70: SET_PIPE,
71: SET_TABLE,
72: #endif
73: #ifdef PHYSTYPE_PPTP
74: SET_PPTPTO,
75: SET_PPTPLIMIT,
76: #endif
77: #ifdef PHYSTYPE_L2TP
78: SET_L2TPTO,
79: SET_L2TPLIMIT,
80: #endif
81: SET_MAX_CHILDREN,
1.1.1.2 misho 82: SET_QTHRESHOLD,
1.1 misho 83: #ifdef USE_NG_BPF
84: SET_FILTER
85: #endif
86: };
87:
88: enum {
89: SHOW_IFACE,
90: SHOW_IP,
91: SHOW_USER,
92: SHOW_SESSION,
93: SHOW_MSESSION,
94: SHOW_BUNDLE,
95: SHOW_LINK,
96: SHOW_PEER
97: };
98:
99: /*
100: * INTERNAL FUNCTIONS
101: */
102:
103: /* Commands */
1.1.1.4 ! misho 104: static int ShowVersion(Context ctx, int ac, const char *const av[], const void *arg);
! 105: static int ShowLayers(Context ctx, int ac, const char *const av[], const void *arg);
! 106: static int ShowTypes(Context ctx, int ac, const char *const av[], const void *arg);
! 107: static int ShowSummary(Context ctx, int ac, const char *const av[], const void *arg);
! 108: static int ShowSessions(Context ctx, int ac, const char *const av[], const void *arg);
! 109: static int ShowCustomer(Context ctx, int ac, const char *const av[], const void *arg);
! 110: static int ShowEvents(Context ctx, int ac, const char *const av[], const void *arg);
! 111: static int ShowGlobal(Context ctx, int ac, const char *const av[], const void *arg);
! 112: static int OpenCommand(Context ctx, int ac, const char *const av[], const void *arg);
! 113: static int CloseCommand(Context ctx, int ac, const char *const av[], const void *arg);
! 114: static int LoadCommand(Context ctx, int ac, const char *const av[], const void *arg);
! 115: static int ExitCommand(Context ctx, int ac, const char *const av[], const void *arg);
! 116: static int QuitCommand(Context ctx, int ac, const char *const av[], const void *arg);
! 117: static int GlobalSetCommand(Context ctx, int ac, const char *const av[], const void *arg);
! 118: static int SetDebugCommand(Context ctx, int ac, const char *const av[], const void *arg);
1.1 misho 119:
120: /* Other stuff */
121: static Layer GetLayer(const char *name);
122:
123: /*
124: * INTERNAL VARIABLES
125: */
126:
1.1.1.4 ! misho 127: static const struct cmdtab GlobalSetCmds[] = {
1.1 misho 128: { "enable {opt ...}", "Enable option" ,
129: GlobalSetCommand, NULL, 2, (void *) SET_ENABLE },
130: { "disable {opt ...}", "Disable option" ,
131: GlobalSetCommand, NULL, 2, (void *) SET_DISABLE },
132: #ifdef USE_IPFW
133: { "startrule {num}", "Initial ipfw rule number" ,
134: GlobalSetCommand, NULL, 2, (void *) SET_RULE },
135: { "startqueue {num}", "Initial ipfw queue number" ,
136: GlobalSetCommand, NULL, 2, (void *) SET_QUEUE },
137: { "startpipe {num}", "Initial ipfw pipe number" ,
138: GlobalSetCommand, NULL, 2, (void *) SET_PIPE },
139: { "starttable {num}", "Initial ipfw table number" ,
140: GlobalSetCommand, NULL, 2, (void *) SET_TABLE },
141: #endif /* USE_IPFW */
142: #ifdef PHYSTYPE_L2TP
143: { "l2tptimeout {sec}", "L2TP tunnel unused timeout" ,
144: GlobalSetCommand, NULL, 2, (void *) SET_L2TPTO },
145: { "l2tplimit {num}", "Calls per L2TP tunnel limit" ,
146: GlobalSetCommand, NULL, 2, (void *) SET_L2TPLIMIT },
147: #endif
148: #ifdef PHYSTYPE_PPTP
149: { "pptptimeout {sec}", "PPTP tunnel unused timeout" ,
150: GlobalSetCommand, NULL, 2, (void *) SET_PPTPTO },
151: { "pptplimit {num}", "Calls per PPTP tunnel limit" ,
152: GlobalSetCommand, NULL, 2, (void *) SET_PPTPLIMIT },
153: #endif
154: { "max-children {num}", "Max number of children",
155: GlobalSetCommand, NULL, 2, (void *) SET_MAX_CHILDREN },
1.1.1.2 misho 156: { "qthreshold {min} {max}", "Message queue limit thresholds",
157: GlobalSetCommand, NULL, 2, (void *) SET_QTHRESHOLD },
1.1 misho 158: #ifdef USE_NG_BPF
159: { "filter {num} add|clear [\"{flt}\"]", "Global traffic filters management",
160: GlobalSetCommand, NULL, 2, (void *) SET_FILTER },
161: #endif
1.1.1.4 ! misho 162: { NULL, NULL, NULL, NULL, 0, NULL },
1.1 misho 163: };
164:
165: static const struct confinfo gGlobalConfList[] = {
166: #ifdef USE_WRAP
167: { 0, GLOBAL_CONF_TCPWRAPPER, "tcp-wrapper" },
168: #endif
169: { 0, GLOBAL_CONF_ONESHOT, "one-shot" },
1.1.1.3 misho 170: { 0, GLOBAL_CONF_AGENT_CID, "agent-cid" },
171: { 0, GLOBAL_CONF_SESS_TIME, "session-time" },
1.1 misho 172: { 0, 0, NULL },
173: };
174:
175: static const struct cmdtab CreateCommands[] = {
176: { "link [template|static] {name} {template|type}", "Create link/template",
177: LinkCreate, NULL, 2, NULL },
178: { "bundle [template|static] {name} {template}", "Create bundle/template",
179: BundCreate, NULL, 2, NULL },
1.1.1.4 ! misho 180: { NULL, NULL, NULL, NULL, 0, NULL },
1.1 misho 181: };
182:
183: static const struct cmdtab DestroyCommands[] = {
184: { "link [{name}]", "Destroy link/template",
185: LinkDestroy, NULL, 2, NULL },
186: { "bundle [{name}]", "Destroy bundle/template",
187: BundDestroy, NULL, 2, NULL },
1.1.1.4 ! misho 188: { NULL, NULL, NULL, NULL, 0, NULL },
1.1 misho 189: };
190:
191: static const struct cmdtab ShowSessCmds[] = {
192: { "iface {name}", "Filter by iface name",
1.1.1.2 misho 193: ShowSessions, NULL, 0, (void *) SHOW_IFACE },
1.1 misho 194: { "ip {ip}", "Filter by IP address",
1.1.1.2 misho 195: ShowSessions, NULL, 0, (void *) SHOW_IP },
1.1 misho 196: { "user {name}", "Filter by user name",
1.1.1.2 misho 197: ShowSessions, NULL, 0, (void *) SHOW_USER },
1.1 misho 198: { "session {ID}", "Filter by session ID",
1.1.1.2 misho 199: ShowSessions, NULL, 0, (void *) SHOW_SESSION },
1.1 misho 200: { "msession {ID}", "Filter by msession ID",
1.1.1.2 misho 201: ShowSessions, NULL, 0, (void *) SHOW_MSESSION },
1.1 misho 202: { "bundle {name}", "Filter by bundle name",
1.1.1.2 misho 203: ShowSessions, NULL, 0, (void *) SHOW_BUNDLE },
1.1 misho 204: { "link {name}", "Filter by link name",
1.1.1.2 misho 205: ShowSessions, NULL, 0, (void *) SHOW_LINK },
1.1 misho 206: { "peer {name}", "Filter by peer name",
1.1.1.2 misho 207: ShowSessions, NULL, 0, (void *) SHOW_PEER },
1.1.1.4 ! misho 208: { NULL, NULL, NULL, NULL, 0, NULL },
1.1 misho 209: };
210:
211: static const struct cmdtab ShowCommands[] = {
212: { "bundle [{name}]", "Bundle status",
213: BundStat, AdmitBund, 0, NULL },
214: { "customer", "Customer summary",
215: ShowCustomer, NULL, 0, NULL },
216: { "repeater [{name}]", "Repeater status",
217: RepStat, AdmitRep, 0, NULL },
218: { "ccp", "CCP status",
219: CcpStat, AdmitBund, 0, NULL },
220: #ifdef CCP_MPPC
221: { "mppc", "MPPC status",
222: MppcStat, AdmitBund, 0, NULL },
223: #endif
224: { "ecp", "ECP status",
225: EcpStat, AdmitBund, 0, NULL },
226: { "eap", "EAP status",
227: EapStat, AdmitLink, 0, NULL },
228: { "events", "Current events",
229: ShowEvents, NULL, 0, NULL },
230: { "ipcp", "IPCP status",
231: IpcpStat, AdmitBund, 0, NULL },
232: { "ipv6cp", "IPV6CP status",
233: Ipv6cpStat, AdmitBund, 0, NULL },
234: { "ippool", "IP pool status",
235: IPPoolStat, NULL, 0, NULL },
236: { "iface", "Interface status",
237: IfaceStat, AdmitBund, 0, NULL },
238: { "routes", "IP routing table",
239: IpShowRoutes, NULL, 0, NULL },
240: { "layers", "Layers to open/close",
241: ShowLayers, NULL, 0, NULL },
242: { "device", "Physical device status",
243: PhysStat, AdmitLink, 0, NULL },
244: #ifdef PHYSTYPE_PPTP
245: { "pptp", "PPTP tunnels status",
246: PptpsStat, NULL, 0, NULL },
247: #endif
248: #ifdef PHYSTYPE_L2TP
249: { "l2tp", "L2TP tunnels status",
250: L2tpsStat, NULL, 0, NULL },
251: #endif
252: { "link", "Link status",
253: LinkStat, AdmitLink, 0, NULL },
254: { "auth", "Auth status",
255: AuthStat, AdmitLink, 0, NULL },
256: { "radius", "RADIUS status",
257: RadStat, AdmitLink, 0, NULL },
258: #ifdef RAD_COA_REQUEST
259: { "radsrv", "RADIUS server status",
260: RadsrvStat, NULL, 0, NULL },
261: #endif
262: { "lcp", "LCP status",
263: LcpStat, AdmitLink, 0, NULL },
264: #ifdef USE_NG_NAT
265: { "nat", "NAT status",
266: NatStat, AdmitBund, 0, NULL },
267: #endif
268: { "mem", "Memory map",
269: MemStat, NULL, 0, NULL },
270: { "console", "Console status",
271: ConsoleStat, NULL, 0, NULL },
272: #ifndef NOWEB
273: { "web", "Web status",
274: WebStat, NULL, 0, NULL },
275: #endif
276: { "user", "Console users" ,
277: UserStat, NULL, 0, NULL },
278: { "global", "Global settings",
279: ShowGlobal, NULL, 0, NULL },
280: { "types", "Supported device types",
281: ShowTypes, NULL, 0, NULL },
282: { "version", "Version string",
283: ShowVersion, NULL, 0, NULL },
284: { "sessions [ {param} {value} ]", "Active sessions",
1.1.1.4 ! misho 285: CMD_SUBMENU, NULL, 0, ShowSessCmds},
1.1 misho 286: { "summary", "Daemon status summary",
287: ShowSummary, NULL, 0, NULL },
1.1.1.2 misho 288: #ifdef USE_NG_NETFLOW
289: { "netflow", "Netflow settings",
290: ShowNetflow, NULL, 0, NULL },
291: #endif
1.1.1.4 ! misho 292: { NULL, NULL, NULL, NULL, 0, NULL },
1.1 misho 293: };
294:
1.1.1.2 misho 295: static const struct cmdtab UnSetCommands[] = {
296: { "radius ...", "RADIUS specific stuff",
1.1.1.4 ! misho 297: CMD_SUBMENU, AdmitLink, 2, RadiusUnSetCmds },
1.1.1.2 misho 298: #ifdef NG_NAT_DESC_LENGTH
299: { "nat ...", "NAT specific stuff",
1.1.1.4 ! misho 300: CMD_SUBMENU, AdmitBund, 2, NatUnSetCmds },
1.1.1.2 misho 301: #endif
1.1.1.4 ! misho 302: { NULL, NULL, NULL, NULL, 0, NULL },
1.1.1.2 misho 303: };
304:
1.1 misho 305: static const struct cmdtab SetCommands[] = {
306: { "bundle ...", "Bundle specific stuff",
1.1.1.4 ! misho 307: CMD_SUBMENU, AdmitBund, 2, BundSetCmds },
1.1 misho 308: { "link ...", "Link specific stuff",
1.1.1.4 ! misho 309: CMD_SUBMENU, AdmitLink, 2, LinkSetCmds },
1.1 misho 310: { "iface ...", "Interface specific stuff",
1.1.1.4 ! misho 311: CMD_SUBMENU, AdmitBund, 2, IfaceSetCmds },
1.1 misho 312: { "ipcp ...", "IPCP specific stuff",
1.1.1.4 ! misho 313: CMD_SUBMENU, AdmitBund, 2, IpcpSetCmds },
1.1 misho 314: { "ipv6cp ...", "IPV6CP specific stuff",
1.1.1.4 ! misho 315: CMD_SUBMENU, AdmitBund, 2, Ipv6cpSetCmds },
1.1 misho 316: { "ippool ...", "IP pool specific stuff",
1.1.1.4 ! misho 317: CMD_SUBMENU, NULL, 2, IPPoolSetCmds },
1.1 misho 318: { "ccp ...", "CCP specific stuff",
1.1.1.4 ! misho 319: CMD_SUBMENU, AdmitBund, 2, CcpSetCmds },
1.1 misho 320: #ifdef CCP_MPPC
321: { "mppc ...", "MPPC specific stuff",
1.1.1.4 ! misho 322: CMD_SUBMENU, AdmitBund, 2, MppcSetCmds },
1.1 misho 323: #endif
324: { "ecp ...", "ECP specific stuff",
1.1.1.4 ! misho 325: CMD_SUBMENU, AdmitBund, 2, EcpSetCmds },
1.1 misho 326: { "eap ...", "EAP specific stuff",
1.1.1.4 ! misho 327: CMD_SUBMENU, AdmitLink, 2, EapSetCmds },
1.1 misho 328: { "auth ...", "Auth specific stuff",
1.1.1.4 ! misho 329: CMD_SUBMENU, AdmitLink, 2, AuthSetCmds },
1.1 misho 330: { "radius ...", "RADIUS specific stuff",
1.1.1.4 ! misho 331: CMD_SUBMENU, AdmitLink, 2, RadiusSetCmds },
1.1 misho 332: #ifdef RAD_COA_REQUEST
333: { "radsrv ...", "RADIUS server specific stuff",
1.1.1.4 ! misho 334: CMD_SUBMENU, NULL, 2, RadsrvSetCmds },
1.1 misho 335: #endif
336: { "console ...", "Console specific stuff",
1.1.1.4 ! misho 337: CMD_SUBMENU, NULL, 0, ConsoleSetCmds },
1.1 misho 338: #ifndef NOWEB
339: { "web ...", "Web specific stuff",
1.1.1.4 ! misho 340: CMD_SUBMENU, NULL, 2, WebSetCmds },
1.1 misho 341: #endif
342: { "user {name} {password} [{priv}]", "Add console user" ,
343: UserCommand, NULL, 2, NULL },
344: { "global ...", "Global settings",
1.1.1.4 ! misho 345: CMD_SUBMENU, NULL, 2, GlobalSetCmds },
1.1 misho 346: #ifdef USE_NG_NETFLOW
347: { "netflow ...", "NetFlow settings",
1.1.1.4 ! misho 348: CMD_SUBMENU, NULL, 2, NetflowSetCmds },
1.1 misho 349: #endif
350: #ifdef USE_NG_NAT
351: { "nat ...", "Nat settings",
1.1.1.4 ! misho 352: CMD_SUBMENU, NULL, 2, NatSetCmds },
1.1 misho 353: #endif
354: { "debug level", "Set netgraph debug level",
355: SetDebugCommand, NULL, 2, NULL },
356: #define _WANT_DEVICE_CMDS
357: #include "devices.h"
1.1.1.4 ! misho 358: { NULL, NULL, NULL, NULL, 0, NULL },
1.1 misho 359: };
360:
361: const struct cmdtab gCommands[] = {
1.1.1.3 misho 362: { "authname {name} [CI]", "Choose link by auth name",
1.1 misho 363: AuthnameCommand, NULL, 0, NULL },
364: { "bundle [{name}]", "Choose/list bundles",
365: BundCommand, NULL, 0, NULL },
366: { "close [{layer}]", "Close a layer",
367: CloseCommand, NULL, 1, NULL },
368: { "create ...", "Create new item",
1.1.1.4 ! misho 369: CMD_SUBMENU, NULL, 2, CreateCommands },
1.1 misho 370: { "destroy ...", "Destroy item",
1.1.1.4 ! misho 371: CMD_SUBMENU, NULL, 2, DestroyCommands },
1.1 misho 372: { "exit", "Exit console",
373: ExitCommand, NULL, 0, NULL },
374: { "iface {iface}", "Choose bundle by iface",
375: IfaceCommand, NULL, 0, NULL },
376: { "help ...", "Help on any command",
377: HelpCommand, NULL, 0, NULL },
378: { "link {name}", "Choose link",
379: LinkCommand, NULL, 0, NULL },
380: { "load [{file}] {label}", "Read from config file",
381: LoadCommand, NULL, 0, NULL },
382: { "log [+/-{opt} ...]", "Set/view log options",
383: LogCommand, NULL, 2, NULL },
384: { "msession {msesid}", "Ch. bundle by msession-id",
385: MSessionCommand, NULL, 0, NULL },
386: { "open [{layer}]", "Open a layer",
387: OpenCommand, NULL, 1, NULL },
1.1.1.3 misho 388: { "shutdown", "Shutdown program",
1.1 misho 389: QuitCommand, NULL, 2, NULL },
390: { "repeater [{name}]", "Choose/list repeaters",
391: RepCommand, NULL, 0, NULL },
392: { "session {sesid}", "Choose link by session-id",
393: SessionCommand, NULL, 0, NULL },
394: { "set ...", "Set parameters",
1.1.1.4 ! misho 395: CMD_SUBMENU, NULL, 0, SetCommands },
1.1.1.2 misho 396: { "unset ...", "Unset parameters",
1.1.1.4 ! misho 397: CMD_SUBMENU, NULL, 0, UnSetCommands },
1.1 misho 398: { "show ...", "Show status",
1.1.1.4 ! misho 399: CMD_SUBMENU, NULL, 0, ShowCommands },
! 400: { NULL, NULL, NULL, NULL, 0, NULL },
1.1 misho 401: };
402:
403:
404:
405: /*
406: * Layers
407: */
408:
1.1.1.4 ! misho 409: static struct layer gLayers[] = {
1.1 misho 410: { "iface",
411: IfaceOpenCmd,
412: IfaceCloseCmd,
413: AdmitBund,
414: "System interface"
415: },
416: { "ipcp",
417: IpcpOpenCmd,
418: IpcpCloseCmd,
419: AdmitBund,
420: "IPCP: IP control protocol"
421: },
422: { "ipv6cp",
423: Ipv6cpOpenCmd,
424: Ipv6cpCloseCmd,
425: AdmitBund,
426: "IPV6CP: IPv6 control protocol"
427: },
428: { "ccp",
429: CcpOpenCmd,
430: CcpCloseCmd,
431: AdmitBund,
432: "CCP: compression ctrl prot."
433: },
434: { "ecp",
435: EcpOpenCmd,
436: EcpCloseCmd,
437: AdmitBund,
438: "ECP: encryption ctrl prot."
439: },
440: { "bund",
441: BundOpenCmd,
442: BundCloseCmd,
443: AdmitBund,
444: "Multilink bundle"
445: },
446: { "link",
447: LinkOpenCmd,
448: LinkCloseCmd,
449: AdmitLink,
450: "Link layer"
451: },
452: { "device",
453: PhysOpenCmd,
454: PhysCloseCmd,
455: AdmitLink,
456: "Physical link layer"
457: },
458: };
459:
460: #define NUM_LAYERS (sizeof(gLayers) / sizeof(*gLayers))
461:
462: /*
463: * DoCommand()
464: *
465: * Executes command. Returns TRUE if user wants to quit.
466: */
467:
468: int
1.1.1.4 ! misho 469: DoCommand(Context ctx, int ac, const char *const av[], const char *file, int line)
1.1 misho 470: {
471: int rtn, i;
472: char filebuf[100], cmd[256];
473:
474: ctx->errmsg[0] = 0;
475: rtn = DoCommandTab(ctx, gCommands, ac, av);
476:
477: if (rtn) {
478: if (file) {
479: snprintf(filebuf,sizeof(filebuf),"%s:%d: ", file, line);
480: } else {
481: filebuf[0] = 0;
482: }
483: cmd[0] = 0;
484: for (i = 0; i < ac; i++) {
485: if (i)
486: strlcat(cmd, " ", sizeof(cmd));
487: strlcat(cmd, av[i], sizeof(cmd));
488: }
489: }
490:
491: switch (rtn) {
492: case 0:
493: break;
494:
495: default:
496: case CMD_ERR_USAGE:
497: case CMD_ERR_UNFIN:
498: HelpCommand(ctx, ac, av, filebuf);
499: Log2(LG_ERR, ("%sError in '%s'", filebuf, cmd));
500: break;
501: case CMD_ERR_UNDEF:
502: Printf("%sUnknown command: '%s'. Try \"help\".\r\n", filebuf, cmd);
503: Log2(LG_ERR, ("%sUnknown command: '%s'. Try \"help\".", filebuf, cmd));
504: break;
505: case CMD_ERR_AMBIG:
506: Printf("%sAmbiguous command: '%s'. Try \"help\".\r\n", filebuf, cmd);
507: Log2(LG_ERR, ("%sAmbiguous command: '%s'. Try \"help\".", filebuf, cmd));
508: break;
509: case CMD_ERR_RECUR:
510: Printf("%sRecursion detected for: '%s'!\r\n", filebuf, cmd);
511: Log2(LG_ERR, ("%sRecursion detected for: '%s'!", filebuf, cmd));
512: break;
513: case CMD_ERR_NOCTX:
514: Printf("%sIncorrect context for: '%s'\r\n", filebuf, cmd);
515: Log2(LG_ERR, ("%sIncorrect context for: '%s'", filebuf, cmd));
516: break;
517: case CMD_ERR_OTHER:
518: Printf("%sError in '%s': %s\r\n", filebuf, cmd, ctx->errmsg);
519: Log2(LG_ERR, ("%sError in '%s': %s", filebuf, cmd, ctx->errmsg));
520: break;
521: }
522:
523: return(rtn);
524: }
525:
526: /*
527: * DoCommandTab()
528: *
529: * Execute command from given command menu
530: */
531:
532: int
1.1.1.4 ! misho 533: DoCommandTab(Context ctx, CmdTab cmdlist, int ac, const char *const av[])
1.1 misho 534: {
535: CmdTab cmd;
536: int rtn = 0;
537:
538: /* Huh? */
539: if (ac <= 0)
540: return(CMD_ERR_UNFIN);
541:
542: /* Find command */
543: if ((rtn = FindCommand(ctx, cmdlist, av[0], &cmd)))
544: return(rtn);
545:
546: /* Check command admissibility */
547: if (cmd->admit && !(cmd->admit)(ctx, cmd))
548: return(CMD_ERR_NOCTX);
549:
550: /* Find command and either execute or recurse into a submenu */
551: if (cmd->func == CMD_SUBMENU) {
552: if ((intptr_t)cmd->arg == (intptr_t)ShowSessCmds) {
553: if (ac > 1)
554: rtn = DoCommandTab(ctx, (CmdTab) cmd->arg, ac - 1, av + 1);
555: else
556: rtn = ShowSessions(ctx, 0, NULL, NULL);
557: } else
558: rtn = DoCommandTab(ctx, (CmdTab) cmd->arg, ac - 1, av + 1);
559: } else
560: rtn = (cmd->func)(ctx, ac - 1, av + 1, cmd->arg);
561:
562: return(rtn);
563: }
564:
565: /*
566: * FindCommand()
567: */
568:
569: int
1.1.1.4 ! misho 570: FindCommand(Context ctx, CmdTab cmds, const char *str, CmdTab *cmdp)
1.1 misho 571: {
572: int nmatch;
573: int len = strlen(str);
574:
575: for (nmatch = 0; cmds->name; cmds++) {
576: if (cmds->name && !strncmp(str, cmds->name, len) &&
577: cmds->priv <= ctx->priv) {
578: *cmdp = cmds;
579: nmatch++;
580: }
581: }
582: switch (nmatch) {
583: case 0:
584: return(CMD_ERR_UNDEF);
585: case 1:
586: return(0);
587: default:
588: return(CMD_ERR_AMBIG);
589: }
590: }
591:
592: /********** COMMANDS **********/
593:
594:
595: /*
596: * GlobalSetCommand()
597: */
598:
599: static int
1.1.1.4 ! misho 600: GlobalSetCommand(Context ctx, int ac, const char *const av[], const void *arg)
1.1 misho 601: {
602: int val;
603:
604: if (ac == 0)
605: return(-1);
606:
607: switch ((intptr_t)arg) {
608: case SET_ENABLE:
609: EnableCommand(ac, av, &gGlobalConf.options, gGlobalConfList);
610: break;
611:
612: case SET_DISABLE:
613: DisableCommand(ac, av, &gGlobalConf.options, gGlobalConfList);
614: break;
615:
616: #ifdef USE_IPFW
617: case SET_RULE:
618: if (rule_pool)
619: Error("Rule pool is not empty. Impossible to set initial number");
620: else {
621: val = atoi(*av);
622: if (val <= 0 || val>=65535)
623: Error("Incorrect rule number");
624: else
625: rule_pool_start = val;
626: }
627: break;
628:
629: case SET_QUEUE:
630: if (queue_pool)
631: Error("Queue pool is not empty. Impossible to set initial number");
632: else {
633: val = atoi(*av);
634: if (val <= 0 || val>=65535)
635: Error("Incorrect queue number");
636: else
637: queue_pool_start = val;
638: }
639: break;
640:
641: case SET_PIPE:
642: if (pipe_pool)
643: Error("Pipe pool is not empty. Impossible to set initial number");
644: else {
645: val = atoi(*av);
646: if (val <= 0 || val>=65535)
647: Error("Incorrect pipe number");
648: else
649: pipe_pool_start = val;
650: }
651: break;
652:
653: case SET_TABLE:
654: if (table_pool)
655: Error("Table pool is not empty. Impossible to set initial number");
656: else {
657: val = atoi(*av);
658: if (val <= 0 || val>127) /* table 0 is usually possible but we deny it */
659: Error("Incorrect table number");
660: else
661: table_pool_start = val;
662: }
663: break;
664: #endif /* USE_IPFW */
665:
666: #ifdef PHYSTYPE_L2TP
667: case SET_L2TPTO:
668: val = atoi(*av);
669: if (val < 0 || val > 1000000)
670: Error("Incorrect L2TP timeout");
671: else
672: gL2TPto = val;
673: break;
674:
675: case SET_L2TPLIMIT:
676: val = atoi(*av);
677: if (val < 0 || val > 65536)
678: Error("Incorrect L2TP call limit");
679: else
1.1.1.4 ! misho 680: gL2TPtunlimit = (unsigned)val;
1.1 misho 681: break;
682: #endif
683:
684: #ifdef PHYSTYPE_PPTP
685: case SET_PPTPTO:
686: val = atoi(*av);
687: if (val < 0 || val > 1000000)
688: Error("Incorrect PPTP timeout");
689: else
690: gPPTPto = val;
691: break;
692:
693: case SET_PPTPLIMIT:
694: val = atoi(*av);
695: if (val <= 0 || val > 65536)
696: Error("Incorrect PPTP call limit");
697: else
1.1.1.4 ! misho 698: gPPTPtunlimit = (unsigned)val;
1.1 misho 699: break;
700: #endif
701:
702: case SET_MAX_CHILDREN:
703: val = atoi(*av);
704: if (val < 0 || val > 65536)
705: Error("Incorrect children links limit");
706: else
707: gMaxChildren = val;
708: break;
709:
710: #ifdef USE_NG_BPF
711: case SET_FILTER:
712: if (ac == 4 && strcasecmp(av[1], "add") == 0) {
713: struct acl **acls, *acls1;
714: int i;
715:
716: i = atol(av[0]);
717: if (i <= 0 || i > ACL_FILTERS)
718: Error("Wrong filter number\r\n");
719: acls = &(acl_filters[i - 1]);
720:
721: i = atol(av[2]);
722: if (i <= 0)
723: Error("Wrong acl number: %i\r\n", i);
724:
725: acls1 = Malloc(MB_AUTH, sizeof(struct acl) + strlen(av[3]));
726: acls1->number = i;
727: acls1->real_number = 0;
728: strcpy(acls1->rule, av[3]);
729: while ((*acls != NULL) && ((*acls)->number < acls1->number))
730: acls = &((*acls)->next);
731:
732: if (*acls == NULL) {
733: acls1->next = NULL;
734: } else if ((*acls)->number == acls1->number) {
735: Freee(acls1);
736: Error("Duplicate acl\r\n");
737: } else {
738: acls1->next = *acls;
739: }
740: *acls = acls1;
741:
742: } else if (ac == 2 && strcasecmp(av[1], "clear") == 0) {
743: struct acl *acls, *acls1;
744: int i;
745:
746: i = atoi(av[0]);
747: if (i <= 0 || i > ACL_FILTERS)
748: Error("Wrong filter number\r\n");
749:
750: acls = acl_filters[i - 1];
751: while (acls != NULL) {
752: acls1 = acls->next;
753: Freee(acls);
754: acls = acls1;
755: };
756: acl_filters[i - 1] = NULL;
757: } else
758: return(-1);
759: break;
760: #endif /* USE_NG_BPF */
761:
1.1.1.2 misho 762: case SET_QTHRESHOLD:
763: if (ac == 2) {
764: int val_max;
765:
766: val = atoi(av[0]);
767: if (val < 0 || val >= MSG_QUEUE_LEN-1)
768: Error("Incorrect minimum threshold for message queue, "
769: "must be between 0 and %d", MSG_QUEUE_LEN-1);
770: val_max = atoi(av[1]);
771: if (val_max <= val || val_max >= MSG_QUEUE_LEN)
772: Error("Incorrect maximum threshold for message queue, "
773: "must be greater than minimum and less than %d",
774: MSG_QUEUE_LEN);
775: gQThresMin = val;
776: gQThresMax = val_max;
777: gQThresDiff = val_max - val;
778: }
779: else
780: return (-1);
781: break;
1.1 misho 782: default:
783: return(-1);
784: }
785:
786: return 0;
787: }
788:
789: /*
790: * HelpCommand()
791: */
792:
793: int
1.1.1.4 ! misho 794: HelpCommand(Context ctx, int ac, const char *const av[], const void *arg)
1.1 misho 795: {
796: int depth, i;
797: CmdTab menu, cmd;
798: char *mark, *mark_save;
799: const char *errfmt;
800: char buf[256];
801: int err;
802:
803: for (mark = buf, depth = *buf = 0, menu = gCommands;
804: depth < ac;
805: depth++, menu = (CmdTab) cmd->arg) {
806: if ((err = FindCommand(ctx, menu, av[depth], &cmd))) {
807: int k;
808:
809: for (*buf = k = 0; k <= depth; k++)
810: snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%s%c",
811: av[k], k == depth ? '\0' : ' ');
812: if (err == CMD_ERR_AMBIG)
813: errfmt = "%sAmbiguous command: '%s'.\r\n";
814: else
815: errfmt = "%sUnknown command: '%s'.\r\n";
816: if (arg) {
1.1.1.4 ! misho 817: Printf(errfmt, (const char*)arg, buf);
1.1 misho 818: } else {
819: Printf(errfmt, "", buf);
820: }
821: return(0);
822: }
823: sprintf(mark, depth ? " %s" : "%s", cmd->name);
824: mark_save = mark;
825: if ((mark = strchr(mark + 1, ' ')) == NULL)
826: mark = mark_save + strlen(mark_save);
827: if (cmd->func != CMD_SUBMENU)
828: {
829: Printf("Usage: %s\r\n", buf);
830: return(0);
831: }
832: }
833:
834: /* Show list of available commands in this submenu */
835: *mark = 0;
836: if (!*buf)
837: Printf("Available commands:\r\n");
838: else
839: Printf("Commands available under \"%s\":\r\n", buf);
840: i = 0;
841: for (cmd = menu; cmd->name; cmd++) {
842: if (cmd->priv > ctx->priv)
843: continue;
844: strlcpy(buf, cmd->name, sizeof(buf));
845: if ((mark = strchr(buf, ' ')))
846: *mark = 0;
847: Printf(" %-9s: %-20s%s", buf, cmd->desc,
848: (i & 1)? "\r\n" : "\t");
849: i++;
850: }
851: if (i & 1)
852: Printf("\r\n");
853: return(0);
854: }
855:
856: /*
857: * SetDebugCommand()
858: */
859:
860: static int
1.1.1.4 ! misho 861: SetDebugCommand(Context ctx, int ac, const char *const av[], const void *arg)
1.1 misho 862: {
1.1.1.4 ! misho 863: (void)arg;
! 864: (void)ctx;
! 865:
1.1 misho 866: switch (ac) {
867: case 1:
868: NgSetDebug(atoi(av[0]));
869: break;
870: default:
871: return(-1);
872: }
873: return(0);
874: }
875:
876: /*
877: * ShowVersion()
878: */
879:
880: static int
1.1.1.4 ! misho 881: ShowVersion(Context ctx, int ac, const char *const av[], const void *arg)
1.1 misho 882: {
1.1.1.4 ! misho 883: (void)ac;
! 884: (void)av;
! 885: (void)arg;
! 886:
1.1 misho 887: Printf("MPD version: %s\r\n", gVersion);
888: Printf(" Available features:\r\n");
889: #ifdef USE_IPFW
890: Printf(" ipfw rules : yes\r\n");
891: #else
892: Printf(" ipfw rules : no\r\n");
893: #endif
894: #ifdef USE_FETCH
895: Printf(" config fetch : yes\r\n");
896: #else
897: Printf(" config fetch : no\r\n");
898: #endif
1.1.1.3 misho 899: #ifdef USE_BACKTRACE
900: Printf(" backtrace() : yes\r\n");
901: #else
902: Printf(" backtrace() : no\r\n");
903: #endif
1.1 misho 904: #ifdef USE_NG_BPF
905: Printf(" ng_bpf : yes\r\n");
906: #else
907: Printf(" ng_bpf : no\r\n");
908: #endif
909: #ifdef USE_NG_CAR
910: Printf(" ng_car : yes\r\n");
911: #else
912: Printf(" ng_car : no\r\n");
913: #endif
914: #ifdef USE_NG_DEFLATE
915: Printf(" ng_deflate : yes\r\n");
916: #else
917: Printf(" ng_deflate : no\r\n");
918: #endif
919: #ifdef USE_NG_IPACCT
920: Printf(" ng_ipacct : yes\r\n");
921: #else
922: Printf(" ng_ipacct : no\r\n");
923: #endif
924: #ifdef CCP_MPPC
925: Printf(" ng_mppc (MPPC) : %s\r\n", MPPCPresent?"yes":"no");
926: Printf(" ng_mppc (MPPE) : %s\r\n", MPPEPresent?"yes":"no");
927: #else
928: Printf(" ng_mppc (MPPC) : no\r\n");
929: Printf(" ng_mppc (MPPE) : no\r\n");
930: #endif
931: #ifdef USE_NG_NAT
932: Printf(" ng_nat : yes\r\n");
933: #ifdef NG_NAT_DESC_LENGTH
934: Printf(" nat redirect : yes\r\n");
935: #else
936: Printf(" nat redirect : no\r\n");
937: #endif
938: #else
939: Printf(" ng_nat : no\r\n");
940: #endif
941: #ifdef USE_NG_NETFLOW
942: Printf(" ng_netflow : yes\r\n");
1.1.1.2 misho 943: #if NGM_NETFLOW_COOKIE >= 1309868867
944: Printf(" netflow v9 : yes\r\n");
945: #else
946: Printf(" netflow v9 : no\r\n");
947: #endif
1.1 misho 948: #else
949: Printf(" ng_netflow : no\r\n");
950: #endif
951: #ifdef USE_NG_PRED1
952: Printf(" ng_pred1 : yes\r\n");
953: #else
954: Printf(" ng_pred1 : emulated\r\n");
955: #endif
956: #ifdef USE_NG_TCPMSS
957: Printf(" ng_tcpmss : yes\r\n");
958: #else
959: Printf(" ng_tcpmss : emulated\r\n");
960: #endif
961: return(0);
962: }
963:
964: /*
965: * ShowEvents()
966: */
967:
968: static int
1.1.1.4 ! misho 969: ShowEvents(Context ctx, int ac, const char *const av[], const void *arg)
1.1 misho 970: {
1.1.1.4 ! misho 971: (void)ac;
! 972: (void)av;
! 973: (void)arg;
! 974:
! 975: EventDump(ctx);
1.1 misho 976: return(0);
977: }
978:
979: /*
980: * ShowGlobal()
981: */
982:
983: static int
1.1.1.4 ! misho 984: ShowGlobal(Context ctx, int ac, const char *const av[], const void *arg)
1.1 misho 985: {
986: #ifdef USE_NG_BPF
987: int k;
988: #endif
989:
1.1.1.4 ! misho 990: (void)ac;
! 991: (void)av;
! 992: (void)arg;
! 993:
1.1 misho 994: Printf("Global settings:\r\n");
995: #ifdef USE_IPFW
996: Printf(" startrule : %d\r\n", rule_pool_start);
997: Printf(" startpipe : %d\r\n", pipe_pool_start);
998: Printf(" startqueue : %d\r\n", queue_pool_start);
999: Printf(" starttable : %d\r\n", table_pool_start);
1000: #endif
1001: #ifdef PHYSTYPE_L2TP
1002: Printf(" l2tptimeout : %d\r\n", gL2TPto);
1.1.1.4 ! misho 1003: Printf(" l2tplimit : %u\r\n", gL2TPtunlimit);
1.1 misho 1004: #endif
1005: #ifdef PHYSTYPE_PPTP
1006: Printf(" pptptimeout : %d\r\n", gPPTPto);
1.1.1.4 ! misho 1007: Printf(" pptplimit : %u\r\n", gPPTPtunlimit);
1.1 misho 1008: #endif
1009: Printf(" max-children : %d\r\n", gMaxChildren);
1.1.1.2 misho 1010: Printf(" qthreshold : %d %d\r\n", gQThresMin, gQThresMax);
1.1 misho 1011: Printf("Global options:\r\n");
1012: OptStat(ctx, &gGlobalConf.options, gGlobalConfList);
1013: #ifdef USE_NG_BPF
1014: Printf("Global traffic filters:\r\n");
1015: for (k = 0; k < ACL_FILTERS; k++) {
1016: struct acl *a = acl_filters[k];
1017: while (a) {
1018: Printf("\t%d#%d\t: '%s'\r\n", (k + 1), a->number, a->rule);
1019: a = a->next;
1020: }
1021: }
1022: #endif
1.1.1.2 misho 1023: Printf("Global state:\r\n");
1024: Printf(" children : %d\r\n", gChildren);
1.1 misho 1025: return 0;
1026: }
1027:
1028:
1029: /*
1030: * ExitCommand()
1031: */
1032:
1033: static int
1.1.1.4 ! misho 1034: ExitCommand(Context ctx, int ac, const char *const av[], const void *arg)
1.1 misho 1035: {
1.1.1.4 ! misho 1036:
! 1037: (void)ac;
! 1038: (void)av;
! 1039: (void)arg;
! 1040:
1.1 misho 1041: if (ctx->cs)
1042: ctx->cs->exit = TRUE;
1043: return(0);
1044: }
1045:
1046: /*
1047: * QuitCommand()
1048: */
1049:
1050: static int
1.1.1.4 ! misho 1051: QuitCommand(Context ctx, int ac, const char *const av[], const void *arg)
1.1 misho 1052: {
1.1.1.4 ! misho 1053: (void)ac;
! 1054: (void)av;
! 1055: (void)arg;
! 1056:
1.1 misho 1057: if (ctx->cs)
1058: ctx->cs->exit = TRUE;
1059: SendSignal(SIGTERM);
1060: return(0);
1061: }
1062:
1063: /*
1064: * LoadCommand()
1065: */
1066:
1067: static int
1.1.1.4 ! misho 1068: LoadCommand(Context ctx, int ac, const char *const av[], const void *arg)
1.1 misho 1069: {
1070: char filename[128];
1071: #ifdef USE_FETCH
1072: char buf[1024];
1073: FILE *f = NULL;
1074: FILE *rf = NULL;
1075: int fetch = 0;
1076: #endif
1077:
1.1.1.4 ! misho 1078: (void)arg;
1.1 misho 1079: if (ac < 1 || ac > 2)
1080: return(-1);
1081: else {
1082: if (ctx->depth > 20)
1083: return(CMD_ERR_RECUR);
1084: ctx->depth++;
1085:
1086: if (ac == 1)
1087: strlcpy(filename, gConfigFile, sizeof(filename));
1088: else {
1089: #ifdef USE_FETCH
1090: if (strncmp(av[0], "http://", 7) == 0 ||
1091: strncmp(av[0], "https://", 8) == 0 ||
1092: strncmp(av[0], "ftp://", 6) == 0) {
1093: fetch = 1;
1094: strcpy(filename, "/tmp/mpd.conf.XXXXXX");
1095: mkstemp(filename);
1096: f = fopen(filename, "w");
1097: if (f == NULL) {
1098: Printf("Can't create temporal file\r\n");
1099: goto out;
1100: }
1101: rf = fetchGetURL(av[0], "");
1102: if (rf == NULL) {
1103: Printf("Can't fetch '%s'\r\n", av[0]);
1104: fclose(f);
1105: goto out;
1106: }
1107: Printf("Fetching '%s' ...", av[0]);
1108: while (!feof(rf)) {
1109: int b = fread(buf, 1, sizeof(buf), rf);
1110: fwrite(buf, b, 1, f);
1111: }
1112: Printf(" done\r\n");
1113: fclose(f);
1114: } else
1115: #endif
1116: strlcpy(filename, av[0], sizeof(filename));
1117: }
1118: if (ReadFile(filename, av[ac - 1], DoCommand, ctx) < 0)
1119: Printf("can't read configuration for \"%s\" from \"%s\"\r\n",
1120: av[ac -1], filename);
1121: #ifdef USE_FETCH
1122: out: if (fetch)
1123: unlink(filename);
1124: #endif
1125: ctx->depth--;
1126: }
1127: return(0);
1128: }
1129:
1130: /*
1131: * OpenCommand()
1132: */
1133:
1134: static int
1.1.1.4 ! misho 1135: OpenCommand(Context ctx, int ac, const char *const av[], const void *arg)
1.1 misho 1136: {
1137: Layer layer;
1138: const char *name;
1139:
1.1.1.4 ! misho 1140: (void)arg;
1.1 misho 1141: switch (ac) {
1142: case 0:
1143: name = DEFAULT_OPEN_LAYER;
1144: break;
1145: case 1:
1146: name = av[0];
1147: break;
1148: default:
1149: return(-1);
1150: }
1151: if ((layer = GetLayer(name)) != NULL) {
1152: /* Check command admissibility */
1153: if (!layer->admit || (layer->admit)(ctx, NULL))
1154: return (*layer->opener)(ctx);
1155: else
1156: return (CMD_ERR_NOCTX);
1157: }
1158: return(-1);
1159: }
1160:
1161: /*
1162: * CloseCommand()
1163: */
1164:
1165: static int
1.1.1.4 ! misho 1166: CloseCommand(Context ctx, int ac, const char *const av[], const void *arg)
1.1 misho 1167: {
1168: Layer layer;
1169: const char *name;
1170:
1.1.1.4 ! misho 1171: (void)arg;
1.1 misho 1172: switch (ac) {
1173: case 0:
1174: name = DEFAULT_OPEN_LAYER;
1175: break;
1176: case 1:
1177: name = av[0];
1178: break;
1179: default:
1180: return(-1);
1181: }
1182: if ((layer = GetLayer(name)) != NULL) {
1183: /* Check command admissibility */
1184: if (!layer->admit || (layer->admit)(ctx, NULL))
1185: return (*layer->closer)(ctx);
1186: else
1187: return (CMD_ERR_NOCTX);
1188: }
1189: return(-1);
1190: }
1191:
1192: /*
1193: * GetLayer()
1194: */
1195:
1196: static Layer
1197: GetLayer(const char *name)
1198: {
1.1.1.3 misho 1199: size_t k;
1200: int found;
1.1 misho 1201:
1202: if (name == NULL)
1203: name = "iface";
1204: for (found = -1, k = 0; k < NUM_LAYERS; k++) {
1205: if (!strncasecmp(name, gLayers[k].name, strlen(name))) {
1206: if (found > 0) {
1207: Log(LG_ERR, ("%s: ambiguous", name));
1208: return(NULL);
1209: } else
1210: found = k;
1211: }
1212: }
1213: if (found < 0) {
1214: Log(LG_ERR, ("unknown layer \"%s\": try \"show layers\"", name));
1215: return(NULL);
1216: }
1217: return(&gLayers[found]);
1218: }
1219:
1220: /*
1221: * ShowLayers()
1222: */
1223:
1224: static int
1.1.1.4 ! misho 1225: ShowLayers(Context ctx, int ac, const char *const av[], const void *arg)
1.1 misho 1226: {
1.1.1.3 misho 1227: size_t k;
1.1 misho 1228:
1.1.1.4 ! misho 1229: (void)ac;
! 1230: (void)av;
! 1231: (void)arg;
! 1232:
1.1 misho 1233: Printf("\tName\t\tDescription\r\n");
1234: Printf("\t----\t\t-----------\r\n");
1235: for (k = 0; k < NUM_LAYERS; k++)
1236: Printf("\t%s\t\t%s\r\n", gLayers[k].name, gLayers[k].desc);
1237: return(0);
1238: }
1239:
1240: /*
1241: * ShowTypes()
1242: */
1243:
1244: static int
1.1.1.4 ! misho 1245: ShowTypes(Context ctx, int ac, const char *const av[], const void *arg)
1.1 misho 1246: {
1.1.1.4 ! misho 1247: const struct phystype *pt;
1.1 misho 1248: int k;
1249:
1.1.1.4 ! misho 1250: (void)ac;
! 1251: (void)av;
! 1252: (void)arg;
! 1253:
1.1 misho 1254: Printf("\tName\t\tDescription\r\n");
1255: Printf("\t----\t\t-----------\r\n");
1256: for (k = 0; (pt = gPhysTypes[k]); k++)
1257: Printf("\t%s\t\t%s\r\n", pt->name, pt->descr);
1258: return(0);
1259: }
1260:
1261: /*
1262: * ShowSummary()
1263: */
1264:
1265: static int
1.1.1.4 ! misho 1266: ShowSummary(Context ctx, int ac, const char *const av[], const void *arg)
1.1 misho 1267: {
1268: int b, l, f;
1269: Bund B;
1270: Link L;
1271: Rep R;
1272: char buf[64];
1273:
1.1.1.4 ! misho 1274: (void)ac;
! 1275: (void)av;
! 1276: (void)arg;
! 1277:
1.1 misho 1278: Printf("Current daemon status summary\r\n");
1279: Printf("Iface\tBund\t\tLink\tLCP\tDevice\t\tUser\t\tFrom\r\n");
1280: for (b = 0; b<gNumLinks; b++) {
1281: if ((L=gLinks[b]) != NULL && L->bund == NULL && L->rep == NULL) {
1282: Printf("\t\t\t");
1283: Printf("%s\t%s\t",
1284: L->name,
1285: FsmStateName(L->lcp.fsm.state));
1286: PhysGetPeerAddr(L, buf, sizeof(buf));
1287: Printf("%s\t%s\t%8s\t%s",
1288: (L->type?L->type->name:""),
1289: gPhysStateNames[L->state],
1290: L->lcp.auth.params.authname,
1291: buf
1292: );
1293: Printf("\r\n");
1294: }
1295: }
1296: for (b = 0; b<gNumBundles; b++) {
1297: if ((B=gBundles[b]) != NULL) {
1298: Printf("%s\t%s\t%s\t", B->iface.ifname, B->name, (B->iface.up?"Up":"Down"));
1299: f = 1;
1300: if (B->n_links == 0)
1301: Printf("\r\n");
1302: else for (l = 0; l < NG_PPP_MAX_LINKS; l++) {
1303: if ((L=B->links[l]) != NULL) {
1304: if (f == 1)
1305: f = 0;
1306: else
1307: Printf("\t\t\t");
1308: PhysGetPeerAddr(L, buf, sizeof(buf));
1309: Printf("%s\t%s\t%s\t%s\t%8s\t%s",
1310: L->name,
1311: FsmStateName(L->lcp.fsm.state),
1312: (L->type?L->type->name:""),
1313: gPhysStateNames[L->state],
1314: L->lcp.auth.params.authname,
1315: buf
1316: );
1317: Printf("\r\n");
1318: }
1319: }
1320: }
1321: }
1322: for (b = 0; b < gNumReps; b++) {
1323: if ((R = gReps[b]) != NULL) {
1324: Printf("Repeater\t%s\t", R->name);
1325: f = 1;
1326: for (l = 0; l < 2; l++) {
1327: if ((L = R->links[l])!= NULL) {
1328: if (f)
1329: f = 0;
1330: else
1331: Printf("\t\t\t");
1332: PhysGetPeerAddr(L, buf, sizeof(buf));
1333: Printf("%s\t%s\t%s\t%s\t%8s\t%s",
1334: L->name,
1335: "",
1336: (L->type?L->type->name:""),
1337: gPhysStateNames[L->state],
1338: "",
1339: buf
1340: );
1341: Printf("\r\n");
1342: }
1343: }
1344: if (f)
1345: Printf("\r\n");
1346: }
1347: }
1348: return(0);
1349: }
1350:
1351: /*
1352: * ShowSessions()
1353: */
1354:
1355: static int
1.1.1.4 ! misho 1356: ShowSessions(Context ctx, int ac, const char *const av[], const void *arg)
1.1 misho 1357: {
1358: int l;
1359: Bund B;
1360: Link L;
1.1.1.3 misho 1361: char peer[64], addr[64], buf[64];
1.1 misho 1362:
1363: if (ac != 0 && ac != 1)
1364: return (-1);
1365:
1366: for (l = 0; l < gNumLinks; l++) {
1367: if ((L=gLinks[l]) != NULL && L->session_id[0] && L->bund) {
1368: B = L->bund;
1369: u_addrtoa(&B->iface.peer_addr, addr, sizeof(addr));
1370: PhysGetPeerAddr(L, peer, sizeof(peer));
1371: if (ac == 0)
1372: goto out;
1373: switch ((intptr_t)arg) {
1374: case SHOW_IFACE:
1375: if (strcmp(av[0], B->iface.ifname))
1376: continue;
1377: break;
1378: case SHOW_IP:
1379: if (strcmp(av[0], addr))
1380: continue;
1381: break;
1382: case SHOW_USER:
1383: if (strcmp(av[0], L->lcp.auth.params.authname))
1384: continue;
1385: break;
1386: case SHOW_MSESSION:
1387: if (strcmp(av[0], B->msession_id))
1388: continue;
1389: break;
1390: case SHOW_SESSION:
1391: if (strcmp(av[0], L->session_id))
1392: continue;
1393: break;
1394: case SHOW_BUNDLE:
1395: if (strcmp(av[0], B->name))
1396: continue;
1397: break;
1398: case SHOW_LINK:
1399: if (av[0][0] == '[') {
1400: int k;
1401: if (sscanf(av[0], "[%x]", &k) != 1)
1402: return (-1);
1403: else {
1404: if (L->id != k)
1405: continue;
1406: }
1407: } else {
1408: if (strcmp(av[1], L->name))
1409: continue;
1410: }
1411: break;
1412: case SHOW_PEER:
1413: if (strcmp(av[0], peer))
1414: continue;
1.1.1.4 ! misho 1415: break;
1.1 misho 1416: default:
1417: return (-1);
1418: }
1419: out:
1420: Printf("%s\t%s\t%s\t%s\t", B->iface.ifname,
1421: addr, B->name, B->msession_id);
1422: Printf("%s\t%d\t%s\t%s\t%s",
1423: L->name,
1424: L->id,
1425: L->session_id,
1426: L->lcp.auth.params.authname,
1427: peer
1428: );
1.1.1.3 misho 1429: if (Enabled(&gGlobalConf.options, GLOBAL_CONF_AGENT_CID)) {
1430: PhysGetSelfName(L, buf, sizeof(buf));
1431: Printf("\t%s", buf);
1432: }
1433: if (Enabled(&gGlobalConf.options, GLOBAL_CONF_SESS_TIME)) {
1434: if (L->state == PHYS_STATE_UP)
1435: Printf("\t%ld", (long int)(time(NULL) - L->last_up));
1436: }
1.1 misho 1437: Printf("\r\n");
1438: }
1439: }
1440: return(0);
1441: }
1442:
1443: /*
1444: * ShowCustomer()
1445: */
1446:
1447: static int
1.1.1.4 ! misho 1448: ShowCustomer(Context ctx, int ac, const char *const av[], const void *arg)
1.1 misho 1449: {
1450: Link l = ctx->lnk;
1451: Bund b = ctx->bund;
1452: IfaceState iface;
1453: IfaceRoute r;
1454: int j;
1455: char buf[64];
1456: #if defined(USE_NG_BPF) || defined(USE_IPFW)
1457: struct acl *a;
1458: #endif
1459:
1.1.1.4 ! misho 1460: (void)ac;
! 1461: (void)av;
! 1462: (void)arg;
! 1463:
1.1 misho 1464: if (b && b->iface.ifname[0]) {
1465: iface = &b->iface;
1466: Printf("Interface:\r\n");
1467: Printf("\tName : %s\r\n", iface->ifname);
1468: Printf("\tStatus : %s\r\n", iface->up ? (iface->dod?"DoD":"UP") : "DOWN");
1469: if (iface->up) {
1470: Printf("\tSession time : %ld seconds\r\n", (long int)(time(NULL) - iface->last_up));
1471: #ifdef USE_NG_BPF
1472: if (b->params.idle_timeout || iface->idle_timeout)
1473: Printf("\tIdle timeout : %d seconds\r\n", b->params.idle_timeout?b->params.idle_timeout:iface->idle_timeout);
1474: #endif
1475: if (b->params.session_timeout || iface->session_timeout)
1476: Printf("\tSession timeout : %d seconds\r\n", b->params.session_timeout?b->params.session_timeout:iface->session_timeout);
1477: Printf("\tMTU : %d bytes\r\n", iface->mtu);
1478: }
1479: if (iface->ip_up && !u_rangeempty(&iface->self_addr)) {
1480: Printf("\tIP Addresses : %s -> ", u_rangetoa(&iface->self_addr,buf,sizeof(buf)));
1481: Printf("%s\r\n", u_addrtoa(&iface->peer_addr,buf,sizeof(buf)));
1482: }
1483: if (iface->ipv6_up && !u_addrempty(&iface->self_ipv6_addr)) {
1484: Printf("\tIPv6 Addresses : %s%%%s -> ",
1485: u_addrtoa(&iface->self_ipv6_addr,buf,sizeof(buf)), iface->ifname);
1486: Printf("%s%%%s\r\n", u_addrtoa(&iface->peer_ipv6_addr,buf,sizeof(buf)), iface->ifname);
1487: }
1488: if (iface->up) {
1489: if (!SLIST_EMPTY(&iface->routes) || !SLIST_EMPTY(&b->params.routes)) {
1490: Printf("\tRoutes via peer :\r\n");
1491: SLIST_FOREACH(r, &iface->routes, next)
1.1.1.3 misho 1492: Printf("\t\t: %s\r\n", u_rangetoa(&r->dest,buf,sizeof(buf)));
1.1 misho 1493: SLIST_FOREACH(r, &b->params.routes, next)
1.1.1.3 misho 1494: Printf("\t\t: %s\r\n", u_rangetoa(&r->dest,buf,sizeof(buf)));
1.1 misho 1495: }
1496: #ifdef USE_IPFW
1497: if (b->params.acl_pipe) {
1498: Printf("\tIPFW pipes :\r\n");
1499: a = b->params.acl_pipe;
1500: while (a) {
1.1.1.3 misho 1501: Printf("\t\t%d (%d)\t: '%s'\r\n", a->number, a->real_number, a->rule);
1.1 misho 1502: a = a->next;
1503: }
1504: }
1505: if (b->params.acl_queue) {
1506: Printf("\tIPFW queues :\r\n");
1507: a = b->params.acl_queue;
1508: while (a) {
1.1.1.3 misho 1509: Printf("\t\t%d (%d)\t: '%s'\r\n", a->number, a->real_number, a->rule);
1.1 misho 1510: a = a->next;
1511: }
1512: }
1513: if (b->params.acl_table) {
1514: Printf("\tIPFW tables :\r\n");
1515: a = b->params.acl_table;
1516: while (a) {
1517: if (a->number != 0)
1.1.1.3 misho 1518: Printf("\t\t%d (%d)\t: '%s'\r\n", a->number, a->real_number, a->rule);
1.1 misho 1519: else
1.1.1.3 misho 1520: Printf("\t\t(%d)\t: '%s'\r\n", a->real_number, a->rule);
1.1 misho 1521: a = a->next;
1522: }
1523: }
1524: if (b->params.acl_rule) {
1525: Printf("\tIPFW rules :\r\n");
1526: a = b->params.acl_rule;
1527: while (a) {
1.1.1.3 misho 1528: Printf("\t\t%d (%d)\t: '%s'\r\n", a->number, a->real_number, a->rule);
1.1 misho 1529: a = a->next;
1530: }
1531: }
1532: #endif /* USE_IPFW */
1533: #ifdef USE_NG_BPF
1534: if (b->params.acl_limits[0] || b->params.acl_limits[1]) {
1535: int k;
1536: Printf("\tTraffic filters :\r\n");
1537: for (k = 0; k < ACL_FILTERS; k++) {
1538: a = b->params.acl_filters[k];
1539: if (a == NULL)
1540: a = acl_filters[k];
1541: while (a) {
1.1.1.3 misho 1542: Printf("\t\t%d#%d\t: '%s'\r\n", (k + 1), a->number, a->rule);
1.1 misho 1543: a = a->next;
1544: }
1545: }
1546: Printf("\tTraffic limits :\r\n");
1547: for (k = 0; k < 2; k++) {
1548: a = b->params.acl_limits[k];
1549: while (a) {
1.1.1.3 misho 1550: Printf("\t\t%s#%d%s%s\t: '%s'\r\n", (k?"out":"in"), a->number,
1.1 misho 1551: ((a->name[0])?"#":""), a->name, a->rule);
1552: a = a->next;
1553: }
1554: }
1555: }
1556: #endif /* USE_NG_BPF */
1557: }
1558: }
1559: if (b) {
1560: Printf("Bundle %s%s:\r\n", b->name, b->tmpl?" (template)":(b->stay?" (static)":""));
1561: Printf("\tStatus : %s\r\n", b->open ? "OPEN" : "CLOSED");
1562: Printf("\tMulti Session Id: %s\r\n", b->msession_id);
1563: Printf("\tPeer authname : \"%s\"\r\n", b->params.authname);
1564: if (b->n_up)
1565: Printf("\tSession time : %ld seconds\r\n", (long int)(time(NULL) - l->last_up));
1566:
1567: if (b->peer_mrru) {
1568: Printf("\tMultilink PPP:\r\n");
1569: Printf("\t\tPeer auth name : \"%s\"\r\n", b->params.authname);
1570: Printf("\t\tPeer discrimin.: %s\r\n", MpDiscrimText(&b->peer_discrim, buf, sizeof(buf)));
1571: }
1572:
1573: if (!b->tmpl) {
1574: /* Show stats */
1575: BundUpdateStats(b);
1576: Printf("\tTraffic stats:\r\n");
1577:
1578: Printf("\t\tInput octets : %llu\r\n", (unsigned long long)b->stats.recvOctets);
1579: Printf("\t\tInput frames : %llu\r\n", (unsigned long long)b->stats.recvFrames);
1580: Printf("\t\tOutput octets : %llu\r\n", (unsigned long long)b->stats.xmitOctets);
1581: Printf("\t\tOutput frames : %llu\r\n", (unsigned long long)b->stats.xmitFrames);
1582: Printf("\t\tBad protocols : %llu\r\n", (unsigned long long)b->stats.badProtos);
1583: Printf("\t\tRunts : %llu\r\n", (unsigned long long)b->stats.runts);
1584: }
1585: }
1586: for (j = 0; j < NG_PPP_MAX_LINKS; j++) {
1587: if (b)
1588: l = b->links[j];
1589: else if (j != 0)
1590: l = NULL;
1591: if (l) {
1592: Printf("Link %s:\r\n", l->name);
1593: Printf("\tDevice type : %s\r\n", l->type?l->type->name:"");
1594: Printf("\tStatus : %s/%s\r\n",
1595: FsmStateName(l->lcp.fsm.state),
1596: gPhysStateNames[l->state]);
1597: Printf("\tSession Id : %s\r\n", l->session_id);
1598: Printf("\tPeer ident : %s\r\n", l->lcp.peer_ident);
1599: if (l->state == PHYS_STATE_UP)
1600: Printf("\tSession time : %ld seconds\r\n", (long int)(time(NULL) - l->last_up));
1601:
1602: PhysGetSelfAddr(l, buf, sizeof(buf));
1603: Printf("\tSelf addr (name): %s", buf);
1604: PhysGetSelfName(l, buf, sizeof(buf));
1605: Printf(" (%s)\r\n", buf);
1606: PhysGetPeerAddr(l, buf, sizeof(buf));
1607: Printf("\tPeer addr (name): %s", buf);
1608: PhysGetPeerName(l, buf, sizeof(buf));
1609: Printf(" (%s)\r\n", buf);
1610: PhysGetPeerMacAddr(l, buf, sizeof(buf));
1611: Printf("\tPeer MAC address: %s\r\n", buf);
1612: PhysGetPeerIface(l, buf, sizeof(buf));
1613: Printf("\tPeer iface : %s\r\n", buf);
1614: PhysGetCallingNum(l, buf, sizeof(buf));
1615: Printf("\tCalling : %s\r\n", buf);
1616: PhysGetCalledNum(l, buf, sizeof(buf));
1617: Printf("\tCalled : %s\r\n", buf);
1618:
1619: if (l->bund) {
1620: LinkUpdateStats(l);
1621: Printf("\tTraffic stats:\r\n");
1622: Printf("\t\tInput octets : %llu\r\n", (unsigned long long)l->stats.recvOctets);
1623: Printf("\t\tInput frames : %llu\r\n", (unsigned long long)l->stats.recvFrames);
1624: Printf("\t\tOutput octets : %llu\r\n", (unsigned long long)l->stats.xmitOctets);
1625: Printf("\t\tOutput frames : %llu\r\n", (unsigned long long)l->stats.xmitFrames);
1626: Printf("\t\tBad protocols : %llu\r\n", (unsigned long long)l->stats.badProtos);
1627: Printf("\t\tRunts : %llu\r\n", (unsigned long long)l->stats.runts);
1628: }
1629: }
1630: }
1631:
1632: return(0);
1633: }
1634:
1635: /*
1636: * AdmitBund()
1637: */
1638:
1639: int
1640: AdmitBund(Context ctx, CmdTab cmd)
1641: {
1.1.1.4 ! misho 1642: (void)cmd;
1.1 misho 1643: if (!ctx->bund)
1644: return(FALSE);
1645: return(TRUE);
1646: }
1647:
1648: /*
1649: * AdmitLink()
1650: */
1651:
1652: int
1653: AdmitLink(Context ctx, CmdTab cmd)
1654: {
1.1.1.4 ! misho 1655: (void)cmd;
1.1 misho 1656: if (!ctx->lnk)
1657: return(FALSE);
1658: return(TRUE);
1659: }
1660:
1661: /*
1662: * AdmitRep()
1663: */
1664:
1665: int
1666: AdmitRep(Context ctx, CmdTab cmd)
1667: {
1.1.1.4 ! misho 1668: (void)cmd;
1.1 misho 1669: if (!ctx->rep)
1670: return(FALSE);
1671: return(TRUE);
1672: }
1673:
1674: /*
1675: * AdmitDev()
1676: */
1677:
1678: int
1679: AdmitDev(Context ctx, CmdTab cmd)
1680: {
1681: if (!cmd)
1682: return(FALSE);
1683: if (!ctx->lnk)
1684: return(FALSE);
1685: if (strncmp(cmd->name, ctx->lnk->type->name, strlen(ctx->lnk->type->name)))
1686: return(FALSE);
1687: return(TRUE);
1688: }
1689:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>