1 //----------------------------------------------------------------------- 2 // This software is part of the OpenBeOS distribution and is covered 3 // by the OpenBeOS license. 4 // 5 // Copyright (c) 2003-2004 Waldemar Kornewald, Waldemar.Kornewald@web.de 6 //----------------------------------------------------------------------- 7 8 #include <OS.h> 9 10 #include <KPPPInterface.h> 11 #include <KPPPConfigurePacket.h> 12 #include <KPPPDevice.h> 13 #include <KPPPLCPExtension.h> 14 #include <KPPPOptionHandler.h> 15 16 #include <LockerHelper.h> 17 18 #include <net/if.h> 19 #include <core_funcs.h> 20 21 22 #define PPP_STATE_MACHINE_TIMEOUT 3000000 23 // 3 seconds 24 25 26 KPPPStateMachine::KPPPStateMachine(KPPPInterface& interface) 27 : fInterface(interface), 28 fLCP(interface.LCP()), 29 fState(PPP_INITIAL_STATE), 30 fPhase(PPP_DOWN_PHASE), 31 fID(system_time() & 0xFF), 32 fMagicNumber(0), 33 fLocalAuthenticationStatus(PPP_NOT_AUTHENTICATED), 34 fPeerAuthenticationStatus(PPP_NOT_AUTHENTICATED), 35 fLocalAuthenticationName(NULL), 36 fPeerAuthenticationName(NULL), 37 fMaxRequest(10), 38 fMaxTerminate(2), 39 fMaxNak(5), 40 fRequestID(0), 41 fTerminateID(0), 42 fEchoID(0), 43 fNextTimeout(0) 44 { 45 } 46 47 48 KPPPStateMachine::~KPPPStateMachine() 49 { 50 free(fLocalAuthenticationName); 51 free(fPeerAuthenticationName); 52 } 53 54 55 uint8 56 KPPPStateMachine::NextID() 57 { 58 return (uint8) atomic_add(&fID, 1); 59 } 60 61 62 // remember: NewState() must always be called _after_ IllegalEvent() 63 // because IllegalEvent() also looks at the current state. 64 void 65 KPPPStateMachine::NewState(ppp_state next) 66 { 67 #if DEBUG 68 dprintf("KPPPSM: NewState(%d) state=%d\n", next, State()); 69 #endif 70 71 // maybe we do not need the timer anymore 72 if(next < PPP_CLOSING_STATE || next == PPP_OPENED_STATE) 73 fNextTimeout = 0; 74 75 if(State() == PPP_OPENED_STATE && next != State()) 76 ResetLCPHandlers(); 77 78 fState = next; 79 } 80 81 82 void 83 KPPPStateMachine::NewPhase(ppp_phase next) 84 { 85 #if DEBUG 86 if(next <= PPP_ESTABLISHMENT_PHASE || next == PPP_ESTABLISHED_PHASE) 87 dprintf("KPPPSM: NewPhase(%d) phase=%d\n", next, Phase()); 88 #endif 89 90 // there is nothing after established phase and nothing before down phase 91 if(next > PPP_ESTABLISHED_PHASE) 92 next = PPP_ESTABLISHED_PHASE; 93 else if(next < PPP_DOWN_PHASE) 94 next = PPP_DOWN_PHASE; 95 96 // Report a down event to parent if we are not usable anymore. 97 // The report threads get their notification later. 98 if(Phase() == PPP_ESTABLISHED_PHASE && next != Phase()) { 99 if(Interface().Ifnet()) { 100 Interface().Ifnet()->if_flags &= ~IFF_RUNNING; 101 102 if(!Interface().DoesDialOnDemand()) 103 Interface().Ifnet()->if_flags &= ~IFF_UP; 104 } 105 106 if(Interface().Parent()) 107 Interface().Parent()->StateMachine().DownEvent(Interface()); 108 } 109 110 fPhase = next; 111 112 if(Phase() == PPP_ESTABLISHED_PHASE) { 113 if(Interface().Ifnet()) 114 Interface().Ifnet()->if_flags |= IFF_UP | IFF_RUNNING; 115 116 Interface().Report(PPP_CONNECTION_REPORT, PPP_REPORT_UP_SUCCESSFUL, 117 &fInterface.fID, sizeof(ppp_interface_id)); 118 } 119 } 120 121 122 // public actions 123 bool 124 KPPPStateMachine::Reconfigure() 125 { 126 #if DEBUG 127 dprintf("KPPPSM: Reconfigure() state=%d phase=%d\n", 128 State(), Phase()); 129 #endif 130 131 LockerHelper locker(fLock); 132 133 if(State() < PPP_REQ_SENT_STATE) 134 return false; 135 136 NewState(PPP_REQ_SENT_STATE); 137 NewPhase(PPP_ESTABLISHMENT_PHASE); 138 // indicates to handlers that we are reconfiguring 139 140 DownProtocols(); 141 ResetLCPHandlers(); 142 143 locker.UnlockNow(); 144 145 return SendConfigureRequest(); 146 } 147 148 149 bool 150 KPPPStateMachine::SendEchoRequest() 151 { 152 #if DEBUG 153 dprintf("KPPPSM: SendEchoRequest() state=%d phase=%d\n", 154 State(), Phase()); 155 #endif 156 157 if(State() != PPP_OPENED_STATE) 158 return false; 159 160 struct mbuf *packet = m_gethdr(MT_DATA); 161 if(!packet) 162 return false; 163 164 packet->m_data += LCP().AdditionalOverhead(); 165 packet->m_pkthdr.len = packet->m_len = 8; 166 // echo requests are at least eight bytes long 167 168 ppp_lcp_packet *request = mtod(packet, ppp_lcp_packet*); 169 request->code = PPP_ECHO_REQUEST; 170 request->id = NextID(); 171 fEchoID = request->id; 172 request->length = htons(packet->m_len); 173 memcpy(request->data, &fMagicNumber, sizeof(fMagicNumber)); 174 175 return LCP().Send(packet) == B_OK; 176 } 177 178 179 bool 180 KPPPStateMachine::SendDiscardRequest() 181 { 182 #if DEBUG 183 dprintf("KPPPSM: SendDiscardRequest() state=%d phase=%d\n", 184 State(), Phase()); 185 #endif 186 187 if(State() != PPP_OPENED_STATE) 188 return false; 189 190 struct mbuf *packet = m_gethdr(MT_DATA); 191 if(!packet) 192 return false; 193 194 packet->m_data += LCP().AdditionalOverhead(); 195 packet->m_pkthdr.len = packet->m_len = 8; 196 // discard requests are at least eight bytes long 197 198 ppp_lcp_packet *request = mtod(packet, ppp_lcp_packet*); 199 request->code = PPP_DISCARD_REQUEST; 200 request->id = NextID(); 201 request->length = htons(packet->m_len); 202 memcpy(request->data, &fMagicNumber, sizeof(fMagicNumber)); 203 204 return LCP().Send(packet) == B_OK; 205 } 206 207 208 // authentication events 209 void 210 KPPPStateMachine::LocalAuthenticationRequested() 211 { 212 #if DEBUG 213 dprintf("KPPPSM: LocalAuthenticationRequested() state=%d phase=%d\n", 214 State(), Phase()); 215 #endif 216 217 LockerHelper locker(fLock); 218 219 fLocalAuthenticationStatus = PPP_AUTHENTICATING; 220 free(fLocalAuthenticationName); 221 fLocalAuthenticationName = NULL; 222 } 223 224 225 void 226 KPPPStateMachine::LocalAuthenticationAccepted(const char *name) 227 { 228 #if DEBUG 229 dprintf("KPPPSM: LocalAuthenticationAccepted() state=%d phase=%d\n", 230 State(), Phase()); 231 #endif 232 233 LockerHelper locker(fLock); 234 235 fLocalAuthenticationStatus = PPP_AUTHENTICATION_SUCCESSFUL; 236 free(fLocalAuthenticationName); 237 if(name) 238 fLocalAuthenticationName = strdup(name); 239 else 240 fLocalAuthenticationName = NULL; 241 242 Interface().Report(PPP_CONNECTION_REPORT, 243 PPP_REPORT_LOCAL_AUTHENTICATION_SUCCESSFUL, &fInterface.fID, 244 sizeof(ppp_interface_id)); 245 } 246 247 248 void 249 KPPPStateMachine::LocalAuthenticationDenied(const char *name) 250 { 251 #if DEBUG 252 dprintf("KPPPSM: LocalAuthenticationDenied() state=%d phase=%d\n", 253 State(), Phase()); 254 #endif 255 256 LockerHelper locker(fLock); 257 258 fLocalAuthenticationStatus = PPP_AUTHENTICATION_FAILED; 259 free(fLocalAuthenticationName); 260 if(name) 261 fLocalAuthenticationName = strdup(name); 262 else 263 fLocalAuthenticationName = NULL; 264 } 265 266 267 void 268 KPPPStateMachine::PeerAuthenticationRequested() 269 { 270 #if DEBUG 271 dprintf("KPPPSM: PeerAuthenticationRequested() state=%d phase=%d\n", 272 State(), Phase()); 273 #endif 274 275 LockerHelper locker(fLock); 276 277 fPeerAuthenticationStatus = PPP_AUTHENTICATING; 278 free(fPeerAuthenticationName); 279 fPeerAuthenticationName = NULL; 280 } 281 282 283 void 284 KPPPStateMachine::PeerAuthenticationAccepted(const char *name) 285 { 286 #if DEBUG 287 dprintf("KPPPSM: PeerAuthenticationAccepted() state=%d phase=%d\n", 288 State(), Phase()); 289 #endif 290 291 LockerHelper locker(fLock); 292 293 fPeerAuthenticationStatus = PPP_AUTHENTICATION_SUCCESSFUL; 294 free(fPeerAuthenticationName); 295 if(name) 296 fPeerAuthenticationName = strdup(name); 297 else 298 fPeerAuthenticationName = NULL; 299 300 Interface().Report(PPP_CONNECTION_REPORT, 301 PPP_REPORT_PEER_AUTHENTICATION_SUCCESSFUL, &fInterface.fID, 302 sizeof(ppp_interface_id)); 303 } 304 305 306 void 307 KPPPStateMachine::PeerAuthenticationDenied(const char *name) 308 { 309 #if DEBUG 310 dprintf("KPPPSM: PeerAuthenticationDenied() state=%d phase=%d\n", 311 State(), Phase()); 312 #endif 313 314 LockerHelper locker(fLock); 315 316 fPeerAuthenticationStatus = PPP_AUTHENTICATION_FAILED; 317 free(fPeerAuthenticationName); 318 if(name) 319 fPeerAuthenticationName = strdup(name); 320 else 321 fPeerAuthenticationName = NULL; 322 323 CloseEvent(); 324 } 325 326 327 void 328 KPPPStateMachine::UpFailedEvent(KPPPInterface& interface) 329 { 330 #if DEBUG 331 dprintf("KPPPSM: UpFailedEvent(interface) state=%d phase=%d\n", 332 State(), Phase()); 333 #endif 334 335 // TODO: 336 // log that an interface did not go up 337 } 338 339 340 void 341 KPPPStateMachine::UpEvent(KPPPInterface& interface) 342 { 343 #if DEBUG 344 dprintf("KPPPSM: UpEvent(interface) state=%d phase=%d\n", 345 State(), Phase()); 346 #endif 347 348 LockerHelper locker(fLock); 349 350 if(Phase() <= PPP_TERMINATION_PHASE) { 351 interface.StateMachine().CloseEvent(); 352 return; 353 } 354 355 Interface().CalculateBaudRate(); 356 357 if(Phase() == PPP_ESTABLISHMENT_PHASE) { 358 // this is the first interface that went up 359 Interface().SetMRU(interface.MRU()); 360 locker.UnlockNow(); 361 ThisLayerUp(); 362 } else if(Interface().MRU() > interface.MRU()) 363 Interface().SetMRU(interface.MRU()); 364 // MRU should always be the smallest value of all children 365 366 NewState(PPP_OPENED_STATE); 367 } 368 369 370 void 371 KPPPStateMachine::DownEvent(KPPPInterface& interface) 372 { 373 #if DEBUG 374 dprintf("KPPPSM: DownEvent(interface) state=%d phase=%d\n", 375 State(), Phase()); 376 #endif 377 378 LockerHelper locker(fLock); 379 380 uint32 MRU = 0; 381 // the new MRU 382 383 Interface().CalculateBaudRate(); 384 385 // when all children are down we should not be running 386 if(Interface().IsMultilink() && !Interface().Parent()) { 387 uint32 count = 0; 388 KPPPInterface *child; 389 for(int32 index = 0; index < Interface().CountChildren(); index++) { 390 child = Interface().ChildAt(index); 391 392 if(child && child->IsUp()) { 393 // set MRU to the smallest value of all children 394 if(MRU == 0) 395 MRU = child->MRU(); 396 else if(MRU > child->MRU()) 397 MRU = child->MRU(); 398 399 ++count; 400 } 401 } 402 403 if(MRU == 0) 404 Interface().SetMRU(1500); 405 else 406 Interface().SetMRU(MRU); 407 408 if(count == 0) { 409 locker.UnlockNow(); 410 DownEvent(); 411 } 412 } 413 } 414 415 416 void 417 KPPPStateMachine::UpFailedEvent(KPPPProtocol *protocol) 418 { 419 #if DEBUG 420 dprintf("KPPPSM: UpFailedEvent(protocol) state=%d phase=%d\n", 421 State(), Phase()); 422 #endif 423 424 if((protocol->Flags() & PPP_NOT_IMPORTANT) == 0) { 425 if(Interface().Mode() == PPP_CLIENT_MODE) { 426 // pretend we lost connection 427 if(Interface().IsMultilink() && !Interface().Parent()) 428 for(int32 index = 0; index < Interface().CountChildren(); index++) 429 Interface().ChildAt(index)->StateMachine().CloseEvent(); 430 else if(Interface().Device()) 431 Interface().Device()->Down(); 432 else 433 CloseEvent(); 434 // just to be on the secure side ;) 435 } else 436 CloseEvent(); 437 } 438 } 439 440 441 void 442 KPPPStateMachine::UpEvent(KPPPProtocol *protocol) 443 { 444 #if DEBUG 445 dprintf("KPPPSM: UpEvent(protocol) state=%d phase=%d\n", 446 State(), Phase()); 447 #endif 448 449 LockerHelper locker(fLock); 450 451 if(Phase() >= PPP_ESTABLISHMENT_PHASE) 452 BringProtocolsUp(); 453 } 454 455 456 void 457 KPPPStateMachine::DownEvent(KPPPProtocol *protocol) 458 { 459 #if DEBUG 460 dprintf("KPPPSM: DownEvent(protocol) state=%d phase=%d\n", 461 State(), Phase()); 462 #endif 463 } 464 465 466 // This is called by the device to tell us that it entered establishment 467 // phase. We can use Device::Down() to abort establishment until UpEvent() 468 // is called. 469 // The return value says if we are waiting for an UpEvent(). If false is 470 // returned the device should immediately abort its attempt to connect. 471 bool 472 KPPPStateMachine::TLSNotify() 473 { 474 #if DEBUG 475 dprintf("KPPPSM: TLSNotify() state=%d phase=%d\n", 476 State(), Phase()); 477 #endif 478 479 LockerHelper locker(fLock); 480 481 if(State() == PPP_STARTING_STATE) { 482 if(Phase() == PPP_DOWN_PHASE) 483 NewPhase(PPP_ESTABLISHMENT_PHASE); 484 // this says that the device is going up 485 return true; 486 } 487 488 return false; 489 } 490 491 492 // This is called by the device to tell us that it entered termination phase. 493 // A Device::Up() should wait until the device went down. 494 // If false is returned we want to stay connected, though we called 495 // Device::Down(). 496 bool 497 KPPPStateMachine::TLFNotify() 498 { 499 #if DEBUG 500 dprintf("KPPPSM: TLFNotify() state=%d phase=%d\n", 501 State(), Phase()); 502 #endif 503 504 LockerHelper locker(fLock); 505 506 NewPhase(PPP_TERMINATION_PHASE); 507 // tell DownEvent() that it may create a connection-lost-report 508 509 return true; 510 } 511 512 513 void 514 KPPPStateMachine::UpFailedEvent() 515 { 516 #if DEBUG 517 dprintf("KPPPSM: UpFailedEvent() state=%d phase=%d\n", 518 State(), Phase()); 519 #endif 520 521 LockerHelper locker(fLock); 522 523 switch(State()) { 524 case PPP_STARTING_STATE: 525 Interface().Report(PPP_CONNECTION_REPORT, PPP_REPORT_DEVICE_UP_FAILED, 526 &fInterface.fID, sizeof(ppp_interface_id)); 527 if(Interface().Parent()) 528 Interface().Parent()->StateMachine().UpFailedEvent(Interface()); 529 530 NewPhase(PPP_DOWN_PHASE); 531 // tell DownEvent() that it should not create a connection-lost-report 532 DownEvent(); 533 break; 534 535 default: 536 IllegalEvent(PPP_UP_FAILED_EVENT); 537 } 538 } 539 540 541 void 542 KPPPStateMachine::UpEvent() 543 { 544 #if DEBUG 545 dprintf("KPPPSM: UpEvent() state=%d phase=%d\n", 546 State(), Phase()); 547 #endif 548 549 // This call is public, thus, it might not only be called by the device. 550 // We must recognize these attempts to fool us and handle them correctly. 551 552 LockerHelper locker(fLock); 553 554 if(!Interface().Device() || !Interface().Device()->IsUp()) 555 return; 556 // it is not our device that went up... 557 558 Interface().CalculateBaudRate(); 559 560 switch(State()) { 561 case PPP_INITIAL_STATE: 562 if(Interface().Mode() != PPP_SERVER_MODE 563 || Phase() != PPP_ESTABLISHMENT_PHASE) { 564 // we are a client or we do not listen for an incoming 565 // connection, so this is an illegal event 566 IllegalEvent(PPP_UP_EVENT); 567 NewState(PPP_CLOSED_STATE); 568 locker.UnlockNow(); 569 ThisLayerFinished(); 570 571 return; 572 } 573 574 // TODO: handle server-up! (maybe already done correctly) 575 NewState(PPP_REQ_SENT_STATE); 576 InitializeRestartCount(); 577 locker.UnlockNow(); 578 SendConfigureRequest(); 579 break; 580 581 case PPP_STARTING_STATE: 582 // we must have called TLS() which sets establishment phase 583 if(Phase() != PPP_ESTABLISHMENT_PHASE) { 584 // there must be a BUG in the device add-on or someone is trying to 585 // fool us (UpEvent() is public) as we did not request the device 586 // to go up 587 IllegalEvent(PPP_UP_EVENT); 588 NewState(PPP_CLOSED_STATE); 589 locker.UnlockNow(); 590 ThisLayerFinished(); 591 break; 592 } 593 594 NewState(PPP_REQ_SENT_STATE); 595 InitializeRestartCount(); 596 locker.UnlockNow(); 597 SendConfigureRequest(); 598 break; 599 600 default: 601 IllegalEvent(PPP_UP_EVENT); 602 } 603 } 604 605 606 void 607 KPPPStateMachine::DownEvent() 608 { 609 #if DEBUG 610 dprintf("KPPPSM: DownEvent() state=%d phase=%d\n", 611 State(), Phase()); 612 #endif 613 614 LockerHelper locker(fLock); 615 616 if(Interface().Device() && Interface().Device()->IsUp()) 617 return; 618 // it is not our device that went up... 619 620 Interface().CalculateBaudRate(); 621 622 // reset IdleSince 623 Interface().fIdleSince = 0; 624 625 switch(State()) { 626 // XXX: this does not belong to the standard, but may happen in our 627 // implementation 628 case PPP_STARTING_STATE: 629 break; 630 631 case PPP_CLOSED_STATE: 632 case PPP_CLOSING_STATE: 633 NewState(PPP_INITIAL_STATE); 634 break; 635 636 case PPP_STOPPED_STATE: 637 // The RFC says we should reconnect, but our implementation 638 // will only do this if auto-redial is enabled (only clients). 639 NewState(PPP_STARTING_STATE); 640 break; 641 642 case PPP_STOPPING_STATE: 643 case PPP_REQ_SENT_STATE: 644 case PPP_ACK_RCVD_STATE: 645 case PPP_ACK_SENT_STATE: 646 case PPP_OPENED_STATE: 647 NewState(PPP_STARTING_STATE); 648 break; 649 650 default: 651 IllegalEvent(PPP_DOWN_EVENT); 652 } 653 654 ppp_phase oldPhase = Phase(); 655 NewPhase(PPP_DOWN_PHASE); 656 657 DownProtocols(); 658 659 fLocalAuthenticationStatus = PPP_NOT_AUTHENTICATED; 660 fPeerAuthenticationStatus = PPP_NOT_AUTHENTICATED; 661 662 // maybe we need to redial 663 if(State() == PPP_STARTING_STATE) { 664 bool needsRedial = false; 665 666 // we do not try to redial if authentication failed 667 if(fLocalAuthenticationStatus == PPP_AUTHENTICATION_FAILED 668 || fLocalAuthenticationStatus == PPP_AUTHENTICATING) 669 Interface().Report(PPP_CONNECTION_REPORT, 670 PPP_REPORT_LOCAL_AUTHENTICATION_FAILED, &fInterface.fID, 671 sizeof(ppp_interface_id)); 672 else if(fPeerAuthenticationStatus == PPP_AUTHENTICATION_FAILED 673 || fPeerAuthenticationStatus == PPP_AUTHENTICATING) 674 Interface().Report(PPP_CONNECTION_REPORT, 675 PPP_REPORT_PEER_AUTHENTICATION_FAILED, &fInterface.fID, 676 sizeof(ppp_interface_id)); 677 else { 678 // if we are going up and lost connection the redial attempt becomes 679 // a dial retry which is managed by the main thread in Interface::Up() 680 if(Interface().fUpThread == -1) 681 needsRedial = true; 682 683 // test if UpFailedEvent() was not called 684 if(oldPhase != PPP_DOWN_PHASE) 685 Interface().Report(PPP_CONNECTION_REPORT, PPP_REPORT_CONNECTION_LOST, 686 &fInterface.fID, sizeof(ppp_interface_id)); 687 } 688 689 if(Interface().Parent()) 690 Interface().Parent()->StateMachine().UpFailedEvent(Interface()); 691 692 NewState(PPP_INITIAL_STATE); 693 694 if(Interface().DoesAutoRedial()) { 695 if(needsRedial) 696 Interface().Redial(Interface().RedialDelay()); 697 } else if(!Interface().DoesDialOnDemand()) 698 Interface().Delete(); 699 } else { 700 Interface().Report(PPP_CONNECTION_REPORT, PPP_REPORT_DOWN_SUCCESSFUL, 701 &fInterface.fID, sizeof(ppp_interface_id)); 702 703 if(!Interface().DoesDialOnDemand()) 704 Interface().Delete(); 705 } 706 } 707 708 709 // private events 710 void 711 KPPPStateMachine::OpenEvent() 712 { 713 #if DEBUG 714 dprintf("KPPPSM: OpenEvent() state=%d phase=%d\n", 715 State(), Phase()); 716 #endif 717 718 LockerHelper locker(fLock); 719 720 // reset all handlers 721 if(Phase() != PPP_ESTABLISHED_PHASE) { 722 DownProtocols(); 723 ResetLCPHandlers(); 724 } 725 726 switch(State()) { 727 case PPP_INITIAL_STATE: 728 if(!Interface().Report(PPP_CONNECTION_REPORT, PPP_REPORT_GOING_UP, 729 &fInterface.fID, sizeof(ppp_interface_id))) 730 return; 731 732 if(Interface().Mode() == PPP_SERVER_MODE) { 733 NewPhase(PPP_ESTABLISHMENT_PHASE); 734 735 if(Interface().Device() && !Interface().Device()->Up()) { 736 Interface().Device()->UpFailedEvent(); 737 return; 738 } 739 } else 740 NewState(PPP_STARTING_STATE); 741 742 if(Interface().IsMultilink() && !Interface().Parent()) { 743 NewPhase(PPP_ESTABLISHMENT_PHASE); 744 for(int32 index = 0; index < Interface().CountChildren(); index++) 745 if(Interface().ChildAt(index)->Mode() == Interface().Mode()) 746 Interface().ChildAt(index)->StateMachine().OpenEvent(); 747 } else { 748 locker.UnlockNow(); 749 ThisLayerStarted(); 750 } 751 break; 752 753 case PPP_CLOSED_STATE: 754 if(Phase() == PPP_DOWN_PHASE) { 755 // the device is already going down 756 return; 757 } 758 759 NewState(PPP_REQ_SENT_STATE); 760 NewPhase(PPP_ESTABLISHMENT_PHASE); 761 InitializeRestartCount(); 762 locker.UnlockNow(); 763 SendConfigureRequest(); 764 break; 765 766 case PPP_CLOSING_STATE: 767 NewState(PPP_STOPPING_STATE); 768 break; 769 770 default: 771 ; 772 } 773 } 774 775 776 void 777 KPPPStateMachine::CloseEvent() 778 { 779 #if DEBUG 780 dprintf("KPPPSM: CloseEvent() state=%d phase=%d\n", 781 State(), Phase()); 782 #endif 783 784 LockerHelper locker(fLock); 785 786 if(Interface().IsMultilink() && !Interface().Parent()) { 787 NewState(PPP_INITIAL_STATE); 788 789 if(Phase() != PPP_DOWN_PHASE) 790 NewPhase(PPP_TERMINATION_PHASE); 791 792 ThisLayerDown(); 793 794 for(int32 index = 0; index < Interface().CountChildren(); index++) 795 Interface().ChildAt(index)->StateMachine().CloseEvent(); 796 797 return; 798 } 799 800 switch(State()) { 801 case PPP_OPENED_STATE: 802 case PPP_REQ_SENT_STATE: 803 case PPP_ACK_RCVD_STATE: 804 case PPP_ACK_SENT_STATE: 805 NewState(PPP_CLOSING_STATE); 806 NewPhase(PPP_TERMINATION_PHASE); 807 // indicates to handlers that we are terminating 808 InitializeRestartCount(); 809 locker.UnlockNow(); 810 if(State() == PPP_OPENED_STATE) 811 ThisLayerDown(); 812 SendTerminateRequest(); 813 break; 814 815 case PPP_STARTING_STATE: 816 NewState(PPP_INITIAL_STATE); 817 818 // TLSNotify() will know that we were faster because we 819 // are in PPP_INITIAL_STATE now 820 if(Phase() == PPP_ESTABLISHMENT_PHASE) { 821 // the device is already up 822 NewPhase(PPP_DOWN_PHASE); 823 // this says the following DownEvent() was not caused by 824 // a connection fault 825 locker.UnlockNow(); 826 ThisLayerFinished(); 827 } 828 break; 829 830 case PPP_STOPPING_STATE: 831 NewState(PPP_CLOSING_STATE); 832 break; 833 834 case PPP_STOPPED_STATE: 835 NewState(PPP_STOPPED_STATE); 836 break; 837 838 default: 839 ; 840 } 841 } 842 843 844 // timeout (restart counters are > 0) 845 void 846 KPPPStateMachine::TOGoodEvent() 847 { 848 #if DEBUG 849 dprintf("KPPPSM: TOGoodEvent() state=%d phase=%d\n", 850 State(), Phase()); 851 #endif 852 853 LockerHelper locker(fLock); 854 855 switch(State()) { 856 case PPP_CLOSING_STATE: 857 case PPP_STOPPING_STATE: 858 locker.UnlockNow(); 859 SendTerminateRequest(); 860 break; 861 862 case PPP_ACK_RCVD_STATE: 863 NewState(PPP_REQ_SENT_STATE); 864 865 case PPP_REQ_SENT_STATE: 866 case PPP_ACK_SENT_STATE: 867 locker.UnlockNow(); 868 SendConfigureRequest(); 869 break; 870 871 default: 872 IllegalEvent(PPP_TO_GOOD_EVENT); 873 } 874 } 875 876 877 // timeout (restart counters are <= 0) 878 void 879 KPPPStateMachine::TOBadEvent() 880 { 881 #if DEBUG 882 dprintf("KPPPSM: TOBadEvent() state=%d phase=%d\n", 883 State(), Phase()); 884 #endif 885 886 LockerHelper locker(fLock); 887 888 switch(State()) { 889 case PPP_CLOSING_STATE: 890 NewState(PPP_CLOSED_STATE); 891 NewPhase(PPP_TERMINATION_PHASE); 892 locker.UnlockNow(); 893 ThisLayerFinished(); 894 break; 895 896 case PPP_STOPPING_STATE: 897 case PPP_REQ_SENT_STATE: 898 case PPP_ACK_RCVD_STATE: 899 case PPP_ACK_SENT_STATE: 900 NewState(PPP_STOPPED_STATE); 901 NewPhase(PPP_TERMINATION_PHASE); 902 locker.UnlockNow(); 903 ThisLayerFinished(); 904 break; 905 906 default: 907 IllegalEvent(PPP_TO_BAD_EVENT); 908 } 909 } 910 911 912 // receive configure request (acceptable request) 913 void 914 KPPPStateMachine::RCRGoodEvent(struct mbuf *packet) 915 { 916 #if DEBUG 917 dprintf("KPPPSM: RCRGoodEvent() state=%d phase=%d\n", 918 State(), Phase()); 919 #endif 920 921 LockerHelper locker(fLock); 922 923 switch(State()) { 924 case PPP_INITIAL_STATE: 925 case PPP_STARTING_STATE: 926 IllegalEvent(PPP_RCR_GOOD_EVENT); 927 m_freem(packet); 928 break; 929 930 case PPP_CLOSED_STATE: 931 locker.UnlockNow(); 932 SendTerminateAck(); 933 m_freem(packet); 934 break; 935 936 case PPP_STOPPED_STATE: 937 // irc,scr,sca/8 938 // XXX: should we do nothing and wait for DownEvent()? 939 m_freem(packet); 940 break; 941 942 case PPP_REQ_SENT_STATE: 943 NewState(PPP_ACK_SENT_STATE); 944 945 case PPP_ACK_SENT_STATE: 946 locker.UnlockNow(); 947 SendConfigureAck(packet); 948 break; 949 950 case PPP_ACK_RCVD_STATE: 951 NewState(PPP_OPENED_STATE); 952 locker.UnlockNow(); 953 SendConfigureAck(packet); 954 ThisLayerUp(); 955 break; 956 957 case PPP_OPENED_STATE: 958 NewState(PPP_ACK_SENT_STATE); 959 NewPhase(PPP_ESTABLISHMENT_PHASE); 960 // indicates to handlers that we are reconfiguring 961 locker.UnlockNow(); 962 ThisLayerDown(); 963 SendConfigureRequest(); 964 SendConfigureAck(packet); 965 break; 966 967 default: 968 m_freem(packet); 969 } 970 } 971 972 973 // receive configure request (unacceptable request) 974 void 975 KPPPStateMachine::RCRBadEvent(struct mbuf *nak, struct mbuf *reject) 976 { 977 #if DEBUG 978 dprintf("KPPPSM: RCRBadEvent() state=%d phase=%d\n", 979 State(), Phase()); 980 #endif 981 982 LockerHelper locker(fLock); 983 984 switch(State()) { 985 case PPP_INITIAL_STATE: 986 case PPP_STARTING_STATE: 987 IllegalEvent(PPP_RCR_BAD_EVENT); 988 break; 989 990 case PPP_CLOSED_STATE: 991 locker.UnlockNow(); 992 SendTerminateAck(); 993 break; 994 995 case PPP_STOPPED_STATE: 996 // irc,scr,scn/6 997 // XXX: should we do nothing and wait for DownEvent()? 998 break; 999 1000 case PPP_OPENED_STATE: 1001 NewState(PPP_REQ_SENT_STATE); 1002 NewPhase(PPP_ESTABLISHMENT_PHASE); 1003 // indicates to handlers that we are reconfiguring 1004 locker.UnlockNow(); 1005 ThisLayerDown(); 1006 SendConfigureRequest(); 1007 1008 case PPP_ACK_SENT_STATE: 1009 if(State() == PPP_ACK_SENT_STATE) 1010 NewState(PPP_REQ_SENT_STATE); 1011 // OPENED_STATE might have set this already 1012 1013 case PPP_REQ_SENT_STATE: 1014 case PPP_ACK_RCVD_STATE: 1015 locker.UnlockNow(); 1016 if(nak && ntohs(mtod(nak, ppp_lcp_packet*)->length) > 3) 1017 SendConfigureNak(nak); 1018 else if(reject && ntohs(mtod(reject, ppp_lcp_packet*)->length) > 3) 1019 SendConfigureNak(reject); 1020 return; 1021 // prevents the nak/reject from being m_freem()'d 1022 1023 default: 1024 ; 1025 } 1026 1027 if(nak) 1028 m_freem(nak); 1029 if(reject) 1030 m_freem(reject); 1031 } 1032 1033 1034 // receive configure ack 1035 void 1036 KPPPStateMachine::RCAEvent(struct mbuf *packet) 1037 { 1038 #if DEBUG 1039 dprintf("KPPPSM: RCAEvent() state=%d phase=%d\n", 1040 State(), Phase()); 1041 #endif 1042 1043 LockerHelper locker(fLock); 1044 1045 if(fRequestID != mtod(packet, ppp_lcp_packet*)->id) { 1046 // this packet is not a reply to our request 1047 1048 // TODO: 1049 // log this event 1050 m_freem(packet); 1051 return; 1052 } 1053 1054 // let the option handlers parse this ack 1055 KPPPConfigurePacket ack(packet); 1056 KPPPOptionHandler *optionHandler; 1057 for(int32 index = 0; index < LCP().CountOptionHandlers(); index++) { 1058 optionHandler = LCP().OptionHandlerAt(index); 1059 if(optionHandler->ParseAck(ack) != B_OK) { 1060 m_freem(packet); 1061 locker.UnlockNow(); 1062 CloseEvent(); 1063 return; 1064 } 1065 } 1066 1067 switch(State()) { 1068 case PPP_INITIAL_STATE: 1069 case PPP_STARTING_STATE: 1070 IllegalEvent(PPP_RCA_EVENT); 1071 break; 1072 1073 case PPP_CLOSED_STATE: 1074 case PPP_STOPPED_STATE: 1075 locker.UnlockNow(); 1076 SendTerminateAck(); 1077 break; 1078 1079 case PPP_REQ_SENT_STATE: 1080 NewState(PPP_ACK_RCVD_STATE); 1081 InitializeRestartCount(); 1082 break; 1083 1084 case PPP_ACK_RCVD_STATE: 1085 NewState(PPP_REQ_SENT_STATE); 1086 locker.UnlockNow(); 1087 SendConfigureRequest(); 1088 break; 1089 1090 case PPP_ACK_SENT_STATE: 1091 NewState(PPP_OPENED_STATE); 1092 InitializeRestartCount(); 1093 locker.UnlockNow(); 1094 ThisLayerUp(); 1095 break; 1096 1097 case PPP_OPENED_STATE: 1098 NewState(PPP_REQ_SENT_STATE); 1099 NewPhase(PPP_ESTABLISHMENT_PHASE); 1100 // indicates to handlers that we are reconfiguring 1101 locker.UnlockNow(); 1102 ThisLayerDown(); 1103 SendConfigureRequest(); 1104 break; 1105 1106 default: 1107 ; 1108 } 1109 1110 m_freem(packet); 1111 } 1112 1113 1114 // receive configure nak/reject 1115 void 1116 KPPPStateMachine::RCNEvent(struct mbuf *packet) 1117 { 1118 #if DEBUG 1119 dprintf("KPPPSM: RCNEvent() state=%d phase=%d\n", 1120 State(), Phase()); 1121 #endif 1122 1123 LockerHelper locker(fLock); 1124 1125 if(fRequestID != mtod(packet, ppp_lcp_packet*)->id) { 1126 // this packet is not a reply to our request 1127 1128 // TODO: 1129 // log this event 1130 m_freem(packet); 1131 return; 1132 } 1133 1134 // let the option handlers parse this nak/reject 1135 KPPPConfigurePacket nak_reject(packet); 1136 KPPPOptionHandler *optionHandler; 1137 for(int32 index = 0; index < LCP().CountOptionHandlers(); index++) { 1138 optionHandler = LCP().OptionHandlerAt(index); 1139 1140 if(nak_reject.Code() == PPP_CONFIGURE_NAK) { 1141 if(optionHandler->ParseNak(nak_reject) != B_OK) { 1142 m_freem(packet); 1143 locker.UnlockNow(); 1144 CloseEvent(); 1145 return; 1146 } 1147 } else if(nak_reject.Code() == PPP_CONFIGURE_REJECT) { 1148 if(optionHandler->ParseReject(nak_reject) != B_OK) { 1149 m_freem(packet); 1150 locker.UnlockNow(); 1151 CloseEvent(); 1152 return; 1153 } 1154 } 1155 } 1156 1157 switch(State()) { 1158 case PPP_INITIAL_STATE: 1159 case PPP_STARTING_STATE: 1160 IllegalEvent(PPP_RCN_EVENT); 1161 break; 1162 1163 case PPP_CLOSED_STATE: 1164 case PPP_STOPPED_STATE: 1165 locker.UnlockNow(); 1166 SendTerminateAck(); 1167 break; 1168 1169 case PPP_REQ_SENT_STATE: 1170 case PPP_ACK_SENT_STATE: 1171 InitializeRestartCount(); 1172 1173 case PPP_ACK_RCVD_STATE: 1174 if(State() == PPP_ACK_RCVD_STATE) 1175 NewState(PPP_REQ_SENT_STATE); 1176 locker.UnlockNow(); 1177 SendConfigureRequest(); 1178 break; 1179 1180 case PPP_OPENED_STATE: 1181 NewState(PPP_REQ_SENT_STATE); 1182 NewPhase(PPP_ESTABLISHMENT_PHASE); 1183 // indicates to handlers that we are reconfiguring 1184 locker.UnlockNow(); 1185 ThisLayerDown(); 1186 SendConfigureRequest(); 1187 break; 1188 1189 default: 1190 ; 1191 } 1192 1193 m_freem(packet); 1194 } 1195 1196 1197 // receive terminate request 1198 void 1199 KPPPStateMachine::RTREvent(struct mbuf *packet) 1200 { 1201 #if DEBUG 1202 dprintf("KPPPSM: RTREvent() state=%d phase=%d\n", 1203 State(), Phase()); 1204 #endif 1205 1206 LockerHelper locker(fLock); 1207 1208 // we should not use the same ID as the peer 1209 if(fID == mtod(packet, ppp_lcp_packet*)->id) 1210 fID -= 128; 1211 1212 fLocalAuthenticationStatus = PPP_NOT_AUTHENTICATED; 1213 fPeerAuthenticationStatus = PPP_NOT_AUTHENTICATED; 1214 1215 switch(State()) { 1216 case PPP_INITIAL_STATE: 1217 case PPP_STARTING_STATE: 1218 IllegalEvent(PPP_RTR_EVENT); 1219 m_freem(packet); 1220 break; 1221 1222 case PPP_ACK_RCVD_STATE: 1223 case PPP_ACK_SENT_STATE: 1224 NewState(PPP_REQ_SENT_STATE); 1225 NewPhase(PPP_TERMINATION_PHASE); 1226 // indicates to handlers that we are terminating 1227 locker.UnlockNow(); 1228 SendTerminateAck(packet); 1229 break; 1230 1231 case PPP_OPENED_STATE: 1232 NewState(PPP_STOPPING_STATE); 1233 NewPhase(PPP_TERMINATION_PHASE); 1234 // indicates to handlers that we are terminating 1235 ZeroRestartCount(); 1236 locker.UnlockNow(); 1237 ThisLayerDown(); 1238 SendTerminateAck(packet); 1239 break; 1240 1241 default: 1242 NewPhase(PPP_TERMINATION_PHASE); 1243 // indicates to handlers that we are terminating 1244 locker.UnlockNow(); 1245 SendTerminateAck(packet); 1246 } 1247 } 1248 1249 1250 // receive terminate ack 1251 void 1252 KPPPStateMachine::RTAEvent(struct mbuf *packet) 1253 { 1254 #if DEBUG 1255 dprintf("KPPPSM: RTAEvent() state=%d phase=%d\n", 1256 State(), Phase()); 1257 #endif 1258 1259 LockerHelper locker(fLock); 1260 1261 if(fTerminateID != mtod(packet, ppp_lcp_packet*)->id) { 1262 // this packet is not a reply to our request 1263 1264 // TODO: 1265 // log this event 1266 m_freem(packet); 1267 return; 1268 } 1269 1270 switch(State()) { 1271 case PPP_INITIAL_STATE: 1272 case PPP_STARTING_STATE: 1273 IllegalEvent(PPP_RTA_EVENT); 1274 break; 1275 1276 case PPP_CLOSING_STATE: 1277 NewState(PPP_CLOSED_STATE); 1278 locker.UnlockNow(); 1279 ThisLayerFinished(); 1280 break; 1281 1282 case PPP_STOPPING_STATE: 1283 NewState(PPP_STOPPED_STATE); 1284 locker.UnlockNow(); 1285 ThisLayerFinished(); 1286 break; 1287 1288 case PPP_ACK_RCVD_STATE: 1289 NewState(PPP_REQ_SENT_STATE); 1290 break; 1291 1292 case PPP_OPENED_STATE: 1293 NewState(PPP_REQ_SENT_STATE); 1294 NewPhase(PPP_ESTABLISHMENT_PHASE); 1295 // indicates to handlers that we are reconfiguring 1296 locker.UnlockNow(); 1297 ThisLayerDown(); 1298 SendConfigureRequest(); 1299 break; 1300 1301 default: 1302 ; 1303 } 1304 1305 m_freem(packet); 1306 } 1307 1308 1309 // receive unknown code 1310 void 1311 KPPPStateMachine::RUCEvent(struct mbuf *packet, uint16 protocolNumber, 1312 uint8 code = PPP_PROTOCOL_REJECT) 1313 { 1314 #if DEBUG 1315 dprintf("KPPPSM: RUCEvent() state=%d phase=%d\n", 1316 State(), Phase()); 1317 #endif 1318 1319 LockerHelper locker(fLock); 1320 1321 switch(State()) { 1322 case PPP_INITIAL_STATE: 1323 case PPP_STARTING_STATE: 1324 IllegalEvent(PPP_RUC_EVENT); 1325 m_freem(packet); 1326 break; 1327 1328 default: 1329 locker.UnlockNow(); 1330 SendCodeReject(packet, protocolNumber, code); 1331 } 1332 } 1333 1334 1335 // receive code/protocol reject (acceptable such as IPX reject) 1336 void 1337 KPPPStateMachine::RXJGoodEvent(struct mbuf *packet) 1338 { 1339 #if DEBUG 1340 dprintf("KPPPSM: RXJGoodEvent() state=%d phase=%d\n", 1341 State(), Phase()); 1342 #endif 1343 1344 // This method does not m_freem(packet) because the acceptable rejects are 1345 // also passed to the parent. RXJEvent() will m_freem(packet) when needed. 1346 LockerHelper locker(fLock); 1347 1348 switch(State()) { 1349 case PPP_INITIAL_STATE: 1350 case PPP_STARTING_STATE: 1351 IllegalEvent(PPP_RXJ_GOOD_EVENT); 1352 break; 1353 1354 case PPP_ACK_RCVD_STATE: 1355 NewState(PPP_REQ_SENT_STATE); 1356 break; 1357 1358 default: 1359 ; 1360 } 1361 } 1362 1363 1364 // receive code/protocol reject (catastrophic such as LCP reject) 1365 void 1366 KPPPStateMachine::RXJBadEvent(struct mbuf *packet) 1367 { 1368 #if DEBUG 1369 dprintf("KPPPSM: RXJBadEvent() state=%d phase=%d\n", 1370 State(), Phase()); 1371 #endif 1372 1373 LockerHelper locker(fLock); 1374 1375 switch(State()) { 1376 case PPP_INITIAL_STATE: 1377 case PPP_STARTING_STATE: 1378 IllegalEvent(PPP_RXJ_BAD_EVENT); 1379 break; 1380 1381 case PPP_CLOSING_STATE: 1382 NewState(PPP_CLOSED_STATE); 1383 1384 case PPP_CLOSED_STATE: 1385 locker.UnlockNow(); 1386 ThisLayerFinished(); 1387 break; 1388 1389 case PPP_REQ_SENT_STATE: 1390 case PPP_ACK_RCVD_STATE: 1391 case PPP_ACK_SENT_STATE: 1392 NewState(PPP_STOPPED_STATE); 1393 1394 case PPP_STOPPING_STATE: 1395 NewPhase(PPP_TERMINATION_PHASE); 1396 1397 case PPP_STOPPED_STATE: 1398 locker.UnlockNow(); 1399 ThisLayerFinished(); 1400 break; 1401 1402 case PPP_OPENED_STATE: 1403 NewState(PPP_STOPPING_STATE); 1404 NewPhase(PPP_TERMINATION_PHASE); 1405 // indicates to handlers that we are terminating 1406 InitializeRestartCount(); 1407 locker.UnlockNow(); 1408 ThisLayerDown(); 1409 SendTerminateRequest(); 1410 break; 1411 } 1412 1413 m_freem(packet); 1414 } 1415 1416 1417 // receive echo request/reply, discard request 1418 void 1419 KPPPStateMachine::RXREvent(struct mbuf *packet) 1420 { 1421 #if DEBUG 1422 dprintf("KPPPSM: RXREvent() state=%d phase=%d\n", 1423 State(), Phase()); 1424 #endif 1425 1426 ppp_lcp_packet *echo = mtod(packet, ppp_lcp_packet*); 1427 1428 if(echo->code == PPP_ECHO_REPLY && echo->id != fEchoID) { 1429 // TODO: 1430 // log that we got a reply, but no request was sent 1431 } 1432 1433 switch(State()) { 1434 case PPP_INITIAL_STATE: 1435 case PPP_STARTING_STATE: 1436 IllegalEvent(PPP_RXR_EVENT); 1437 break; 1438 1439 case PPP_OPENED_STATE: 1440 if(echo->code == PPP_ECHO_REQUEST) 1441 SendEchoReply(packet); 1442 return; 1443 // this prevents the packet from being freed 1444 1445 default: 1446 ; 1447 } 1448 1449 m_freem(packet); 1450 } 1451 1452 1453 // general events (for Good/Bad events) 1454 void 1455 KPPPStateMachine::TimerEvent() 1456 { 1457 #if DEBUG 1458 if(fNextTimeout != 0) 1459 dprintf("KPPPSM: TimerEvent()\n"); 1460 #endif 1461 1462 LockerHelper locker(fLock); 1463 if(fNextTimeout == 0 || fNextTimeout > system_time()) 1464 return; 1465 fNextTimeout = 0; 1466 locker.UnlockNow(); 1467 1468 switch(State()) { 1469 case PPP_CLOSING_STATE: 1470 case PPP_STOPPING_STATE: 1471 if(fTerminateCounter <= 0) 1472 TOBadEvent(); 1473 else 1474 TOGoodEvent(); 1475 break; 1476 1477 case PPP_REQ_SENT_STATE: 1478 case PPP_ACK_RCVD_STATE: 1479 case PPP_ACK_SENT_STATE: 1480 if(fRequestCounter <= 0) 1481 TOBadEvent(); 1482 else 1483 TOGoodEvent(); 1484 break; 1485 1486 default: 1487 ; 1488 } 1489 } 1490 1491 1492 // ReceiveConfigureRequest 1493 // Here we get a configure-request packet from LCP and aks all OptionHandlers 1494 // if its values are acceptable. From here we call our Good/Bad counterparts. 1495 void 1496 KPPPStateMachine::RCREvent(struct mbuf *packet) 1497 { 1498 #if DEBUG 1499 dprintf("KPPPSM: RCREvent() state=%d phase=%d\n", 1500 State(), Phase()); 1501 #endif 1502 1503 KPPPConfigurePacket request(packet); 1504 KPPPConfigurePacket nak(PPP_CONFIGURE_NAK); 1505 KPPPConfigurePacket reject(PPP_CONFIGURE_REJECT); 1506 1507 // we should not use the same id as the peer 1508 if(fID == mtod(packet, ppp_lcp_packet*)->id) 1509 fID -= 128; 1510 1511 nak.SetID(request.ID()); 1512 reject.SetID(request.ID()); 1513 1514 // each handler should add unacceptable values for each item 1515 status_t result; 1516 // the return value of ParseRequest() 1517 KPPPOptionHandler *optionHandler; 1518 for(int32 index = 0; index < request.CountItems(); index++) { 1519 optionHandler = LCP().OptionHandlerFor(request.ItemAt(index)->type); 1520 1521 if(!optionHandler || !optionHandler->IsEnabled()) { 1522 dprintf("KPPPSM::RCREvent(): unknown type:%d\n", request.ItemAt(index)->type); 1523 // unhandled items should be added to the reject 1524 reject.AddItem(request.ItemAt(index)); 1525 continue; 1526 } 1527 1528 #if DEBUG 1529 dprintf("KPPPSM::RCREvent(): OH=%s\n", optionHandler->Name()); 1530 #endif 1531 result = optionHandler->ParseRequest(request, index, nak, reject); 1532 1533 if(result == PPP_UNHANDLED) { 1534 // unhandled items should be added to the reject 1535 reject.AddItem(request.ItemAt(index)); 1536 continue; 1537 } else if(result != B_OK) { 1538 // the request contains a value that has been sent more than 1539 // once or the value is corrupted 1540 dprintf("KPPPSM::RCREvent(): OptionHandler returned parse error!\n"); 1541 m_freem(packet); 1542 CloseEvent(); 1543 return; 1544 } 1545 } 1546 1547 // Additional values may be appended. 1548 // If we sent too many naks we should not append additional values. 1549 if(fNakCounter > 0) { 1550 for(int32 index = 0; index < LCP().CountOptionHandlers(); index++) { 1551 optionHandler = LCP().OptionHandlerAt(index); 1552 if(optionHandler && optionHandler->IsEnabled()) { 1553 result = optionHandler->ParseRequest(request, request.CountItems(), 1554 nak, reject); 1555 1556 if(result != B_OK) { 1557 // the request contains a value that has been sent more than 1558 // once or the value is corrupted 1559 dprintf("KPPPSM::RCREvent(): OptionHandler returned append error!\n"); 1560 m_freem(packet); 1561 CloseEvent(); 1562 return; 1563 } 1564 } 1565 } 1566 } 1567 1568 if(nak.CountItems() > 0) { 1569 RCRBadEvent(nak.ToMbuf(Interface().MRU(), LCP().AdditionalOverhead()), NULL); 1570 m_freem(packet); 1571 } else if(reject.CountItems() > 0) { 1572 RCRBadEvent(NULL, reject.ToMbuf(Interface().MRU(), LCP().AdditionalOverhead())); 1573 m_freem(packet); 1574 } else 1575 RCRGoodEvent(packet); 1576 } 1577 1578 1579 // ReceiveCodeReject 1580 // LCP received a code/protocol-reject packet and we look if it is acceptable. 1581 // From here we call our Good/Bad counterparts. 1582 void 1583 KPPPStateMachine::RXJEvent(struct mbuf *packet) 1584 { 1585 #if DEBUG 1586 dprintf("KPPPSM: RXJEvent() state=%d phase=%d\n", 1587 State(), Phase()); 1588 #endif 1589 1590 ppp_lcp_packet *reject = mtod(packet, ppp_lcp_packet*); 1591 1592 if(reject->code == PPP_CODE_REJECT) { 1593 uint8 rejectedCode = reject->data[0]; 1594 1595 // test if the rejected code belongs to the minimum LCP requirements 1596 if(rejectedCode >= PPP_MIN_LCP_CODE && rejectedCode <= PPP_MAX_LCP_CODE) { 1597 if(Interface().IsMultilink() && !Interface().Parent()) { 1598 // Main interfaces do not have states between STARTING and OPENED. 1599 // An RXJBadEvent() would enter one of those states which is bad. 1600 m_freem(packet); 1601 CloseEvent(); 1602 } else 1603 RXJBadEvent(packet); 1604 1605 return; 1606 } 1607 1608 // find the LCP extension and disable it 1609 KPPPLCPExtension *lcpExtension; 1610 for(int32 index = 0; index < LCP().CountLCPExtensions(); index++) { 1611 lcpExtension = LCP().LCPExtensionAt(index); 1612 1613 if(lcpExtension->Code() == rejectedCode) 1614 lcpExtension->SetEnabled(false); 1615 } 1616 1617 m_freem(packet); 1618 } else if(reject->code == PPP_PROTOCOL_REJECT) { 1619 // disable all handlers for rejected protocol type 1620 uint16 rejected = *((uint16*) reject->data); 1621 // rejected protocol number 1622 1623 if(rejected == PPP_LCP_PROTOCOL) { 1624 // LCP must not be rejected! 1625 RXJBadEvent(packet); 1626 return; 1627 } 1628 1629 // disable protocols with the rejected protocol number 1630 KPPPProtocol *protocol = Interface().FirstProtocol(); 1631 for(; protocol; protocol = protocol->NextProtocol()) { 1632 if(protocol->ProtocolNumber() == rejected) 1633 protocol->SetEnabled(false); 1634 // disable protocol 1635 } 1636 1637 RXJGoodEvent(packet); 1638 // this event handler does not m_freem(packet)!!! 1639 1640 // notify parent, too 1641 if(Interface().Parent()) 1642 Interface().Parent()->StateMachine().RXJEvent(packet); 1643 else 1644 m_freem(packet); 1645 } 1646 } 1647 1648 1649 // actions (all private) 1650 void 1651 KPPPStateMachine::IllegalEvent(ppp_event event) 1652 { 1653 // TODO: 1654 // update error statistics 1655 dprintf("KPPPSM: IllegalEvent(event=%d) state=%d phase=%d\n", 1656 event, State(), Phase()); 1657 } 1658 1659 1660 void 1661 KPPPStateMachine::ThisLayerUp() 1662 { 1663 #if DEBUG 1664 dprintf("KPPPSM: ThisLayerUp() state=%d phase=%d\n", 1665 State(), Phase()); 1666 #endif 1667 1668 LockerHelper locker(fLock); 1669 1670 // We begin with authentication phase and wait until each phase is done. 1671 // We stop when we reach established phase. 1672 1673 // Do not forget to check if we are going down. 1674 if(Phase() != PPP_ESTABLISHMENT_PHASE) 1675 return; 1676 1677 NewPhase(PPP_AUTHENTICATION_PHASE); 1678 1679 locker.UnlockNow(); 1680 1681 BringProtocolsUp(); 1682 } 1683 1684 1685 void 1686 KPPPStateMachine::ThisLayerDown() 1687 { 1688 #if DEBUG 1689 dprintf("KPPPSM: ThisLayerDown() state=%d phase=%d\n", 1690 State(), Phase()); 1691 #endif 1692 1693 // KPPPProtocol::Down() should block if needed. 1694 DownProtocols(); 1695 } 1696 1697 1698 void 1699 KPPPStateMachine::ThisLayerStarted() 1700 { 1701 #if DEBUG 1702 dprintf("KPPPSM: ThisLayerStarted() state=%d phase=%d\n", 1703 State(), Phase()); 1704 #endif 1705 1706 if(Interface().Device() && !Interface().Device()->Up()) 1707 Interface().Device()->UpFailedEvent(); 1708 } 1709 1710 1711 void 1712 KPPPStateMachine::ThisLayerFinished() 1713 { 1714 #if DEBUG 1715 dprintf("KPPPSM: ThisLayerFinished() state=%d phase=%d\n", 1716 State(), Phase()); 1717 #endif 1718 1719 if(Interface().Device()) 1720 Interface().Device()->Down(); 1721 } 1722 1723 1724 void 1725 KPPPStateMachine::InitializeRestartCount() 1726 { 1727 fRequestCounter = fMaxRequest; 1728 fTerminateCounter = fMaxTerminate; 1729 fNakCounter = fMaxNak; 1730 } 1731 1732 1733 void 1734 KPPPStateMachine::ZeroRestartCount() 1735 { 1736 fRequestCounter = 0; 1737 fTerminateCounter = 0; 1738 fNakCounter = 0; 1739 } 1740 1741 1742 bool 1743 KPPPStateMachine::SendConfigureRequest() 1744 { 1745 #if DEBUG 1746 dprintf("KPPPSM: SendConfigureRequest() state=%d phase=%d\n", 1747 State(), Phase()); 1748 #endif 1749 1750 LockerHelper locker(fLock); 1751 --fRequestCounter; 1752 fNextTimeout = system_time() + PPP_STATE_MACHINE_TIMEOUT; 1753 locker.UnlockNow(); 1754 1755 KPPPConfigurePacket request(PPP_CONFIGURE_REQUEST); 1756 request.SetID(NextID()); 1757 fRequestID = request.ID(); 1758 1759 for(int32 index = 0; index < LCP().CountOptionHandlers(); index++) { 1760 // add all items 1761 if(LCP().OptionHandlerAt(index)->AddToRequest(request) != B_OK) { 1762 CloseEvent(); 1763 return false; 1764 } 1765 } 1766 1767 return LCP().Send(request.ToMbuf(Interface().MRU(), 1768 LCP().AdditionalOverhead())) == B_OK; 1769 } 1770 1771 1772 bool 1773 KPPPStateMachine::SendConfigureAck(struct mbuf *packet) 1774 { 1775 #if DEBUG 1776 dprintf("KPPPSM: SendConfigureAck() state=%d phase=%d\n", 1777 State(), Phase()); 1778 #endif 1779 1780 if(!packet) 1781 return false; 1782 1783 mtod(packet, ppp_lcp_packet*)->code = PPP_CONFIGURE_ACK; 1784 KPPPConfigurePacket ack(packet); 1785 1786 // notify all option handlers that we are sending an ack for each value 1787 for(int32 index = 0; index < LCP().CountOptionHandlers(); index++) { 1788 if(LCP().OptionHandlerAt(index)->SendingAck(ack) != B_OK) { 1789 m_freem(packet); 1790 CloseEvent(); 1791 return false; 1792 } 1793 } 1794 1795 return LCP().Send(packet) == B_OK; 1796 } 1797 1798 1799 bool 1800 KPPPStateMachine::SendConfigureNak(struct mbuf *packet) 1801 { 1802 #if DEBUG 1803 dprintf("KPPPSM: SendConfigureNak() state=%d phase=%d\n", 1804 State(), Phase()); 1805 #endif 1806 1807 if(!packet) 1808 return false; 1809 1810 ppp_lcp_packet *nak = mtod(packet, ppp_lcp_packet*); 1811 if(nak->code == PPP_CONFIGURE_NAK) { 1812 if(fNakCounter == 0) { 1813 // We sent enough naks. Let's try a reject. 1814 nak->code = PPP_CONFIGURE_REJECT; 1815 } else 1816 --fNakCounter; 1817 } 1818 1819 return LCP().Send(packet) == B_OK; 1820 } 1821 1822 1823 bool 1824 KPPPStateMachine::SendTerminateRequest() 1825 { 1826 #if DEBUG 1827 dprintf("KPPPSM: SendTerminateRequest() state=%d phase=%d\n", 1828 State(), Phase()); 1829 #endif 1830 1831 LockerHelper locker(fLock); 1832 --fTerminateCounter; 1833 fNextTimeout = system_time() + PPP_STATE_MACHINE_TIMEOUT; 1834 locker.UnlockNow(); 1835 1836 struct mbuf *packet = m_gethdr(MT_DATA); 1837 if(!packet) 1838 return false; 1839 1840 packet->m_pkthdr.len = packet->m_len = 4; 1841 1842 // reserve some space for other protocols 1843 packet->m_data += LCP().AdditionalOverhead(); 1844 1845 ppp_lcp_packet *request = mtod(packet, ppp_lcp_packet*); 1846 request->code = PPP_TERMINATE_REQUEST; 1847 request->id = fTerminateID = NextID(); 1848 request->length = htons(4); 1849 1850 return LCP().Send(packet) == B_OK; 1851 } 1852 1853 1854 bool 1855 KPPPStateMachine::SendTerminateAck(struct mbuf *request = NULL) 1856 { 1857 #if DEBUG 1858 dprintf("KPPPSM: SendTerminateAck() state=%d phase=%d\n", 1859 State(), Phase()); 1860 #endif 1861 1862 struct mbuf *reply = request; 1863 1864 ppp_lcp_packet *ack; 1865 1866 if(!reply) { 1867 reply = m_gethdr(MT_DATA); 1868 if(!reply) 1869 return false; 1870 1871 reply->m_data += LCP().AdditionalOverhead(); 1872 reply->m_pkthdr.len = reply->m_len = 4; 1873 1874 ack = mtod(reply, ppp_lcp_packet*); 1875 ack->id = NextID(); 1876 } else 1877 ack = mtod(reply, ppp_lcp_packet*); 1878 1879 ack->code = PPP_TERMINATE_ACK; 1880 ack->length = htons(4); 1881 1882 return LCP().Send(reply) == B_OK; 1883 } 1884 1885 1886 bool 1887 KPPPStateMachine::SendCodeReject(struct mbuf *packet, uint16 protocolNumber, uint8 code) 1888 { 1889 #if DEBUG 1890 dprintf("KPPPSM: SendCodeReject(protocolNumber=%X;code=%d) state=%d phase=%d\n", 1891 protocolNumber, code, State(), Phase()); 1892 #endif 1893 1894 if(!packet) 1895 return false; 1896 1897 int32 length; 1898 // additional space needed for this reject 1899 if(code == PPP_PROTOCOL_REJECT) 1900 length = 6; 1901 else 1902 length = 4; 1903 1904 M_PREPEND(packet, length); 1905 // add some space for the header 1906 1907 // adjust packet if too big 1908 int32 adjust = Interface().MRU(); 1909 if(packet->m_flags & M_PKTHDR) { 1910 adjust -= packet->m_pkthdr.len; 1911 } else 1912 adjust -= packet->m_len; 1913 1914 if(adjust < 0) 1915 m_adj(packet, adjust); 1916 1917 ppp_lcp_packet *reject = mtod(packet, ppp_lcp_packet*); 1918 reject->code = code; 1919 reject->id = NextID(); 1920 if(packet->m_flags & M_PKTHDR) 1921 reject->length = htons(packet->m_pkthdr.len); 1922 else 1923 reject->length = htons(packet->m_len); 1924 1925 protocolNumber = htons(protocolNumber); 1926 if(code == PPP_PROTOCOL_REJECT) 1927 memcpy(&reject->data, &protocolNumber, sizeof(protocolNumber)); 1928 1929 return LCP().Send(packet) == B_OK; 1930 } 1931 1932 1933 bool 1934 KPPPStateMachine::SendEchoReply(struct mbuf *request) 1935 { 1936 #if DEBUG 1937 dprintf("KPPPSM: SendEchoReply() state=%d phase=%d\n", 1938 State(), Phase()); 1939 #endif 1940 1941 if(!request) 1942 return false; 1943 1944 ppp_lcp_packet *reply = mtod(request, ppp_lcp_packet*); 1945 reply->code = PPP_ECHO_REPLY; 1946 // the request becomes a reply 1947 1948 if(request->m_flags & M_PKTHDR) 1949 request->m_pkthdr.len = 8; 1950 request->m_len = 8; 1951 1952 memcpy(reply->data, &fMagicNumber, sizeof(fMagicNumber)); 1953 1954 return LCP().Send(request) == B_OK; 1955 } 1956 1957 1958 // methods for bringing protocols up 1959 void 1960 KPPPStateMachine::BringProtocolsUp() 1961 { 1962 // use a simple check for phase changes (e.g., caused by CloseEvent()) 1963 while(Phase() <= PPP_ESTABLISHED_PHASE && Phase() >= PPP_AUTHENTICATION_PHASE) { 1964 if(BringPhaseUp() > 0) 1965 break; 1966 1967 LockerHelper locker(fLock); 1968 1969 if(Phase() < PPP_AUTHENTICATION_PHASE) 1970 return; 1971 // phase was changed by another event 1972 else if(Phase() == PPP_ESTABLISHED_PHASE) { 1973 if(Interface().Parent()) 1974 Interface().Parent()->StateMachine().UpEvent(Interface()); 1975 break; 1976 } else 1977 NewPhase((ppp_phase) (Phase() + 1)); 1978 } 1979 } 1980 1981 1982 // this returns the number of handlers waiting to go up 1983 uint32 1984 KPPPStateMachine::BringPhaseUp() 1985 { 1986 // Servers do not need to bring all protocols up. 1987 // The client specifies which protocols he wants to go up. 1988 1989 LockerHelper locker(fLock); 1990 1991 // check for phase change 1992 if(Phase() < PPP_AUTHENTICATION_PHASE) 1993 return 0; 1994 1995 uint32 count = 0; 1996 KPPPProtocol *protocol = Interface().FirstProtocol(); 1997 for(; protocol; protocol = protocol->NextProtocol()) { 1998 if(protocol->IsEnabled() && protocol->ActivationPhase() == Phase()) { 1999 if(protocol->IsGoingUp() && Interface().Mode() == PPP_CLIENT_MODE) 2000 ++count; 2001 else if(protocol->IsDown() && protocol->IsUpRequested()) { 2002 if(Interface().Mode() == PPP_CLIENT_MODE) 2003 ++count; 2004 2005 protocol->Up(); 2006 } 2007 } 2008 } 2009 2010 // We only wait until authentication is complete. 2011 if(Interface().Mode() == PPP_SERVER_MODE 2012 && (LocalAuthenticationStatus() == PPP_AUTHENTICATING 2013 || PeerAuthenticationStatus() == PPP_AUTHENTICATING)) 2014 ++count; 2015 2016 return count; 2017 } 2018 2019 2020 void 2021 KPPPStateMachine::DownProtocols() 2022 { 2023 KPPPProtocol *protocol = Interface().FirstProtocol(); 2024 2025 for(; protocol; protocol = protocol->NextProtocol()) 2026 if(protocol->IsEnabled()) 2027 protocol->Down(); 2028 } 2029 2030 2031 void 2032 KPPPStateMachine::ResetLCPHandlers() 2033 { 2034 for(int32 index = 0; index < LCP().CountOptionHandlers(); index++) 2035 LCP().OptionHandlerAt(index)->Reset(); 2036 2037 for(int32 index = 0; index < LCP().CountLCPExtensions(); index++) 2038 LCP().LCPExtensionAt(index)->Reset(); 2039 } 2040