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