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