Annotation of embedaddon/mpd/src/input.c, revision 1.1.1.2.2.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:
1.1.1.2.2.1! misho     104:             AuthInput(l, proto, bp);
        !           105:             return(0);
1.1       misho     106:         case PROTO_EAP:
1.1.1.2.2.1! misho     107: #ifdef USE_RADIUS
1.1       misho     108:             AuthInput(l, proto, bp);
                    109:             return(0);
1.1.1.2.2.1! misho     110: #else
        !           111:            reject = 1;
        !           112:            goto done;
        !           113: #endif
1.1       misho     114:        case PROTO_MP:
                    115:            if (!Enabled(&l->conf.options, LINK_CONF_MULTILINK))
                    116:                reject = 1;
                    117:            goto done;
                    118:         }
                    119:     }
                    120: 
                    121:     /* bundle level protos */
                    122:     if (b) {
                    123:        switch (proto) {
                    124:        case PROTO_IPCP:
                    125:        case PROTO_IP:
                    126:         case PROTO_VJUNCOMP:
                    127:         case PROTO_VJCOMP:
                    128:            if (!Enabled(&b->conf.options, BUND_CONF_IPCP))
                    129:                reject = 1;
                    130:            else if (proto == PROTO_IPCP) {
                    131:                IpcpInput(b, bp);
                    132:                return(0);
                    133:            }
                    134:            break;
                    135:        case PROTO_IPV6CP:
                    136:        case PROTO_IPV6:
                    137:            if (!Enabled(&b->conf.options, BUND_CONF_IPV6CP))
                    138:                reject = 1;
                    139:            else if (proto == PROTO_IPV6CP) {
                    140:                Ipv6cpInput(b, bp);
                    141:                return(0);
                    142:            }
                    143:            break;
                    144:        case PROTO_CCP:
                    145:        case PROTO_COMPD:
                    146:            if (!Enabled(&b->conf.options, BUND_CONF_COMPRESSION))
                    147:                reject = 1;
                    148:            else if (proto == PROTO_CCP) {
                    149:                CcpInput(b, bp);
                    150:                return(0);
                    151:            }
                    152:            break;
                    153:        case PROTO_ECP:
                    154:        case PROTO_CRYPT:
                    155:            if (!Enabled(&b->conf.options, BUND_CONF_ENCRYPTION))
                    156:                reject = 1;
                    157:            else if (proto == PROTO_ECP) {
                    158:                EcpInput(b, bp);
                    159:                return(0);
                    160:            }
                    161:            break;
                    162:        default:        /* completely unknown protocol, reject it */
                    163:            reject = 1;
                    164:            break;
                    165:        }
                    166:     }
                    167: 
                    168: done:
                    169:     /* Protocol unexpected, so either reject or drop */
                    170:     Log(LG_LINK|LG_BUND, ("[%s] rec'd unexpected protocol %s%s",
                    171:        (l ? l->name : b->name), ProtoName(proto), reject ? ", rejecting" : ""));
                    172:     if (!reject)
                    173:        mbfree(bp);
                    174:     return (reject ? -1 : 0);
                    175: }
                    176: 
                    177: /*
                    178:  * InputLinkCheck()
                    179:  *
                    180:  * Make sure this protocol is acceptable and makes sense on this link.
                    181:  * Returns TRUE if so and the frame should be handled further.
                    182:  */
                    183: 
                    184: static int
                    185: InputLinkCheck(Link l, int proto)
                    186: {
                    187:   /* Check link LCP state */
                    188:   switch (l->lcp.phase) {
                    189:     case PHASE_DEAD:
                    190:       Log(LG_LINK, ("[%s] rec'd proto %s while dead",
                    191:        l->name, ProtoName(proto)));
                    192:       return(FALSE);
                    193:     case PHASE_ESTABLISH:
                    194:       if (proto != PROTO_LCP) {
                    195:        Log(LG_LINK, ("[%s] rec'd proto %s during establishment phase",
                    196:          l->name, ProtoName(proto)));
                    197:        return(FALSE);
                    198:       }
                    199:       break;
                    200:     case PHASE_AUTHENTICATE:
                    201:       if (!PROT_LINK_LAYER(proto)) {
                    202:        Log(LG_LINK, ("[%s] rec'd proto %s during authenticate phase",
                    203:          l->name, ProtoName(proto)));
                    204:        return(FALSE);
                    205:       }
                    206:       break;
                    207:     case PHASE_NETWORK:
                    208:       break;
                    209:     case PHASE_TERMINATE:
                    210:       if (proto != PROTO_LCP) {
                    211:        Log(LG_LINK, ("[%s] rec'd proto %s during terminate phase",
                    212:          l->name, ProtoName(proto)));
                    213:        return(FALSE);
                    214:       }
                    215:       break;
                    216:     default:
                    217:       assert(0);
                    218:   }
                    219: 
                    220:   /* OK */
                    221:   return(TRUE);
                    222: }
                    223: 
                    224: /*
                    225:  * InputMPLink()
                    226:  *
                    227:  * Deal with an incoming link-level packet on the virtual link (!)
                    228:  * Only certain link-level packets make sense coming over the bundle.
                    229:  * In any case, this consumes the mbuf.
                    230:  */
                    231: 
                    232: static void
                    233: InputMPLink(Bund b, int proto, Mbuf pkt)
                    234: {
                    235:     struct fsmheader   *hdr;
                    236:     int                        k;
                    237: 
                    238:     switch (proto) {
                    239:        case PROTO_LCP:
                    240:            if (MBLEN(pkt) < sizeof(hdr))
                    241:                break;
1.1.1.2   misho     242:            hdr = (struct fsmheader *)(void *)MBDATA(pkt);
1.1       misho     243:            switch (hdr->code) {
                    244:                case CODE_CODEREJ:              /* these two are OK */
                    245:                case CODE_PROTOREJ:
                    246:                    for (k = 0; k < NG_PPP_MAX_LINKS && !b->links[k]; k++)
                    247:                    if (k < NG_PPP_MAX_LINKS) {
                    248:                        InputFrame(b, b->links[k], proto, pkt);
                    249:                        return;
                    250:                    }
                    251:                    break;
                    252: 
                    253:                case CODE_ECHOREQ:
                    254:                    Log(LG_ECHO, ("[%s] rec'd %s #%d, replying...",
                    255:                        b->name, FsmCodeName(hdr->code), hdr->id));
                    256:                    MBDATAU(pkt)[0] = CODE_ECHOREP;
                    257:                    NgFuncWritePppFrame(b, NG_PPP_BUNDLE_LINKNUM, PROTO_LCP, pkt);
                    258:                    return;
                    259: 
                    260:                case CODE_ECHOREP:
                    261:                    Log(LG_ECHO, ("[%s] rec'd %s #%d",
                    262:                        b->name, FsmCodeName(hdr->code), hdr->id));
                    263:                    break;
                    264: 
                    265:                default:
                    266:                    Log(LG_ERR, ("[%s] rec'd LCP %s #%d on MP link! (ignoring)",
                    267:                        b->name, FsmCodeName(hdr->code), hdr->id));
                    268:                    break;
                    269:            }
                    270:            break;
                    271: 
                    272:        default:
                    273:            Log(LG_ERR, ("[%s] rec'd proto %s on MP link! (ignoring)",
                    274:                b->name, ProtoName(proto)));
                    275:            break;
                    276:     }
                    277:     mbfree(pkt);
                    278: }
                    279: 

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