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