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>