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