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

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: 
1.1.1.2 ! misho      67:   static int   Ipv6cpSetCommand(Context ctx, int ac, const char *const av[], const void *arg);
1.1       misho      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},
1.1.1.2 ! misho      87:     { NULL, NULL, NULL, NULL, 0, NULL },
1.1       misho      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 },
1.1.1.2 ! misho      97:     { NULL, 0, 0, 0, 0 }
1.1       misho      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,
1.1.1.2 ! misho     127:     NULL, NULL, NULL, NULL
1.1       misho     128:   };
                    129: 
                    130: /*
                    131:  * Ipv6cpStat()
                    132:  */
                    133: 
                    134: int
1.1.1.2 ! misho     135: Ipv6cpStat(Context ctx, int ac, const char *const av[], const void *arg)
1.1       misho     136: {
                    137:   Ipv6cpState          const ipv6cp = &ctx->bund->ipv6cp;
                    138:   Fsm                  fp = &ipv6cp->fsm;
                    139: 
1.1.1.2 ! misho     140:   (void)ac;
        !           141:   (void)av;
        !           142:   (void)arg;
        !           143: 
1.1       misho     144:   Printf("[%s] %s [%s]\r\n", Pref(fp), Fsm(fp), FsmStateName(fp->state));
                    145:   Printf("Interface identificators:\r\n");
                    146:   Printf("\tSelf: %02x%02x:%02x%02x:%02x%02x:%02x%02x\r\n",
                    147:     ipv6cp->myintid[0], ipv6cp->myintid[1], ipv6cp->myintid[2], ipv6cp->myintid[3],
                    148:     ipv6cp->myintid[4], ipv6cp->myintid[5], ipv6cp->myintid[6], ipv6cp->myintid[7]);
                    149:   Printf("\tPeer: %02x%02x:%02x%02x:%02x%02x:%02x%02x\r\n",
                    150:     ipv6cp->hisintid[0], ipv6cp->hisintid[1], ipv6cp->hisintid[2], ipv6cp->hisintid[3],
                    151:     ipv6cp->hisintid[4], ipv6cp->hisintid[5], ipv6cp->hisintid[6], ipv6cp->hisintid[7]);
                    152:   Printf("IPV6CP Options:\r\n");
                    153:   OptStat(ctx, &ipv6cp->conf.options, gConfList);
                    154: 
                    155:   return(0);
                    156: }
                    157: 
                    158: /*
                    159:  * CreateInterfaceID()
                    160:  */
                    161: 
                    162: void
                    163: CreateInterfaceID(u_char *intid, int r)
                    164: {
                    165:     struct sockaddr_dl hwaddr;
                    166:     u_char     *ether;
                    167: 
                    168:     if (!r) {
                    169:        if (!GetEther(NULL, &hwaddr)) {
                    170:            ether = (u_char *) LLADDR(&hwaddr);
                    171:            intid[0]=ether[0] ^ 0x02; /* reverse the u/l bit*/
                    172:            intid[1]=ether[1];
                    173:            intid[2]=ether[2];
                    174:            intid[3]=0xff;
                    175:            intid[4]=0xfe;
                    176:            intid[5]=ether[3];
                    177:            intid[6]=ether[4];
                    178:            intid[7]=ether[5];
                    179:            return;
                    180:        }
                    181:     }
                    182: 
                    183:     srandomdev();
1.1.1.2 ! misho     184:     ((u_int32_t*)(void*)intid)[0]=(((u_int32_t)random()) % 0xFFFFFFFF) + 1;
        !           185:     ((u_int32_t*)(void*)intid)[1]=(((u_int32_t)random()) % 0xFFFFFFFF) + 1;
1.1       misho     186:     intid[0] &= 0xfd;
                    187: 
                    188: }
                    189: 
                    190: /*
                    191:  * Ipv6cpInit()
                    192:  */
                    193: 
                    194: void
                    195: Ipv6cpInit(Bund b)
                    196: {
                    197:   Ipv6cpState  ipv6cp = &b->ipv6cp;
                    198: 
                    199:   /* Init state machine */
                    200:   memset(ipv6cp, 0, sizeof(*ipv6cp));
                    201:   FsmInit(&ipv6cp->fsm, &gIpv6cpFsmType, b);
                    202: 
                    203:   CreateInterfaceID(ipv6cp->myintid,0);
                    204: 
                    205: }
                    206: 
                    207: /*
                    208:  * Ipv6cpInst()
                    209:  */
                    210: 
                    211: void
                    212: Ipv6cpInst(Bund b, Bund bt)
                    213: {
                    214:   Ipv6cpState  ipv6cp = &b->ipv6cp;
                    215: 
                    216:   /* Init state machine */
                    217:   memcpy(ipv6cp, &bt->ipv6cp, sizeof(*ipv6cp));
                    218:   FsmInst(&ipv6cp->fsm, &bt->ipv6cp.fsm, b);
                    219: }
                    220: 
                    221: /*
                    222:  * Ipv6cpConfigure()
                    223:  */
                    224: 
                    225: static void
                    226: Ipv6cpConfigure(Fsm fp)
                    227: {
                    228:     Bund       b = (Bund)fp->arg;
                    229:   Ipv6cpState  const ipv6cp = &b->ipv6cp;
                    230: 
                    231:   /* FSM stuff */
                    232:   ipv6cp->peer_reject = 0;
                    233: 
                    234: }
                    235: 
                    236: /*
                    237:  * Ipv6cpUnConfigure()
                    238:  */
                    239: 
                    240: static void
                    241: Ipv6cpUnConfigure(Fsm fp)
                    242: {
1.1.1.2 ! misho     243:   (void)fp;
1.1       misho     244: }
                    245: 
                    246: /*
                    247:  * Ipv6cpBuildConfigReq()
                    248:  */
                    249: 
                    250: static u_char *
                    251: Ipv6cpBuildConfigReq(Fsm fp, u_char *cp)
                    252: {
                    253:     Bund       b = (Bund)fp->arg;
                    254:   Ipv6cpState  const ipv6cp = &b->ipv6cp;
                    255: 
                    256:   cp = FsmConfValue(cp, TY_INTIDENT, 8, ipv6cp->myintid);
                    257: 
                    258: /* Done */
                    259: 
                    260:   return(cp);
                    261: }
                    262: 
                    263: /*
                    264:  * Ipv6cpLayerStart()
                    265:  *
                    266:  * Tell the lower layer (the bundle) that we need it
                    267:  */
                    268: 
                    269: static void
                    270: Ipv6cpLayerStart(Fsm fp)
                    271: {
                    272:     BundNcpsStart((Bund)(fp->arg), NCP_IPV6CP);
                    273: }
                    274: 
                    275: /*
                    276:  * Ipv6cpLayerFinish()
                    277:  *
                    278:  * Tell the lower layer (the bundle) that we no longer need it
                    279:  */
                    280: 
                    281: static void
                    282: Ipv6cpLayerFinish(Fsm fp)
                    283: {
                    284:     BundNcpsFinish((Bund)(fp->arg), NCP_IPV6CP);
                    285: }
                    286: 
                    287: /*
                    288:  * Ipv6cpLayerUp()
                    289:  *
                    290:  * Called when IPV6CP has reached the OPEN state
                    291:  */
                    292: 
                    293: static void
                    294: Ipv6cpLayerUp(Fsm fp)
                    295: {
                    296:     Bund       b = (Bund)fp->arg;
                    297:     Ipv6cpState                const ipv6cp = &b->ipv6cp;
                    298: 
                    299:     /* Report */
                    300:     Log(fp->log, ("[%s]   %02x%02x:%02x%02x:%02x%02x:%02x%02x -> %02x%02x:%02x%02x:%02x%02x:%02x%02x", b->name,
                    301:        ipv6cp->myintid[0], ipv6cp->myintid[1], ipv6cp->myintid[2], ipv6cp->myintid[3],
                    302:        ipv6cp->myintid[4], ipv6cp->myintid[5], ipv6cp->myintid[6], ipv6cp->myintid[7],
                    303:        ipv6cp->hisintid[0], ipv6cp->hisintid[1], ipv6cp->hisintid[2], ipv6cp->hisintid[3],
                    304:        ipv6cp->hisintid[4], ipv6cp->hisintid[5], ipv6cp->hisintid[6], ipv6cp->hisintid[7]));
                    305: 
                    306:     /* Enable IP packets in the PPP node */
                    307:     b->pppConfig.bund.enableIPv6 = 1;
                    308:     NgFuncSetConfig(b);
                    309: 
                    310:     BundNcpsJoin(b, NCP_IPV6CP);
                    311: }
                    312: 
                    313: /*
                    314:  * Ipv6cpLayerDown()
                    315:  *
                    316:  * Called when IPV6CP leaves the OPEN state
                    317:  */
                    318: 
                    319: static void
                    320: Ipv6cpLayerDown(Fsm fp)
                    321: {
                    322:     Bund       b = (Bund)fp->arg;
                    323: 
                    324:     BundNcpsLeave(b, NCP_IPV6CP);
                    325: 
                    326:     /* Turn off IP packets */
                    327:     b->pppConfig.bund.enableIPv6 = 0;
                    328:     NgFuncSetConfig(b);
                    329: }
                    330: 
                    331: /*
                    332:  * Ipv6cpUp()
                    333:  */
                    334: 
                    335: void
                    336: Ipv6cpUp(Bund b)
                    337: {
                    338:   FsmUp(&b->ipv6cp.fsm);
                    339: }
                    340: 
                    341: /*
                    342:  * Ipv6cpDown()
                    343:  */
                    344: 
                    345: void
                    346: Ipv6cpDown(Bund b)
                    347: {
                    348:   FsmDown(&b->ipv6cp.fsm);
                    349: }
                    350: 
                    351: /*
                    352:  * Ipv6cpOpen()
                    353:  */
                    354: 
                    355: void
                    356: Ipv6cpOpen(Bund b)
                    357: {
                    358:   FsmOpen(&b->ipv6cp.fsm);
                    359: }
                    360: 
                    361: /*
                    362:  * Ipv6cpClose()
                    363:  */
                    364: 
                    365: void
                    366: Ipv6cpClose(Bund b)
                    367: {
                    368:   FsmClose(&b->ipv6cp.fsm);
                    369: }
                    370: 
                    371: /*
                    372:  * Ipv6cpOpenCmd()
                    373:  */
                    374: 
                    375: int
                    376: Ipv6cpOpenCmd(Context ctx)
                    377: {
                    378:     if (ctx->bund->tmpl)
                    379:        Error("impossible to open template");
                    380:     FsmOpen(&ctx->bund->ipv6cp.fsm);
                    381:     return (0);
                    382: }
                    383: 
                    384: /*
                    385:  * Ipv6cpCloseCmd()
                    386:  */
                    387: 
                    388: int
                    389: Ipv6cpCloseCmd(Context ctx)
                    390: {
                    391:     if (ctx->bund->tmpl)
                    392:        Error("impossible to close template");
                    393:     FsmClose(&ctx->bund->ipv6cp.fsm);
                    394:     return (0);
                    395: }
                    396: 
                    397: /*
                    398:  * Ipv6cpFailure()
                    399:  */
                    400: 
                    401: static void
                    402: Ipv6cpFailure(Fsm fp, enum fsmfail reason)
                    403: {
                    404:     Bund       b = (Bund)fp->arg;
                    405:     RecordLinkUpDownReason(b, NULL, 0, STR_PROTO_ERR, STR_IPV6CP_FAILED, FsmFailureStr(reason));
                    406: }
                    407: 
                    408: /*
                    409:  * Ipv6cpDecodeConfig()
                    410:  */
                    411: 
                    412: static void
                    413: Ipv6cpDecodeConfig(Fsm fp, FsmOption list, int num, int mode)
                    414: {
                    415:     Bund       b = (Bund)fp->arg;
                    416:   Ipv6cpState          const ipv6cp = &b->ipv6cp;
                    417:   int                  k;
                    418: 
                    419:   /* Decode each config option */
                    420:   for (k = 0; k < num; k++) {
                    421:     FsmOption  const opt = &list[k];
                    422:     FsmOptInfo const oi = FsmFindOptInfo(gIpv6cpConfOpts, opt->type);
                    423: 
                    424:     if (!oi) {
                    425:       Log(LG_IPV6CP, ("[%s]   UNKNOWN[%d] len=%d", b->name, opt->type, opt->len));
                    426:       if (mode == MODE_REQ)
                    427:        FsmRej(fp, opt);
                    428:       continue;
                    429:     }
                    430:     if (!oi->supported) {
                    431:       Log(LG_IPV6CP, ("[%s]   %s", b->name, oi->name));
                    432:       if (mode == MODE_REQ) {
                    433:        Log(LG_IPV6CP, ("[%s]     Not supported", b->name));
                    434:        FsmRej(fp, opt);
                    435:       }
                    436:       continue;
                    437:     }
                    438:     if (opt->len < oi->minLen + 2 || opt->len > oi->maxLen + 2) {
                    439:       Log(LG_IPV6CP, ("[%s]   %s", b->name, oi->name));
                    440:       if (mode == MODE_REQ) {
                    441:        Log(LG_IPV6CP, ("[%s]     bogus len=%d min=%d max=%d", b->name, opt->len, oi->minLen + 2, oi->maxLen + 2));
                    442:        FsmRej(fp, opt);
                    443:       }
                    444:       continue;
                    445:     }
                    446:     switch (opt->type) {
                    447:       case TY_INTIDENT:
                    448:        {
                    449:          Log(LG_IPV6CP2, ("[%s]   %s %02x%02x:%02x%02x:%02x%02x:%02x%02x", b->name, oi->name,
                    450:            opt->data[0], opt->data[1], opt->data[2], opt->data[3],
                    451:            opt->data[4], opt->data[5], opt->data[6], opt->data[7]));
                    452:          switch (mode) {
1.1.1.2 ! misho     453:            u_int32_t *ui32p;
1.1       misho     454:            case MODE_REQ:
1.1.1.2 ! misho     455:              ui32p = (u_int32_t *)(void *)opt->data;
        !           456:              if ((ui32p[0]==0) && (ui32p[1]==0)) {
1.1       misho     457:                Log(LG_IPV6CP2, ("[%s]     Empty INTIDENT, propose our.", b->name));
                    458:                CreateInterfaceID(ipv6cp->hisintid, 1);
                    459:                memcpy(opt->data, ipv6cp->hisintid, 8);
                    460:                FsmNak(fp, opt);
                    461:              } else if (bcmp(opt->data, ipv6cp->myintid, 8) == 0) {
                    462:                Log(LG_IPV6CP2, ("[%s]     Duplicate INTIDENT, generate and propose other.", b->name));
                    463:                CreateInterfaceID(ipv6cp->hisintid, 1);
                    464:                memcpy(opt->data, ipv6cp->hisintid, 8);
                    465:                FsmNak(fp, opt);
                    466:              } else {
                    467:                Log(LG_IPV6CP2, ("[%s]     It's OK.", b->name));
                    468:                memcpy(ipv6cp->hisintid, opt->data, 8);
                    469:                FsmAck(fp, opt);
                    470:              }
                    471:              break;
                    472:            case MODE_NAK:
                    473:                Log(LG_IPV6CP2, ("[%s]     I agree to get this to myself.", b->name));
                    474:                memcpy(ipv6cp->myintid, opt->data, 8);
                    475:              break;
                    476:            case MODE_REJ:
                    477:              IPV6CP_PEER_REJ(ipv6cp, opt->type);
                    478:              break;
                    479:          }
                    480:        }
                    481:        break;
                    482: 
                    483:       default:
                    484:        assert(0);
                    485:     }
                    486:   }
                    487: }
                    488: 
                    489: /*
                    490:  * Ipv6cpInput()
                    491:  *
                    492:  * Deal with an incoming IPV6CP packet
                    493:  */
                    494: 
                    495: void
                    496: Ipv6cpInput(Bund b, Mbuf bp)
                    497: {
                    498:   FsmInput(&b->ipv6cp.fsm, bp);
                    499: }
                    500: 
                    501: /*
                    502:  * Ipv6cpSetCommand()
                    503:  */
                    504: 
                    505: static int
