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
This commit is contained in:
@@ -33,10 +33,8 @@ class PPPDevice {
|
|||||||
|
|
||||||
virtual status_t Control(uint32 op, void *data, size_t length);
|
virtual status_t Control(uint32 op, void *data, size_t length);
|
||||||
|
|
||||||
virtual bool SetMTU(uint32 MTU);
|
|
||||||
uint32 MTU() const
|
uint32 MTU() const
|
||||||
{ return fMTU; }
|
{ return fMTU; }
|
||||||
virtual uint32 PreferredMTU() const = 0;
|
|
||||||
|
|
||||||
// these calls must not block
|
// these calls must not block
|
||||||
virtual void Up() = 0;
|
virtual void Up() = 0;
|
||||||
@@ -64,6 +62,9 @@ class PPPDevice {
|
|||||||
virtual void Pulse();
|
virtual void Pulse();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
void SetMTU(uint32 MTU)
|
||||||
|
{ fMTU = MTU; }
|
||||||
|
|
||||||
// Report that we are going up/down
|
// Report that we are going up/down
|
||||||
// (from now on, the Up() process can be aborted).
|
// (from now on, the Up() process can be aborted).
|
||||||
// Abort if false is returned!
|
// Abort if false is returned!
|
||||||
@@ -77,6 +78,7 @@ class PPPDevice {
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
uint32 fMTU;
|
uint32 fMTU;
|
||||||
|
// always hold this value up-to-date!
|
||||||
bool fIsUp;
|
bool fIsUp;
|
||||||
|
|
||||||
status_t fInitStatus;
|
status_t fInitStatus;
|
||||||
|
|||||||
@@ -58,6 +58,8 @@ class PPPEncapsulator {
|
|||||||
{ return fUpRequested; }
|
{ return fUpRequested; }
|
||||||
|
|
||||||
virtual status_t Control(uint32 op, void *data, size_t length);
|
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)
|
void SetNext(PPPEncapsulator *next)
|
||||||
{ fNext = next; }
|
{ fNext = next; }
|
||||||
|
|||||||
@@ -36,17 +36,19 @@ struct ppp_module_info;
|
|||||||
|
|
||||||
class PPPInterface {
|
class PPPInterface {
|
||||||
friend class PPPStateMachine;
|
friend class PPPStateMachine;
|
||||||
|
friend class PPPManager;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// copies are not allowed!
|
// copies are not allowed!
|
||||||
PPPInterface(const PPPInterface& copy);
|
PPPInterface(const PPPInterface& copy);
|
||||||
PPPInterface& operator= (const PPPInterface& copy);
|
PPPInterface& operator= (const PPPInterface& copy);
|
||||||
|
|
||||||
public:
|
// only PPPManager may construct us!
|
||||||
PPPInterface(interface_id ID, driver_settings *settings,
|
PPPInterface(interface_id ID, driver_settings *settings,
|
||||||
PPPInterface *parent = NULL);
|
PPPInterface *parent = NULL);
|
||||||
~PPPInterface();
|
~PPPInterface();
|
||||||
|
|
||||||
|
public:
|
||||||
void Delete();
|
void Delete();
|
||||||
|
|
||||||
status_t InitCheck() const;
|
status_t InitCheck() const;
|
||||||
@@ -80,12 +82,12 @@ class PPPInterface {
|
|||||||
uint32 DisconnectAfterIdleSince() const
|
uint32 DisconnectAfterIdleSince() const
|
||||||
{ return fDisconnectAfterIdleSince; }
|
{ return fDisconnectAfterIdleSince; }
|
||||||
|
|
||||||
void SetMRU(uint32 MRU);
|
bool SetMRU(uint32 MRU);
|
||||||
uint32 MRU() const
|
uint32 MRU() const
|
||||||
{ return fMRU; }
|
{ return fMRU; }
|
||||||
// this is the smallest MRU that we and the peer have
|
// this is the smallest MRU that we and the peer have
|
||||||
void SetInterfaceMTU(uint32 interfaceMTU)
|
bool SetInterfaceMTU(uint32 interfaceMTU)
|
||||||
{ SetMRU(interfaceMTU - fHeaderLength); }
|
{ return SetMRU(interfaceMTU - fHeaderLength); }
|
||||||
uint32 InterfaceMTU() const
|
uint32 InterfaceMTU() const
|
||||||
{ return fInterfaceMTU; }
|
{ return fInterfaceMTU; }
|
||||||
// this is the MRU including encapsulator overhead
|
// this is the MRU including encapsulator overhead
|
||||||
@@ -125,11 +127,11 @@ class PPPInterface {
|
|||||||
bool IsMultilink() const
|
bool IsMultilink() const
|
||||||
{ return fIsMultilink; }
|
{ return fIsMultilink; }
|
||||||
|
|
||||||
void SetAutoRedial(bool autoredial = true);
|
void SetAutoRedial(bool autoRedial = true);
|
||||||
bool DoesAutoRedial() const
|
bool DoesAutoRedial() const
|
||||||
{ return fAutoRedial; }
|
{ return fAutoRedial; }
|
||||||
|
|
||||||
void SetDialOnDemand(bool dialondemand = true);
|
void SetDialOnDemand(bool dialOnDemand = true);
|
||||||
bool DoesDialOnDemand() const
|
bool DoesDialOnDemand() const
|
||||||
{ return fDialOnDemand; }
|
{ return fDialOnDemand; }
|
||||||
|
|
||||||
@@ -192,14 +194,12 @@ class PPPInterface {
|
|||||||
|
|
||||||
status_t StackControl(uint32 op, void *data);
|
status_t StackControl(uint32 op, void *data);
|
||||||
// stack routes ioctls to interface
|
// stack routes ioctls to interface
|
||||||
status_t ControlEachHandler(uint32 op, void *data, size_t length);
|
status_t StackControlEachHandler(uint32 op, void *data);
|
||||||
// this calls Control() with the given parameters for each handler
|
// this calls StackControl() with the given parameters for each handler
|
||||||
|
|
||||||
void CalculateInterfaceMTU();
|
void CalculateInterfaceMTU();
|
||||||
void CalculateBaudRate();
|
void CalculateBaudRate();
|
||||||
|
|
||||||
bool SetupDialOnDemand();
|
|
||||||
|
|
||||||
void Redial(uint32 delay);
|
void Redial(uint32 delay);
|
||||||
|
|
||||||
// multilink methods
|
// multilink methods
|
||||||
|
|||||||
@@ -40,6 +40,8 @@ class PPPLCPExtension {
|
|||||||
{ return fCode; }
|
{ return fCode; }
|
||||||
|
|
||||||
virtual status_t Control(uint32 op, void *data, size_t length);
|
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;
|
virtual status_t Receive(struct mbuf *packet, uint8 code) = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -42,6 +42,8 @@ class PPPOptionHandler {
|
|||||||
{ return fEnabled; }
|
{ return fEnabled; }
|
||||||
|
|
||||||
virtual status_t Control(uint32 op, void *data, size_t length);
|
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
|
// we want to send a configure request or we received a reply
|
||||||
virtual status_t AddToRequest(PPPConfigurePacket& request) = 0;
|
virtual status_t AddToRequest(PPPConfigurePacket& request) = 0;
|
||||||
|
|||||||
@@ -55,15 +55,12 @@ class PPPProtocol {
|
|||||||
{ return fUpRequested; }
|
{ return fUpRequested; }
|
||||||
|
|
||||||
virtual status_t Control(uint32 op, void *data, size_t length);
|
virtual status_t Control(uint32 op, void *data, size_t length);
|
||||||
|
virtual status_t StackControl(uint32 op, void *data);
|
||||||
virtual status_t SetupDialOnDemand();
|
// called by netstack (forwarded by PPPInterface)
|
||||||
// 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 bool Up() = 0;
|
virtual bool Up() = 0;
|
||||||
virtual bool Down() = 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
|
bool IsUp() const
|
||||||
{ return fConnectionStatus == PPP_ESTABLISHED_PHASE; }
|
{ return fConnectionStatus == PPP_ESTABLISHED_PHASE; }
|
||||||
bool IsDown() const
|
bool IsDown() const
|
||||||
|
|||||||
@@ -31,6 +31,16 @@ is_handler_allowed(T& handler, ppp_state state, ppp_phase phase)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// the list template does not support iterating over each item :(
|
||||||
|
// this template iterates over each item in an indexed list
|
||||||
|
template<class _LIST, class _FUNCTION>
|
||||||
|
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
|
// These are very simple send/receive_data functions with a timeout
|
||||||
// and there is a race condition beween has_data() and send/receive_data().
|
// and there is a race condition beween has_data() and send/receive_data().
|
||||||
|
|||||||
@@ -59,10 +59,6 @@ enum ppp_control_ops {
|
|||||||
PPPC_SET_ENABLED,
|
PPPC_SET_ENABLED,
|
||||||
PPPC_GET_SIMPLE_HANDLER_INFO,
|
PPPC_GET_SIMPLE_HANDLER_INFO,
|
||||||
// PPPOptionHandler and PPPLCPExtension
|
// 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
|
PPP_CONTROL_OPS_END = B_DEVICE_OP_CODES_END + 0xFFFF
|
||||||
@@ -119,7 +115,7 @@ typedef struct ppp_device_info {
|
|||||||
|
|
||||||
const driver_parameter *settings;
|
const driver_parameter *settings;
|
||||||
|
|
||||||
uint32 MTU, preferredMTU;
|
uint32 MTU;
|
||||||
uint32 inputTransferRate, outputTransferRate, outputBytesCount;
|
uint32 inputTransferRate, outputTransferRate, outputBytesCount;
|
||||||
} ppp_device_info;
|
} ppp_device_info;
|
||||||
typedef struct ppp_device_info_t {
|
typedef struct ppp_device_info_t {
|
||||||
|
|||||||
@@ -50,7 +50,6 @@ enum {
|
|||||||
PPP_UNHANDLED = PPP_ERROR_BASE,
|
PPP_UNHANDLED = PPP_ERROR_BASE,
|
||||||
// The packet does not belong to this handler.
|
// The packet does not belong to this handler.
|
||||||
// Do not delete the packet when you return this!
|
// Do not delete the packet when you return this!
|
||||||
// For PPPOptionHandler: the item is unrecognized
|
|
||||||
|
|
||||||
// return values of PPPInterface::Receive()
|
// return values of PPPInterface::Receive()
|
||||||
PPP_DISCARDED,
|
PPP_DISCARDED,
|
||||||
|
|||||||
@@ -25,6 +25,6 @@ R5KernelStaticLibrary kernelppp :
|
|||||||
cpp.cpp
|
cpp.cpp
|
||||||
|
|
||||||
# integrated modules
|
# integrated modules
|
||||||
|
_KPPPMRUHandler.cpp
|
||||||
_KPPPPFCHandler.cpp
|
_KPPPPFCHandler.cpp
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|||||||
@@ -56,7 +56,6 @@ PPPDevice::Control(uint32 op, void *data, size_t length)
|
|||||||
strcpy(info->name, Name());
|
strcpy(info->name, Name());
|
||||||
info->settings = Settings();
|
info->settings = Settings();
|
||||||
info->MTU = MTU();
|
info->MTU = MTU();
|
||||||
info->preferredMTU = PreferredMTU();
|
|
||||||
info->inputTransferRate = InputTransferRate();
|
info->inputTransferRate = InputTransferRate();
|
||||||
info->outputTransferRate = OutputTransferRate();
|
info->outputTransferRate = OutputTransferRate();
|
||||||
info->outputBytesCount = CountOutputBytes();
|
info->outputBytesCount = CountOutputBytes();
|
||||||
|
|||||||
@@ -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
|
status_t
|
||||||
PPPEncapsulator::SendToNext(struct mbuf *packet, uint16 protocol) const
|
PPPEncapsulator::SendToNext(struct mbuf *packet, uint16 protocol) const
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -32,6 +32,7 @@
|
|||||||
#include "settings_tools.h"
|
#include "settings_tools.h"
|
||||||
|
|
||||||
// internal modules
|
// internal modules
|
||||||
|
#include "_KPPPMRUHandler.h"
|
||||||
#include "_KPPPPFCHandler.h"
|
#include "_KPPPPFCHandler.h"
|
||||||
|
|
||||||
|
|
||||||
@@ -68,7 +69,7 @@ PPPInterface::PPPInterface(uint32 ID, driver_settings *settings,
|
|||||||
fDialRetriesLimit(0),
|
fDialRetriesLimit(0),
|
||||||
fIdleSince(0),
|
fIdleSince(0),
|
||||||
fMRU(1500),
|
fMRU(1500),
|
||||||
fInterfaceMTU(1498),
|
fInterfaceMTU(1500),
|
||||||
fHeaderLength(2),
|
fHeaderLength(2),
|
||||||
fAutoRedial(false),
|
fAutoRedial(false),
|
||||||
fDialOnDemand(false),
|
fDialOnDemand(false),
|
||||||
@@ -81,6 +82,12 @@ PPPInterface::PPPInterface(uint32 ID, driver_settings *settings,
|
|||||||
fDeleteCounter(0)
|
fDeleteCounter(0)
|
||||||
{
|
{
|
||||||
// add internal modules
|
// add internal modules
|
||||||
|
// MRU
|
||||||
|
_PPPMRUHandler *mruHandler =
|
||||||
|
new _PPPMRUHandler(*this);
|
||||||
|
if(mruHandler->InitCheck() != B_OK)
|
||||||
|
delete mruHandler;
|
||||||
|
// PFC
|
||||||
_PPPPFCHandler *pfcHandler =
|
_PPPPFCHandler *pfcHandler =
|
||||||
new _PPPPFCHandler(fLocalPFCState, fPeerPFCState, *this);
|
new _PPPPFCHandler(fLocalPFCState, fPeerPFCState, *this);
|
||||||
if(pfcHandler->InitCheck() != B_OK)
|
if(pfcHandler->InitCheck() != B_OK)
|
||||||
@@ -255,14 +262,19 @@ PPPInterface::InitCheck() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
bool
|
||||||
PPPInterface::SetMRU(uint32 MRU)
|
PPPInterface::SetMRU(uint32 MRU)
|
||||||
{
|
{
|
||||||
|
if(MRU > Device()->MTU() - 2)
|
||||||
|
return false;
|
||||||
|
|
||||||
LockerHelper locker(fLock);
|
LockerHelper locker(fLock);
|
||||||
|
|
||||||
fMRU = MRU;
|
fMRU = MRU;
|
||||||
|
|
||||||
CalculateInterfaceMTU();
|
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);
|
return child->Control(control->op, control->data, control->length);
|
||||||
} break;
|
} 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:
|
default:
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
}
|
}
|
||||||
@@ -460,7 +461,7 @@ PPPInterface::SetDevice(PPPDevice *device)
|
|||||||
|
|
||||||
fDevice = device;
|
fDevice = device;
|
||||||
|
|
||||||
fMRU = fDevice->MTU();
|
fMRU = fDevice->MTU() - 2;
|
||||||
|
|
||||||
CalculateInterfaceMTU();
|
CalculateInterfaceMTU();
|
||||||
CalculateBaudRate();
|
CalculateBaudRate();
|
||||||
@@ -727,47 +728,54 @@ PPPInterface::ChildAt(int32 index) const
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
PPPInterface::SetAutoRedial(bool autoredial = true)
|
PPPInterface::SetAutoRedial(bool autoRedial = true)
|
||||||
{
|
{
|
||||||
if(Mode() == PPP_CLIENT_MODE)
|
if(Mode() == PPP_CLIENT_MODE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
LockerHelper locker(fLock);
|
LockerHelper locker(fLock);
|
||||||
|
|
||||||
fAutoRedial = autoredial;
|
fAutoRedial = autoRedial;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
PPPInterface::SetDialOnDemand(bool dialondemand = true)
|
PPPInterface::SetDialOnDemand(bool dialOnDemand = true)
|
||||||
{
|
{
|
||||||
// All protocols must check if DialOnDemand was enabled/disabled after this
|
// All protocols must check if DialOnDemand was enabled/disabled after this
|
||||||
// interface went down. This is the only situation where a change is relevant.
|
// interface went down. This is the only situation where a change is relevant.
|
||||||
|
|
||||||
// only clients support DialOnDemand
|
// Only clients support DialOnDemand. Maybe no change needed.
|
||||||
if(Mode() != PPP_CLIENT_MODE)
|
if(Mode() != PPP_CLIENT_MODE || DoesDialOnDemand() == dialOnDemand)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
LockerHelper locker(fLock);
|
LockerHelper locker(fLock);
|
||||||
|
|
||||||
if(DoesDialOnDemand() && !dialondemand && State() != PPP_OPENED_STATE) {
|
fDialOnDemand = dialOnDemand;
|
||||||
// as long as the protocols were not configured we can just delete us
|
|
||||||
Delete();
|
// 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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fDialOnDemand = dialondemand;
|
|
||||||
|
|
||||||
// check if we need to register/unregister
|
// check if we need to register/unregister
|
||||||
if(fDialOnDemand) {
|
if(dialOnDemand) {
|
||||||
RegisterInterface();
|
RegisterInterface();
|
||||||
if(Ifnet())
|
if(Ifnet())
|
||||||
Ifnet()->if_flags |= IFF_RUNNING;
|
Ifnet()->if_flags |= IFF_RUNNING;
|
||||||
} else if(!fDialOnDemand && Phase() < PPP_ESTABLISHED_PHASE) {
|
} else if(!dialOnDemand && Phase() < PPP_ESTABLISHED_PHASE) {
|
||||||
UnregisterInterface();
|
UnregisterInterface();
|
||||||
|
|
||||||
// if we are already down we must delete us
|
// if we are already down we must delete us
|
||||||
if(Phase() == PPP_DOWN_PHASE)
|
if(State() == PPP_INITIAL_STATE && Phase() == PPP_DOWN_PHASE)
|
||||||
Delete();
|
Delete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1414,7 +1422,6 @@ PPPInterface::RegisterInterface()
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
CalculateBaudRate();
|
CalculateBaudRate();
|
||||||
SetupDialOnDemand();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -1443,7 +1450,7 @@ PPPInterface::UnregisterInterface()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// stack routes ioctls to interface
|
// called by PPPManager: manager routes stack ioctls to interface
|
||||||
status_t
|
status_t
|
||||||
PPPInterface::StackControl(uint32 op, void *data)
|
PPPInterface::StackControl(uint32 op, void *data)
|
||||||
{
|
{
|
||||||
@@ -1452,75 +1459,59 @@ PPPInterface::StackControl(uint32 op, void *data)
|
|||||||
|
|
||||||
switch(op) {
|
switch(op) {
|
||||||
default:
|
default:
|
||||||
return B_BAD_VALUE;
|
return StackControlEachHandler(op, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// used by ControlEachHandler()
|
||||||
|
template<class T>
|
||||||
|
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.
|
// This calls Control() with the given parameters for each handler.
|
||||||
// Return values:
|
// Return values:
|
||||||
// B_OK: all handlers returned B_OK
|
// B_OK: all handlers returned B_OK
|
||||||
// B_BAD_VALUE: no handler was found
|
// B_BAD_VALUE: no handler was found
|
||||||
// any other value: the error value that was returned by the last handler that failed
|
// any other value: the error value that was returned by the last handler that failed
|
||||||
status_t
|
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;
|
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();
|
PPPEncapsulator *encapsulator = FirstEncapsulator();
|
||||||
for(; encapsulator; encapsulator = encapsulator->Next()) {
|
for(; encapsulator; encapsulator = encapsulator->Next()) {
|
||||||
tmp = encapsulator->Control(op, data, length);
|
tmp = encapsulator->StackControl(op, data);
|
||||||
if(tmp == B_OK && result == B_BAD_VALUE)
|
if(tmp == B_OK && result == B_BAD_VALUE)
|
||||||
result = B_OK;
|
result = B_OK;
|
||||||
else if(tmp != B_BAD_VALUE)
|
else if(tmp != B_BAD_VALUE)
|
||||||
result = tmp;
|
result = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
// option handlers
|
ForEachItem(fProtocols, CallStackControl<PPPProtocol>(op, data, result));
|
||||||
PPPOptionHandler *optionHandler;
|
ForEachItem(LCP().fLCPExtensions,
|
||||||
for(index = 0; index < LCP().CountOptionHandlers(); index++) {
|
CallStackControl<PPPLCPExtension>(op, data, result));
|
||||||
optionHandler = LCP().OptionHandlerAt(index);
|
ForEachItem(LCP().fOptionHandlers,
|
||||||
if(!optionHandler)
|
CallStackControl<PPPOptionHandler>(op, data, result));
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -1531,9 +1522,7 @@ PPPInterface::CalculateInterfaceMTU()
|
|||||||
{
|
{
|
||||||
fInterfaceMTU = fMRU;
|
fInterfaceMTU = fMRU;
|
||||||
|
|
||||||
// sum all headers
|
// sum all headers (the protocol field is not counted)
|
||||||
fHeaderLength = sizeof(uint16);
|
|
||||||
|
|
||||||
PPPEncapsulator *encapsulator = fFirstEncapsulator;
|
PPPEncapsulator *encapsulator = fFirstEncapsulator;
|
||||||
for(; encapsulator; encapsulator = encapsulator->Next())
|
for(; encapsulator; encapsulator = encapsulator->Next())
|
||||||
fHeaderLength += encapsulator->Overhead();
|
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
|
void
|
||||||
PPPInterface::Redial(uint32 delay)
|
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
|
status_t
|
||||||
interface_deleter_thread(void *data)
|
interface_deleter_thread(void *data)
|
||||||
{
|
{
|
||||||
delete (PPPInterface*) data;
|
PPPManager((PPPInterface*) data);
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,9 +18,6 @@
|
|||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
|
||||||
|
|
||||||
#define PPP_PROTOCOL_OVERHEAD 2
|
|
||||||
|
|
||||||
|
|
||||||
PPPLCP::PPPLCP(PPPInterface& interface)
|
PPPLCP::PPPLCP(PPPInterface& interface)
|
||||||
: PPPProtocol("LCP", PPP_ESTABLISHMENT_PHASE, PPP_LCP_PROTOCOL,
|
: PPPProtocol("LCP", PPP_ESTABLISHMENT_PHASE, PPP_LCP_PROTOCOL,
|
||||||
AF_UNSPEC, interface, NULL, PPP_ALWAYS_ALLOWED),
|
AF_UNSPEC, interface, NULL, PPP_ALWAYS_ALLOWED),
|
||||||
@@ -177,7 +174,7 @@ PPPLCP::LCPExtensionFor(uint8 code, int32 *start = NULL) const
|
|||||||
uint32
|
uint32
|
||||||
PPPLCP::AdditionalOverhead() const
|
PPPLCP::AdditionalOverhead() const
|
||||||
{
|
{
|
||||||
uint32 overhead = PPP_PROTOCOL_OVERHEAD;
|
uint32 overhead = 0;
|
||||||
|
|
||||||
if(Target())
|
if(Target())
|
||||||
overhead += Target()->Overhead();
|
overhead += Target()->Overhead();
|
||||||
|
|||||||
@@ -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
|
void
|
||||||
PPPLCPExtension::Reset()
|
PPPLCPExtension::Reset()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -68,3 +68,15 @@ PPPOptionHandler::Control(uint32 op, void *data, size_t length)
|
|||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
PPPOptionHandler::StackControl(uint32 op, void *data)
|
||||||
|
{
|
||||||
|
switch(op) {
|
||||||
|
default:
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|||||||
@@ -105,8 +105,13 @@ PPPProtocol::Control(uint32 op, void *data, size_t length)
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
PPPProtocol::SetupDialOnDemand()
|
PPPProtocol::StackControl(uint32 op, void *data)
|
||||||
{
|
{
|
||||||
|
switch(op) {
|
||||||
|
default:
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -313,7 +313,10 @@ PPPStateMachine::DownEvent(PPPInterface& interface)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Interface().SetMRU(MRU);
|
if(MRU == 0)
|
||||||
|
Interface().SetMRU(1500);
|
||||||
|
else
|
||||||
|
Interface().SetMRU(MRU);
|
||||||
|
|
||||||
if(count == 0) {
|
if(count == 0) {
|
||||||
locker.UnlockNow();
|
locker.UnlockNow();
|
||||||
@@ -1341,7 +1344,7 @@ PPPStateMachine::RCREvent(struct mbuf *packet)
|
|||||||
|
|
||||||
result = handler->ParseRequest(request, index, nak, reject);
|
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
|
// the request contains a value that has been sent more than
|
||||||
// once or the value is corrupted
|
// once or the value is corrupted
|
||||||
m_freem(packet);
|
m_freem(packet);
|
||||||
@@ -1359,7 +1362,7 @@ PPPStateMachine::RCREvent(struct mbuf *packet)
|
|||||||
result = handler->ParseRequest(request, request.CountItems(),
|
result = handler->ParseRequest(request, request.CountItems(),
|
||||||
nak, reject);
|
nak, reject);
|
||||||
|
|
||||||
if(result != B_OK && result != PPP_UNHANDLED) {
|
if(result != B_OK) {
|
||||||
// the request contains a value that has been sent more than
|
// the request contains a value that has been sent more than
|
||||||
// once or the value is corrupted
|
// once or the value is corrupted
|
||||||
m_freem(packet);
|
m_freem(packet);
|
||||||
|
|||||||
@@ -0,0 +1,140 @@
|
|||||||
|
//----------------------------------------------------------------------
|
||||||
|
// This software is part of the OpenBeOS distribution and is covered
|
||||||
|
// by the OpenBeOS license.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2003 Waldemar Kornewald, [email protected]
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include "_KPPPMRUHandler.h"
|
||||||
|
|
||||||
|
#include <KPPPConfigurePacket.h>
|
||||||
|
#include <KPPPDevice.h>
|
||||||
|
|
||||||
|
#include <netinet/in.h>
|
||||||
|
|
||||||
|
#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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
//----------------------------------------------------------------------
|
||||||
|
// This software is part of the OpenBeOS distribution and is covered
|
||||||
|
// by the OpenBeOS license.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2003 Waldemar Kornewald, [email protected]
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifndef __K_PPP_MRU_HANDLER__H
|
||||||
|
#define __K_PPP_MRU_HANDLER__H
|
||||||
|
|
||||||
|
#include <KPPPOptionHandler.h>
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
Reference in New Issue
Block a user