1 /* 2 * Copyright 2003-2007, Waldemar Kornewald <wkornew@gmx.net> 3 * Distributed under the terms of the MIT License. 4 */ 5 6 /*! \class KPPPInterface 7 \brief The kernel representation of a PPP interface. 8 9 This class is never created by the programmer directly. Instead, the PPP manager 10 kernel module should be used. \n 11 KPPPInterface handles all interface-specific commands from userspace and it 12 passes packets to their receiver or sends them to the device. Additionally, 13 it contains the KPPPLCP object with represents the LCP protocol and the 14 KPPPStateMachine object which represents the state machine. \n 15 All PPP modules are loaded from here. \n 16 Protocols and encapsulators should be added to this class. LCP-specific extensions 17 belong to the KPPPLCP object. \n 18 Multilink support is distributed between KPPPInterface and KPPPStateMachine. 19 */ 20 21 // cstdio must be included before KPPPModule.h/KPPPManager.h because 22 // dprintf is defined twice with different return values, once with 23 // void (KernelExport.h) and once with int (stdio.h). 24 #include <cstdio> 25 #include <cstring> 26 27 #include <ByteOrder.h> 28 #include <net_buffer.h> 29 #include <net_stack.h> 30 #include <ppp_device.h> 31 32 // now our headers... 33 #include <KPPPInterface.h> 34 35 // our other classes 36 #include <PPPControl.h> 37 #include <KPPPDevice.h> 38 #include <KPPPLCPExtension.h> 39 #include <KPPPOptionHandler.h> 40 #include <KPPPModule.h> 41 #include <KPPPManager.h> 42 #include <KPPPUtils.h> 43 44 // general helper classes not only belonging to us 45 // #include <lock.h> 46 // #include <util/AutoLock.h> 47 48 // tools only for us :) 49 #include "settings_tools.h" 50 51 // internal modules 52 #include "_KPPPMRUHandler.h" 53 #include "_KPPPAuthenticationHandler.h" 54 #include "_KPPPPFCHandler.h" 55 56 57 // TODO: 58 // - implement timers with support for setting next event instead of receiving timer 59 // events periodically 60 // - add missing settings support (ConnectRetryDelay, etc.) 61 62 63 //! Private structure needed for reconnecting. 64 typedef struct reconnect_info { 65 KPPPInterface *interface; 66 thread_id *thread; 67 uint32 delay; 68 } reconnect_info; 69 70 extern net_buffer_module_info *gBufferModule; 71 extern net_stack_module_info *gStackModule; 72 73 status_t reconnect_thread(void *data); 74 75 // other functions 76 status_t interface_deleter_thread(void *data); 77 78 79 /*! \brief Creates a new interface. 80 81 \param name Name of the PPP interface description file. 82 \param entry The PPP manager passes an internal structure to the constructor. 83 \param ID The interface's ID. 84 \param settings (Optional): If no name is given you must pass the settings here. 85 \param parent (Optional): Interface's parent (only used for multilink interfaces). 86 */ 87 KPPPInterface::KPPPInterface(const char *name, ppp_interface_entry *entry, 88 ppp_interface_id ID, const driver_settings *settings, KPPPInterface *parent) 89 : 90 KPPPLayer(name, PPP_INTERFACE_LEVEL, 2), 91 fID(ID), 92 fSettings(NULL), 93 fIfnet(NULL), 94 fReconnectThread(-1), 95 fConnectAttempt(1), 96 fConnectRetriesLimit(0), 97 fManager(NULL), 98 fConnectedSince(0), 99 fIdleSince(0), 100 fMRU(1500), 101 fInterfaceMTU(1498), 102 fHeaderLength(2), 103 fParent(NULL), 104 fIsMultilink(false), 105 fAutoReconnect(false), 106 fConnectOnDemand(true), 107 fAskBeforeConnecting(false), 108 fMode(PPP_CLIENT_MODE), 109 fLocalPFCState(PPP_PFC_DISABLED), 110 fPeerPFCState(PPP_PFC_DISABLED), 111 fPFCOptions(0), 112 fDevice(NULL), 113 fFirstProtocol(NULL), 114 fStateMachine(*this), 115 fLCP(*this), 116 fReportManager(StateMachine().fLock), 117 fLock(StateMachine().fLock), 118 fDeleteCounter(0) 119 { 120 entry->interface = this; 121 122 if (name) { 123 // load settings from description file 124 char path[B_PATH_NAME_LENGTH]; 125 sprintf(path, "ptpnet/%s", name); 126 127 void *handle = load_driver_settings(path); 128 if (!handle) { 129 ERROR("KPPPInterface: Unable to load %s PPP driver settings!\n", path); 130 fInitStatus = B_ERROR; 131 return; 132 } 133 134 fSettings = dup_driver_settings(get_driver_settings(handle)); 135 unload_driver_settings(handle); 136 } else 137 fSettings = dup_driver_settings(settings); 138 // use the given settings 139 140 if (!fSettings) { 141 ERROR("KPPPInterface: No fSettings!\n"); 142 fInitStatus = B_ERROR; 143 return; 144 } 145 146 // add internal modules 147 // LCP 148 if (!AddProtocol(&LCP())) { 149 ERROR("KPPPInterface: Could not add LCP protocol!\n"); 150 fInitStatus = B_ERROR; 151 return; 152 } 153 // MRU 154 _KPPPMRUHandler *mruHandler = 155 new _KPPPMRUHandler(*this); 156 if (!LCP().AddOptionHandler(mruHandler) || mruHandler->InitCheck() != B_OK) { 157 ERROR("KPPPInterface: Could not add MRU handler!\n"); 158 delete mruHandler; 159 } 160 // authentication 161 _KPPPAuthenticationHandler *authenticationHandler = 162 new _KPPPAuthenticationHandler(*this); 163 if (!LCP().AddOptionHandler(authenticationHandler) 164 || authenticationHandler->InitCheck() != B_OK) { 165 ERROR("KPPPInterface: Could not add authentication handler!\n"); 166 delete authenticationHandler; 167 } 168 // PFC 169 _KPPPPFCHandler *pfcHandler = 170 new _KPPPPFCHandler(fLocalPFCState, fPeerPFCState, *this); 171 if (!LCP().AddOptionHandler(pfcHandler) || pfcHandler->InitCheck() != B_OK) { 172 ERROR("KPPPInterface: Could not add PFC handler!\n"); 173 delete pfcHandler; 174 } 175 176 // set up connect delays 177 fConnectRetryDelay = 3000; 178 // 3s delay between each new attempt to reconnect 179 fReconnectDelay = 1000; 180 // 1s delay between lost connection and reconnect 181 182 if (get_module(PPP_INTERFACE_MODULE_NAME, (module_info**) &fManager) != B_OK) 183 ERROR("KPPPInterface: Manager module not found!\n"); 184 185 // are we a multilink subinterface? 186 if (parent && parent->IsMultilink()) { 187 fParent = parent; 188 fParent->AddChild(this); 189 fIsMultilink = true; 190 } 191 192 RegisterInterface(); 193 194 if (!fSettings) { 195 fInitStatus = B_ERROR; 196 return; 197 } 198 199 const char *value; 200 201 // get login 202 value = get_settings_value(PPP_USERNAME_KEY, fSettings); 203 fUsername = value ? strdup(value) : strdup(""); 204 value = get_settings_value(PPP_PASSWORD_KEY, fSettings); 205 fPassword = value ? strdup(value) : strdup(""); 206 207 // get DisonnectAfterIdleSince settings 208 value = get_settings_value(PPP_DISONNECT_AFTER_IDLE_SINCE_KEY, fSettings); 209 if (!value) 210 fDisconnectAfterIdleSince = 0; 211 else 212 fDisconnectAfterIdleSince = atoi(value) * 1000; 213 214 if (fDisconnectAfterIdleSince < 0) 215 fDisconnectAfterIdleSince = 0; 216 217 // get mode settings 218 value = get_settings_value(PPP_MODE_KEY, fSettings); 219 if (value && !strcasecmp(value, PPP_SERVER_MODE_VALUE)) 220 fMode = PPP_SERVER_MODE; 221 else 222 fMode = PPP_CLIENT_MODE; 223 // we are a client by default 224 225 SetAutoReconnect( 226 get_boolean_value( 227 get_settings_value(PPP_AUTO_RECONNECT_KEY, fSettings), 228 false) 229 ); 230 // auto reconnect is disabled by default 231 232 fAskBeforeConnecting = get_boolean_value( 233 get_settings_value(PPP_ASK_BEFORE_CONNECTING_KEY, fSettings), false); 234 235 // load all protocols and the device 236 if (!LoadModules(fSettings, 0, fSettings->parameter_count)) { 237 ERROR("KPPPInterface: Error loading modules!\n"); 238 fInitStatus = B_ERROR; 239 } 240 } 241 242 243 //! Destructor: Disconnects and marks interface for deletion. 244 KPPPInterface::~KPPPInterface() 245 { 246 TRACE("KPPPInterface: Destructor\n"); 247 248 // tell protocols to uninit (remove routes, etc.) 249 KPPPProtocol *protocol = FirstProtocol(); 250 for (; protocol; protocol = protocol->NextProtocol()) 251 protocol->Uninit(); 252 253 // make sure we are not accessible by any thread before we continue 254 UnregisterInterface(); 255 256 if (fManager) 257 fManager->RemoveInterface(ID()); 258 259 // Call Down() until we get a lock on an interface that is down. 260 // This lock is not released until we are actually deleted. 261 while (true) { 262 Down(); 263 { 264 MutexLocker (fLock); 265 if (State() == PPP_INITIAL_STATE && Phase() == PPP_DOWN_PHASE) 266 break; 267 } 268 } 269 270 Report(PPP_DESTRUCTION_REPORT, 0, &fID, sizeof(ppp_interface_id)); 271 // tell all listeners that we are being destroyed 272 273 int32 tmp; 274 send_data_with_timeout(fReconnectThread, 0, NULL, 0, 200); 275 // tell thread that we are being destroyed (200ms timeout) 276 wait_for_thread(fReconnectThread, &tmp); 277 278 while (CountChildren()) 279 delete ChildAt(0); 280 281 delete Device(); 282 283 while (FirstProtocol()) { 284 if (FirstProtocol() == &LCP()) 285 fFirstProtocol = fFirstProtocol->NextProtocol(); 286 else 287 delete FirstProtocol(); 288 // destructor removes protocol from list 289 } 290 291 for (int32 index = 0; index < fModules.CountItems(); index++) { 292 put_module(fModules.ItemAt(index)); 293 delete[] fModules.ItemAt(index); 294 } 295 296 free_driver_settings(fSettings); 297 298 if (Parent()) 299 Parent()->RemoveChild(this); 300 301 if (fManager) 302 put_module(PPP_INTERFACE_MODULE_NAME); 303 } 304 305 306 //! Marks interface for deletion. 307 void 308 KPPPInterface::Delete() 309 { 310 // MutexLocker locker(fLock); 311 // alreay locked in KPPPStatemachine::DownEvent 312 // uncomment this line will cause double lock 313 314 if (fDeleteCounter > 0) 315 return; 316 // only one thread should delete us! 317 318 fDeleteCounter = 1; 319 320 fManager->DeleteInterface(ID()); 321 // This will mark us for deletion. 322 // Any subsequent calls to delete_interface() will do nothing. 323 } 324 325 326 //! Returns if interface was initialized correctly. 327 status_t 328 KPPPInterface::InitCheck() const 329 { 330 if (fInitStatus != B_OK) 331 return fInitStatus; 332 333 if (!fSettings || !fManager) 334 return B_ERROR; 335 336 // sub-interfaces should have a device 337 if (IsMultilink()) { 338 if (Parent() && !fDevice) 339 return B_ERROR; 340 } else if (!fDevice) 341 return B_ERROR; 342 343 return B_OK; 344 } 345 346 347 //! The username used for authentication. 348 const char* 349 KPPPInterface::Username() const 350 { 351 // this data is not available before we authenticate 352 if (Phase() < PPP_AUTHENTICATION_PHASE) 353 return NULL; 354 355 return fUsername; 356 } 357 358 359 //! The password used for authentication. 360 const char* 361 KPPPInterface::Password() const 362 { 363 // this data is not available before we authenticate 364 if (Phase() < PPP_AUTHENTICATION_PHASE) 365 return NULL; 366 367 return fPassword; 368 } 369 370 371 //! Sets interface MRU. 372 bool 373 KPPPInterface::SetMRU(uint32 MRU) 374 { 375 TRACE("KPPPInterface: SetMRU(%ld)\n", MRU); 376 377 if (Device() && MRU > Device()->MTU() - 2) 378 return false; 379 380 // MutexLocker locker(fLock); 381 // uncomment this line will cause double lock 382 // alreay locked in ::Up and ::KPPPInterface 383 384 fMRU = MRU; 385 386 CalculateInterfaceMTU(); 387 388 return true; 389 } 390 391 392 //! Returns number of bytes spent for protocol overhead. Includes device overhead. 393 uint32 394 KPPPInterface::PacketOverhead() const 395 { 396 uint32 overhead = fHeaderLength + 2; 397 398 if (Device()) 399 overhead += Device()->Overhead(); 400 401 return overhead; 402 } 403 404 405 /*! \brief Allows accessing additional functions. 406 407 This is normally called by userland apps to get information about the interface. 408 409 \param op The op value (see ppp_control_ops enum). 410 \param data (Optional): Additional data may be needed for this op. 411 \param length Length of data. 412 413 \return 414 - \c B_OK: \c Control() was successful. 415 - \c B_ERROR: Either \a length is too small or data is NULL. 416 - \c B_NOT_ALLOWED: Operation not allowed (at this point in time). 417 - \c B_BAD_INDEX: Wrong index (e.g.: when accessing interface submodules). 418 - \c B_BAD_VALUE: Unknown op. 419 - Return value of submodule (when controlling one). 420 */ 421 status_t 422 KPPPInterface::Control(uint32 op, void *data, size_t length) 423 { 424 TRACE("%s:%s\n", __FILE__, __func__); 425 426 control_net_module_args* args = (control_net_module_args*)data; 427 if (op != NET_STACK_CONTROL_NET_MODULE) { 428 dprintf("unknow op!!\n"); 429 return B_BAD_VALUE; 430 } 431 432 switch (args->op) { 433 case PPPC_COUNT_INTERFACES: 434 { 435 // should be implepented 436 dprintf("PPPC_COUNT_INTERFACES should be implepentd\n"); 437 438 return B_OK; 439 } 440 441 case PPPC_GET_INTERFACES: 442 { 443 dprintf("PPPC_GET_INTERFACES\n"); 444 ppp_get_interfaces_info* info = (ppp_get_interfaces_info*)args->data; 445 dprintf("info->interfaces: %p\n", info->interfaces); 446 *(info->interfaces) = 1; 447 info->resultCount = 1; 448 449 return B_OK; 450 } 451 452 case PPPC_CONTROL_INTERFACE: 453 { 454 dprintf("PPPC_CONTROL_INTERFACE\n"); 455 ppp_control_info* control = (ppp_control_info*)args->data; 456 457 switch (control->op) { 458 case PPPC_GET_INTERFACE_INFO: 459 { 460 dprintf("PPPC_GET_INTERFACE_INFO\n"); 461 if (control->length < sizeof(ppp_interface_info_t) || !control->data) { 462 dprintf("size wrong!\n"); 463 return B_ERROR; 464 } 465 466 ppp_interface_info *info = (ppp_interface_info*) control->data; 467 dprintf("info addr:%p\n", info); 468 memset(info, 0, sizeof(ppp_interface_info_t)); 469 if (Name()) 470 strncpy(info->name, Name(), PPP_HANDLER_NAME_LENGTH_LIMIT); 471 472 if (Ifnet()) 473 info->if_unit = Ifnet()->index; 474 else 475 info->if_unit = -1; 476 info->mode = Mode(); 477 info->state = State(); 478 info->phase = Phase(); 479 info->localAuthenticationStatus = 480 StateMachine().LocalAuthenticationStatus(); 481 info->peerAuthenticationStatus = 482 StateMachine().PeerAuthenticationStatus(); 483 info->localPFCState = LocalPFCState(); 484 info->peerPFCState = PeerPFCState(); 485 info->pfcOptions = PFCOptions(); 486 info->protocolsCount = CountProtocols(); 487 info->optionHandlersCount = LCP().CountOptionHandlers(); 488 info->LCPExtensionsCount = 0; 489 info->childrenCount = CountChildren(); 490 info->MRU = MRU(); 491 info->interfaceMTU = InterfaceMTU(); 492 info->connectAttempt = fConnectAttempt; 493 info->connectRetriesLimit = fConnectRetriesLimit; 494 info->connectRetryDelay = ConnectRetryDelay(); 495 info->reconnectDelay = ReconnectDelay(); 496 info->connectedSince = ConnectedSince(); 497 info->idleSince = IdleSince(); 498 info->disconnectAfterIdleSince = DisconnectAfterIdleSince(); 499 info->doesConnectOnDemand = DoesConnectOnDemand(); 500 info->doesAutoReconnect = DoesAutoReconnect(); 501 info->hasDevice = Device(); 502 info->isMultilink = IsMultilink(); 503 info->hasParent = Parent(); 504 break; 505 } 506 507 case PPPC_SET_USERNAME: 508 { 509 dprintf("PPPC_SET_USERNAME\n"); 510 if (control->length > PPP_HANDLER_NAME_LENGTH_LIMIT || !control->data) { 511 dprintf("size wrong!\n"); 512 return B_ERROR; 513 } 514 515 MutexLocker locker(fLock); 516 // login information can only be changed before we authenticate 517 if (Phase() >= PPP_AUTHENTICATION_PHASE) 518 return B_NOT_ALLOWED; 519 520 free(fUsername); 521 fUsername = control->data ? strdup((const char*) control->data) : strdup(""); 522 dprintf("set ppp user name to %s\n", fUsername); 523 524 break; 525 } 526 527 case PPPC_SET_PASSWORD: 528 { 529 dprintf("PPPC_SET_PASSWORD\n"); 530 if (control->length > PPP_HANDLER_NAME_LENGTH_LIMIT || !control->data) { 531 dprintf("size wrong!\n"); 532 return B_ERROR; 533 } 534 535 MutexLocker locker(fLock); 536 // login information can only be changed before we authenticate 537 if (Phase() >= PPP_AUTHENTICATION_PHASE) 538 return B_NOT_ALLOWED; 539 540 free(fPassword); 541 fPassword = control->data ? strdup((const char*) control->data) : strdup(""); 542 dprintf("set ppp password to %s!\n", fPassword); 543 break; 544 } 545 546 case PPPC_SET_ASK_BEFORE_CONNECTING: 547 { 548 dprintf("PPPC_SET_ASK_BEFORE_CONNECTING\n"); 549 if (control->length < sizeof(uint32) || !control->data) { 550 dprintf("size wrong!\n"); 551 return B_ERROR; 552 } 553 554 SetAskBeforeConnecting(*((uint32*)control->data)); 555 dprintf("goto PPPC_SET_ASK_BEFORE_CONNECTING here!\n"); 556 break; 557 } 558 559 case PPPC_GET_STATISTICS: 560 { 561 dprintf("PPPC_GET_STATISTICS\n"); 562 if (control->length < sizeof(ppp_statistics) || !control->data) { 563 dprintf("size wrong!\n"); 564 return B_ERROR; 565 } 566 567 dprintf("should PPPC_GET_STATISTICS here!\n"); 568 569 memcpy(control->data, &fStatistics, sizeof(ppp_statistics)); 570 break; 571 } 572 573 case PPPC_HAS_INTERFACE_SETTINGS: 574 { 575 dprintf("PPPC_HAS_INTERFACE_SETTINGS\n"); 576 if (control->length < sizeof(driver_settings) || !control->data) { 577 dprintf("size wrong!\n"); 578 return B_ERROR; 579 } 580 581 dprintf("should PPPC_HAS_INTERFACE_SETTINGS here!\n"); 582 583 if (equal_interface_settings(Settings(), (driver_settings*)control->data)) 584 return B_OK; 585 else 586 return B_ERROR; 587 break; 588 589 } 590 591 case PPPC_ENABLE_REPORTS: 592 { 593 dprintf("PPPC_ENABLE_REPORTS\n"); 594 if (control->length < sizeof(ppp_report_request) || !control->data) { 595 dprintf("size wrong!\n"); 596 return B_ERROR; 597 } 598 599 dprintf("should PPPC_ENABLE_REPORTS here!\n"); 600 601 MutexLocker locker(fLock); 602 ppp_report_request *request = (ppp_report_request*) control->data; 603 // first, we send an initial state report 604 if (request->type == PPP_CONNECTION_REPORT) { 605 ppp_report_packet report; 606 report.type = PPP_CONNECTION_REPORT; 607 report.code = StateMachine().fLastConnectionReportCode; 608 report.length = sizeof(fID); 609 KPPPReportManager::SendReport(request->thread, &report); 610 if (request->flags & PPP_REMOVE_AFTER_REPORT) 611 return B_OK; 612 } 613 ReportManager().EnableReports(request->type, request->thread, 614 request->flags); 615 break; 616 } 617 618 case PPPC_DISABLE_REPORTS: 619 { 620 dprintf("PPPC_DISABLE_REPORTS\n"); 621 if (control->length < sizeof(ppp_report_request) || !control->data) { 622 dprintf("size wrong!\n"); 623 return B_ERROR; 624 } 625 626 dprintf("should PPPC_DISABLE_REPORTS here!\n"); 627 628 ppp_report_request *request = (ppp_report_request*) control->data; 629 ReportManager().DisableReports(request->type, request->thread); 630 break; 631 } 632 633 case PPPC_CONTROL_DEVICE: 634 { 635 dprintf("PPPC_CONTROL_DEVICE\n"); 636 if (control->length < sizeof(ppp_control_info) || !control->data) 637 return B_ERROR; 638 639 ppp_control_info *controlInfo = (ppp_control_info*) control->data; 640 if (controlInfo->index != 0 || !Device()) { 641 dprintf("index is 0 or no Device\n"); 642 return B_BAD_INDEX; 643 } 644 645 return Device()->Control(controlInfo->op, controlInfo->data, controlInfo->length); 646 } 647 648 case PPPC_CONTROL_PROTOCOL: 649 { 650 dprintf("PPPC_CONTROL_PROTOCOL\n"); 651 if (control->length < sizeof(ppp_control_info) || !control->data) 652 return B_ERROR; 653 654 ppp_control_info *controlInfo = (ppp_control_info*) control->data; 655 KPPPProtocol *protocol = ProtocolAt(controlInfo->index); 656 if (!protocol) 657 return B_BAD_INDEX; 658 659 return protocol->Control(controlInfo->op, controlInfo->data, controlInfo->length); 660 } 661 662 case PPPC_CONTROL_OPTION_HANDLER: 663 { 664 dprintf("PPPC_CONTROL_OPTION_HANDLER\n"); 665 if (control->length < sizeof(ppp_control_info) || !control->data) 666 return B_ERROR; 667 668 ppp_control_info *controlInfo = (ppp_control_info*) control->data; 669 KPPPOptionHandler *optionHandler = LCP().OptionHandlerAt(controlInfo->index); 670 if (!optionHandler) { 671 dprintf("optionHandler no avail\n"); 672 return B_BAD_INDEX; 673 } 674 675 return optionHandler->Control(controlInfo->op, controlInfo->data, 676 controlInfo->length); 677 } 678 679 case PPPC_CONTROL_LCP_EXTENSION: 680 { 681 dprintf("PPPC_CONTROL_LCP_EXTENSION\n"); 682 if (control->length < sizeof(ppp_control_info) || !control->data) 683 return B_ERROR; 684 685 ppp_control_info *controlInfo = (ppp_control_info*) control->data; 686 KPPPLCPExtension *lcpExtension = LCP().LCPExtensionAt(controlInfo->index); 687 if (!lcpExtension) 688 return B_BAD_INDEX; 689 690 return lcpExtension->Control(controlInfo->op, controlInfo->data, 691 controlInfo->length); 692 } 693 694 case PPPC_CONTROL_CHILD: 695 { 696 dprintf("PPPC_CONTROL_CHILD\n"); 697 if (control->length < sizeof(ppp_control_info) || !control->data) 698 return B_ERROR; 699 700 ppp_control_info *controlInfo = (ppp_control_info*) control->data; 701 KPPPInterface *child = ChildAt(controlInfo->index); 702 if (!child) 703 return B_BAD_INDEX; 704 705 return child->Control(controlInfo->op, controlInfo->data, controlInfo->length); 706 } 707 708 default : 709 return B_ERROR; 710 } 711 712 return B_OK; 713 } 714 715 case PPPC_GET_INTERFACE_INFO: 716 { 717 if (length < sizeof(ppp_interface_info_t) || !data) 718 return B_ERROR; 719 720 ppp_interface_info *info = (ppp_interface_info*) data; 721 memset(info, 0, sizeof(ppp_interface_info_t)); 722 if (Name()) 723 strncpy(info->name, Name(), PPP_HANDLER_NAME_LENGTH_LIMIT); 724 if (Ifnet()) 725 info->if_unit = Ifnet()->index; 726 else 727 info->if_unit = -1; 728 info->mode = Mode(); 729 info->state = State(); 730 info->phase = Phase(); 731 info->localAuthenticationStatus = 732 StateMachine().LocalAuthenticationStatus(); 733 info->peerAuthenticationStatus = 734 StateMachine().PeerAuthenticationStatus(); 735 info->localPFCState = LocalPFCState(); 736 info->peerPFCState = PeerPFCState(); 737 info->pfcOptions = PFCOptions(); 738 info->protocolsCount = CountProtocols(); 739 info->optionHandlersCount = LCP().CountOptionHandlers(); 740 info->LCPExtensionsCount = 0; 741 info->childrenCount = CountChildren(); 742 info->MRU = MRU(); 743 info->interfaceMTU = InterfaceMTU(); 744 info->connectAttempt = fConnectAttempt; 745 info->connectRetriesLimit = fConnectRetriesLimit; 746 info->connectRetryDelay = ConnectRetryDelay(); 747 info->reconnectDelay = ReconnectDelay(); 748 info->connectedSince = ConnectedSince(); 749 info->idleSince = IdleSince(); 750 info->disconnectAfterIdleSince = DisconnectAfterIdleSince(); 751 info->doesConnectOnDemand = DoesConnectOnDemand(); 752 info->doesAutoReconnect = DoesAutoReconnect(); 753 info->hasDevice = Device(); 754 info->isMultilink = IsMultilink(); 755 info->hasParent = Parent(); 756 break; 757 } 758 759 case PPPC_SET_USERNAME: 760 { 761 if (!data) 762 return B_ERROR; 763 764 MutexLocker locker(fLock); 765 // login information can only be changed before we authenticate 766 if (Phase() >= PPP_AUTHENTICATION_PHASE) 767 return B_NOT_ALLOWED; 768 769 free(fUsername); 770 fUsername = data ? strdup((const char*) data) : strdup(""); 771 break; 772 } 773 774 case PPPC_SET_PASSWORD: 775 { 776 if (!data) 777 return B_ERROR; 778 779 MutexLocker locker(fLock); 780 // login information can only be changed before we authenticate 781 if (Phase() >= PPP_AUTHENTICATION_PHASE) 782 return B_NOT_ALLOWED; 783 784 free(fPassword); 785 fPassword = data ? strdup((const char*) data) : strdup(""); 786 break; 787 } 788 789 case PPPC_SET_ASK_BEFORE_CONNECTING: 790 if (length < sizeof(uint32) || !data) 791 return B_ERROR; 792 793 SetAskBeforeConnecting(*((uint32*)data)); 794 break; 795 796 case PPPC_SET_MRU: 797 if (length < sizeof(uint32) || !data) 798 return B_ERROR; 799 800 SetMRU(*((uint32*)data)); 801 break; 802 803 case PPPC_SET_CONNECT_ON_DEMAND: 804 if (length < sizeof(uint32) || !data) 805 return B_ERROR; 806 807 SetConnectOnDemand(*((uint32*)data)); 808 break; 809 810 case PPPC_SET_AUTO_RECONNECT: 811 if (length < sizeof(uint32) || !data) 812 return B_ERROR; 813 814 SetAutoReconnect(*((uint32*)data)); 815 break; 816 817 case PPPC_HAS_INTERFACE_SETTINGS: 818 if (length < sizeof(driver_settings) || !data) 819 return B_ERROR; 820 821 if (equal_interface_settings(Settings(), (driver_settings*) data)) 822 return B_OK; 823 else 824 return B_ERROR; 825 break; 826 827 case PPPC_ENABLE_REPORTS: 828 { 829 if (length < sizeof(ppp_report_request) || !data) 830 return B_ERROR; 831 832 MutexLocker locker(fLock); 833 ppp_report_request *request = (ppp_report_request*) data; 834 // first, we send an initial state report 835 if (request->type == PPP_CONNECTION_REPORT) { 836 ppp_report_packet report; 837 report.type = PPP_CONNECTION_REPORT; 838 report.code = StateMachine().fLastConnectionReportCode; 839 report.length = sizeof(fID); 840 KPPPReportManager::SendReport(request->thread, &report); 841 if (request->flags & PPP_REMOVE_AFTER_REPORT) 842 return B_OK; 843 } 844 ReportManager().EnableReports(request->type, request->thread, 845 request->flags); 846 break; 847 } 848 849 case PPPC_DISABLE_REPORTS: 850 { 851 if (length < sizeof(ppp_report_request) || !data) 852 return B_ERROR; 853 854 ppp_report_request *request = (ppp_report_request*) data; 855 ReportManager().DisableReports(request->type, request->thread); 856 break; 857 } 858 859 case PPPC_GET_STATISTICS: 860 if (length < sizeof(ppp_statistics) || !data) 861 return B_ERROR; 862 863 memcpy(data, &fStatistics, sizeof(ppp_statistics)); 864 break; 865 866 case PPPC_CONTROL_DEVICE: 867 { 868 if (length < sizeof(ppp_control_info) || !data) 869 return B_ERROR; 870 871 ppp_control_info *control = (ppp_control_info*) data; 872 if (control->index != 0 || !Device()) 873 return B_BAD_INDEX; 874 875 return Device()->Control(control->op, control->data, control->length); 876 } 877 878 case PPPC_CONTROL_PROTOCOL: 879 { 880 if (length < sizeof(ppp_control_info) || !data) 881 return B_ERROR; 882 883 ppp_control_info *control = (ppp_control_info*) data; 884 KPPPProtocol *protocol = ProtocolAt(control->index); 885 if (!protocol) 886 return B_BAD_INDEX; 887 888 return protocol->Control(control->op, control->data, control->length); 889 } 890 891 case PPPC_CONTROL_OPTION_HANDLER: 892 { 893 if (length < sizeof(ppp_control_info) || !data) 894 return B_ERROR; 895 896 ppp_control_info *control = (ppp_control_info*) data; 897 KPPPOptionHandler *optionHandler = LCP().OptionHandlerAt(control->index); 898 if (!optionHandler) 899 return B_BAD_INDEX; 900 901 return optionHandler->Control(control->op, control->data, 902 control->length); 903 } 904 905 case PPPC_CONTROL_LCP_EXTENSION: 906 { 907 if (length < sizeof(ppp_control_info) || !data) 908 return B_ERROR; 909 910 ppp_control_info *control = (ppp_control_info*) data; 911 KPPPLCPExtension *lcpExtension = LCP().LCPExtensionAt(control->index); 912 if (!lcpExtension) 913 return B_BAD_INDEX; 914 915 return lcpExtension->Control(control->op, control->data, 916 control->length); 917 } 918 919 case PPPC_CONTROL_CHILD: 920 { 921 if (length < sizeof(ppp_control_info) || !data) 922 return B_ERROR; 923 924 ppp_control_info *control = (ppp_control_info*) data; 925 KPPPInterface *child = ChildAt(control->index); 926 if (!child) 927 return B_BAD_INDEX; 928 929 return child->Control(control->op, control->data, control->length); 930 } 931 932 default: 933 dprintf("bad ppp_interface_control!\n"); 934 return B_BAD_VALUE; 935 } 936 937 return B_OK; 938 } 939 940 941 /*! \brief Sets a new device for this interface. 942 943 A device add-on should call this method to register itself. The best place to do 944 this is in your module's \c add_to() function. 945 946 \param device The device object. 947 948 \return \c true if successful or \c false otherwise. 949 950 \sa KPPPDevice 951 \sa kppp_module_info 952 */ 953 bool 954 KPPPInterface::SetDevice(KPPPDevice *device) 955 { 956 TRACE("KPPPInterface: SetDevice(%p)\n", device); 957 958 if (device && &device->Interface() != this) 959 return false; 960 961 if (IsMultilink() && !Parent()) 962 return false; 963 // main interfaces do not have devices 964 965 MutexLocker locker(fLock); 966 967 if (Phase() != PPP_DOWN_PHASE) 968 return false; 969 // a running connection may not change 970 971 if (fDevice && (IsUp() || fDevice->IsUp())) 972 Down(); 973 974 fDevice = device; 975 SetNext(device); 976 977 if (fDevice) 978 fMRU = fDevice->MTU() - 2; 979 980 CalculateInterfaceMTU(); 981 CalculateBaudRate(); 982 983 return true; 984 } 985 986 987 /*! \brief Adds a new protocol to this interface. 988 989 NOTE: You can only add protocols in \c PPP_DOWN_PHASE. \n 990 A protocol add-on should call this method to register itself. The best place to do 991 this is in your module's \c add_to() function. 992 993 \param protocol The protocol object. 994 995 \return \c true if successful or \c false otherwise. 996 997 \sa KPPPProtocol 998 \sa kppp_module_info 999 */ 1000 bool 1001 KPPPInterface::AddProtocol(KPPPProtocol *protocol) 1002 { 1003 // Find insert position after the last protocol 1004 // with the same level. 1005 1006 TRACE("KPPPInterface: AddProtocol(%X)\n", 1007 protocol ? protocol->ProtocolNumber() : 0); 1008 1009 if (!protocol || &protocol->Interface() != this 1010 || protocol->Level() == PPP_INTERFACE_LEVEL) 1011 return false; 1012 1013 MutexLocker locker(fLock); 1014 1015 if (Phase() != PPP_DOWN_PHASE) 1016 return false; 1017 // a running connection may not change 1018 1019 KPPPProtocol *current = fFirstProtocol, *previous = NULL; 1020 1021 while (current) { 1022 if (current->Level() < protocol->Level()) 1023 break; 1024 1025 previous = current; 1026 current = current->NextProtocol(); 1027 } 1028 1029 if (!current) { 1030 if (!previous) 1031 fFirstProtocol = protocol; 1032 else 1033 previous->SetNextProtocol(protocol); 1034 1035 // set up the last protocol in the chain 1036 protocol->SetNextProtocol(NULL); 1037 // this also sets next to NULL 1038 protocol->SetNext(this); 1039 // we need to set us as the next layer for the last protocol 1040 } else { 1041 protocol->SetNextProtocol(current); 1042 1043 if (!previous) 1044 fFirstProtocol = protocol; 1045 else 1046 previous->SetNextProtocol(protocol); 1047 } 1048 1049 if (protocol->Level() < PPP_PROTOCOL_LEVEL) 1050 CalculateInterfaceMTU(); 1051 1052 if (IsUp() || Phase() >= protocol->ActivationPhase()) 1053 protocol->Up(); 1054 1055 return true; 1056 } 1057 1058 1059 /*! \brief Removes a protocol from this interface. 1060 1061 NOTE: You can only remove protocols in \c PPP_DOWN_PHASE. \n 1062 A protocol add-on should call this method to remove itself explicitly from the 1063 interface. \n 1064 Normally, this method is called in KPPPProtocol's destructor. Do not call it 1065 yourself unless you know what you do! 1066 1067 \param protocol The protocol object. 1068 1069 \return \c true if successful or \c false otherwise. 1070 */ 1071 bool 1072 KPPPInterface::RemoveProtocol(KPPPProtocol *protocol) 1073 { 1074 TRACE("KPPPInterface: RemoveProtocol(%X)\n", 1075 protocol ? protocol->ProtocolNumber() : 0); 1076 1077 MutexLocker locker(fLock); 1078 1079 if (Phase() != PPP_DOWN_PHASE) 1080 return false; 1081 // a running connection may not change 1082 1083 KPPPProtocol *current = fFirstProtocol, *previous = NULL; 1084 1085 while (current) { 1086 if (current == protocol) { 1087 if (!protocol->IsDown()) 1088 protocol->Down(); 1089 1090 if (previous) { 1091 previous->SetNextProtocol(current->NextProtocol()); 1092 1093 // set us as next layer if needed 1094 if (!previous->Next()) 1095 previous->SetNext(this); 1096 } else 1097 fFirstProtocol = current->NextProtocol(); 1098 1099 current->SetNextProtocol(NULL); 1100 1101 CalculateInterfaceMTU(); 1102 1103 return true; 1104 } 1105 1106 previous = current; 1107 current = current->NextProtocol(); 1108 } 1109 1110 return false; 1111 } 1112 1113 1114 //! Returns the number of protocol modules belonging to this interface. 1115 int32 1116 KPPPInterface::CountProtocols() const 1117 { 1118 MutexLocker locker(fLock); 1119 1120 KPPPProtocol *protocol = FirstProtocol(); 1121 1122 int32 count = 0; 1123 for (; protocol; protocol = protocol->NextProtocol()) 1124 ++count; 1125 1126 return count; 1127 } 1128 1129 1130 //! Returns the protocol at the given \a index or \c NULL if it could not be found. 1131 KPPPProtocol* 1132 KPPPInterface::ProtocolAt(int32 index) const 1133 { 1134 MutexLocker locker(fLock); 1135 1136 KPPPProtocol *protocol = FirstProtocol(); 1137 1138 int32 currentIndex = 0; 1139 for (; protocol && currentIndex != index; protocol = protocol->NextProtocol()) 1140 ++currentIndex; 1141 1142 return protocol; 1143 } 1144 1145 1146 /*! \brief Returns the protocol object responsible for a given protocol number. 1147 1148 \param protocolNumber The protocol number that the object should handle. 1149 \param start (Optional): Start with this protocol. Can be used for iteration. 1150 1151 \return Either the object that was found or \c NULL. 1152 */ 1153 KPPPProtocol* 1154 KPPPInterface::ProtocolFor(uint16 protocolNumber, KPPPProtocol *start) const 1155 { 1156 TRACE("KPPPInterface: ProtocolFor(%X)\n", protocolNumber); 1157 1158 // MutexLocker locker(fLock); 1159 // already locked in ::Receive, uncomment this line will cause double lock 1160 1161 KPPPProtocol *current = start ? start : FirstProtocol(); 1162 1163 for (; current; current = current->NextProtocol()) { 1164 if (current->ProtocolNumber() == protocolNumber 1165 || (current->Flags() & PPP_INCLUDES_NCP 1166 && (current->ProtocolNumber() & 0x7FFF) 1167 == (protocolNumber & 0x7FFF))) 1168 return current; 1169 } 1170 1171 return NULL; 1172 } 1173 1174 1175 //! Adds a new child interface (used for multilink interfaces). 1176 bool 1177 KPPPInterface::AddChild(KPPPInterface *child) 1178 { 1179 TRACE("KPPPInterface: AddChild(%lX)\n", child ? child->ID() : 0); 1180 1181 if (!child) 1182 return false; 1183 1184 MutexLocker locker(fLock); 1185 1186 if (fChildren.HasItem(child) || !fChildren.AddItem(child)) 1187 return false; 1188 1189 child->SetParent(this); 1190 1191 return true; 1192 } 1193 1194 1195 //! Removes a new child from this interface (used for multilink interfaces). 1196 bool 1197 KPPPInterface::RemoveChild(KPPPInterface *child) 1198 { 1199 TRACE("KPPPInterface: RemoveChild(%lX)\n", child ? child->ID() : 0); 1200 1201 MutexLocker locker(fLock); 1202 1203 if (!fChildren.RemoveItem(child)) 1204 return false; 1205 1206 child->SetParent(NULL); 1207 1208 // parents cannot exist without their children 1209 if (CountChildren() == 0 && fManager && Ifnet()) 1210 Delete(); 1211 1212 return true; 1213 } 1214 1215 1216 //! Returns the child interface at the given \a index (used for multilink interfaces). 1217 KPPPInterface* 1218 KPPPInterface::ChildAt(int32 index) const 1219 { 1220 TRACE("KPPPInterface: ChildAt(%ld)\n", index); 1221 1222 MutexLocker locker(fLock); 1223 1224 KPPPInterface *child = fChildren.ItemAt(index); 1225 1226 if (child == fChildren.GetDefaultItem()) 1227 return NULL; 1228 1229 return child; 1230 } 1231 1232 1233 //! Enables or disables the auto-reconnect feture. 1234 void 1235 KPPPInterface::SetAutoReconnect(bool autoReconnect) 1236 { 1237 TRACE("KPPPInterface: SetAutoReconnect(%s)\n", autoReconnect ? "true" : "false"); 1238 1239 if (Mode() != PPP_CLIENT_MODE) 1240 return; 1241 1242 fAutoReconnect = autoReconnect; 1243 } 1244 1245 1246 //! Enables or disables the connect-on-demand feature. 1247 void 1248 KPPPInterface::SetConnectOnDemand(bool connectOnDemand) 1249 { 1250 // All protocols must check if ConnectOnDemand was enabled/disabled after this 1251 // interface went down. This is the only situation where a change is relevant. 1252 1253 TRACE("KPPPInterface: SetConnectOnDemand(%s)\n", connectOnDemand ? "true" : "false"); 1254 1255 MutexLocker locker(fLock); 1256 1257 // Only clients support ConnectOnDemand. 1258 if (Mode() != PPP_CLIENT_MODE) { 1259 TRACE("KPPPInterface::SetConnectOnDemand(): Wrong mode!\n"); 1260 fConnectOnDemand = false; 1261 return; 1262 } else if (DoesConnectOnDemand() == connectOnDemand) 1263 return; 1264 1265 fConnectOnDemand = connectOnDemand; 1266 1267 // Do not allow changes when we are disconnected (only main interfaces). 1268 // This would make no sense because 1269 // - enabling: this cannot happen because hidden interfaces are deleted if they 1270 // could not establish a connection (the user cannot access hidden interfaces) 1271 // - disabling: the interface disappears as seen from the user, so we delete it 1272 if (!Parent() && State() == PPP_INITIAL_STATE && Phase() == PPP_DOWN_PHASE) { 1273 if (!connectOnDemand) 1274 Delete(); 1275 // as long as the protocols were not configured we can just delete us 1276 1277 return; 1278 } 1279 1280 // check if we need to set/unset flags 1281 if (connectOnDemand) { 1282 if (Ifnet()) 1283 Ifnet()->flags |= IFF_UP; 1284 } else if (!connectOnDemand && Phase() < PPP_ESTABLISHED_PHASE) { 1285 if (Ifnet()) 1286 Ifnet()->flags &= ~IFF_UP; 1287 } 1288 } 1289 1290 1291 //! Sets whether the user is asked before establishing the connection. 1292 void 1293 KPPPInterface::SetAskBeforeConnecting(bool ask) 1294 { 1295 MutexLocker locker(fLock); 1296 1297 bool old = fAskBeforeConnecting; 1298 fAskBeforeConnecting = ask; 1299 1300 if (old && fAskBeforeConnecting == false && State() == PPP_STARTING_STATE 1301 && Phase() == PPP_DOWN_PHASE) { 1302 // locker.Unlock(); 1303 StateMachine().ContinueOpenEvent(); 1304 } 1305 } 1306 1307 1308 //! Sets Protocol-Field-Compression options. 1309 bool 1310 KPPPInterface::SetPFCOptions(uint8 pfcOptions) 1311 { 1312 TRACE("KPPPInterface: SetPFCOptions(0x%X)\n", pfcOptions); 1313 1314 MutexLocker locker(fLock); 1315 1316 if (PFCOptions() & PPP_FREEZE_PFC_OPTIONS) 1317 return false; 1318 1319 fPFCOptions = pfcOptions; 1320 return true; 1321 } 1322 1323 1324 /*! \brief Brings this interface up. 1325 1326 \c Down() overrides all \c Up() requests. \n 1327 This method runs an asynchronous process (it returns immediately). 1328 1329 \return \c false on error. 1330 */ 1331 bool 1332 KPPPInterface::Up() 1333 { 1334 TRACE("KPPPInterface: Up()\n"); 1335 1336 if (InitCheck() != B_OK || Phase() == PPP_TERMINATION_PHASE) 1337 return false; 1338 1339 if (IsUp()) 1340 return true; 1341 1342 MutexLocker locker(fLock); 1343 StateMachine().OpenEvent(); 1344 1345 return true; 1346 } 1347 1348 1349 /*! \brief Brings this interface down. 1350 1351 \c Down() overrides all \c Up() requests. \n 1352 This method runs an asynchronous process (it returns immediately). 1353 1354 \return \c false on error. 1355 */ 1356 bool 1357 KPPPInterface::Down() 1358 { 1359 TRACE("KPPPInterface: Down()\n"); 1360 1361 if (InitCheck() != B_OK) 1362 return false; 1363 else if (State() == PPP_INITIAL_STATE && Phase() == PPP_DOWN_PHASE) 1364 return true; 1365 1366 send_data_with_timeout(fReconnectThread, 0, NULL, 0, 200); 1367 // tell the reconnect thread to abort its attempt (if it's still waiting) 1368 1369 MutexLocker locker(fLock); 1370 StateMachine().CloseEvent(); 1371 1372 return true; 1373 } 1374 1375 1376 //! Waits for connection establishment. Returns true if successful. 1377 bool 1378 KPPPInterface::WaitForConnection() 1379 { 1380 TRACE("KPPPInterface: WaitForConnection()\n"); 1381 1382 if (InitCheck() != B_OK) 1383 return false; 1384 1385 // just delay ~3 seconds to wait for ppp go up 1386 for (uint32 i = 0; i < 10000; i++) 1387 for (uint32 j = 0; j < 3000000; j++) 1388 1389 return true; // for temporary 1390 1391 ReportManager().EnableReports(PPP_CONNECTION_REPORT, find_thread(NULL)); 1392 1393 ppp_report_packet report; 1394 thread_id sender; 1395 bool successful = false; 1396 while (true) { 1397 if (receive_data(&sender, &report, sizeof(report)) != PPP_REPORT_CODE) 1398 continue; 1399 1400 if (report.type == PPP_DESTRUCTION_REPORT) 1401 break; 1402 else if (report.type != PPP_CONNECTION_REPORT) 1403 continue; 1404 1405 if (report.code == PPP_REPORT_UP_SUCCESSFUL) { 1406 successful = true; 1407 break; 1408 } else if (report.code == PPP_REPORT_DOWN_SUCCESSFUL) 1409 break; 1410 } 1411 1412 ReportManager().DisableReports(PPP_CONNECTION_REPORT, find_thread(NULL)); 1413 dprintf("KPPPInterface: WaitForConnection():%s\n", successful ? "True" : "False"); 1414 return successful; 1415 } 1416 1417 1418 /*! \brief Loads modules specified in the settings structure. 1419 1420 \param settings PPP interface description file format settings. 1421 \param start Index of driver_parameter to start with. 1422 \param count Number of driver_parameters to look at. 1423 1424 \return \c true if successful or \c false otherwise. 1425 */ 1426 bool 1427 KPPPInterface::LoadModules(driver_settings *settings, int32 start, int32 count) 1428 { 1429 TRACE("KPPPInterface: LoadModules()\n"); 1430 1431 if (Phase() != PPP_DOWN_PHASE) 1432 return false; 1433 // a running connection may not change 1434 1435 ppp_module_key_type type; 1436 // which type key was used for loading this module? 1437 1438 const char *name = NULL; 1439 1440 // multilink handling 1441 for (int32 index = start; 1442 index < settings->parameter_count && index < (start + count); index++) { 1443 if (!strcasecmp(settings->parameters[index].name, PPP_MULTILINK_KEY) 1444 && settings->parameters[index].value_count > 0) { 1445 if (!LoadModule(settings->parameters[index].values[0], 1446 &settings->parameters[index], PPP_MULTILINK_KEY_TYPE)) 1447 return false; 1448 break; 1449 } 1450 } 1451 1452 // are we a multilink main interface? 1453 if (IsMultilink() && !Parent()) { 1454 // main interfaces only load the multilink module 1455 // and create a child using their settings 1456 fManager->CreateInterface(settings, ID()); 1457 return true; 1458 } 1459 1460 for (int32 index = start; 1461 index < settings->parameter_count && index < start + count; index++) { 1462 type = PPP_UNDEFINED_KEY_TYPE; 1463 1464 name = settings->parameters[index].name; 1465 1466 if (!strcasecmp(name, PPP_LOAD_MODULE_KEY)) 1467 type = PPP_LOAD_MODULE_KEY_TYPE; 1468 else if (!strcasecmp(name, PPP_DEVICE_KEY)) 1469 type = PPP_DEVICE_KEY_TYPE; 1470 else if (!strcasecmp(name, PPP_PROTOCOL_KEY)) 1471 type = PPP_PROTOCOL_KEY_TYPE; 1472 else if (!strcasecmp(name, PPP_AUTHENTICATOR_KEY)) 1473 type = PPP_AUTHENTICATOR_KEY_TYPE; 1474 1475 if (type >= 0) 1476 for (int32 value_id = 0; value_id < settings->parameters[index].value_count; 1477 value_id++) 1478 if (!LoadModule(settings->parameters[index].values[value_id], 1479 &settings->parameters[index], type)) 1480 return false; 1481 } 1482 1483 return true; 1484 } 1485 1486 1487 /*! \brief Loads a specific module. 1488 1489 \param name Name of the module. 1490 \param parameter Module settings. 1491 \param type Type of module. 1492 1493 \return \c true if successful or \c false otherwise. 1494 */ 1495 bool 1496 KPPPInterface::LoadModule(const char *name, driver_parameter *parameter, 1497 ppp_module_key_type type) 1498 { 1499 TRACE("KPPPInterface: LoadModule(%s)\n", name ? name : "XXX: NO NAME"); 1500 1501 if (Phase() != PPP_DOWN_PHASE) 1502 return false; 1503 // a running connection may not change 1504 1505 if (!name || strlen(name) > B_FILE_NAME_LENGTH) 1506 return false; 1507 1508 char *moduleName = new char[B_PATH_NAME_LENGTH]; 1509 1510 sprintf(moduleName, "%s/%s", PPP_MODULES_PATH, name); 1511 1512 ppp_module_info *module; 1513 if (get_module(moduleName, (module_info**) &module) != B_OK) { 1514 delete[] moduleName; 1515 return false; 1516 } 1517 1518 // add the module to the list of loaded modules 1519 // for putting them on our destruction 1520 fModules.AddItem(moduleName); 1521 1522 return module->add_to(Parent() ? *Parent() : *this, this, parameter, type); 1523 } 1524 1525 1526 //! Always returns true. 1527 bool 1528 KPPPInterface::IsAllowedToSend() const 1529 { 1530 return true; 1531 } 1532 1533 1534 /*! \brief Sends a packet to the device. 1535 1536 This brings the interface up if connect-on-demand is enabled and we are not 1537 connected. \n 1538 PFC encoding is handled here. \n 1539 NOTE: In order to prevent interface destruction while sending you must either 1540 hold a refcount for this interface or make sure it is locked. 1541 1542 \param packet The packet. 1543 \param protocolNumber The packet's protocol number. 1544 1545 \return 1546 - \c B_OK: Sending was successful. 1547 - \c B_ERROR: Some error occured. 1548 */ 1549 status_t 1550 KPPPInterface::Send(net_buffer *packet, uint16 protocolNumber) 1551 { 1552 TRACE("KPPPInterface: Send(0x%X)\n", protocolNumber); 1553 1554 if (!packet) 1555 return B_ERROR; 1556 1557 // we must pass the basic tests like: 1558 // do we have a device? 1559 // did we load all modules? 1560 if (InitCheck() != B_OK) { 1561 ERROR("InitCheck() fail\n"); 1562 gBufferModule->free(packet); 1563 return B_ERROR; 1564 } 1565 1566 1567 // go up if ConnectOnDemand is enabled and we are disconnected 1568 // TODO: our new netstack will simplify ConnectOnDemand handling, so 1569 // we do not have to handle it here 1570 if ((protocolNumber != PPP_LCP_PROTOCOL && DoesConnectOnDemand() 1571 && (Phase() == PPP_DOWN_PHASE 1572 || Phase() == PPP_ESTABLISHMENT_PHASE) 1573 && !Up()) && !WaitForConnection()) { 1574 dprintf("DoesConnectOnDemand fail!\n"); 1575 // gBufferModule->free(packet); 1576 return B_ERROR; 1577 } 1578 1579 // find the protocol handler for the current protocol number 1580 KPPPProtocol *protocol = ProtocolFor(protocolNumber); 1581 while (protocol && !protocol->IsEnabled()) 1582 protocol = protocol->NextProtocol() ? 1583 ProtocolFor(protocolNumber, protocol->NextProtocol()) : NULL; 1584 1585 #if DEBUG 1586 if (!protocol) 1587 TRACE("KPPPInterface::Send(): no protocol found!\n"); 1588 else if (!Device()->IsUp()) 1589 TRACE("KPPPInterface::Send(): device is not up!\n"); 1590 else if (!protocol->IsEnabled()) 1591 TRACE("KPPPInterface::Send(): protocol not enabled!\n"); 1592 else if (!IsProtocolAllowed(*protocol)) 1593 TRACE("KPPPInterface::Send(): protocol not allowed to send!\n"); 1594 else 1595 TRACE("KPPPInterface::Send(): protocol allowed\n"); 1596 #endif 1597 1598 // make sure that protocol is allowed to send and everything is up 1599 if (Device()->IsUp() && protocolNumber == 0x0021) { 1600 // IP_PROTOCOL 0x0021 1601 TRACE("send IP packet!\n"); 1602 } else if (!Device()->IsUp() || !protocol || !protocol->IsEnabled() 1603 || !IsProtocolAllowed(*protocol)) { 1604 ERROR("KPPPInterface::Send(): Device is down, throw packet away!!\n"); 1605 // gBufferModule->free(packet); 1606 return B_ERROR; 1607 } 1608 1609 // encode in ppp frame and consider using PFC 1610 if (UseLocalPFC() && (protocolNumber & 0xFF00) == 0) { 1611 TRACE("%s::%s should not go here\n", __FILE__, __func__); 1612 NetBufferPrepend<uint8> bufferHeader(packet); 1613 if (bufferHeader.Status() != B_OK) 1614 return bufferHeader.Status(); 1615 1616 uint8 &header = bufferHeader.Data(); 1617 1618 // memcpy(header.destination, ether_pppoe_ppp_header, 1); 1619 header = (protocolNumber & 0x00FF); 1620 // bufferHeader.Sync(); 1621 1622 } else { 1623 NetBufferPrepend<uint16> bufferHeader(packet); 1624 if (bufferHeader.Status() != B_OK) 1625 return bufferHeader.Status(); 1626 1627 uint16 &header = bufferHeader.Data(); 1628 1629 // set protocol (the only header field) 1630 header = htons(protocolNumber); 1631 // bufferHeader.Sync(); 1632 } 1633 1634 // pass to device if we're either not a multilink interface or a child interface 1635 if (!IsMultilink() || Parent()) { 1636 // check if packet is too big for device 1637 uint32 length = packet->size; 1638 1639 if (length > MRU()) { 1640 dprintf("packet too large!\n"); 1641 gBufferModule->free(packet); 1642 return B_ERROR; 1643 } 1644 1645 atomic_add64(&fStatistics.bytesSent, length); 1646 atomic_add64(&fStatistics.packetsSent, 1); 1647 TRACE("%s::%s SendToNext\n", __FILE__, __func__); 1648 return SendToNext(packet, 0); 1649 // this is normally the device, but there can be something inbetween 1650 } else { 1651 // the multilink protocol should have sent it to some child interface 1652 TRACE("It is weird to go here!\n"); 1653 gBufferModule->free(packet); 1654 return B_ERROR; 1655 } 1656 } 1657 1658 1659 /*! \brief Receives a packet. 1660 1661 Encapsulation protocols may use this method to pass encapsulated packets to the 1662 PPP interface. Packets will be handled as if they were raw packets that came 1663 directly from the device via \c ReceiveFromDevice(). \n 1664 If no handler could be found in this interface the parent's \c Receive() method 1665 is called. 1666 1667 \param packet The packet. 1668 \param protocolNumber The packet's protocol number. 1669 1670 \return 1671 - \c B_OK: Receiving was successful. 1672 - \c B_ERROR: Some error occured. 1673 - \c PPP_REJECTED: No protocol handler could be found for this packet. 1674 - \c PPP_DISCARDED: The protocol handler(s) did not handle this packet. 1675 */ 1676 status_t 1677 KPPPInterface::Receive(net_buffer *packet, uint16 protocolNumber) 1678 { 1679 TRACE("KPPPInterface: Receive(0x%X)\n", protocolNumber); 1680 1681 if (!packet) 1682 return B_ERROR; 1683 1684 MutexLocker locker(fLock); 1685 1686 int32 result = PPP_REJECTED; 1687 // assume we have no handler 1688 1689 if (protocolNumber == 0x0021 && Device() && Device()->IsUp()) { 1690 // IP_PROTOCOL 0x0021 1691 TRACE("%s::%s: receiving IP packet\n", __FILE__, __func__); 1692 ppp_device* dev=(ppp_device*)Ifnet(); 1693 1694 if (dev) 1695 return gStackModule->fifo_enqueue_buffer(&(dev->ppp_fifo), packet); 1696 else { 1697 dprintf("%s::%s: no ppp_device\n", __FILE__, __func__); 1698 return B_ERROR; 1699 } 1700 } 1701 // // Set our interface as the receiver. 1702 // // The real netstack protocols (IP, IPX, etc.) might get confused if our 1703 // // interface is a main interface and at the same time not registered 1704 // // because then there is no receiver interface. 1705 // // PPP NCPs should be aware of that! 1706 // if (packet->m_flags & M_PKTHDR && Ifnet() != NULL) 1707 // packet->m_pkthdr.rcvif = Ifnet(); 1708 1709 // Find handler and let it parse the packet. 1710 // The handler does need not be up because if we are a server 1711 // the handler might be upped by this packet. 1712 // If authenticating we only allow authentication phase protocols. 1713 KPPPProtocol *protocol = ProtocolFor(protocolNumber); 1714 for (; protocol; 1715 protocol = protocol->NextProtocol() ? 1716 ProtocolFor(protocolNumber, protocol->NextProtocol()) : NULL) { 1717 TRACE("KPPPInterface::Receive(): trying protocol\n"); 1718 1719 if (!protocol->IsEnabled() || !IsProtocolAllowed(*protocol)) 1720 continue; 1721 // skip handler if disabled or not allowed 1722 1723 result = protocol->Receive(packet, protocolNumber); 1724 if (result == PPP_UNHANDLED) 1725 continue; 1726 1727 return result; 1728 } 1729 1730 TRACE("KPPPInterface::Receive(): trying parent\n"); 1731 1732 // maybe the parent interface can handle the packet 1733 if (Parent()) 1734 return Parent()->Receive(packet, protocolNumber); 1735 1736 if (result == PPP_UNHANDLED) { 1737 gBufferModule->free(packet); 1738 return PPP_DISCARDED; 1739 } else { 1740 StateMachine().RUCEvent(packet, protocolNumber); 1741 return PPP_REJECTED; 1742 } 1743 } 1744 1745 1746 /*! \brief Receives a base PPP packet from the device. 1747 1748 KPPPDevice should call this method when it receives a packet. \n 1749 PFC decoding is handled here. 1750 1751 \param packet The packet. 1752 1753 \return 1754 - \c B_OK: Receiving was successful. 1755 - \c B_ERROR: Some error occured. 1756 - \c PPP_REJECTED: No protocol handler could be found for this packet. 1757 - \c PPP_DISCARDED: The protocol handler(s) did not handle this packet. 1758 */ 1759 status_t 1760 KPPPInterface::ReceiveFromDevice(net_buffer *packet) 1761 { 1762 TRACE("KPPPInterface: ReceiveFromDevice()\n"); 1763 1764 if (!packet) 1765 return B_ERROR; 1766 1767 if (InitCheck() != B_OK) { 1768 gBufferModule->free(packet); 1769 return B_ERROR; 1770 } 1771 1772 uint32 length = packet->size; 1773 // decode ppp frame and recognize PFC 1774 NetBufferHeaderReader<uint16> bufferHeader(packet); 1775 if (bufferHeader.Status() < B_OK) 1776 return bufferHeader.Status(); 1777 1778 uint16 &header = bufferHeader.Data(); 1779 uint16 protocolNumber = ntohs(header); // copy the protocol number 1780 TRACE("%s::%s: ppp protocol number:%x\n", __FILE__, __func__, protocolNumber); 1781 1782 bufferHeader.Remove(); 1783 bufferHeader.Sync(); 1784 1785 // PFC only use 1 byte for protocol, the next byte is in first byte of message 1786 if (protocolNumber & (1UL<<8)) { 1787 NetBufferPrepend<uint8> bufferprepend(packet); 1788 if (bufferprepend.Status() < B_OK) { 1789 gBufferModule->free(packet); 1790 return bufferprepend.Status(); 1791 } 1792 1793 uint8 &prepend = bufferprepend.Data(); 1794 prepend = (uint8)(protocolNumber & 0x00FF); 1795 // bufferprepend.Sync(); 1796 TRACE("%s::%s:PFC protocol:%x\n", __FILE__, __func__, protocolNumber>>8); 1797 } else { 1798 TRACE("%s::%s:Non-PFC protocol:%x\n", __FILE__, __func__, protocolNumber); 1799 } 1800 1801 atomic_add64(&fStatistics.bytesReceived, length); 1802 atomic_add64(&fStatistics.packetsReceived, 1); 1803 return Receive(packet, protocolNumber); 1804 } 1805 1806 1807 //! Manages Pulse() calls for all add-ons and hanldes idle-disconnection. 1808 void 1809 KPPPInterface::Pulse() 1810 { 1811 MutexLocker locker(fLock); 1812 1813 if (Device()) 1814 Device()->Pulse(); 1815 1816 KPPPProtocol *protocol = FirstProtocol(); 1817 for (; protocol; protocol = protocol->NextProtocol()) 1818 protocol->Pulse(); 1819 1820 uint32 currentTime = real_time_clock(); 1821 if (fUpdateIdleSince) { 1822 fIdleSince = currentTime; 1823 fUpdateIdleSince = false; 1824 } 1825 1826 // check our idle time and disconnect if needed 1827 if (fDisconnectAfterIdleSince > 0 && fIdleSince != 0 1828 && fIdleSince - currentTime >= fDisconnectAfterIdleSince) 1829 StateMachine().CloseEvent(); 1830 } 1831 1832 1833 //! Registers an ifnet structure for this interface. 1834 bool 1835 KPPPInterface::RegisterInterface() 1836 { 1837 TRACE("KPPPInterface: RegisterInterface()\n"); 1838 1839 if (fIfnet) 1840 return true; 1841 // we are already registered 1842 1843 MutexLocker locker(fLock); 1844 1845 // only MainInterfaces get an ifnet 1846 if (IsMultilink() && Parent() && Parent()->RegisterInterface()) 1847 return true; 1848 1849 if (!fManager) 1850 return false; 1851 1852 fIfnet = fManager->RegisterInterface(ID()); 1853 1854 if (!fIfnet) { 1855 dprintf("%s:%s: damn it no fIfnet device\n", __FILE__, __func__); 1856 return false; 1857 } 1858 1859 if (DoesConnectOnDemand()) 1860 fIfnet->flags |= IFF_UP; 1861 1862 CalculateInterfaceMTU(); 1863 CalculateBaudRate(); 1864 1865 return true; 1866 } 1867 1868 1869 //! Unregisters this interface's ifnet structure. 1870 bool 1871 KPPPInterface::UnregisterInterface() 1872 { 1873 TRACE("KPPPInterface: UnregisterInterface()\n"); 1874 1875 if (!fIfnet) 1876 return true; 1877 // we are already unregistered 1878 1879 MutexLocker locker(fLock); 1880 1881 // only MainInterfaces get an ifnet 1882 if (IsMultilink() && Parent()) 1883 return true; 1884 1885 if (!fManager) 1886 return false; 1887 1888 fManager->UnregisterInterface(ID()); 1889 // this will delete fIfnet, so do not access it anymore! 1890 fIfnet = NULL; 1891 1892 return true; 1893 } 1894 1895 1896 //! Called by KPPPManager: manager routes stack ioctls to the corresponding interface. 1897 status_t 1898 KPPPInterface::StackControl(uint32 op, void *data) 1899 { 1900 TRACE("KPPPInterface: StackControl(0x%lX)\n", op); 1901 1902 switch (op) { 1903 default: 1904 return StackControlEachHandler(op, data); 1905 } 1906 1907 return B_OK; 1908 } 1909 1910 1911 //! Utility class used by ControlEachHandler(). 1912 template<class T> 1913 class CallStackControl { 1914 public: 1915 inline CallStackControl(uint32 op, void *data, status_t& result) 1916 : fOp(op), fData(data), fResult(result) {} 1917 inline void operator() (T *item) 1918 { 1919 if (!item || !item->IsEnabled()) 1920 return; 1921 status_t tmp = item->StackControl(fOp, fData); 1922 if (tmp == B_OK && fResult == B_BAD_VALUE) 1923 fResult = B_OK; 1924 else if (tmp != B_BAD_VALUE) 1925 fResult = tmp; 1926 } 1927 private: 1928 uint32 fOp; 1929 void *fData; 1930 status_t& fResult; 1931 }; 1932 1933 /*! \brief This calls Control() with the given parameters for each add-on. 1934 1935 \return 1936 - \c B_OK: All handlers returned B_OK. 1937 - \c B_BAD_VALUE: No handler was found. 1938 - Any other value: Error code which was returned by the last failing handler. 1939 */ 1940 status_t 1941 KPPPInterface::StackControlEachHandler(uint32 op, void *data) 1942 { 1943 TRACE("KPPPInterface: StackControlEachHandler(0x%lX)\n", op); 1944 1945 status_t result = B_BAD_VALUE, tmp; 1946 1947 MutexLocker locker(fLock); 1948 1949 KPPPProtocol *protocol = FirstProtocol(); 1950 for (; protocol; protocol = protocol->NextProtocol()) { 1951 tmp = protocol->StackControl(op, data); 1952 if (tmp == B_OK && result == B_BAD_VALUE) 1953 result = B_OK; 1954 else if (tmp != B_BAD_VALUE) 1955 result = tmp; 1956 } 1957 1958 ForEachItem(LCP().fLCPExtensions, 1959 CallStackControl<KPPPLCPExtension>(op, data, result)); 1960 ForEachItem(LCP().fOptionHandlers, 1961 CallStackControl<KPPPOptionHandler>(op, data, result)); 1962 1963 return result; 1964 } 1965 1966 1967 //! Recalculates the MTU from the MRU (includes encapsulation protocol overheads). 1968 void 1969 KPPPInterface::CalculateInterfaceMTU() 1970 { 1971 TRACE("KPPPInterface: CalculateInterfaceMTU()\n"); 1972 1973 // MutexLocker locker(fLock); 1974 // uncomment this line will cause double lock 1975 // alreay locked in ::KPPPInterface 1976 1977 fInterfaceMTU = fMRU; 1978 fHeaderLength = 2; 1979 1980 // sum all headers (the protocol field is not counted) 1981 KPPPProtocol *protocol = FirstProtocol(); 1982 for (; protocol; protocol = protocol->NextProtocol()) { 1983 if (protocol->Level() < PPP_PROTOCOL_LEVEL) 1984 fHeaderLength += protocol->Overhead(); 1985 } 1986 1987 fInterfaceMTU -= fHeaderLength; 1988 1989 if (Ifnet()) { 1990 Ifnet()->mtu = fInterfaceMTU; 1991 Ifnet()->header_length = fHeaderLength; 1992 return; 1993 } 1994 1995 if (Parent()) 1996 Parent()->CalculateInterfaceMTU(); 1997 } 1998 1999 2000 //! Recalculates the baud rate. 2001 void 2002 KPPPInterface::CalculateBaudRate() 2003 { 2004 TRACE("KPPPInterface: CalculateBaudRate()\n"); 2005 2006 // MutexLocker locker(fLock); // uncomment this will cause double lock 2007 2008 if (!Ifnet()) 2009 return; 2010 2011 if (Device()) 2012 fIfnet->link_speed = max_c(Device()->InputTransferRate(), 2013 Device()->OutputTransferRate()); 2014 else { 2015 fIfnet->link_speed = 0; 2016 for (int32 index = 0; index < CountChildren(); index++) 2017 if (ChildAt(index)->Ifnet()) 2018 fIfnet->link_speed += ChildAt(index)->Ifnet()->link_speed; 2019 return; 2020 } 2021 } 2022 2023 2024 //! Reconnects. Waits a given delay (in miliseconds) before reconnecting. 2025 void 2026 KPPPInterface::Reconnect(uint32 delay) 2027 { 2028 TRACE("KPPPInterface: Reconnect(%ld)\n", delay); 2029 2030 MutexLocker locker(fLock); 2031 2032 if (fReconnectThread != -1) 2033 return; 2034 2035 ++fConnectAttempt; 2036 2037 // start a new thread that calls our Up() method 2038 reconnect_info info; 2039 info.interface = this; 2040 info.thread = &fReconnectThread; 2041 info.delay = delay; 2042 2043 fReconnectThread = spawn_kernel_thread(reconnect_thread, 2044 "KPPPInterface: reconnect_thread", B_NORMAL_PRIORITY, NULL); 2045 2046 resume_thread(fReconnectThread); 2047 2048 send_data(fReconnectThread, 0, &info, sizeof(reconnect_info)); 2049 } 2050 2051 2052 status_t 2053 reconnect_thread(void *data) 2054 { 2055 reconnect_info info; 2056 thread_id sender; 2057 int32 code; 2058 2059 receive_data(&sender, &info, sizeof(reconnect_info)); 2060 2061 // we try to receive data instead of snooze, so we can quit on destruction 2062 if (receive_data_with_timeout(&sender, &code, NULL, 0, info.delay) == B_OK) { 2063 *info.thread = -1; 2064 return B_OK; 2065 } 2066 2067 info.interface->Up(); 2068 *info.thread = -1; 2069 2070 return B_OK; 2071 } 2072