From c2a58f5169a3a09963d38e76586c045ae3773469 Mon Sep 17 00:00:00 2001 From: Waldemar Kornewald Date: Sun, 14 Sep 2003 13:24:24 +0000 Subject: [PATCH] Added MRU option handler. Fixed wrong definition of MRU. Added the StackControl() method to all handlers (expect PPPDevice) and changed how the netstack ioctls are passed to the handlers. Added a template for iterating over indexed lists (needed methods: CountItems() and ItemAt()). This simplified StackControlEachHandler() a little bit. Some minor changes. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@4673 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/tests/kits/net/ppp/headers/KPPPDevice.h | 6 +- .../kits/net/ppp/headers/KPPPEncapsulator.h | 2 + .../kits/net/ppp/headers/KPPPInterface.h | 24 +-- .../kits/net/ppp/headers/KPPPLCPExtension.h | 2 + .../kits/net/ppp/headers/KPPPOptionHandler.h | 2 + src/tests/kits/net/ppp/headers/KPPPProtocol.h | 9 +- src/tests/kits/net/ppp/headers/KPPPUtils.h | 10 + src/tests/kits/net/ppp/headers/PPPControl.h | 6 +- src/tests/kits/net/ppp/headers/PPPDefs.h | 1 - src/tests/kits/net/ppp/src/Jamfile | 2 +- src/tests/kits/net/ppp/src/KPPPDevice.cpp | 1 - .../kits/net/ppp/src/KPPPEncapsulator.cpp | 12 ++ src/tests/kits/net/ppp/src/KPPPInterface.cpp | 181 ++++++++---------- src/tests/kits/net/ppp/src/KPPPLCP.cpp | 5 +- .../kits/net/ppp/src/KPPPLCPExtension.cpp | 12 ++ .../kits/net/ppp/src/KPPPOptionHandler.cpp | 12 ++ src/tests/kits/net/ppp/src/KPPPProtocol.cpp | 7 +- .../kits/net/ppp/src/KPPPStateMachine.cpp | 9 +- .../kits/net/ppp/src/_KPPPMRUHandler.cpp | 140 ++++++++++++++ src/tests/kits/net/ppp/src/_KPPPMRUHandler.h | 34 ++++ 20 files changed, 340 insertions(+), 137 deletions(-) create mode 100644 src/tests/kits/net/ppp/src/_KPPPMRUHandler.cpp create mode 100644 src/tests/kits/net/ppp/src/_KPPPMRUHandler.h diff --git a/src/tests/kits/net/ppp/headers/KPPPDevice.h b/src/tests/kits/net/ppp/headers/KPPPDevice.h index 3bac05dd68..88d2c69df0 100644 --- a/src/tests/kits/net/ppp/headers/KPPPDevice.h +++ b/src/tests/kits/net/ppp/headers/KPPPDevice.h @@ -33,10 +33,8 @@ class PPPDevice { virtual status_t Control(uint32 op, void *data, size_t length); - virtual bool SetMTU(uint32 MTU); uint32 MTU() const { return fMTU; } - virtual uint32 PreferredMTU() const = 0; // these calls must not block virtual void Up() = 0; @@ -64,6 +62,9 @@ class PPPDevice { virtual void Pulse(); protected: + void SetMTU(uint32 MTU) + { fMTU = MTU; } + // Report that we are going up/down // (from now on, the Up() process can be aborted). // Abort if false is returned! @@ -77,6 +78,7 @@ class PPPDevice { protected: uint32 fMTU; + // always hold this value up-to-date! bool fIsUp; status_t fInitStatus; diff --git a/src/tests/kits/net/ppp/headers/KPPPEncapsulator.h b/src/tests/kits/net/ppp/headers/KPPPEncapsulator.h index 34839a6ba9..7e8f26f1d8 100644 --- a/src/tests/kits/net/ppp/headers/KPPPEncapsulator.h +++ b/src/tests/kits/net/ppp/headers/KPPPEncapsulator.h @@ -58,6 +58,8 @@ class PPPEncapsulator { { 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; } diff --git a/src/tests/kits/net/ppp/headers/KPPPInterface.h b/src/tests/kits/net/ppp/headers/KPPPInterface.h index 06a985bb06..1cf2546fb0 100644 --- a/src/tests/kits/net/ppp/headers/KPPPInterface.h +++ b/src/tests/kits/net/ppp/headers/KPPPInterface.h @@ -36,17 +36,19 @@ struct ppp_module_info; class PPPInterface { friend class PPPStateMachine; + friend class PPPManager; private: // copies are not allowed! PPPInterface(const PPPInterface& copy); PPPInterface& operator= (const PPPInterface& copy); - - public: + + // only PPPManager may construct us! PPPInterface(interface_id ID, driver_settings *settings, PPPInterface *parent = NULL); ~PPPInterface(); - + + public: void Delete(); status_t InitCheck() const; @@ -80,12 +82,12 @@ class PPPInterface { uint32 DisconnectAfterIdleSince() const { return fDisconnectAfterIdleSince; } - void SetMRU(uint32 MRU); + bool SetMRU(uint32 MRU); uint32 MRU() const { return fMRU; } // this is the smallest MRU that we and the peer have - void SetInterfaceMTU(uint32 interfaceMTU) - { SetMRU(interfaceMTU - fHeaderLength); } + bool SetInterfaceMTU(uint32 interfaceMTU) + { return SetMRU(interfaceMTU - fHeaderLength); } uint32 InterfaceMTU() const { return fInterfaceMTU; } // this is the MRU including encapsulator overhead @@ -125,11 +127,11 @@ class PPPInterface { bool IsMultilink() const { return fIsMultilink; } - void SetAutoRedial(bool autoredial = true); + void SetAutoRedial(bool autoRedial = true); bool DoesAutoRedial() const { return fAutoRedial; } - void SetDialOnDemand(bool dialondemand = true); + void SetDialOnDemand(bool dialOnDemand = true); bool DoesDialOnDemand() const { return fDialOnDemand; } @@ -192,14 +194,12 @@ class PPPInterface { status_t StackControl(uint32 op, void *data); // stack routes ioctls to interface - status_t ControlEachHandler(uint32 op, void *data, size_t length); - // this calls Control() with the given parameters for each handler + status_t StackControlEachHandler(uint32 op, void *data); + // this calls StackControl() with the given parameters for each handler void CalculateInterfaceMTU(); void CalculateBaudRate(); - bool SetupDialOnDemand(); - void Redial(uint32 delay); // multilink methods diff --git a/src/tests/kits/net/ppp/headers/KPPPLCPExtension.h b/src/tests/kits/net/ppp/headers/KPPPLCPExtension.h index 39da7dd415..da58774286 100644 --- a/src/tests/kits/net/ppp/headers/KPPPLCPExtension.h +++ b/src/tests/kits/net/ppp/headers/KPPPLCPExtension.h @@ -40,6 +40,8 @@ class PPPLCPExtension { { return fCode; } 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) virtual status_t Receive(struct mbuf *packet, uint8 code) = 0; diff --git a/src/tests/kits/net/ppp/headers/KPPPOptionHandler.h b/src/tests/kits/net/ppp/headers/KPPPOptionHandler.h index 0674f686e7..1c3ec8e784 100644 --- a/src/tests/kits/net/ppp/headers/KPPPOptionHandler.h +++ b/src/tests/kits/net/ppp/headers/KPPPOptionHandler.h @@ -42,6 +42,8 @@ class PPPOptionHandler { { return fEnabled; } 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) // we want to send a configure request or we received a reply virtual status_t AddToRequest(PPPConfigurePacket& request) = 0; diff --git a/src/tests/kits/net/ppp/headers/KPPPProtocol.h b/src/tests/kits/net/ppp/headers/KPPPProtocol.h index 03b0587046..1a805aebd1 100644 --- a/src/tests/kits/net/ppp/headers/KPPPProtocol.h +++ b/src/tests/kits/net/ppp/headers/KPPPProtocol.h @@ -55,15 +55,12 @@ class PPPProtocol { { return fUpRequested; } virtual status_t Control(uint32 op, void *data, size_t length); - - virtual status_t SetupDialOnDemand(); - // This is not called when the protocol is added to the interface, - // but only when someone enables DialOnDemand and interface is down. - // Of course, your constructor may/should use this method (if needed). + virtual status_t StackControl(uint32 op, void *data); + // called by netstack (forwarded by PPPInterface) virtual bool Up() = 0; virtual bool Down() = 0; - // if DialOnDemand is implemented check for DialOnDemand settings change + // if DialOnDemand is supported check for DialOnDemand settings change bool IsUp() const { return fConnectionStatus == PPP_ESTABLISHED_PHASE; } bool IsDown() const diff --git a/src/tests/kits/net/ppp/headers/KPPPUtils.h b/src/tests/kits/net/ppp/headers/KPPPUtils.h index f9840c9bf8..403d186669 100644 --- a/src/tests/kits/net/ppp/headers/KPPPUtils.h +++ b/src/tests/kits/net/ppp/headers/KPPPUtils.h @@ -31,6 +31,16 @@ is_handler_allowed(T& handler, ppp_state state, ppp_phase phase) return false; } +// the list template does not support iterating over each item :( +// this template iterates over each item in an indexed list +template +inline +void +ForEachItem(_LIST& list, _FUNCTION function) +{ + for(int index = 0; index < list.CountItems(); index++) + function(list.ItemAt(index)); +} // These are very simple send/receive_data functions with a timeout // and there is a race condition beween has_data() and send/receive_data(). diff --git a/src/tests/kits/net/ppp/headers/PPPControl.h b/src/tests/kits/net/ppp/headers/PPPControl.h index a6bcd1e3cd..de9b3382dd 100644 --- a/src/tests/kits/net/ppp/headers/PPPControl.h +++ b/src/tests/kits/net/ppp/headers/PPPControl.h @@ -59,10 +59,6 @@ enum ppp_control_ops { PPPC_SET_ENABLED, PPPC_GET_SIMPLE_HANDLER_INFO, // PPPOptionHandler and PPPLCPExtension - PPPC_STACK_IOCTL, - // Ioctls from the stack are passed to all handlers and the interface - // using a ppp_control_info (only op and data are defined!). - // You should return B_BAD_VALUE if you did not handle this ioctl. // ----------------------------------------------------- PPP_CONTROL_OPS_END = B_DEVICE_OP_CODES_END + 0xFFFF @@ -119,7 +115,7 @@ typedef struct ppp_device_info { const driver_parameter *settings; - uint32 MTU, preferredMTU; + uint32 MTU; uint32 inputTransferRate, outputTransferRate, outputBytesCount; } ppp_device_info; typedef struct ppp_device_info_t { diff --git a/src/tests/kits/net/ppp/headers/PPPDefs.h b/src/tests/kits/net/ppp/headers/PPPDefs.h index cf629f6b8a..7921575238 100644 --- a/src/tests/kits/net/ppp/headers/PPPDefs.h +++ b/src/tests/kits/net/ppp/headers/PPPDefs.h @@ -50,7 +50,6 @@ enum { PPP_UNHANDLED = PPP_ERROR_BASE, // The packet does not belong to this handler. // Do not delete the packet when you return this! - // For PPPOptionHandler: the item is unrecognized // return values of PPPInterface::Receive() PPP_DISCARDED, diff --git a/src/tests/kits/net/ppp/src/Jamfile b/src/tests/kits/net/ppp/src/Jamfile index 353cf2e936..e07d6f1d43 100644 --- a/src/tests/kits/net/ppp/src/Jamfile +++ b/src/tests/kits/net/ppp/src/Jamfile @@ -25,6 +25,6 @@ R5KernelStaticLibrary kernelppp : cpp.cpp # integrated modules + _KPPPMRUHandler.cpp _KPPPPFCHandler.cpp ; - diff --git a/src/tests/kits/net/ppp/src/KPPPDevice.cpp b/src/tests/kits/net/ppp/src/KPPPDevice.cpp index 5d845f3662..d55a692824 100644 --- a/src/tests/kits/net/ppp/src/KPPPDevice.cpp +++ b/src/tests/kits/net/ppp/src/KPPPDevice.cpp @@ -56,7 +56,6 @@ PPPDevice::Control(uint32 op, void *data, size_t length) strcpy(info->name, Name()); info->settings = Settings(); info->MTU = MTU(); - info->preferredMTU = PreferredMTU(); info->inputTransferRate = InputTransferRate(); info->outputTransferRate = OutputTransferRate(); info->outputBytesCount = CountOutputBytes(); diff --git a/src/tests/kits/net/ppp/src/KPPPEncapsulator.cpp b/src/tests/kits/net/ppp/src/KPPPEncapsulator.cpp index cc494492c9..a8fe58e470 100644 --- a/src/tests/kits/net/ppp/src/KPPPEncapsulator.cpp +++ b/src/tests/kits/net/ppp/src/KPPPEncapsulator.cpp @@ -102,6 +102,18 @@ PPPEncapsulator::Control(uint32 op, void *data, size_t length) } +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 { diff --git a/src/tests/kits/net/ppp/src/KPPPInterface.cpp b/src/tests/kits/net/ppp/src/KPPPInterface.cpp index 2b2439d833..0b02f481b8 100644 --- a/src/tests/kits/net/ppp/src/KPPPInterface.cpp +++ b/src/tests/kits/net/ppp/src/KPPPInterface.cpp @@ -32,6 +32,7 @@ #include "settings_tools.h" // internal modules +#include "_KPPPMRUHandler.h" #include "_KPPPPFCHandler.h" @@ -68,7 +69,7 @@ PPPInterface::PPPInterface(uint32 ID, driver_settings *settings, fDialRetriesLimit(0), fIdleSince(0), fMRU(1500), - fInterfaceMTU(1498), + fInterfaceMTU(1500), fHeaderLength(2), fAutoRedial(false), fDialOnDemand(false), @@ -81,6 +82,12 @@ PPPInterface::PPPInterface(uint32 ID, driver_settings *settings, fDeleteCounter(0) { // add internal modules + // MRU + _PPPMRUHandler *mruHandler = + new _PPPMRUHandler(*this); + if(mruHandler->InitCheck() != B_OK) + delete mruHandler; + // PFC _PPPPFCHandler *pfcHandler = new _PPPPFCHandler(fLocalPFCState, fPeerPFCState, *this); if(pfcHandler->InitCheck() != B_OK) @@ -255,14 +262,19 @@ PPPInterface::InitCheck() const } -void +bool PPPInterface::SetMRU(uint32 MRU) { + if(MRU > Device()->MTU() - 2) + return false; + LockerHelper locker(fLock); fMRU = MRU; CalculateInterfaceMTU(); + + return true; } @@ -420,17 +432,6 @@ PPPInterface::Control(uint32 op, void *data, size_t length) return child->Control(control->op, control->data, control->length); } break; - case PPPC_STACK_IOCTL: { - if(length < sizeof(ppp_control_info) || !data) - return B_ERROR; - - ppp_control_info *control = (ppp_control_info*) data; - if(StackControl(control->op, control->data) == B_BAD_VALUE) - return ControlEachHandler(op, data, length); - - return B_OK; - } break; - default: return B_BAD_VALUE; } @@ -460,7 +461,7 @@ PPPInterface::SetDevice(PPPDevice *device) fDevice = device; - fMRU = fDevice->MTU(); + fMRU = fDevice->MTU() - 2; CalculateInterfaceMTU(); CalculateBaudRate(); @@ -727,47 +728,54 @@ PPPInterface::ChildAt(int32 index) const void -PPPInterface::SetAutoRedial(bool autoredial = true) +PPPInterface::SetAutoRedial(bool autoRedial = true) { if(Mode() == PPP_CLIENT_MODE) return; LockerHelper locker(fLock); - fAutoRedial = autoredial; + fAutoRedial = autoRedial; } void -PPPInterface::SetDialOnDemand(bool dialondemand = true) +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 - if(Mode() != PPP_CLIENT_MODE) + // Only clients support DialOnDemand. Maybe no change needed. + if(Mode() != PPP_CLIENT_MODE || DoesDialOnDemand() == dialOnDemand) return; LockerHelper locker(fLock); - if(DoesDialOnDemand() && !dialondemand && State() != PPP_OPENED_STATE) { - // as long as the protocols were not configured we can just delete us - Delete(); + fDialOnDemand = dialOnDemand; + + // 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 + // could not establish a connection (the user cannot access hidden interfaces) + // - disabling: the interface disappears as seen from the user, so we delete it + if(!Parent() && State() == PPP_INITIAL_STATE && Phase() == PPP_DOWN_PHASE) { + if(!dialOnDemand) + Delete(); + // as long as the protocols were not configured we can just delete us + return; } - fDialOnDemand = dialondemand; - // check if we need to register/unregister - if(fDialOnDemand) { + if(dialOnDemand) { RegisterInterface(); if(Ifnet()) Ifnet()->if_flags |= IFF_RUNNING; - } else if(!fDialOnDemand && Phase() < PPP_ESTABLISHED_PHASE) { + } else if(!dialOnDemand && Phase() < PPP_ESTABLISHED_PHASE) { UnregisterInterface(); // if we are already down we must delete us - if(Phase() == PPP_DOWN_PHASE) + if(State() == PPP_INITIAL_STATE && Phase() == PPP_DOWN_PHASE) Delete(); } } @@ -1414,7 +1422,6 @@ PPPInterface::RegisterInterface() return false; CalculateBaudRate(); - SetupDialOnDemand(); return true; } @@ -1443,7 +1450,7 @@ PPPInterface::UnregisterInterface() } -// stack routes ioctls to interface +// called by PPPManager: manager routes stack ioctls to interface status_t PPPInterface::StackControl(uint32 op, void *data) { @@ -1452,75 +1459,59 @@ PPPInterface::StackControl(uint32 op, void *data) switch(op) { default: - return B_BAD_VALUE; + return StackControlEachHandler(op, data); } return B_OK; } +// used by ControlEachHandler() +template +class CallStackControl { + public: + inline CallStackControl(uint32 op, void *data, status_t& result) + : fOp(op), fData(data), fResult(result) {} + inline void operator() (T *item) + { + if(!item || !item->IsEnabled()) + return; + status_t tmp = item->StackControl(fOp, fData); + if(tmp == B_OK && fResult == B_BAD_VALUE) + fResult = B_OK; + else if(tmp != B_BAD_VALUE) + fResult = tmp; + } + private: + uint32 fOp; + void *fData; + status_t& fResult; +}; + // This calls Control() with the given parameters for each handler. // Return values: // B_OK: all handlers returned B_OK // B_BAD_VALUE: no handler was found // any other value: the error value that was returned by the last handler that failed status_t -PPPInterface::ControlEachHandler(uint32 op, void *data, size_t length) +PPPInterface::StackControlEachHandler(uint32 op, void *data) { - int32 index; status_t result = B_BAD_VALUE, tmp; - // protocols - PPPProtocol *protocol; - for(index = 0; index < CountProtocols(); index++) { - protocol = ProtocolAt(index); - if(!protocol) - break; - - tmp = protocol->Control(op, data, length); - if(tmp == B_OK && result == B_BAD_VALUE) - result = B_OK; - else if(tmp != B_BAD_VALUE) - result = tmp; - } - - // encapsulators PPPEncapsulator *encapsulator = FirstEncapsulator(); for(; encapsulator; encapsulator = encapsulator->Next()) { - tmp = encapsulator->Control(op, data, length); + tmp = encapsulator->StackControl(op, data); if(tmp == B_OK && result == B_BAD_VALUE) result = B_OK; else if(tmp != B_BAD_VALUE) result = tmp; } - // option handlers - PPPOptionHandler *optionHandler; - for(index = 0; index < LCP().CountOptionHandlers(); index++) { - optionHandler = LCP().OptionHandlerAt(index); - if(!optionHandler) - break; - - tmp = optionHandler->Control(op, data, length); - if(tmp == B_OK && result == B_BAD_VALUE) - result = B_OK; - else if(tmp != B_BAD_VALUE) - result = tmp; - } - - // LCP extensions - PPPLCPExtension *lcpExtension; - for(index = 0; index < LCP().CountLCPExtensions(); index++) { - lcpExtension = LCP().LCPExtensionAt(index); - if(!lcpExtension) - break; - - tmp = lcpExtension->Control(op, data, length); - 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, + CallStackControl(op, data, result)); return result; } @@ -1531,9 +1522,7 @@ PPPInterface::CalculateInterfaceMTU() { fInterfaceMTU = fMRU; - // sum all headers - fHeaderLength = sizeof(uint16); - + // sum all headers (the protocol field is not counted) PPPEncapsulator *encapsulator = fFirstEncapsulator; for(; encapsulator; encapsulator = encapsulator->Next()) fHeaderLength += encapsulator->Overhead(); @@ -1568,28 +1557,6 @@ PPPInterface::CalculateBaudRate() } -bool -PPPInterface::SetupDialOnDemand() -{ - LockerHelper locker(fLock); - - if(State() == PPP_OPENED_STATE) - return true; - - bool result = true; - - PPPProtocol *protocol; - for(int32 index = 0; index < CountProtocols(); index++) { - protocol = ProtocolAt(index); - if(protocol && protocol->IsEnabled()) - if(protocol->SetupDialOnDemand() != B_OK) - result = false; - } - - return result; -} - - void PPPInterface::Redial(uint32 delay) { @@ -1660,10 +1627,22 @@ in_queue_thread(void *data) } +// ---------------------------------- +// 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). +class PPPManager { + public: + PPPManager(PPPInterface *interface) + { if(interface) delete interface; } +}; + status_t interface_deleter_thread(void *data) { - delete (PPPInterface*) data; + PPPManager((PPPInterface*) data); return B_OK; } diff --git a/src/tests/kits/net/ppp/src/KPPPLCP.cpp b/src/tests/kits/net/ppp/src/KPPPLCP.cpp index 3fb4da226b..ae76c7a9d7 100644 --- a/src/tests/kits/net/ppp/src/KPPPLCP.cpp +++ b/src/tests/kits/net/ppp/src/KPPPLCP.cpp @@ -18,9 +18,6 @@ #include -#define PPP_PROTOCOL_OVERHEAD 2 - - PPPLCP::PPPLCP(PPPInterface& interface) : PPPProtocol("LCP", PPP_ESTABLISHMENT_PHASE, PPP_LCP_PROTOCOL, AF_UNSPEC, interface, NULL, PPP_ALWAYS_ALLOWED), @@ -177,7 +174,7 @@ PPPLCP::LCPExtensionFor(uint8 code, int32 *start = NULL) const uint32 PPPLCP::AdditionalOverhead() const { - uint32 overhead = PPP_PROTOCOL_OVERHEAD; + uint32 overhead = 0; if(Target()) overhead += Target()->Overhead(); diff --git a/src/tests/kits/net/ppp/src/KPPPLCPExtension.cpp b/src/tests/kits/net/ppp/src/KPPPLCPExtension.cpp index 800c438077..dde5449d06 100644 --- a/src/tests/kits/net/ppp/src/KPPPLCPExtension.cpp +++ b/src/tests/kits/net/ppp/src/KPPPLCPExtension.cpp @@ -70,6 +70,18 @@ PPPLCPExtension::Control(uint32 op, void *data, size_t length) } +status_t +PPPLCPExtension::StackControl(uint32 op, void *data) +{ + switch(op) { + default: + return B_BAD_VALUE; + } + + return B_OK; +} + + void PPPLCPExtension::Reset() { diff --git a/src/tests/kits/net/ppp/src/KPPPOptionHandler.cpp b/src/tests/kits/net/ppp/src/KPPPOptionHandler.cpp index 0a768af341..394ebf5780 100644 --- a/src/tests/kits/net/ppp/src/KPPPOptionHandler.cpp +++ b/src/tests/kits/net/ppp/src/KPPPOptionHandler.cpp @@ -68,3 +68,15 @@ PPPOptionHandler::Control(uint32 op, void *data, size_t length) return B_OK; } + + +status_t +PPPOptionHandler::StackControl(uint32 op, void *data) +{ + switch(op) { + default: + return B_BAD_VALUE; + } + + return B_OK; +} diff --git a/src/tests/kits/net/ppp/src/KPPPProtocol.cpp b/src/tests/kits/net/ppp/src/KPPPProtocol.cpp index 693eb93bc8..65653f9be8 100644 --- a/src/tests/kits/net/ppp/src/KPPPProtocol.cpp +++ b/src/tests/kits/net/ppp/src/KPPPProtocol.cpp @@ -105,8 +105,13 @@ PPPProtocol::Control(uint32 op, void *data, size_t length) status_t -PPPProtocol::SetupDialOnDemand() +PPPProtocol::StackControl(uint32 op, void *data) { + switch(op) { + default: + return B_BAD_VALUE; + } + return B_OK; } diff --git a/src/tests/kits/net/ppp/src/KPPPStateMachine.cpp b/src/tests/kits/net/ppp/src/KPPPStateMachine.cpp index 0255c3df39..a46980391e 100644 --- a/src/tests/kits/net/ppp/src/KPPPStateMachine.cpp +++ b/src/tests/kits/net/ppp/src/KPPPStateMachine.cpp @@ -313,7 +313,10 @@ PPPStateMachine::DownEvent(PPPInterface& interface) } } - Interface().SetMRU(MRU); + if(MRU == 0) + Interface().SetMRU(1500); + else + Interface().SetMRU(MRU); if(count == 0) { locker.UnlockNow(); @@ -1341,7 +1344,7 @@ PPPStateMachine::RCREvent(struct mbuf *packet) result = handler->ParseRequest(request, index, nak, reject); - if(result != B_OK && result != PPP_UNHANDLED) { + if(result != B_OK) { // the request contains a value that has been sent more than // once or the value is corrupted m_freem(packet); @@ -1359,7 +1362,7 @@ PPPStateMachine::RCREvent(struct mbuf *packet) result = handler->ParseRequest(request, request.CountItems(), nak, reject); - if(result != B_OK && result != PPP_UNHANDLED) { + if(result != B_OK) { // the request contains a value that has been sent more than // once or the value is corrupted m_freem(packet); diff --git a/src/tests/kits/net/ppp/src/_KPPPMRUHandler.cpp b/src/tests/kits/net/ppp/src/_KPPPMRUHandler.cpp new file mode 100644 index 0000000000..29cefdb6f9 --- /dev/null +++ b/src/tests/kits/net/ppp/src/_KPPPMRUHandler.cpp @@ -0,0 +1,140 @@ +//---------------------------------------------------------------------- +// 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 "_KPPPMRUHandler.h" + +#include +#include + +#include + +#define MRU_TYPE 0x1 + +typedef struct mru_item { + uint8 type; + uint8 length; + uint16 MRU; +}; + +status_t ParseRequestedItem(mru_item *item, PPPInterface& interface); + + +_PPPMRUHandler::_PPPMRUHandler(PPPInterface& interface) + : PPPOptionHandler("MRU Handler", MRU_TYPE, interface, NULL) +{ + Reset(); +} + + +status_t +_PPPMRUHandler::AddToRequest(PPPConfigurePacket& request) +{ + if(!Interface().Device() || Interface().MRU() == 1500) + return B_OK; + + // add MRU request + mru_item item; + item.type = MRU_TYPE; + item.length = 4; + item.MRU = htons(fLocalMRU); + return request.AddItem((ppp_configure_item*) &item) ? B_OK : B_ERROR; +} + + +status_t +_PPPMRUHandler::ParseNak(const PPPConfigurePacket& nak) +{ + mru_item *item = (mru_item*) nak.ItemWithType(MRU_TYPE); + if(!item || item->length != 4) + return B_OK; + + uint16 MRU = ntohs(item->MRU); + if(MRU < fLocalMRU) + fLocalMRU = MRU; + + return B_OK; +} + + +status_t +_PPPMRUHandler::ParseReject(const PPPConfigurePacket& reject) +{ + if(reject.ItemWithType(MRU_TYPE)) + return B_ERROR; + + return B_OK; +} + + +status_t +_PPPMRUHandler::ParseAck(const PPPConfigurePacket& ack) +{ + uint16 MRU = 1500; + mru_item *item = (mru_item*) ack.ItemWithType(MRU_TYPE); + + if(item) + MRU = ntohs(item->MRU); + + if(MRU < Interface().MRU()) + fLocalMRU = MRU; + + return B_OK; +} + + +status_t +_PPPMRUHandler::ParseRequest(const PPPConfigurePacket& request, + int32 index, PPPConfigurePacket& nak, PPPConfigurePacket& reject) +{ + if(index == reject.CountItems()) + return B_OK; + + return ParseRequestedItem((mru_item*) request.ItemAt(index), Interface()); + + return B_OK; +} + + +status_t +_PPPMRUHandler::SendingAck(const PPPConfigurePacket& ack) +{ + return ParseRequestedItem((mru_item*) ack.ItemWithType(MRU_TYPE), Interface()); +} + + +// this function contains code shared by ParseRequest and SendingAck +status_t +ParseRequestedItem(mru_item *item, PPPInterface& interface) +{ + uint16 MRU = 1500; + + if(item) { + if(item->length != 4) + return B_ERROR; + // the request had a corrupted item + + MRU = ntohs(item->MRU); + } + + if(MRU < interface.MRU()) + interface.SetMRU(MRU); + + return B_OK; +} + + +void +_PPPMRUHandler::Reset() +{ + if(Interface().Device()) { + fLocalMRU = Interface().Device()->MTU() - 2; + Interface().SetMRU(fLocalMRU); + } else { + Interface().SetMRU(1500); + fLocalMRU = 1500; + } +} diff --git a/src/tests/kits/net/ppp/src/_KPPPMRUHandler.h b/src/tests/kits/net/ppp/src/_KPPPMRUHandler.h new file mode 100644 index 0000000000..4418eb39d3 --- /dev/null +++ b/src/tests/kits/net/ppp/src/_KPPPMRUHandler.h @@ -0,0 +1,34 @@ +//---------------------------------------------------------------------- +// 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_MRU_HANDLER__H +#define __K_PPP_MRU_HANDLER__H + +#include + + +class _PPPMRUHandler : public PPPOptionHandler { + public: + _PPPMRUHandler(PPPInterface& interface); + + virtual status_t AddToRequest(PPPConfigurePacket& request); + virtual status_t ParseNak(const PPPConfigurePacket& nak); + virtual status_t ParseReject(const PPPConfigurePacket& reject); + virtual status_t ParseAck(const PPPConfigurePacket& ack); + + virtual status_t ParseRequest(const PPPConfigurePacket& request, + int32 index, PPPConfigurePacket& nak, PPPConfigurePacket& reject); + virtual status_t SendingAck(const PPPConfigurePacket& ack); + + virtual void Reset(); + + private: + uint16 fLocalMRU; +}; + + +#endif