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