Return to input.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / mpd / src |
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;
1.1.1.2 ! misho 235: hdr = (struct fsmheader *)(void *)MBDATA(pkt);
1.1 misho 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: