Annotation of embedaddon/mpd/src/command.c, revision 1.1.1.4.2.1

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>