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 c82c472dd0..7e581804dc 100644 --- a/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPConfigurePacket.cpp +++ b/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPConfigurePacket.cpp @@ -20,20 +20,20 @@ PPPConfigurePacket::PPPConfigurePacket(uint8 code) PPPConfigurePacket::PPPConfigurePacket(struct mbuf *packet) { // decode packet - ppp_lcp_packet *data = mtod(packet, ppp_lcp_packet*); + ppp_lcp_packet *header = mtod(packet, ppp_lcp_packet*); - if(!SetCode(data->code)) + if(!SetCode(header->code)) return; - if(data->length < 4) + if(header->length < 4) return; // there are no items (or one corrupted item) int32 position = 0; ppp_configure_item *item; - while(position <= data->length - 4) { - item = (ppp_configure_item*) (data->data + position); + while(position <= header->length - 4) { + item = (ppp_configure_item*) (header->data + position); position += item->length; AddItem(item); @@ -130,9 +130,9 @@ PPPConfigurePacket::ToMbuf(uint32 reserve = 0) struct mbuf *packet = m_gethdr(MT_DATA); packet->m_data += reserve; - ppp_lcp_packet *data = mtod(packet, ppp_lcp_packet*); + ppp_lcp_packet *header = mtod(packet, ppp_lcp_packet*); - data->code = Code(); + header->code = Code(); uint8 length = 0; ppp_configure_item *item; @@ -140,17 +140,18 @@ PPPConfigurePacket::ToMbuf(uint32 reserve = 0) for(int32 index = 0; index < CountItems(); index++) { item = ItemAt(index); + // make sure we have enough space left if(0xFF - length < item->length) { m_freem(packet); return NULL; } - memcpy(data->data + length, item, item->length); + memcpy(header->data + length, item, item->length); length += item->length; } - data->length = length + 2; - packet->m_len = data->length; + header->length = length + 2; + packet->m_len = header->length; return packet; } 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 88be55cd00..fc6c850fe5 100644 --- a/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPDevice.cpp +++ b/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPDevice.cpp @@ -19,15 +19,15 @@ PPPDevice::PPPDevice(const char *name, PPPInterface& interface, fMTU(1500), fInterface(interface), fSettings(settings), - fIsUp(false) + fConnectionPhase(PPP_DOWN_PHASE) { - fInitStatus = interface.SetDevice(this) && fInitStatus == B_OK ? B_OK : B_ERROR; } PPPDevice::~PPPDevice() { - Interface().SetDevice(NULL); + if(Interface().Device() == this) + Interface().SetDevice(NULL); } @@ -85,15 +85,19 @@ PPPDevice::Pulse() bool -PPPDevice::UpStarted() const +PPPDevice::UpStarted() { + fConnectionPhase = PPP_ESTABLISHMENT_PHASE; + return Interface().StateMachine().TLSNotify(); } bool -PPPDevice::DownStarted() const +PPPDevice::DownStarted() { + fConnectionPhase = PPP_TERMINATION_PHASE; + return Interface().StateMachine().TLFNotify(); } @@ -101,7 +105,7 @@ PPPDevice::DownStarted() const void PPPDevice::UpFailedEvent() { - fIsUp = false; + fConnectionPhase = PPP_DOWN_PHASE; Interface().StateMachine().UpFailedEvent(); } @@ -110,7 +114,7 @@ PPPDevice::UpFailedEvent() void PPPDevice::UpEvent() { - fIsUp = true; + fConnectionPhase = PPP_ESTABLISHED_PHASE; Interface().StateMachine().UpEvent(); } @@ -119,7 +123,7 @@ PPPDevice::UpEvent() void PPPDevice::DownEvent() { - fIsUp = false; + fConnectionPhase = PPP_DOWN_PHASE; Interface().StateMachine().DownEvent(); } 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 2dd0919ae9..f374f5a4e0 100644 --- a/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPInterface.cpp +++ b/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPInterface.cpp @@ -37,7 +37,8 @@ #ifdef _KERNEL_MODE -#define spawn_thread spawn_kernel_thread + #define spawn_thread spawn_kernel_thread + #define printf dprintf #endif @@ -59,48 +60,58 @@ status_t redial_thread(void *data); status_t interface_deleter_thread(void *data); -PPPInterface::PPPInterface(uint32 ID, driver_settings *settings, +PPPInterface::PPPInterface(uint32 ID, const driver_settings *settings, PPPInterface *parent = NULL) : PPPLayer("PPPInterface", PPP_INTERFACE_LEVEL), fID(ID), fSettings(dup_driver_settings(settings)), - fStateMachine(*this), - fLCP(*this), - fReportManager(StateMachine().Locker()), fIfnet(NULL), fUpThread(-1), fRedialThread(-1), fDialRetry(0), fDialRetriesLimit(0), + fManager(NULL), fIdleSince(0), fMRU(1500), - fInterfaceMTU(1500), + fInterfaceMTU(1498), fHeaderLength(2), + fParent(NULL), + fIsMultilink(false), fAutoRedial(false), fDialOnDemand(false), + fMode(PPP_CLIENT_MODE), fLocalPFCState(PPP_PFC_DISABLED), fPeerPFCState(PPP_PFC_DISABLED), fPFCOptions(0), fDevice(NULL), fFirstProtocol(NULL), - fLock(StateMachine().Locker()), + fStateMachine(*this), + fLCP(*this), + fReportManager(StateMachine().fLock), + fLock(StateMachine().fLock), fDeleteCounter(0) { // add internal modules + // LCP + if(!AddProtocol(&LCP())) { + fInitStatus = B_ERROR; + return; + } // MRU _PPPMRUHandler *mruHandler = new _PPPMRUHandler(*this); - if(mruHandler->InitCheck() != B_OK) + if(!LCP().AddOptionHandler(mruHandler) || mruHandler->InitCheck() != B_OK) delete mruHandler; // authentication _PPPAuthenticationHandler *authenticationHandler = new _PPPAuthenticationHandler(*this); - if(authenticationHandler->InitCheck() != B_OK) + if(!LCP().AddOptionHandler(authenticationHandler) + || authenticationHandler->InitCheck() != B_OK) delete authenticationHandler; // PFC _PPPPFCHandler *pfcHandler = new _PPPPFCHandler(fLocalPFCState, fPeerPFCState, *this); - if(pfcHandler->InitCheck() != B_OK) + if(!LCP().AddOptionHandler(pfcHandler) || pfcHandler->InitCheck() != B_OK) delete pfcHandler; // set up dial delays @@ -110,20 +121,18 @@ PPPInterface::PPPInterface(uint32 ID, driver_settings *settings, // 1s delay between lost connection and redial if(get_module(PPP_INTERFACE_MODULE_NAME, (module_info**) &fManager) != B_OK) - fManager = NULL; + printf("PPPInterface: Manager module not found!\n"); // are we a multilink subinterface? if(parent && parent->IsMultilink()) { fParent = parent; fParent->AddChild(this); fIsMultilink = true; - } else { - fParent = NULL; - fIsMultilink = false; } + RegisterInterface(); + if(!fSettings) { - fMode = PPP_CLIENT_MODE; fInitStatus = B_ERROR; return; } @@ -142,7 +151,7 @@ PPPInterface::PPPInterface(uint32 ID, driver_settings *settings, // get mode settings value = get_settings_value(PPP_MODE_KEY, fSettings); - if(!strcasecmp(value, PPP_SERVER_MODE_VALUE)) + if(value && !strcasecmp(value, PPP_SERVER_MODE_VALUE)) fMode = PPP_SERVER_MODE; else fMode = PPP_CLIENT_MODE; @@ -164,10 +173,10 @@ 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) && fInitStatus == B_OK) - fInitStatus = B_OK; - else + if(!LoadModules(fSettings, 0, fSettings->parameter_count)) { + printf("PPPInterface: Error loading modules!\n"); fInitStatus = B_ERROR; + } } @@ -175,6 +184,10 @@ PPPInterface::~PPPInterface() { ++fDeleteCounter; +#if DEBUG + printf("PPPInterface: Destructor\n"); +#endif + // make sure we are not accessible by any thread before we continue UnregisterInterface(); @@ -204,11 +217,12 @@ PPPInterface::~PPPInterface() delete Device(); - while(CountProtocols()) - delete ProtocolAt(0); - - while(FirstProtocol()) - delete FirstProtocol(); + while(FirstProtocol()) { + if(FirstProtocol() == &LCP()) + fFirstProtocol = fFirstProtocol->NextProtocol(); + else + delete FirstProtocol(); + } for(int32 index = 0; index < fModules.CountItems(); index++) { put_module(fModules.ItemAt(index)); @@ -249,6 +263,10 @@ PPPInterface::Delete() status_t PPPInterface::InitCheck() const { +#if DEBUG + printf("PPPInterface: InitCheck(): 0x%lX\n", fInitStatus); +#endif + if(fInitStatus != B_OK) return fInitStatus; @@ -269,7 +287,11 @@ PPPInterface::InitCheck() const bool PPPInterface::SetMRU(uint32 MRU) { - if(MRU > Device()->MTU() - 2) +#if DEBUG + printf("PPPInterface: SetMRU(%ld)\n", MRU); +#endif + + if(Device() && MRU > Device()->MTU() - 2) return false; LockerHelper locker(fLock); @@ -293,6 +315,10 @@ PPPInterface::Control(uint32 op, void *data, size_t length) ppp_interface_info *info = (ppp_interface_info*) data; memset(info, 0, sizeof(ppp_interface_info_t)); info->settings = Settings(); + if(Ifnet()) + info->if_unit = Ifnet()->if_unit; + else + info->if_unit = -1; info->mode = Mode(); info->state = State(); info->phase = Phase(); @@ -343,7 +369,7 @@ PPPInterface::Control(uint32 op, void *data, size_t length) SetAutoRedial(*((uint32*)data)); break; - case PPPC_ENABLE_INTERFACE_REPORTS: { + case PPPC_ENABLE_REPORTS: { if(length < sizeof(ppp_report_request) || !data) return B_ERROR; @@ -352,7 +378,7 @@ PPPInterface::Control(uint32 op, void *data, size_t length) request->flags); } break; - case PPPC_DISABLE_INTERFACE_REPORTS: { + case PPPC_DISABLE_REPORTS: { if(length < sizeof(ppp_report_request) || !data) return B_ERROR; @@ -432,7 +458,11 @@ PPPInterface::Control(uint32 op, void *data, size_t length) bool PPPInterface::SetDevice(PPPDevice *device) { - if(!device) +#if DEBUG + printf("PPPInterface: SetDevice()\n"); +#endif + + if(device && &device->Interface() != this) return false; if(IsMultilink() && !Parent()) @@ -451,7 +481,8 @@ PPPInterface::SetDevice(PPPDevice *device) fDevice = device; SetNext(device); - fMRU = fDevice->MTU() - 2; + if(fDevice) + fMRU = fDevice->MTU() - 2; CalculateInterfaceMTU(); CalculateBaudRate(); @@ -466,7 +497,12 @@ PPPInterface::AddProtocol(PPPProtocol *protocol) // Find instert position after the last protocol // with the same level. - if(!protocol || protocol->Level() == PPP_INTERFACE_LEVEL) +#if DEBUG + printf("PPPInterface: AddProtocol()\n"); +#endif + + if(!protocol || &protocol->Interface() != this + || protocol->Level() == PPP_INTERFACE_LEVEL) return false; LockerHelper locker(fLock); @@ -495,7 +531,7 @@ PPPInterface::AddProtocol(PPPProtocol *protocol) protocol->SetNextProtocol(NULL); // this also sets next to NULL protocol->SetNext(this); - // we need to set us as the next layer + // we need to set us as the next layer for the last protocol } else { protocol->SetNextProtocol(current); @@ -518,6 +554,10 @@ PPPInterface::AddProtocol(PPPProtocol *protocol) bool PPPInterface::RemoveProtocol(PPPProtocol *protocol) { +#if DEBUG + printf("PPPInterface: RemoveProtocol()\n"); +#endif + LockerHelper locker(fLock); if(Phase() != PPP_DOWN_PHASE) @@ -559,10 +599,15 @@ int32 PPPInterface::CountProtocols() const { PPPProtocol *protocol = FirstProtocol(); + int32 count = 0; for(; protocol; protocol = protocol->NextProtocol()) ++count; +#if DEBUG + printf("PPPInterface: CountProtocols(): %ld\n", count); +#endif + return count; } @@ -570,19 +615,27 @@ PPPInterface::CountProtocols() const PPPProtocol* PPPInterface::ProtocolAt(int32 index) const { - PPPProtocol *protocol = FirstProtocol(); - int32 currentIndex = 0; - for(; protocol; protocol = protocol->NextProtocol(), ++currentIndex) - if(currentIndex == index) - return protocol; +#if DEBUG + printf("PPPInterface: ProtocolAt(%ld)\n", index); +#endif - return NULL; + PPPProtocol *protocol = FirstProtocol(); + + int32 currentIndex = 0; + for(; protocol && currentIndex != index; protocol = protocol->NextProtocol()) + ++currentIndex; + + return protocol; } PPPProtocol* PPPInterface::ProtocolFor(uint16 protocolNumber, PPPProtocol *start = NULL) const { +#if DEBUG + printf("PPPInterface: ProtocolFor(0x%X)\n", protocolNumber); +#endif + PPPProtocol *current = start ? start : FirstProtocol(); for(; current; current = current->NextProtocol()) { @@ -599,6 +652,10 @@ PPPInterface::ProtocolFor(uint16 protocolNumber, PPPProtocol *start = NULL) cons bool PPPInterface::AddChild(PPPInterface *child) { +#if DEBUG + printf("PPPInterface: AddChild()\n"); +#endif + if(!child) return false; @@ -616,6 +673,10 @@ PPPInterface::AddChild(PPPInterface *child) bool PPPInterface::RemoveChild(PPPInterface *child) { +#if DEBUG + printf("PPPInterface: RemoveChild()\n"); +#endif + LockerHelper locker(fLock); if(!fChildren.RemoveItem(child)) @@ -634,6 +695,10 @@ PPPInterface::RemoveChild(PPPInterface *child) PPPInterface* PPPInterface::ChildAt(int32 index) const { +#if DEBUG + printf("PPPInterface: ChildAt(%ld)\n", index); +#endif + PPPInterface *child = fChildren.ItemAt(index); if(child == fChildren.GetDefaultItem()) @@ -646,6 +711,10 @@ PPPInterface::ChildAt(int32 index) const void PPPInterface::SetAutoRedial(bool autoRedial = true) { +#if DEBUG + printf("PPPInterface: SetAutoRedial(%s)\n", autoRedial ? "true" : "false"); +#endif + if(Mode() == PPP_CLIENT_MODE) return; @@ -661,14 +730,29 @@ PPPInterface::SetDialOnDemand(bool dialOnDemand = true) // All protocols must check if DialOnDemand was enabled/disabled after this // interface went down. This is the only situation where a change is relevant. - // Only clients support DialOnDemand. Maybe no change needed. - if(Mode() != PPP_CLIENT_MODE || DoesDialOnDemand() == dialOnDemand) +#if DEBUG + printf("PPPInterface: SetDialOnDemand(%s)\n", dialOnDemand ? "true" : "false"); + printf("PPPInterface::SetDialOnDemand(): %s\n", fDialOnDemand ? "true" : "false"); +#endif + + // Only clients support DialOnDemand. + if(Mode() != PPP_CLIENT_MODE) { +#if DEBUG + printf("PPPInterface::SetDialOnDemand(): Wrong mode!\n"); +#endif + fDialOnDemand = false; + return; + } else if(DoesDialOnDemand() == dialOnDemand) return; LockerHelper locker(fLock); fDialOnDemand = dialOnDemand; +#if DEBUG + printf("PPPInterface::SetDialOnDemand() done: %s\n", fDialOnDemand?"true":"false"); +#endif + // Do not allow changes when we are disconnected (only main interfaces). // This would make no sense because // - enabling: this cannot happen because hidden interfaces are deleted if they @@ -682,17 +766,13 @@ PPPInterface::SetDialOnDemand(bool dialOnDemand = true) return; } - // check if we need to register/unregister + // check if we need to set/unset flags if(dialOnDemand) { - RegisterInterface(); if(Ifnet()) - Ifnet()->if_flags |= IFF_RUNNING; + Ifnet()->if_flags |= IFF_UP; } else if(!dialOnDemand && Phase() < PPP_ESTABLISHED_PHASE) { - UnregisterInterface(); - - // if we are already down we must delete us - if(State() == PPP_INITIAL_STATE && Phase() == PPP_DOWN_PHASE) - Delete(); + if(Ifnet()) + Ifnet()->if_flags &= ~IFF_UP; } } @@ -700,6 +780,10 @@ PPPInterface::SetDialOnDemand(bool dialOnDemand = true) bool PPPInterface::SetPFCOptions(uint8 pfcOptions) { +#if DEBUG + printf("PPPInterface: SetPFCOptions(0x%X)\n", pfcOptions); +#endif + if(PFCOptions() & PPP_FREEZE_PFC_OPTIONS) return false; @@ -711,6 +795,10 @@ PPPInterface::SetPFCOptions(uint8 pfcOptions) bool PPPInterface::Up() { +#if DEBUG + printf("PPPInterface: Up()\n"); +#endif + if(InitCheck() != B_OK || Phase() == PPP_TERMINATION_PHASE) return false; @@ -763,6 +851,11 @@ PPPInterface::Up() if(receive_data(&sender, &report, sizeof(report)) != PPP_REPORT_CODE) continue; +#if DEBUG + printf("PPPInterface::Up(): Report: Type = %ld Code = %ld\n", report.type, + report.code); +#endif + if(IsUp()) { if(me == fUpThread) { fDialRetry = 0; @@ -894,6 +987,10 @@ PPPInterface::Up() bool PPPInterface::Down() { +#if DEBUG + printf("PPPInterface: Down()\n"); +#endif + if(InitCheck() != B_OK) return false; @@ -951,6 +1048,10 @@ PPPInterface::IsUp() const bool PPPInterface::LoadModules(driver_settings *settings, int32 start, int32 count) { +#if DEBUG + printf("PPPInterface: LoadModules()\n"); +#endif + if(Phase() != PPP_DOWN_PHASE) return false; // a running connection may not change @@ -966,11 +1067,10 @@ PPPInterface::LoadModules(driver_settings *settings, int32 start, int32 count) if(!strcasecmp(settings->parameters[index].name, PPP_MULTILINK_KEY) && settings->parameters[index].value_count > 0) { if(!LoadModule(settings->parameters[index].values[0], - settings->parameters[index].parameters, PPP_MULTILINK_KEY_TYPE)) + &settings->parameters[index], PPP_MULTILINK_KEY_TYPE)) return false; break; } - } // are we a multilink main interface? @@ -1000,7 +1100,7 @@ PPPInterface::LoadModules(driver_settings *settings, int32 start, int32 count) for(int32 value_id = 0; value_id < settings->parameters[index].value_count; value_id++) if(!LoadModule(settings->parameters[index].values[value_id], - settings->parameters[index].parameters, type)) + &settings->parameters[index], type)) return false; } @@ -1012,6 +1112,10 @@ bool PPPInterface::LoadModule(const char *name, driver_parameter *parameter, ppp_module_key_type type) { +#if DEBUG + printf("PPPInterface: LoadModule(%s)\n", name ? name : "XXX: NO NAME"); +#endif + if(Phase() != PPP_DOWN_PHASE) return false; // a running connection may not change @@ -1031,7 +1135,7 @@ PPPInterface::LoadModule(const char *name, driver_parameter *parameter, // for putting them on our destruction fModules.AddItem(module_name); - return module->add_to(Parent()?*Parent():*this, this, parameter, type); + return module->add_to(Parent() ? *Parent() : *this, this, parameter, type); } @@ -1045,6 +1149,10 @@ PPPInterface::IsAllowedToSend() const status_t PPPInterface::Send(struct mbuf *packet, uint16 protocolNumber) { +#if DEBUG + printf("PPPInterface: Send(0x%X)\n", protocolNumber); +#endif + if(!packet) return B_ERROR; @@ -1129,6 +1237,10 @@ PPPInterface::Send(struct mbuf *packet, uint16 protocolNumber) status_t PPPInterface::Receive(struct mbuf *packet, uint16 protocolNumber) { +#if DEBUG + printf("PPPInterface: Receive(0x%X)\n", protocolNumber); +#endif + if(!packet) return B_ERROR; @@ -1178,6 +1290,10 @@ PPPInterface::Receive(struct mbuf *packet, uint16 protocolNumber) status_t PPPInterface::ReceiveFromDevice(struct mbuf *packet) { +#if DEBUG + printf("PPPInterface: ReceiveFromDevice()\n"); +#endif + if(!packet) return B_ERROR; @@ -1225,6 +1341,10 @@ PPPInterface::Pulse() bool PPPInterface::RegisterInterface() { +#if DEBUG + printf("PPPInterface: RegisterInterface()\n"); +#endif + if(fIfnet) return true; // we are already registered @@ -1247,6 +1367,10 @@ PPPInterface::RegisterInterface() if(!fIfnet) return false; + if(DoesDialOnDemand()) + fIfnet->if_flags |= IFF_UP; + + CalculateInterfaceMTU(); CalculateBaudRate(); return true; @@ -1256,6 +1380,10 @@ PPPInterface::RegisterInterface() bool PPPInterface::UnregisterInterface() { +#if DEBUG + printf("PPPInterface: UnregisterInterface()\n"); +#endif + if(!fIfnet) return true; // we are already unregistered @@ -1270,6 +1398,7 @@ PPPInterface::UnregisterInterface() return false; fManager->UnregisterInterface(ID()); + // this will delete fIfnet, so do not access it anymore! fIfnet = NULL; return true; @@ -1280,8 +1409,9 @@ PPPInterface::UnregisterInterface() status_t PPPInterface::StackControl(uint32 op, void *data) { - // TODO: - // implement when writing ppp interface module +#if DEBUG + printf("PPPInterface: StackControl(0x%lX)\n", op); +#endif switch(op) { default: @@ -1322,6 +1452,10 @@ class CallStackControl { status_t PPPInterface::StackControlEachHandler(uint32 op, void *data) { +#if DEBUG + printf("PPPInterface: StackControlEachHandler(0x%lX)\n", op); +#endif + status_t result = B_BAD_VALUE, tmp; PPPProtocol *protocol = FirstProtocol(); @@ -1345,7 +1479,12 @@ PPPInterface::StackControlEachHandler(uint32 op, void *data) void PPPInterface::CalculateInterfaceMTU() { +#if DEBUG + printf("PPPInterface: CalculateInterfaceMTU()\n"); +#endif + fInterfaceMTU = fMRU; + fHeaderLength = 2; // sum all headers (the protocol field is not counted) PPPProtocol *protocol = FirstProtocol(); @@ -1369,6 +1508,10 @@ PPPInterface::CalculateInterfaceMTU() void PPPInterface::CalculateBaudRate() { +#if DEBUG + printf("PPPInterface: CalculateBaudRate()\n"); +#endif + if(!Ifnet()) return; @@ -1387,6 +1530,10 @@ PPPInterface::CalculateBaudRate() void PPPInterface::Redial(uint32 delay) { +#if DEBUG + printf("PPPInterface: Redial(%ld)\n", delay); +#endif + if(fRedialThread != -1) return; 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 4accdc33fc..b71deea0e2 100644 --- a/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPLCP.cpp +++ b/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPLCP.cpp @@ -32,16 +32,18 @@ PPPLCP::~PPPLCP() { while(CountOptionHandlers()) delete OptionHandlerAt(0); + while(CountLCPExtensions()) + delete LCPExtensionAt(0); } bool PPPLCP::AddOptionHandler(PPPOptionHandler *optionHandler) { - if(!optionHandler) + if(!optionHandler || &optionHandler->Interface() != &Interface()) return false; - LockerHelper locker(StateMachine().Locker()); + LockerHelper locker(StateMachine().fLock); if(Interface().Phase() != PPP_DOWN_PHASE || OptionHandlerFor(optionHandler->Type())) return false; @@ -55,7 +57,7 @@ PPPLCP::AddOptionHandler(PPPOptionHandler *optionHandler) bool PPPLCP::RemoveOptionHandler(PPPOptionHandler *optionHandler) { - LockerHelper locker(StateMachine().Locker()); + LockerHelper locker(StateMachine().fLock); if(Interface().Phase() != PPP_DOWN_PHASE) return false; @@ -106,10 +108,10 @@ PPPLCP::OptionHandlerFor(uint8 type, int32 *start = NULL) const bool PPPLCP::AddLCPExtension(PPPLCPExtension *lcpExtension) { - if(!lcpExtension) + if(!lcpExtension || &lcpExtension->Interface() != &Interface()) return false; - LockerHelper locker(StateMachine().Locker()); + LockerHelper locker(StateMachine().fLock); if(Interface().Phase() != PPP_DOWN_PHASE) return false; @@ -122,7 +124,7 @@ PPPLCP::AddLCPExtension(PPPLCPExtension *lcpExtension) bool PPPLCP::RemoveLCPExtension(PPPLCPExtension *lcpExtension) { - LockerHelper locker(StateMachine().Locker()); + LockerHelper locker(StateMachine().fLock); if(Interface().Phase() != PPP_DOWN_PHASE) return false; 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 26d1c3d01d..8bbfd29701 100644 --- a/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPLCPExtension.cpp +++ b/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPLCPExtension.cpp @@ -21,8 +21,6 @@ PPPLCPExtension::PPPLCPExtension(const char *name, uint8 code, PPPInterface& int fName = strdup(name); else fName = strdup("Unknown"); - - fInitStatus = interface.LCP().AddLCPExtension(this) ? B_OK : 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 index 49355a342d..cbc021844f 100644 --- a/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPLayer.cpp +++ b/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPLayer.cpp @@ -11,11 +11,14 @@ #include #include -#include +#ifdef _KERNEL_MODE + #include +#endif PPPLayer::PPPLayer(const char *name, ppp_level level) : fInitStatus(B_OK), + fLevel(level), fNext(NULL) { if(name) 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 265278fb5f..bfe34ae8bd 100644 --- a/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPOptionHandler.cpp +++ b/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPOptionHandler.cpp @@ -21,8 +21,6 @@ PPPOptionHandler::PPPOptionHandler(const char *name, uint8 type, fName = strdup(name); else fName = strdup("Unknown"); - - fInitStatus = interface.LCP().AddOptionHandler(this) ? B_OK : 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 af072a972c..ff6f469232 100644 --- a/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPProtocol.cpp +++ b/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPProtocol.cpp @@ -45,8 +45,6 @@ PPPProtocol::PPPProtocol(const char *name, ppp_phase activationPhase, else fSide = PPP_PEER_SIDE; } - - fInitStatus = interface.AddProtocol(this) && fInitStatus == B_OK ? B_OK : B_ERROR; } 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 b714c24afc..ee2796797c 100644 --- a/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPReportManager.cpp +++ b/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPReportManager.cpp @@ -118,11 +118,17 @@ PPPReportManager::Report(ppp_report_type type, int32 code, void *data, int32 len continue; } else if(result == B_OK) { if(request->flags & PPP_WAIT_FOR_REPLY) { + thread_info info; + if(request->flags & PPP_NO_REPLY_TIMEOUT) { sender = -1; - while(sender != request->thread) - code = receive_data(&sender, NULL, 0); - result = B_OK; + result = B_ERROR; + // always check if the thread still exists + while(sender != request->thread + && get_thread_info(request->thread, &info) + != B_BAD_THREAD_ID) + result = receive_data_with_timeout(&sender, &code, NULL, 0, + PPP_REPORT_TIMEOUT); } else { sender = -1; result = B_OK; 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 23c29c065c..5d3f9e8710 100644 --- a/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPStateMachine.cpp +++ b/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPStateMachine.cpp @@ -75,8 +75,6 @@ PPPStateMachine::NewState(ppp_state next) void PPPStateMachine::NewPhase(ppp_phase next) { - // the ifnet's running flag is set here and in PPPInterface::SetDialOnDemand() - // there is nothing after established phase and nothing before down phase if(next > PPP_ESTABLISHED_PHASE) next = PPP_ESTABLISHED_PHASE; @@ -86,10 +84,16 @@ PPPStateMachine::NewPhase(ppp_phase next) // Report a down event to parent if we are not usable anymore. // The report threads get their notification later. if(Phase() == PPP_ESTABLISHED_PHASE && next != Phase()) { - // there is no need to unset the running flag because we unregister, anyway if(!Interface().DoesDialOnDemand()) Interface().UnregisterInterface(); + if(Interface().Ifnet()) { + Interface().Ifnet()->if_flags &= ~IFF_RUNNING; + + if(!Interface().DoesDialOnDemand()) + Interface().Ifnet()->if_flags &= ~IFF_UP; + } + if(Interface().Parent()) Interface().Parent()->StateMachine().DownEvent(Interface()); } @@ -97,8 +101,8 @@ PPPStateMachine::NewPhase(ppp_phase next) fPhase = next; if(Phase() == PPP_ESTABLISHED_PHASE) { - if(Interface().Ifnet() && !Interface().DoesDialOnDemand()) - Interface().Ifnet()->if_flags |= IFF_RUNNING; + if(Interface().Ifnet()) + Interface().Ifnet()->if_flags |= IFF_UP | IFF_RUNNING; Interface().Report(PPP_CONNECTION_REPORT, PPP_REPORT_UP_SUCCESSFUL, NULL, 0); } @@ -419,6 +423,11 @@ PPPStateMachine::UpFailedEvent() if(Interface().Parent()) Interface().Parent()->StateMachine().UpFailedEvent(Interface()); + + NewPhase(PPP_DOWN_PHASE); + // tell DownEvent() that we do not need to redial + + DownEvent(); break; default: @@ -525,6 +534,7 @@ PPPStateMachine::DownEvent() IllegalEvent(PPP_DOWN_EVENT); } + ppp_phase oldPhase = Phase(); NewPhase(PPP_DOWN_PHASE); DownProtocols(); @@ -536,6 +546,7 @@ PPPStateMachine::DownEvent() if(State() == PPP_STARTING_STATE) { bool needsRedial = false; + // we do not try to redial if authentication failed if(fLocalAuthenticationStatus == PPP_AUTHENTICATION_FAILED || fLocalAuthenticationStatus == PPP_AUTHENTICATING) Interface().Report(PPP_CONNECTION_REPORT, @@ -550,8 +561,10 @@ PPPStateMachine::DownEvent() if(Interface().fUpThread == -1) needsRedial = true; - Interface().Report(PPP_CONNECTION_REPORT, PPP_REPORT_CONNECTION_LOST, - NULL, 0); + // test if UpFailedEvent() was not called + if(oldPhase != PPP_DOWN_PHASE) + Interface().Report(PPP_CONNECTION_REPORT, PPP_REPORT_CONNECTION_LOST, + NULL, 0); } if(Interface().Parent()) @@ -587,8 +600,10 @@ PPPStateMachine::OpenEvent() if(Interface().Mode() == PPP_SERVER_MODE) { NewPhase(PPP_ESTABLISHMENT_PHASE); - if(Interface().Device()) - Interface().Device()->Listen(); + if(Interface().Device() && !Interface().Device()->Up()) { + Interface().Device()->UpFailedEvent(); + return; + } } else NewState(PPP_STARTING_STATE); @@ -1452,8 +1467,8 @@ PPPStateMachine::ThisLayerDown() void PPPStateMachine::ThisLayerStarted() { - if(Interface().Device()) - Interface().Device()->Up(); + if(Interface().Device() && !Interface().Device()->Up()) + Interface().Device()->UpFailedEvent(); } 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 eeb687c11c..238e960b36 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 @@ -16,7 +16,7 @@ struct mbuf; typedef struct ppp_configure_item { uint8 type; uint8 length; - int8 data[0]; + uint8 data[0]; // the data follows this structure } ppp_configure_item; 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 5a32c6a69d..d5aafabc7a 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 @@ -11,8 +11,6 @@ #include -typedef uint32 interface_id; - // various constants #define PPP_PULSE_RATE 500000 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 7804e04266..82f4e4fd3e 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 @@ -17,6 +17,8 @@ class PPPDevice : public PPPLayer { + friend class PPPStateMachine; + protected: // PPPDevice must be subclassed PPPDevice(const char *name, PPPInterface& interface, @@ -35,12 +37,18 @@ class PPPDevice : public PPPLayer { uint32 MTU() const { return fMTU; } - // these calls must not block virtual bool Up() = 0; + // In server mode you should listen for incoming connections. + // On error: either call UpFailedEvent() or return false. virtual bool Down() = 0; - virtual bool Listen() = 0; bool IsUp() const - { return fIsUp; } + { return fConnectionPhase == PPP_ESTABLISHED_PHASE; } + bool IsDown() const + { return fConnectionPhase == PPP_DOWN_PHASE; } + bool IsGoingUp() const + { return fConnectionPhase == PPP_ESTABLISHMENT_PHASE; } + bool IsGoingDown() const + { return fConnectionPhase == PPP_TERMINATION_PHASE; } // The biggest of the two tranfer rates will be set in ifnet. // These methods should return default values when disconnected. @@ -68,8 +76,8 @@ class PPPDevice : public PPPLayer { // Report that we are going up/down // (from now on, the Up() process can be aborted). // Abort if false is returned! - bool UpStarted() const; - bool DownStarted() const; + bool UpStarted(); + bool DownStarted(); // report up/down events void UpFailedEvent(); @@ -85,7 +93,7 @@ class PPPDevice : public PPPLayer { PPPInterface& fInterface; driver_parameter *fSettings; - bool fIsUp; + ppp_phase fConnectionPhase; }; 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 04163cf4f8..8ea2502974 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 @@ -43,7 +43,7 @@ class PPPInterface : public PPPLayer { PPPInterface& operator= (const PPPInterface& copy); // only PPPManager may construct us! - PPPInterface(interface_id ID, driver_settings *settings, + PPPInterface(interface_id ID, const driver_settings *settings, PPPInterface *parent = NULL); ~PPPInterface(); @@ -152,7 +152,7 @@ class PPPInterface : public PPPLayer { PPPReportManager& ReportManager() { return fReportManager; } bool Report(ppp_report_type type, int32 code, void *data, int32 length) - { return fReportManager.Report(type, code, data, length); } + { return ReportManager().Report(type, code, data, length); } // returns false if reply was bad (or an error occured) bool LoadModules(driver_settings *settings, @@ -168,9 +168,7 @@ class PPPInterface : public PPPLayer { virtual status_t Receive(struct mbuf *packet, uint16 protocolNumber); status_t ReceiveFromDevice(struct mbuf *packet); - // This is called by the receive-thread. - // Only call this if it does not block Send() or - // SendToDevice()! + // This must not block PPPDevice::Send()! void Pulse(); // this manages all timeouts, etc. @@ -199,9 +197,6 @@ class PPPInterface : public PPPLayer { interface_id fID; // the manager assigns an ID to every interface driver_settings *fSettings; - PPPStateMachine fStateMachine; - PPPLCP fLCP; - PPPReportManager fReportManager; struct ifnet *fIfnet; thread_id fUpThread; @@ -229,6 +224,9 @@ class PPPInterface : public PPPLayer { PPPProtocol *fFirstProtocol; List fModules; + PPPStateMachine fStateMachine; + PPPLCP fLCP; + PPPReportManager fReportManager; BLocker& fLock; int32 fDeleteCounter; }; 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 6c2fd3b959..058433e93f 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 @@ -9,6 +9,8 @@ #define _K_PPP_MANAGER__H #include "net_module.h" +#include +#include #define PPP_INTERFACE_MODULE_NAME "network/interfaces/ppp" @@ -16,18 +18,12 @@ #define PPP_UNDEFINED_INTERFACE_ID 0 // create_interface() returns this value on failure -// this allows you to ask for specific interface_ids -enum ppp_interface_filter { - PPP_ALL_INTERFACES, - PPP_REGISTERED_INTERFACES, - PPP_UNREGISTERED_INTERFACES -}; typedef struct ppp_interface_module_info { kernel_net_module_info knminfo; interface_id (*CreateInterface)(const driver_settings *settings, - interface_id parent); + interface_id parentID = PPP_UNDEFINED_INTERFACE_ID); // you should always create interfaces using this function void (*DeleteInterface)(interface_id ID); // this marks the interface for deletion @@ -37,12 +33,18 @@ typedef struct ppp_interface_module_info { 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 (*ControlInterface)(interface_id ID, uint32 op, void *data, + size_t length); int32 (*GetInterfaces)(interface_id *interfaces, int32 count, ppp_interface_filter filter = PPP_REGISTERED_INTERFACES); // make sure interfaces has enough space for count items - int32 (*CountInterfaces)(); + int32 (*CountInterfaces)(ppp_interface_filter filter = PPP_REGISTERED_INTERFACES); + + void (*EnableReports)(ppp_report_type type, thread_id thread, + int32 flags = PPP_NO_FLAGS); + void (*DisableReports)(ppp_report_type type, thread_id thread); + bool (*DoesReport)(ppp_report_type type, thread_id thread); } ppp_interface_module_info; diff --git a/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/KPPPModule.h b/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/KPPPModule.h index c3f24e6c98..8fa982eb92 100644 --- a/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/KPPPModule.h +++ b/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/KPPPModule.h @@ -16,7 +16,7 @@ class PPPInterface; typedef struct ppp_module_info { module_info minfo; status_t (*control)(uint32 op, void *data, size_t length); - status_t (*add_to)(PPPInterface& mainInterface, PPPInterface *subInterface, + bool (*add_to)(PPPInterface& mainInterface, PPPInterface *subInterface, driver_parameter *settings, ppp_module_key_type type); // multilink: handlers that must run on a real device // should be added to subInterface (may be NULL) 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 57437a0810..c16fc3b23a 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 @@ -108,7 +108,6 @@ class PPPProtocol : public PPPLayer { private: ppp_phase fActivationPhase; - ppp_level fLevel; uint16 fProtocolNumber; int32 fAddressFamily; PPPInterface& fInterface; 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 b25539c602..3c2f1cad55 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 @@ -91,9 +91,6 @@ class PPPStateMachine { void DownEvent(); private: - BLocker& Locker() - { return fLock; } - // private StateMachine methods void NewState(ppp_state next); void NewPhase(ppp_phase next); 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 38ddf7c903..e865fc27ca 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,10 @@ #ifndef LIST_H #define LIST_H -#include +#ifdef _KERNEL_MODE + #include +#endif + #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 d5fa467363..1c59060867 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 @@ -9,6 +9,7 @@ #define _PPP_CONTROL__H #include +#include #include @@ -29,6 +30,17 @@ enum ppp_control_ops { + // ----------------------------------------------------- + // PPPManager + PPPC_CREATE_INTERFACE = PPP_OPS_START, + PPPC_DELETE_INTERFACE, + PPPC_BRING_INTERFACE_UP, + PPPC_BRING_INTERFACE_DOWN, + PPPC_CONTROL_INTERFACE, + PPPC_GET_INTERFACES, + PPPC_COUNT_INTERFACES, + // ----------------------------------------------------- + // ----------------------------------------------------- // PPPInterface PPPC_GET_INTERFACE_INFO = PPP_INTERFACE_OPS_START, @@ -36,11 +48,6 @@ enum ppp_control_ops { PPPC_SET_DIAL_ON_DEMAND, PPPC_SET_AUTO_REDIAL, - // these control ops use the ppp_report_request structure - PPPC_ENABLE_INTERFACE_REPORTS, - PPPC_DISABLE_INTERFACE_REPORTS, - // flags are not used for this control op - // handler access PPPC_CONTROL_DEVICE, PPPC_CONTROL_PROTOCOL, @@ -64,15 +71,35 @@ enum ppp_control_ops { PPPC_ENABLE, PPPC_GET_SIMPLE_HANDLER_INFO, // PPPOptionHandler and PPPLCPExtension + + // these two control ops use the ppp_report_request structure + PPPC_ENABLE_REPORTS, + PPPC_DISABLE_REPORTS, + // flags are not used for this control op // ----------------------------------------------------- PPP_CONTROL_OPS_END = B_DEVICE_OP_CODES_END + 0xFFFF }; +typedef struct ppp_interface_settings_info { + const driver_settings *settings; + interface_id interface; + // only when creating: this is the id of the created interface +} ppp_interface_settings_info; + + +typedef struct ppp_get_interfaces_info { + interface_id *interfaces; + int32 count; + ppp_interface_filter filter; + int32 resultCount; +} ppp_get_interfaces_info; + + typedef struct ppp_control_info { uint32 index; - // index of interface/protocol/etc. + // index/id of interface/protocol/etc. uint32 op; // the Control()/ioctl() opcode void *data; @@ -91,6 +118,9 @@ typedef struct ppp_control_info { typedef struct ppp_interface_info { const driver_settings *settings; + int32 if_unit; + // negative if not registered + ppp_mode mode; ppp_state state; ppp_phase phase; 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 522c68283b..47b05668de 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 @@ -11,6 +11,9 @@ #include +typedef uint32 interface_id; + + // settings keys #define PPP_DISONNECT_AFTER_IDLE_SINCE_KEY "DisonnectAfterIdleSince" #define PPP_MODE_KEY "Mode" @@ -35,6 +38,14 @@ #define PPP_ERROR_BASE B_ERRORS_END + 1 + +// this is used when talking to the interface manager +enum ppp_interface_filter { + PPP_ALL_INTERFACES, + PPP_REGISTERED_INTERFACES, + PPP_UNREGISTERED_INTERFACES +}; + // return values for Send()/Receive() methods in addition to B_ERROR and B_OK // PPP_UNHANDLED is also used by PPPOptionHandler enum { diff --git a/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/PPPReportDefs.h b/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/PPPReportDefs.h index 664b561947..8d45d95c51 100644 --- a/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/PPPReportDefs.h +++ b/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/PPPReportDefs.h @@ -8,6 +8,8 @@ #ifndef _PPP_REPORT_DEFS__H #define _PPP_REPORT_DEFS__H +#include + #define PPP_REPORT_TIMEOUT 10 @@ -28,13 +30,21 @@ enum ppp_report_flags { enum ppp_report_type { PPP_ALL_REPORTS = -1, // used only when disabling reports + PPP_MANAGER_REPORT = 1, PPP_DESTRUCTION_REPORT = 16, // the interface is being destroyed (no code is needed) // this report is sent even if it was not requested PPP_CONNECTION_REPORT = 17 }; + // report codes (type-specific) +enum ppp_manager_report_codes { + // the interface id is added to the following reports + PPP_REPORT_INTERFACE_CREATED = 0 +}; + + enum ppp_connection_report_codes { PPP_REPORT_GOING_UP = 0, PPP_REPORT_UP_SUCCESSFUL = 1, 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 8c6049a9b4..78037175ca 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 @@ -27,10 +27,15 @@ dup_driver_settings(const driver_settings *dup) driver_settings *ret = (driver_settings*) malloc(sizeof(driver_settings)); ret->parameter_count = dup->parameter_count; - ret->parameters = (driver_parameter*) malloc(ret->parameter_count * sizeof(driver_parameter)); - for(int32 i=0; i < ret->parameter_count; i++) - copy_parameter(&dup->parameters[i], &ret->parameters[i]); + if(ret->parameter_count > 0) + ret->parameters = + (driver_parameter*) malloc(ret->parameter_count * sizeof(driver_parameter)); + else + ret->parameters = NULL; + + for(int32 index = 0; index < ret->parameter_count; index++) + copy_parameter(&dup->parameters[index], &ret->parameters[index]); return ret; } @@ -43,48 +48,111 @@ copy_parameter(const driver_parameter *from, driver_parameter *to) to->name = strdup(from->name); to->value_count = from->value_count; - to->values = (char**) malloc(to->value_count * sizeof(char*)); + if(to->value_count > 0) + to->values = (char**) malloc(to->value_count * sizeof(char*)); + else + to->values = NULL; - for(int32 i=0; i < to->value_count; i++) - to->values[i] = strdup(from->values[i]); + for(int32 index = 0; index < to->value_count; index++) + to->values[index] = strdup(from->values[index]); to->parameter_count = from->parameter_count; - to->parameters = (driver_parameter*) malloc(to->parameter_count * sizeof(driver_parameter)); + if(to->parameter_count > 0) + to->parameters = + (driver_parameter*) malloc(to->parameter_count * sizeof(driver_parameter)); + else + to->parameters = NULL; - for(int32 i=0; i < to->parameter_count; i++) - copy_parameter(&from->parameters[i], &to->parameters[i]); + for(int32 index = 0; index < to->parameter_count; index++) + copy_parameter(&from->parameters[index], &to->parameters[index]); } void free_driver_settings(driver_settings *settings) { - for(int32 i=0; i < settings->parameter_count; i++) - free_driver_parameter(&settings->parameters[i]); + if(!settings) + return; + + for(int32 index = 0; index < settings->parameter_count; index++) + free_driver_parameter(&settings->parameters[index]); free(settings->parameters); free(settings); } +static void free_driver_parameter(driver_parameter *p) { free(p->name); - for(int32 i=0; i < p->value_count; i++) - free(p->values[i]); + for(int32 index = 0; index < p->value_count; index++) + free(p->values[index]); free(p->values); - for(int32 i=0; i < p->parameter_count; i++) - free_driver_parameter(&p->parameters[i]); + for(int32 index = 0; index < p->parameter_count; index++) + free_driver_parameter(&p->parameters[index]); free(p->parameters); } +bool +equal_driver_settings(const driver_settings *lhs, const driver_settings *rhs) +{ + if(!lhs && !rhs) + return true; + else if(!lhs || !rhs) + return false; + + if(lhs->parameter_count != rhs->parameter_count) + return false; + + for(int32 index = 0; index < lhs->parameter_count; index++) { + if(!equal_driver_parameters(&lhs->parameters[index], &rhs->parameters[index])) + return false; + } + + return true; +} + + +bool +equal_driver_parameters(const driver_parameter *lhs, const driver_parameter *rhs) +{ + if(!lhs && !rhs) + return true; + else if(!lhs || !rhs) + return false; + + if(lhs->name && rhs->name) { + if(strcmp(lhs->name, rhs->name)) + return false; + } else if(lhs->name != rhs->name) + return false; + + if(lhs->value_count != rhs->value_count + || lhs->parameter_count != rhs->parameter_count) + return false; + + for(int32 index = 0; index < lhs->value_count; index++) { + if(strcmp(lhs->values[index], rhs->values[index])) + return false; + } + + for(int32 index = 0; index < lhs->parameter_count; index++) { + if(!equal_driver_parameters(&lhs->parameters[index], &rhs->parameters[index])) + return false; + } + + return true; +} + + ppp_side get_side_string_value(const char *sideString, ppp_side unknownValue) { @@ -139,10 +207,11 @@ get_settings_value(const char *name, const driver_settings *settings) if(!name || !settings) return NULL; - for(int32 i=0; i < settings->parameter_count; i++) - if(!strcasecmp(settings->parameters[i].name, name) - && settings->parameters[i].value_count > 0) - return settings->parameters[i].values[0]; + for(int32 index = 0; index < settings->parameter_count; index++) + if(!strcasecmp(settings->parameters[index].name, name) + && settings->parameters[index].value_count > 0 + && settings->parameters[index].values) + return settings->parameters[index].values[0]; return NULL; } 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 041e52f1dd..cb20093e6f 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 @@ -8,15 +8,16 @@ #ifndef _SETTINGS_TOOLS__H #define _SETTINGS_TOOLS__H -// remove this as soon as we get the extended driver_settings API +#include -struct driver_settings; -struct driver_parameter; +// TODO: remove this as soon as we get the extended driver_settings API driver_settings *dup_driver_settings(const driver_settings *settings); void free_driver_settings(driver_settings *settings); +bool equal_driver_settings(const driver_settings *lhs, const driver_settings *rhs); +bool equal_driver_parameters(const driver_parameter *lhs, const driver_parameter *rhs); ppp_side get_side_string_value(const char *sideString, ppp_side unknownValue); bool get_boolean_value(const char *string, bool unknownValue); @@ -27,7 +28,8 @@ inline const char* get_parameter_value(const char *name, const driver_parameter *parameters) { - return get_settings_value(name, (driver_settings*) ¶meters->parameter_count); + return get_settings_value(name, + parameters ? (driver_settings*) ¶meters->parameter_count : NULL); }