comparison network/PPP.c @ 110:4eb5a746d7af avr-http

Import avrusbmodem code minus the USB bits. Not built yet.
author Matt Johnston <matt@ucc.asn.au>
date Sat, 15 Sep 2012 21:49:05 +0800
parents 56d09a0969b5
children
comparison
equal deleted inserted replaced
109:315850d48eec 110:4eb5a746d7af
1 /*
2 LUFA Powered Wireless 3G Modem Host
3
4 Copyright (C) Mike Alexander, 2010.
5 Copyright (C) Dean Camera, 2010.
6 */
7
8 /*
9 Copyright 2010 Mike Alexander (mike [at] mikealex [dot] com)
10 Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
11
12 Permission to use, copy, modify, distribute, and sell this
13 software and its documentation for any purpose is hereby granted
14 without fee, provided that the above copyright notice appear in
15 all copies and that both that the copyright notice and this
16 permission notice and warranty disclaimer appear in supporting
17 documentation, and that the name of the author not be used in
18 advertising or publicity pertaining to distribution of the
19 software without specific, written prior permission.
20
21 The author disclaim all warranties with regard to this
22 software, including all implied warranties of merchantability
23 and fitness. In no event shall the author be liable for any
24 special, indirect or consequential damages or any damages
25 whatsoever resulting from loss of use, data or profits, whether
26 in an action of contract, negligence or other tortious action,
27 arising out of or in connection with the use or performance of
28 this software.
29 */
30
31 #define INCLUDE_FROM_PPP_C
32 #include "PPP.h"
33
34 static uint8_t OutgoingPacketID; // Unique packet ID
35 static PPP_Phases_t PPP_Phase; // PPP negotiation phases
36 static PPP_States_t LCP_State; // Each phase has a number of states
37 static PPP_States_t PAP_State;
38 static PPP_States_t IPCP_State;
39 static PPP_Packet_t* OutgoingPacket; // Pointer to the outgoing packet
40 static PPP_Packet_t* IncomingPacket; // Pointer to the incoming packet
41 static uint16_t CurrentProtocol; // Type of the last received packet
42 static uint8_t RestartCount;
43 static uint16_t LinkTimer;
44 static bool TimerOn;
45 static bool MarkForNAK;
46 static bool MarkForREJ;
47 static uint8_t OutgoingPacketBuffer[OUTGOING_PACKET_BUFFER_SIZE]; // Buffer to store the outgoing packet in
48
49 PPP_Packet_t* dummy;
50
51
52 void PPP_InitPPP(void)
53 {
54 PPP_Phase = PPP_PHASE_Dead;
55 TimerOn = false;
56 }
57
58 void PPP_StartLink(void)
59 {
60 OutgoingPacket = NULL;
61 CurrentProtocol = NONE;
62 TimerOn = false;
63 LinkTimer = 0;
64 uip_len = 0;
65 RestartCount = MAX_RESTARTS;
66 MarkForNAK = MarkForREJ = false;
67 OutgoingPacketID = -1;
68 OutgoingPacket = IncomingPacket = NULL;
69 LCP_State = PPP_STATE_Initial;
70 PAP_State = PPP_STATE_Initial;
71 IPCP_State = PPP_STATE_Initial;
72 PPP_Phase = PPP_PHASE_Establish;
73 PPP_ManageState(PPP_EVENT_Open, &LCP_State, PPP_LAYER_Physical);
74 PPP_ManageState(PPP_EVENT_Up, &LCP_State, PPP_LAYER_Physical);
75 }
76
77 // Called every 10ms. Send events to the state machine every 3 seconds if the timer is currently running
78 void PPP_LinkTimer(void)
79 {
80 if (!TimerOn || LinkTimer++ < 300)
81 return;
82
83 if (RestartCount > 0)
84 {
85 Debug_Print("Timer+\r\n");
86
87 switch(PPP_Phase)
88 {
89 case PPP_PHASE_Establish:
90 PPP_ManageState(PPP_EVENT_TOPlus, &LCP_State, PPP_LAYER_Physical);
91 break;
92
93 case PPP_PHASE_Authenticate:
94 PPP_ManageState(PPP_EVENT_TOPlus, &PAP_State, PPP_LAYER_Authentication);
95 break;
96
97 case PPP_PHASE_Network:
98 PPP_ManageState(PPP_EVENT_TOPlus, &IPCP_State, PPP_LAYER_Network);
99 break;
100
101 default:
102 break;
103 }
104 }
105 else
106 {
107 Debug_Print("Timer-\r\n");
108
109 switch(PPP_Phase)
110 {
111 case PPP_PHASE_Establish:
112 PPP_ManageState(PPP_EVENT_TOMinus, &LCP_State, PPP_LAYER_Physical);
113 break;
114
115 case PPP_PHASE_Authenticate:
116 PPP_ManageState(PPP_EVENT_TOMinus, &PAP_State, PPP_LAYER_Authentication);
117 break;
118
119 case PPP_PHASE_Network:
120 PPP_ManageState(PPP_EVENT_TOMinus, &IPCP_State, PPP_LAYER_Network);
121 break;
122
123 default:
124 break;
125 }
126 }
127
128 LinkTimer = 0; // Reset Timer
129 }
130
131 void PPP_ManageLink(void)
132 {
133 if (PPP_Phase == PPP_PHASE_Dead)
134 return;
135
136 uint16_t ReadProtocol = network_read(); // Don't mess with CurrentProtocol in case we get 0 (No data) back
137
138 if (ReadProtocol == 0)
139 return;
140
141 CurrentProtocol = ReadProtocol;
142 IncomingPacket = (PPP_Packet_t*)uip_buf; // Map the incoming data to a packet
143
144 Debug_Print("Got ");
145
146 switch (CurrentProtocol)
147 {
148 case LCP:
149 Debug_Print("LCP ");
150
151 switch(IncomingPacket->Code)
152 {
153 case REQ:
154 Debug_Print("REQ\r\n");
155
156 MarkForNAK = MarkForREJ = false;
157
158 // List of options that we can support. If any other options come in, we have to REJ them
159 const uint8_t SupportedOptions[] = {LCP_OPTION_Maximum_Receive_Unit,
160 LCP_OPTION_Magic_Number,
161 LCP_OPTION_Async_Control_Character_Map,
162 LCP_OPTION_Authentication_Protocol,
163 LCP_OPTION_Protocol_Field_Compression,
164 LCP_OPTION_Address_and_Control_Field_Compression};
165
166 if ((MarkForREJ = PPP_TestForREJ(SupportedOptions, sizeof(SupportedOptions)))) // Check that we can support all the options the other end wants to use
167 {
168 PPP_ManageState(PPP_EVENT_RCRMinus, &LCP_State, PPP_LAYER_Physical);
169 break;
170 }
171
172 static PPP_Option_t Option3 = {.Type = 0x03, .Length = 4, .Data = {0xc0, 0x23}};
173
174 if ((MarkForNAK = PPP_TestForNAK(&Option3))) // Check that the authentication protocol = PAP (0xc023)
175 {
176 PPP_ManageState(PPP_EVENT_RCRMinus, &LCP_State, PPP_LAYER_Physical);
177 break;
178 }
179
180 PPP_ManageState(PPP_EVENT_RCRPlus, &LCP_State, PPP_LAYER_Physical);
181 break;
182
183 case ACK:
184 Debug_Print("ACK\r\n");
185
186 if (IncomingPacket->PacketID != OutgoingPacketID)
187 {
188 Debug_Print("Out of sync\r\n");
189 break;
190 }
191
192 PPP_ManageState(PPP_EVENT_RCA, &LCP_State, PPP_LAYER_Physical);
193 break;
194
195 case NAK:
196 Debug_Print("NAK\r\n");
197
198 if (IncomingPacket->PacketID != OutgoingPacketID)
199 {
200 Debug_Print("Out of sync\r\n");
201 break;
202 }
203
204 PPP_ProcessNAK();
205 PPP_ManageState(PPP_EVENT_RCN, &LCP_State, PPP_LAYER_Physical);
206 break;
207
208 case REJ:
209 Debug_Print("REJ\r\n");
210
211 if (IncomingPacket->PacketID != OutgoingPacketID)
212 {
213 Debug_Print("Out of sync\r\n");
214 break;
215 }
216
217 PPP_ProcessREJ();
218 PPP_ManageState(PPP_EVENT_RCN, &LCP_State, PPP_LAYER_Physical);
219 break;
220
221 case DISC:
222 case ECHOREQ:
223 case ECHOREPLY:
224 Debug_Print("DISC\r\n");
225 PPP_ManageState(PPP_EVENT_RXR, &LCP_State, PPP_LAYER_Physical);
226 break;
227
228 case TERMREQ:
229 Debug_Print("TERM\r\n");
230 PPP_ManageState(PPP_EVENT_RTR, &LCP_State, PPP_LAYER_Physical);
231 break;
232
233 case CODEREJ:
234 case PROTREJ:
235 Debug_Print("CODE/PROTREJ\r\n");
236 PPP_ManageState(PPP_EVENT_RXJMinus, &LCP_State, PPP_LAYER_Physical);
237 break;
238
239 default:
240 Debug_Print("unknown\r\n");
241 PPP_ManageState(PPP_EVENT_RUC, &LCP_State, PPP_LAYER_Physical);
242 break;
243 }
244 break;
245
246 case PAP:
247 Debug_Print("PAP ");
248
249 switch(IncomingPacket->Code)
250 {
251 case REQ:
252 Debug_Print("REQ\r\n");
253 PPP_ManageState(PPP_EVENT_RCRPlus, &PAP_State, PPP_LAYER_Authentication);
254 break;
255
256 case ACK:
257 Debug_Print("ACK\r\n");
258 PPP_ManageState(PPP_EVENT_RCRPlus, &PAP_State, PPP_LAYER_Authentication); // The host never sends a Configure request for PAP, but we need it to move the state machine to completion. So, fake it.
259 PPP_ManageState(PPP_EVENT_RCA, &PAP_State, PPP_LAYER_Authentication);
260 break;
261 }
262 break;
263
264 case IPCP:
265 Debug_Print("IPCP ");
266
267 switch(IncomingPacket->Code)
268 {
269 case REQ:
270 Debug_Print("REQ\r\n");
271
272 MarkForNAK = MarkForREJ = false;
273
274 // List of options that we can support. If any other options come in, we have to REJ them
275 uint8_t SupportedOptions[] = {IPCP_OPTION_IP_address, IPCP_OPTION_Primary_DNS, IPCP_OPTION_Secondary_DNS};
276
277 if ((MarkForREJ = PPP_TestForREJ(SupportedOptions, sizeof(SupportedOptions))))
278 {
279 PPP_ManageState(PPP_EVENT_RCRMinus, &IPCP_State, PPP_LAYER_Network);
280 break;
281 }
282
283 PPP_ManageState(PPP_EVENT_RCRPlus, &IPCP_State, PPP_LAYER_Network);
284 break;
285
286 case ACK:
287 Debug_Print("ACK\r\n");
288
289 if (IncomingPacket->PacketID != OutgoingPacketID)
290 {
291 Debug_Print("Out of sync\r\n");
292 break;
293 }
294
295 IPAddr1 = IncomingPacket->Options[0].Data[0]; // Store address for use in IP packets.
296 IPAddr2 = IncomingPacket->Options[0].Data[1]; // Assumption is that Option 3 is the first option, which it
297 IPAddr3 = IncomingPacket->Options[0].Data[2]; // should be as the PPP spec states that implementations should
298 IPAddr4 = IncomingPacket->Options[0].Data[3]; // not reorder packets, and we sent out a REQ with option 3 first
299
300 PPP_ManageState(PPP_EVENT_RCA, &IPCP_State, PPP_LAYER_Network);
301 break;
302
303 case NAK:
304 Debug_Print("NAK\r\n");
305 if (IncomingPacket->PacketID != OutgoingPacketID)
306 {
307 Debug_Print("Out of sync\r\n");
308 break;
309 }
310
311 PPP_ProcessNAK();
312 PPP_ManageState(PPP_EVENT_RCN, &IPCP_State, PPP_LAYER_Network);
313 break;
314
315 case REJ:
316 Debug_Print("REJ\r\n");
317
318 if (IncomingPacket->PacketID != OutgoingPacketID)
319 {
320 Debug_Print("Out of sync\r\n");
321 break;
322 }
323
324 PPP_ProcessREJ();
325 PPP_ManageState(PPP_EVENT_RCN, &IPCP_State, PPP_LAYER_Network);
326 break;
327 }
328 break;
329
330 case IP:
331 TCPIP_GotNewPacket();
332 break;
333
334 default:
335 Debug_Print("unknown protocol: 0x");
336 Debug_PrintHex(CurrentProtocol / 256); Debug_PrintHex(CurrentProtocol & 255);
337 Debug_Print("\r\n");
338 break;
339 }
340 }
341
342
343 // Either create a new OutgoingPacket, or if we've just received a NAK or REJ we will have already changed the OutgoingPacket so just send that
344 static void Send_Configure_Request(void)
345 {
346 Debug_Print("Send Configure Request\r\n");
347
348 switch(PPP_Phase)
349 {
350 case PPP_PHASE_Establish:
351 if (OutgoingPacket == NULL) // Create a new packet
352 {
353 // When we send a REQ, we want to make sure that the other end supports these options
354 // static PPP_Option_t Option1 = {.Type = LCP_OPTION_Maximum_Receive_Unit, .Length = 4, .Data = {0x5, 0xa0}};
355 static PPP_Option_t Option2 = {.Type = LCP_OPTION_Async_Control_Character_Map, .Length = 6, .Data = {0x0, 0x0, 0x0, 0x0}};
356 static PPP_Option_t Option5 = {.Type = LCP_OPTION_Magic_Number, .Length = 6, .Data = {0x27, 0xf5, 0x46, 0xa1}};
357 static PPP_Option_t Option7 = {.Type = LCP_OPTION_Protocol_Field_Compression, .Length = 2};
358 static PPP_Option_t Option8 = {.Type = LCP_OPTION_Address_and_Control_Field_Compression, .Length = 2};
359 static PPP_Option_t OptionD = {.Type = LCP_OPTION_Callback, .Length = 3, .Data = {0x6}};
360
361 //PPP_AddOption(OutgoingPacket, &Option1);
362 PPP_AddOption(&Option2);
363 PPP_AddOption(&Option5);
364 PPP_AddOption(&Option7);
365 PPP_AddOption(&Option8);
366 PPP_AddOption(&OptionD);
367 OutgoingPacket->Code = REQ;
368 CurrentProtocol = LCP;
369 }
370 break;
371
372 case PPP_PHASE_Authenticate:
373 if (OutgoingPacket == NULL) // Create a new packet
374 {
375 static PPP_Option_t Option0 = {.Type = 0x00, .Length = 2};
376
377 PPP_AddOption(&Option0);
378 OutgoingPacket->Options[0].Type = 0x00; // No User Name
379 OutgoingPacket->Options[0].Length = 0x00; // No Password
380 OutgoingPacket->Code = REQ;
381 CurrentProtocol = PAP;
382 }
383 break;
384
385 case PPP_PHASE_Network:
386 if (OutgoingPacket == NULL) // Create a new packet
387 {
388 // When we send a REQ, we want to make sure that the other end supports these options
389 static PPP_Option_t Option3 = {.Type = IPCP_OPTION_IP_address, .Length = 6, .Data = {0, 0, 0, 0}};
390 static PPP_Option_t Option81 = {.Type = IPCP_OPTION_Primary_DNS, .Length = 6, .Data = {0, 0, 0, 0}};
391 static PPP_Option_t Option83 = {.Type = IPCP_OPTION_Secondary_DNS, .Length = 6, .Data = {0, 0, 0, 0}};
392
393 PPP_AddOption(&Option3); // Make sure Option3 is first
394 PPP_AddOption(&Option81);
395 PPP_AddOption(&Option83);
396 OutgoingPacket->Code = REQ;
397 CurrentProtocol = IPCP;
398 }
399 break;
400
401 default:
402 break;
403 }
404
405 OutgoingPacket->PacketID = ++OutgoingPacketID; // Every new REQ Packet going out gets a new ID
406 RestartCount--; // Decrement the count before we restart the layer
407 uip_len = uip_ntohs(OutgoingPacket->Length);
408 memcpy(uip_buf, OutgoingPacket, uip_len); // Copy the outgoing packet to the buffer for sending
409
410 network_send(CurrentProtocol); // Send either the new packet or the modified packet
411 }
412
413
414 // We change the incoming packet code to send an ACK to the remote end, and re-use all the data from the incoming packet
415 static void Send_Configure_Ack(void)
416 {
417 Debug_Print("Send Configure ACK\r\n");
418
419 IncomingPacket->Code = ACK;
420 network_send(CurrentProtocol);
421 }
422
423 // We change the incoming packet code to send a NAK or REJ to the remote end. The incoming packet has already been altered to show which options to NAK/REJ
424 static void Send_Configure_Nak_Rej(void)
425 {
426 if (MarkForNAK)
427 {
428 Debug_Print("Send Configure NAK\r\n");
429 IncomingPacket->Code = NAK;
430 }
431 else if (MarkForREJ)
432 {
433 Debug_Print("Send Configure REJ\r\n");
434 IncomingPacket->Code = REJ;
435 }
436 else
437 {
438 return;
439 }
440
441 uip_len = uip_ntohs(IncomingPacket->Length);
442 network_send(CurrentProtocol);
443 }
444
445 // Send a TERM to the remote end.
446 static void Send_Terminate_Request(void)
447 {
448 Debug_Print("Send Terminate Request\r\n");
449
450 OutgoingPacket = (PPP_Packet_t*)uip_buf; // Build the outgoing packet in uip_buf
451 CurrentProtocol = LCP;
452 OutgoingPacket->Code = TERMREQ;
453 OutgoingPacket->Length = UIP_HTONS(sizeof(PPP_Packet_t));
454 OutgoingPacket->PacketID = ++OutgoingPacketID; // Every new REQ Packet going out gets a new ID
455
456 RestartCount--;
457
458 uip_len = uip_ntohs(OutgoingPacket->Length);
459 network_send(CurrentProtocol); // Send the packet
460 }
461
462 // Send a TERM ACK to the remote end.
463 static void Send_Terminate_Ack(void)
464 {
465 Debug_Print("Send Terminate ACK\r\n");
466
467 IncomingPacket->Code = TERMREPLY;
468 network_send(CurrentProtocol);
469 }
470
471 // Send a REJ to the remote end.
472 static void Send_Code_Reject(void)
473 {
474 Debug_Print("Send Code Reject\r\n");
475
476 IncomingPacket->Code = CODEREJ;
477 network_send(CurrentProtocol);
478 }
479
480 // Send an ECHO to the remote end.
481 static void Send_Echo_Reply(void)
482 {
483 Debug_Print("Send Echo Reply\r\n");
484
485 IncomingPacket->Code = ECHOREPLY;
486 network_send(CurrentProtocol);
487 }
488
489 // Called by the state machine when the current layer comes up. Use this to start the next layer up.
490 static void This_Layer_Up(PPP_Layers_t Layer)
491 {
492 CurrentProtocol = NONE;
493 OutgoingPacket = NULL; // Clear the outgoing packet
494
495 switch(Layer)
496 {
497 case PPP_LAYER_Physical:
498 Debug_Print("**LCP Up**\r\n");
499 PPP_Phase = PPP_PHASE_Authenticate;
500 OutgoingPacketID = -1;
501 PPP_ManageState(PPP_EVENT_Open, &PAP_State, PPP_LAYER_Authentication);
502 PPP_ManageState(PPP_EVENT_Up, &PAP_State, PPP_LAYER_Authentication);
503 break;
504
505 case PPP_LAYER_Authentication:
506 Debug_Print("**PAP Up**\r\n");
507 PPP_Phase = PPP_PHASE_Network;
508 OutgoingPacketID = -1;
509 PPP_ManageState(PPP_EVENT_Open, &IPCP_State, PPP_LAYER_Network);
510 PPP_ManageState(PPP_EVENT_Up, &IPCP_State, PPP_LAYER_Network);
511 break;
512
513 case PPP_LAYER_Network:
514 Debug_Print("**IPCP Up**\r\n");
515 ConnectedState = LINKMANAGEMENT_STATE_InitializeTCPStack;
516 break;
517
518 default:
519 break;
520 }
521 }
522
523 // Called by the state machine when a layer goes down. Use this to stop the next layer up
524 static void This_Layer_Down(PPP_Layers_t Layer)
525 {
526 OutgoingPacket = NULL; // Clear the outgoing packet
527
528 switch(Layer)
529 {
530 case PPP_LAYER_Physical:
531 Debug_Print("**LCP Down**\r\n");
532 PPP_ManageState(PPP_EVENT_Down, &PAP_State, PPP_LAYER_Authentication);
533 PPP_Phase = PPP_PHASE_Establish;
534 break;
535
536 case PPP_LAYER_Authentication:
537 Debug_Print("**PAP Down**\r\n");
538 PPP_ManageState(PPP_EVENT_Down, &IPCP_State, PPP_LAYER_Network);
539 break;
540
541 case PPP_LAYER_Network:
542 Debug_Print("**IPCP Down**\r\n");
543 break;
544
545 default:
546 break;
547 }
548 }
549
550 // Called by the state machine when the current layer starts
551 static void This_Layer_Started(PPP_Layers_t Layer)
552 {
553 switch(Layer)
554 {
555 case PPP_LAYER_Physical:
556 Debug_Print("**LCP Started**\r\n");
557 break;
558
559 case PPP_LAYER_Authentication:
560 Debug_Print("**PAP Started**\r\n");
561 break;
562
563 case PPP_LAYER_Network:
564 Debug_Print("**IPCP Started**\r\n");
565 break;
566
567 default:
568 break;
569 }
570 }
571
572 // Called by the state machine when the current layer finishes
573 static void This_Layer_Finished(PPP_Layers_t Layer)
574 {
575 switch(Layer)
576 {
577 case PPP_LAYER_Physical:
578 Debug_Print("**LCP Finished**\r\n");
579 break;
580
581 case PPP_LAYER_Authentication:
582 Debug_Print("**PAP Finished**\r\n");
583 break;
584
585 case PPP_LAYER_Network:
586 Debug_Print("**IPCP Finished**\r\n");
587 break;
588
589 default:
590 break;
591 }
592
593 Debug_Print("**Rebooting**\r\n");
594 Reboot();
595 }
596
597
598 // We get a NAK if our outbound Configure Request contains valid options, but the values are wrong. So we adjust our values for when the next Configure Request is sent
599 static void PPP_ProcessNAK(void)
600 {
601 PPP_Option_t* CurrentOption = NULL;
602
603 while ((CurrentOption = PPP_GetNextOption(IncomingPacket, CurrentOption)) != NULL) // Scan options in NAK packet
604 {
605 if (PPP_CheckForOption(CurrentOption))
606 PPP_ChangeOption(OutgoingPacket, CurrentOption); // If the NAK'd option is already in the outgoing packet then change the existing option
607 else
608 PPP_AddOption(CurrentOption); // Otherwise add it
609 }
610 }
611
612 // We get a REJ if our outbound Configure Request contains any options not acceptable to the remote end. So we remove those options.
613 static void PPP_ProcessREJ(void)
614 {
615 PPP_Option_t* CurrentOption = NULL;
616
617 while ((CurrentOption = PPP_GetNextOption(IncomingPacket, CurrentOption)) != NULL) // Scan options in REJ packet
618 PPP_RemoveOption(OutgoingPacket, CurrentOption->Type); // Remove the options(s) we don't want
619 }
620
621 // Test to see if the incoming packet contains any options we can't support If so, take out all good options and leave the bad ones to be sent out in the REJ
622 static bool PPP_TestForREJ(const uint8_t Options[],
623 const uint8_t NumOptions)
624 {
625 PPP_Option_t* CurrentOption = NULL;
626 bool FoundBadOption = false;
627 bool ThisOptionOK;
628
629 while ((CurrentOption = PPP_GetNextOption(IncomingPacket, CurrentOption)) != NULL) // Scan incoming options
630 {
631 ThisOptionOK = false;
632
633 for (uint8_t i = 0; i < NumOptions; i++)
634 {
635 if (CurrentOption->Type == Options[i])
636 {
637 ThisOptionOK = true;
638 break;
639 }
640 }
641
642 if (!ThisOptionOK)
643 FoundBadOption = true;
644 }
645
646 if (!FoundBadOption) // No bad options. Return, leaving the packet untouched
647 return false;
648
649 // We found some bad options, so now we need to go through the packet and remove all others, leaving the bad options to be sent out in the REJ
650 while ((CurrentOption = PPP_GetNextOption(IncomingPacket, CurrentOption)) != NULL)
651 {
652 for (uint8_t i = 0; i < NumOptions; i++)
653 {
654 if (CurrentOption->Type == Options[i])
655 {
656 PPP_RemoveOption(IncomingPacket, CurrentOption->Type);
657 CurrentOption = NULL; // Start again. Easier than moving back (as next option has now moved into place of current option)
658 break;
659 }
660 }
661 }
662
663 return true;
664 }
665
666 // Test to see if the incoming packet contains an option with values that we can't accept
667 static bool PPP_TestForNAK(const PPP_Option_t* const Option)
668 {
669 PPP_Option_t* CurrentOption = NULL;
670 bool FoundBadOption = false;
671
672 while ((CurrentOption = PPP_GetNextOption(IncomingPacket, CurrentOption)) != NULL) // Scan options in receiver buffer
673 {
674 if (CurrentOption->Type == Option->Type)
675 {
676 for (uint8_t i = 0; i < Option->Length - 2; i++)
677 {
678 if (CurrentOption->Data[i] != Option->Data[i])
679 FoundBadOption = true;
680 }
681 }
682 }
683
684 if (!FoundBadOption) // No bad option. Return, leaving the packet untouched
685 return false;
686
687 // We found a bad option, so now we need to go through the packet and remove all others, leaving the bad option to be sent out in the NAK
688 // and change the bad option to have a value that we can support
689 while ((CurrentOption = PPP_GetNextOption(IncomingPacket, CurrentOption)) != NULL)
690 {
691 if (CurrentOption->Type == Option->Type)
692 {
693 PPP_ChangeOption(IncomingPacket, Option);
694 }
695 else
696 {
697 PPP_RemoveOption(IncomingPacket, CurrentOption->Type);
698 CurrentOption = NULL; // Start again. Easier than moving back (as next option has now moved into place of current option)
699 }
700 }
701
702 return true;
703 }
704
705
706 /////////////////////////////
707 // Packet Helper functions //
708 /////////////////////////////
709
710 // Check if the given option is in the outgoing packet
711 static bool PPP_CheckForOption(const PPP_Option_t* const Option)
712 {
713 PPP_Option_t* CurrentOption = NULL;
714
715 while ((CurrentOption = PPP_GetNextOption(OutgoingPacket, CurrentOption)) != NULL) // Scan options in the packet
716 {
717 if (CurrentOption->Type == Option->Type)
718 return true;
719 }
720
721 return false;
722 }
723
724 // Add the given option to the end of the outgoing packet and adjust the size of the packet
725 static void PPP_AddOption(const PPP_Option_t* const Option)
726 {
727 uint16_t OldPacketLength, NewPacketLength;
728
729 if (OutgoingPacket == NULL)
730 {
731 OutgoingPacket = (PPP_Packet_t*)&OutgoingPacketBuffer;
732 OldPacketLength = sizeof(PPP_Packet_t); // If we're creating a new empty packet
733 }
734 else
735 OldPacketLength = uip_ntohs(OutgoingPacket->Length); // If the packet already exists
736
737 NewPacketLength = OldPacketLength + Option->Length;
738
739 if (NewPacketLength > OUTGOING_PACKET_BUFFER_SIZE)
740 {
741 Debug_Print("*** Packet overflow ***\r\n");
742 return;
743 }
744
745 memcpy((void*)OutgoingPacket + OldPacketLength, Option, Option->Length); // Add the new option
746
747 OutgoingPacket->Length = uip_htons(NewPacketLength);
748 }
749
750 // Try and find the option in the packet, and if it exists, change its value to that in the passed-in option (assumes the option lengths are the same)
751 static void PPP_ChangeOption(PPP_Packet_t* const ThisPacket,
752 const PPP_Option_t* const Option)
753 {
754 PPP_Option_t* CurrentOption = NULL;
755
756 while ((CurrentOption = PPP_GetNextOption(ThisPacket, CurrentOption)) != NULL) // Scan options in the packet
757 {
758 if (CurrentOption->Type == Option->Type)
759 memcpy(CurrentOption->Data, Option->Data, Option->Length - 2); // Copy the data portion of the option (not Type or Length)
760 }
761 }
762
763 // Try and find the option in the packet, and if it exists remove it and adjust the size of the packet
764 static void PPP_RemoveOption(PPP_Packet_t* const ThisPacket,
765 const uint8_t Type)
766 {
767 PPP_Option_t* CurrentOption = NULL;
768 PPP_Option_t* NextOption = NULL;
769
770 while ((CurrentOption = PPP_GetNextOption(ThisPacket, CurrentOption)) != NULL) // Scan the options in the packet
771 {
772 if (CurrentOption->Type == Type) // Is it the packet we want to remove?
773 {
774 NextOption = PPP_GetNextOption(ThisPacket, CurrentOption); // Find the next option in the packet
775 uint8_t OptionLength = CurrentOption->Length; // Save the Option Length as the memcpy will change CurrentOption->Length
776
777 if (NextOption != NULL) // If it's not the last option in the packet ...
778 {
779 uint16_t LenToCopy = uip_ntohs(ThisPacket->Length) - ((void*)CurrentOption - (void*)ThisPacket) - OptionLength;
780 memcpy(CurrentOption, NextOption, LenToCopy); // ... move all further options forward
781 }
782
783 ThisPacket->Length = uip_htons(uip_ntohs(ThisPacket->Length) - OptionLength); // Adjust the length
784 }
785 }
786 }
787
788 // Get the next option in the packet from the option that is passed in. Return NULL if last packet
789 static PPP_Option_t* PPP_GetNextOption(const PPP_Packet_t* const ThisPacket,
790 const PPP_Option_t* const CurrentOption)
791 {
792 PPP_Option_t* NextOption;
793
794 if (CurrentOption == NULL)
795 NextOption = (PPP_Option_t*)ThisPacket->Options; // First option
796 else
797 NextOption = (PPP_Option_t*)((uint8_t*)CurrentOption + CurrentOption->Length);
798
799 // Check that we haven't overrun the end of the packet
800 if (((void*)NextOption - (void*)ThisPacket->Options) < (uip_ntohs(ThisPacket->Length) - 4))
801 return NextOption;
802 else
803 return NULL;
804 }
805
806
807
808 /////////////////////////////////////////////////////////////////////////////////////////
809 // The main PPP state machine - following RFC1661 - http://tools.ietf.org/html/rfc1661 //
810 /////////////////////////////////////////////////////////////////////////////////////////
811
812 static void PPP_ManageState(const PPP_Events_t Event,
813 PPP_States_t* const State,
814 PPP_Layers_t const Layer)
815 {
816 switch (*State)
817 {
818 case PPP_STATE_Initial:
819
820 switch (Event)
821 {
822 case PPP_EVENT_Up:
823 *State = PPP_STATE_Closed;
824 break;
825
826 case PPP_EVENT_Open:
827 *State = PPP_STATE_Starting;
828 This_Layer_Started(Layer);
829 break;
830
831 case PPP_EVENT_Close:
832 *State = PPP_STATE_Initial;
833 break;
834
835 case PPP_EVENT_TOPlus:
836 case PPP_EVENT_TOMinus:
837 break;
838
839 default:
840 Debug_Print("Illegal Event\r\n");
841 break;
842 }
843 break;
844
845 case PPP_STATE_Starting:
846
847 switch (Event)
848 {
849 case PPP_EVENT_Up:
850 *State = PPP_STATE_Req_Sent;
851 RestartCount = MAX_RESTARTS;
852 LinkTimer = 0;
853 TimerOn = true;
854 Send_Configure_Request();
855 break;
856
857 case PPP_EVENT_Open:
858 *State = PPP_STATE_Starting;
859 break;
860
861 case PPP_EVENT_Close:
862 *State = PPP_STATE_Initial;
863 This_Layer_Finished(Layer);
864 break;
865
866 case PPP_EVENT_TOPlus:
867 case PPP_EVENT_TOMinus:
868 break;
869
870 default:
871 Debug_Print("Illegal Event\r\n");
872 break;
873 }
874 break;
875
876 case PPP_STATE_Closed:
877
878 switch (Event)
879 {
880 case PPP_EVENT_Down:
881 *State = PPP_STATE_Initial;
882 break;
883
884 case PPP_EVENT_Open:
885 *State = PPP_STATE_Req_Sent;
886 RestartCount = MAX_RESTARTS;
887 LinkTimer = 0;
888 TimerOn = true;
889 Send_Configure_Request();
890 break;
891
892 case PPP_EVENT_Close:
893 case PPP_EVENT_RTA:
894 case PPP_EVENT_RXJPlus:
895 case PPP_EVENT_RXR:
896 *State = PPP_STATE_Closed;
897 break;
898
899 case PPP_EVENT_RCRPlus:
900 case PPP_EVENT_RCRMinus:
901 case PPP_EVENT_RCA:
902 case PPP_EVENT_RCN:
903 *State = PPP_STATE_Closed;
904 Send_Terminate_Ack();
905 break;
906
907 case PPP_EVENT_TOPlus:
908 case PPP_EVENT_TOMinus:
909 break;
910
911 default:
912 Debug_Print("Illegal Event\r\n");
913 break;
914 }
915 break;
916
917 case PPP_STATE_Stopped:
918
919 switch (Event)
920 {
921 case PPP_EVENT_Down:
922 *State = PPP_STATE_Starting;
923 This_Layer_Started(Layer);
924 break;
925
926 case PPP_EVENT_Open:
927 *State = PPP_STATE_Stopped;
928 break;
929
930 case PPP_EVENT_Close:
931 *State = PPP_STATE_Closed;
932 break;
933
934 case PPP_EVENT_RCRPlus:
935 *State = PPP_STATE_Ack_Sent;
936 RestartCount = MAX_RESTARTS;
937 LinkTimer = 0;
938 TimerOn = true;
939 Send_Configure_Request();
940 Send_Configure_Ack();
941 break;
942
943 case PPP_EVENT_RCRMinus:
944 *State = PPP_STATE_Req_Sent;
945 RestartCount = MAX_RESTARTS;
946 LinkTimer = 0;
947 TimerOn = true;
948 Send_Configure_Request();
949 Send_Configure_Nak_Rej();
950 break;
951
952 case PPP_EVENT_RCA:
953 case PPP_EVENT_RCN:
954 case PPP_EVENT_RTR:
955 *State = PPP_STATE_Stopped;
956 Send_Terminate_Ack();
957 break;
958
959 case PPP_EVENT_RTA:
960 case PPP_EVENT_RXJPlus:
961 case PPP_EVENT_RXR:
962 *State = PPP_STATE_Stopped;
963 break;
964
965 case PPP_EVENT_RUC:
966 *State = PPP_STATE_Stopped;
967 Send_Code_Reject();
968 break;
969
970 case PPP_EVENT_RXJMinus:
971 *State = PPP_STATE_Stopped;
972 This_Layer_Finished(Layer);
973 break;
974
975 case PPP_EVENT_TOPlus:
976 case PPP_EVENT_TOMinus:
977 break;
978
979 default:
980 Debug_Print("Illegal Event\r\n");
981 break;
982 }
983 break;
984
985 case PPP_STATE_Closing:
986
987 switch (Event)
988 {
989 case PPP_EVENT_Down:
990 TimerOn = false;
991 *State = PPP_STATE_Initial;
992 break;
993
994 case PPP_EVENT_Open:
995 *State = PPP_STATE_Stopping;
996 break;
997
998 case PPP_EVENT_Close:
999 *State = PPP_STATE_Closing;
1000 break;
1001
1002 case PPP_EVENT_TOPlus:
1003 Send_Terminate_Request();
1004 *State = PPP_STATE_Closing;
1005 break;
1006
1007 case PPP_EVENT_TOMinus:
1008 *State = PPP_STATE_Closed;
1009 TimerOn = false;
1010 This_Layer_Finished(Layer);
1011 break;
1012
1013 case PPP_EVENT_RCRPlus:
1014 case PPP_EVENT_RCRMinus:
1015 case PPP_EVENT_RCA:
1016 case PPP_EVENT_RCN:
1017 case PPP_EVENT_RXJPlus:
1018 case PPP_EVENT_RXR:
1019 *State = PPP_STATE_Closing;
1020 break;
1021
1022 case PPP_EVENT_RTR:
1023 *State = PPP_STATE_Closing;
1024 Send_Terminate_Ack();
1025 break;
1026
1027 case PPP_EVENT_RTA:
1028 case PPP_EVENT_RXJMinus:
1029 *State = PPP_STATE_Closed;
1030 TimerOn = false;
1031 This_Layer_Finished(Layer);
1032 break;
1033
1034 case PPP_EVENT_RUC:
1035 *State = PPP_STATE_Closing;
1036 Send_Code_Reject();
1037 break;
1038
1039 default:
1040 Debug_Print("Illegal Event\r\n");
1041 break;
1042 }
1043 break;
1044
1045 case PPP_STATE_Stopping:
1046
1047 switch (Event)
1048 {
1049 case PPP_EVENT_Down:
1050 *State = PPP_STATE_Starting;
1051 TimerOn = false;
1052 break;
1053
1054 case PPP_EVENT_Open:
1055 *State = PPP_STATE_Stopping;
1056 break;
1057
1058 case PPP_EVENT_Close:
1059 *State = PPP_STATE_Closing;
1060 break;
1061
1062 case PPP_EVENT_TOPlus:
1063 Send_Terminate_Request();
1064 *State = PPP_STATE_Stopping;
1065 break;
1066
1067 case PPP_EVENT_TOMinus:
1068 This_Layer_Finished(Layer);
1069 TimerOn = false;
1070 *State = PPP_STATE_Stopped;
1071 break;
1072
1073 case PPP_EVENT_RCRPlus:
1074 case PPP_EVENT_RCRMinus:
1075 case PPP_EVENT_RCA:
1076 case PPP_EVENT_RCN:
1077 case PPP_EVENT_RXJPlus:
1078 case PPP_EVENT_RXR:
1079 *State = PPP_STATE_Stopping;
1080 break;
1081
1082 case PPP_EVENT_RTR:
1083 Send_Terminate_Ack();
1084 *State = PPP_STATE_Stopping;
1085 break;
1086
1087 case PPP_EVENT_RTA:
1088 case PPP_EVENT_RXJMinus:
1089 This_Layer_Finished(Layer);
1090 TimerOn = false;
1091 *State = PPP_STATE_Stopped;
1092 break;
1093
1094 case PPP_EVENT_RUC:
1095 Send_Code_Reject();
1096 *State = PPP_STATE_Stopping;
1097 break;
1098
1099 default:
1100 Debug_Print("Illegal Event\r\n");
1101 break;
1102 }
1103 break;
1104
1105 case PPP_STATE_Req_Sent:
1106
1107 switch (Event)
1108 {
1109 case PPP_EVENT_Down:
1110 *State = PPP_STATE_Starting;
1111 TimerOn = false;
1112 break;
1113
1114 case PPP_EVENT_Open:
1115 case PPP_EVENT_RTA:
1116 case PPP_EVENT_RXJPlus:
1117 case PPP_EVENT_RXR:
1118 *State = PPP_STATE_Req_Sent;
1119 break;
1120
1121 case PPP_EVENT_Close:
1122 RestartCount = MAX_RESTARTS;
1123 LinkTimer = 0;
1124 Send_Terminate_Request();
1125 *State = PPP_STATE_Closing;
1126 break;
1127
1128 case PPP_EVENT_TOPlus:
1129 Send_Configure_Request();
1130 *State = PPP_STATE_Req_Sent;
1131 break;
1132
1133 case PPP_EVENT_TOMinus:
1134 This_Layer_Finished(Layer);
1135 TimerOn = false;
1136 *State = PPP_STATE_Stopped;
1137 break;
1138
1139 case PPP_EVENT_RCRPlus:
1140 if (Layer != PPP_LAYER_Authentication) // We faked a Configure request for PAP. So no need to answer it if we're in the authentication phase
1141 Send_Configure_Ack();
1142
1143 *State = PPP_STATE_Ack_Sent;
1144 break;
1145
1146 case PPP_EVENT_RCRMinus:
1147 Send_Configure_Nak_Rej();
1148 *State = PPP_STATE_Req_Sent;
1149 break;
1150
1151 case PPP_EVENT_RCA:
1152 RestartCount = MAX_RESTARTS;
1153 LinkTimer = 0;
1154 *State = PPP_STATE_Ack_Rcvd;
1155 break;
1156
1157 case PPP_EVENT_RCN:
1158 RestartCount = MAX_RESTARTS;
1159 LinkTimer = 0;
1160 Send_Configure_Request();
1161 *State = PPP_STATE_Req_Sent;
1162 break;
1163
1164 case PPP_EVENT_RTR:
1165 Send_Terminate_Ack();
1166 *State = PPP_STATE_Req_Sent;
1167 break;
1168
1169 case PPP_EVENT_RUC:
1170 Send_Code_Reject();
1171 *State = PPP_STATE_Req_Sent;
1172 break;
1173
1174 case PPP_EVENT_RXJMinus:
1175 This_Layer_Finished(Layer);
1176 TimerOn = false;
1177 *State = PPP_STATE_Stopped;
1178 break;
1179
1180 default:
1181 Debug_Print("Illegal Event\r\n");
1182 break;
1183 }
1184 break;
1185
1186 case PPP_STATE_Ack_Rcvd:
1187
1188 switch (Event)
1189 {
1190 case PPP_EVENT_Down:
1191 *State = PPP_STATE_Starting;
1192 TimerOn = false;
1193 break;
1194
1195 case PPP_EVENT_Open:
1196 case PPP_EVENT_RXR:
1197 *State = PPP_STATE_Ack_Rcvd;
1198 break;
1199
1200 case PPP_EVENT_Close:
1201 RestartCount = MAX_RESTARTS;
1202 LinkTimer = 0;
1203 Send_Terminate_Request();
1204 *State = PPP_STATE_Closing;
1205 break;
1206
1207 case PPP_EVENT_TOPlus:
1208 case PPP_EVENT_RCA:
1209 case PPP_EVENT_RCN:
1210 Send_Configure_Request();
1211 *State = PPP_STATE_Req_Sent;
1212 break;
1213
1214 case PPP_EVENT_TOMinus:
1215 This_Layer_Finished(Layer);
1216 TimerOn = false;
1217 *State = PPP_STATE_Stopped;
1218 break;
1219
1220 case PPP_EVENT_RCRPlus:
1221 Send_Configure_Ack();
1222 This_Layer_Up(Layer);
1223 TimerOn = false;
1224 *State = PPP_STATE_Opened;
1225 break;
1226
1227 case PPP_EVENT_RCRMinus:
1228 Send_Configure_Nak_Rej();
1229 *State = PPP_STATE_Ack_Rcvd;
1230 break;
1231
1232 case PPP_EVENT_RTR:
1233 Send_Terminate_Ack();
1234 *State = PPP_STATE_Req_Sent;
1235 break;
1236
1237 case PPP_EVENT_RTA:
1238 case PPP_EVENT_RXJPlus:
1239 Send_Terminate_Ack();
1240 *State = PPP_STATE_Req_Sent;
1241 break;
1242
1243 case PPP_EVENT_RUC:
1244 Send_Code_Reject();
1245 *State = PPP_STATE_Ack_Rcvd;
1246 break;
1247
1248 case PPP_EVENT_RXJMinus:
1249 This_Layer_Finished(Layer);
1250 TimerOn = false;
1251 *State = PPP_STATE_Stopped;
1252 break;
1253
1254 default:
1255 Debug_Print("Illegal Event\r\n");
1256 break;
1257 }
1258 break;
1259
1260 case PPP_STATE_Ack_Sent:
1261
1262 switch (Event)
1263 {
1264 case PPP_EVENT_Down:
1265 *State = PPP_STATE_Starting;
1266 TimerOn = false;
1267 break;
1268
1269 case PPP_EVENT_Open:
1270 case PPP_EVENT_RTA:
1271 case PPP_EVENT_RXJPlus:
1272 case PPP_EVENT_RXR:
1273 *State = PPP_STATE_Ack_Sent;
1274 break;
1275
1276 case PPP_EVENT_Close:
1277 RestartCount = MAX_RESTARTS;
1278 LinkTimer = 0;
1279 Send_Terminate_Request();
1280 *State = PPP_STATE_Closing;
1281 break;
1282
1283 case PPP_EVENT_TOPlus:
1284 Send_Configure_Request();
1285 *State = PPP_STATE_Ack_Sent;
1286 break;
1287
1288 case PPP_EVENT_TOMinus:
1289 This_Layer_Finished(Layer);
1290 TimerOn = false;
1291 *State = PPP_STATE_Stopped;
1292 break;
1293
1294 case PPP_EVENT_RCRPlus:
1295 Send_Configure_Ack();
1296 *State = PPP_STATE_Ack_Sent;
1297 break;
1298
1299 case PPP_EVENT_RCRMinus:
1300 Send_Configure_Nak_Rej();
1301 *State = PPP_STATE_Req_Sent;
1302 break;
1303
1304 case PPP_EVENT_RCA:
1305 RestartCount = MAX_RESTARTS;
1306 LinkTimer = 0;
1307 TimerOn = false;
1308 This_Layer_Up(Layer);
1309 *State = PPP_STATE_Opened;
1310 break;
1311
1312 case PPP_EVENT_RCN:
1313 RestartCount = MAX_RESTARTS;
1314 LinkTimer = 0;
1315 Send_Configure_Request();
1316 *State = PPP_STATE_Ack_Sent;
1317 break;
1318
1319 case PPP_EVENT_RTR:
1320 Send_Terminate_Ack();
1321 *State = PPP_STATE_Req_Sent;
1322 break;
1323
1324 case PPP_EVENT_RUC:
1325 Send_Code_Reject();
1326 *State = PPP_STATE_Ack_Sent;
1327 break;
1328
1329 case PPP_EVENT_RXJMinus:
1330 This_Layer_Finished(Layer);
1331 TimerOn = false;
1332 *State = PPP_STATE_Stopped;
1333 break;
1334
1335 default:
1336 Debug_Print("Illegal Event\r\n");
1337 break;
1338 }
1339 break;
1340
1341 case PPP_STATE_Opened:
1342
1343 switch (Event)
1344 {
1345 case PPP_EVENT_Down:
1346 This_Layer_Down(Layer);
1347 *State = PPP_STATE_Starting;
1348 break;
1349
1350 case PPP_EVENT_Open:
1351 case PPP_EVENT_RXJPlus:
1352 *State = PPP_STATE_Opened;
1353 break;
1354
1355 case PPP_EVENT_Close:
1356 This_Layer_Down(Layer);
1357 RestartCount = MAX_RESTARTS;
1358 LinkTimer = 0;
1359 TimerOn = true;
1360 Send_Terminate_Request();
1361 *State = PPP_STATE_Closing;
1362 break;
1363
1364 case PPP_EVENT_RCRPlus:
1365 This_Layer_Down(Layer);
1366 TimerOn = true;
1367 Send_Configure_Request();
1368 Send_Configure_Ack();
1369 *State = PPP_STATE_Ack_Sent;
1370 break;
1371
1372 case PPP_EVENT_RCRMinus:
1373 This_Layer_Down(Layer);
1374 TimerOn = true;
1375 Send_Configure_Request();
1376 Send_Configure_Nak_Rej();
1377 *State = PPP_STATE_Req_Sent;
1378 break;
1379
1380 case PPP_EVENT_RCA:
1381 case PPP_EVENT_RCN:
1382 case PPP_EVENT_RTA:
1383 This_Layer_Down(Layer);
1384 TimerOn = true;
1385 Send_Configure_Request();
1386 *State = PPP_STATE_Req_Sent;
1387 break;
1388
1389 case PPP_EVENT_RTR:
1390 This_Layer_Down(Layer);
1391 RestartCount = 0;
1392 LinkTimer = 0;
1393 TimerOn = true;
1394 Send_Terminate_Ack();
1395 *State = PPP_STATE_Stopping;
1396 break;
1397
1398 case PPP_EVENT_RUC:
1399 Send_Code_Reject();
1400 *State = PPP_STATE_Opened;
1401 break;
1402
1403 case PPP_EVENT_RXJMinus:
1404 This_Layer_Down(Layer);
1405 RestartCount = MAX_RESTARTS;
1406 LinkTimer = 0;
1407 TimerOn = true;
1408 Send_Terminate_Request();
1409 *State = PPP_STATE_Stopping;
1410 break;
1411
1412 case PPP_EVENT_RXR:
1413 Send_Echo_Reply();
1414 *State = PPP_STATE_Opened;
1415 break;
1416
1417 default:
1418 Debug_Print("Illegal Event\r\n");
1419 break;
1420 }
1421 break;
1422
1423 default:
1424 break;
1425 }
1426 }