Annotation of embedaddon/mpd/src/command.c, revision 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>