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>