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>