blob: 907e5ceb99e688b2d34558353302f365bb0a99d3 [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 *
oliverschmidtacc63952004-08-29 15:11:45 +000046 * $Id: ppp.c,v 1.3 2004/08/29 15:11:46 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
oliverschmidtacc63952004-08-29 15:11:45 +000061#if 1
62#define DEBUG1(x)
63#else
64#include <stdio.h>
oliverschmidt3396e9a2004-08-20 12:29:54 +000065#define DEBUG1(x) 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
72#define DEBUG_LV1 1
73#define DEBUG_LV2 2
74
75#if PACKET_RX_DEBUG
76#include <stdio.h>
77#endif
78
79/*
80 Include stuff
81*/
82/*#include "mTypes.h"*/
83#include "ppp.h"
84#include "ahdlc.h"
85#include "ipcp.h"
86#include "lcp.h"
87
88
89/*
90 Buffers that this layer needs (this can be optimized out)
91*/
92u8_t ppp_rx_buffer[PPP_RX_BUFFER_SIZE];
93/*u8_t ppp_tx_buffer[PPP_TX_BUFFER_SIZE];*/
94
95/*
96 * IP addr set by PPP server
97 */
98uip_ipaddr_t our_ipaddr;
99
100/*
101 * Other state storage (this can be placed in a struct and this could could
102 * support multiple PPP connections, would have to embedded the other ppp
103 * module state also)
104 */
105u8_t ppp_flags;
106u8_t ppp_id;
107u8_t ppp_retry;
108
oliverschmidt3396e9a2004-08-20 12:29:54 +0000109#if PACKET_RX_DEBUG
110u16_t ppp_rx_frame_count=0;
111u16_t ppp_rx_tobig_error;
112u8_t done; /* temporary variable */
113#endif
114
115/*---------------------------------------------------------------------------*/
116static u8_t
117check_ppp_errors(void)
118{
119 u8_t ret = 0;
120
121 /* Check Errors */
122 if(lcp_state & LCP_TX_TIMEOUT) {
123 ret = 1;
124 }
125 if(lcp_state & LCP_RX_TIMEOUT) {
126 ret = 2;
127 }
128
129 if(pap_state & PAP_TX_AUTH_FAIL) {
130 ret = 3;
131 }
132 if(pap_state & PAP_RX_AUTH_FAIL) {
133 ret = 4;
134 }
135
136 if(pap_state & PAP_TX_TIMEOUT) {
137 ret = 5;
138 }
139 if(pap_state & PAP_RX_TIMEOUT) {
140 ret = 6;
141 }
142
143 if(ipcp_state & IPCP_TX_TIMEOUT) {
144 ret = 7;
145 }
146
147 return ret;
148}
149/*---------------------------------------------------------------------------*/
150/*
151 * Unknown Protocol Handler, sends reject
152 */
153static void
154ppp_reject_protocol(u16_t protocol, u8_t *buffer, u16_t count)
155{
156 u16_t i;
157 u8_t *dptr, *sptr;
158 LCPPKT *pkt;
159
160 /* first copy rejected packet back, start from end and work forward,
161 +++ Pay attention to buffer managment when updated. Assumes fixed
162 PPP blocks. */
163 DEBUG1(("Rejecting Protocol\n"));
164 if((count + 6) > PPP_RX_BUFFER_SIZE) {
165 /* This is a fatal error +++ do somthing about it. */
166 DEBUG1(("Cannot Reject Protocol, PKT to big\n"));
167 return;
168 }
169 dptr = buffer + count + 6;
170 sptr = buffer + count;
171 for(i = 0; i < count; ++i) {
172 *dptr-- = *sptr--;
173 }
174
175 pkt = (LCPPKT *)buffer;
176 pkt->code = PROT_REJ; /* Write Conf_rej */
177 /*pkt->id = tid++;*/ /* write tid */
178 pkt->len = htons(count + 6);
179 *((u16_t *)(&pkt->data[0])) = htons(protocol);
180
181 ahdlc_tx(LCP, buffer, 0, (u16_t)(count + 6), 0);
182}
183/*---------------------------------------------------------------------------*/
184#if PACKET_RX_DEBUG
185void
186dump_ppp_packet(u8_t *buffer, u16_t len)
187{
188 int i;
189
190 for(i = 0;i < len; ++i) {
191 if((i & 0x1f) == 0x10) {
192 printf("\n");
193 }
194 printf("%x ",buffer[i]);
195 }
196 printf("\n");
197}
198#endif
199/*---------------------------------------------------------------------------*/
200/* Initialize and start PPP engine. This just sets things up to
201 * starting values. This can stay a private method.
202 */
203/*---------------------------------------------------------------------------*/
204void
205ppp_init()
206{
207#if PACKET_RX_DEBUG
208 ppp_rx_frame_count = 0;
209 done = 0;
210#endif
211 ppp_flags = 0;
212 pap_init();
213 ipcp_init();
214 lcp_init();
215 ppp_flags = 0;
216
217 ahdlc_init(ppp_rx_buffer, PPP_RX_BUFFER_SIZE);
218 ahdlc_rx_ready();
219}
220/*---------------------------------------------------------------------------*/
221/* raise_ppp() - This routine will try to bring up a PPP connection,
222 * It is blocking. In the future we probably want to pass a
223 * structure with all the options on bringing up a PPP link, like
224 * server/client, DSN server, username password for PAP... +++ for
225 * now just use config and bit defines
226 */
227/*---------------------------------------------------------------------------*/
228#if 0
229u16_t
230ppp_raise(u8_t config, u8_t *username, u8_t *password)
231{
232 u16_t status = 0;
233
234 /* Initialize PPP engine */
235 /* init_ppp(); */
236 pap_init();
237 ipcp_init();
238 lcp_init();
239
240 /* Enable PPP */
241 ppp_flags = PPP_RX_READY;
242
243 /* Try to bring up the layers */
244 while(status == 0) {
245#ifdef SYSTEM_POLLER
246 /* If the the serial interrupt is not hooked to ahdlc_rx, or the
247 system needs to handle other stuff while were blocking, call
248 the system poller.*/
249 system_poller();
250#endif
251
252 /* call the lcp task to bring up the LCP layer */
253 lcp_task(ppp_tx_buffer);
254
255 /* If LCP is up, neg next layer */
256 if(lcp_state & LCP_TX_UP) {
257 /* If LCP wants PAP, try to authenticate, else bring up IPCP */
258 if((lcp_state & LCP_RX_AUTH) && (!(pap_state & PAP_TX_UP))) {
259 pap_task(ppp_tx_buffer,username,password);
260 } else {
261 ipcp_task(ppp_tx_buffer);
262 }
263 }
264
265
266 /* If IPCP came up then our link should be up. */
267 if((ipcp_state & IPCP_TX_UP) && (ipcp_state & IPCP_RX_UP)) {
268 break;
269 }
270
271 status = check_ppp_errors();
272 }
273
274 return status;
275}
276#endif
277/*---------------------------------------------------------------------------*/
278void
oliverschmidta0f331a2004-08-22 21:10:02 +0000279ppp_connect(void)
oliverschmidt3396e9a2004-08-20 12:29:54 +0000280{
281 /* Initialize PPP engine */
282 /* init_ppp(); */
283 pap_init();
284 ipcp_init();
285 lcp_init();
286
287 /* Enable PPP */
288 ppp_flags = PPP_RX_READY;
oliverschmidt3396e9a2004-08-20 12:29:54 +0000289}
290/*---------------------------------------------------------------------------*/
291void
292ppp_send(void)
293{
294 /* If IPCP came up then our link should be up. */
295 if((ipcp_state & IPCP_TX_UP) && (ipcp_state & IPCP_RX_UP)) {
296 ahdlc_tx(IPV4, uip_buf, uip_appdata, 40, uip_len - 40);
297 }
298}
299/*---------------------------------------------------------------------------*/
300void
301ppp_poll(void)
302{
303 u8_t c;
304
305 uip_len = 0;
306
307 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;
339 /* DEBUG1(("\n<<<<<<<<<<<<<<-----------\n"));
340 dump_ppp_packet(buffer, len);
341 DEBUG1(("\n<<<<<<<<<<<<<<-----------\n")); */
342 if(ppp_rx_frame_count > 18) {
343 done = 1;
344 }
345#endif
346
347 /* check to see if we have a packet waiting to be processed */
348 if(ppp_flags & PPP_RX_READY) {
349 /* demux on protocol field */
350 switch(protocol) {
351 case LCP: /* We must support some level of LCP */
352 DEBUG1(("LCP Packet - "));
353 lcp_rx(buffer, len);
354 DEBUG1(("\n"));
355 break;
356 case PAP: /* PAP should be compile in optional */
357 DEBUG1(("PAP Packet - "));
358 pap_rx(buffer, len);
359 DEBUG1(("\n"));
360 break;
361 case IPCP: /* IPCP should be compile in optional. */
362 DEBUG1(("IPCP Packet - "));
363 ipcp_rx(buffer, len);
364 DEBUG1(("\n"));
365 break;
366 case IPV4: /* We must support IPV4 */
367 DEBUG1(("IPV4 Packet---\n"));
368 memcpy(uip_buf, buffer, len);
369 uip_len = len;
370 DEBUG1(("\n"));
371 break;
372 default:
373 DEBUG1(("Unknown PPP Packet Type %x - ",protocol));
374 ppp_reject_protocol(protocol, buffer, len);
375 DEBUG1(("\n"));
376 break;
377 }
378 }
379}
380/*---------------------------------------------------------------------------*/
381/* scan_packet(list,buffer,len)
382 *
383 * list = list of supported ID's
384 * *buffer pointer to the first code in the packet
385 * length of the codespace
386 */
387u16_t
388scan_packet(u16_t protocol, u8_t *list, u8_t *buffer, u8_t *options, u16_t len)
389{
390 u8_t *tlist, *bptr;
391 u8_t *tptr;
392 u8_t bad = 0;
393 u8_t i, j, good;
394
395 bptr = tptr = options;
396 /* scan through the packet and see if it has any unsupported codes */
397 while(bptr < options + len) {
398 /* get code and see if it matches somwhere in the list, if not
399 we don't support it */
400 i = *bptr++;
401
402 /* DEBUG2("%x - ",i);*/
403 tlist = list;
404 good = 0;
405 while(*tlist) {
406 /* DEBUG2("%x ",*tlist);*/
407 if(i == *tlist++) {
408 good = 1;
409 break;
410 }
411 }
412 if(!good) {
413 /* we don't understand it, write it back */
414 DEBUG1(("We don't understand option %x\n",i));
415 bad = 1;
416 *tptr++ = i;
417 j = *tptr++ = *bptr++;
418 for(i = 0; i < j - 2; ++i) {
419 *tptr++ = *bptr++;
420 }
421 } else {
422 /* advance over to next option */
423 bptr += *bptr - 1;
424 }
425 }
426
427 /* Bad? if we we need to send a config Reject */
428 if(bad) {
429 /* write the config Rej packet we've built above, take on the header */
430 bptr = buffer;
431 *bptr++ = CONF_REJ; /* Write Conf_rej */
432 bptr++; /* skip over ID */
433 *bptr++ = 0;
434 *bptr = tptr - buffer;
435 /* length right here? */
436
437 /* write the reject frame */
438 DEBUG1(("Writing Reject frame --\n"));
439 ahdlc_tx(protocol, buffer, 0, (u16_t)(tptr - buffer), 0);
440 DEBUG1(("\nEnd writing reject \n"));
441
442 }
443 return bad;
444}
445/*---------------------------------------------------------------------------*/