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

1.1     ! misho       1: 
        !             2: /*
        !             3:  * input.c
        !             4:  *
        !             5:  * Written by Archie Cobbs <archie@freebsd.org>
        !             6:  * Copyright (c) 1995-1999 Whistle Communications, Inc. All rights reserved.
        !             7:  * See ``COPYRIGHT.whistle''
        !             8:  */
        !             9: 
        !            10: #include "ppp.h"
        !            11: #include "input.h"
        !            12: #include "ipcp.h"
        !            13: #include "chap.h"
        !            14: #include "pap.h"
        !            15: #include "eap.h"
        !            16: #include "lcp.h"
        !            17: #include "ip.h"
        !            18: #include "ccp.h"
        !            19: #include "ecp.h"
        !            20: #include "ngfunc.h"
        !            21: 
        !            22: /*
        !            23:  * INTERNAL FUNCTIONS
        !            24:  */
        !            25: 
        !            26:   static int   InputLinkCheck(Link l, int proto);
        !            27:   static void  InputMPLink(Bund b, int proto, Mbuf pkt);
        !            28:   static int   InputDispatch(Bund b, Link l, int proto, Mbuf bp);
        !            29: 
        !            30: /*
        !            31:  * InputFrame()
        !            32:  *
        !            33:  * Input a PPP frame having protocol "proto" from link "linkNum",
        !            34:  * which may be either a link number or NG_PPP_BUNDLE_LINKNUM.
        !            35:  * This always consumes the mbuf.
        !            36:  */
        !            37: 
        !            38: void
        !            39: InputFrame(Bund b, Link l, int proto, Mbuf bp)
        !            40: {
        !            41:     Mbuf       protoRej;
        !            42:     u_int16_t  nprot;
        !            43: 
        !            44:     /* Check the link */
        !            45:     if (l == NULL) {
        !            46:        /* Only limited link-layer stuff allowed over the MP bundle */
        !            47:        if (PROT_LINK_LAYER(proto)) {
        !            48:            InputMPLink(b, proto, bp);
        !            49:            return;
        !            50:        }
        !            51:     } else {
        !            52:        /* Check protocol vs. link state */
        !            53:        if (!InputLinkCheck(l, proto)) {
        !            54:            mbfree(bp);
        !            55:            return;
        !            56:        }
        !            57:     }
        !            58: 
        !            59:     /* Dispatch frame to the appropriate protocol engine */
        !            60:     if (InputDispatch(b, l, proto, bp) >= 0)
        !            61:        return;
        !            62: 
        !            63:     /* Unknown protocol, so find a link to send protocol reject on */
        !            64:     if (l == NULL) {
        !            65:        int     k;
        !            66:        for (k = 0; k < NG_PPP_MAX_LINKS && 
        !            67:            (!b->links[k] || b->links[k]->lcp.phase != PHASE_NETWORK);
        !            68:            k++);
        !            69:        if (k == NG_PPP_MAX_LINKS) {
        !            70:            mbfree(bp);
        !            71:            return;
        !            72:        }
        !            73:        l = b->links[k];
        !            74:     }
        !            75: 
        !            76:     /* Send a protocol reject on the chosen link */
        !            77:     nprot = htons((u_int16_t) proto);
        !            78:     protoRej = mbcopyback(bp, -2, (u_char *) &nprot, 2);
        !            79:     FsmOutputMbuf(&l->lcp.fsm, CODE_PROTOREJ, l->lcp.fsm.rejid++, protoRej);
        !            80: }
        !            81: 
        !            82: /*
        !            83:  * InputDispatch()
        !            84:  *
        !            85:  * Given an unwrapped PPP frame of type "proto", dispatch to wherever.
        !            86:  * Returns negative if protocol was unknown, otherwise returns zero
        !            87:  * and consumes packet. Any packets we expect the peer to send but
        !            88:  * shouldn't be received by this daemon are logged and dropped.
        !            89:  */
        !            90: 
        !            91: static int
        !            92: InputDispatch(Bund b, Link l, int proto, Mbuf bp)
        !            93: {
        !            94:     int reject = 0;
        !            95: 
        !            96:     /* link level protos */
        !            97:     if (l) {
        !            98:        switch (proto) {
        !            99:         case PROTO_LCP:
        !           100:             LcpInput(l, bp);
        !           101:             return(0);
        !           102:         case PROTO_PAP:
        !           103:         case PROTO_CHAP:
        !           104:         case PROTO_EAP:
        !           105:             AuthInput(l, proto, bp);
        !           106:             return(0);
        !           107:        case PROTO_MP:
        !           108:            if (!Enabled(&l->conf.options, LINK_CONF_MULTILINK))
        !           109:                reject = 1;
        !           110:            goto done;
        !           111:         }
        !           112:     }
        !           113: 
        !           114:     /* bundle level protos */
        !           115:     if (b) {
        !           116:        switch (proto) {
        !           117:        case PROTO_IPCP:
        !           118:        case PROTO_IP:
        !           119:         case PROTO_VJUNCOMP:
        !           120:         case PROTO_VJCOMP:
        !           121:            if (!Enabled(&b->conf.options, BUND_CONF_IPCP))
        !           122:                reject = 1;
        !           123:            else if (proto == PROTO_IPCP) {
        !           124:                IpcpInput(b, bp);
        !           125:                return(0);
        !           126:            }
        !           127:            break;
        !           128:        case PROTO_IPV6CP:
        !           129:        case PROTO_IPV6:
        !           130:            if (!Enabled(&b->conf.options, BUND_CONF_IPV6CP))
        !           131:                reject = 1;
        !           132:            else if (proto == PROTO_IPV6CP) {
        !           133:                Ipv6cpInput(b, bp);
        !           134:                return(0);
        !           135:            }
        !           136:            break;
        !           137:        case PROTO_CCP:
        !           138:        case PROTO_COMPD:
        !           139:            if (!Enabled(&b->conf.options, BUND_CONF_COMPRESSION))
        !           140:                reject = 1;
        !           141:            else if (proto == PROTO_CCP) {
        !           142:                CcpInput(b, bp);
        !           143:                return(0);
        !           144:            }
        !           145:            break;
        !           146:        case PROTO_ECP:
        !           147:        case PROTO_CRYPT:
        !           148:            if (!Enabled(&b->conf.options, BUND_CONF_ENCRYPTION))
        !           149:                reject = 1;
        !           150:            else if (proto == PROTO_ECP) {
        !           151:                EcpInput(b, bp);
        !           152:                return(0);
        !           153:            }
        !           154:            break;
        !           155:        default:        /* completely unknown protocol, reject it */
        !           156:            reject = 1;
        !           157:            break;
        !           158:        }
        !           159:     }
        !           160: 
        !           161: done:
        !           162:     /* Protocol unexpected, so either reject or drop */
        !           163:     Log(LG_LINK|LG_BUND, ("[%s] rec'd unexpected protocol %s%s",
        !           164:        (l ? l->name : b->name), ProtoName(proto), reject ? ", rejecting" : ""));
        !           165:     if (!reject)
        !           166:        mbfree(bp);
        !           167:     return (reject ? -1 : 0);
        !           168: }
        !           169: 
        !           170: /*
        !           171:  * InputLinkCheck()
        !           172:  *
        !           173:  * Make sure this protocol is acceptable and makes sense on this link.
        !           174:  * Returns TRUE if so and the frame should be handled further.
        !           175:  */
        !           176: 
        !           177: static int
        !           178: InputLinkCheck(Link l, int proto)
        !           179: {
        !           180:   /* Check link LCP state */
        !           181:   switch (l->lcp.phase) {
        !           182:     case PHASE_DEAD:
        !           183:       Log(LG_LINK, ("[%s] rec'd proto %s while dead",
        !           184:        l->name, ProtoName(proto)));
        !           185:       return(FALSE);
        !           186:     case PHASE_ESTABLISH:
        !           187:       if (proto != PROTO_LCP) {
        !           188:        Log(LG_LINK, ("[%s] rec'd proto %s during establishment phase",
        !           189:          l->name, ProtoName(proto)));
        !           190:        return(FALSE);
        !           191:       }
        !           192:       break;
        !           193:     case PHASE_AUTHENTICATE:
        !           194:       if (!PROT_LINK_LAYER(proto)) {
        !           195:        Log(LG_LINK, ("[%s] rec'd proto %s during authenticate phase",
        !           196:          l->name, ProtoName(proto)));
        !           197:        return(FALSE);
        !           198:       }
        !           199:       break;
        !           200:     case PHASE_NETWORK:
        !           201:       break;
        !           202:     case PHASE_TERMINATE:
        !           203:       if (proto != PROTO_LCP) {
        !           204:        Log(LG_LINK, ("[%s] rec'd proto %s during terminate phase",
        !           205:          l->name, ProtoName(proto)));
        !           206:        return(FALSE);
        !           207:       }
        !           208:       break;
        !           209:     default:
        !           210:       assert(0);
        !           211:   }
        !           212: 
        !           213:   /* OK */
        !           214:   return(TRUE);
        !           215: }
        !           216: 
        !           217: /*
        !           218:  * InputMPLink()
        !           219:  *
        !           220:  * Deal with an incoming link-level packet on the virtual link (!)
        !           221:  * Only certain link-level packets make sense coming over the bundle.
        !           222:  * In any case, this consumes the mbuf.
        !           223:  */
        !           224: 
        !           225: static void
        !           226: InputMPLink(Bund b, int proto, Mbuf pkt)
        !           227: {
        !           228:     struct fsmheader   *hdr;
        !           229:     int                        k;
        !           230: 
        !           231:     switch (proto) {
        !           232:        case PROTO_LCP:
        !           233:            if (MBLEN(pkt) < sizeof(hdr))
        !           234:                break;
        !           235:            hdr = (struct fsmheader *)MBDATA(pkt);
        !           236:            switch (hdr->code) {
        !           237:                case CODE_CODEREJ:              /* these two are OK */
        !           238:                case CODE_PROTOREJ:
        !           239:                    for (k = 0; k < NG_PPP_MAX_LINKS && !b->links[k]; k++)
        !           240:                    if (k < NG_PPP_MAX_LINKS) {
        !           241:                        InputFrame(b, b->links[k], proto, pkt);
        !           242:                        return;
        !           243:                    }
        !           244:                    break;
        !           245: 
        !           246:                case CODE_ECHOREQ:
        !           247:                    Log(LG_ECHO, ("[%s] rec'd %s #%d, replying...",
        !           248:                        b->name, FsmCodeName(hdr->code), hdr->id));
        !           249:                    MBDATAU(pkt)[0] = CODE_ECHOREP;
        !           250:                    NgFuncWritePppFrame(b, NG_PPP_BUNDLE_LINKNUM, PROTO_LCP, pkt);
        !           251:                    return;
        !           252: 
        !           253:                case CODE_ECHOREP:
        !           254:                    Log(LG_ECHO, ("[%s] rec'd %s #%d",
        !           255:                        b->name, FsmCodeName(hdr->code), hdr->id));
        !           256:                    break;
        !           257: 
        !           258:                default:
        !           259:                    Log(LG_ERR, ("[%s] rec'd LCP %s #%d on MP link! (ignoring)",
        !           260:                        b->name, FsmCodeName(hdr->code), hdr->id));
        !           261:                    break;
        !           262:            }
        !           263:            break;
        !           264: 
        !           265:        default:
        !           266:            Log(LG_ERR, ("[%s] rec'd proto %s on MP link! (ignoring)",
        !           267:                b->name, ProtoName(proto)));
        !           268:            break;
        !           269:     }
        !           270:     mbfree(pkt);
        !           271: }
        !           272: 

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