blob: ba993a33b0c81bf6fd6fd3a3488715f530cf5ffa [file] [log] [blame]
oliverschmidt3396e9a2004-08-20 12:29:54 +00001/*
2 *---------------------------------------------------------------------------
3 * ppp.c - PPP Processor/Handler -
4 * -
5 *---------------------------------------------------------------------------
6 *
7 * Version -
8 * 0.1 Original Version Jun 3, 2000 -
9 * -
10 *---------------------------------------------------------------------------
11 */
12/*
13 * Copyright (c) 2003, Mike Johnson, Mycal Labs, www.mycal.net
14 * All rights reserved.
15 *
16 * Redistribution and use in source and binary forms, with or without
17 * modification, are permitted provided that the following conditions
18 * are met:
19 * 1. Redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer.
21 * 2. Redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution.
24 * 3. All advertising materials mentioning features or use of this software
25 * must display the following acknowledgement:
26 * This product includes software developed by Mike Johnson/Mycal Labs
27 * www.mycal.net.
28 * 4. The name of the author may not be used to endorse or promote
29 * products derived from this software without specific prior
30 * written permission.
31 *
32 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
33 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
34 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
35 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
36 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
38 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
39 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
40 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
41 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
42 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
43 *
44 * This file is part of the Mycal Modified uIP TCP/IP stack.
45 *
oliverschmidt37420872005-02-23 22:38:43 +000046 * $Id: ppp.c,v 1.5 2005/02/23 22:38:43 oliverschmidt Exp $
oliverschmidt3396e9a2004-08-20 12:29:54 +000047 *
48 */
49
50/* */
51/* include files */
52/* */
53
54
55#include "lcp.h"
56#include "pap.h"
57#include "ipcp.h"
58/*#include "time.h"*/
59/*#include "mip.h"*/
60
oliverschmidt85729cb2005-01-26 23:36:22 +000061#if 0
oliverschmidtacc63952004-08-29 15:11:45 +000062#define DEBUG1(x)
63#else
64#include <stdio.h>
oliverschmidt85729cb2005-01-26 23:36:22 +000065#define DEBUG1(x) debug_printf x
oliverschmidtacc63952004-08-29 15:11:45 +000066#endif
oliverschmidt3396e9a2004-08-20 12:29:54 +000067
68/*
69 Set the debug message level
70*/
71#define PACKET_RX_DEBUG 1
oliverschmidt3396e9a2004-08-20 12:29:54 +000072
73/*
74 Include stuff
75*/
76/*#include "mTypes.h"*/
77#include "ppp.h"
78#include "ahdlc.h"
79#include "ipcp.h"
80#include "lcp.h"
81
82
83/*
84 Buffers that this layer needs (this can be optimized out)
85*/
86u8_t ppp_rx_buffer[PPP_RX_BUFFER_SIZE];
87/*u8_t ppp_tx_buffer[PPP_TX_BUFFER_SIZE];*/
88
89/*
90 * IP addr set by PPP server
91 */
92uip_ipaddr_t our_ipaddr;
93
94/*
95 * Other state storage (this can be placed in a struct and this could could
96 * support multiple PPP connections, would have to embedded the other ppp
97 * module state also)
98 */
99u8_t ppp_flags;
100u8_t ppp_id;
101u8_t ppp_retry;
102
oliverschmidt3396e9a2004-08-20 12:29:54 +0000103#if PACKET_RX_DEBUG
104u16_t ppp_rx_frame_count=0;
105u16_t ppp_rx_tobig_error;
106u8_t done; /* temporary variable */
107#endif
108
109/*---------------------------------------------------------------------------*/
110static u8_t
111check_ppp_errors(void)
112{
113 u8_t ret = 0;
114
115 /* Check Errors */
116 if(lcp_state & LCP_TX_TIMEOUT) {
117 ret = 1;
118 }
119 if(lcp_state & LCP_RX_TIMEOUT) {
120 ret = 2;
121 }
122
123 if(pap_state & PAP_TX_AUTH_FAIL) {
124 ret = 3;
125 }
126 if(pap_state & PAP_RX_AUTH_FAIL) {
127 ret = 4;
128 }
129
130 if(pap_state & PAP_TX_TIMEOUT) {
131 ret = 5;
132 }
133 if(pap_state & PAP_RX_TIMEOUT) {
134 ret = 6;
135 }
136
137 if(ipcp_state & IPCP_TX_TIMEOUT) {
138 ret = 7;
139 }
140
141 return ret;
142}
143/*---------------------------------------------------------------------------*/
144/*
145 * Unknown Protocol Handler, sends reject
146 */
147static void
148ppp_reject_protocol(u16_t protocol, u8_t *buffer, u16_t count)
149{
150 u16_t i;
151 u8_t *dptr, *sptr;
152 LCPPKT *pkt;
153
154 /* first copy rejected packet back, start from end and work forward,
155 +++ Pay attention to buffer managment when updated. Assumes fixed
156 PPP blocks. */
157 DEBUG1(("Rejecting Protocol\n"));
158 if((count + 6) > PPP_RX_BUFFER_SIZE) {
159 /* This is a fatal error +++ do somthing about it. */
160 DEBUG1(("Cannot Reject Protocol, PKT to big\n"));
161 return;
162 }
163 dptr = buffer + count + 6;
164 sptr = buffer + count;
165 for(i = 0; i < count; ++i) {
166 *dptr-- = *sptr--;
167 }
168
169 pkt = (LCPPKT *)buffer;
170 pkt->code = PROT_REJ; /* Write Conf_rej */
171 /*pkt->id = tid++;*/ /* write tid */
172 pkt->len = htons(count + 6);
173 *((u16_t *)(&pkt->data[0])) = htons(protocol);
174
175 ahdlc_tx(LCP, buffer, 0, (u16_t)(count + 6), 0);
176}
177/*---------------------------------------------------------------------------*/
178#if PACKET_RX_DEBUG
179void
180dump_ppp_packet(u8_t *buffer, u16_t len)
181{
182 int i;
183
oliverschmidt85729cb2005-01-26 23:36:22 +0000184 DEBUG1(("\n"));
oliverschmidt3396e9a2004-08-20 12:29:54 +0000185 for(i = 0;i < len; ++i) {
186 if((i & 0x1f) == 0x10) {
oliverschmidt85729cb2005-01-26 23:36:22 +0000187 DEBUG1(("\n"));
oliverschmidt3396e9a2004-08-20 12:29:54 +0000188 }
oliverschmidt85729cb2005-01-26 23:36:22 +0000189 DEBUG1(("0x%02x ",buffer[i]));
oliverschmidt3396e9a2004-08-20 12:29:54 +0000190 }
oliverschmidt85729cb2005-01-26 23:36:22 +0000191 DEBUG1(("\n\n"));
oliverschmidt3396e9a2004-08-20 12:29:54 +0000192}
193#endif
194/*---------------------------------------------------------------------------*/
195/* Initialize and start PPP engine. This just sets things up to
196 * starting values. This can stay a private method.
197 */
198/*---------------------------------------------------------------------------*/
199void
200ppp_init()
201{
202#if PACKET_RX_DEBUG
203 ppp_rx_frame_count = 0;
204 done = 0;
205#endif
206 ppp_flags = 0;
207 pap_init();
208 ipcp_init();
209 lcp_init();
210 ppp_flags = 0;
211
212 ahdlc_init(ppp_rx_buffer, PPP_RX_BUFFER_SIZE);
213 ahdlc_rx_ready();
214}
215/*---------------------------------------------------------------------------*/
216/* raise_ppp() - This routine will try to bring up a PPP connection,
217 * It is blocking. In the future we probably want to pass a
218 * structure with all the options on bringing up a PPP link, like
219 * server/client, DSN server, username password for PAP... +++ for
220 * now just use config and bit defines
221 */
222/*---------------------------------------------------------------------------*/
223#if 0
224u16_t
225ppp_raise(u8_t config, u8_t *username, u8_t *password)
226{
227 u16_t status = 0;
228
229 /* Initialize PPP engine */
230 /* init_ppp(); */
231 pap_init();
232 ipcp_init();
233 lcp_init();
234
235 /* Enable PPP */
236 ppp_flags = PPP_RX_READY;
237
238 /* Try to bring up the layers */
239 while(status == 0) {
240#ifdef SYSTEM_POLLER
241 /* If the the serial interrupt is not hooked to ahdlc_rx, or the
242 system needs to handle other stuff while were blocking, call
243 the system poller.*/
244 system_poller();
245#endif
246
247 /* call the lcp task to bring up the LCP layer */
248 lcp_task(ppp_tx_buffer);
249
250 /* If LCP is up, neg next layer */
251 if(lcp_state & LCP_TX_UP) {
252 /* If LCP wants PAP, try to authenticate, else bring up IPCP */
253 if((lcp_state & LCP_RX_AUTH) && (!(pap_state & PAP_TX_UP))) {
254 pap_task(ppp_tx_buffer,username,password);
255 } else {
256 ipcp_task(ppp_tx_buffer);
257 }
258 }
259
260
261 /* If IPCP came up then our link should be up. */
262 if((ipcp_state & IPCP_TX_UP) && (ipcp_state & IPCP_RX_UP)) {
263 break;
264 }
265
266 status = check_ppp_errors();
267 }
268
269 return status;
270}
271#endif
272/*---------------------------------------------------------------------------*/
273void
oliverschmidta0f331a2004-08-22 21:10:02 +0000274ppp_connect(void)
oliverschmidt3396e9a2004-08-20 12:29:54 +0000275{
276 /* Initialize PPP engine */
277 /* init_ppp(); */
278 pap_init();
279 ipcp_init();
280 lcp_init();
281
282 /* Enable PPP */
283 ppp_flags = PPP_RX_READY;
oliverschmidt3396e9a2004-08-20 12:29:54 +0000284}
285/*---------------------------------------------------------------------------*/
286void
287ppp_send(void)
288{
289 /* If IPCP came up then our link should be up. */
290 if((ipcp_state & IPCP_TX_UP) && (ipcp_state & IPCP_RX_UP)) {
oliverschmidt37420872005-02-23 22:38:43 +0000291 ahdlc_tx(IPV4, uip_buf, uip_appdata,
292 UIP_TCPIP_HLEN, uip_len - UIP_TCPIP_HLEN);
oliverschmidt3396e9a2004-08-20 12:29:54 +0000293 }
294}
295/*---------------------------------------------------------------------------*/
296void
297ppp_poll(void)
298{
299 u8_t c;
300
301 uip_len = 0;
302
oliverschmidt85729cb2005-01-26 23:36:22 +0000303 if(!(ppp_flags & PPP_RX_READY)) {
304 return;
305 }
306
oliverschmidt3396e9a2004-08-20 12:29:54 +0000307 while(uip_len == 0 && ppp_arch_getchar(&c)) {
308 ahdlc_rx(c);
309 }
310
311 /* If IPCP came up then our link should be up. */
312 if((ipcp_state & IPCP_TX_UP) && (ipcp_state & IPCP_RX_UP)) {
313 return;
314 }
315
316 /* call the lcp task to bring up the LCP layer */
317 lcp_task(uip_buf);
318
319 /* If LCP is up, neg next layer */
320 if(lcp_state & LCP_TX_UP) {
321 /* If LCP wants PAP, try to authenticate, else bring up IPCP */
322 if((lcp_state & LCP_RX_AUTH) && (!(pap_state & PAP_TX_UP))) {
oliverschmidta0f331a2004-08-22 21:10:02 +0000323 pap_task(uip_buf);
oliverschmidt3396e9a2004-08-20 12:29:54 +0000324 } else {
325 ipcp_task(uip_buf);
326 }
327 }
328}
329/*---------------------------------------------------------------------------*/
330/* ppp_upcall() - this is where valid PPP frames from the ahdlc layer are
331 * sent to be processed and demuxed.
332 */
333/*---------------------------------------------------------------------------*/
334void
335ppp_upcall(u16_t protocol, u8_t *buffer, u16_t len)
336{
337#if PACKET_RX_DEBUG
338 ++ppp_rx_frame_count;
oliverschmidt85729cb2005-01-26 23:36:22 +0000339 dump_ppp_packet(buffer, len);
oliverschmidt3396e9a2004-08-20 12:29:54 +0000340 if(ppp_rx_frame_count > 18) {
341 done = 1;
342 }
343#endif
344
345 /* check to see if we have a packet waiting to be processed */
346 if(ppp_flags & PPP_RX_READY) {
347 /* demux on protocol field */
348 switch(protocol) {
349 case LCP: /* We must support some level of LCP */
350 DEBUG1(("LCP Packet - "));
351 lcp_rx(buffer, len);
352 DEBUG1(("\n"));
353 break;
354 case PAP: /* PAP should be compile in optional */
355 DEBUG1(("PAP Packet - "));
356 pap_rx(buffer, len);
357 DEBUG1(("\n"));
358 break;
359 case IPCP: /* IPCP should be compile in optional. */
360 DEBUG1(("IPCP Packet - "));
361 ipcp_rx(buffer, len);
362 DEBUG1(("\n"));
363 break;
364 case IPV4: /* We must support IPV4 */
365 DEBUG1(("IPV4 Packet---\n"));
366 memcpy(uip_buf, buffer, len);
367 uip_len = len;
368 DEBUG1(("\n"));
369 break;
370 default:
oliverschmidt85729cb2005-01-26 23:36:22 +0000371 DEBUG1(("Unknown PPP Packet Type 0x%04x - ",protocol));
oliverschmidt3396e9a2004-08-20 12:29:54 +0000372 ppp_reject_protocol(protocol, buffer, len);
373 DEBUG1(("\n"));
374 break;
375 }
376 }
377}
378/*---------------------------------------------------------------------------*/
379/* scan_packet(list,buffer,len)
380 *
381 * list = list of supported ID's
382 * *buffer pointer to the first code in the packet
383 * length of the codespace
384 */
385u16_t
386scan_packet(u16_t protocol, u8_t *list, u8_t *buffer, u8_t *options, u16_t len)
387{
388 u8_t *tlist, *bptr;
389 u8_t *tptr;
390 u8_t bad = 0;
391 u8_t i, j, good;
392
393 bptr = tptr = options;
394 /* scan through the packet and see if it has any unsupported codes */
395 while(bptr < options + len) {
396 /* get code and see if it matches somwhere in the list, if not
397 we don't support it */
398 i = *bptr++;
399
400 /* DEBUG2("%x - ",i);*/
401 tlist = list;
402 good = 0;
403 while(*tlist) {
404 /* DEBUG2("%x ",*tlist);*/
405 if(i == *tlist++) {
406 good = 1;
407 break;
408 }
409 }
410 if(!good) {
411 /* we don't understand it, write it back */
oliverschmidt85729cb2005-01-26 23:36:22 +0000412 DEBUG1(("We don't understand option 0x%02x\n",i));
oliverschmidt3396e9a2004-08-20 12:29:54 +0000413 bad = 1;
414 *tptr++ = i;
415 j = *tptr++ = *bptr++;
416 for(i = 0; i < j - 2; ++i) {
417 *tptr++ = *bptr++;
418 }
419 } else {
420 /* advance over to next option */
421 bptr += *bptr - 1;
422 }
423 }
424
425 /* Bad? if we we need to send a config Reject */
426 if(bad) {
427 /* write the config Rej packet we've built above, take on the header */
428 bptr = buffer;
429 *bptr++ = CONF_REJ; /* Write Conf_rej */
430 bptr++; /* skip over ID */
431 *bptr++ = 0;
432 *bptr = tptr - buffer;
433 /* length right here? */
434
435 /* write the reject frame */
436 DEBUG1(("Writing Reject frame --\n"));
437 ahdlc_tx(protocol, buffer, 0, (u16_t)(tptr - buffer), 0);
438 DEBUG1(("\nEnd writing reject \n"));
439
440 }
441 return bad;
442}
443/*---------------------------------------------------------------------------*/