Finished:
- PPPDevice - PPPEncapsulator - PPPOptionHandler - PPPProtocol Added SendCodeReject implementation (though, I am not sure if it really works because I am not familiar with mbufs). Fixed some bugs. Changed the manager interface (there are no pointers to classes anymore). Some minor changes. TODO for libkernelppp.a: - finish PPPLCP - finish PPPConfigurePacket git-svn-id: file:///srv/svn/repos/haiku/trunk/current@4400 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -44,7 +44,7 @@ class PPPConfigurePacket {
|
|||||||
int32 CountItems() const;
|
int32 CountItems() const;
|
||||||
configure_item *ItemAt(int32 index) const;
|
configure_item *ItemAt(int32 index) const;
|
||||||
|
|
||||||
mbuf *ToMbuf();
|
mbuf *ToMbuf(uint32 reserve = 0, uint32 maxSize = 0);
|
||||||
// the user is responsible for freeing the mbuf
|
// the user is responsible for freeing the mbuf
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -11,29 +11,35 @@
|
|||||||
#include <Errors.h>
|
#include <Errors.h>
|
||||||
|
|
||||||
|
|
||||||
|
typedef uint32 interface_id;
|
||||||
|
|
||||||
|
// various constants
|
||||||
|
#define PPP_PULSE_RATE 750000
|
||||||
|
|
||||||
// settings keys
|
// settings keys
|
||||||
#define PPP_MODE_KEY "Mode"
|
#define PPP_DISONNECT_AFTER_IDLE_SINCE_KEY "DisonnectAfterIdleSince"
|
||||||
#define PPP_DIAL_ON_DEMAND_KEY "DialOnDemand"
|
#define PPP_MODE_KEY "Mode"
|
||||||
#define PPP_AUTO_REDIAL_KEY "AutoRedial"
|
#define PPP_DIAL_ON_DEMAND_KEY "DialOnDemand"
|
||||||
#define PPP_LOAD_MODULE_KEY "LoadModule"
|
#define PPP_AUTO_REDIAL_KEY "AutoRedial"
|
||||||
#define PPP_PROTOCOL_KEY "Protocol"
|
#define PPP_LOAD_MODULE_KEY "LoadModule"
|
||||||
#define PPP_DEVICE_KEY "Device"
|
#define PPP_PROTOCOL_KEY "Protocol"
|
||||||
#define PPP_AUTHENTICATOR_KEY "Authenticator"
|
#define PPP_DEVICE_KEY "Device"
|
||||||
#define PPP_PEER_AUTHENTICATOR_KEY "Peer-Authenticator"
|
#define PPP_AUTHENTICATOR_KEY "Authenticator"
|
||||||
#define PPP_MULTILINK_KEY "Multilink-Protocol"
|
#define PPP_PEER_AUTHENTICATOR_KEY "Peer-Authenticator"
|
||||||
|
#define PPP_MULTILINK_KEY "Multilink-Protocol"
|
||||||
|
|
||||||
// settings values
|
// settings values
|
||||||
#define PPP_CLIENT_MODE_VALUE "Client"
|
#define PPP_CLIENT_MODE_VALUE "Client"
|
||||||
#define PPP_SERVER_MODE_VALUE "Server"
|
#define PPP_SERVER_MODE_VALUE "Server"
|
||||||
|
|
||||||
// path defines
|
// path defines
|
||||||
#define PPP_MODULES_PATH "network/ppp-modules"
|
#define PPP_MODULES_PATH "network/ppp-modules"
|
||||||
|
|
||||||
// built-in protocols
|
// built-in protocols
|
||||||
#define PPP_LCP_PROTOCOL 0xC021
|
#define PPP_LCP_PROTOCOL 0xC021
|
||||||
|
|
||||||
|
|
||||||
#define PPP_ERROR_BASE B_ERRORS_END
|
#define PPP_ERROR_BASE B_ERRORS_END
|
||||||
|
|
||||||
// return values for Send()/Receive() methods in addition to B_ERROR and B_OK
|
// return values for Send()/Receive() methods in addition to B_ERROR and B_OK
|
||||||
// PPP_UNHANDLED is also used by PPPOptionHandler
|
// PPP_UNHANDLED is also used by PPPOptionHandler
|
||||||
|
|||||||
@@ -13,11 +13,11 @@
|
|||||||
|
|
||||||
class PPPDevice {
|
class PPPDevice {
|
||||||
public:
|
public:
|
||||||
PPPDevice(const char *fName, uint32 overhead, PPPInterface *interface,
|
PPPDevice(const char *name, uint32 overhead, PPPInterface *interface,
|
||||||
driver_parameter *settings);
|
driver_parameter *settings);
|
||||||
virtual ~PPPDevice();
|
virtual ~PPPDevice();
|
||||||
|
|
||||||
virtual status_t InitCheck() const = 0;
|
virtual status_t InitCheck() const;
|
||||||
|
|
||||||
const char *Name() const
|
const char *Name() const
|
||||||
{ return fName; }
|
{ return fName; }
|
||||||
@@ -58,18 +58,20 @@ class PPPDevice {
|
|||||||
// This will pass the packet to the interface's queue.
|
// This will pass the packet to the interface's queue.
|
||||||
// Do not call Interface::ReceiveFromDevice directly
|
// Do not call Interface::ReceiveFromDevice directly
|
||||||
// if this can block a Send()!
|
// if this can block a Send()!
|
||||||
|
|
||||||
|
virtual void Pulse();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// 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!
|
||||||
bool UpStarted();
|
bool UpStarted() const;
|
||||||
bool DownStarted();
|
bool DownStarted() const;
|
||||||
|
|
||||||
// report up/down events
|
// report up/down events
|
||||||
void UpEvent();
|
void UpFailedEvent() const;
|
||||||
void UpFailedEvent();
|
void UpEvent() const;
|
||||||
void DownEvent();
|
void DownEvent() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool fIsUp;
|
bool fIsUp;
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ class PPPEncapsulator {
|
|||||||
int32 flags = PPP_NO_FLAGS);
|
int32 flags = PPP_NO_FLAGS);
|
||||||
virtual ~PPPEncapsulator();
|
virtual ~PPPEncapsulator();
|
||||||
|
|
||||||
virtual status_t InitCheck() const = 0;
|
virtual status_t InitCheck() const;
|
||||||
|
|
||||||
const char *Name() const
|
const char *Name() const
|
||||||
{ return fName; }
|
{ return fName; }
|
||||||
@@ -46,7 +46,8 @@ class PPPEncapsulator {
|
|||||||
bool IsEnabled() const
|
bool IsEnabled() const
|
||||||
{ return fEnabled; }
|
{ return fEnabled; }
|
||||||
|
|
||||||
void SetUpRequested(bool requested = true);
|
void SetUpRequested(bool requested = true)
|
||||||
|
{ fUpRequested = requested; }
|
||||||
bool IsUpRequested() const
|
bool IsUpRequested() const
|
||||||
{ return fUpRequested; }
|
{ return fUpRequested; }
|
||||||
|
|
||||||
@@ -71,10 +72,12 @@ class PPPEncapsulator {
|
|||||||
virtual status_t Send(mbuf *packet, uint16 protocol) = 0;
|
virtual status_t Send(mbuf *packet, uint16 protocol) = 0;
|
||||||
virtual status_t Receive(mbuf *packet, uint16 protocol) = 0;
|
virtual status_t Receive(mbuf *packet, uint16 protocol) = 0;
|
||||||
|
|
||||||
status_t SendToNext(mbuf *packet, uint16 protocol);
|
status_t SendToNext(mbuf *packet, uint16 protocol) const;
|
||||||
// this will send your packet to the next (up) encapsulator
|
// this will send your packet to the next (up) encapsulator
|
||||||
// if there is no next encapsulator (==NULL), it will
|
// if there is no next encapsulator (==NULL), it will
|
||||||
// call the interface's SendToDevice function
|
// call the interface's SendToDevice function
|
||||||
|
|
||||||
|
virtual void Pulse();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void UpStarted();
|
void UpStarted();
|
||||||
@@ -91,10 +94,11 @@ class PPPEncapsulator {
|
|||||||
private:
|
private:
|
||||||
char *fName;
|
char *fName;
|
||||||
PPP_ENCAPSULATION_LEVEL fLevel;
|
PPP_ENCAPSULATION_LEVEL fLevel;
|
||||||
|
uint16 fProtocol;
|
||||||
|
int32 fAddressFamily;
|
||||||
PPPInterface *fInterface;
|
PPPInterface *fInterface;
|
||||||
driver_parameter *fSettings;
|
driver_parameter *fSettings;
|
||||||
uint16 fProtocol;
|
int32 fFlags;
|
||||||
int32 fAddressFamily, fFlags;
|
|
||||||
|
|
||||||
PPPEncapsulator *fNext;
|
PPPEncapsulator *fNext;
|
||||||
|
|
||||||
|
|||||||
@@ -34,13 +34,17 @@ class PPPInterface {
|
|||||||
PPPInterface& operator= (const PPPInterface& copy);
|
PPPInterface& operator= (const PPPInterface& copy);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PPPInterface(driver_settings *settings, PPPInterface *parent = NULL);
|
PPPInterface(interface_id ID, driver_settings *settings,
|
||||||
|
PPPInterface *parent = NULL);
|
||||||
~PPPInterface();
|
~PPPInterface();
|
||||||
|
|
||||||
void Delete();
|
void Delete();
|
||||||
|
|
||||||
status_t InitCheck() const;
|
status_t InitCheck() const;
|
||||||
|
|
||||||
|
interface_id ID() const
|
||||||
|
{ return fID; }
|
||||||
|
|
||||||
driver_settings* Settings()
|
driver_settings* Settings()
|
||||||
{ return fSettings; }
|
{ return fSettings; }
|
||||||
|
|
||||||
@@ -55,6 +59,12 @@ class PPPInterface {
|
|||||||
struct ifq *InQueue() const
|
struct ifq *InQueue() const
|
||||||
{ return fInQueue; }
|
{ return fInQueue; }
|
||||||
|
|
||||||
|
// idle handling
|
||||||
|
bigtime_t IdleSince() const
|
||||||
|
{ return fIdleSince; }
|
||||||
|
bigtime_t DisconnectAfterIdleSince() const
|
||||||
|
{ return fDisconnectAfterIdleSince; }
|
||||||
|
|
||||||
void SetLinkMTU(uint32 linkMTU);
|
void SetLinkMTU(uint32 linkMTU);
|
||||||
uint32 LinkMTU() const
|
uint32 LinkMTU() const
|
||||||
{ return fLinkMTU; }
|
{ return fLinkMTU; }
|
||||||
@@ -142,6 +152,7 @@ class PPPInterface {
|
|||||||
bool UnregisterInterface();
|
bool UnregisterInterface();
|
||||||
|
|
||||||
void CalculateMRU();
|
void CalculateMRU();
|
||||||
|
void CalculateBaudRate();
|
||||||
|
|
||||||
void Redial();
|
void Redial();
|
||||||
|
|
||||||
@@ -150,7 +161,9 @@ class PPPInterface {
|
|||||||
{ fParent = parent; }
|
{ fParent = parent; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
driver_parameter *fSettings;
|
interface_id fID;
|
||||||
|
// the manager assigns an ID to every interface
|
||||||
|
driver_settings *fSettings;
|
||||||
PPPStateMachine fStateMachine;
|
PPPStateMachine fStateMachine;
|
||||||
PPPLCP fLCP;
|
PPPLCP fLCP;
|
||||||
PPPReportManager fReportManager;
|
PPPReportManager fReportManager;
|
||||||
@@ -164,6 +177,7 @@ class PPPInterface {
|
|||||||
|
|
||||||
ppp_manager_info *fManager;
|
ppp_manager_info *fManager;
|
||||||
|
|
||||||
|
bigtime_t fIdleSince, fDisconnectAfterIdleSince;
|
||||||
uint32 fLinkMTU, fMRU, fHeaderLength;
|
uint32 fLinkMTU, fMRU, fHeaderLength;
|
||||||
|
|
||||||
PPPInterface *fParent;
|
PPPInterface *fParent;
|
||||||
|
|||||||
@@ -41,10 +41,15 @@ class PPPLCP : public PPPProtocol {
|
|||||||
{ return fOptionHandlers.CountItems(); }
|
{ return fOptionHandlers.CountItems(); }
|
||||||
PPPOptionHandler *OptionHandlerAt(int32 index) const;
|
PPPOptionHandler *OptionHandlerAt(int32 index) const;
|
||||||
|
|
||||||
|
PPPEncapsulator *Target() const
|
||||||
|
{ return fTarget; }
|
||||||
void SetTarget(PPPEncapsulator *target)
|
void SetTarget(PPPEncapsulator *target)
|
||||||
{ fTarget = target; }
|
{ fTarget = target; }
|
||||||
// if target != all packtes will be passed to the encapsulator
|
// if target != all packtes will be passed to the encapsulator
|
||||||
// instead of the interface/device
|
// instead of the interface/device
|
||||||
|
|
||||||
|
uint32 AdditionalOverhead() const;
|
||||||
|
// the overhead caused by the target, the device, and the interface
|
||||||
|
|
||||||
private:
|
private:
|
||||||
List<PPPOptionHandler*> fOptionHandlers;
|
List<PPPOptionHandler*> fOptionHandlers;
|
||||||
|
|||||||
@@ -13,25 +13,30 @@
|
|||||||
|
|
||||||
#define PPP_MANAGER_MODULE_NAME "network/interfaces/ppp"
|
#define PPP_MANAGER_MODULE_NAME "network/interfaces/ppp"
|
||||||
|
|
||||||
|
// 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_manager_info {
|
typedef struct ppp_manager_info {
|
||||||
kernel_net_module_info knminfo;
|
kernel_net_module_info knminfo;
|
||||||
|
|
||||||
// when you want to iterate through interfaces you should use locking
|
uint32 (*create_interface)(driver_settings *settings, interface_id parent);
|
||||||
void (*lock)();
|
// you should always create interfaces using this function
|
||||||
void (*unlock)();
|
void (*delete_interface)(interface_id ID);
|
||||||
|
// this marks the interface for deletion
|
||||||
|
|
||||||
ifnet* (*add_interface)(PPPInterface *interface);
|
ifnet* (*register_interface)(interface_id ID);
|
||||||
bool (*remove_interface)(PPPInterface *interface);
|
bool (*unregister_interface)(interface_id ID);
|
||||||
|
|
||||||
int32 (*count_interfaces)(int32 index);
|
status_t (*control)(interface_id ID, uint32 op, void *data, size_t length);
|
||||||
|
|
||||||
PPPInterface *(*get_interface_at)(int32 index);
|
status_t (*get_interfaces)(interface_id **interfaces, uint32 *count,
|
||||||
void (*put_interface)(PPPInterface *interface);
|
PPP_INTERFACE_FILTER filter = PPP_REGISTERED_INTERFACES);
|
||||||
|
// the user is responsible for free()'ing the interface_id array
|
||||||
void (*delete_interface)(PPPInterface *interface);
|
} ppp_manager_info;
|
||||||
// this deletes the interface when it is not needed anymore
|
|
||||||
} ppp_manager;
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ class PPPOptionHandler {
|
|||||||
driver_parameter *settings);
|
driver_parameter *settings);
|
||||||
virtual ~PPPOptionHandler();
|
virtual ~PPPOptionHandler();
|
||||||
|
|
||||||
virtual status_t InitCheck() = 0;
|
virtual status_t InitCheck() const;
|
||||||
|
|
||||||
void SetEnabled(bool enabled = true);
|
void SetEnabled(bool enabled = true);
|
||||||
bool IsEnabled() const
|
bool IsEnabled() const
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ class PPPProtocol {
|
|||||||
driver_parameter *settings, int32 flags = PPP_NO_FLAGS);
|
driver_parameter *settings, int32 flags = PPP_NO_FLAGS);
|
||||||
virtual ~PPPProtocol();
|
virtual ~PPPProtocol();
|
||||||
|
|
||||||
virtual status_t InitCheck() const = 0;
|
virtual status_t InitCheck() const;
|
||||||
|
|
||||||
const char *Name() const
|
const char *Name() const
|
||||||
{ return fName; }
|
{ return fName; }
|
||||||
@@ -41,7 +41,8 @@ class PPPProtocol {
|
|||||||
bool IsEnabled() const
|
bool IsEnabled() const
|
||||||
{ return fEnabled; }
|
{ return fEnabled; }
|
||||||
|
|
||||||
void SetUpRequested(bool requested = true);
|
void SetUpRequested(bool requested = true)
|
||||||
|
{ fUpRequested = requested; }
|
||||||
bool IsUpRequested() const
|
bool IsUpRequested() const
|
||||||
{ return fUpRequested; }
|
{ return fUpRequested; }
|
||||||
|
|
||||||
@@ -60,6 +61,8 @@ class PPPProtocol {
|
|||||||
|
|
||||||
virtual status_t Send(mbuf *packet) = 0;
|
virtual status_t Send(mbuf *packet) = 0;
|
||||||
virtual status_t Receive(mbuf *packet) = 0;
|
virtual status_t Receive(mbuf *packet) = 0;
|
||||||
|
|
||||||
|
virtual void Pulse();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void UpStarted();
|
void UpStarted();
|
||||||
@@ -74,9 +77,10 @@ class PPPProtocol {
|
|||||||
char *name;
|
char *name;
|
||||||
PPP_PHASE fPhase;
|
PPP_PHASE fPhase;
|
||||||
uint16 fProtocol;
|
uint16 fProtocol;
|
||||||
int32 fAddressFamily, fFlags;
|
int32 fAddressFamily;
|
||||||
PPPInterface fInterface;
|
PPPInterface fInterface;
|
||||||
driver_parameter fSettings;
|
driver_parameter fSettings;
|
||||||
|
int32 fFlags;
|
||||||
|
|
||||||
bool fEnabled;
|
bool fEnabled;
|
||||||
bool fUpRequested;
|
bool fUpRequested;
|
||||||
|
|||||||
@@ -26,7 +26,8 @@ enum PPP_REPORT_FLAGS {
|
|||||||
enum PPP_REPORT_TYPE {
|
enum PPP_REPORT_TYPE {
|
||||||
PPP_DESTRUCTION_REPORT = 0,
|
PPP_DESTRUCTION_REPORT = 0,
|
||||||
// the interface is being destroyed (no code is needed)
|
// the interface is being destroyed (no code is needed)
|
||||||
PPP_CONNECTION_REPORT = 1
|
PPP_CONNECTION_REPORT = 1,
|
||||||
|
PPP_AUTHENTICATION_REPORT = 2
|
||||||
};
|
};
|
||||||
|
|
||||||
// report codes (type-specific)
|
// report codes (type-specific)
|
||||||
@@ -36,10 +37,13 @@ enum PPP_CONNECTION_REPORT_CODES {
|
|||||||
PPP_REPORT_DOWN_SUCCESSFUL = 2,
|
PPP_REPORT_DOWN_SUCCESSFUL = 2,
|
||||||
PPP_REPORT_UP_ABORTED = 3,
|
PPP_REPORT_UP_ABORTED = 3,
|
||||||
PPP_REPORT_DEVICE_UP_FAILED = 4,
|
PPP_REPORT_DEVICE_UP_FAILED = 4,
|
||||||
PPP_REPORT_AUTHENTICATION_FAILED = 5,
|
PPP_REPORT_AUTHENTICATION_SUCCESSFUL = 5,
|
||||||
PPP_REPORT_CONNECTION_LOST = 6
|
PPP_REPORT_PEER_AUTHENTICATION_SUCCESSFUL = 6,
|
||||||
|
PPP_REPORT_AUTHENTICATION_FAILED = 7,
|
||||||
|
PPP_REPORT_CONNECTION_LOST = 8
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
typedef struct ppp_report_packet {
|
typedef struct ppp_report_packet {
|
||||||
int32 type;
|
int32 type;
|
||||||
int32 code;
|
int32 code;
|
||||||
|
|||||||
@@ -6,3 +6,127 @@
|
|||||||
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
#include "KPPPDevice.h"
|
#include "KPPPDevice.h"
|
||||||
|
|
||||||
|
|
||||||
|
PPPDevice::PPPDevice(const char *name, uint32 overhead, PPPInterface *interface,
|
||||||
|
driver_parameter *settings)
|
||||||
|
: fOverhead(overhead), fInterface(interface),
|
||||||
|
fSettings(settings)
|
||||||
|
{
|
||||||
|
fName = name ? strdup(name) : NULL;
|
||||||
|
|
||||||
|
SetMTU(PreferredMTU());
|
||||||
|
|
||||||
|
if(interface)
|
||||||
|
interface->SetDevice(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PPPDevice::~PPPDevice()
|
||||||
|
{
|
||||||
|
free(fName);
|
||||||
|
|
||||||
|
if(Interface())
|
||||||
|
Interface()->SetDevice(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
PPPDevice::InitCheck() const
|
||||||
|
{
|
||||||
|
if(!Interface() || !Settings())
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
PPPDevice::Control(uint32 op, void *data, size_t length)
|
||||||
|
{
|
||||||
|
switch(op) {
|
||||||
|
// TODO:
|
||||||
|
// get:
|
||||||
|
// - name
|
||||||
|
// - mtu (+ preferred)
|
||||||
|
// - status
|
||||||
|
// - transfer rates
|
||||||
|
|
||||||
|
default:
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t
|
||||||
|
PPPDevice::PassToInterface(mbuf *packet)
|
||||||
|
{
|
||||||
|
if(!Interface() || !Interface()->InQueue())
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
IFQ_ENQUEUE(Interface()->InQueue(), packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PPPDevice::Pulse()
|
||||||
|
{
|
||||||
|
// do nothing by default
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
PPPDevice::UpStarted() const
|
||||||
|
{
|
||||||
|
if(!Interface())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return Interface()->StateMachine().TLSNotify();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
PPPDevice::DownStarted() const
|
||||||
|
{
|
||||||
|
if(!Interface())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return Interface()->StateMachine().TLFNotify();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PPPDevice::UpFailedEvent()
|
||||||
|
{
|
||||||
|
fIsUp = false;
|
||||||
|
|
||||||
|
if(!Interface())
|
||||||
|
return;
|
||||||
|
|
||||||
|
Interface()->StateMachine().UpFailedEvent();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PPPDevice::UpEvent()
|
||||||
|
{
|
||||||
|
fIsUp = true;
|
||||||
|
|
||||||
|
if(!Interface())
|
||||||
|
return;
|
||||||
|
|
||||||
|
Interface()->StateMachine().UpEvent();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PPPDevice::DownEvent()
|
||||||
|
{
|
||||||
|
fIsUp = false;
|
||||||
|
|
||||||
|
if(!Interface())
|
||||||
|
return;
|
||||||
|
|
||||||
|
Interface()->StateMachine().DownEvent();
|
||||||
|
}
|
||||||
|
|||||||
@@ -6,3 +6,143 @@
|
|||||||
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
#include "KPPPEncapsulator.h"
|
#include "KPPPEncapsulator.h"
|
||||||
|
|
||||||
|
|
||||||
|
PPPEncapsulator::PPPEncapsulator(const char *name, PPP_ENCAPSULATION_LEVEL level,
|
||||||
|
uint16 protocol, int32 addressFamily, uint32 overhead,
|
||||||
|
PPPInterface *interface, driver_parameter *settings,
|
||||||
|
int32 flags = PPP_NO_FLAGS)
|
||||||
|
: fOverhead(overhead), fLevel(level), fProtocol(protocol),
|
||||||
|
fAddressFamily(addressFamily), fInterface(interface),
|
||||||
|
fSettings(settings), fFlags(flags), fEnabled(true),
|
||||||
|
fUpRequested(true), fConnectionStatus(PPP_DOWN_PHASE)
|
||||||
|
{
|
||||||
|
fName = name ? strdup(name) : NULL;
|
||||||
|
|
||||||
|
if(interface)
|
||||||
|
interface->AddEncapsulator(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PPPEncapsulator::~PPPEncapsulator()
|
||||||
|
{
|
||||||
|
free(fName);
|
||||||
|
|
||||||
|
if(Interface())
|
||||||
|
Interface()->RemoveEncapsulator(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
PPPEncapsulator::InitCheck() const
|
||||||
|
{
|
||||||
|
if(!Interface() || !Settings())
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PPPEncapsulator::SetEnabled(bool enabled = true)
|
||||||
|
{
|
||||||
|
fEnabled = enabled;
|
||||||
|
|
||||||
|
if(!Interface())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(!enabled) {
|
||||||
|
if(IsUp() || IsGoingUp()))
|
||||||
|
Down();
|
||||||
|
} else if(!IsUp() && !IsGoingUp() && IsUpRequested() && Interface()->IsUp())
|
||||||
|
Up();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
PPPEncapsulator::Control(uint32 op, void *data, size_t length)
|
||||||
|
{
|
||||||
|
switch(op) {
|
||||||
|
// TODO:
|
||||||
|
// get:
|
||||||
|
// - name
|
||||||
|
// - level, protocol, address family, overhead
|
||||||
|
// - status (Is(Going)Up/Down/UpRequested/Enabled)
|
||||||
|
// set:
|
||||||
|
// - enabled
|
||||||
|
|
||||||
|
default:
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
PPPEncapsulator::SendToNext(mbuf *packet, uint16 protocol) const
|
||||||
|
{
|
||||||
|
if(Next())
|
||||||
|
return Next()->Send(packet, protocol);
|
||||||
|
else if(Interface())
|
||||||
|
return Interface()->SendToDevice(packet, protocol);
|
||||||
|
else
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PPPEncapsulator::Pulse()
|
||||||
|
{
|
||||||
|
// do nothing by default
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PPPEncapsulator::UpStarted()
|
||||||
|
{
|
||||||
|
fConnectionStatus = PPP_ESTABLISHMENT_PHASE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PPPEncapsulator::DownStarted()
|
||||||
|
{
|
||||||
|
fConnectionStatus = PPP_TERMINATION_PHASE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PPPEncapsulator::UpFailedEvent()
|
||||||
|
{
|
||||||
|
fConnectionStatus = PPP_DOWN_PHASE;
|
||||||
|
|
||||||
|
if(!Interface())
|
||||||
|
return;
|
||||||
|
|
||||||
|
Interface()->StateMachine().UpFailedEvent(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PPPEncapsulator::UpEvent()
|
||||||
|
{
|
||||||
|
fConnectionStatus = PPP_ESTABLISHED_PHASE;
|
||||||
|
|
||||||
|
if(!Interface())
|
||||||
|
return;
|
||||||
|
|
||||||
|
Interface()->StateMachine().UpEvent(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PPPEncapsulator::DownEvent()
|
||||||
|
{
|
||||||
|
fConnectionStatus = PPP_DOWN_PHASE;
|
||||||
|
|
||||||
|
if(!Interface())
|
||||||
|
return;
|
||||||
|
|
||||||
|
Interface()->StateMachine().DownEvent(this);
|
||||||
|
}
|
||||||
|
|||||||
@@ -12,7 +12,6 @@
|
|||||||
#include "KPPPManager.h"
|
#include "KPPPManager.h"
|
||||||
|
|
||||||
// general helper classes not only belonging to us
|
// general helper classes not only belonging to us
|
||||||
#include "AccessHelper.h"
|
|
||||||
#include "LockerHelper.h"
|
#include "LockerHelper.h"
|
||||||
|
|
||||||
// tools only for us :)
|
// tools only for us :)
|
||||||
@@ -43,13 +42,15 @@ status_t redial_func(void *data);
|
|||||||
status_t in_queue_thread(void *data);
|
status_t in_queue_thread(void *data);
|
||||||
|
|
||||||
|
|
||||||
PPPInterface::PPPInterface(driver_settings *settings, PPPInterface *parent = NULL)
|
PPPInterface::PPPInterface(uint32 ID, driver_settings *settings,
|
||||||
: fSettings(dup_driver_settings(settings)),
|
PPPInterface *parent = NULL)
|
||||||
|
: fID(ID), fSettings(dup_driver_settings(settings)),
|
||||||
fStateMachine(*this), fLCP(*this), ReportManager()(StateMachine().Locker()),
|
fStateMachine(*this), fLCP(*this), ReportManager()(StateMachine().Locker()),
|
||||||
fIfnet(NULL), fUpThread(-1), fRedialThread(-1), fDialRetry(0),
|
fIfnet(NULL), fUpThread(-1), fRedialThread(-1), fDialRetry(0),
|
||||||
fDialRetriesLimit(0), fLinkMTU(1500), fAccessing(0), fChildrenCount(0),
|
fDialRetriesLimit(0), fIdleSince(0), fLinkMTU(1500), fDevice(NULL),
|
||||||
fDevice(NULL), fFirstEncapsulator(NULL), fLock(StateMachine().Locker())
|
fFirstEncapsulator(NULL), fLock(StateMachine().Locker())
|
||||||
{
|
{
|
||||||
|
// set up queue
|
||||||
fInQueue = start_ifq();
|
fInQueue = start_ifq();
|
||||||
fInQueueThread = spawn_kernel_thread(in_queue_thread, "PPPInterface: Input",
|
fInQueueThread = spawn_kernel_thread(in_queue_thread, "PPPInterface: Input",
|
||||||
B_NORMAL_PRIORITY, this);
|
B_NORMAL_PRIORITY, this);
|
||||||
@@ -61,17 +62,32 @@ PPPInterface::PPPInterface(driver_settings *settings, PPPInterface *parent = NUL
|
|||||||
// are we a multilink subinterface?
|
// are we a multilink subinterface?
|
||||||
if(parent && parent->IsMultilink()) {
|
if(parent && parent->IsMultilink()) {
|
||||||
fParent = parent;
|
fParent = parent;
|
||||||
|
fParent->AddChild(this);
|
||||||
fIsMultilink = true;
|
fIsMultilink = true;
|
||||||
} else {
|
} else {
|
||||||
fParent = NULL;
|
fParent = NULL;
|
||||||
fIsMultilink = false;
|
fIsMultilink = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!fSettings)
|
if(!fSettings) {
|
||||||
|
fMode = PPP_CLIENT_MODE;
|
||||||
|
fDisconnectAfterIdleSince = 0;
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const char *value;
|
const char *value;
|
||||||
|
|
||||||
|
// get DisonnectAfterIdleSince settings
|
||||||
|
value = get_settings_value(PPP_DISONNECT_AFTER_IDLE_SINCE_KEY, fSettings);
|
||||||
|
if(!value)
|
||||||
|
fDisconnectAfterIdleSince = 0;
|
||||||
|
else
|
||||||
|
fDisconnectAfterIdleSince = atoi(value);
|
||||||
|
|
||||||
|
if(fDisconnectAfterIdleSince < 0)
|
||||||
|
fDisconnectAfterIdleSince = 0;
|
||||||
|
|
||||||
|
// get mode settings
|
||||||
value = get_settings_value(PPP_MODE_KEY, fSettings);
|
value = get_settings_value(PPP_MODE_KEY, fSettings);
|
||||||
if(!strcasecmp(value, PPP_SERVER_MODE_VALUE))
|
if(!strcasecmp(value, PPP_SERVER_MODE_VALUE))
|
||||||
fMode = PPP_SERVER_MODE;
|
fMode = PPP_SERVER_MODE;
|
||||||
@@ -132,7 +148,7 @@ PPPInterface::~PPPInterface()
|
|||||||
void
|
void
|
||||||
PPPInterface::Delete()
|
PPPInterface::Delete()
|
||||||
{
|
{
|
||||||
fManager->delete_interface(this);
|
fManager->delete_interface(ID());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -177,7 +193,7 @@ PPPInterface::Control(uint32 op, void *data, size_t length)
|
|||||||
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
@@ -206,11 +222,9 @@ PPPInterface::SetDevice(PPPDevice *device)
|
|||||||
fDevice = device;
|
fDevice = device;
|
||||||
|
|
||||||
fLinkMTU = fDevice->MTU();
|
fLinkMTU = fDevice->MTU();
|
||||||
if(Ifnet())
|
|
||||||
Ifnet()->if_baudrate = max(fDevice->InputTransferRate(),
|
|
||||||
fDevice->OutputTransferRate());
|
|
||||||
|
|
||||||
CalculateMRU();
|
CalculateMRU();
|
||||||
|
CalculateBaudRate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -407,9 +421,7 @@ PPPInterface::RemoveChild(PPPInterface *child)
|
|||||||
|
|
||||||
// parents cannot exist without their children
|
// parents cannot exist without their children
|
||||||
if(CountChildren() == 0 && fManager && Ifnet())
|
if(CountChildren() == 0 && fManager && Ifnet())
|
||||||
fManager->delete_interface(this);
|
fManager->delete_interface(ID());
|
||||||
|
|
||||||
CalculateMRU();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -534,7 +546,7 @@ PPPInterface::Up()
|
|||||||
fUpThread = -1;
|
fUpThread = -1;
|
||||||
|
|
||||||
if(!DoesDialOnDemand() && report.code != PPP_REPORT_DOWN_SUCCESSFUL)
|
if(!DoesDialOnDemand() && report.code != PPP_REPORT_DOWN_SUCCESSFUL)
|
||||||
fManager->delete_interface(this);
|
fManager->delete_interface(ID());
|
||||||
}
|
}
|
||||||
|
|
||||||
PPP_REPLY(sender, B_OK);
|
PPP_REPLY(sender, B_OK);
|
||||||
@@ -572,7 +584,7 @@ PPPInterface::Up()
|
|||||||
|
|
||||||
if(!DoesDialOnDemand()
|
if(!DoesDialOnDemand()
|
||||||
&& report.code != PPP_REPORT_DOWN_SUCCESSFUL)
|
&& report.code != PPP_REPORT_DOWN_SUCCESSFUL)
|
||||||
fManager->delete_interface(this);
|
fManager->delete_interface(ID());
|
||||||
|
|
||||||
PPP_REPLY(sender, B_OK);
|
PPP_REPLY(sender, B_OK);
|
||||||
ReportManager().DisableReports(PPP_CONNECTION_REPORT, me);
|
ReportManager().DisableReports(PPP_CONNECTION_REPORT, me);
|
||||||
@@ -599,12 +611,15 @@ PPPInterface::Up()
|
|||||||
|
|
||||||
if(!DoesDialOnDemand()
|
if(!DoesDialOnDemand()
|
||||||
&& report.code != PPP_REPORT_DOWN_SUCCESSFUL)
|
&& report.code != PPP_REPORT_DOWN_SUCCESSFUL)
|
||||||
fManager->delete_interface(this);
|
fManager->delete_interface(ID());
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if the code is unknown we continue
|
||||||
|
PPP_REPLY(sender, B_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@@ -644,7 +659,7 @@ PPPInterface::Down()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(!DoesDialOnDemand())
|
if(!DoesDialOnDemand())
|
||||||
fManager->delete_interface(this);
|
fManager->delete_interface(ID());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -674,12 +689,11 @@ PPPInterface::LoadModules(const driver_settings *settings,
|
|||||||
|
|
||||||
// multilink handling
|
// multilink handling
|
||||||
for(int32 i = start;
|
for(int32 i = start;
|
||||||
i < settings->parameter_count && i < start + count;
|
i < settings->parameter_count && i < start + count; i++) {
|
||||||
i++) {
|
|
||||||
if(!strcasecmp(settings->parameters[i].name, PPP_MULTILINK_KEY)
|
if(!strcasecmp(settings->parameters[i].name, PPP_MULTILINK_KEY)
|
||||||
&& settings->parameters[i].value_count > 0) {
|
&& settings->parameters[i].value_count > 0) {
|
||||||
if(!LoadModule(settings->parameters[i].value[0],
|
if(!LoadModule(settings->parameters[i].value[0],
|
||||||
parameters[i].parameters, PPP_MULTILINK_TYPE))
|
parameters[i].parameters, PPP_MULTILINK_TYPE))
|
||||||
return false;
|
return false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -690,14 +704,12 @@ PPPInterface::LoadModules(const driver_settings *settings,
|
|||||||
if(IsMultilink() && !Parent()) {
|
if(IsMultilink() && !Parent()) {
|
||||||
// main interfaces only load the multilink module
|
// main interfaces only load the multilink module
|
||||||
// and create a child using their settings
|
// and create a child using their settings
|
||||||
AddChild(new PPPInterface(settings, this));
|
fManager->create_interface(settings, ID());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int32 i = start;
|
for(int32 i = start;
|
||||||
i < settings->parameter_count && i < start + count;
|
i < settings->parameter_count && i < start + count; i++) {
|
||||||
i++) {
|
|
||||||
|
|
||||||
type = -1;
|
type = -1;
|
||||||
|
|
||||||
name = settings->parameters[i].name;
|
name = settings->parameters[i].name;
|
||||||
@@ -715,9 +727,9 @@ PPPInterface::LoadModules(const driver_settings *settings,
|
|||||||
|
|
||||||
if(type >= 0)
|
if(type >= 0)
|
||||||
for(int32 value_id = 0; value_id < settings->parameters[i].value_count;
|
for(int32 value_id = 0; value_id < settings->parameters[i].value_count;
|
||||||
value_id++)
|
value_id++)
|
||||||
if(!LoadModule(settings->parameters[i].value[value_id],
|
if(!LoadModule(settings->parameters[i].value[value_id],
|
||||||
settings->parameters[i].parameters, type))
|
settings->parameters[i].parameters, type))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -756,8 +768,6 @@ PPPInterface::LoadModule(const char *name, const driver_parameter *parameter,
|
|||||||
status_t
|
status_t
|
||||||
PPPInterface::Send(mbuf *packet, uint16 protocol)
|
PPPInterface::Send(mbuf *packet, uint16 protocol)
|
||||||
{
|
{
|
||||||
AccessHelper access(&fAccessing);
|
|
||||||
|
|
||||||
if(!packet)
|
if(!packet)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
@@ -781,8 +791,10 @@ PPPInterface::Send(mbuf *packet, uint16 protocol)
|
|||||||
// Note that these protocols are not passed to encapsulators!
|
// Note that these protocols are not passed to encapsulators!
|
||||||
PPPProtocol *sending_protocol = ProtocolFor(protocol);
|
PPPProtocol *sending_protocol = ProtocolFor(protocol);
|
||||||
if(sending_protocol && sending_protocol->Flags() & PPP_ALWAYS_ALLOWED
|
if(sending_protocol && sending_protocol->Flags() & PPP_ALWAYS_ALLOWED
|
||||||
&& sending_protocol->IsEnabled() && fDevice->IsUp())
|
&& sending_protocol->IsEnabled() && fDevice->IsUp()) {
|
||||||
|
fIdleSince = system_time();
|
||||||
return SendToDevice(packet, protocol);
|
return SendToDevice(packet, protocol);
|
||||||
|
}
|
||||||
|
|
||||||
// never send normal protocols when we are down
|
// never send normal protocols when we are down
|
||||||
if(!IsUp()) {
|
if(!IsUp()) {
|
||||||
@@ -790,6 +802,8 @@ PPPInterface::Send(mbuf *packet, uint16 protocol)
|
|||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fIdleSince = system_time();
|
||||||
|
|
||||||
// send to next up encapsulator
|
// send to next up encapsulator
|
||||||
if(!fFirstEncapsulator)
|
if(!fFirstEncapsulator)
|
||||||
return SendToDevice(packet, protocol);
|
return SendToDevice(packet, protocol);
|
||||||
@@ -804,8 +818,6 @@ PPPInterface::Send(mbuf *packet, uint16 protocol)
|
|||||||
status_t
|
status_t
|
||||||
PPPInterface::Receive(mbuf *packet, uint16 protocol)
|
PPPInterface::Receive(mbuf *packet, uint16 protocol)
|
||||||
{
|
{
|
||||||
AccessHelper access(&fAccessing);
|
|
||||||
|
|
||||||
if(!packet)
|
if(!packet)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
@@ -874,8 +886,6 @@ PPPInterface::Receive(mbuf *packet, uint16 protocol)
|
|||||||
status_t
|
status_t
|
||||||
PPPInterface::SendToDevice(mbuf *packet, uint16 protocol)
|
PPPInterface::SendToDevice(mbuf *packet, uint16 protocol)
|
||||||
{
|
{
|
||||||
AccessHelper access(&fAccessing);
|
|
||||||
|
|
||||||
if(!packet)
|
if(!packet)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
@@ -914,7 +924,7 @@ PPPInterface::SendToDevice(mbuf *packet, uint16 protocol)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// encode in ppp frame
|
// encode in ppp frame
|
||||||
packet = M_PREPEND(packet, sizeof(uint16));
|
M_PREPEND(packet, sizeof(uint16));
|
||||||
|
|
||||||
if(packet == NULL)
|
if(packet == NULL)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
@@ -924,11 +934,13 @@ PPPInterface::SendToDevice(mbuf *packet, uint16 protocol)
|
|||||||
uint16 *header = mtod(packet, uint16*);
|
uint16 *header = mtod(packet, uint16*);
|
||||||
*header = protocol;
|
*header = protocol;
|
||||||
|
|
||||||
|
fIdleSince = system_time();
|
||||||
|
|
||||||
// pass to device/children
|
// pass to device/children
|
||||||
if(!IsMultilink() || Parent()) {
|
if(!IsMultilink() || Parent()) {
|
||||||
// check if packet is too big for device
|
// check if packet is too big for device
|
||||||
if((packet->m_flags & M_PKTHDR && packet->m_pkt_hdr.len > LinkMTU())
|
if((packet->m_flags & M_PKTHDR && packet->m_pkthdr.len > LinkMTU())
|
||||||
|| packet->m_len > LinkMTU()) {
|
|| packet->m_len > LinkMTU()) {
|
||||||
m_freem(packet);
|
m_freem(packet);
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
@@ -945,8 +957,6 @@ PPPInterface::SendToDevice(mbuf *packet, uint16 protocol)
|
|||||||
status_t
|
status_t
|
||||||
PPPInterface::ReceiveFromDevice(mbuf *packet)
|
PPPInterface::ReceiveFromDevice(mbuf *packet)
|
||||||
{
|
{
|
||||||
AccessHelper access(&fAccessing);
|
|
||||||
|
|
||||||
if(!packet)
|
if(!packet)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
@@ -961,16 +971,12 @@ PPPInterface::ReceiveFromDevice(mbuf *packet)
|
|||||||
|
|
||||||
m_adj(packet, sizeof(uint16));
|
m_adj(packet, sizeof(uint16));
|
||||||
|
|
||||||
if(packet->m_flags & M_PKTHDR) {
|
// Set our interface as the receiver.
|
||||||
|
// This might be NULL, so protocols that belong to the network stack (IP, etc.)
|
||||||
|
// will probably be confused (as there is no interface from which the packet came).
|
||||||
|
// Protocols that live only in the PPP interface should have no problems with this.
|
||||||
|
if(packet->m_flags & M_PKTHDR)
|
||||||
packet->m_pkthdr.rcvif = Ifnet();
|
packet->m_pkthdr.rcvif = Ifnet();
|
||||||
// make sure the protocols think we received
|
|
||||||
// the packet
|
|
||||||
|
|
||||||
if(!packet->m_pkthdr.rcvif) {
|
|
||||||
m_freem(packet);
|
|
||||||
return B_ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Receive(packet, protocol);
|
return Receive(packet, protocol);
|
||||||
}
|
}
|
||||||
@@ -979,10 +985,24 @@ PPPInterface::ReceiveFromDevice(mbuf *packet)
|
|||||||
void
|
void
|
||||||
PPPInterface::Pulse()
|
PPPInterface::Pulse()
|
||||||
{
|
{
|
||||||
// TODO:
|
// check our idle time and disconnect if needed
|
||||||
// check our idle time
|
if(fDisconnectAfterIdleSince > 0 && fIdleSince != 0
|
||||||
|
&& fIdleSince - system_time() >= fDisconnectAfterIdleSince) {
|
||||||
|
StateMachine().CloseEvent();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
StateMachine().TimerEvent();
|
StateMachine().TimerEvent();
|
||||||
|
|
||||||
|
if(Device())
|
||||||
|
Device()->Pulse();
|
||||||
|
|
||||||
|
for(int32 index = 0; index < CountProtocols(); index++)
|
||||||
|
ProtocolAt(index)->Pulse();
|
||||||
|
|
||||||
|
PPPEncapsulator *encapsulator = fFirstEncapsulator;
|
||||||
|
for(; encapsulator; encapsulator = encapsulator->Next())
|
||||||
|
encapsulator->Pulse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1004,14 +1024,12 @@ PPPInterface::RegisterInterface()
|
|||||||
if(!fManager)
|
if(!fManager)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
fIfnet = fManager->add_interface(this);
|
fIfnet = fManager->register_interface(ID());
|
||||||
|
|
||||||
if(!fIfnet)
|
if(!fIfnet)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if(Device())
|
CalculateBaudRate();
|
||||||
fIfnet->if_baudrate = max(Device()->InputTransferRate(),
|
|
||||||
Device()->OutputTransferRate());
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -1031,7 +1049,7 @@ PPPInterface::UnregisterInterface()
|
|||||||
if(!fManager)
|
if(!fManager)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
fManager->remove_interface(this);
|
fManager->unregister_interface(ID());
|
||||||
fIfnet = NULL;
|
fIfnet = NULL;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -1047,10 +1065,8 @@ PPPInterface::CalculateMRU()
|
|||||||
fHeaderLength = sizeof(uint16);
|
fHeaderLength = sizeof(uint16);
|
||||||
|
|
||||||
PPPEncapsulator encapsulator = fFirstEncapsulator;
|
PPPEncapsulator encapsulator = fFirstEncapsulator;
|
||||||
while(encapsulator) {
|
for(; encapsulator; encapsulator = encapsulator->Next())
|
||||||
fHeaderLength += encapsulator->Overhead();
|
fHeaderLength += encapsulator->Overhead();
|
||||||
encapsulator = encapsulator->Next();
|
|
||||||
}
|
|
||||||
|
|
||||||
fMRU -= fHeaderLength;
|
fMRU -= fHeaderLength;
|
||||||
|
|
||||||
@@ -1064,6 +1080,24 @@ PPPInterface::CalculateMRU()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PPPInterface::CalculateBaudRate()
|
||||||
|
{
|
||||||
|
if(!Ifnet())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(Device())
|
||||||
|
fIfnet->if_baudrate = max(Device()->InputTransferRate(),
|
||||||
|
Device()->OutputTransferRate());
|
||||||
|
else {
|
||||||
|
fIfnet->if_baudrate = 0;
|
||||||
|
for(int32 index = 0; index < CountChildren(); index++)
|
||||||
|
if(ChildAt(index)->Ifnet())
|
||||||
|
fIfnet->if_baudrate += ChildAt(index)->Ifnet()->if_baudrate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
PPPInterface::Redial()
|
PPPInterface::Redial()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -64,3 +64,16 @@ PPPLCP::OptionHandlerAt(int32 index) const
|
|||||||
|
|
||||||
return handler;
|
return handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32
|
||||||
|
PPPLCP::AdditionalOverhead const
|
||||||
|
{
|
||||||
|
uint32 overhead += PPP_PROTOCOL_OVERHEAD;
|
||||||
|
|
||||||
|
if(Target())
|
||||||
|
overhead += Target()->Overhead();
|
||||||
|
if(Interface()->Device())
|
||||||
|
overhead += Interface()->Device()->Overhead();
|
||||||
|
|
||||||
|
return overhead;
|
||||||
|
}
|
||||||
|
|||||||
@@ -6,3 +6,33 @@
|
|||||||
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
#include "KPPPOptionHandler.h"
|
#include "KPPPOptionHandler.h"
|
||||||
|
|
||||||
|
|
||||||
|
PPPOptionHandler::PPPOptionHandler(const char *name, PPPInterface *interface,
|
||||||
|
driver_parameter *settings)
|
||||||
|
: fInterface(interface), fSettings(settings)
|
||||||
|
{
|
||||||
|
fName = name ? strdup(name) : NULL;
|
||||||
|
|
||||||
|
if(interface)
|
||||||
|
interface->LCP().AddOptionHandler(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PPPOptionHandler::~PPPOptionHandler()
|
||||||
|
{
|
||||||
|
free(fName);
|
||||||
|
|
||||||
|
if(Interface())
|
||||||
|
Interface()->LCP().RemoveOptionHandler(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
PPPOptionHandler::InitCheck() const
|
||||||
|
{
|
||||||
|
if(!Interface() || !Settings())
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|||||||
@@ -6,3 +6,129 @@
|
|||||||
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
#include "KPPPProtocol.h"
|
#include "KPPPProtocol.h"
|
||||||
|
|
||||||
|
|
||||||
|
PPPProtocol::PPPProtocol(const char *name, PPP_PHASE phase, uint16 protocol,
|
||||||
|
int32 addressFamily, PPPInterface *interface,
|
||||||
|
driver_parameter *settings, int32 flags = PPP_NO_FLAGS)
|
||||||
|
: fPhase(phase), fProtocol(protocol), fAddressFamily(addressFamily),
|
||||||
|
fInterface(interface), fSettings(settings), fFlags(flags),
|
||||||
|
fEnabled(true), fUpRequested(true), fConnectionStatus(PPP_DOWN_PHASE)
|
||||||
|
{
|
||||||
|
fName = name ? strdup(name) : NULL;
|
||||||
|
|
||||||
|
if(interface)
|
||||||
|
interface->AddProtocol(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PPPProtocol::~PPPProtocol()
|
||||||
|
{
|
||||||
|
free(fName);
|
||||||
|
|
||||||
|
if(Interface())
|
||||||
|
Interface()->RemoveProtocol(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
PPPProtocol::InitCheck() const
|
||||||
|
{
|
||||||
|
if(!Interface() || !Settings())
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PPPProtocol::SetEnabled(bool enabled = true)
|
||||||
|
{
|
||||||
|
fEnabled = enabled;
|
||||||
|
|
||||||
|
if(!Interface())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(!enabled) {
|
||||||
|
if(IsUp() || IsGoingUp()))
|
||||||
|
Down();
|
||||||
|
} else if(!IsUp() && !IsGoingUp() && IsUpRequested() && Interface()->IsUp())
|
||||||
|
Up();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
PPPProtocol::Control(uint32 op, void *data, size_t length)
|
||||||
|
{
|
||||||
|
switch(op) {
|
||||||
|
// TODO:
|
||||||
|
// get:
|
||||||
|
// - name
|
||||||
|
// - protocol, address family
|
||||||
|
// - status (Is(Going)Up/Down/UpRequested/Enabled)
|
||||||
|
// set:
|
||||||
|
// - enabled
|
||||||
|
|
||||||
|
default:
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PPPProtocol::Pulse()
|
||||||
|
{
|
||||||
|
// do nothing by default
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PPPProtocol::UpStarted()
|
||||||
|
{
|
||||||
|
fConnectionStatus = PPP_ESTABLISHMENT_PHASE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PPPProtocol::DownStarted()
|
||||||
|
{
|
||||||
|
fConnectionStatus = PPP_TERMINATION_PHASE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PPPProtocol::UpFailedEvent()
|
||||||
|
{
|
||||||
|
fConnectionStatus = PPP_DOWN_PHASE;
|
||||||
|
|
||||||
|
if(!Interface())
|
||||||
|
return;
|
||||||
|
|
||||||
|
Interface()->StateMachine().UpFailedEvent(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PPPProtocol::UpEvent()
|
||||||
|
{
|
||||||
|
fConnectionStatus = PPP_ESTABLISHED_PHASE;
|
||||||
|
|
||||||
|
if(!Interface())
|
||||||
|
return;
|
||||||
|
|
||||||
|
Interface()->StateMachine().UpEvent(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PPPProtocol::DownEvent()
|
||||||
|
{
|
||||||
|
fConnectionStatus = PPP_DOWN_PHASE;
|
||||||
|
|
||||||
|
if(!Interface())
|
||||||
|
return;
|
||||||
|
|
||||||
|
Interface()->StateMachine().DownEvent(this);
|
||||||
|
}
|
||||||
|
|||||||
@@ -105,6 +105,8 @@ PPPStateMachine::AuthenticationAccepted(const char *name)
|
|||||||
fAuthenticationStatus = PPP_AUTHENTICATION_SUCCESSFUL;
|
fAuthenticationStatus = PPP_AUTHENTICATION_SUCCESSFUL;
|
||||||
free(fAuthenticationName);
|
free(fAuthenticationName);
|
||||||
fAuthenticationName = strdup(name);
|
fAuthenticationName = strdup(name);
|
||||||
|
|
||||||
|
Interface()->Report(PPP_CONNECTION_REPORT, PPP_REPORT_AUTHENTICATION_SUCCESSFUL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -147,6 +149,9 @@ PPPStateMachine::PeerAuthenticationAccepted(const char *name)
|
|||||||
fPeerAuthenticationStatus = PPP_AUTHENTICATION_SUCCESSFUL;
|
fPeerAuthenticationStatus = PPP_AUTHENTICATION_SUCCESSFUL;
|
||||||
free(fPeerAuthenticationName);
|
free(fPeerAuthenticationName);
|
||||||
fPeerAuthenticationName = strdup(name);
|
fPeerAuthenticationName = strdup(name);
|
||||||
|
|
||||||
|
Interface()->Report(PPP_CONNECTION_REPORT,
|
||||||
|
PPP_REPORT_PEER_AUTHENTICATION_SUCCESSFUL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -183,17 +188,23 @@ PPPStateMachine::UpEvent(PPPInterface *interface)
|
|||||||
{
|
{
|
||||||
LockerHelper locker(fLock);
|
LockerHelper locker(fLock);
|
||||||
|
|
||||||
if(Phase() <= PPP_TERMINATION_PHASE || State() != PPP_STARTING_STATE) {
|
if(Phase() <= PPP_TERMINATION_PHASE) {
|
||||||
interface->StateMachine().CloseEvent();
|
interface->StateMachine().CloseEvent();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
NewState(PPP_OPENED_STATE);
|
Interface()->CalculateBaudRate();
|
||||||
|
|
||||||
if(Phase() == PPP_ESTABLISHMENT_PHASE) {
|
if(Phase() == PPP_ESTABLISHMENT_PHASE) {
|
||||||
NewPhase(PPP_AUTHENTICATION_PHASE);
|
// this is the first interface that went up
|
||||||
|
Interface()->SetLinkMTU(interface->LinkMTU());
|
||||||
locker.UnlockNow();
|
locker.UnlockNow();
|
||||||
ThisLayerUp();
|
ThisLayerUp();
|
||||||
}
|
} else if(Interface()->LinkMTU() > interface->LinkMTU())
|
||||||
|
Interface()->SetLinkMTU(interface->LinkMTU());
|
||||||
|
// linkMTU should always be the smallest value of all children
|
||||||
|
|
||||||
|
NewState(PPP_OPENED_STATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -202,6 +213,11 @@ PPPStateMachine::DownEvent(PPPInterface *interface)
|
|||||||
{
|
{
|
||||||
LockerHelper locker(fLock);
|
LockerHelper locker(fLock);
|
||||||
|
|
||||||
|
uint32 linkMTU = 0;
|
||||||
|
// the new linkMTU
|
||||||
|
|
||||||
|
Interface()->CalculateBaudRate();
|
||||||
|
|
||||||
// when all children are down we should not be running
|
// when all children are down we should not be running
|
||||||
if(Interface()->IsMultilink() && !Interface()->Parent()) {
|
if(Interface()->IsMultilink() && !Interface()->Parent()) {
|
||||||
uint32 count = 0;
|
uint32 count = 0;
|
||||||
@@ -209,10 +225,19 @@ PPPStateMachine::DownEvent(PPPInterface *interface)
|
|||||||
for(int32 index = 0; index < Interface()->CountChildren(); index++) {
|
for(int32 index = 0; index < Interface()->CountChildren(); index++) {
|
||||||
child = Interface()->ChildAt(index);
|
child = Interface()->ChildAt(index);
|
||||||
|
|
||||||
if(child && child->IsUp())
|
if(child && child->IsUp()) {
|
||||||
|
// set linkMTU to the smallest value of all children
|
||||||
|
if(linkMTU == 0)
|
||||||
|
linkMTU = child->LinkMTU();
|
||||||
|
else if(linkMTU > child->LinkMTU())
|
||||||
|
linkMTU = child->LinkMTU();
|
||||||
|
|
||||||
++count;
|
++count;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Interface()->SetLinkMTU(linkMTU);
|
||||||
|
|
||||||
if(count == 0) {
|
if(count == 0) {
|
||||||
locker.UnlockNow();
|
locker.UnlockNow();
|
||||||
DownEvent();
|
DownEvent();
|
||||||
@@ -372,10 +397,7 @@ PPPStateMachine::UpEvent()
|
|||||||
return;
|
return;
|
||||||
// it is not our device that went up...
|
// it is not our device that went up...
|
||||||
|
|
||||||
if(Interface()->Ifnet())
|
Interface()->CalculateBaudRate();
|
||||||
Interface()->Ifnet()->if_baudrate = max(
|
|
||||||
Interface()->Device()->InputTransferRate(),
|
|
||||||
Interface()->Device()->OutputTransferRate());
|
|
||||||
|
|
||||||
switch(State()) {
|
switch(State()) {
|
||||||
case PPP_INITIAL_STATE:
|
case PPP_INITIAL_STATE:
|
||||||
@@ -428,14 +450,14 @@ PPPStateMachine::DownEvent()
|
|||||||
{
|
{
|
||||||
LockerHelper locker(fLock);
|
LockerHelper locker(fLock);
|
||||||
|
|
||||||
if(!Interface()->Device() || Interface()->Device->IsUp())
|
if(Interface()->Device() && Interface()->Device->IsUp())
|
||||||
return;
|
return;
|
||||||
// it is not our device that went up...
|
// it is not our device that went up...
|
||||||
|
|
||||||
if(Interface()->Ifnet())
|
Interface()->CalculateBaudRate();
|
||||||
Interface()->Ifnet()->if_baudrate = max(
|
|
||||||
Interface()->Device()->InputTransferRate(),
|
// reset IdleSince
|
||||||
Interface()->Device()->OutputTransferRate());
|
Interface()->fIdleSince = 0;
|
||||||
|
|
||||||
switch(State()) {
|
switch(State()) {
|
||||||
case PPP_CLOSED_STATE:
|
case PPP_CLOSED_STATE:
|
||||||
@@ -1150,7 +1172,7 @@ PPPStateMachine::RCREvent(mbuf *packet)
|
|||||||
handled = false;
|
handled = false;
|
||||||
|
|
||||||
for(int32 index = 0; index < LCP().CountOptionHandlers();
|
for(int32 index = 0; index < LCP().CountOptionHandlers();
|
||||||
index++) {
|
index++) {
|
||||||
handler = LCP().OptionHandlerAt(index);
|
handler = LCP().OptionHandlerAt(index);
|
||||||
error = handler->ParseRequest(&request, item, &nak, &reject);
|
error = handler->ParseRequest(&request, item, &nak, &reject);
|
||||||
if(error == PPP_UNHANLED)
|
if(error == PPP_UNHANLED)
|
||||||
@@ -1171,9 +1193,9 @@ PPPStateMachine::RCREvent(mbuf *packet)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(nak.CountItems() > 0)
|
if(nak.CountItems() > 0)
|
||||||
RCRBadEvent(nak.ToMbuf(), NULL);
|
RCRBadEvent(nak.ToMbuf(LCP().AdditionalOverhead()), NULL);
|
||||||
else if(reject.CountItmes() > 0)
|
else if(reject.CountItmes() > 0)
|
||||||
RCRBadEvent(NULL, reject.ToMbuf());
|
RCRBadEvent(NULL, reject.ToMbuf(LCP().AdditionalOverhead()));
|
||||||
else
|
else
|
||||||
RCRGoodEvent(packet);
|
RCRGoodEvent(packet);
|
||||||
}
|
}
|
||||||
@@ -1326,7 +1348,7 @@ PPPStateMachine::SendConfigureRequest()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LCP().Send(request.ToMbuf());
|
LCP().Send(request.ToMbuf(LCP().AdditionalOverhead()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1369,11 +1391,7 @@ PPPStateMachine::SendTerminateRequest()
|
|||||||
--fTerminateCounter;
|
--fTerminateCounter;
|
||||||
|
|
||||||
// reserve some space for other protocols
|
// reserve some space for other protocols
|
||||||
m->m_data += PPP_PROTOCOL_OVERHEAD;
|
m->m_data += LCP().AdditionalOverhead();
|
||||||
if(LCP().Encapsulator())
|
|
||||||
m->m_data += LCP().Encapsulator()->Overhead();
|
|
||||||
if(Interface()->Device())
|
|
||||||
m->m_data += Interface()->Device()->Overhead();
|
|
||||||
|
|
||||||
lcp_packet *request = mtod(m, lcp_packet*);
|
lcp_packet *request = mtod(m, lcp_packet*);
|
||||||
request->code = PPP_TERMINATE_REQUEST;
|
request->code = PPP_TERMINATE_REQUEST;
|
||||||
@@ -1398,8 +1416,36 @@ PPPStateMachine::SendTerminateAck(mbuf *request)
|
|||||||
void
|
void
|
||||||
PPPStateMachine::SendCodeReject(mbuf *packet, uint16 protocol, uint8 type)
|
PPPStateMachine::SendCodeReject(mbuf *packet, uint16 protocol, uint8 type)
|
||||||
{
|
{
|
||||||
// TODO:
|
int32 length;
|
||||||
// add the packet to the reject and truncate it if needed
|
// additional space needed for this reject
|
||||||
|
if(type == PPP_PROTOCOL_REJECT)
|
||||||
|
length = 6;
|
||||||
|
else
|
||||||
|
length = 4;
|
||||||
|
|
||||||
|
M_PREPEND(packet, length + LCP().AdditionalOverhead());
|
||||||
|
|
||||||
|
int32 adjust = 0;
|
||||||
|
// adjust packet size by this value if packet is too big
|
||||||
|
if(packet->m_flags & M_PKTHDR) {
|
||||||
|
if(packet->m_pkthdr.len > Interface()->LinkMTU())
|
||||||
|
adjust = Interface()->LinkMTU() - packet->m_pkthdr.len;
|
||||||
|
} else if(packet->m_len > Interface()->LinkMTU())
|
||||||
|
adjust = Interface()->LinkMTU() - packet->m_len;
|
||||||
|
|
||||||
|
if(adjust != 0)
|
||||||
|
m_adj(packet, adjust);
|
||||||
|
|
||||||
|
lcp_packet *reject = mtod(packet, lcp_packet*);
|
||||||
|
data->code = type;
|
||||||
|
data->id = NextID();
|
||||||
|
data->length = (uint16) htons(reject->m_pkthdr.len);
|
||||||
|
|
||||||
|
protocol = (uint16) htons(protocol);
|
||||||
|
if(type == PPP_PROTOCOL_REJECT)
|
||||||
|
memcpy(&data->data, &protocol, sizeof(protocol));
|
||||||
|
|
||||||
|
LCP().Send(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1483,7 +1529,8 @@ void
|
|||||||
PPPStateMachine::DownProtocols()
|
PPPStateMachine::DownProtocols()
|
||||||
{
|
{
|
||||||
for(int32 index = 0; index < Interface()->CountProtocols(); index++)
|
for(int32 index = 0; index < Interface()->CountProtocols(); index++)
|
||||||
Interface()->ProtocolAt(index)->Down();
|
if(Interface()->ProtocolAt(index)->IsEnabled())
|
||||||
|
Interface()->ProtocolAt(index)->Down();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1494,7 +1541,8 @@ PPPStateMachine::DownEncapsulators()
|
|||||||
|
|
||||||
for(; encapsulator_handler;
|
for(; encapsulator_handler;
|
||||||
encapsulator_handler = encapsulator_handler->Next())
|
encapsulator_handler = encapsulator_handler->Next())
|
||||||
encapsualtor_handler->Down();
|
if(encapsulator_handler->IsEnabled())
|
||||||
|
encapsualtor_handler->Down();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user