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