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