Annotation of embedaddon/mpd/src/ipcp.c, revision 1.1

1.1     ! misho       1: 
        !             2: /*
        !             3:  * ipcp.c
        !             4:  *
        !             5:  * Written by Toshiharu OHNO <tony-o@iij.ad.jp>
        !             6:  * Copyright (c) 1993, Internet Initiative Japan, Inc. All rights reserved.
        !             7:  * See ``COPYRIGHT.iij''
        !             8:  * 
        !             9:  * Rewritten by Archie Cobbs <archie@freebsd.org>
        !            10:  * Copyright (c) 1995-1999 Whistle Communications, Inc. All rights reserved.
        !            11:  * See ``COPYRIGHT.whistle''
        !            12:  */
        !            13: 
        !            14: #include "ppp.h"
        !            15: #include "ipcp.h"
        !            16: #include "fsm.h"
        !            17: #include "ip.h"
        !            18: #include "iface.h"
        !            19: #include "msg.h"
        !            20: #include "ngfunc.h"
        !            21: #include "ippool.h"
        !            22: #include "util.h"
        !            23: 
        !            24: #include <netgraph.h>
        !            25: #include <sys/mbuf.h>
        !            26: #ifdef USE_NG_VJC
        !            27: #include <net/slcompress.h>
        !            28: #include <netgraph/ng_vjc.h>
        !            29: #endif
        !            30: 
        !            31: /*
        !            32:  * DEFINITIONS
        !            33:  */
        !            34: 
        !            35:   #define IPCP_KNOWN_CODES     (   (1 << CODE_CONFIGREQ)       \
        !            36:                                  | (1 << CODE_CONFIGACK)       \
        !            37:                                  | (1 << CODE_CONFIGNAK)       \
        !            38:                                  | (1 << CODE_CONFIGREJ)       \
        !            39:                                  | (1 << CODE_TERMREQ)         \
        !            40:                                  | (1 << CODE_TERMACK)         \
        !            41:                                  | (1 << CODE_CODEREJ)         )
        !            42: 
        !            43:   #define TY_IPADDRS           1
        !            44:   #define TY_COMPPROTO         2
        !            45:   #define TY_IPADDR            3
        !            46:   #define TY_PRIMARYDNS                129
        !            47:   #define TY_PRIMARYNBNS       130
        !            48:   #define TY_SECONDARYDNS      131
        !            49:   #define TY_SECONDARYNBNS     132
        !            50: 
        !            51:   /* Keep sync with above */
        !            52:   #define o2b(x)               (((x)<128)?(x):(x)-128+3)
        !            53: 
        !            54:   #define IPCP_REJECTED(p,x)   ((p)->peer_reject & (1<<o2b(x)))
        !            55:   #define IPCP_PEER_REJ(p,x)   do{(p)->peer_reject |= (1<<o2b(x));}while(0)
        !            56: 
        !            57: #ifdef USE_NG_VJC
        !            58:   #define IPCP_VJCOMP_MIN_MAXCHAN      (NG_VJC_MIN_CHANNELS - 1)
        !            59:   #define IPCP_VJCOMP_MAX_MAXCHAN      (NG_VJC_MAX_CHANNELS - 1)
        !            60:   #define IPCP_VJCOMP_DEFAULT_MAXCHAN  IPCP_VJCOMP_MAX_MAXCHAN
        !            61: #endif
        !            62: 
        !            63:   /* Set menu options */
        !            64:   enum {
        !            65:     SET_RANGES,
        !            66:     SET_ENABLE,
        !            67:     SET_DNS,
        !            68:     SET_NBNS,
        !            69:     SET_DISABLE,
        !            70:     SET_ACCEPT,
        !            71:     SET_DENY,
        !            72:     SET_YES,
        !            73:     SET_NO
        !            74:   };
        !            75: 
        !            76: /*
        !            77:  * INTERNAL FUNCTIONS
        !            78:  */
        !            79: 
        !            80:   static void  IpcpConfigure(Fsm fp);
        !            81:   static void  IpcpUnConfigure(Fsm fp);
        !            82: 
        !            83:   static u_char        *IpcpBuildConfigReq(Fsm fp, u_char *cp);
        !            84:   static void  IpcpDecodeConfig(Fsm fp, FsmOption list, int num, int mode);
        !            85:   static void  IpcpLayerStart(Fsm fp);
        !            86:   static void  IpcpLayerFinish(Fsm fp);
        !            87:   static void  IpcpLayerUp(Fsm fp);
        !            88:   static void  IpcpLayerDown(Fsm fp);
        !            89:   static void  IpcpFailure(Fsm fp, enum fsmfail reason);
        !            90: 
        !            91: #ifdef USE_NG_VJC
        !            92:   static int   IpcpNgInitVJ(Bund b);
        !            93:   static void  IpcpNgShutdownVJ(Bund b);
        !            94: #endif
        !            95: 
        !            96:   static int   IpcpSetCommand(Context ctx, int ac, char *av[], void *arg);
        !            97: 
        !            98: /*
        !            99:  * GLOBAL VARIABLES
        !           100:  */
        !           101: 
        !           102:   const struct cmdtab IpcpSetCmds[] = {
        !           103:     { "ranges {self}[/{width}]|ippool {pool} {peer}[/{width}]|ippool {pool}",  "Allowed IP address ranges",
        !           104:        IpcpSetCommand, NULL, 2, (void *) SET_RANGES },
        !           105:     { "enable [opt ...]",              "Enable option",
        !           106:        IpcpSetCommand, NULL, 2, (void *) SET_ENABLE},
        !           107:     { "dns primary [secondary]",       "Set peer DNS servers",
        !           108:        IpcpSetCommand, NULL, 2, (void *) SET_DNS},
        !           109:     { "nbns primary [secondary]",      "Set peer NBNS servers",
        !           110:        IpcpSetCommand, NULL, 2, (void *) SET_NBNS},
        !           111:     { "disable [opt ...]",             "Disable option",
        !           112:        IpcpSetCommand, NULL, 2, (void *) SET_DISABLE},
        !           113:     { "accept [opt ...]",              "Accept option",
        !           114:        IpcpSetCommand, NULL, 2, (void *) SET_ACCEPT},
        !           115:     { "deny [opt ...]",                        "Deny option",
        !           116:        IpcpSetCommand, NULL, 2, (void *) SET_DENY},
        !           117:     { "yes [opt ...]",                 "Enable and accept option",
        !           118:        IpcpSetCommand, NULL, 2, (void *) SET_YES},
        !           119:     { "no [opt ...]",                  "Disable and deny option",
        !           120:        IpcpSetCommand, NULL, 2, (void *) SET_NO},
        !           121:     { NULL },
        !           122:   };
        !           123: 
        !           124: /*
        !           125:  * INTERNAL VARIABLES
        !           126:  */
        !           127: 
        !           128:   static const struct fsmoptinfo       gIpcpConfOpts[] = {
        !           129:     { "IPADDRS",       TY_IPADDRS,             8, 8, FALSE },
        !           130: #ifdef USE_NG_VJC
        !           131:     { "COMPPROTO",     TY_COMPPROTO,           4, 4, TRUE },
        !           132: #endif
        !           133:     { "IPADDR",                TY_IPADDR,              4, 4, TRUE },
        !           134:     { "PRIDNS",                TY_PRIMARYDNS,          4, 4, TRUE },
        !           135:     { "PRINBNS",       TY_PRIMARYNBNS,         4, 4, TRUE },
        !           136:     { "SECDNS",                TY_SECONDARYDNS,        4, 4, TRUE },
        !           137:     { "SECNBNS",       TY_SECONDARYNBNS,       4, 4, TRUE },
        !           138:     { NULL }
        !           139:   };
        !           140: 
        !           141:   static const struct confinfo gConfList[] = {
        !           142: #ifdef USE_NG_VJC
        !           143:     { 1,       IPCP_CONF_VJCOMP,       "vjcomp"        },
        !           144: #endif
        !           145:     { 0,       IPCP_CONF_REQPRIDNS,    "req-pri-dns"   },
        !           146:     { 0,       IPCP_CONF_REQSECDNS,    "req-sec-dns"   },
        !           147:     { 0,       IPCP_CONF_REQPRINBNS,   "req-pri-nbns"  },
        !           148:     { 0,       IPCP_CONF_REQSECNBNS,   "req-sec-nbns"  },
        !           149:     { 0,       IPCP_CONF_PRETENDIP,    "pretend-ip"    },
        !           150:     { 0,       0,                      NULL            },
        !           151:   };
        !           152: 
        !           153:   static const struct fsmtype gIpcpFsmType = {
        !           154:     "IPCP",
        !           155:     PROTO_IPCP,
        !           156:     IPCP_KNOWN_CODES,
        !           157:     FALSE,
        !           158:     LG_IPCP, LG_IPCP2,
        !           159:     NULL,
        !           160:     IpcpLayerUp,
        !           161:     IpcpLayerDown,
        !           162:     IpcpLayerStart,
        !           163:     IpcpLayerFinish,
        !           164:     IpcpBuildConfigReq,
        !           165:     IpcpDecodeConfig,
        !           166:     IpcpConfigure,
        !           167:     IpcpUnConfigure,
        !           168:     NULL,
        !           169:     NULL,
        !           170:     NULL,
        !           171:     NULL,
        !           172:     IpcpFailure,
        !           173:     NULL,
        !           174:     NULL,
        !           175:     NULL,
        !           176:   };
        !           177: 
        !           178: /*
        !           179:  * IpcpStat()
        !           180:  */
        !           181: 
        !           182: int
        !           183: IpcpStat(Context ctx, int ac, char *av[], void *arg)
        !           184: {
        !           185: #ifdef USE_NG_VJC
        !           186:   char                 path[NG_PATHSIZ];
        !           187: #endif
        !           188:   IpcpState            const ipcp = &ctx->bund->ipcp;
        !           189:   Fsm                  fp = &ipcp->fsm;
        !           190: #ifdef USE_NG_VJC
        !           191:   union {
        !           192:       u_char           buf[sizeof(struct ng_mesg) + sizeof(struct slcompress)];
        !           193:       struct ng_mesg   reply;
        !           194:   }                    u;
        !           195:   struct slcompress    *const sls = (struct slcompress *)(void *)u.reply.data;
        !           196: #endif
        !           197:   char                 buf[48];
        !           198: 
        !           199:   Printf("[%s] %s [%s]\r\n", Pref(fp), Fsm(fp), FsmStateName(fp->state));
        !           200:   Printf("Allowed IP address ranges:\r\n");
        !           201:     if (ipcp->conf.self_ippool[0]) {
        !           202:        Printf("\tPeer: ippool %s\r\n",
        !           203:          ipcp->conf.self_ippool);
        !           204:     } else {
        !           205:        Printf("\tSelf: %s\r\n",
        !           206:            u_rangetoa(&ipcp->conf.self_allow,buf,sizeof(buf)));
        !           207:     }
        !           208:     if (ipcp->conf.ippool[0]) {
        !           209:        Printf("\tPeer: ippool %s\r\n",
        !           210:          ipcp->conf.ippool);
        !           211:     } else {
        !           212:        Printf("\tPeer: %s\r\n",
        !           213:          u_rangetoa(&ipcp->conf.peer_allow,buf,sizeof(buf)));
        !           214:     }
        !           215:   Printf("IPCP Options:\r\n");
        !           216:   OptStat(ctx, &ipcp->conf.options, gConfList);
        !           217:   Printf("Current addressing:\r\n");
        !           218:   Printf("\tSelf: %s\r\n", inet_ntoa(ipcp->want_addr));
        !           219:   Printf("\tPeer: %s\r\n", inet_ntoa(ipcp->peer_addr));
        !           220: #ifdef USE_NG_VJC
        !           221:   Printf("Compression:\r\n");
        !           222:   Printf("\tSelf: ");
        !           223:   if (ipcp->want_comp.proto != 0)
        !           224:     Printf("%s, %d compression channels, CID %scompressible\r\n",
        !           225:       ProtoName(ntohs(ipcp->want_comp.proto)),
        !           226:       ipcp->want_comp.maxchan + 1, ipcp->want_comp.compcid ? "" : "not ");
        !           227:   else
        !           228:     Printf("None\r\n");
        !           229:   Printf("\tPeer: ");
        !           230:   if (ipcp->peer_comp.proto != 0)
        !           231:     Printf("%s, %d compression channels, CID %scompressible\n",
        !           232:       ProtoName(ntohs(ipcp->peer_comp.proto)),
        !           233:       ipcp->peer_comp.maxchan + 1, ipcp->peer_comp.compcid ? "" : "not ");
        !           234:   else
        !           235:     Printf("None\r\n");
        !           236: #endif /* USE_NG_VJC */
        !           237:   Printf("Server info we give to peer:\r\n");
        !           238:   Printf("DNS servers : %15s", inet_ntoa(ipcp->conf.peer_dns[0]));
        !           239:   Printf("  %15s\r\n", inet_ntoa(ipcp->conf.peer_dns[1]));
        !           240:   Printf("NBNS servers: %15s", inet_ntoa(ipcp->conf.peer_nbns[0]));
        !           241:   Printf("  %15s\r\n", inet_ntoa(ipcp->conf.peer_nbns[1]));
        !           242:   Printf("Server info peer gave to us:\r\n");
        !           243:   Printf("DNS servers : %15s", inet_ntoa(ipcp->want_dns[0]));
        !           244:   Printf("  %15s\r\n", inet_ntoa(ipcp->want_dns[1]));
        !           245:   Printf("NBNS servers: %15s", inet_ntoa(ipcp->want_nbns[0]));
        !           246:   Printf("  %15s\r\n", inet_ntoa(ipcp->want_nbns[1]));
        !           247: 
        !           248: #ifdef USE_NG_VJC
        !           249:   /* Get VJC state */
        !           250:   snprintf(path, sizeof(path), "mpd%d-%s:%s", gPid, ctx->bund->name, NG_PPP_HOOK_VJC_IP);
        !           251:   if (NgFuncSendQuery(path, NGM_VJC_COOKIE, NGM_VJC_GET_STATE,
        !           252:       NULL, 0, &u.reply, sizeof(u), NULL) < 0)
        !           253:     return(0);
        !           254: 
        !           255:   Printf("VJ Compression:\r\n");
        !           256:   Printf("\tOut comp : %d\r\n", sls->sls_compressed);
        !           257:   Printf("\tOut total: %d\r\n", sls->sls_packets);
        !           258:   Printf("\tMissed   : %d\r\n", sls->sls_misses);
        !           259:   Printf("\tSearched : %d\r\n", sls->sls_searches);
        !           260:   Printf("\tIn comp  : %d\r\n", sls->sls_compressedin);
        !           261:   Printf("\tIn uncomp: %d\r\n", sls->sls_uncompressedin);
        !           262:   Printf("\tIn error : %d\r\n", sls->sls_errorin);
        !           263:   Printf("\tIn tossed: %d\r\n", sls->sls_tossed);
        !           264: #endif /* USE_NG_VJC */
        !           265:   return(0);
        !           266: }
        !           267: 
        !           268: /*
        !           269:  * IpcpInit()
        !           270:  */
        !           271: 
        !           272: void
        !           273: IpcpInit(Bund b)
        !           274: {
        !           275:   IpcpState            const ipcp = &b->ipcp;
        !           276: 
        !           277:   /* Init state machine */
        !           278:   memset(ipcp, 0, sizeof(*ipcp));
        !           279:   FsmInit(&ipcp->fsm, &gIpcpFsmType, b);
        !           280: 
        !           281:   /* Come up with a default IP address for my side of the link */
        !           282:   u_rangeclear(&ipcp->conf.self_allow);
        !           283:   GetAnyIpAddress(&ipcp->conf.self_allow.addr, NULL);
        !           284: 
        !           285: #ifdef USE_NG_VJC
        !           286:   /* Default we want VJ comp */
        !           287:   Enable(&ipcp->conf.options, IPCP_CONF_VJCOMP);
        !           288:   Accept(&ipcp->conf.options, IPCP_CONF_VJCOMP);
        !           289: #endif
        !           290: }
        !           291: 
        !           292: /*
        !           293:  * IpcpInst()
        !           294:  */
        !           295: 
        !           296: void
        !           297: IpcpInst(Bund b, Bund bt)
        !           298: {
        !           299:   IpcpState            const ipcp = &b->ipcp;
        !           300: 
        !           301:   /* Init state machine */
        !           302:   memcpy(ipcp, &bt->ipcp, sizeof(*ipcp));
        !           303:   FsmInst(&ipcp->fsm, &bt->ipcp.fsm, b);
        !           304: }
        !           305: 
        !           306: /*
        !           307:  * IpcpConfigure()
        !           308:  */
        !           309: 
        !           310: static void
        !           311: IpcpConfigure(Fsm fp)
        !           312: {
        !           313:     Bund       b = (Bund)fp->arg;
        !           314:     IpcpState  const ipcp = &b->ipcp;
        !           315:     char       buf[48];
        !           316: 
        !           317:     /* FSM stuff */
        !           318:     ipcp->peer_reject = 0;
        !           319: 
        !           320:     /* Get allowed IP addresses from config and/or from current bundle */
        !           321:     if (ipcp->conf.self_ippool[0]) {
        !           322:        if (IPPoolGet(ipcp->conf.self_ippool, &ipcp->self_allow.addr)) {
        !           323:            Log(LG_IPCP, ("[%s] IPCP: Can't get IP from pool \"%s\" for self",
        !           324:                b->name, ipcp->conf.self_ippool));
        !           325:        } else {
        !           326:            Log(LG_IPCP, ("[%s] IPCP: Got IP %s from pool \"%s\" for self",
        !           327:                b->name,
        !           328:                u_addrtoa(&ipcp->self_allow.addr, buf, sizeof(buf)),
        !           329:                ipcp->conf.self_ippool));
        !           330:            ipcp->self_allow.width = 32;
        !           331:            ipcp->self_ippool_used = 1;
        !           332:        }
        !           333:     } else
        !           334:        ipcp->self_allow = ipcp->conf.self_allow;
        !           335: 
        !           336:     if ((b->params.range_valid) && (!u_rangeempty(&b->params.range)))
        !           337:        ipcp->peer_allow = b->params.range;
        !           338:     else if (b->params.ippool[0]) {
        !           339:        /* Get IP from pool if needed */
        !           340:        if (IPPoolGet(b->params.ippool, &ipcp->peer_allow.addr)) {
        !           341:            Log(LG_IPCP, ("[%s] IPCP: Can't get IP from pool \"%s\" for peer",
        !           342:                b->name, b->params.ippool));
        !           343:        } else {
        !           344:            Log(LG_IPCP, ("[%s] IPCP: Got IP %s from pool \"%s\" for peer",
        !           345:                b->name,
        !           346:                u_addrtoa(&ipcp->peer_allow.addr, buf, sizeof(buf)),
        !           347:                b->params.ippool));
        !           348:            ipcp->peer_allow.width = 32;
        !           349:            b->params.ippool_used = 1;
        !           350:        }
        !           351:     } else if (ipcp->conf.ippool[0]) {
        !           352:        if (IPPoolGet(ipcp->conf.ippool, &ipcp->peer_allow.addr)) {
        !           353:            Log(LG_IPCP, ("[%s] IPCP: Can't get IP from pool \"%s\"",
        !           354:                b->name, ipcp->conf.ippool));
        !           355:        } else {
        !           356:            Log(LG_IPCP, ("[%s] IPCP: Got IP %s from pool \"%s\" for peer",
        !           357:                b->name,
        !           358:                u_addrtoa(&ipcp->peer_allow.addr, buf, sizeof(buf)),
        !           359:                ipcp->conf.ippool));
        !           360:            ipcp->peer_allow.width = 32;
        !           361:            ipcp->ippool_used = 1;
        !           362:        }
        !           363:     } else
        !           364:        ipcp->peer_allow = ipcp->conf.peer_allow;
        !           365:     
        !           366:     /* Initially request addresses as specified by config */
        !           367:     u_addrtoin_addr(&ipcp->self_allow.addr, &ipcp->want_addr);
        !           368:     u_addrtoin_addr(&ipcp->peer_allow.addr, &ipcp->peer_addr);
        !           369: 
        !           370: #ifdef USE_NG_VJC
        !           371:     /* Van Jacobson compression */
        !           372:     ipcp->peer_comp.proto = 0;
        !           373:     ipcp->peer_comp.maxchan = IPCP_VJCOMP_DEFAULT_MAXCHAN;
        !           374:     ipcp->peer_comp.compcid = 0;
        !           375: 
        !           376:     ipcp->want_comp.proto =
        !           377:        (b->params.vjc_enable || Enabled(&ipcp->conf.options, IPCP_CONF_VJCOMP)) ?
        !           378:            htons(PROTO_VJCOMP) : 0;
        !           379:     ipcp->want_comp.maxchan = IPCP_VJCOMP_MAX_MAXCHAN;
        !           380: 
        !           381:     /* If any of our links are unable to give receive error indications, we must
        !           382:      tell the peer not to compress the slot-id in VJCOMP packets (cf. RFC1144).
        !           383:      To be on the safe side, we always say this. */
        !           384:     ipcp->want_comp.compcid = 0;
        !           385: #endif
        !           386: 
        !           387:     /* DNS and NBNS servers */
        !           388:     memset(&ipcp->want_dns, 0, sizeof(ipcp->want_dns));
        !           389:     memset(&ipcp->want_nbns, 0, sizeof(ipcp->want_nbns));
        !           390: }
        !           391: 
        !           392: /*
        !           393:  * IpcpUnConfigure()
        !           394:  */
        !           395: 
        !           396: static void
        !           397: IpcpUnConfigure(Fsm fp)
        !           398: {
        !           399:     Bund       b = (Bund)fp->arg;
        !           400:     IpcpState  const ipcp = &b->ipcp;
        !           401:   
        !           402:     if (ipcp->self_ippool_used) {
        !           403:        struct u_addr ip;
        !           404:        in_addrtou_addr(&ipcp->want_addr, &ip);
        !           405:        IPPoolFree(ipcp->conf.self_ippool, &ip);
        !           406:        ipcp->self_ippool_used = 0;
        !           407:     }
        !           408:     if (b->params.ippool_used) {
        !           409:        struct u_addr ip;
        !           410:        in_addrtou_addr(&ipcp->peer_addr, &ip);
        !           411:        IPPoolFree(b->params.ippool, &ip);
        !           412:        b->params.ippool_used = 0;
        !           413:     } else if (ipcp->ippool_used) {
        !           414:        struct u_addr ip;
        !           415:        in_addrtou_addr(&ipcp->peer_addr, &ip);
        !           416:        IPPoolFree(ipcp->conf.ippool, &ip);
        !           417:        ipcp->ippool_used = 0;
        !           418:     }
        !           419: }
        !           420: 
        !           421: /*
        !           422:  * IpcpBuildConfigReq()
        !           423:  */
        !           424: 
        !           425: static u_char *
        !           426: IpcpBuildConfigReq(Fsm fp, u_char *cp)
        !           427: {
        !           428:     Bund       b = (Bund)fp->arg;
        !           429:     IpcpState  const ipcp = &b->ipcp;
        !           430: 
        !           431:     /* Put in my desired IP address */
        !           432:     if (!IPCP_REJECTED(ipcp, TY_IPADDR) || ipcp->want_addr.s_addr == 0)
        !           433:        cp = FsmConfValue(cp, TY_IPADDR, 4, &ipcp->want_addr.s_addr);
        !           434: 
        !           435: #ifdef USE_NG_VJC
        !           436:     /* Put in my requested compression protocol */
        !           437:     if (ipcp->want_comp.proto != 0 && !IPCP_REJECTED(ipcp, TY_COMPPROTO))
        !           438:        cp = FsmConfValue(cp, TY_COMPPROTO, 4, &ipcp->want_comp);
        !           439: #endif
        !           440: 
        !           441:   /* Request peer's DNS and NBNS servers */
        !           442:   {
        !           443:     const int  sopts[2][2] = { { IPCP_CONF_REQPRIDNS, IPCP_CONF_REQSECDNS },
        !           444:                                { IPCP_CONF_REQPRINBNS, IPCP_CONF_REQSECNBNS }};
        !           445:     const int  nopts[2][2] = { { TY_PRIMARYDNS, TY_SECONDARYDNS }, 
        !           446:                                { TY_PRIMARYNBNS, TY_SECONDARYNBNS } };
        !           447:     struct in_addr     *vals[2] = { ipcp->want_dns, ipcp->want_nbns };
        !           448:     int                        sopt, pri;
        !           449: 
        !           450:     for (sopt = 0; sopt < 2; sopt++) {
        !           451:       for (pri = 0; pri < 2; pri++) {
        !           452:        const int       opt = nopts[sopt][pri];
        !           453: 
        !           454:        /* Add option if we desire it and it hasn't been rejected */
        !           455:        if (Enabled(&ipcp->conf.options, sopts[sopt][pri])
        !           456:            && !IPCP_REJECTED(ipcp, opt)) {
        !           457:          cp = FsmConfValue(cp, opt, 4, &vals[sopt][pri]);
        !           458:        }
        !           459:       }
        !           460:     }
        !           461:   }
        !           462: 
        !           463: /* Done */
        !           464: 
        !           465:   return(cp);
        !           466: }
        !           467: 
        !           468: /*
        !           469:  * IpcpLayerStart()
        !           470:  *
        !           471:  * Tell the lower layer (the bundle) that we need it
        !           472:  */
        !           473: 
        !           474: static void
        !           475: IpcpLayerStart(Fsm fp)
        !           476: {
        !           477:   BundNcpsStart((Bund)(fp->arg), NCP_IPCP);
        !           478: }
        !           479: 
        !           480: /*
        !           481:  * IpcpLayerFinish()
        !           482:  *
        !           483:  * Tell the lower layer (the bundle) that we no longer need it
        !           484:  */
        !           485: 
        !           486: static void
        !           487: IpcpLayerFinish(Fsm fp)
        !           488: {
        !           489:   BundNcpsFinish((Bund)(fp->arg), NCP_IPCP);
        !           490: }
        !           491: 
        !           492: /*
        !           493:  * IpcpLayerUp()
        !           494:  *
        !           495:  * Called when IPCP has reached the OPEN state
        !           496:  */
        !           497: 
        !           498: static void
        !           499: IpcpLayerUp(Fsm fp)
        !           500: {
        !           501:     Bund                       b = (Bund)fp->arg;
        !           502:     IpcpState                  const ipcp = &b->ipcp;
        !           503:     char                       ipbuf[20];
        !           504: #ifdef USE_NG_VJC
        !           505:     char                       path[NG_PATHSIZ];
        !           506:     struct ngm_vjc_config      vjc;
        !           507: #endif
        !           508:     struct u_addr              tmp;
        !           509: 
        !           510:     /* Determine actual address we'll use for ourselves */
        !           511:     in_addrtou_addr(&ipcp->want_addr, &tmp);
        !           512:     if (!IpAddrInRange(&ipcp->self_allow, &tmp)) {
        !           513:        Log(LG_IPCP, ("[%s]   Note: ignoring negotiated %s IP %s,",
        !           514:            b->name, "self", inet_ntoa(ipcp->want_addr)));
        !           515:        u_addrtoin_addr(&ipcp->self_allow.addr, &ipcp->want_addr);
        !           516:        Log(LG_IPCP, ("[%s]        using %s instead.",
        !           517:            b->name, inet_ntoa(ipcp->want_addr)));
        !           518:     }
        !           519: 
        !           520:     /* Determine actual address we'll use for peer */
        !           521:     in_addrtou_addr(&ipcp->peer_addr, &tmp);
        !           522:     if (!IpAddrInRange(&ipcp->peer_allow, &tmp)
        !           523:            && !u_addrempty(&ipcp->peer_allow.addr)) {
        !           524:        Log(LG_IPCP, ("[%s]   Note: ignoring negotiated %s IP %s,",
        !           525:            b->name, "peer", inet_ntoa(ipcp->peer_addr)));
        !           526:        u_addrtoin_addr(&ipcp->peer_allow.addr, &ipcp->peer_addr);
        !           527:        Log(LG_IPCP, ("[%s]        using %s instead.",
        !           528:            b->name, inet_ntoa(ipcp->peer_addr)));
        !           529:     }
        !           530: 
        !           531:     /* Report */
        !           532:     strlcpy(ipbuf, inet_ntoa(ipcp->peer_addr), sizeof(ipbuf));
        !           533:     Log(LG_IPCP, ("[%s]   %s -> %s", b->name, inet_ntoa(ipcp->want_addr), ipbuf));
        !           534: 
        !           535: #ifdef USE_NG_VJC
        !           536:     memset(&vjc, 0, sizeof(vjc));
        !           537:     if (ntohs(ipcp->peer_comp.proto) == PROTO_VJCOMP || 
        !           538:            ntohs(ipcp->want_comp.proto) == PROTO_VJCOMP) {
        !           539:   
        !           540:        IpcpNgInitVJ(b);
        !           541: 
        !           542:        /* Configure VJ compression node */
        !           543:        vjc.enableComp = ntohs(ipcp->peer_comp.proto) == PROTO_VJCOMP;
        !           544:        vjc.enableDecomp = ntohs(ipcp->want_comp.proto) == PROTO_VJCOMP;
        !           545:        vjc.maxChannel = ipcp->peer_comp.maxchan;
        !           546:        vjc.compressCID = ipcp->peer_comp.compcid;
        !           547:         snprintf(path, sizeof(path), "[%x]:%s", b->nodeID, NG_PPP_HOOK_VJC_IP);
        !           548:        if (NgSendMsg(gLinksCsock, path,
        !           549:                NGM_VJC_COOKIE, NGM_VJC_SET_CONFIG, &vjc, sizeof(vjc)) < 0) {
        !           550:            Perror("[%s] can't config %s node", b->name, NG_VJC_NODE_TYPE);
        !           551:        }
        !           552:     }
        !           553: #endif /* USE_NG_VJC */
        !           554: 
        !           555:     /* Enable IP packets in the PPP node */
        !           556:     b->pppConfig.bund.enableIP = 1;
        !           557: #ifdef USE_NG_VJC
        !           558:     b->pppConfig.bund.enableVJCompression = vjc.enableComp;
        !           559:     b->pppConfig.bund.enableVJDecompression = vjc.enableDecomp;
        !           560: #endif
        !           561:     NgFuncSetConfig(b);
        !           562: 
        !           563:     BundNcpsJoin(b, NCP_IPCP);
        !           564: }
        !           565: 
        !           566: /*
        !           567:  * IpcpLayerDown()
        !           568:  *
        !           569:  * Called when IPCP leaves the OPEN state
        !           570:  */
        !           571: 
        !           572: static void
        !           573: IpcpLayerDown(Fsm fp)
        !           574: {
        !           575:     Bund       b = (Bund)fp->arg;
        !           576: #ifdef USE_NG_VJC
        !           577:     IpcpState  const ipcp = &b->ipcp;
        !           578: #endif
        !           579: 
        !           580:     BundNcpsLeave(b, NCP_IPCP);
        !           581: 
        !           582:     /* Turn off IP packets */
        !           583:     b->pppConfig.bund.enableIP = 0;
        !           584: #ifdef USE_NG_VJC
        !           585:     b->pppConfig.bund.enableVJCompression = 0;
        !           586:     b->pppConfig.bund.enableVJDecompression = 0;
        !           587: #endif
        !           588:     NgFuncSetConfig(b);
        !           589: 
        !           590: #ifdef USE_NG_VJC
        !           591:     if (ntohs(ipcp->peer_comp.proto) == PROTO_VJCOMP || 
        !           592:            ntohs(ipcp->want_comp.proto) == PROTO_VJCOMP) {
        !           593:        IpcpNgShutdownVJ(b);
        !           594:     }
        !           595: #endif /* USE_NG_VJC */
        !           596: }
        !           597: 
        !           598: /*
        !           599:  * IpcpUp()
        !           600:  */
        !           601: 
        !           602: void
        !           603: IpcpUp(Bund b)
        !           604: {
        !           605:     FsmUp(&b->ipcp.fsm);
        !           606: }
        !           607: 
        !           608: /*
        !           609:  * IpcpDown()
        !           610:  */
        !           611: 
        !           612: void
        !           613: IpcpDown(Bund b)
        !           614: {
        !           615:     FsmDown(&b->ipcp.fsm);
        !           616: }
        !           617: 
        !           618: /*
        !           619:  * IpcpOpen()
        !           620:  */
        !           621: 
        !           622: void
        !           623: IpcpOpen(Bund b)
        !           624: {
        !           625:     FsmOpen(&b->ipcp.fsm);
        !           626: }
        !           627: 
        !           628: /*
        !           629:  * IpcpClose()
        !           630:  */
        !           631: 
        !           632: void
        !           633: IpcpClose(Bund b)
        !           634: {
        !           635:     FsmClose(&b->ipcp.fsm);
        !           636: }
        !           637: 
        !           638: /*
        !           639:  * IpcpOpenCmd()
        !           640:  */
        !           641: 
        !           642: int
        !           643: IpcpOpenCmd(Context ctx)
        !           644: {
        !           645:     if (ctx->bund->tmpl)
        !           646:        Error("impossible to open template");
        !           647:     FsmOpen(&ctx->bund->ipcp.fsm);
        !           648:     return (0);
        !           649: }
        !           650: 
        !           651: /*
        !           652:  * IpcpCloseCmd()
        !           653:  */
        !           654: 
        !           655: int
        !           656: IpcpCloseCmd(Context ctx)
        !           657: {
        !           658:     if (ctx->bund->tmpl)
        !           659:        Error("impossible to close template");
        !           660:     FsmClose(&ctx->bund->ipcp.fsm);
        !           661:     return (0);
        !           662: }
        !           663: 
        !           664: /*
        !           665:  * IpcpFailure()
        !           666:  */
        !           667: 
        !           668: static void
        !           669: IpcpFailure(Fsm fp, enum fsmfail reason)
        !           670: {
        !           671:     Bund       b = (Bund)fp->arg;
        !           672:     RecordLinkUpDownReason(b, NULL, 0, STR_PROTO_ERR, STR_IPCP_FAILED, FsmFailureStr(reason));
        !           673: }
        !           674: 
        !           675: /*
        !           676:  * IpcpDecodeConfig()
        !           677:  */
        !           678: 
        !           679: static void
        !           680: IpcpDecodeConfig(Fsm fp, FsmOption list, int num, int mode)
        !           681: {
        !           682:     Bund       b = (Bund)fp->arg;
        !           683:   IpcpState            const ipcp = &b->ipcp;
        !           684:   struct in_addr       *wantip, *peerip;
        !           685:   int                  k;
        !           686: 
        !           687:   /* Decode each config option */
        !           688:   for (k = 0; k < num; k++) {
        !           689:     FsmOption  const opt = &list[k];
        !           690:     FsmOptInfo const oi = FsmFindOptInfo(gIpcpConfOpts, opt->type);
        !           691: 
        !           692:     if (!oi) {
        !           693:       Log(LG_IPCP, ("[%s]   UNKNOWN[%d] len=%d", b->name, opt->type, opt->len));
        !           694:       if (mode == MODE_REQ)
        !           695:        FsmRej(fp, opt);
        !           696:       continue;
        !           697:     }
        !           698:     if (!oi->supported) {
        !           699:       Log(LG_IPCP, ("[%s]   %s", b->name, oi->name));
        !           700:       if (mode == MODE_REQ) {
        !           701:        Log(LG_IPCP, ("[%s]     Not supported", b->name));
        !           702:        FsmRej(fp, opt);
        !           703:       }
        !           704:       continue;
        !           705:     }
        !           706:     if (opt->len < oi->minLen + 2 || opt->len > oi->maxLen + 2) {
        !           707:       Log(LG_IPCP, ("[%s]   %s", b->name, oi->name));
        !           708:       if (mode == MODE_REQ) {
        !           709:        Log(LG_IPCP, ("[%s]     bogus len=%d", b->name, opt->len));
        !           710:        FsmRej(fp, opt);
        !           711:       }
        !           712:       continue;
        !           713:     }
        !           714:     switch (opt->type) {
        !           715:       case TY_IPADDR:
        !           716:        {
        !           717:          struct in_addr        ip;
        !           718:          struct u_addr         tmp;
        !           719: 
        !           720:          memcpy(&ip, opt->data, 4);
        !           721:          in_addrtou_addr(&ip, &tmp);
        !           722:          Log(LG_IPCP, ("[%s]   %s %s", b->name, oi->name, inet_ntoa(ip)));
        !           723:          switch (mode) {
        !           724:            case MODE_REQ:
        !           725:              if (!IpAddrInRange(&ipcp->peer_allow, &tmp) || !ip.s_addr) {
        !           726:                if (ipcp->peer_addr.s_addr == 0)
        !           727:                  Log(LG_IPCP, ("[%s]     no IP address available for peer!", b->name));
        !           728:                if (Enabled(&ipcp->conf.options, IPCP_CONF_PRETENDIP)) {
        !           729:                  Log(LG_IPCP, ("[%s]     pretending that %s is OK, will ignore",
        !           730:                      b->name, inet_ntoa(ip)));
        !           731:                  ipcp->peer_addr = ip;
        !           732:                  FsmAck(fp, opt);
        !           733:                  break;
        !           734:                }
        !           735:                memcpy(opt->data, &ipcp->peer_addr, 4);
        !           736:                Log(LG_IPCP, ("[%s]     NAKing with %s", b->name, inet_ntoa(ipcp->peer_addr)));
        !           737:                FsmNak(fp, opt);
        !           738:                break;
        !           739:              }
        !           740:              Log(LG_IPCP, ("[%s]     %s is OK", b->name, inet_ntoa(ip)));
        !           741:              ipcp->peer_addr = ip;
        !           742:              FsmAck(fp, opt);
        !           743:              break;
        !           744:            case MODE_NAK:
        !           745:              {
        !           746:                if (IpAddrInRange(&ipcp->self_allow, &tmp)) {
        !           747:                  Log(LG_IPCP, ("[%s]     %s is OK", b->name, inet_ntoa(ip)));
        !           748:                  ipcp->want_addr = ip;
        !           749:                } else if (Enabled(&ipcp->conf.options, IPCP_CONF_PRETENDIP)) {
        !           750:                  Log(LG_IPCP, ("[%s]     pretending that %s is OK, will ignore",
        !           751:                      b->name, inet_ntoa(ip)));
        !           752:                  ipcp->want_addr = ip;
        !           753:                } else
        !           754:                  Log(LG_IPCP, ("[%s]     %s is unacceptable", b->name, inet_ntoa(ip)));
        !           755:              }
        !           756:              break;
        !           757:            case MODE_REJ:
        !           758:              IPCP_PEER_REJ(ipcp, opt->type);
        !           759:              if (ipcp->want_addr.s_addr == 0)
        !           760:                Log(LG_IPCP, ("[%s]     Problem: I need an IP address!", b->name));
        !           761:              break;
        !           762:          }
        !           763:        }
        !           764:        break;
        !           765: 
        !           766: #ifdef USE_NG_VJC
        !           767:       case TY_COMPPROTO:
        !           768:        {
        !           769:          struct ipcpvjcomp     vj;
        !           770: 
        !           771:          memcpy(&vj, opt->data, sizeof(vj));
        !           772:          Log(LG_IPCP, ("[%s]   %s %s, %d comp. channels, %s comp-cid",
        !           773:            b->name, oi->name, ProtoName(ntohs(vj.proto)),
        !           774:            vj.maxchan + 1, vj.compcid ? "allow" : "no"));
        !           775:          switch (mode) {
        !           776:            case MODE_REQ:
        !           777:              if (!Acceptable(&ipcp->conf.options, IPCP_CONF_VJCOMP) && 
        !           778:                  !b->params.vjc_enable) {
        !           779:                FsmRej(fp, opt);
        !           780:                break;
        !           781:              }
        !           782:              if (ntohs(vj.proto) == PROTO_VJCOMP
        !           783:                  && vj.maxchan <= IPCP_VJCOMP_MAX_MAXCHAN
        !           784:                  && vj.maxchan >= IPCP_VJCOMP_MIN_MAXCHAN) {
        !           785:                ipcp->peer_comp = vj;
        !           786:                FsmAck(fp, opt);
        !           787:                break;
        !           788:              }
        !           789:              vj.proto = htons(PROTO_VJCOMP);
        !           790:              vj.maxchan = IPCP_VJCOMP_MAX_MAXCHAN;
        !           791:              vj.compcid = 0;
        !           792:              memcpy(opt->data, &vj, sizeof(vj));
        !           793:              FsmNak(fp, opt);
        !           794:              break;
        !           795:            case MODE_NAK:
        !           796:              if (ntohs(vj.proto) != PROTO_VJCOMP) {
        !           797:                Log(LG_IPCP, ("[%s]     Can't accept proto 0x%04x",
        !           798:                  b->name, (u_short) ntohs(vj.proto)));
        !           799:                break;
        !           800:              }
        !           801:              if (vj.maxchan != ipcp->want_comp.maxchan) {
        !           802:                if (vj.maxchan <= IPCP_VJCOMP_MAX_MAXCHAN
        !           803:                    && vj.maxchan >= IPCP_VJCOMP_MIN_MAXCHAN) {
        !           804:                  Log(LG_IPCP, ("[%s]     Adjusting # compression channels", b->name));
        !           805:                  ipcp->want_comp.maxchan = vj.maxchan;
        !           806:                } else {
        !           807:                  Log(LG_IPCP, ("[%s]     Can't handle %d maxchan", b->name, vj.maxchan));
        !           808:                }
        !           809:              }
        !           810:              if (vj.compcid) {
        !           811:                Log(LG_IPCP, ("[%s]     Can't accept comp-cid", b->name));
        !           812:                break;
        !           813:              }
        !           814:              break;
        !           815:            case MODE_REJ:
        !           816:              IPCP_PEER_REJ(ipcp, opt->type);
        !           817:              ipcp->want_comp.proto = 0;
        !           818:              break;
        !           819:          }
        !           820:        }
        !           821:        break;
        !           822: #endif /* USE_NG_VJC */
        !           823: 
        !           824:       case TY_PRIMARYDNS:
        !           825:         if (b->params.peer_dns[0].s_addr != 0)
        !           826:            peerip = &b->params.peer_dns[0];
        !           827:        else
        !           828:            peerip = &ipcp->conf.peer_dns[0];
        !           829:        wantip = &ipcp->want_dns[0];
        !           830:        goto doDnsNbns;
        !           831:       case TY_PRIMARYNBNS:
        !           832:         if (b->params.peer_nbns[0].s_addr != 0)
        !           833:            peerip = &b->params.peer_nbns[0];
        !           834:        else
        !           835:            peerip = &ipcp->conf.peer_nbns[0];
        !           836:        wantip = &ipcp->want_nbns[0];
        !           837:        goto doDnsNbns;
        !           838:       case TY_SECONDARYDNS:
        !           839:         if (b->params.peer_dns[1].s_addr != 0)
        !           840:            peerip = &b->params.peer_dns[1];
        !           841:        else
        !           842:            peerip = &ipcp->conf.peer_dns[1];
        !           843:        wantip = &ipcp->want_dns[1];
        !           844:        goto doDnsNbns;
        !           845:       case TY_SECONDARYNBNS:
        !           846:         if (b->params.peer_nbns[1].s_addr != 0)
        !           847:            peerip = &b->params.peer_nbns[1];
        !           848:        else
        !           849:            peerip = &ipcp->conf.peer_nbns[1];
        !           850:        wantip = &ipcp->want_nbns[1];
        !           851: doDnsNbns:
        !           852:        {
        !           853:          struct in_addr        hisip;
        !           854: 
        !           855:          memcpy(&hisip, opt->data, 4);
        !           856:          Log(LG_IPCP, ("[%s]   %s %s", b->name, oi->name, inet_ntoa(hisip)));
        !           857:          switch (mode) {
        !           858:            case MODE_REQ:
        !           859:              if (hisip.s_addr == 0) {          /* he's asking for one */
        !           860:                if (peerip->s_addr == 0) {      /* we don't got one */
        !           861:                  FsmRej(fp, opt);
        !           862:                  break;
        !           863:                }
        !           864:                Log(LG_IPCP, ("[%s]     NAKing with %s", b->name, inet_ntoa(*peerip)));
        !           865:                memcpy(opt->data, peerip, sizeof(*peerip));
        !           866:                FsmNak(fp, opt);                /* we got one for him */
        !           867:                break;
        !           868:              }
        !           869:              FsmAck(fp, opt);                  /* he knows what he wants */
        !           870:              break;
        !           871:            case MODE_NAK:      /* we asked for his server, he's telling us */
        !           872:              *wantip = hisip;
        !           873:              break;
        !           874:            case MODE_REJ:      /* we asked for his server, he's ignorant */
        !           875:              IPCP_PEER_REJ(ipcp, opt->type);
        !           876:              break;
        !           877:          }
        !           878:        }
        !           879:        break;
        !           880: 
        !           881:       default:
        !           882:        assert(0);
        !           883:     }
        !           884:   }
        !           885: }
        !           886: 
        !           887: /*
        !           888:  * IpcpInput()
        !           889:  *
        !           890:  * Deal with an incoming IPCP packet
        !           891:  */
        !           892: 
        !           893: void
        !           894: IpcpInput(Bund b, Mbuf bp)
        !           895: {
        !           896:     FsmInput(&b->ipcp.fsm, bp);
        !           897: }
        !           898: 
        !           899: #ifdef USE_NG_VJC
        !           900: static int
        !           901: IpcpNgInitVJ(Bund b)
        !           902: {
        !           903:   struct ngm_mkpeer    mp;
        !           904:   struct ngm_connect   cn;
        !           905:   char path[NG_PATHSIZ];
        !           906:   struct ngm_name      nm;
        !           907: 
        !           908:   /* Add a VJ compression node */
        !           909:   snprintf(path, sizeof(path), "[%x]:", b->nodeID);
        !           910:   strcpy(mp.type, NG_VJC_NODE_TYPE);
        !           911:   strcpy(mp.ourhook, NG_PPP_HOOK_VJC_IP);
        !           912:   strcpy(mp.peerhook, NG_VJC_HOOK_IP);
        !           913:   if (NgSendMsg(gLinksCsock, path,
        !           914:       NGM_GENERIC_COOKIE, NGM_MKPEER, &mp, sizeof(mp)) < 0) {
        !           915:     Perror("[%s] can't create %s node at \"%s\"->\"%s\"",
        !           916:       b->name, NG_VJC_NODE_TYPE, path, mp.ourhook);
        !           917:     goto fail;
        !           918:   }
        !           919: 
        !           920:   /* Give it a name */
        !           921:   strlcat(path, NG_PPP_HOOK_VJC_IP, sizeof(path));
        !           922:   snprintf(nm.name, sizeof(nm.name), "mpd%d-%s-vjc", gPid, b->name);
        !           923:   if (NgSendMsg(gLinksCsock, path,
        !           924:       NGM_GENERIC_COOKIE, NGM_NAME, &nm, sizeof(nm)) < 0) {
        !           925:     Perror("[%s] can't name %s node", b->name, NG_VJC_NODE_TYPE);
        !           926:     goto fail;
        !           927:   }
        !           928: 
        !           929:   /* Connect the other three hooks between the ppp and vjc nodes */
        !           930:   snprintf(path, sizeof(path), "[%x]:", b->nodeID);
        !           931:   strcpy(cn.path, NG_PPP_HOOK_VJC_IP);
        !           932:   strcpy(cn.ourhook, NG_PPP_HOOK_VJC_COMP);
        !           933:   strcpy(cn.peerhook, NG_VJC_HOOK_VJCOMP);
        !           934:   if (NgSendMsg(gLinksCsock, path,
        !           935:       NGM_GENERIC_COOKIE, NGM_CONNECT, &cn, sizeof(cn)) < 0) {
        !           936:     Perror("[%s] can't connect \"%s\"->\"%s\" and \"%s\"->\"%s\"",
        !           937:       b->name, path, cn.ourhook, cn.path, cn.peerhook);
        !           938:     goto fail;
        !           939:   }
        !           940:   strcpy(cn.ourhook, NG_PPP_HOOK_VJC_UNCOMP);
        !           941:   strcpy(cn.peerhook, NG_VJC_HOOK_VJUNCOMP);
        !           942:   if (NgSendMsg(gLinksCsock, path,
        !           943:       NGM_GENERIC_COOKIE, NGM_CONNECT, &cn, sizeof(cn)) < 0) {
        !           944:     Perror("[%s] can't connect \"%s\"->\"%s\" and \"%s\"->\"%s\"",
        !           945:       b->name, path, cn.ourhook, cn.path, cn.peerhook);
        !           946:     goto fail;
        !           947:   }
        !           948:   strcpy(cn.ourhook, NG_PPP_HOOK_VJC_VJIP);
        !           949:   strcpy(cn.peerhook, NG_VJC_HOOK_VJIP);
        !           950:   if (NgSendMsg(gLinksCsock, path,
        !           951:       NGM_GENERIC_COOKIE, NGM_CONNECT, &cn, sizeof(cn)) < 0) {
        !           952:     Perror("[%s] can't connect \"%s\"->\"%s\" and \"%s\"->\"%s\"",
        !           953:       b->name, path, cn.ourhook, cn.path, cn.peerhook);
        !           954:     goto fail;
        !           955:   }
        !           956: 
        !           957:     return 0;
        !           958: fail:
        !           959:     return -1;
        !           960: }
        !           961: 
        !           962: static void
        !           963: IpcpNgShutdownVJ(Bund b)
        !           964: {
        !           965:     char       path[NG_PATHSIZ];
        !           966: 
        !           967:     snprintf(path, sizeof(path), "[%x]:%s", b->nodeID, NG_PPP_HOOK_VJC_IP);
        !           968:     NgFuncShutdownNode(gLinksCsock, b->name, path);
        !           969: }
        !           970: #endif /* USE_NG_VJC */
        !           971: 
        !           972: /*
        !           973:  * IpcpSetCommand()
        !           974:  */
        !           975: 
        !           976: static int
        !           977: IpcpSetCommand(Context ctx, int ac, char *av[], void *arg)
        !           978: {
        !           979:   IpcpState            const ipcp = &ctx->bund->ipcp;
        !           980:   struct in_addr       *ips;
        !           981: 
        !           982:   if (ac == 0)
        !           983:     return(-1);
        !           984:   switch ((intptr_t)arg) {
        !           985:     case SET_RANGES:
        !           986:       {
        !           987:        struct u_range  self_new_allow;
        !           988:        struct u_range  peer_new_allow;
        !           989:        int pos = 0, self_new_pool = -1, peer_new_pool = -1;
        !           990: 
        !           991:        /* Parse args */
        !           992:        if (ac < 2)
        !           993:            return (-1);
        !           994:        if (strcmp(av[pos], "ippool") == 0) {
        !           995:            self_new_pool = pos+1;
        !           996:            pos+=2;
        !           997:        } else {
        !           998:            if (!ParseRange(av[pos], &self_new_allow, ALLOW_IPV4))
        !           999:                return(-1);
        !          1000:            pos++;
        !          1001:        }
        !          1002:        if (pos >= ac)
        !          1003:            return (-1);
        !          1004:        if (strcmp(av[pos], "ippool") == 0) {
        !          1005:            if ((pos + 1) >= ac)
        !          1006:                return (-1);
        !          1007:            peer_new_pool = pos+1;
        !          1008:            pos+=2;
        !          1009:        } else {
        !          1010:            if (!ParseRange(av[pos], &peer_new_allow, ALLOW_IPV4))
        !          1011:                return(-1);
        !          1012:            pos++;
        !          1013:        }
        !          1014:        if (pos != ac)
        !          1015:            return (-1);
        !          1016: 
        !          1017:        if (self_new_pool >= 0)
        !          1018:            strlcpy(ipcp->conf.self_ippool, av[self_new_pool], sizeof(ipcp->conf.self_ippool));
        !          1019:        else
        !          1020:            ipcp->conf.self_ippool[0] = 0;
        !          1021:        if (peer_new_pool >= 0)
        !          1022:            strlcpy(ipcp->conf.ippool, av[peer_new_pool], sizeof(ipcp->conf.ippool));
        !          1023:        else
        !          1024:            ipcp->conf.ippool[0] = 0;
        !          1025:        ipcp->conf.self_allow = self_new_allow;
        !          1026:        ipcp->conf.peer_allow = peer_new_allow;
        !          1027: 
        !          1028:       }
        !          1029:       break;
        !          1030: 
        !          1031:     case SET_DNS:
        !          1032:       ips = ipcp->conf.peer_dns;
        !          1033:       goto getPrimSec;
        !          1034:       break;
        !          1035:     case SET_NBNS:
        !          1036:       ips = ipcp->conf.peer_nbns;
        !          1037: getPrimSec:
        !          1038:       if (!inet_aton(av[0], &ips[0]))
        !          1039:        Error("invalid IP address: \'%s\'", av[0]);
        !          1040:       ips[1].s_addr = 0;
        !          1041:       if (ac > 1 && !inet_aton(av[1], &ips[1]))
        !          1042:        Error("invalid IP address: \'%s\'", av[1]);
        !          1043:       break;
        !          1044: 
        !          1045:     case SET_ACCEPT:
        !          1046:       AcceptCommand(ac, av, &ipcp->conf.options, gConfList);
        !          1047:       break;
        !          1048: 
        !          1049:     case SET_DENY:
        !          1050:       DenyCommand(ac, av, &ipcp->conf.options, gConfList);
        !          1051:       break;
        !          1052: 
        !          1053:     case SET_ENABLE:
        !          1054:       EnableCommand(ac, av, &ipcp->conf.options, gConfList);
        !          1055:       break;
        !          1056: 
        !          1057:     case SET_DISABLE:
        !          1058:       DisableCommand(ac, av, &ipcp->conf.options, gConfList);
        !          1059:       break;
        !          1060: 
        !          1061:     case SET_YES:
        !          1062:       YesCommand(ac, av, &ipcp->conf.options, gConfList);
        !          1063:       break;
        !          1064: 
        !          1065:     case SET_NO:
        !          1066:       NoCommand(ac, av, &ipcp->conf.options, gConfList);
        !          1067:       break;
        !          1068: 
        !          1069:     default:
        !          1070:       assert(0);
        !          1071:   }
        !          1072:   return(0);
        !          1073: }
        !          1074: 

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