File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / mpd / src / input.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Mon Jul 22 08:44:29 2013 UTC (11 years ago) by misho
Branches: mpd, MAIN
CVS tags: v5_8p7, v5_8p1_cross, v5_8p1, v5_8, v5_7p0, v5_7, v5_6, HEAD
5.7

    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>