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