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