1.1.1.2 ! misho     506: Ipv6cpSetCommand(Context ctx, int ac, const char *const av[], const void *arg)
1.1       misho     507: {
                    508:   Ipv6cpState          const ipv6cp = &ctx->bund->ipv6cp;
                    509: 
                    510:   if (ac == 0)
                    511:     return(-1);
                    512:   switch ((intptr_t)arg) {
                    513:     case SET_ACCEPT:
                    514:       AcceptCommand(ac, av, &ipv6cp->conf.options, gConfList);
                    515:       break;
                    516: 
                    517:     case SET_DENY:
                    518:       DenyCommand(ac, av, &ipv6cp->conf.options, gConfList);
                    519:       break;
                    520: 
                    521:     case SET_ENABLE:
                    522:       EnableCommand(ac, av, &ipv6cp->conf.options, gConfList);
                    523:       break;
                    524: 
                    525:     case SET_DISABLE:
                    526:       DisableCommand(ac, av, &ipv6cp->conf.options, gConfList);
                    527:       break;
                    528: 
                    529:     case SET_YES:
                    530:       YesCommand(ac, av, &ipv6cp->conf.options, gConfList);
                    531:       break;
                    532: 
                    533:     case SET_NO:
                    534:       NoCommand(ac, av, &ipv6cp->conf.options, gConfList);
                    535:       break;
                    536: 
                    537:     default:
                    538:       assert(0);
                    539:   }
                    540:   return(0);
                    541: }
                    542: 

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