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

1.1     ! misho       1: 
        !             2: /*
        !             3:  * ipv6cp.c
        !             4:  *
        !             5:  * Written by Alexander Motin <mav@FreeBSD.org>
        !             6:  */
        !             7: 
        !             8: #include "ppp.h"
        !             9: #include "ipv6cp.h"
        !            10: #include "fsm.h"
        !            11: #include "ip.h"
        !            12: #include "iface.h"
        !            13: #include "msg.h"
        !            14: #include "ngfunc.h"
        !            15: #include "util.h"
        !            16: 
        !            17: #include <netgraph.h>
        !            18: #include <sys/mbuf.h>
        !            19: 
        !            20: /*
        !            21:  * DEFINITIONS
        !            22:  */
        !            23: 
        !            24:   #define IPV6CP_KNOWN_CODES   (   (1 << CODE_CONFIGREQ)       \
        !            25:                                  | (1 << CODE_CONFIGACK)       \
        !            26:                                  | (1 << CODE_CONFIGNAK)       \
        !            27:                                  | (1 << CODE_CONFIGREJ)       \
        !            28:                                  | (1 << CODE_TERMREQ)         \
        !            29:                                  | (1 << CODE_TERMACK)         \
        !            30:                                  | (1 << CODE_CODEREJ)         )
        !            31: 
        !            32:   #define TY_INTIDENT          1
        !            33:   #define TY_COMPPROTO         2
        !            34: 
        !            35:   #define IPV6CP_REJECTED(p,x) ((p)->peer_reject & (1<<(x)))
        !            36:   #define IPV6CP_PEER_REJ(p,x) do{(p)->peer_reject |= (1<<(x));}while(0)
        !            37: 
        !            38:   #define IPV6CP_VJCOMP_MIN_MAXCHAN    (NG_VJC_MIN_CHANNELS - 1)
        !            39:   #define IPV6CP_VJCOMP_MAX_MAXCHAN    (NG_VJC_MAX_CHANNELS - 1)
        !            40:   #define IPV6CP_VJCOMP_DEFAULT_MAXCHAN        IPV6CP_VJCOMP_MAX_MAXCHAN
        !            41: 
        !            42:   /* Set menu options */
        !            43:   enum {
        !            44:     SET_ENABLE,
        !            45:     SET_DISABLE,
        !            46:     SET_ACCEPT,
        !            47:     SET_DENY,
        !            48:     SET_YES,
        !            49:     SET_NO
        !            50:   };
        !            51: 
        !            52: /*
        !            53:  * INTERNAL FUNCTIONS
        !            54:  */
        !            55: 
        !            56:   static void  Ipv6cpConfigure(Fsm fp);
        !            57:   static void  Ipv6cpUnConfigure(Fsm fp);
        !            58: 
        !            59:   static u_char        *Ipv6cpBuildConfigReq(Fsm fp, u_char *cp);
        !            60:   static void  Ipv6cpDecodeConfig(Fsm fp, FsmOption list, int num, int mode);
        !            61:   static void  Ipv6cpLayerStart(Fsm fp);
        !            62:   static void  Ipv6cpLayerFinish(Fsm fp);
        !            63:   static void  Ipv6cpLayerUp(Fsm fp);
        !            64:   static void  Ipv6cpLayerDown(Fsm fp);
        !            65:   static void  Ipv6cpFailure(Fsm fp, enum fsmfail reason);
        !            66: 
        !            67:   static int   Ipv6cpSetCommand(Context ctx, int ac, char *av[], void *arg);
        !            68: 
        !            69:   void                 CreateInterfaceID(u_char *intid, int random);
        !            70: /*
        !            71:  * GLOBAL VARIABLES
        !            72:  */
        !            73: 
        !            74:   const struct cmdtab Ipv6cpSetCmds[] = {
        !            75:     { "enable [opt ...]",              "Enable option",
        !            76:        Ipv6cpSetCommand, NULL, 2, (void *) SET_ENABLE},
        !            77:     { "disable [opt ...]",             "Disable option",
        !            78:        Ipv6cpSetCommand, NULL, 2, (void *) SET_DISABLE},
        !            79:     { "accept [opt ...]",              "Accept option",
        !            80:        Ipv6cpSetCommand, NULL, 2, (void *) SET_ACCEPT},
        !            81:     { "deny [opt ...]",                        "Deny option",
        !            82:        Ipv6cpSetCommand, NULL, 2, (void *) SET_DENY},
        !            83:     { "yes [opt ...]",                 "Enable and accept option",
        !            84:        Ipv6cpSetCommand, NULL, 2, (void *) SET_YES},
        !            85:     { "no [opt ...]",                  "Disable and deny option",
        !            86:        Ipv6cpSetCommand, NULL, 2, (void *) SET_NO},
        !            87:     { NULL },
        !            88:   };
        !            89: 
        !            90: /*
        !            91:  * INTERNAL VARIABLES
        !            92:  */
        !            93: 
        !            94:   static const struct fsmoptinfo       gIpv6cpConfOpts[] = {
        !            95:     { "INTIDENT",      TY_INTIDENT,            8, 8, TRUE },
        !            96:     { "COMPPROTO",     TY_COMPPROTO,           4, 4, FALSE },
        !            97:     { NULL }
        !            98:   };
        !            99: 
        !           100:   static const struct confinfo gConfList[] = {
        !           101: /*    { 1,     IPV6CP_CONF_VJCOMP,     "vjcomp"        },*/
        !           102:     { 0,       0,                      NULL            },
        !           103:   };
        !           104: 
        !           105:   static const struct fsmtype gIpv6cpFsmType = {
        !           106:     "IPV6CP",
        !           107:     PROTO_IPV6CP,
        !           108:     IPV6CP_KNOWN_CODES,
        !           109:     FALSE,
        !           110:     LG_IPV6CP, LG_IPV6CP2,
        !           111:     NULL,
        !           112:     Ipv6cpLayerUp,
        !           113:     Ipv6cpLayerDown,
        !           114:     Ipv6cpLayerStart,
        !           115:     Ipv6cpLayerFinish,
        !           116:     Ipv6cpBuildConfigReq,
        !           117:     Ipv6cpDecodeConfig,
        !           118:     Ipv6cpConfigure,
        !           119:     Ipv6cpUnConfigure,
        !           120:     NULL,
        !           121:     NULL,
        !           122:     NULL,
        !           123:     NULL,
        !           124:     Ipv6cpFailure,
        !           125:     NULL,
        !           126:     NULL,
        !           127:     NULL,
        !           128:   };
        !           129: 
        !           130: /*
        !           131:  * Ipv6cpStat()
        !           132:  */
        !           133: 
        !           134: int
        !           135: Ipv6cpStat(Context ctx, int ac, char *av[], void *arg)
        !           136: {
        !           137:   Ipv6cpState          const ipv6cp = &ctx->bund->ipv6cp;
        !           138:   Fsm                  fp = &ipv6cp->fsm;
        !           139: 
        !           140:   Printf("[%s] %s [%s]\r\n", Pref(fp), Fsm(fp), FsmStateName(fp->state));
        !           141:   Printf("Interface identificators:\r\n");
        !           142:   Printf("\tSelf: %02x%02x:%02x%02x:%02x%02x:%02x%02x\r\n",
        !           143:     ipv6cp->myintid[0], ipv6cp->myintid[1], ipv6cp->myintid[2], ipv6cp->myintid[3],
        !           144:     ipv6cp->myintid[4], ipv6cp->myintid[5], ipv6cp->myintid[6], ipv6cp->myintid[7]);
        !           145:   Printf("\tPeer: %02x%02x:%02x%02x:%02x%02x:%02x%02x\r\n",
        !           146:     ipv6cp->hisintid[0], ipv6cp->hisintid[1], ipv6cp->hisintid[2], ipv6cp->hisintid[3],
        !           147:     ipv6cp->hisintid[4], ipv6cp->hisintid[5], ipv6cp->hisintid[6], ipv6cp->hisintid[7]);
        !           148:   Printf("IPV6CP Options:\r\n");
        !           149:   OptStat(ctx, &ipv6cp->conf.options, gConfList);
        !           150: 
        !           151:   return(0);
        !           152: }
        !           153: 
        !           154: /*
        !           155:  * CreateInterfaceID()
        !           156:  */
        !           157: 
        !           158: void
        !           159: CreateInterfaceID(u_char *intid, int r)
        !           160: {
        !           161:     struct sockaddr_dl hwaddr;
        !           162:     u_char     *ether;
        !           163: 
        !           164:     if (!r) {
        !           165:        if (!GetEther(NULL, &hwaddr)) {
        !           166:            ether = (u_char *) LLADDR(&hwaddr);
        !           167:            intid[0]=ether[0] ^ 0x02; /* reverse the u/l bit*/
        !           168:            intid[1]=ether[1];
        !           169:            intid[2]=ether[2];
        !           170:            intid[3]=0xff;
        !           171:            intid[4]=0xfe;
        !           172:            intid[5]=ether[3];
        !           173:            intid[6]=ether[4];
        !           174:            intid[7]=ether[5];
        !           175:            return;
        !           176:        }
        !           177:     }
        !           178: 
        !           179:     srandomdev();
        !           180:     ((u_int32_t*)intid)[0]=(((u_int32_t)random()) % 0xFFFFFFFF) + 1;
        !           181:     ((u_int32_t*)intid)[1]=(((u_int32_t)random()) % 0xFFFFFFFF) + 1;
        !           182:     intid[0] &= 0xfd;
        !           183: 
        !           184: }
        !           185: 
        !           186: /*
        !           187:  * Ipv6cpInit()
        !           188:  */
        !           189: 
        !           190: void
        !           191: Ipv6cpInit(Bund b)
        !           192: {
        !           193:   Ipv6cpState  ipv6cp = &b->ipv6cp;
        !           194: 
        !           195:   /* Init state machine */
        !           196:   memset(ipv6cp, 0, sizeof(*ipv6cp));
        !           197:   FsmInit(&ipv6cp->fsm, &gIpv6cpFsmType, b);
        !           198: 
        !           199:   CreateInterfaceID(ipv6cp->myintid,0);
        !           200: 
        !           201: }
        !           202: 
        !           203: /*
        !           204:  * Ipv6cpInst()
        !           205:  */
        !           206: 
        !           207: void
        !           208: Ipv6cpInst(Bund b, Bund bt)
        !           209: {
        !           210:   Ipv6cpState  ipv6cp = &b->ipv6cp;
        !           211: 
        !           212:   /* Init state machine */
        !           213:   memcpy(ipv6cp, &bt->ipv6cp, sizeof(*ipv6cp));
        !           214:   FsmInst(&ipv6cp->fsm, &bt->ipv6cp.fsm, b);
        !           215: }
        !           216: 
        !           217: /*
        !           218:  * Ipv6cpConfigure()
        !           219:  */
        !           220: 
        !           221: static void
        !           222: Ipv6cpConfigure(Fsm fp)
        !           223: {
        !           224:     Bund       b = (Bund)fp->arg;
        !           225:   Ipv6cpState  const ipv6cp = &b->ipv6cp;
        !           226: 
        !           227:   /* FSM stuff */
        !           228:   ipv6cp->peer_reject = 0;
        !           229: 
        !           230: }
        !           231: 
        !           232: /*
        !           233:  * Ipv6cpUnConfigure()
        !           234:  */
        !           235: 
        !           236: static void
        !           237: Ipv6cpUnConfigure(Fsm fp)
        !           238: {
        !           239: }
        !           240: 
        !           241: /*
        !           242:  * Ipv6cpBuildConfigReq()
        !           243:  */
        !           244: 
        !           245: static u_char *
        !           246: Ipv6cpBuildConfigReq(Fsm fp, u_char *cp)
        !           247: {
        !           248:     Bund       b = (Bund)fp->arg;
        !           249:   Ipv6cpState  const ipv6cp = &b->ipv6cp;
        !           250: 
        !           251:   cp = FsmConfValue(cp, TY_INTIDENT, 8, ipv6cp->myintid);
        !           252: 
        !           253: /* Done */
        !           254: 
        !           255:   return(cp);
        !           256: }
        !           257: 
        !           258: /*
        !           259:  * Ipv6cpLayerStart()
        !           260:  *
        !           261:  * Tell the lower layer (the bundle) that we need it
        !           262:  */
        !           263: 
        !           264: static void
        !           265: Ipv6cpLayerStart(Fsm fp)
        !           266: {
        !           267:     BundNcpsStart((Bund)(fp->arg), NCP_IPV6CP);
        !           268: }
        !           269: 
        !           270: /*
        !           271:  * Ipv6cpLayerFinish()
        !           272:  *
        !           273:  * Tell the lower layer (the bundle) that we no longer need it
        !           274:  */
        !           275: 
        !           276: static void
        !           277: Ipv6cpLayerFinish(Fsm fp)
        !           278: {
        !           279:     BundNcpsFinish((Bund)(fp->arg), NCP_IPV6CP);
        !           280: }
        !           281: 
        !           282: /*
        !           283:  * Ipv6cpLayerUp()
        !           284:  *
        !           285:  * Called when IPV6CP has reached the OPEN state
        !           286:  */
        !           287: 
        !           288: static void
        !           289: Ipv6cpLayerUp(Fsm fp)
        !           290: {
        !           291:     Bund       b = (Bund)fp->arg;
        !           292:     Ipv6cpState                const ipv6cp = &b->ipv6cp;
        !           293: 
        !           294:     /* Report */
        !           295:     Log(fp->log, ("[%s]   %02x%02x:%02x%02x:%02x%02x:%02x%02x -> %02x%02x:%02x%02x:%02x%02x:%02x%02x", b->name,
        !           296:        ipv6cp->myintid[0], ipv6cp->myintid[1], ipv6cp->myintid[2], ipv6cp->myintid[3],
        !           297:        ipv6cp->myintid[4], ipv6cp->myintid[5], ipv6cp->myintid[6], ipv6cp->myintid[7],
        !           298:        ipv6cp->hisintid[0], ipv6cp->hisintid[1], ipv6cp->hisintid[2], ipv6cp->hisintid[3],
        !           299:        ipv6cp->hisintid[4], ipv6cp->hisintid[5], ipv6cp->hisintid[6], ipv6cp->hisintid[7]));
        !           300: 
        !           301:     /* Enable IP packets in the PPP node */
        !           302:     b->pppConfig.bund.enableIPv6 = 1;
        !           303:     NgFuncSetConfig(b);
        !           304: 
        !           305:     BundNcpsJoin(b, NCP_IPV6CP);
        !           306: }
        !           307: 
        !           308: /*
        !           309:  * Ipv6cpLayerDown()
        !           310:  *
        !           311:  * Called when IPV6CP leaves the OPEN state
        !           312:  */
        !           313: 
        !           314: static void
        !           315: Ipv6cpLayerDown(Fsm fp)
        !           316: {
        !           317:     Bund       b = (Bund)fp->arg;
        !           318: 
        !           319:     BundNcpsLeave(b, NCP_IPV6CP);
        !           320: 
        !           321:     /* Turn off IP packets */
        !           322:     b->pppConfig.bund.enableIPv6 = 0;
        !           323:     NgFuncSetConfig(b);
        !           324: }
        !           325: 
        !           326: /*
        !           327:  * Ipv6cpUp()
        !           328:  */
        !           329: 
        !           330: void
        !           331: Ipv6cpUp(Bund b)
        !           332: {
        !           333:   FsmUp(&b->ipv6cp.fsm);
        !           334: }
        !           335: 
        !           336: /*
        !           337:  * Ipv6cpDown()
        !           338:  */
        !           339: 
        !           340: void
        !           341: Ipv6cpDown(Bund b)
        !           342: {
        !           343:   FsmDown(&b->ipv6cp.fsm);
        !           344: }
        !           345: 
        !           346: /*
        !           347:  * Ipv6cpOpen()
        !           348:  */
        !           349: 
        !           350: void
        !           351: Ipv6cpOpen(Bund b)
        !           352: {
        !           353:   FsmOpen(&b->ipv6cp.fsm);
        !           354: }
        !           355: 
        !           356: /*
        !           357:  * Ipv6cpClose()
        !           358:  */
        !           359: 
        !           360: void
        !           361: Ipv6cpClose(Bund b)
        !           362: {
        !           363:   FsmClose(&b->ipv6cp.fsm);
        !           364: }
        !           365: 
        !           366: /*
        !           367:  * Ipv6cpOpenCmd()
        !           368:  */
        !           369: 
        !           370: int
        !           371: Ipv6cpOpenCmd(Context ctx)
        !           372: {
        !           373:     if (ctx->bund->tmpl)
        !           374:        Error("impossible to open template");
        !           375:     FsmOpen(&ctx->bund->ipv6cp.fsm);
        !           376:     return (0);
        !           377: }
        !           378: 
        !           379: /*
        !           380:  * Ipv6cpCloseCmd()
        !           381:  */
        !           382: 
        !           383: int
        !           384: Ipv6cpCloseCmd(Context ctx)
        !           385: {
        !           386:     if (ctx->bund->tmpl)
        !           387:        Error("impossible to close template");
        !           388:     FsmClose(&ctx->bund->ipv6cp.fsm);
        !           389:     return (0);
        !           390: }
        !           391: 
        !           392: /*
        !           393:  * Ipv6cpFailure()
        !           394:  */
        !           395: 
        !           396: static void
        !           397: Ipv6cpFailure(Fsm fp, enum fsmfail reason)
        !           398: {
        !           399:     Bund       b = (Bund)fp->arg;
        !           400:     RecordLinkUpDownReason(b, NULL, 0, STR_PROTO_ERR, STR_IPV6CP_FAILED, FsmFailureStr(reason));
        !           401: }
        !           402: 
        !           403: /*
        !           404:  * Ipv6cpDecodeConfig()
        !           405:  */
        !           406: 
        !           407: static void
        !           408: Ipv6cpDecodeConfig(Fsm fp, FsmOption list, int num, int mode)
        !           409: {
        !           410:     Bund       b = (Bund)fp->arg;
        !           411:   Ipv6cpState          const ipv6cp = &b->ipv6cp;
        !           412:   int                  k;
        !           413: 
        !           414:   /* Decode each config option */
        !           415:   for (k = 0; k < num; k++) {
        !           416:     FsmOption  const opt = &list[k];
        !           417:     FsmOptInfo const oi = FsmFindOptInfo(gIpv6cpConfOpts, opt->type);
        !           418: 
        !           419:     if (!oi) {
        !           420:       Log(LG_IPV6CP, ("[%s]   UNKNOWN[%d] len=%d", b->name, opt->type, opt->len));
        !           421:       if (mode == MODE_REQ)
        !           422:        FsmRej(fp, opt);
        !           423:       continue;
        !           424:     }
        !           425:     if (!oi->supported) {
        !           426:       Log(LG_IPV6CP, ("[%s]   %s", b->name, oi->name));
        !           427:       if (mode == MODE_REQ) {
        !           428:        Log(LG_IPV6CP, ("[%s]     Not supported", b->name));
        !           429:        FsmRej(fp, opt);
        !           430:       }
        !           431:       continue;
        !           432:     }
        !           433:     if (opt->len < oi->minLen + 2 || opt->len > oi->maxLen + 2) {
        !           434:       Log(LG_IPV6CP, ("[%s]   %s", b->name, oi->name));
        !           435:       if (mode == MODE_REQ) {
        !           436:        Log(LG_IPV6CP, ("[%s]     bogus len=%d min=%d max=%d", b->name, opt->len, oi->minLen + 2, oi->maxLen + 2));
        !           437:        FsmRej(fp, opt);
        !           438:       }
        !           439:       continue;
        !           440:     }
        !           441:     switch (opt->type) {
        !           442:       case TY_INTIDENT:
        !           443:        {
        !           444:          Log(LG_IPV6CP2, ("[%s]   %s %02x%02x:%02x%02x:%02x%02x:%02x%02x", b->name, oi->name,
        !           445:            opt->data[0], opt->data[1], opt->data[2], opt->data[3],
        !           446:            opt->data[4], opt->data[5], opt->data[6], opt->data[7]));
        !           447:          switch (mode) {
        !           448:            case MODE_REQ:
        !           449:              if ((((u_int32_t*)opt->data)[0]==0) && (((u_int32_t*)opt->data)[1]==0)) {
        !           450:                Log(LG_IPV6CP2, ("[%s]     Empty INTIDENT, propose our.", b->name));
        !           451:                CreateInterfaceID(ipv6cp->hisintid, 1);
        !           452:                memcpy(opt->data, ipv6cp->hisintid, 8);
        !           453:                FsmNak(fp, opt);
        !           454:              } else if (bcmp(opt->data, ipv6cp->myintid, 8) == 0) {
        !           455:                Log(LG_IPV6CP2, ("[%s]     Duplicate INTIDENT, generate and propose other.", b->name));
        !           456:                CreateInterfaceID(ipv6cp->hisintid, 1);
        !           457:                memcpy(opt->data, ipv6cp->hisintid, 8);
        !           458:                FsmNak(fp, opt);
        !           459:              } else {
        !           460:                Log(LG_IPV6CP2, ("[%s]     It's OK.", b->name));
        !           461:                memcpy(ipv6cp->hisintid, opt->data, 8);
        !           462:                FsmAck(fp, opt);
        !           463:              }
        !           464:              break;
        !           465:            case MODE_NAK:
        !           466:                Log(LG_IPV6CP2, ("[%s]     I agree to get this to myself.", b->name));
        !           467:                memcpy(ipv6cp->myintid, opt->data, 8);
        !           468:              break;
        !           469:            case MODE_REJ:
        !           470:              IPV6CP_PEER_REJ(ipv6cp, opt->type);
        !           471:              break;
        !           472:          }
        !           473:        }
        !           474:        break;
        !           475: 
        !           476:       default:
        !           477:        assert(0);
        !           478:     }
        !           479:   }
        !           480: }
        !           481: 
        !           482: /*
        !           483:  * Ipv6cpInput()
        !           484:  *
        !           485:  * Deal with an incoming IPV6CP packet
        !           486:  */
        !           487: 
        !           488: void
        !           489: Ipv6cpInput(Bund b, Mbuf bp)
        !           490: {
        !           491:   FsmInput(&b->ipv6cp.fsm, bp);
        !           492: }
        !           493: 
        !           494: /*
        !           495:  * Ipv6cpSetCommand()
        !           496:  */
        !           497: 
        !           498: static int
        !           499: Ipv6cpSetCommand(Context ctx, int ac, char *av[], void *arg)
        !           500: {
        !           501:   Ipv6cpState          const ipv6cp = &ctx->bund->ipv6cp;
        !           502: 
        !           503:   if (ac == 0)
        !           504:     return(-1);
        !           505:   switch ((intptr_t)arg) {
        !           506:     case SET_ACCEPT:
        !           507:       AcceptCommand(ac, av, &ipv6cp->conf.options, gConfList);
        !           508:       break;
        !           509: 
        !           510:     case SET_DENY:
        !           511:       DenyCommand(ac, av, &ipv6cp->conf.options, gConfList);
        !           512:       break;
        !           513: 
        !           514:     case SET_ENABLE:
        !           515:       EnableCommand(ac, av, &ipv6cp->conf.options, gConfList);
        !           516:       break;
        !           517: 
        !           518:     case SET_DISABLE:
        !           519:       DisableCommand(ac, av, &ipv6cp->conf.options, gConfList);
        !           520:       break;
        !           521: 
        !           522:     case SET_YES:
        !           523:       YesCommand(ac, av, &ipv6cp->conf.options, gConfList);
        !           524:       break;
        !           525: 
        !           526:     case SET_NO:
        !           527:       NoCommand(ac, av, &ipv6cp->conf.options, gConfList);
        !           528:       break;
        !           529: 
        !           530:     default:
        !           531:       assert(0);
        !           532:   }
        !           533:   return(0);
        !           534: }
        !           535: 

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