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