diff --git a/src/add-ons/kernel/network/ppp/shared/libkernelppp/Jamfile b/src/add-ons/kernel/network/ppp/shared/libkernelppp/Jamfile index d392d6f84b..fbae18afa3 100644 --- a/src/add-ons/kernel/network/ppp/shared/libkernelppp/Jamfile +++ b/src/add-ons/kernel/network/ppp/shared/libkernelppp/Jamfile @@ -1,18 +1,22 @@ SubDir OBOS_TOP src add-ons kernel network ppp shared libkernelppp ; -# for cpp.cpp and BLocker -SEARCH_SOURCE += [ FDirName $(OBOS_TOP) src add-ons kernel file_systems bfs ] ; +# for kernel_cpp.cpp/h and BLocker +SEARCH_SOURCE += [ FDirName $(OBOS_TOP) src kernel core util ] ; SEARCH_SOURCE += [ FDirName $(OBOS_TOP) src kernel core disk_device_manager ] ; -UseHeaders [ FDirName $(OBOS_TOP) src add-ons kernel file_systems bfs ] ; UsePrivateHeaders net ; +UsePrivateHeaders [ FDirName kernel ] ; +UsePrivateHeaders [ FDirName kernel util ] ; UseHeaders [ FDirName $(OBOS_TOP) src add-ons kernel network ppp shared libkernelppp headers ] ; + R5KernelStaticLibrary kernelppp : + kernel_cpp.cpp + KPPPConfigurePacket.cpp KPPPDevice.cpp - KPPPEncapsulator.cpp KPPPInterface.cpp + KPPPLayer.cpp KPPPLCP.cpp KPPPLCPExtension.cpp KPPPOptionHandler.cpp @@ -22,7 +26,6 @@ R5KernelStaticLibrary kernelppp : KPPPUtils.cpp Locker.cpp settings_tools.cpp - cpp.cpp # integrated modules _KPPPMRUHandler.cpp diff --git a/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPConfigurePacket.cpp b/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPConfigurePacket.cpp index 62475750f7..c82c472dd0 100644 --- a/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPConfigurePacket.cpp +++ b/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPConfigurePacket.cpp @@ -8,6 +8,8 @@ #include #include +#include + PPPConfigurePacket::PPPConfigurePacket(uint8 code) : fCode(code) diff --git a/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPDevice.cpp b/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPDevice.cpp index c2a0de388e..88be55cd00 100644 --- a/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPDevice.cpp +++ b/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPDevice.cpp @@ -8,42 +8,29 @@ #include #include -#include +#include #include PPPDevice::PPPDevice(const char *name, PPPInterface& interface, driver_parameter *settings) - : fMTU(1500), - fIsUp(false), + : PPPLayer(name, PPP_DEVICE_LEVEL), + fMTU(1500), fInterface(interface), - fSettings(settings) + fSettings(settings), + fIsUp(false) { - if(name) - fName = strdup(name); - else - fName = strdup("Unknown"); - - fInitStatus = interface.SetDevice(this) ? B_OK : B_ERROR; + fInitStatus = interface.SetDevice(this) && fInitStatus == B_OK ? B_OK : B_ERROR; } PPPDevice::~PPPDevice() { - free(fName); - Interface().SetDevice(NULL); } -status_t -PPPDevice::InitCheck() const -{ - return fInitStatus; -} - - status_t PPPDevice::Control(uint32 op, void *data, size_t length) { @@ -60,6 +47,7 @@ PPPDevice::Control(uint32 op, void *data, size_t length) info->inputTransferRate = InputTransferRate(); info->outputTransferRate = OutputTransferRate(); info->outputBytesCount = CountOutputBytes(); + info->isUp = IsUp(); } break; default: @@ -70,15 +58,22 @@ PPPDevice::Control(uint32 op, void *data, size_t length) } -status_t -PPPDevice::PassToInterface(struct mbuf *packet) +bool +PPPDevice::IsAllowedToSend() const { - if(!Interface().InQueue()) - return B_ERROR; - - IFQ_ENQUEUE(Interface().InQueue(), packet); - - return B_OK; + return true; + // our connection status will be reported in Send() +} + + +status_t +PPPDevice::Receive(struct mbuf *packet, uint16 protocolNumber) +{ + // let the interface handle the packet + if(protocolNumber == 0) + return Interface().ReceiveFromDevice(packet); + else + return Interface().Receive(packet, protocolNumber); } diff --git a/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPEncapsulator.cpp b/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPEncapsulator.cpp deleted file mode 100644 index 540129e9a9..0000000000 --- a/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPEncapsulator.cpp +++ /dev/null @@ -1,191 +0,0 @@ -//---------------------------------------------------------------------- -// This software is part of the OpenBeOS distribution and is covered -// by the OpenBeOS license. -// -// Copyright (c) 2003 Waldemar Kornewald, Waldemar.Kornewald@web.de -//--------------------------------------------------------------------- - -#include -#include -#include "settings_tools.h" - -#include - - -PPPEncapsulator::PPPEncapsulator(const char *name, ppp_phase phase, - ppp_encapsulation_level level, uint16 protocol, - int32 addressFamily, uint32 overhead, - PPPInterface& interface, driver_parameter *settings, - int32 flags = PPP_NO_FLAGS) - : fOverhead(overhead), - fPhase(phase), - fLevel(level), - fProtocol(protocol), - fAddressFamily(addressFamily), - fInterface(interface), - fSettings(settings), - fFlags(flags), - fEnabled(true), - fUpRequested(true), - fConnectionStatus(PPP_DOWN_PHASE) -{ - if(name) - fName = strdup(name); - else - fName = strdup("Unknown"); - - const char *sideString = get_parameter_value("side", settings); - if(sideString) - fSide = get_side_string_value(sideString, PPP_LOCAL_SIDE); - else { - if(interface.Mode() == PPP_CLIENT_MODE) - fSide = PPP_LOCAL_SIDE; - else - fSide = PPP_PEER_SIDE; - } - - fInitStatus = interface.AddEncapsulator(this) ? B_OK : B_ERROR; -} - - -PPPEncapsulator::~PPPEncapsulator() -{ - free(fName); - - Interface().RemoveEncapsulator(this); -} - - -status_t -PPPEncapsulator::InitCheck() const -{ - return fInitStatus; -} - - -void -PPPEncapsulator::SetEnabled(bool enabled = true) -{ - fEnabled = enabled; - - if(!enabled) { - if(IsUp() || IsGoingUp()) - Down(); - } else if(!IsUp() && !IsGoingUp() && IsUpRequested() && Interface().IsUp()) - Up(); -} - - -status_t -PPPEncapsulator::Control(uint32 op, void *data, size_t length) -{ - switch(op) { - case PPPC_GET_HANDLER_INFO: { - if(length < sizeof(ppp_handler_info_t) || !data) - return B_ERROR; - - ppp_handler_info *info = (ppp_handler_info*) data; - memset(info, 0, sizeof(ppp_handler_info_t)); - strncpy(info->name, Name(), PPP_HANDLER_NAME_LENGTH_LIMIT); - info->settings = Settings(); - info->phase = Phase(); - info->addressFamily = AddressFamily(); - info->flags = Flags(); - info->side = Side(); - info->protocol = Protocol(); - info->isEnabled = IsEnabled(); - info->isUpRequested = IsUpRequested(); - info->connectionStatus = fConnectionStatus; - info->level = Level(); - info->overhead = Overhead(); - } break; - - case PPPC_SET_ENABLED: - if(length < sizeof(uint32) || !data) - return B_ERROR; - - SetEnabled(*((uint32*)data)); - break; - - default: - return B_BAD_VALUE; - } - - return B_OK; -} - - -status_t -PPPEncapsulator::StackControl(uint32 op, void *data) -{ - switch(op) { - default: - return B_BAD_VALUE; - } - - return B_OK; -} - - -status_t -PPPEncapsulator::SendToNext(struct mbuf *packet, uint16 protocol) const -{ - // Find the next possible handler for this packet. - // This handler should be enabled, up, and allowed to send - if(Next()) { - if(Next()->IsEnabled() && Next()->IsUp() - && is_handler_allowed(*Next(), Interface().State(), Interface().Phase())) - return Next()->Send(packet, protocol); - else - return Next()->SendToNext(packet, protocol); - } else - return Interface().SendToDevice(packet, protocol); -} - - -void -PPPEncapsulator::Pulse() -{ - // do nothing by default -} - - -void -PPPEncapsulator::UpStarted() -{ - fConnectionStatus = PPP_ESTABLISHMENT_PHASE; -} - - -void -PPPEncapsulator::DownStarted() -{ - fConnectionStatus = PPP_TERMINATION_PHASE; -} - - -void -PPPEncapsulator::UpFailedEvent() -{ - fConnectionStatus = PPP_DOWN_PHASE; - - Interface().StateMachine().UpFailedEvent(this); -} - - -void -PPPEncapsulator::UpEvent() -{ - fConnectionStatus = PPP_ESTABLISHED_PHASE; - - Interface().StateMachine().UpEvent(this); -} - - -void -PPPEncapsulator::DownEvent() -{ - fConnectionStatus = PPP_DOWN_PHASE; - - Interface().StateMachine().DownEvent(this); -} diff --git a/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPInterface.cpp b/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPInterface.cpp index e6b212b5f3..2dd0919ae9 100644 --- a/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPInterface.cpp +++ b/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPInterface.cpp @@ -10,7 +10,7 @@ // void (KernelExport.h) and once with int (stdio.h). #include #include -#include +#include // now our headers... #include @@ -18,7 +18,6 @@ // our other classes #include #include -#include #include #include #include @@ -37,6 +36,11 @@ #include "_KPPPPFCHandler.h" +#ifdef _KERNEL_MODE +#define spawn_thread spawn_kernel_thread +#endif + + // TODO: // - implement timers with support for settings next time instead of receiving timer // events periodically @@ -52,13 +56,13 @@ typedef struct redial_info { status_t redial_thread(void *data); // other functions -status_t in_queue_thread(void *data); status_t interface_deleter_thread(void *data); PPPInterface::PPPInterface(uint32 ID, driver_settings *settings, PPPInterface *parent = NULL) - : fID(ID), + : PPPLayer("PPPInterface", PPP_INTERFACE_LEVEL), + fID(ID), fSettings(dup_driver_settings(settings)), fStateMachine(*this), fLCP(*this), @@ -78,7 +82,7 @@ PPPInterface::PPPInterface(uint32 ID, driver_settings *settings, fPeerPFCState(PPP_PFC_DISABLED), fPFCOptions(0), fDevice(NULL), - fFirstEncapsulator(NULL), + fFirstProtocol(NULL), fLock(StateMachine().Locker()), fDeleteCounter(0) { @@ -105,13 +109,7 @@ PPPInterface::PPPInterface(uint32 ID, driver_settings *settings, fRedialDelay = 1000; // 1s delay between lost connection and redial - // set up queue - fInQueue = start_ifq(); - fInQueueThread = spawn_thread(in_queue_thread, "PPPInterface: in_queue_thread", - B_NORMAL_PRIORITY, this); - resume_thread(fInQueueThread); - - if(get_module(PPP_MANAGER_MODULE_NAME, (module_info**) &fManager) != B_OK) + if(get_module(PPP_INTERFACE_MODULE_NAME, (module_info**) &fManager) != B_OK) fManager = NULL; // are we a multilink subinterface? @@ -166,7 +164,7 @@ PPPInterface::PPPInterface(uint32 ID, driver_settings *settings, // auto redial is disabled by default // load all protocols and the device - if(LoadModules(fSettings, 0, fSettings->parameter_count)) + if(LoadModules(fSettings, 0, fSettings->parameter_count) && fInitStatus == B_OK) fInitStatus = B_OK; else fInitStatus = B_ERROR; @@ -181,7 +179,7 @@ PPPInterface::~PPPInterface() UnregisterInterface(); if(fManager) - fManager->remove_interface(ID()); + fManager->RemoveInterface(ID()); // Call Down() until we get a lock on an interface that is down. // This lock is not released until we are actually deleted. @@ -197,9 +195,6 @@ PPPInterface::~PPPInterface() // tell all listeners that we are being destroyed int32 tmp; - stop_ifq(InQueue()); - wait_for_thread(fInQueueThread, &tmp); - send_data_with_timeout(fRedialThread, 0, NULL, 0, 200); // tell thread that we are being destroyed (200ms timeout) wait_for_thread(fRedialThread, &tmp); @@ -212,8 +207,8 @@ PPPInterface::~PPPInterface() while(CountProtocols()) delete ProtocolAt(0); - while(FirstEncapsulator()) - delete FirstEncapsulator(); + while(FirstProtocol()) + delete FirstProtocol(); for(int32 index = 0; index < fModules.CountItems(); index++) { put_module(fModules.ItemAt(index)); @@ -226,7 +221,7 @@ PPPInterface::~PPPInterface() Parent()->RemoveChild(this); if(fManager) - put_module(PPP_MANAGER_MODULE_NAME); + put_module(PPP_INTERFACE_MODULE_NAME); } @@ -238,7 +233,7 @@ PPPInterface::Delete() // only one thread should delete us! if(fManager) - fManager->delete_interface(ID()); + fManager->DeleteInterface(ID()); // This will mark us for deletion. // Any subsequent calls to delete_interface() will do nothing. else { @@ -254,7 +249,10 @@ PPPInterface::Delete() status_t PPPInterface::InitCheck() const { - if(!fSettings || !fManager || fInitStatus != B_OK) + if(fInitStatus != B_OK) + return fInitStatus; + + if(!fSettings || !fManager) return B_ERROR; // sub-interfaces should have a device @@ -306,7 +304,6 @@ PPPInterface::Control(uint32 op, void *data, size_t length) info->peerPFCState = PeerPFCState(); info->pfcOptions = PFCOptions(); info->protocolsCount = CountProtocols(); - info->encapsulatorsCount = CountEncapsulators(); info->optionHandlersCount = LCP().CountOptionHandlers(); info->LCPExtensionsCount = 0; info->childrenCount = CountChildren(); @@ -379,25 +376,11 @@ PPPInterface::Control(uint32 op, void *data, size_t length) return B_ERROR; ppp_control_info *control = (ppp_control_info*) data; - PPPProtocol *protocol_handler = ProtocolAt(control->index); - if(!protocol_handler) + PPPProtocol *protocol = ProtocolAt(control->index); + if(!protocol) return B_BAD_INDEX; - return protocol_handler->Control(control->op, control->data, - control->length); - } break; - - case PPPC_CONTROL_ENCAPSULATOR: { - if(length < sizeof(ppp_control_info) || !data) - return B_ERROR; - - ppp_control_info *control = (ppp_control_info*) data; - PPPEncapsulator *encapsulator_handler = EncapsulatorAt(control->index); - if(!encapsulator_handler) - return B_BAD_INDEX; - - return encapsulator_handler->Control(control->op, control->data, - control->length); + return protocol->Control(control->op, control->data, control->length); } break; case PPPC_CONTROL_OPTION_HANDLER: { @@ -405,11 +388,11 @@ PPPInterface::Control(uint32 op, void *data, size_t length) return B_ERROR; ppp_control_info *control = (ppp_control_info*) data; - PPPOptionHandler *option_handler = LCP().OptionHandlerAt(control->index); - if(!option_handler) + PPPOptionHandler *optionHandler = LCP().OptionHandlerAt(control->index); + if(!optionHandler) return B_BAD_INDEX; - return option_handler->Control(control->op, control->data, + return optionHandler->Control(control->op, control->data, control->length); } break; @@ -418,11 +401,11 @@ PPPInterface::Control(uint32 op, void *data, size_t length) return B_ERROR; ppp_control_info *control = (ppp_control_info*) data; - PPPLCPExtension *extension_handler = LCP().LCPExtensionAt(control->index); - if(!extension_handler) + PPPLCPExtension *lcpExtension = LCP().LCPExtensionAt(control->index); + if(!lcpExtension) return B_BAD_INDEX; - return extension_handler->Control(control->op, control->data, + return lcpExtension->Control(control->op, control->data, control->length); } break; @@ -466,6 +449,7 @@ PPPInterface::SetDevice(PPPDevice *device) Down(); fDevice = device; + SetNext(device); fMRU = fDevice->MTU() - 2; @@ -479,19 +463,52 @@ PPPInterface::SetDevice(PPPDevice *device) bool PPPInterface::AddProtocol(PPPProtocol *protocol) { - if(!protocol) + // Find instert position after the last protocol + // with the same level. + + if(!protocol || protocol->Level() == PPP_INTERFACE_LEVEL) return false; LockerHelper locker(fLock); if(Phase() != PPP_DOWN_PHASE) return false; - // a running connection may not change and there may only be - // one authenticator protocol for each protocol number + // a running connection may not change - fProtocols.AddItem(protocol); + PPPProtocol *current = fFirstProtocol, *previous = NULL; - if(IsUp() || Phase() >= protocol->Phase()) + while(current) { + if(current->Level() < protocol->Level()) + break; + + previous = current; + current = current->NextProtocol(); + } + + if(!current) { + if(!previous) + fFirstProtocol = protocol; + else + previous->SetNextProtocol(protocol); + + // set up the last protocol in the chain + protocol->SetNextProtocol(NULL); + // this also sets next to NULL + protocol->SetNext(this); + // we need to set us as the next layer + } else { + protocol->SetNextProtocol(current); + + if(!previous) + fFirstProtocol = protocol; + else + previous->SetNextProtocol(protocol); + } + + if(protocol->Level() < PPP_PROTOCOL_LEVEL) + CalculateInterfaceMTU(); + + if(IsUp() || Phase() >= protocol->ActivationPhase()) protocol->Up(); return true; @@ -507,128 +524,23 @@ PPPInterface::RemoveProtocol(PPPProtocol *protocol) return false; // a running connection may not change - if(!fProtocols.HasItem(protocol)) - return false; - - if(IsUp() || Phase() >= protocol->Phase()) - protocol->Down(); - - return fProtocols.RemoveItem(protocol); -} - - -PPPProtocol* -PPPInterface::ProtocolAt(int32 index) const -{ - PPPProtocol *protocol = fProtocols.ItemAt(index); - - if(protocol == fProtocols.GetDefaultItem()) - return NULL; - - return protocol; -} - - -PPPProtocol* -PPPInterface::ProtocolFor(uint16 protocol, int32 *start = NULL) const -{ - // The iteration style in this method is strange C/C++. - // Explanation: I use this style because it makes extending all XXXFor - // methods simpler as that they look very similar, now. - - int32 index = start ? *start : 0; - - if(index < 0) - return NULL; - - PPPProtocol *current = ProtocolAt(index); - - for(; current; current = ProtocolAt(++index)) { - if(current->Protocol() == protocol - || (current->Flags() & PPP_INCLUDES_NCP - && current->Protocol() & 0x7FFF == protocol & 0x7FFF)) { - if(start) - *start = index; - return current; - } - } - - return NULL; -} - - -bool -PPPInterface::AddEncapsulator(PPPEncapsulator *encapsulator) -{ - // Find instert position after the last encapsulator - // with the same level. - - if(!encapsulator) - return false; - - LockerHelper locker(fLock); - - if(Phase() != PPP_DOWN_PHASE) - return false; - // a running connection may not change - - PPPEncapsulator *current = fFirstEncapsulator, *previous = NULL; + PPPProtocol *current = fFirstProtocol, *previous = NULL; while(current) { - if(current->Level() < encapsulator->Level()) - break; - - previous = current; - current = current->Next(); - } - - if(!current) { - if(!previous) - fFirstEncapsulator = encapsulator; - else - previous->SetNext(encapsulator); - - encapsulator->SetNext(NULL); - } else { - encapsulator->SetNext(current); - - if(!previous) - fFirstEncapsulator = encapsulator; - else - previous->SetNext(encapsulator); - } - - CalculateInterfaceMTU(); - - if(IsUp()) - encapsulator->Up(); - - return true; -} - - -bool -PPPInterface::RemoveEncapsulator(PPPEncapsulator *encapsulator) -{ - LockerHelper locker(fLock); - - if(Phase() != PPP_DOWN_PHASE) - return false; - // a running connection may not change - - PPPEncapsulator *current = fFirstEncapsulator, *previous = NULL; - - while(current) { - if(current == encapsulator) { - if(IsUp()) - encapsulator->Down(); + if(current == protocol) { + if(!protocol->IsDown()) + protocol->Down(); - if(previous) - previous->SetNext(current->Next()); - else - fFirstEncapsulator = current->Next(); + if(previous) { + previous->SetNextProtocol(current->NextProtocol()); + + // set us as next layer if needed + if(!previous->Next()) + previous->SetNext(this); + } else + fFirstProtocol = current->NextProtocol(); - current->SetNext(NULL); + current->SetNextProtocol(NULL); CalculateInterfaceMTU(); @@ -636,7 +548,7 @@ PPPInterface::RemoveEncapsulator(PPPEncapsulator *encapsulator) } previous = current; - current = current->Next(); + current = current->NextProtocol(); } return false; @@ -644,39 +556,39 @@ PPPInterface::RemoveEncapsulator(PPPEncapsulator *encapsulator) int32 -PPPInterface::CountEncapsulators() const +PPPInterface::CountProtocols() const { - PPPEncapsulator *encapsulator = FirstEncapsulator(); + PPPProtocol *protocol = FirstProtocol(); int32 count = 0; - for(; encapsulator; encapsulator = encapsulator->Next()) + for(; protocol; protocol = protocol->NextProtocol()) ++count; return count; } -PPPEncapsulator* -PPPInterface::EncapsulatorAt(int32 index) const +PPPProtocol* +PPPInterface::ProtocolAt(int32 index) const { - PPPEncapsulator *encapsulator = FirstEncapsulator(); + PPPProtocol *protocol = FirstProtocol(); int32 currentIndex = 0; - for(; encapsulator; encapsulator = encapsulator->Next(), ++currentIndex) + for(; protocol; protocol = protocol->NextProtocol(), ++currentIndex) if(currentIndex == index) - return encapsulator; + return protocol; return NULL; } -PPPEncapsulator* -PPPInterface::EncapsulatorFor(uint16 protocol, PPPEncapsulator *start = NULL) const +PPPProtocol* +PPPInterface::ProtocolFor(uint16 protocolNumber, PPPProtocol *start = NULL) const { - PPPEncapsulator *current = start ? start : fFirstEncapsulator; + PPPProtocol *current = start ? start : FirstProtocol(); - for(; current; current = current->Next()) { - if(current->Protocol() == protocol + for(; current; current = current->NextProtocol()) { + if(current->ProtocolNumber() == protocolNumber || (current->Flags() & PPP_INCLUDES_NCP - && current->Protocol() & 0x7FFF == protocol & 0x7FFF)) + && current->ProtocolNumber() & 0x7FFF == protocolNumber & 0x7FFF)) return current; } @@ -1065,7 +977,7 @@ PPPInterface::LoadModules(driver_settings *settings, int32 start, int32 count) if(IsMultilink() && !Parent()) { // main interfaces only load the multilink module // and create a child using their settings - fManager->create_interface(settings, ID()); + fManager->CreateInterface(settings, ID()); return true; } @@ -1123,150 +1035,15 @@ PPPInterface::LoadModule(const char *name, driver_parameter *parameter, } -status_t -PPPInterface::Send(struct mbuf *packet, uint16 protocol) +bool +PPPInterface::IsAllowedToSend() const { - if(!packet) - return B_ERROR; - - // we must pass the basic tests! - if(InitCheck() != B_OK) { - m_freem(packet); - return B_ERROR; - } - - // test whether are going down - if(Phase() == PPP_TERMINATION_PHASE) { - m_freem(packet); - return B_ERROR; - } - - // go up if DialOnDemand enabled and we are down - if(DoesDialOnDemand() && Phase() == PPP_DOWN_PHASE) - Up(); - - // find the protocol handler for the current protocol number - int32 index = 0; - PPPProtocol *sending_protocol = ProtocolFor(protocol, &index); - while(sending_protocol && !sending_protocol->IsEnabled()) - sending_protocol = ProtocolFor(protocol, &(++index)); - - // Check if we must encapsulate the packet. - // We do not necessarily need a handler for 'protocol'. - // In such a case we still encapsulate the packet. - // Protocols which have the PPP_ALWAYS_ALLOWED flag set are never - // encapsulated. - if(sending_protocol && sending_protocol->Flags() & PPP_ALWAYS_ALLOWED - && is_handler_allowed(*sending_protocol, State(), Phase())) { - fIdleSince = real_time_clock(); - return SendToDevice(packet, protocol); - } - - // try the same for the encapsulator handler - PPPEncapsulator *sending_encapsulator = EncapsulatorFor(protocol); - while(sending_encapsulator && sending_encapsulator->Next() - && !sending_encapsulator->IsEnabled()) - sending_encapsulator = sending_encapsulator->Next() ? - EncapsulatorFor(protocol, sending_encapsulator->Next()) : NULL; - - if(sending_encapsulator && sending_encapsulator->Flags() & PPP_ALWAYS_ALLOWED - && is_handler_allowed(*sending_encapsulator, State(), Phase())) { - fIdleSince = real_time_clock(); - return SendToDevice(packet, protocol); - } - - // never send normal protocols when we are not up - if(!IsUp()) { - m_freem(packet); - return B_ERROR; - } - - fIdleSince = real_time_clock(); - - // send to next up encapsulator - if(!fFirstEncapsulator) - return SendToDevice(packet, protocol); - - if(!fFirstEncapsulator->IsEnabled()) - return fFirstEncapsulator->SendToNext(packet, protocol); - - if(is_handler_allowed(*fFirstEncapsulator, State(), Phase())) - return fFirstEncapsulator->Send(packet, protocol); - - m_freem(packet); - return B_ERROR; + return true; } status_t -PPPInterface::Receive(struct mbuf *packet, uint16 protocol) -{ - if(!packet) - return B_ERROR; - - int32 result = PPP_REJECTED; - // assume we have no handler - - // Set our interface as the receiver. - // The real netstack protocols (IP, IPX, etc.) might get confused if our - // interface is a main interface and at the same time is not registered - // because then there is no receiver interface. - // PPP NCPs should be aware of that! - if(packet->m_flags & M_PKTHDR && Ifnet() != NULL) - packet->m_pkthdr.rcvif = Ifnet(); - - // Find handler and let it parse the packet. - // The handler does need not be up because if we are a server - // the handler might be upped by this packet. - PPPEncapsulator *encapsulator_handler = EncapsulatorFor(protocol); - for(; encapsulator_handler; - encapsulator_handler = - encapsulator_handler->Next() ? - EncapsulatorFor(protocol, encapsulator_handler->Next()) : NULL) { - if(!encapsulator_handler->IsEnabled() - || !is_handler_allowed(*encapsulator_handler, State(), Phase())) - continue; - // skip handler if disabled or not allowed - - result = encapsulator_handler->Receive(packet, protocol); - if(result == PPP_UNHANDLED) - continue; - - return result; - } - - // no encapsulator handler could be found; try a protocol handler - int32 index = 0; - PPPProtocol *protocol_handler = ProtocolFor(protocol, &index); - for(; protocol_handler; protocol_handler = ProtocolFor(protocol, &(++index))) { - if(!protocol_handler->IsEnabled() - || !is_handler_allowed(*protocol_handler, State(), Phase())) - continue; - // skip handler if disabled or not allowed - - result = protocol_handler->Receive(packet, protocol); - if(result == PPP_UNHANDLED) - continue; - - return result; - } - - // maybe the parent interface can handle the packet - if(Parent()) - return Parent()->Receive(packet, protocol); - - if(result == PPP_UNHANDLED) { - m_freem(packet); - return PPP_DISCARDED; - } else { - StateMachine().RUCEvent(packet, protocol); - return PPP_REJECTED; - } -} - - -status_t -PPPInterface::SendToDevice(struct mbuf *packet, uint16 protocol) +PPPInterface::Send(struct mbuf *packet, uint16 protocolNumber) { if(!packet) return B_ERROR; @@ -1295,27 +1072,27 @@ PPPInterface::SendToDevice(struct mbuf *packet, uint16 protocol) } // find the protocol handler for the current protocol number - int32 index = 0; - PPPProtocol *sending_protocol = ProtocolFor(protocol, &index); - while(sending_protocol && !sending_protocol->IsEnabled()) - sending_protocol = ProtocolFor(protocol, &(++index)); + PPPProtocol *protocol = ProtocolFor(protocolNumber); + while(protocol && !protocol->IsEnabled()) + protocol = protocol->NextProtocol() ? + ProtocolFor(protocolNumber, protocol->NextProtocol()) : NULL; // make sure that protocol is allowed to send and everything is up - if(!Device()->IsUp() || !sending_protocol || !sending_protocol->IsEnabled() - || !is_handler_allowed(*sending_protocol, State(), Phase())){ + if(!Device()->IsUp() || !protocol || !protocol->IsEnabled() + || !IsProtocolAllowed(*protocol)){ m_freem(packet); return B_ERROR; } // encode in ppp frame and consider using PFC - if(UseLocalPFC() && protocol & 0xFF00 == 0) { + if(UseLocalPFC() && protocolNumber & 0xFF00 == 0) { M_PREPEND(packet, 1); if(packet == NULL) return B_ERROR; uint8 *header = mtod(packet, uint8*); - *header = protocol & 0xFF; + *header = protocolNumber & 0xFF; } else { M_PREPEND(packet, 2); @@ -1323,9 +1100,9 @@ PPPInterface::SendToDevice(struct mbuf *packet, uint16 protocol) return B_ERROR; // set protocol (the only header field) - protocol = htons(protocol); + protocolNumber = htons(protocolNumber); uint16 *header = mtod(packet, uint16*); - *header = protocol; + *header = protocolNumber; } fIdleSince = real_time_clock(); @@ -1339,15 +1116,65 @@ PPPInterface::SendToDevice(struct mbuf *packet, uint16 protocol) return B_ERROR; } - return Device()->Send(packet); + return SendToNext(packet, 0); + // this is normally the device, but there can be something inbetween } else { - // the multilink encapsulator should have sent it to some child interface + // the multilink protocol should have sent it to some child interface m_freem(packet); return B_ERROR; } } +status_t +PPPInterface::Receive(struct mbuf *packet, uint16 protocolNumber) +{ + if(!packet) + return B_ERROR; + + int32 result = PPP_REJECTED; + // assume we have no handler + + // Set our interface as the receiver. + // The real netstack protocols (IP, IPX, etc.) might get confused if our + // interface is a main interface and at the same time is not registered + // because then there is no receiver interface. + // PPP NCPs should be aware of that! + if(packet->m_flags & M_PKTHDR && Ifnet() != NULL) + packet->m_pkthdr.rcvif = Ifnet(); + + // Find handler and let it parse the packet. + // The handler does need not be up because if we are a server + // the handler might be upped by this packet. + PPPProtocol *protocol = ProtocolFor(protocolNumber); + for(; protocol; + protocol = protocol->NextProtocol() ? + ProtocolFor(protocolNumber, protocol->NextProtocol()) : NULL) { + if(!protocol->IsEnabled() || !IsProtocolAllowed(*protocol)) + continue; + // skip handler if disabled or not allowed + + result = protocol->Receive(packet, protocolNumber); + if(result == PPP_UNHANDLED) + continue; + + return result; + } + + // maybe the parent interface can handle the packet + if(Parent()) + return Parent()->Receive(packet, protocolNumber); + + if(result == PPP_UNHANDLED) { + m_freem(packet); + return PPP_DISCARDED; + } else { + StateMachine().RUCEvent(packet, protocolNumber); + return PPP_REJECTED; + } +} + + status_t PPPInterface::ReceiveFromDevice(struct mbuf *packet) { @@ -1360,15 +1187,15 @@ PPPInterface::ReceiveFromDevice(struct mbuf *packet) } // decode ppp frame and recognize PFC - uint16 protocol = *mtod(packet, uint8*); - if(protocol == 0) + uint16 protocolNumber = *mtod(packet, uint8*); + if(protocolNumber == 0) m_adj(packet, 1); else { - protocol = ntohs(*mtod(packet, uint16*)); + protocolNumber = ntohs(*mtod(packet, uint16*)); m_adj(packet, 2); } - return Receive(packet, protocol); + return Receive(packet, protocolNumber); } @@ -1389,12 +1216,9 @@ PPPInterface::Pulse() if(Device()) Device()->Pulse(); - for(int32 index = 0; index < CountProtocols(); index++) - ProtocolAt(index)->Pulse(); - - PPPEncapsulator *encapsulator = fFirstEncapsulator; - for(; encapsulator; encapsulator = encapsulator->Next()) - encapsulator->Pulse(); + PPPProtocol *protocol = FirstProtocol(); + for(; protocol; protocol = protocol->NextProtocol()) + protocol->Pulse(); } @@ -1418,7 +1242,7 @@ PPPInterface::RegisterInterface() if(!fManager) return false; - fIfnet = fManager->register_interface(ID()); + fIfnet = fManager->RegisterInterface(ID()); if(!fIfnet) return false; @@ -1445,7 +1269,7 @@ PPPInterface::UnregisterInterface() if(!fManager) return false; - fManager->unregister_interface(ID()); + fManager->UnregisterInterface(ID()); fIfnet = NULL; return true; @@ -1457,7 +1281,7 @@ status_t PPPInterface::StackControl(uint32 op, void *data) { // TODO: - // implement when writing ppp_manager module + // implement when writing ppp interface module switch(op) { default: @@ -1500,16 +1324,15 @@ PPPInterface::StackControlEachHandler(uint32 op, void *data) { status_t result = B_BAD_VALUE, tmp; - PPPEncapsulator *encapsulator = FirstEncapsulator(); - for(; encapsulator; encapsulator = encapsulator->Next()) { - tmp = encapsulator->StackControl(op, data); + PPPProtocol *protocol = FirstProtocol(); + for(; protocol; protocol = protocol->NextProtocol()) { + tmp = protocol->StackControl(op, data); if(tmp == B_OK && result == B_BAD_VALUE) result = B_OK; else if(tmp != B_BAD_VALUE) result = tmp; } - ForEachItem(fProtocols, CallStackControl(op, data, result)); ForEachItem(LCP().fLCPExtensions, CallStackControl(op, data, result)); ForEachItem(LCP().fOptionHandlers, @@ -1525,9 +1348,11 @@ PPPInterface::CalculateInterfaceMTU() fInterfaceMTU = fMRU; // sum all headers (the protocol field is not counted) - PPPEncapsulator *encapsulator = fFirstEncapsulator; - for(; encapsulator; encapsulator = encapsulator->Next()) - fHeaderLength += encapsulator->Overhead(); + PPPProtocol *protocol = FirstProtocol(); + for(; protocol; protocol = protocol->NextProtocol()) { + if(protocol->Level() < PPP_PROTOCOL_LEVEL) + fHeaderLength += protocol->Overhead(); + } fInterfaceMTU -= fHeaderLength; @@ -1603,38 +1428,12 @@ redial_thread(void *data) } -status_t -in_queue_thread(void *data) -{ - PPPInterface *interface = (PPPInterface*) data; - struct ifq *queue = interface->InQueue(); - struct mbuf *packet; - status_t error; - - while(true) { - error = acquire_sem_etc(queue->pop, 1, B_CAN_INTERRUPT | B_DO_NOT_RESCHEDULE, 0); - - if(error == B_INTERRUPTED) - continue; - else if(error != B_NO_ERROR) - break; - - IFQ_DEQUEUE(queue, packet); - - if(packet) - interface->ReceiveFromDevice(packet); - } - - return B_ERROR; -} - - // ---------------------------------- // Function: interface_deleter_thread // ---------------------------------- // The destructor is private, so this thread function cannot delete our interface. // To solve this problem we create a 'fake' class PPPManager (friend of PPPInterface) -// which is only defined here (the real class is defined in the ppp_manager module). +// which is only defined here (the real class is defined in the ppp interface module). class PPPManager { public: PPPManager(PPPInterface *interface) diff --git a/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPLCP.cpp b/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPLCP.cpp index ae76c7a9d7..4accdc33fc 100644 --- a/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPLCP.cpp +++ b/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPLCP.cpp @@ -7,20 +7,19 @@ #include #include -#include #include #include #include #include -#include +#include #include PPPLCP::PPPLCP(PPPInterface& interface) - : PPPProtocol("LCP", PPP_ESTABLISHMENT_PHASE, PPP_LCP_PROTOCOL, - AF_UNSPEC, interface, NULL, PPP_ALWAYS_ALLOWED), + : PPPProtocol("LCP", PPP_ESTABLISHMENT_PHASE, PPP_LCP_PROTOCOL, PPP_PROTOCOL_LEVEL, + AF_UNSPEC, 0, interface, NULL, PPP_ALWAYS_ALLOWED), fStateMachine(interface.StateMachine()), fTarget(NULL) { @@ -37,44 +36,44 @@ PPPLCP::~PPPLCP() bool -PPPLCP::AddOptionHandler(PPPOptionHandler *handler) +PPPLCP::AddOptionHandler(PPPOptionHandler *optionHandler) { - if(!handler) + if(!optionHandler) return false; LockerHelper locker(StateMachine().Locker()); - if(Phase() != PPP_DOWN_PHASE || OptionHandlerFor(handler->Type())) + if(Interface().Phase() != PPP_DOWN_PHASE || OptionHandlerFor(optionHandler->Type())) return false; // a running connection may not change and there may only be // one handler per option type - return fOptionHandlers.AddItem(handler); + return fOptionHandlers.AddItem(optionHandler); } bool -PPPLCP::RemoveOptionHandler(PPPOptionHandler *handler) +PPPLCP::RemoveOptionHandler(PPPOptionHandler *optionHandler) { LockerHelper locker(StateMachine().Locker()); - if(Phase() != PPP_DOWN_PHASE) + if(Interface().Phase() != PPP_DOWN_PHASE) return false; // a running connection may not change - return fOptionHandlers.RemoveItem(handler); + return fOptionHandlers.RemoveItem(optionHandler); } PPPOptionHandler* PPPLCP::OptionHandlerAt(int32 index) const { - PPPOptionHandler *handler = fOptionHandlers.ItemAt(index); + PPPOptionHandler *optionHandler = fOptionHandlers.ItemAt(index); - if(handler == fOptionHandlers.GetDefaultItem()) + if(optionHandler == fOptionHandlers.GetDefaultItem()) return NULL; - return handler; + return optionHandler; } @@ -105,43 +104,43 @@ PPPLCP::OptionHandlerFor(uint8 type, int32 *start = NULL) const bool -PPPLCP::AddLCPExtension(PPPLCPExtension *extension) +PPPLCP::AddLCPExtension(PPPLCPExtension *lcpExtension) { - if(!extension) + if(!lcpExtension) return false; LockerHelper locker(StateMachine().Locker()); - if(Phase() != PPP_DOWN_PHASE) + if(Interface().Phase() != PPP_DOWN_PHASE) return false; // a running connection may not change - return fLCPExtensions.AddItem(extension); + return fLCPExtensions.AddItem(lcpExtension); } bool -PPPLCP::RemoveLCPExtension(PPPLCPExtension *extension) +PPPLCP::RemoveLCPExtension(PPPLCPExtension *lcpExtension) { LockerHelper locker(StateMachine().Locker()); - if(Phase() != PPP_DOWN_PHASE) + if(Interface().Phase() != PPP_DOWN_PHASE) return false; // a running connection may not change - return fLCPExtensions.RemoveItem(extension); + return fLCPExtensions.RemoveItem(lcpExtension); } PPPLCPExtension* PPPLCP::LCPExtensionAt(int32 index) const { - PPPLCPExtension *extension = fLCPExtensions.ItemAt(index); + PPPLCPExtension *lcpExtension = fLCPExtensions.ItemAt(index); - if(extension == fLCPExtensions.GetDefaultItem()) + if(lcpExtension == fLCPExtensions.GetDefaultItem()) return NULL; - return extension; + return lcpExtension; } @@ -198,7 +197,7 @@ PPPLCP::Down() status_t -PPPLCP::Send(struct mbuf *packet) +PPPLCP::Send(struct mbuf *packet, uint16 protocolNumber) { if(Target()) return Target()->Send(packet, PPP_LCP_PROTOCOL); @@ -208,12 +207,12 @@ PPPLCP::Send(struct mbuf *packet) status_t -PPPLCP::Receive(struct mbuf *packet, uint16 protocol) +PPPLCP::Receive(struct mbuf *packet, uint16 protocolNumber) { if(!packet) return B_ERROR; - if(protocol != PPP_LCP_PROTOCOL) + if(protocolNumber != PPP_LCP_PROTOCOL) return PPP_UNHANDLED; ppp_lcp_packet *data = mtod(packet, ppp_lcp_packet*); @@ -288,12 +287,12 @@ PPPLCP::Receive(struct mbuf *packet, uint16 protocol) // Try to find LCP extensions that can handle this code. // We must duplicate the packet in order to ask all handlers. int32 index = 0; - PPPLCPExtension *extension = LCPExtensionFor(data->code, &index); - for(; extension; extension = LCPExtensionFor(data->code, &(++index))) { - if(!extension->IsEnabled()) + PPPLCPExtension *lcpExtension = LCPExtensionFor(data->code, &index); + for(; lcpExtension; lcpExtension = LCPExtensionFor(data->code, &(++index))) { + if(!lcpExtension->IsEnabled()) continue; - result = extension->Receive(packet, data->code); + result = lcpExtension->Receive(packet, data->code); // check return value and return it on error if(result == B_OK) diff --git a/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPLCPExtension.cpp b/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPLCPExtension.cpp index 65ba15d444..26d1c3d01d 100644 --- a/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPLCPExtension.cpp +++ b/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPLCPExtension.cpp @@ -56,7 +56,7 @@ PPPLCPExtension::Control(uint32 op, void *data, size_t length) info->isEnabled = IsEnabled(); } break; - case PPPC_SET_ENABLED: + case PPPC_ENABLE: if(length < sizeof(uint32) || !data) return B_ERROR; diff --git a/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPLayer.cpp b/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPLayer.cpp new file mode 100644 index 0000000000..49355a342d --- /dev/null +++ b/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPLayer.cpp @@ -0,0 +1,62 @@ +//---------------------------------------------------------------------- +// This software is part of the OpenBeOS distribution and is covered +// by the OpenBeOS license. +// +// Copyright (c) 2003 Waldemar Kornewald, Waldemar.Kornewald@web.de +//--------------------------------------------------------------------- + +#include + +#include +#include +#include + +#include + + +PPPLayer::PPPLayer(const char *name, ppp_level level) + : fInitStatus(B_OK), + fNext(NULL) +{ + if(name) + fName = strdup(name); + else + fName = strdup("Unknown"); +} + + +PPPLayer::~PPPLayer() +{ + free(fName); +} + + +status_t +PPPLayer::InitCheck() const +{ + return fInitStatus; +} + + +status_t +PPPLayer::SendToNext(struct mbuf *packet, uint16 protocolNumber) const +{ + // Find the next possible handler for this packet. + // Normal protocols (Level() >= PPP_PROTOCOL_LEVEL) do not encapsulate anything. + if(Next()) { + if(Next()->IsAllowedToSend() && Next()->Level() < PPP_PROTOCOL_LEVEL) + return Next()->Send(packet, protocolNumber); + else + return Next()->SendToNext(packet, protocolNumber); + } else { + m_freem(packet); + return B_ERROR; + } +} + + +void +PPPLayer::Pulse() +{ + // do nothing by default +} diff --git a/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPOptionHandler.cpp b/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPOptionHandler.cpp index f1f0d7cbb6..265278fb5f 100644 --- a/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPOptionHandler.cpp +++ b/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPOptionHandler.cpp @@ -56,7 +56,7 @@ PPPOptionHandler::Control(uint32 op, void *data, size_t length) info->isEnabled = IsEnabled(); } break; - case PPPC_SET_ENABLED: + case PPPC_ENABLE: if(length < sizeof(uint32) || !data) return B_ERROR; diff --git a/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPProtocol.cpp b/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPProtocol.cpp index 37b4020d45..af072a972c 100644 --- a/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPProtocol.cpp +++ b/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPProtocol.cpp @@ -6,34 +6,31 @@ //--------------------------------------------------------------------- #include -#include - +#include #include #include "settings_tools.h" #include -PPPProtocol::PPPProtocol(const char *name, ppp_phase phase, uint16 protocol, - int32 addressFamily, PPPInterface& interface, +PPPProtocol::PPPProtocol(const char *name, ppp_phase activationPhase, + uint16 protocolNumber, ppp_level level, int32 addressFamily, + uint32 overhead, PPPInterface& interface, driver_parameter *settings, int32 flags = PPP_NO_FLAGS, const char *type = NULL, PPPOptionHandler *optionHandler = NULL) - : fPhase(phase), - fProtocol(protocol), + : PPPLayer(name, level), + fActivationPhase(activationPhase), + fProtocolNumber(protocolNumber), fAddressFamily(addressFamily), fInterface(interface), fSettings(settings), fFlags(flags), fOptionHandler(optionHandler), + fNextProtocol(NULL), fEnabled(true), fUpRequested(true), - fConnectionStatus(PPP_DOWN_PHASE) + fConnectionPhase(PPP_DOWN_PHASE) { - if(name) - fName = strdup(name); - else - fName = strdup("Unknown"); - if(type) fType = strdup(type); else @@ -49,36 +46,15 @@ PPPProtocol::PPPProtocol(const char *name, ppp_phase phase, uint16 protocol, fSide = PPP_PEER_SIDE; } - fInitStatus = interface.AddProtocol(this) ? B_OK : B_ERROR; + fInitStatus = interface.AddProtocol(this) && fInitStatus == B_OK ? B_OK : B_ERROR; } PPPProtocol::~PPPProtocol() { - free(fName); - free(fType); - Interface().RemoveProtocol(this); -} - - -status_t -PPPProtocol::InitCheck() const -{ - return fInitStatus; -} - - -void -PPPProtocol::SetEnabled(bool enabled = true) -{ - fEnabled = enabled; - if(!enabled) { - if(IsUp() || IsGoingUp()) - Down(); - } else if(!IsUp() && !IsGoingUp() && IsUpRequested() && Interface().IsUp()) - Up(); + free(fType); } @@ -86,26 +62,28 @@ status_t PPPProtocol::Control(uint32 op, void *data, size_t length) { switch(op) { - case PPPC_GET_HANDLER_INFO: { - if(length < sizeof(ppp_handler_info_t) || !data) + case PPPC_GET_PROTOCOL_INFO: { + if(length < sizeof(ppp_protocol_info_t) || !data) return B_ERROR; - ppp_handler_info *info = (ppp_handler_info*) data; - memset(info, 0, sizeof(ppp_handler_info_t)); + ppp_protocol_info *info = (ppp_protocol_info*) data; + memset(info, 0, sizeof(ppp_protocol_info_t)); strncpy(info->name, Name(), PPP_HANDLER_NAME_LENGTH_LIMIT); + strncpy(info->type, Type(), PPP_HANDLER_NAME_LENGTH_LIMIT); info->settings = Settings(); - info->phase = Phase(); + info->activationPhase = ActivationPhase(); info->addressFamily = AddressFamily(); info->flags = Flags(); info->side = Side(); - info->protocol = Protocol(); + info->level = Level(); + info->overhead = Overhead(); + info->connectionPhase = fConnectionPhase; + info->protocolNumber = ProtocolNumber(); info->isEnabled = IsEnabled(); info->isUpRequested = IsUpRequested(); - info->connectionStatus = fConnectionStatus; - strncpy(info->type, Type(), PPP_HANDLER_NAME_LENGTH_LIMIT); } break; - case PPPC_SET_ENABLED: + case PPPC_ENABLE: if(length < sizeof(uint32) || !data) return B_ERROR; @@ -133,30 +111,43 @@ PPPProtocol::StackControl(uint32 op, void *data) void -PPPProtocol::Pulse() +PPPProtocol::SetEnabled(bool enabled = true) { - // do nothing by default + fEnabled = enabled; + + if(!enabled) { + if(IsUp() || IsGoingUp()) + Down(); + } else if(!IsUp() && !IsGoingUp() && IsUpRequested() && Interface().IsUp()) + Up(); +} + + +bool +PPPProtocol::IsAllowedToSend() const +{ + return IsEnabled() && IsUp() && IsProtocolAllowed(*this); } void PPPProtocol::UpStarted() { - fConnectionStatus = PPP_ESTABLISHMENT_PHASE; + fConnectionPhase = PPP_ESTABLISHMENT_PHASE; } void PPPProtocol::DownStarted() { - fConnectionStatus = PPP_TERMINATION_PHASE; + fConnectionPhase = PPP_TERMINATION_PHASE; } void PPPProtocol::UpFailedEvent() { - fConnectionStatus = PPP_DOWN_PHASE; + fConnectionPhase = PPP_DOWN_PHASE; Interface().StateMachine().UpFailedEvent(this); } @@ -165,7 +156,7 @@ PPPProtocol::UpFailedEvent() void PPPProtocol::UpEvent() { - fConnectionStatus = PPP_ESTABLISHED_PHASE; + fConnectionPhase = PPP_ESTABLISHED_PHASE; Interface().StateMachine().UpEvent(this); } @@ -174,7 +165,7 @@ PPPProtocol::UpEvent() void PPPProtocol::DownEvent() { - fConnectionStatus = PPP_DOWN_PHASE; + fConnectionPhase = PPP_DOWN_PHASE; Interface().StateMachine().DownEvent(this); } diff --git a/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPReportManager.cpp b/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPReportManager.cpp index 2a03c69dfb..b714c24afc 100644 --- a/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPReportManager.cpp +++ b/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPReportManager.cpp @@ -10,8 +10,6 @@ #include -#include - PPPReportManager::PPPReportManager(BLocker& lock) : fLock(lock) diff --git a/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPStateMachine.cpp b/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPStateMachine.cpp index 937eda7fce..23c29c065c 100644 --- a/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPStateMachine.cpp +++ b/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPStateMachine.cpp @@ -10,12 +10,11 @@ #include #include #include -#include #include #include #include -#include +#include #define PPP_STATE_MACHINE_TIMEOUT 3000000 @@ -119,7 +118,6 @@ PPPStateMachine::Reconfigure() NewPhase(PPP_ESTABLISHMENT_PHASE); DownProtocols(); - DownEncapsulators(); ResetLCPHandlers(); locker.UnlockNow(); @@ -331,7 +329,7 @@ PPPStateMachine::UpFailedEvent(PPPProtocol *protocol) { if((protocol->Flags() & PPP_NOT_IMPORTANT) == 0) { if(Interface().Mode() == PPP_CLIENT_MODE) { - // pretend we lost connection: + // pretend we lost connection if(Interface().IsMultilink() && !Interface().Parent()) for(int32 index = 0; index < Interface().CountChildren(); index++) Interface().ChildAt(index)->StateMachine().CloseEvent(); @@ -352,7 +350,7 @@ PPPStateMachine::UpEvent(PPPProtocol *protocol) LockerHelper locker(fLock); if(Phase() >= PPP_ESTABLISHMENT_PHASE) - BringHandlersUp(); + BringProtocolsUp(); } @@ -362,42 +360,6 @@ PPPStateMachine::DownEvent(PPPProtocol *protocol) } -void -PPPStateMachine::UpFailedEvent(PPPEncapsulator *encapsulator) -{ - if((encapsulator->Flags() & PPP_NOT_IMPORTANT) == 0) { - if(Interface().Mode() == PPP_CLIENT_MODE) { - // pretend we lost connection: - if(Interface().IsMultilink() && !Interface().Parent()) - for(int32 index = 0; index < Interface().CountChildren(); index++) - Interface().ChildAt(index)->StateMachine().CloseEvent(); - else if(Interface().Device()) - Interface().Device()->Down(); - else - CloseEvent(); - // just to be on the secure side ;) - } else - CloseEvent(); - } -} - - -void -PPPStateMachine::UpEvent(PPPEncapsulator *encapsulator) -{ - LockerHelper locker(fLock); - - if(Phase() >= PPP_ESTABLISHMENT_PHASE) - BringHandlersUp(); -} - - -void -PPPStateMachine::DownEvent(PPPEncapsulator *encapsulator) -{ -} - - // This is called by the device to tell us that it entered establishment // phase. We can use Device::Down() to abort establishment until UpEvent() // is called. @@ -566,7 +528,6 @@ PPPStateMachine::DownEvent() NewPhase(PPP_DOWN_PHASE); DownProtocols(); - DownEncapsulators(); fLocalAuthenticationStatus = PPP_NOT_AUTHENTICATED; fPeerAuthenticationStatus = PPP_NOT_AUTHENTICATED; @@ -916,10 +877,10 @@ PPPStateMachine::RCAEvent(struct mbuf *packet) // let the option handlers parse this ack PPPConfigurePacket ack(packet); - PPPOptionHandler *handler; + PPPOptionHandler *optionHandler; for(int32 index = 0; index < LCP().CountOptionHandlers(); index++) { - handler = LCP().OptionHandlerAt(index); - if(handler->ParseAck(ack) != B_OK) { + optionHandler = LCP().OptionHandlerAt(index); + if(optionHandler->ParseAck(ack) != B_OK) { m_freem(packet); locker.UnlockNow(); CloseEvent(); @@ -991,19 +952,19 @@ PPPStateMachine::RCNEvent(struct mbuf *packet) // let the option handlers parse this nak/reject PPPConfigurePacket nak_reject(packet); - PPPOptionHandler *handler; + PPPOptionHandler *optionHandler; for(int32 index = 0; index < LCP().CountOptionHandlers(); index++) { - handler = LCP().OptionHandlerAt(index); + optionHandler = LCP().OptionHandlerAt(index); if(nak_reject.Code() == PPP_CONFIGURE_NAK) { - if(handler->ParseNak(nak_reject) != B_OK) { + if(optionHandler->ParseNak(nak_reject) != B_OK) { m_freem(packet); locker.UnlockNow(); CloseEvent(); return; } } else if(nak_reject.Code() == PPP_CONFIGURE_REJECT) { - if(handler->ParseReject(nak_reject) != B_OK) { + if(optionHandler->ParseReject(nak_reject) != B_OK) { m_freem(packet); locker.UnlockNow(); CloseEvent(); @@ -1156,7 +1117,7 @@ PPPStateMachine::RTAEvent(struct mbuf *packet) // receive unknown code void -PPPStateMachine::RUCEvent(struct mbuf *packet, uint16 protocol, +PPPStateMachine::RUCEvent(struct mbuf *packet, uint16 protocolNumber, uint8 code = PPP_PROTOCOL_REJECT) { LockerHelper locker(fLock); @@ -1170,7 +1131,7 @@ PPPStateMachine::RUCEvent(struct mbuf *packet, uint16 protocol, default: locker.UnlockNow(); - SendCodeReject(packet, protocol, code); + SendCodeReject(packet, protocolNumber, code); } } @@ -1332,17 +1293,17 @@ PPPStateMachine::RCREvent(struct mbuf *packet) // each handler should add unacceptable values for each item status_t result; // the return value of ParseRequest() - PPPOptionHandler *handler; + PPPOptionHandler *optionHandler; for(int32 index = 0; index < request.CountItems(); index++) { - handler = LCP().OptionHandlerFor(request.ItemAt(index)->type); + optionHandler = LCP().OptionHandlerFor(request.ItemAt(index)->type); - if(!handler || !handler->IsEnabled()) { + if(!optionHandler || !optionHandler->IsEnabled()) { // unhandled items should be added to the reject reject.AddItem(request.ItemAt(index)); continue; } - result = handler->ParseRequest(request, index, nak, reject); + result = optionHandler->ParseRequest(request, index, nak, reject); if(result == PPP_UNHANDLED) { // unhandled items should be added to the reject @@ -1361,9 +1322,9 @@ PPPStateMachine::RCREvent(struct mbuf *packet) // If we sent too many naks we should not append additional values. if(fNakCounter > 0) { for(int32 index = 0; index < LCP().CountOptionHandlers(); index++) { - handler = LCP().OptionHandlerAt(index); - if(handler && handler->IsEnabled()) { - result = handler->ParseRequest(request, request.CountItems(), + optionHandler = LCP().OptionHandlerAt(index); + if(optionHandler && optionHandler->IsEnabled()) { + result = optionHandler->ParseRequest(request, request.CountItems(), nak, reject); if(result != B_OK) { @@ -1411,12 +1372,12 @@ PPPStateMachine::RXJEvent(struct mbuf *packet) } // find the LCP extension and disable it - PPPLCPExtension *extension; + PPPLCPExtension *lcpExtension; for(int32 index = 0; index < LCP().CountLCPExtensions(); index++) { - extension = LCP().LCPExtensionAt(index); + lcpExtension = LCP().LCPExtensionAt(index); - if(extension->Code() == rejectedCode) - extension->SetEnabled(false); + if(lcpExtension->Code() == rejectedCode) + lcpExtension->SetEnabled(false); } m_freem(packet); @@ -1431,25 +1392,14 @@ PPPStateMachine::RXJEvent(struct mbuf *packet) return; } - // disable protocols and encapsulators with the rejected protocl number - int32 index; - PPPProtocol *protocol_handler; - PPPEncapsulator *encapsulator_handler = Interface().FirstEncapsulator(); - - for(index = 0; index < Interface().CountProtocols(); index++) { - protocol_handler = Interface().ProtocolAt(index); - if(protocol_handler && protocol_handler->Protocol() == rejected) - protocol_handler->SetEnabled(false); + // disable protocols with the rejected protocol number + PPPProtocol *protocol = Interface().FirstProtocol(); + for(; protocol; protocol = protocol->NextProtocol()) { + if(protocol->ProtocolNumber() == rejected) + protocol->SetEnabled(false); // disable protocol } - for(; encapsulator_handler; - encapsulator_handler = encapsulator_handler->Next()) { - if(encapsulator_handler->Protocol() == rejected) - encapsulator_handler->SetEnabled(false); - // disable encapsulator - } - RXJGoodEvent(packet); // this event handler does not m_freem(packet)!!! @@ -1487,16 +1437,15 @@ PPPStateMachine::ThisLayerUp() locker.UnlockNow(); - BringHandlersUp(); + BringProtocolsUp(); } void PPPStateMachine::ThisLayerDown() { - // PPPProtocol/Encapsulator::Down() should block if needed. + // PPPProtocol::Down() should block if needed. DownProtocols(); - DownEncapsulators(); } @@ -1653,7 +1602,7 @@ PPPStateMachine::SendTerminateAck(struct mbuf *request = NULL) bool -PPPStateMachine::SendCodeReject(struct mbuf *packet, uint16 protocol, uint8 code) +PPPStateMachine::SendCodeReject(struct mbuf *packet, uint16 protocolNumber, uint8 code) { if(!packet) return false; @@ -1687,9 +1636,9 @@ PPPStateMachine::SendCodeReject(struct mbuf *packet, uint16 protocol, uint8 code else reject->length = htons(packet->m_len); - protocol = htons(protocol); + protocolNumber = htons(protocolNumber); if(code == PPP_PROTOCOL_REJECT) - memcpy(&reject->data, &protocol, sizeof(protocol)); + memcpy(&reject->data, &protocolNumber, sizeof(protocolNumber)); return LCP().Send(packet) == B_OK; } @@ -1716,9 +1665,9 @@ PPPStateMachine::SendEchoReply(struct mbuf *request) } -// methods for bringing protocols/encapsulators up +// methods for bringing protocols up void -PPPStateMachine::BringHandlersUp() +PPPStateMachine::BringProtocolsUp() { // use a simple check for phase changes (e.g., caused by CloseEvent()) while(Phase() <= PPP_ESTABLISHED_PHASE && Phase() >= PPP_AUTHENTICATION_PHASE) { @@ -1750,29 +1699,13 @@ PPPStateMachine::BringPhaseUp() return 0; uint32 count = 0; - PPPProtocol *protocol_handler; - PPPEncapsulator *encapsulator_handler = Interface().FirstEncapsulator(); - - for(int32 index = 0; index < Interface().CountProtocols(); index++) { - protocol_handler = Interface().ProtocolAt(index); - if(protocol_handler && protocol_handler->IsEnabled() - && protocol_handler->Phase() == Phase()) { - if(protocol_handler->IsUpRequested()) { + PPPProtocol *protocol = Interface().FirstProtocol(); + for(; protocol; protocol = protocol->NextProtocol()) { + if(protocol->IsEnabled() && protocol->ActivationPhase() == Phase()) { + if(protocol->IsUpRequested()) { ++count; - protocol_handler->Up(); - } else if(protocol_handler->IsGoingUp()) - ++count; - } - } - - for(; encapsulator_handler; - encapsulator_handler = encapsulator_handler->Next()) { - if(encapsulator_handler && encapsulator_handler->IsEnabled() - && encapsulator_handler->Phase() == Phase()) { - if(encapsulator_handler->IsUpRequested()) { - ++count; - encapsulator_handler->Up(); - } else if(encapsulator_handler->IsGoingUp()) + protocol->Up(); + } else if(protocol->IsGoingUp()) ++count; } } @@ -1784,21 +1717,11 @@ PPPStateMachine::BringPhaseUp() void PPPStateMachine::DownProtocols() { - for(int32 index = 0; index < Interface().CountProtocols(); index++) - if(Interface().ProtocolAt(index)->IsEnabled()) - Interface().ProtocolAt(index)->Down(); -} - - -void -PPPStateMachine::DownEncapsulators() -{ - PPPEncapsulator *encapsulator_handler = Interface().FirstEncapsulator(); + PPPProtocol *protocol = Interface().FirstProtocol(); - for(; encapsulator_handler; - encapsulator_handler = encapsulator_handler->Next()) - if(encapsulator_handler->IsEnabled()) - encapsulator_handler->Down(); + for(; protocol; protocol = protocol->NextProtocol()) + if(protocol->IsEnabled()) + protocol->Down(); } diff --git a/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPUtils.cpp b/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPUtils.cpp index c8d9e0c0e4..4b66548c3e 100644 --- a/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPUtils.cpp +++ b/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPUtils.cpp @@ -8,6 +8,23 @@ #include #include +#include + + +bool +IsProtocolAllowed(const PPPProtocol& protocol) +{ + if(protocol.ProtocolNumber() == PPP_LCP_PROTOCOL) + return true; + else if(protocol.Interface().State() != PPP_OPENED_STATE) + return false; + else if(protocol.Interface().Phase() > PPP_AUTHENTICATION_PHASE + || (protocol.Interface().Phase() >= PPP_ESTABLISHMENT_PHASE + && protocol.Flags() & PPP_ALWAYS_ALLOWED)) + return true; + else + return false; +} // These are very simple send/receive_data functions with a timeout diff --git a/src/add-ons/kernel/network/ppp/shared/libkernelppp/_KPPPAuthenticationHandler.cpp b/src/add-ons/kernel/network/ppp/shared/libkernelppp/_KPPPAuthenticationHandler.cpp index bf6517aef4..b6a1b11da0 100644 --- a/src/add-ons/kernel/network/ppp/shared/libkernelppp/_KPPPAuthenticationHandler.cpp +++ b/src/add-ons/kernel/network/ppp/shared/libkernelppp/_KPPPAuthenticationHandler.cpp @@ -18,36 +18,35 @@ typedef struct authentication_item { uint8 type; uint8 length; - uint16 protocol; + uint16 protocolNumber; } authentication_item; _PPPAuthenticationHandler::_PPPAuthenticationHandler(PPPInterface& interface) : PPPOptionHandler("Authentication Handler", AUTHENTICATION_TYPE, interface, NULL), - fLocalIndex(-1), - fPeerIndex(-1), - fSuggestedLocalIndex(-1), - fSuggestedPeerIndex(-1), + fLocalAuthenticator(NULL), + fPeerAuthenticator(NULL), + fSuggestedLocalAuthenticator(NULL), + fSuggestedPeerAuthenticator(NULL), fPeerAuthenticatorRejected(false) { } -int32 -_PPPAuthenticationHandler::NextAuthenticator(int32 start, ppp_side side) +PPPProtocol* +_PPPAuthenticationHandler::NextAuthenticator(const PPPProtocol *start, + ppp_side side) const { // find the next authenticator for side, beginning at start + PPPProtocol *current = start ? start->NextProtocol() : Interface().FirstProtocol(); - PPPProtocol *protocol; - for(int32 index = start; index < Interface().CountProtocols(); index++) { - protocol = Interface().ProtocolAt(index); - if(protocol && !strcasecmp(protocol->Type(), AUTHENTICATOR_TYPE_STRING) - && protocol->OptionHandler() - && protocol->Side() == side) - return index; + for(; current; current = current->NextProtocol()) { + if(!strcasecmp(current->Type(), AUTHENTICATOR_TYPE_STRING) + && current->OptionHandler() && current->Side() == side) + return current; } - return -1; + return NULL; } @@ -58,52 +57,49 @@ _PPPAuthenticationHandler::AddToRequest(PPPConfigurePacket& request) // add an authentication request if needed. This request is added // by the authenticator's OptionHandler. - int32 index; - PPPProtocol *protocol; - if(fPeerIndex != -1 && (protocol = Interface().ProtocolAt(fPeerIndex))) - protocol->SetEnabled(false); - if(fSuggestedPeerIndex != -1 - && (protocol = Interface().ProtocolAt(fSuggestedPeerIndex))) - protocol->SetEnabled(false); + if(fPeerAuthenticator) + fPeerAuthenticator->SetEnabled(false); + if(fSuggestedPeerAuthenticator) + fSuggestedPeerAuthenticator->SetEnabled(false); + PPPProtocol *authenticator; if(fPeerAuthenticatorRejected) { - if(fSuggestedPeerIndex == -1) { + if(!fSuggestedPeerAuthenticator) { // This happens when the protocol is rejected, but no alternative // protocol is supplied to us or the suggested protocol is not supported. // We can use this chance to increase fPeerIndex to the next authenticator. - index = NextAuthenticator(fPeerIndex + 1, PPP_PEER_SIDE); + authenticator = NextAuthenticator(fPeerAuthenticator, PPP_PEER_SIDE); } else - index = fSuggestedPeerIndex; + authenticator = fSuggestedPeerAuthenticator; fPeerAuthenticatorRejected = false; } else { - if(fPeerIndex == -1) { + if(!fPeerAuthenticator) { // there is no authenticator selected, so find one for us - index = NextAuthenticator(fPeerIndex + 1, PPP_PEER_SIDE); + authenticator = NextAuthenticator(fPeerAuthenticator, PPP_PEER_SIDE); } else - index = fPeerIndex; + authenticator = fPeerAuthenticator; } // check if all authenticators were rejected or if no authentication needed - if(index == -1) { - if(fPeerIndex == -1) - return B_OK; - // no peer authentication needed - else + if(!authenticator) { + if(fPeerAuthenticator) return B_ERROR; // all authenticators were denied + else + return B_OK; + // no peer authentication needed } - protocol = Interface().ProtocolAt(index); - if(!protocol || !protocol->OptionHandler()) + if(!authenticator || !authenticator->OptionHandler()) return B_ERROR; - fPeerIndex = index; + fPeerAuthenticator = authenticator; // this could omit some authenticators when we get a suggestion, but that is // no problem because the suggested authenticator will be accepted (hopefully) - protocol->SetEnabled(true); - return protocol->OptionHandler()->AddToRequest(request); + authenticator->SetEnabled(true); + return authenticator->OptionHandler()->AddToRequest(request); // let protocol add its request } @@ -122,26 +118,25 @@ _PPPAuthenticationHandler::ParseNak(const PPPConfigurePacket& nak) if(item->length < 4) return B_ERROR; - PPPProtocol *protocol; - if(fSuggestedPeerIndex != -1 - && (protocol = Interface().ProtocolAt(fSuggestedPeerIndex))) { - protocol->SetEnabled(false); + if(fSuggestedPeerAuthenticator) { + fSuggestedPeerAuthenticator->SetEnabled(false); // if no alternative protocol is supplied we will choose a new one in // AddToRequest() - if(ntohs(item->protocol) == protocol->Protocol()) { - fSuggestedPeerIndex = -1; + if(ntohs(item->protocolNumber) == + fSuggestedPeerAuthenticator->ProtocolNumber()) { + fSuggestedPeerAuthenticator = NULL; return B_OK; } } fPeerAuthenticatorRejected = true; - int32 index = 0; - if((protocol = Interface().ProtocolFor(ntohs(item->protocol), &index)) - && !strcasecmp(protocol->Type(), AUTHENTICATOR_TYPE_STRING) - && protocol->OptionHandler()) - fSuggestedPeerIndex = index; + PPPProtocol *authenticator = Interface().ProtocolFor(ntohs(item->protocolNumber)); + if(authenticator + && !strcasecmp(authenticator->Type(), AUTHENTICATOR_TYPE_STRING) + && authenticator->OptionHandler()) + fSuggestedPeerAuthenticator = authenticator; else - fSuggestedPeerIndex = -1; + fSuggestedPeerAuthenticator = NULL; return B_OK; } @@ -164,20 +159,20 @@ _PPPAuthenticationHandler::ParseAck(const PPPConfigurePacket& ack) authentication_item *item = (authentication_item*) ack.ItemWithType(AUTHENTICATION_TYPE); - PPPProtocol *protocol = Interface().ProtocolAt(fPeerIndex); - if(fPeerIndex != -1 && !protocol) + if(!fPeerAuthenticator) return B_ERROR; - // could not find the protocol + // could not find the authenticator if(!item) { - if(fPeerIndex != -1) + if(fPeerAuthenticator) return B_ERROR; // the ack does not contain our request - } else if(fPeerIndex == -1 || ntohs(item->protocol) != protocol->Protocol()) + } else if(!fPeerAuthenticator + || ntohs(item->protocolNumber) != fPeerAuthenticator->ProtocolNumber()) return B_ERROR; // this item was never requested - return protocol->OptionHandler()->ParseAck(ack); + return fPeerAuthenticator->OptionHandler()->ParseAck(ack); // this should enable the authenticator } @@ -186,48 +181,45 @@ status_t _PPPAuthenticationHandler::ParseRequest(const PPPConfigurePacket& request, int32 index, PPPConfigurePacket& nak, PPPConfigurePacket& reject) { - PPPProtocol *protocol; - if(fLocalIndex != -1 && (protocol = Interface().ProtocolAt(fLocalIndex))) - protocol->SetEnabled(false); + if(fLocalAuthenticator) + fLocalAuthenticator->SetEnabled(false); authentication_item *item = (authentication_item*) request.ItemAt(index); if(!item) return B_OK; - // no authentication requested by peer + // no authentication requested by peer (index > request.CountItems()) - // try to find the requested protocol and select it by saving it in fLocalIndex - fLocalIndex = 0; - protocol = Interface().ProtocolFor(ntohs(item->protocol), &fLocalIndex); - if(protocol && !strcasecmp(protocol->Type(), AUTHENTICATOR_TYPE_STRING) - && protocol->OptionHandler()) - return protocol->OptionHandler()->ParseRequest(request, index, nak, reject); + // try to find the requested protocol + fLocalAuthenticator = Interface().ProtocolFor(ntohs(item->protocolNumber)); + if(fLocalAuthenticator && + !strcasecmp(fLocalAuthenticator->Type(), AUTHENTICATOR_TYPE_STRING) + && fLocalAuthenticator->OptionHandler()) + return fLocalAuthenticator->OptionHandler()->ParseRequest(request, index, + nak, reject); // suggest another authentication protocol - int32 nextIndex = NextAuthenticator(fSuggestedLocalIndex + 1, PPP_LOCAL_SIDE); + PPPProtocol *nextAuthenticator = + NextAuthenticator(fSuggestedLocalAuthenticator, PPP_LOCAL_SIDE); - if(nextIndex == -1) { - if(fSuggestedLocalIndex == -1) { + if(!nextAuthenticator) { + if(!fSuggestedLocalAuthenticator) { // reject the complete authentication option reject.AddItem((ppp_configure_item*) item); return B_OK; } else - nextIndex = fSuggestedLocalIndex; + nextAuthenticator = fSuggestedLocalAuthenticator; // try the old one again as it was not rejected until now } - protocol = Interface().ProtocolAt(nextIndex); - if(!protocol) - return B_ERROR; - - fSuggestedLocalIndex = nextIndex; - fLocalIndex = -1; + fSuggestedLocalAuthenticator = nextAuthenticator; + fLocalAuthenticator = NULL; // no authenticator selected // nak this authenticator and suggest an alternative authentication_item suggestion; suggestion.type = AUTHENTICATION_TYPE; suggestion.length = 4; - suggestion.protocol = htons(protocol->Protocol()); + suggestion.protocolNumber = htons(nextAuthenticator->ProtocolNumber()); return nak.AddItem((ppp_configure_item*) &suggestion) ? B_OK : B_ERROR; } @@ -244,18 +236,17 @@ _PPPAuthenticationHandler::SendingAck(const PPPConfigurePacket& ack) return B_OK; // no authentication needed - fSuggestedLocalIndex = -1; + fSuggestedLocalAuthenticator = NULL; - if(fLocalIndex == -1) + if(!fLocalAuthenticator) return B_ERROR; // no authenticator selected (our suggestions must be requested, too) - PPPProtocol *protocol = Interface().ProtocolAt(fLocalIndex); - if(!protocol) + if(!fLocalAuthenticator) return B_ERROR; - protocol->SetEnabled(true); - return protocol->OptionHandler()->SendingAck(ack); + fLocalAuthenticator->SetEnabled(true); + return fLocalAuthenticator->OptionHandler()->SendingAck(ack); // this should enable the authenticator } @@ -263,21 +254,20 @@ _PPPAuthenticationHandler::SendingAck(const PPPConfigurePacket& ack) void _PPPAuthenticationHandler::Reset() { - PPPProtocol *protocol = NULL; - if(fLocalIndex != -1 && (protocol = Interface().ProtocolAt(fLocalIndex))) { - protocol->SetEnabled(false); - protocol->OptionHandler()->Reset(); + if(fLocalAuthenticator) { + fLocalAuthenticator->SetEnabled(false); + fLocalAuthenticator->OptionHandler()->Reset(); } - if(fPeerIndex != -1 && (protocol = Interface().ProtocolAt(fPeerIndex))) { - protocol->SetEnabled(false); - protocol->OptionHandler()->Reset(); + if(fPeerAuthenticator) { + fPeerAuthenticator->SetEnabled(false); + fPeerAuthenticator->OptionHandler()->Reset(); } - if(fSuggestedPeerIndex != -1 - && (protocol = Interface().ProtocolAt(fSuggestedPeerIndex))) { - protocol->SetEnabled(false); - protocol->OptionHandler()->Reset(); + if(fSuggestedPeerAuthenticator) { + fSuggestedPeerAuthenticator->SetEnabled(false); + fSuggestedPeerAuthenticator->OptionHandler()->Reset(); } - fLocalIndex = fPeerIndex = fSuggestedLocalIndex = fSuggestedPeerIndex = -1; + fLocalAuthenticator = fPeerAuthenticator = fSuggestedLocalAuthenticator = + fSuggestedPeerAuthenticator = NULL; fPeerAuthenticatorRejected = false; } diff --git a/src/add-ons/kernel/network/ppp/shared/libkernelppp/_KPPPAuthenticationHandler.h b/src/add-ons/kernel/network/ppp/shared/libkernelppp/_KPPPAuthenticationHandler.h index c9264f307e..0179316cf7 100644 --- a/src/add-ons/kernel/network/ppp/shared/libkernelppp/_KPPPAuthenticationHandler.h +++ b/src/add-ons/kernel/network/ppp/shared/libkernelppp/_KPPPAuthenticationHandler.h @@ -15,7 +15,7 @@ class _PPPAuthenticationHandler : public PPPOptionHandler { public: _PPPAuthenticationHandler(PPPInterface& interface); - int32 NextAuthenticator(int32 start, ppp_side side); + PPPProtocol *NextAuthenticator(const PPPProtocol *start, ppp_side side) const; virtual status_t AddToRequest(PPPConfigurePacket& request); virtual status_t ParseNak(const PPPConfigurePacket& nak); @@ -29,7 +29,8 @@ class _PPPAuthenticationHandler : public PPPOptionHandler { virtual void Reset(); private: - int32 fLocalIndex, fPeerIndex, fSuggestedLocalIndex, fSuggestedPeerIndex; + PPPProtocol *fLocalAuthenticator, *fPeerAuthenticator, + *fSuggestedLocalAuthenticator, *fSuggestedPeerAuthenticator; bool fPeerAuthenticatorRejected; }; diff --git a/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/KPPP.h b/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/KPPP.h index 2b08ec19fa..dc58ac94c7 100644 --- a/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/KPPP.h +++ b/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/KPPP.h @@ -12,7 +12,6 @@ #include // includes KPPPInterface.h, KPPPLCP.h, // KPPPStateMachine.h and KPPPProtocol.h -#include #include #include diff --git a/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/KPPPConfigurePacket.h b/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/KPPPConfigurePacket.h index 3c0111729c..eeb687c11c 100644 --- a/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/KPPPConfigurePacket.h +++ b/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/KPPPConfigurePacket.h @@ -8,9 +8,10 @@ #ifndef _K_PPP_CONFIGURE_PACKET__H #define _K_PPP_CONFIGURE_PACKET__H -#include #include +struct mbuf; + typedef struct ppp_configure_item { uint8 type; diff --git a/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/KPPPDefs.h b/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/KPPPDefs.h index e1845c9209..5a32c6a69d 100644 --- a/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/KPPPDefs.h +++ b/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/KPPPDefs.h @@ -17,6 +17,9 @@ typedef uint32 interface_id; #define PPP_PULSE_RATE 500000 +extern struct core_module_info *core; + + // module key types (used when loading a module) enum ppp_module_key_type { PPP_UNDEFINED_KEY_TYPE = -1, diff --git a/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/KPPPDevice.h b/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/KPPPDevice.h index bd7525c3f4..7804e04266 100644 --- a/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/KPPPDevice.h +++ b/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/KPPPDevice.h @@ -9,23 +9,22 @@ #define _K_PPP_DEVICE__H #include +#include #ifndef _K_PPP_INTERFACE__H #include #endif -class PPPDevice { - public: +class PPPDevice : public PPPLayer { + protected: + // PPPDevice must be subclassed PPPDevice(const char *name, PPPInterface& interface, driver_parameter *settings); + + public: virtual ~PPPDevice(); - virtual status_t InitCheck() const; - - const char *Name() const - { return fName; } - PPPInterface& Interface() const { return fInterface; } driver_parameter *Settings() const @@ -37,9 +36,9 @@ class PPPDevice { { return fMTU; } // these calls must not block - virtual void Up() = 0; - virtual void Down() = 0; - virtual void Listen() = 0; + virtual bool Up() = 0; + virtual bool Down() = 0; + virtual bool Listen() = 0; bool IsUp() const { return fIsUp; } @@ -51,13 +50,14 @@ class PPPDevice { virtual uint32 CountOutputBytes() const = 0; // how many bytes are waiting to be sent? - virtual status_t Send(struct mbuf *packet) = 0; - // This should enqueue the packet and return immediately. + virtual bool IsAllowedToSend() const; + // always returns true + + virtual status_t Send(struct mbuf *packet, uint16 protocolNumber) = 0; + // This should enqueue the packet and return immediately (never block). // The device is responsible for freeing the packet. - status_t PassToInterface(struct mbuf *packet); - // This will pass the packet to the interface's queue. - // Do not call Interface::ReceiveFromDevice directly - // if this can block a Send()! + virtual status_t Receive(struct mbuf *packet, uint16 protocolNumber); + // this method is never used virtual void Pulse(); @@ -79,13 +79,13 @@ class PPPDevice { protected: uint32 fMTU; // always hold this value up-to-date! - bool fIsUp; - status_t fInitStatus; private: char *fName; PPPInterface& fInterface; driver_parameter *fSettings; + + bool fIsUp; }; diff --git a/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/KPPPEncapsulator.h b/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/KPPPEncapsulator.h deleted file mode 100644 index f007328635..0000000000 --- a/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/KPPPEncapsulator.h +++ /dev/null @@ -1,128 +0,0 @@ -//---------------------------------------------------------------------- -// This software is part of the OpenBeOS distribution and is covered -// by the OpenBeOS license. -// -// Copyright (c) 2003 Waldemar Kornewald, Waldemar.Kornewald@web.de -//--------------------------------------------------------------------- - -#ifndef _K_PPP_ENCAPSULATOR__H -#define _K_PPP_ENCAPSULATOR__H - -#include - -#ifndef _K_PPP_INTERFACE__H -#include -#endif - - -class PPPEncapsulator { - public: - PPPEncapsulator(const char *name, ppp_phase phase, - ppp_encapsulation_level level, uint16 protocol, - int32 addressFamily, uint32 overhead, - PPPInterface& interface, driver_parameter *settings, - int32 flags = PPP_NO_FLAGS); - virtual ~PPPEncapsulator(); - - virtual status_t InitCheck() const; - - const char *Name() const - { return fName; } - - ppp_phase Phase() const - { return fPhase; } - - ppp_encapsulation_level Level() const - { return fLevel; } - uint32 Overhead() const - { return fOverhead; } - - PPPInterface& Interface() const - { return fInterface; } - driver_parameter *Settings() const - { return fSettings; } - - uint16 Protocol() const - { return fProtocol; } - int32 AddressFamily() const - { return fAddressFamily; } - // negative values and values > 0xFF are ignored - int32 Flags() const - { return fFlags; } - ppp_side Side() const - { return fSide; } - // which side this encapsulator works for - - void SetEnabled(bool enabled = true); - bool IsEnabled() const - { return fEnabled; } - - bool IsUpRequested() const - { return fUpRequested; } - - virtual status_t Control(uint32 op, void *data, size_t length); - virtual status_t StackControl(uint32 op, void *data); - // called by netstack (forwarded by PPPInterface) - - void SetNext(PPPEncapsulator *next) - { fNext = next; } - PPPEncapsulator *Next() const - { return fNext; } - - virtual bool Up() = 0; - virtual bool Down() = 0; - bool IsUp() const - { return fConnectionStatus == PPP_ESTABLISHED_PHASE; } - bool IsDown() const - { return fConnectionStatus == PPP_DOWN_PHASE; } - bool IsGoingUp() const - { return fConnectionStatus == PPP_ESTABLISHMENT_PHASE; } - bool IsGoingDown() const - { return fConnectionStatus == PPP_TERMINATION_PHASE; } - - virtual status_t Send(struct mbuf *packet, uint16 protocol) = 0; - virtual status_t Receive(struct mbuf *packet, uint16 protocol) = 0; - - status_t SendToNext(struct mbuf *packet, uint16 protocol) const; - // this will send your packet to the next (up) encapsulator - // if there is no next encapsulator (==NULL), it will - // call the interface's SendToDevice function - - virtual void Pulse(); - - protected: - void SetUpRequested(bool requested = true) - { fUpRequested = requested; } - - void UpStarted(); - void DownStarted(); - - void UpFailedEvent(); - void UpEvent(); - void DownEvent(); - // report up/down events - - protected: - uint32 fOverhead; - ppp_side fSide; - status_t fInitStatus; - - private: - char *fName; - ppp_phase fPhase; - ppp_encapsulation_level fLevel; - uint16 fProtocol; - int32 fAddressFamily; - PPPInterface& fInterface; - driver_parameter *fSettings; - int32 fFlags; - - PPPEncapsulator *fNext; - - bool fEnabled; - bool fUpRequested; - ppp_phase fConnectionStatus; -}; - - -#endif diff --git a/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/KPPPInterface.h b/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/KPPPInterface.h index 1cf2546fb0..04163cf4f8 100644 --- a/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/KPPPInterface.h +++ b/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/KPPPInterface.h @@ -27,14 +27,13 @@ class PPPDevice; class PPPProtocol; -class PPPEncapsulator; class PPPOptionHandler; -struct ppp_manager_info; +struct ppp_interface_module_info; struct ppp_module_info; -class PPPInterface { +class PPPInterface : public PPPLayer { friend class PPPStateMachine; friend class PPPManager; @@ -51,7 +50,7 @@ class PPPInterface { public: void Delete(); - status_t InitCheck() const; + virtual status_t InitCheck() const; interface_id ID() const { return fID; } @@ -67,9 +66,6 @@ class PPPInterface { struct ifnet *Ifnet() const { return fIfnet; } - struct ifq *InQueue() const - { return fInQueue; } - // delays uint32 DialRetryDelay() const { return fDialRetryDelay; } @@ -90,9 +86,9 @@ class PPPInterface { { return SetMRU(interfaceMTU - fHeaderLength); } uint32 InterfaceMTU() const { return fInterfaceMTU; } - // this is the MRU including encapsulator overhead + // this is the MRU including protocol overhead - status_t Control(uint32 op, void *data, size_t length); + virtual status_t Control(uint32 op, void *data, size_t length); bool SetDevice(PPPDevice *device); PPPDevice *Device() const @@ -100,21 +96,11 @@ class PPPInterface { bool AddProtocol(PPPProtocol *protocol); bool RemoveProtocol(PPPProtocol *protocol); - int32 CountProtocols() const - { return fProtocols.CountItems(); } + int32 CountProtocols() const; PPPProtocol *ProtocolAt(int32 index) const; - PPPProtocol *ProtocolFor(uint16 protocol, int32 *start = NULL) const; - int32 IndexOfProtocol(PPPProtocol *protocol) const - { return fProtocols.IndexOf(protocol); } - - bool AddEncapsulator(PPPEncapsulator *encapsulator); - bool RemoveEncapsulator(PPPEncapsulator *encapsulator); - int32 CountEncapsulators() const; - PPPEncapsulator *EncapsulatorAt(int32 index) const; - PPPEncapsulator *FirstEncapsulator() const - { return fFirstEncapsulator; } - PPPEncapsulator *EncapsulatorFor(uint16 protocol, - PPPEncapsulator *start = NULL) const; + PPPProtocol *FirstProtocol() const + { return fFirstProtocol; } + PPPProtocol *ProtocolFor(uint16 protocolNumber, PPPProtocol *start = NULL) const; // multilink methods bool AddChild(PPPInterface *child); @@ -158,9 +144,9 @@ class PPPInterface { bool UseLocalPFC() const { return LocalPFCState() & PPP_PFC_ACCEPTED; } - bool Up(); + virtual bool Up(); // in server mode Up() listens for an incoming connection - bool Down(); + virtual bool Down(); bool IsUp() const; PPPReportManager& ReportManager() @@ -174,10 +160,13 @@ class PPPInterface { bool LoadModule(const char *name, driver_parameter *parameter, ppp_module_key_type type); - status_t Send(struct mbuf *packet, uint16 protocol); - status_t Receive(struct mbuf *packet, uint16 protocol); + virtual bool IsAllowedToSend() const; + // always returns true + + virtual status_t Send(struct mbuf *packet, uint16 protocolNumber); + // sends the packet to the next handler (normally the device) + virtual status_t Receive(struct mbuf *packet, uint16 protocolNumber); - status_t SendToDevice(struct mbuf *packet, uint16 protocol); status_t ReceiveFromDevice(struct mbuf *packet); // This is called by the receive-thread. // Only call this if it does not block Send() or @@ -215,14 +204,13 @@ class PPPInterface { PPPReportManager fReportManager; struct ifnet *fIfnet; - thread_id fUpThread, fInQueueThread; - struct ifq *fInQueue; + thread_id fUpThread; thread_id fRedialThread; uint32 fDialRetry, fDialRetriesLimit; uint32 fDialRetryDelay, fRedialDelay; - ppp_manager_info *fManager; + ppp_interface_module_info *fManager; uint32 fIdleSince, fDisconnectAfterIdleSince; uint32 fMRU, fInterfaceMTU, fHeaderLength; @@ -238,13 +226,10 @@ class PPPInterface { uint8 fPFCOptions; PPPDevice *fDevice; - PPPEncapsulator *fFirstEncapsulator; - List fProtocols; + PPPProtocol *fFirstProtocol; List fModules; BLocker& fLock; - - status_t fInitStatus; int32 fDeleteCounter; }; diff --git a/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/KPPPLCP.h b/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/KPPPLCP.h index b80e692619..f19322d68a 100644 --- a/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/KPPPLCP.h +++ b/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/KPPPLCP.h @@ -22,7 +22,6 @@ #include #endif -class PPPEncapsulator; class PPPLCPExtension; class PPPOptionHandler; @@ -65,12 +64,12 @@ class PPPLCP : public PPPProtocol { PPPLCPExtension *LCPExtensionAt(int32 index) const; PPPLCPExtension *LCPExtensionFor(uint8 code, int32 *start = NULL) const; - PPPEncapsulator *Target() const - { return fTarget; } - void SetTarget(PPPEncapsulator *target) + void SetTarget(PPPProtocol *target) { fTarget = target; } - // if target != all packtes will be passed to the encapsulator + // if target != NULL all packtes will be passed to the protocol // instead of the interface/device + PPPProtocol *Target() const + { return fTarget; } uint32 AdditionalOverhead() const; // the overhead caused by the target, the device, and the interface @@ -78,8 +77,9 @@ class PPPLCP : public PPPProtocol { virtual bool Up(); virtual bool Down(); - virtual status_t Send(struct mbuf *packet); - virtual status_t Receive(struct mbuf *packet, uint16 protocol); + virtual status_t Send(struct mbuf *packet, + uint16 protocolNumber = PPP_LCP_PROTOCOL); + virtual status_t Receive(struct mbuf *packet, uint16 protocolNumber); virtual void Pulse(); @@ -89,7 +89,7 @@ class PPPLCP : public PPPProtocol { List fOptionHandlers; List fLCPExtensions; - PPPEncapsulator *fTarget; + PPPProtocol *fTarget; }; diff --git a/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/KPPPLCPExtension.h b/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/KPPPLCPExtension.h index 0400e1dafa..3f606125e6 100644 --- a/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/KPPPLCPExtension.h +++ b/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/KPPPLCPExtension.h @@ -16,9 +16,12 @@ class PPPLCPExtension { - public: + protected: + // PPPLCPExtension must be subclassed PPPLCPExtension(const char *name, uint8 code, PPPInterface& interface, driver_parameter *settings); + + public: virtual ~PPPLCPExtension(); virtual status_t InitCheck() const; diff --git a/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/KPPPLayer.h b/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/KPPPLayer.h new file mode 100644 index 0000000000..e9265889bf --- /dev/null +++ b/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/KPPPLayer.h @@ -0,0 +1,59 @@ +//---------------------------------------------------------------------- +// This software is part of the OpenBeOS distribution and is covered +// by the OpenBeOS license. +// +// Copyright (c) 2003 Waldemar Kornewald, Waldemar.Kornewald@web.de +//--------------------------------------------------------------------- + +#ifndef _K_PPP_LAYER__H +#define _K_PPP_LAYER__H + +#include + + +class PPPLayer { + protected: + // PPPLayer must be subclassed + PPPLayer(const char *name, ppp_level level); + + public: + virtual ~PPPLayer(); + + virtual status_t InitCheck() const; + + const char *Name() const + { return fName; } + ppp_level Level() const + { return fLevel; } + // should be PPP_PROTOCOL_LEVEL if not encapsulator + + void SetNext(PPPLayer *next) + { fNext = next; } + PPPLayer *Next() const + { return fNext; } + + virtual bool Up() = 0; + virtual bool Down() = 0; + + virtual bool IsAllowedToSend() const = 0; + + virtual status_t Send(struct mbuf *packet, uint16 protocolNumber) = 0; + virtual status_t Receive(struct mbuf *packet, uint16 protocolNumber) = 0; + + status_t SendToNext(struct mbuf *packet, uint16 protocolNumber) const; + // send the packet to the next layer + + virtual void Pulse(); + + protected: + status_t fInitStatus; + + private: + char *fName; + ppp_level fLevel; + + PPPLayer *fNext; +}; + + +#endif diff --git a/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/KPPPManager.h b/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/KPPPManager.h index ecd38ef893..6c2fd3b959 100644 --- a/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/KPPPManager.h +++ b/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/KPPPManager.h @@ -11,7 +11,7 @@ #include "net_module.h" -#define PPP_MANAGER_MODULE_NAME "network/interfaces/ppp" +#define PPP_INTERFACE_MODULE_NAME "network/interfaces/ppp" #define PPP_UNDEFINED_INTERFACE_ID 0 // create_interface() returns this value on failure @@ -23,26 +23,27 @@ enum ppp_interface_filter { PPP_UNREGISTERED_INTERFACES }; -typedef struct ppp_manager_info { +typedef struct ppp_interface_module_info { kernel_net_module_info knminfo; - interface_id (*create_interface)(const driver_settings *settings, + interface_id (*CreateInterface)(const driver_settings *settings, interface_id parent); // you should always create interfaces using this function - void (*delete_interface)(interface_id ID); + void (*DeleteInterface)(interface_id ID); // this marks the interface for deletion - void (*remove_interface)(interface_id ID); + void (*RemoveInterface)(interface_id ID); // remove the interface from database (make sure you can delete it yourself!) - ifnet* (*register_interface)(interface_id ID); - bool (*unregister_interface)(interface_id ID); + ifnet *(*RegisterInterface)(interface_id ID); + bool (*UnregisterInterface)(interface_id ID); - status_t (*control)(interface_id ID, uint32 op, void *data, size_t length); + status_t (*Control)(interface_id ID, uint32 op, void *data, size_t length); - status_t (*get_interfaces)(interface_id **interfaces, uint32 *count, + int32 (*GetInterfaces)(interface_id *interfaces, int32 count, ppp_interface_filter filter = PPP_REGISTERED_INTERFACES); - // the user is responsible for free()'ing the interface_id array -} ppp_manager_info; + // make sure interfaces has enough space for count items + int32 (*CountInterfaces)(); +} ppp_interface_module_info; #endif diff --git a/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/KPPPOptionHandler.h b/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/KPPPOptionHandler.h index fb00c998fe..0632158022 100644 --- a/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/KPPPOptionHandler.h +++ b/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/KPPPOptionHandler.h @@ -18,9 +18,12 @@ class PPPConfigurePacket; class PPPOptionHandler { - public: + protected: + // PPPOptionHandler must be subclassed PPPOptionHandler(const char *name, uint8 type, PPPInterface& interface, driver_parameter *settings); + + public: virtual ~PPPOptionHandler(); virtual status_t InitCheck() const; diff --git a/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/KPPPProtocol.h b/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/KPPPProtocol.h index ca7efb0bbe..57437a0810 100644 --- a/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/KPPPProtocol.h +++ b/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/KPPPProtocol.h @@ -9,34 +9,38 @@ #define _K_PPP_PROTOCOL__H #include +#include class PPPInterface; class PPPOptionHandler; -class PPPProtocol { - public: - PPPProtocol(const char *name, ppp_phase phase, uint16 protocol, - int32 addressFamily, PPPInterface& interface, +class PPPProtocol : public PPPLayer { + protected: + // PPPProtocol must be subclassed + PPPProtocol(const char *name, ppp_phase activationPhase, + uint16 protocolNumber, ppp_level level, int32 addressFamily, + uint32 overhead, PPPInterface& interface, driver_parameter *settings, int32 flags = PPP_NO_FLAGS, const char *type = NULL, PPPOptionHandler *optionHandler = NULL); + + public: virtual ~PPPProtocol(); - virtual status_t InitCheck() const; - - const char *Name() const - { return fName; } - - ppp_phase Phase() const - { return fPhase; } - PPPInterface& Interface() const { return fInterface; } driver_parameter *Settings() const { return fSettings; } - uint16 Protocol() const - { return fProtocol; } + ppp_phase ActivationPhase() const + { return fActivationPhase; } + + uint32 Overhead() const + { return fOverhead; } + // only useful for encapsulation protocols + + uint16 ProtocolNumber() const + { return fProtocolNumber; } int32 AddressFamily() const { return fAddressFamily; } // negative values and values > 0xFF are ignored @@ -46,12 +50,16 @@ class PPPProtocol { { return fSide; } // which side this protocol works for - // extensions const char *Type() const { return fType; } PPPOptionHandler *OptionHandler() const { return fOptionHandler; } + void SetNextProtocol(PPPProtocol *protocol) + { fNextProtocol = protocol; SetNext(protocol); } + PPPProtocol *NextProtocol() const + { return fNextProtocol; } + void SetEnabled(bool enabled = true); bool IsEnabled() const { return fEnabled; } @@ -67,39 +75,41 @@ class PPPProtocol { virtual bool Down() = 0; // if DialOnDemand is supported check for DialOnDemand settings change bool IsUp() const - { return fConnectionStatus == PPP_ESTABLISHED_PHASE; } + { return fConnectionPhase == PPP_ESTABLISHED_PHASE; } bool IsDown() const - { return fConnectionStatus == PPP_DOWN_PHASE; } + { return fConnectionPhase == PPP_DOWN_PHASE; } bool IsGoingUp() const - { return fConnectionStatus == PPP_ESTABLISHMENT_PHASE; } + { return fConnectionPhase == PPP_ESTABLISHMENT_PHASE; } bool IsGoingDown() const - { return fConnectionStatus == PPP_TERMINATION_PHASE; } + { return fConnectionPhase == PPP_TERMINATION_PHASE; } - virtual status_t Send(struct mbuf *packet) = 0; - virtual status_t Receive(struct mbuf *packet, uint16 protocol) = 0; + virtual bool IsAllowedToSend() const; - virtual void Pulse(); + virtual status_t Send(struct mbuf *packet, uint16 protocolNumber) = 0; + virtual status_t Receive(struct mbuf *packet, uint16 protocolNumber) = 0; protected: void SetUpRequested(bool requested = true) { fUpRequested = requested; } + // Report that we are going up/down + // (from now on, the Up() process can be aborted). void UpStarted(); void DownStarted(); + // report up/down events void UpFailedEvent(); void UpEvent(); void DownEvent(); - // report up/down events protected: + uint32 fOverhead; ppp_side fSide; - status_t fInitStatus; private: - char *fName; - ppp_phase fPhase; - uint16 fProtocol; + ppp_phase fActivationPhase; + ppp_level fLevel; + uint16 fProtocolNumber; int32 fAddressFamily; PPPInterface& fInterface; driver_parameter *fSettings; @@ -107,9 +117,10 @@ class PPPProtocol { char *fType; PPPOptionHandler *fOptionHandler; + PPPProtocol *fNextProtocol; bool fEnabled; bool fUpRequested; - ppp_phase fConnectionStatus; + ppp_phase fConnectionPhase; }; diff --git a/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/KPPPStateMachine.h b/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/KPPPStateMachine.h index 1939eb669c..b25539c602 100644 --- a/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/KPPPStateMachine.h +++ b/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/KPPPStateMachine.h @@ -10,7 +10,6 @@ #include -class PPPEncapsulator; class PPPProtocol; #ifndef _K_PPP_INTERFACE__H @@ -84,11 +83,6 @@ class PPPStateMachine { void UpEvent(PPPProtocol *protocol); void DownEvent(PPPProtocol *protocol); - // encapsulator events - void UpFailedEvent(PPPEncapsulator *encapsulator); - void UpEvent(PPPEncapsulator *encapsulator); - void DownEvent(PPPEncapsulator *encapsulator); - // device events bool TLSNotify(); bool TLFNotify(); @@ -115,7 +109,7 @@ class PPPStateMachine { void RCNEvent(struct mbuf *packet); void RTREvent(struct mbuf *packet); void RTAEvent(struct mbuf *packet); - void RUCEvent(struct mbuf *packet, uint16 protocol, + void RUCEvent(struct mbuf *packet, uint16 protocolNumber, uint8 code = PPP_PROTOCOL_REJECT); void RXJGoodEvent(struct mbuf *packet); void RXJBadEvent(struct mbuf *packet); @@ -139,14 +133,13 @@ class PPPStateMachine { bool SendConfigureNak(struct mbuf *packet); bool SendTerminateRequest(); bool SendTerminateAck(struct mbuf *request = NULL); - bool SendCodeReject(struct mbuf *packet, uint16 protocol, uint8 code); + bool SendCodeReject(struct mbuf *packet, uint16 protocolNumber, uint8 code); bool SendEchoReply(struct mbuf *request); - void BringHandlersUp(); + void BringProtocolsUp(); uint32 BringPhaseUp(); void DownProtocols(); - void DownEncapsulators(); void ResetLCPHandlers(); private: diff --git a/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/KPPPUtils.h b/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/KPPPUtils.h index 87289cd21d..166c945395 100644 --- a/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/KPPPUtils.h +++ b/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/KPPPUtils.h @@ -12,24 +12,13 @@ #include #endif +#include + +class PPPProtocol; + // helper functions -template -inline -bool -is_handler_allowed(T& handler, ppp_state state, ppp_phase phase) -{ - if(handler.Protocol() == PPP_LCP_PROTOCOL) - return true; - else if(state != PPP_OPENED_STATE) - return false; - else if(phase > PPP_AUTHENTICATION_PHASE - || (phase >= PPP_ESTABLISHMENT_PHASE - && handler.Flags() & PPP_ALWAYS_ALLOWED)) - return true; - else - return false; -} +bool IsProtocolAllowed(const PPPProtocol& protocol); // the list template does not support iterating over each item :( // this template iterates over each item in an indexed list diff --git a/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/List.h b/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/List.h index 21aeb87533..38ddf7c903 100644 --- a/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/List.h +++ b/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/List.h @@ -28,7 +28,7 @@ #ifndef LIST_H #define LIST_H -#include +#include #include #include diff --git a/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/PPPControl.h b/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/PPPControl.h index b92821dad5..d5fa467363 100644 --- a/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/PPPControl.h +++ b/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/PPPControl.h @@ -22,7 +22,6 @@ #define PPP_INTERFACE_OPS_START PPP_OPS_START + PPP_RESERVE_OPS_COUNT #define PPP_DEVICE_OPS_START PPP_OPS_START + 2 * PPP_RESERVE_OPS_COUNT #define PPP_PROTOCOL_OPS_START PPP_OPS_START + 3 * PPP_RESERVE_OPS_COUNT -#define PPP_ENCAPSULATOR_OPS_START PPP_OPS_START + 4 * PPP_RESERVE_OPS_COUNT #define PPP_OPTION_HANDLER_OPS_START PPP_OPS_START + 5 * PPP_RESERVE_OPS_COUNT #define PPP_LCP_EXTENSION_OPS_START PPP_OPS_START + 6 * PPP_RESERVE_OPS_COUNT #define PPP_COMMON_OPS_START PPP_OPS_START + 10 * PPP_RESERVE_OPS_COUNT @@ -45,7 +44,6 @@ enum ppp_control_ops { // handler access PPPC_CONTROL_DEVICE, PPPC_CONTROL_PROTOCOL, - PPPC_CONTROL_ENCAPSULATOR, PPPC_CONTROL_OPTION_HANDLER, PPPC_CONTROL_LCP_EXTENSION, PPPC_CONTROL_CHILD, @@ -56,11 +54,14 @@ enum ppp_control_ops { PPPC_GET_DEVICE_INFO = PPP_DEVICE_OPS_START, // ----------------------------------------------------- + // ----------------------------------------------------- + // PPPProtocol + PPPC_GET_PROTOCOL_INFO = PPP_PROTOCOL_OPS_START, + // ----------------------------------------------------- + // ----------------------------------------------------- // Common/mixed ops - PPPC_GET_HANDLER_INFO = PPP_COMMON_OPS_START, - // PPPProtocol and PPPEncapsulator - PPPC_SET_ENABLED, + PPPC_ENABLE, PPPC_GET_SIMPLE_HANDLER_INFO, // PPPOptionHandler and PPPLCPExtension // ----------------------------------------------------- @@ -71,7 +72,7 @@ enum ppp_control_ops { typedef struct ppp_control_info { uint32 index; - // index of interface/protocol/encapsulator/etc. + // index of interface/protocol/etc. uint32 op; // the Control()/ioctl() opcode void *data; @@ -97,8 +98,7 @@ typedef struct ppp_interface_info { ppp_pfc_state localPFCState, peerPFCState; uint8 pfcOptions; - uint32 protocolsCount, encapsulatorsCount, optionHandlersCount, - LCPExtensionsCount, childrenCount; + uint32 protocolsCount, optionHandlersCount, LCPExtensionsCount, childrenCount; uint32 MRU, interfaceMTU; uint32 dialRetry, dialRetriesLimit; @@ -118,9 +118,9 @@ typedef struct ppp_device_info { char name[PPP_HANDLER_NAME_LENGTH_LIMIT + 1]; const driver_parameter *settings; - uint32 MTU; uint32 inputTransferRate, outputTransferRate, outputBytesCount; + bool isUp; } ppp_device_info; typedef struct ppp_device_info_t { ppp_device_info info; @@ -128,39 +128,32 @@ typedef struct ppp_device_info_t { } ppp_device_info_t; -typedef struct ppp_handler_info { +typedef struct ppp_protocol_info { char name[PPP_HANDLER_NAME_LENGTH_LIMIT + 1]; + char type[PPP_HANDLER_NAME_LENGTH_LIMIT + 1]; - // general const driver_parameter *settings; - - ppp_phase phase; + ppp_phase activationPhase; int32 addressFamily, flags; ppp_side side; - uint16 protocol; + ppp_level level; + uint32 overhead; - bool isEnabled; - - // only protocol and encapsulator - bool isUpRequested; - ppp_phase connectionStatus; + ppp_phase connectionPhase; // there are four possible states: // PPP_ESTABLISHED_PHASE - IsUp() == true // PPP_DOWN_PHASE - IsDown() == true // PPP_ESTABLISHMENT_PHASE - IsGoingUp() == true // PPP_TERMINATION_PHASE - IsGoingDown() == true - // only protocol - char type[PPP_HANDLER_NAME_LENGTH_LIMIT + 1]; - - // only encapsulator - ppp_encapsulation_level level; - uint32 overhead; -} ppp_handler_info; -typedef struct ppp_handler_info_t { - ppp_handler_info info; - uint8 _reserved_[_PPP_INFO_T_SIZE_ - sizeof(ppp_handler_info)]; -} ppp_handler_info_t; + uint16 protocolNumber; + bool isEnabled; + bool isUpRequested; +} ppp_protocol_info; +typedef struct ppp_protocol_info_t { + ppp_protocol_info info; + uint8 _reserved_[_PPP_INFO_T_SIZE_ - sizeof(ppp_protocol_info)]; +} ppp_protocol_info_t; typedef struct ppp_simple_handler_info { diff --git a/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/PPPDefs.h b/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/PPPDefs.h index 378dd2fb1f..522c68283b 100644 --- a/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/PPPDefs.h +++ b/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/PPPDefs.h @@ -41,16 +41,16 @@ enum { // B_ERROR means that the packet is corrupted // B_OK means the packet was handled correctly - // return values for PPPProtocol and PPPEncapsulator (and PPPOptionHandler) + // return values for PPPProtocol PPP_UNHANDLED = PPP_ERROR_BASE, - // The packet does not belong to this handler. + // The packet does not belong to this protocol. // Do not delete the packet when you return this! // return values of PPPInterface::Receive() PPP_DISCARDED, // packet was silently discarded PPP_REJECTED, - // a protocol-reject + // a protocol-reject was sent PPP_NO_CONNECTION // could not send a packet because device is not connected @@ -75,7 +75,7 @@ enum ppp_pfc_state { // not used for peer state }; -// protocol and encapsulator flags +// protocol flags enum { PPP_NO_FLAGS = 0x00, PPP_ALWAYS_ALLOWED = 0x01, @@ -112,11 +112,15 @@ enum ppp_phase { }; // this defines the order in which the packets get encapsulated -enum ppp_encapsulation_level { +enum ppp_level { PPP_DEVICE_LEVEL = 0, + PPP_INTERFACE_LEVEL = 1, + // only used by PPPInterface PPP_MULTILINK_LEVEL = 2, PPP_ENCRYPTION_LEVEL = 5, - PPP_COMPRESSION_LEVEL = 10 + PPP_COMPRESSION_LEVEL = 10, + PPP_PROTOCOL_LEVEL = 1000 + // highest level possible; use for protocols that do not encapsulate }; // we can be a ppp client or a ppp server interface @@ -125,7 +129,7 @@ enum ppp_mode { PPP_SERVER_MODE }; -// which side the protocol/encapsulator works for +// which side the protocol works for enum ppp_side { PPP_NO_SIDE, PPP_LOCAL_SIDE, diff --git a/src/add-ons/kernel/network/ppp/shared/libkernelppp/settings_tools.cpp b/src/add-ons/kernel/network/ppp/shared/libkernelppp/settings_tools.cpp index c88e526412..8c6049a9b4 100644 --- a/src/add-ons/kernel/network/ppp/shared/libkernelppp/settings_tools.cpp +++ b/src/add-ons/kernel/network/ppp/shared/libkernelppp/settings_tools.cpp @@ -107,7 +107,7 @@ get_side_string_value(const char *sideString, ppp_side unknownValue) bool -get_string_value(const char *string, bool unknownValue) +get_boolean_value(const char *string, bool unknownValue) { if(!string) return unknownValue; diff --git a/src/add-ons/kernel/network/ppp/shared/libkernelppp/settings_tools.h b/src/add-ons/kernel/network/ppp/shared/libkernelppp/settings_tools.h index f45ac91c60..041e52f1dd 100644 --- a/src/add-ons/kernel/network/ppp/shared/libkernelppp/settings_tools.h +++ b/src/add-ons/kernel/network/ppp/shared/libkernelppp/settings_tools.h @@ -21,7 +21,14 @@ void free_driver_settings(driver_settings *settings); ppp_side get_side_string_value(const char *sideString, ppp_side unknownValue); bool get_boolean_value(const char *string, bool unknownValue); const char *get_settings_value(const char *name, const driver_settings *settings); -const char *get_parameter_value(const char *name, const driver_parameter *parameters) - { return get_settings_value(name, (driver_settings*) ¶meters->parameter_count); } + + +inline +const char* +get_parameter_value(const char *name, const driver_parameter *parameters) +{ + return get_settings_value(name, (driver_settings*) ¶meters->parameter_count); +} + #endif