Added some extended support for DialOnDemand.

Fixed missing ifnet flags.
PPPStateMachine: replaced nearly all pointers to PPPInterface objects with references.
PPPInterface: added delay to Redial() method (will be used to implement DialRetryDelay, too).
PPPLCP: changed the way Receive() handles LCPExtensions and added code for removing padding from packet.
PPPOptionHandler: added code and only one OptionHandler per code is allowed from now on.
Added some changes to support authenticators.

TODO:
- add DialRetryDelay
- maybe change how StateMachine iterates over OptionHandlers (as they have a code field now)
- commit changes for PFC support and PFC, MRU, and authentication handler


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@4661 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Waldemar Kornewald
2003-09-12 15:27:29 +00:00
parent 90685fb799
commit 53a75b6389
28 changed files with 443 additions and 281 deletions
+15
View File
@@ -0,0 +1,15 @@
#ifndef _K_PPP__H
#define _K_PPP__H
#include <KPPPConfigurePacket.h>
#include <KPPPDevice.h>
// includes KPPPInterface.h, KPPPLCP.h,
// KPPPStateMachine.h and KPPPProtocol.h
#include <KPPPEncapsulator.h>
#include <KPPPLCPExtension.h>
#include <KPPPOptionHandler.h>
#include <PPPControl.h>
#endif
@@ -45,7 +45,6 @@ class PPPConfigurePacket {
int32 CountItems() const int32 CountItems() const
{ return fItems.CountItems(); } { return fItems.CountItems(); }
ppp_configure_item *ItemAt(int32 index) const; ppp_configure_item *ItemAt(int32 index) const;
bool HasItemWithType(uint8 type) const;
ppp_configure_item *ItemWithType(uint8 type) const; ppp_configure_item *ItemWithType(uint8 type) const;
struct mbuf *ToMbuf(uint32 reserve = 0); struct mbuf *ToMbuf(uint32 reserve = 0);
+3 -3
View File
@@ -18,7 +18,7 @@ typedef uint32 interface_id;
// module key types (used when loading a module) // module key types (used when loading a module)
enum PPP_MODULE_KEY_TYPE { enum ppp_module_key_type {
PPP_UNDEFINED_KEY_TYPE = -1, PPP_UNDEFINED_KEY_TYPE = -1,
PPP_LOAD_MODULE_TYPE = 0, PPP_LOAD_MODULE_TYPE = 0,
PPP_DEVICE_TYPE, PPP_DEVICE_TYPE,
@@ -29,7 +29,7 @@ enum PPP_MODULE_KEY_TYPE {
}; };
// PPP events as defined in RFC 1661 (with one exception: PPP_UP_FAILED_EVENT) // PPP events as defined in RFC 1661 (with one exception: PPP_UP_FAILED_EVENT)
enum PPP_EVENT { enum ppp_event {
PPP_UP_FAILED_EVENT, PPP_UP_FAILED_EVENT,
PPP_UP_EVENT, PPP_UP_EVENT,
PPP_DOWN_EVENT, PPP_DOWN_EVENT,
@@ -51,7 +51,7 @@ enum PPP_EVENT {
// LCP protocol codes as defined in RFC 1661 // LCP protocol codes as defined in RFC 1661
// ToDo: add LCP extensions // ToDo: add LCP extensions
enum PPP_LCP_CODE { enum ppp_lcp_code {
PPP_CONFIGURE_REQUEST = 1, PPP_CONFIGURE_REQUEST = 1,
PPP_CONFIGURE_ACK = 2, PPP_CONFIGURE_ACK = 2,
PPP_CONFIGURE_NAK = 3, PPP_CONFIGURE_NAK = 3,
@@ -83,6 +83,7 @@ class PPPDevice {
char fName[PPP_HANDLER_NAME_LENGTH_LIMIT + 1]; char fName[PPP_HANDLER_NAME_LENGTH_LIMIT + 1];
PPPInterface& fInterface; PPPInterface& fInterface;
driver_parameter *fSettings; driver_parameter *fSettings;
status_t fInitStatus;
}; };
@@ -17,8 +17,8 @@
class PPPEncapsulator { class PPPEncapsulator {
public: public:
PPPEncapsulator(const char *name, PPP_PHASE phase, PPPEncapsulator(const char *name, ppp_phase phase,
PPP_ENCAPSULATION_LEVEL level, uint16 protocol, ppp_encapsulation_level level, uint16 protocol,
int32 addressFamily, uint32 overhead, int32 addressFamily, uint32 overhead,
PPPInterface& interface, driver_parameter *settings, PPPInterface& interface, driver_parameter *settings,
int32 flags = PPP_NO_FLAGS); int32 flags = PPP_NO_FLAGS);
@@ -29,10 +29,10 @@ class PPPEncapsulator {
const char *Name() const const char *Name() const
{ return fName; } { return fName; }
PPP_PHASE Phase() const ppp_phase Phase() const
{ return fPhase; } { return fPhase; }
PPP_ENCAPSULATION_LEVEL Level() const ppp_encapsulation_level Level() const
{ return fLevel; } { return fLevel; }
uint32 Overhead() const uint32 Overhead() const
{ return fOverhead; } { return fOverhead; }
@@ -102,8 +102,8 @@ class PPPEncapsulator {
private: private:
char fName[PPP_HANDLER_NAME_LENGTH_LIMIT + 1]; char fName[PPP_HANDLER_NAME_LENGTH_LIMIT + 1];
PPP_PHASE fPhase; ppp_phase fPhase;
PPP_ENCAPSULATION_LEVEL fLevel; ppp_encapsulation_level fLevel;
uint16 fProtocol; uint16 fProtocol;
int32 fAddressFamily; int32 fAddressFamily;
PPPInterface& fInterface; PPPInterface& fInterface;
@@ -114,7 +114,8 @@ class PPPEncapsulator {
bool fEnabled; bool fEnabled;
bool fUpRequested; bool fUpRequested;
PPP_PHASE fConnectionStatus; ppp_phase fConnectionStatus;
status_t fInitStatus;
}; };
+21 -10
View File
@@ -68,16 +68,24 @@ class PPPInterface {
struct ifq *InQueue() const struct ifq *InQueue() const
{ return fInQueue; } { return fInQueue; }
// delays
uint32 DialRetryDelay() const
{ return fDialRetryDelay; }
uint32 RedialDelay() const
{ return fRedialDelay; }
// idle handling // idle handling
bigtime_t IdleSince() const uint32 IdleSince() const
{ return fIdleSince; } { return fIdleSince; }
bigtime_t DisconnectAfterIdleSince() const uint32 DisconnectAfterIdleSince() const
{ return fDisconnectAfterIdleSince; } { return fDisconnectAfterIdleSince; }
void SetMRU(uint32 MRU); void 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)
{ 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,12 +133,12 @@ class PPPInterface {
bool DoesDialOnDemand() const bool DoesDialOnDemand() const
{ return fDialOnDemand; } { return fDialOnDemand; }
PPP_MODE Mode() const ppp_mode Mode() const
{ return fMode; } { return fMode; }
// client or server mode? // client or server mode?
PPP_STATE State() const ppp_state State() const
{ return fStateMachine.State(); } { return fStateMachine.State(); }
PPP_PHASE Phase() const ppp_phase Phase() const
{ return fStateMachine.Phase(); } { return fStateMachine.Phase(); }
bool Up(); bool Up();
@@ -140,14 +148,14 @@ class PPPInterface {
PPPReportManager& ReportManager() PPPReportManager& ReportManager()
{ return fReportManager; } { return fReportManager; }
bool Report(PPP_REPORT_TYPE type, int32 code, void *data, int32 length) bool Report(ppp_report_type type, int32 code, void *data, int32 length)
{ return fReportManager.Report(type, code, data, length); } { return fReportManager.Report(type, code, data, length); }
// returns false if reply was bad (or an error occured) // returns false if reply was bad (or an error occured)
bool LoadModules(driver_settings *settings, bool LoadModules(driver_settings *settings,
int32 start, int32 count); int32 start, int32 count);
bool LoadModule(const char *name, driver_parameter *parameter, bool LoadModule(const char *name, driver_parameter *parameter,
PPP_MODULE_KEY_TYPE type); ppp_module_key_type type);
status_t Send(struct mbuf *packet, uint16 protocol); status_t Send(struct mbuf *packet, uint16 protocol);
status_t Receive(struct mbuf *packet, uint16 protocol); status_t Receive(struct mbuf *packet, uint16 protocol);
@@ -170,7 +178,9 @@ class PPPInterface {
void CalculateInterfaceMTU(); void CalculateInterfaceMTU();
void CalculateBaudRate(); void CalculateBaudRate();
void Redial(); bool SetupDialOnDemand();
void Redial(uint32 delay);
// multilink methods // multilink methods
void SetParent(PPPInterface *parent) void SetParent(PPPInterface *parent)
@@ -190,10 +200,11 @@ class PPPInterface {
thread_id fRedialThread; thread_id fRedialThread;
uint32 fDialRetry, fDialRetriesLimit; uint32 fDialRetry, fDialRetriesLimit;
uint32 fDialRetryDelay, fRedialDelay;
ppp_manager_info *fManager; ppp_manager_info *fManager;
bigtime_t fIdleSince, fDisconnectAfterIdleSince; uint32 fIdleSince, fDisconnectAfterIdleSince;
uint32 fMRU, fInterfaceMTU, fHeaderLength; uint32 fMRU, fInterfaceMTU, fHeaderLength;
PPPInterface *fParent; PPPInterface *fParent;
@@ -204,7 +215,7 @@ class PPPInterface {
vint32 fAccesing; vint32 fAccesing;
PPP_MODE fMode; ppp_mode fMode;
PPPDevice *fDevice; PPPDevice *fDevice;
PPPEncapsulator *fFirstEncapsulator; PPPEncapsulator *fFirstEncapsulator;
+2
View File
@@ -56,12 +56,14 @@ class PPPLCP : public PPPProtocol {
int32 CountOptionHandlers() const int32 CountOptionHandlers() const
{ return fOptionHandlers.CountItems(); } { return fOptionHandlers.CountItems(); }
PPPOptionHandler *OptionHandlerAt(int32 index) const; PPPOptionHandler *OptionHandlerAt(int32 index) const;
PPPOptionHandler *OptionHandlerFor(uint8 type, int32 *start = NULL) const;
bool AddLCPExtension(PPPLCPExtension *extension); bool AddLCPExtension(PPPLCPExtension *extension);
bool RemoveLCPExtension(PPPLCPExtension *extension); bool RemoveLCPExtension(PPPLCPExtension *extension);
int32 CountLCPExtensions() const int32 CountLCPExtensions() const
{ return fLCPExtensions.CountItems(); } { return fLCPExtensions.CountItems(); }
PPPLCPExtension *LCPExtensionAt(int32 index) const; PPPLCPExtension *LCPExtensionAt(int32 index) const;
PPPLCPExtension *LCPExtensionFor(uint8 code, int32 *start = NULL) const;
PPPEncapsulator *Target() const PPPEncapsulator *Target() const
{ return fTarget; } { return fTarget; }
@@ -54,6 +54,7 @@ class PPPLCPExtension {
uint8 fCode; uint8 fCode;
bool fEnabled; bool fEnabled;
status_t fInitStatus;
}; };
+2 -2
View File
@@ -17,7 +17,7 @@
// create_interface() returns this value on failure // create_interface() returns this value on failure
// this allows you to ask for specific interface_ids // this allows you to ask for specific interface_ids
enum PPP_INTERFACE_FILTER { enum ppp_interface_filter {
PPP_ALL_INTERFACES, PPP_ALL_INTERFACES,
PPP_REGISTERED_INTERFACES, PPP_REGISTERED_INTERFACES,
PPP_UNREGISTERED_INTERFACES PPP_UNREGISTERED_INTERFACES
@@ -40,7 +40,7 @@ typedef struct ppp_manager_info {
status_t (*control)(interface_id ID, uint32 op, void *data, size_t length); status_t (*control)(interface_id ID, uint32 op, void *data, size_t length);
status_t (*get_interfaces)(interface_id **interfaces, uint32 *count, status_t (*get_interfaces)(interface_id **interfaces, uint32 *count,
PPP_INTERFACE_FILTER filter = PPP_REGISTERED_INTERFACES); ppp_interface_filter filter = PPP_REGISTERED_INTERFACES);
// the user is responsible for free()'ing the interface_id array // the user is responsible for free()'ing the interface_id array
} ppp_manager_info; } ppp_manager_info;
+1 -1
View File
@@ -17,7 +17,7 @@ typedef struct ppp_module_info {
module_info minfo; module_info minfo;
status_t (*control)(uint32 op, void *data, size_t length); status_t (*control)(uint32 op, void *data, size_t length);
status_t (*add_to)(PPPInterface& mainInterface, PPPInterface *subInterface, status_t (*add_to)(PPPInterface& mainInterface, PPPInterface *subInterface,
driver_parameter *settings, PPP_MODULE_KEY_TYPE type); driver_parameter *settings, ppp_module_key_type type);
// multilink: handlers that must run on a real device // multilink: handlers that must run on a real device
// should be added to subInterface (may be NULL) // should be added to subInterface (may be NULL)
// while mainInterface handlers are used for the // while mainInterface handlers are used for the
@@ -19,7 +19,7 @@ class PPPConfigurePacket;
class PPPOptionHandler { class PPPOptionHandler {
public: public:
PPPOptionHandler(const char *name, PPPInterface& interface, PPPOptionHandler(const char *name, uint8 type, PPPInterface& interface,
driver_parameter *settings); driver_parameter *settings);
virtual ~PPPOptionHandler(); virtual ~PPPOptionHandler();
@@ -28,6 +28,9 @@ class PPPOptionHandler {
const char *Name() const const char *Name() const
{ return fName; } { return fName; }
uint8 Type() const
{ return fType; }
PPPInterface& Interface() const PPPInterface& Interface() const
{ return fInterface; } { return fInterface; }
driver_parameter *Settings() const driver_parameter *Settings() const
@@ -62,10 +65,12 @@ class PPPOptionHandler {
private: private:
char fName[PPP_HANDLER_NAME_LENGTH_LIMIT + 1]; char fName[PPP_HANDLER_NAME_LENGTH_LIMIT + 1];
uint8 fType;
PPPInterface& fInterface; PPPInterface& fInterface;
driver_parameter *fSettings; driver_parameter *fSettings;
bool fEnabled; bool fEnabled;
status_t fInitStatus;
}; };
+17 -5
View File
@@ -17,9 +17,10 @@ class PPPInterface;
class PPPProtocol { class PPPProtocol {
public: public:
PPPProtocol(const char *name, PPP_PHASE phase, uint16 protocol, PPPProtocol(const char *name, ppp_phase phase, uint16 protocol,
int32 addressFamily, PPPInterface& interface, int32 addressFamily, PPPInterface& interface,
driver_parameter *settings, int32 flags = PPP_NO_FLAGS); driver_parameter *settings, int32 flags = PPP_NO_FLAGS,
ppp_authenticator_type authenticatorType = PPP_NO_AUTHENTICATOR);
virtual ~PPPProtocol(); virtual ~PPPProtocol();
virtual status_t InitCheck() const; virtual status_t InitCheck() const;
@@ -27,7 +28,7 @@ class PPPProtocol {
const char *Name() const const char *Name() const
{ return fName; } { return fName; }
PPP_PHASE Phase() const ppp_phase Phase() const
{ return fPhase; } { return fPhase; }
PPPInterface& Interface() const PPPInterface& Interface() const
@@ -43,6 +44,9 @@ class PPPProtocol {
int32 Flags() const int32 Flags() const
{ return fFlags; } { return fFlags; }
ppp_authenticator_type AuthenticatorType() const
{ return fAuthenticatorType; }
void SetEnabled(bool enabled = true); void SetEnabled(bool enabled = true);
bool IsEnabled() const bool IsEnabled() const
{ return fEnabled; } { return fEnabled; }
@@ -52,8 +56,14 @@ class PPPProtocol {
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 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 bool Up() = 0; virtual bool Up() = 0;
virtual bool Down() = 0; virtual bool Down() = 0;
// if DialOnDemand is implemented 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
@@ -82,16 +92,18 @@ class PPPProtocol {
private: private:
char fName[PPP_HANDLER_NAME_LENGTH_LIMIT + 1]; char fName[PPP_HANDLER_NAME_LENGTH_LIMIT + 1];
PPP_PHASE fPhase; ppp_phase fPhase;
uint16 fProtocol; uint16 fProtocol;
int32 fAddressFamily; int32 fAddressFamily;
PPPInterface& fInterface; PPPInterface& fInterface;
driver_parameter *fSettings; driver_parameter *fSettings;
int32 fFlags; int32 fFlags;
ppp_authenticator_type fAuthenticatorType;
bool fEnabled; bool fEnabled;
bool fUpRequested; bool fUpRequested;
PPP_PHASE fConnectionStatus; ppp_phase fConnectionStatus;
status_t fInitStatus;
}; };
@@ -23,11 +23,11 @@ class PPPReportManager {
PPPReportManager(BLocker& lock); PPPReportManager(BLocker& lock);
~PPPReportManager(); ~PPPReportManager();
void EnableReports(PPP_REPORT_TYPE type, thread_id thread, void EnableReports(ppp_report_type type, thread_id thread,
int32 flags = PPP_NO_FLAGS); int32 flags = PPP_NO_FLAGS);
void DisableReports(PPP_REPORT_TYPE type, thread_id thread); void DisableReports(ppp_report_type type, thread_id thread);
bool DoesReport(PPP_REPORT_TYPE type, thread_id thread); bool DoesReport(ppp_report_type type, thread_id thread);
bool Report(PPP_REPORT_TYPE type, int32 code, void *data, int32 length); bool Report(ppp_report_type type, int32 code, void *data, int32 length);
// returns false if reply was bad (or an error occured) // returns false if reply was bad (or an error occured)
private: private:
@@ -34,14 +34,14 @@ class PPPStateMachine {
PPPStateMachine& operator= (const PPPStateMachine& copy); PPPStateMachine& operator= (const PPPStateMachine& copy);
public: public:
PPPInterface *Interface() const PPPInterface& Interface() const
{ return fInterface; } { return fInterface; }
PPPLCP& LCP() const PPPLCP& LCP() const
{ return fLCP; } { return fLCP; }
PPP_STATE State() const ppp_state State() const
{ return fState; } { return fState; }
PPP_PHASE Phase() const ppp_phase Phase() const
{ return fPhase; } { return fPhase; }
uint8 NextID(); uint8 NextID();
@@ -63,7 +63,7 @@ class PPPStateMachine {
void AuthenticationDenied(const char *name); void AuthenticationDenied(const char *name);
const char *AuthenticationName() const const char *AuthenticationName() const
{ return fAuthenticationName; } { return fAuthenticationName; }
PPP_AUTHENTICATION_STATUS AuthenticationStatus() const ppp_authentication_status AuthenticationStatus() const
{ return fAuthenticationStatus; } { return fAuthenticationStatus; }
void PeerAuthenticationRequested(); void PeerAuthenticationRequested();
@@ -71,13 +71,13 @@ class PPPStateMachine {
void PeerAuthenticationDenied(const char *name); void PeerAuthenticationDenied(const char *name);
const char *PeerAuthenticationName() const const char *PeerAuthenticationName() const
{ return fPeerAuthenticationName; } { return fPeerAuthenticationName; }
PPP_AUTHENTICATION_STATUS PeerAuthenticationStatus() const ppp_authentication_status PeerAuthenticationStatus() const
{ return fPeerAuthenticationStatus; } { return fPeerAuthenticationStatus; }
// sub-interface events // sub-interface events
void UpFailedEvent(PPPInterface *interface); void UpFailedEvent(PPPInterface& interface);
void UpEvent(PPPInterface *interface); void UpEvent(PPPInterface& interface);
void DownEvent(PPPInterface *interface); void DownEvent(PPPInterface& interface);
// protocol events // protocol events
void UpFailedEvent(PPPProtocol *protocol); void UpFailedEvent(PPPProtocol *protocol);
@@ -101,8 +101,8 @@ class PPPStateMachine {
{ return fLock; } { return fLock; }
// private StateMachine methods // private StateMachine methods
void NewState(PPP_STATE next); void NewState(ppp_state next);
void NewPhase(PPP_PHASE next); void NewPhase(ppp_phase next);
// private events // private events
void OpenEvent(); void OpenEvent();
@@ -127,7 +127,7 @@ class PPPStateMachine {
void RXJEvent(struct mbuf *packet); void RXJEvent(struct mbuf *packet);
// actions // actions
void IllegalEvent(PPP_EVENT event); void IllegalEvent(ppp_event event);
void ThisLayerUp(); void ThisLayerUp();
void ThisLayerDown(); void ThisLayerDown();
void ThisLayerStarted(); void ThisLayerStarted();
@@ -147,19 +147,19 @@ class PPPStateMachine {
void DownProtocols(); void DownProtocols();
void DownEncapsulators(); void DownEncapsulators();
void ResetOptionHandlers(); void ResetLCPHandlers();
private: private:
PPPInterface *fInterface; PPPInterface& fInterface;
PPPLCP& fLCP; PPPLCP& fLCP;
PPP_PHASE fPhase; ppp_phase fPhase;
PPP_STATE fState; ppp_state fState;
vint32 fID; vint32 fID;
uint32 fMagicNumber; uint32 fMagicNumber;
PPP_AUTHENTICATION_STATUS fAuthenticationStatus, ppp_authentication_status fAuthenticationStatus,
fPeerAuthenticationStatus; fPeerAuthenticationStatus;
char *fAuthenticationName, *fPeerAuthenticationName; char *fAuthenticationName, *fPeerAuthenticationName;
+1 -1
View File
@@ -17,7 +17,7 @@
template<class T> template<class T>
inline inline
bool bool
is_handler_allowed(T& handler, PPP_STATE state, PPP_PHASE phase) is_handler_allowed(T& handler, ppp_state state, ppp_phase phase)
{ {
if(handler.Protocol() == PPP_LCP_PROTOCOL) if(handler.Protocol() == PPP_LCP_PROTOCOL)
return true; return true;
+11 -10
View File
@@ -25,7 +25,7 @@
#define PPP_USER_OPS_START PPP_OPS_START + 32 * PPP_RESERVE_OPS_COUNT #define PPP_USER_OPS_START PPP_OPS_START + 32 * PPP_RESERVE_OPS_COUNT
enum PPP_CONTROL_OPS { enum ppp_control_ops {
// ----------------------------------------------------- // -----------------------------------------------------
// PPPInterface // PPPInterface
PPPC_GET_INTERFACE_INFO = PPP_INTERFACE_OPS_START, PPPC_GET_INTERFACE_INFO = PPP_INTERFACE_OPS_START,
@@ -50,7 +50,6 @@ enum PPP_CONTROL_OPS {
// ----------------------------------------------------- // -----------------------------------------------------
// PPPDevice // PPPDevice
PPPC_GET_DEVICE_INFO = PPP_DEVICE_OPS_START, PPPC_GET_DEVICE_INFO = PPP_DEVICE_OPS_START,
PPPC_SET_MTU,
// ----------------------------------------------------- // -----------------------------------------------------
// ----------------------------------------------------- // -----------------------------------------------------
@@ -86,12 +85,11 @@ typedef struct ppp_control_info {
typedef struct ppp_interface_info { typedef struct ppp_interface_info {
const driver_settings *settings; const driver_settings *settings;
struct ifnet *ifnet;
PPP_MODE mode; ppp_mode mode;
PPP_STATE state; ppp_state state;
PPP_PHASE phase; ppp_phase phase;
PPP_AUTHENTICATION_STATUS authenticationStatus, peerAuthenticationStatus; ppp_authentication_status authenticationStatus, peerAuthenticationStatus;
uint32 protocolsCount, encapsulatorsCount, optionHandlersCount, uint32 protocolsCount, encapsulatorsCount, optionHandlersCount,
LCPExtensionsCount, childrenCount; LCPExtensionsCount, childrenCount;
@@ -128,7 +126,7 @@ typedef struct ppp_handler_info {
// general // general
const driver_parameter *settings; const driver_parameter *settings;
PPP_PHASE phase; ppp_phase phase;
int32 addressFamily, flags; int32 addressFamily, flags;
uint16 protocol; uint16 protocol;
@@ -136,15 +134,18 @@ typedef struct ppp_handler_info {
// only protocol and encapsulator // only protocol and encapsulator
bool isUpRequested; bool isUpRequested;
PPP_PHASE connectionStatus; ppp_phase connectionStatus;
// there are four possible states: // there are four possible states:
// PPP_ESTABLISHED_PHASE - IsUp() == true // PPP_ESTABLISHED_PHASE - IsUp() == true
// PPP_DOWN_PHASE - IsDown() == true // PPP_DOWN_PHASE - IsDown() == true
// PPP_ESTABLISHMENT_PHASE - IsGoingUp() == true // PPP_ESTABLISHMENT_PHASE - IsGoingUp() == true
// PPP_TERMINATION_PHASE - IsGoingDown() == true // PPP_TERMINATION_PHASE - IsGoingDown() == true
// only protocol
ppp_authenticator_type authenticatorType;
// only encapsulator // only encapsulator
PPP_ENCAPSULATION_LEVEL level; ppp_encapsulation_level level;
uint32 overhead; uint32 overhead;
} ppp_handler_info; } ppp_handler_info;
typedef struct ppp_handler_info_t { typedef struct ppp_handler_info_t {
+12 -5
View File
@@ -80,7 +80,7 @@ enum {
}; };
// phase when the protocol is brought up // phase when the protocol is brought up
enum PPP_PHASE { enum ppp_phase {
// the following may be used by protocols // the following may be used by protocols
PPP_AUTHENTICATION_PHASE = 15, PPP_AUTHENTICATION_PHASE = 15,
PPP_NCP_PHASE = 20, PPP_NCP_PHASE = 20,
@@ -99,20 +99,27 @@ enum PPP_PHASE {
}; };
// this defines the order in which the packets get encapsulated // this defines the order in which the packets get encapsulated
enum PPP_ENCAPSULATION_LEVEL { enum ppp_encapsulation_level {
PPP_MULTILINK_LEVEL = 0, PPP_MULTILINK_LEVEL = 0,
PPP_ENCRYPTION_LEVEL = 5, PPP_ENCRYPTION_LEVEL = 5,
PPP_COMPRESSION_LEVEL = 10 PPP_COMPRESSION_LEVEL = 10
}; };
// we can be a ppp client or a ppp server interface // we can be a ppp client or a ppp server interface
enum PPP_MODE { enum ppp_mode {
PPP_CLIENT_MODE = 0, PPP_CLIENT_MODE = 0,
PPP_SERVER_MODE PPP_SERVER_MODE
}; };
// PPPProtocol serves as authenticator
enum ppp_authenticator_type {
PPP_NO_AUTHENTICATOR = 0,
PPP_LOCAL_AUTHENTICATOR,
PPP_PEER_AUTHENTICATOR
};
// authentication status // authentication status
enum PPP_AUTHENTICATION_STATUS { enum ppp_authentication_status {
PPP_AUTHENTICATION_FAILED = -1, PPP_AUTHENTICATION_FAILED = -1,
PPP_NOT_AUTHENTICATED = 0, PPP_NOT_AUTHENTICATED = 0,
PPP_AUTHENTICATION_SUCCESSFUL = 1, PPP_AUTHENTICATION_SUCCESSFUL = 1,
@@ -120,7 +127,7 @@ enum PPP_AUTHENTICATION_STATUS {
}; };
// PPP states as defined in RFC 1661 // PPP states as defined in RFC 1661
enum PPP_STATE { enum ppp_state {
PPP_INITIAL_STATE, PPP_INITIAL_STATE,
PPP_STARTING_STATE, PPP_STARTING_STATE,
PPP_CLOSED_STATE, PPP_CLOSED_STATE,
@@ -17,7 +17,7 @@
// the code of receive_data() must have this value // the code of receive_data() must have this value
// report flags // report flags
enum PPP_REPORT_FLAGS { enum ppp_report_flags {
PPP_WAIT_FOR_REPLY = 0x1, PPP_WAIT_FOR_REPLY = 0x1,
PPP_REMOVE_AFTER_REPORT = 0x2, PPP_REMOVE_AFTER_REPORT = 0x2,
PPP_NO_REPLY_TIMEOUT = 0x4 PPP_NO_REPLY_TIMEOUT = 0x4
@@ -25,7 +25,7 @@ enum PPP_REPORT_FLAGS {
// report types // report types
// the first 16 report types are reserved for the interface manager // the first 16 report types are reserved for the interface manager
enum PPP_REPORT_TYPE { enum ppp_report_type {
PPP_ALL_REPORTS = -1, PPP_ALL_REPORTS = -1,
// used only when disabling reports // used only when disabling reports
PPP_DESTRUCTION_REPORT = 16, PPP_DESTRUCTION_REPORT = 16,
@@ -35,7 +35,7 @@ enum PPP_REPORT_TYPE {
}; };
// report codes (type-specific) // report codes (type-specific)
enum PPP_CONNECTION_REPORT_CODES { enum ppp_connection_report_codes {
PPP_REPORT_GOING_UP = 0, PPP_REPORT_GOING_UP = 0,
PPP_REPORT_UP_SUCCESSFUL = 1, PPP_REPORT_UP_SUCCESSFUL = 1,
PPP_REPORT_DOWN_SUCCESSFUL = 2, PPP_REPORT_DOWN_SUCCESSFUL = 2,
@@ -57,7 +57,7 @@ typedef struct ppp_report_packet {
typedef struct ppp_report_request { typedef struct ppp_report_request {
PPP_REPORT_TYPE type; ppp_report_type type;
thread_id thread; thread_id thread;
int32 flags; int32 flags;
} ppp_report_request; } ppp_report_request;
@@ -107,21 +107,6 @@ PPPConfigurePacket::ItemAt(int32 index) const
} }
bool
PPPConfigurePacket::HasItemWithType(uint8 type) const
{
ppp_configure_item *item;
for(int32 index; index < CountItems(); index++) {
item = ItemAt(index);
if(item && item->type == type)
return true;
}
return false;
}
ppp_configure_item* ppp_configure_item*
PPPConfigurePacket::ItemWithType(uint8 type) const PPPConfigurePacket::ItemWithType(uint8 type) const
{ {
+2 -9
View File
@@ -23,7 +23,7 @@ PPPDevice::PPPDevice(const char *name, PPPInterface& interface,
} else } else
strcpy(fName, "???"); strcpy(fName, "???");
interface.SetDevice(this); fInitStatus = interface.SetDevice(this) ? B_OK : B_ERROR;
} }
@@ -39,7 +39,7 @@ PPPDevice::InitCheck() const
if(!Settings()) if(!Settings())
return B_ERROR; return B_ERROR;
return B_OK; return fInitStatus;
} }
@@ -62,13 +62,6 @@ PPPDevice::Control(uint32 op, void *data, size_t length)
info->outputBytesCount = CountOutputBytes(); info->outputBytesCount = CountOutputBytes();
} break; } break;
case PPPC_SET_MTU:
if(length < sizeof(uint32) || !data)
return B_ERROR;
return SetMTU(*((uint32*)data)) ? B_OK : B_ERROR;
break;
default: default:
return PPP_UNHANDLED; return PPP_UNHANDLED;
} }
@@ -11,8 +11,8 @@
#include <PPPControl.h> #include <PPPControl.h>
PPPEncapsulator::PPPEncapsulator(const char *name, PPP_PHASE phase, PPPEncapsulator::PPPEncapsulator(const char *name, ppp_phase phase,
PPP_ENCAPSULATION_LEVEL level, uint16 protocol, ppp_encapsulation_level level, uint16 protocol,
int32 addressFamily, uint32 overhead, int32 addressFamily, uint32 overhead,
PPPInterface& interface, driver_parameter *settings, PPPInterface& interface, driver_parameter *settings,
int32 flags = PPP_NO_FLAGS) int32 flags = PPP_NO_FLAGS)
@@ -27,7 +27,7 @@ PPPEncapsulator::PPPEncapsulator(const char *name, PPP_PHASE phase,
} else } else
strcpy(fName, "???"); strcpy(fName, "???");
interface.AddEncapsulator(this); fInitStatus = interface.AddEncapsulator(this) ? B_OK : B_ERROR;
} }
@@ -43,7 +43,7 @@ PPPEncapsulator::InitCheck() const
if(!Settings()) if(!Settings())
return B_ERROR; return B_ERROR;
return B_OK; return fInitStatus;
} }
+78 -18
View File
@@ -40,6 +40,7 @@
typedef struct redial_info { typedef struct redial_info {
PPPInterface *interface; PPPInterface *interface;
thread_id *thread; thread_id *thread;
uint32 delay;
} redial_info; } redial_info;
status_t redial_thread(void *data); status_t redial_thread(void *data);
@@ -54,9 +55,16 @@ PPPInterface::PPPInterface(uint32 ID, driver_settings *settings,
: fID(ID), fSettings(dup_driver_settings(settings)), : fID(ID), fSettings(dup_driver_settings(settings)),
fStateMachine(*this), fLCP(*this), fReportManager(StateMachine().Locker()), fStateMachine(*this), fLCP(*this), fReportManager(StateMachine().Locker()),
fIfnet(NULL), fUpThread(-1), fRedialThread(-1), fDialRetry(0), fIfnet(NULL), fUpThread(-1), fRedialThread(-1), fDialRetry(0),
fDialRetriesLimit(0), fIdleSince(0), fMRU(1500), fDevice(NULL), fDialRetriesLimit(0), fIdleSince(0), fMRU(1500), fInterfaceMTU(1498),
fHeaderLength(2), fAutoRedial(false), fDialOnDemand(false), fDevice(NULL),
fFirstEncapsulator(NULL), fLock(StateMachine().Locker()), fDeleteCounter(0) fFirstEncapsulator(NULL), fLock(StateMachine().Locker()), fDeleteCounter(0)
{ {
// set up dial delays
fDialRetryDelay = 3000;
// 3s delay between each new attempt to redial
fRedialDelay = 1000;
// 1s delay between lost connection and redial
// set up queue // set up queue
fInQueue = start_ifq(); fInQueue = start_ifq();
fInQueueThread = spawn_thread(in_queue_thread, "PPPInterface: in_queue_thread", fInQueueThread = spawn_thread(in_queue_thread, "PPPInterface: in_queue_thread",
@@ -78,7 +86,7 @@ PPPInterface::PPPInterface(uint32 ID, driver_settings *settings,
if(!fSettings) { if(!fSettings) {
fMode = PPP_CLIENT_MODE; fMode = PPP_CLIENT_MODE;
fDisconnectAfterIdleSince = 0; fInitStatus = B_ERROR;
return; return;
} }
@@ -89,7 +97,7 @@ PPPInterface::PPPInterface(uint32 ID, driver_settings *settings,
if(!value) if(!value)
fDisconnectAfterIdleSince = 0; fDisconnectAfterIdleSince = 0;
else else
fDisconnectAfterIdleSince = atoi(value) * 1000000; fDisconnectAfterIdleSince = atoi(value) * 1000;
if(fDisconnectAfterIdleSince < 0) if(fDisconnectAfterIdleSince < 0)
fDisconnectAfterIdleSince = 0; fDisconnectAfterIdleSince = 0;
@@ -152,6 +160,8 @@ PPPInterface::~PPPInterface()
stop_ifq(InQueue()); stop_ifq(InQueue());
wait_for_thread(fInQueueThread, &tmp); wait_for_thread(fInQueueThread, &tmp);
send_data_with_timeout(fRedialThread, 0, NULL, 0, 200);
// tell thread that we are being destroyed (200ms timeout)
wait_for_thread(fRedialThread, &tmp); wait_for_thread(fRedialThread, &tmp);
while(CountChildren()) while(CountChildren())
@@ -240,7 +250,6 @@ PPPInterface::Control(uint32 op, void *data, size_t length)
ppp_interface_info *info = (ppp_interface_info*) data; ppp_interface_info *info = (ppp_interface_info*) data;
memset(info, 0, sizeof(ppp_interface_info_t)); memset(info, 0, sizeof(ppp_interface_info_t));
info->settings = Settings(); info->settings = Settings();
info->ifnet = Ifnet();
info->mode = Mode(); info->mode = Mode();
info->state = State(); info->state = State();
info->phase = Phase(); info->phase = Phase();
@@ -413,9 +422,12 @@ PPPInterface::AddProtocol(PPPProtocol *protocol)
LockerHelper locker(fLock); LockerHelper locker(fLock);
if(Phase() != PPP_DOWN_PHASE) if(Phase() != PPP_DOWN_PHASE
|| (protocol->AuthenticatorType() != PPP_NO_AUTHENTICATOR
&& ProtocolFor(protocol->Protocol())))
return false; return false;
// a running connection may not change // a running connection may not change and there may only be
// one authenticator protocol for each protocol number
fProtocols.AddItem(protocol); fProtocols.AddItem(protocol);
@@ -461,8 +473,8 @@ PPPProtocol*
PPPInterface::ProtocolFor(uint16 protocol, int32 *start = NULL) const PPPInterface::ProtocolFor(uint16 protocol, int32 *start = NULL) const
{ {
// The iteration style in this method is strange C/C++. // The iteration style in this method is strange C/C++.
// Explanation: I use this style because it makes extending ProtocolFor // Explanation: I use this style because it makes extending all XXXFor
// and EncapsulatorFor simpler as that they look very similar, now. // methods simpler as that they look very similar, now.
int32 index = start ? *start : 0; int32 index = start ? *start : 0;
@@ -674,18 +686,33 @@ PPPInterface::SetAutoRedial(bool autoredial = true)
void 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) if(Mode() != PPP_CLIENT_MODE)
return; return;
LockerHelper locker(fLock); LockerHelper locker(fLock);
if(DoesDialOnDemand() && !dialondemand && State() != PPP_OPENED_STATE) {
// as long as the protocols were not configured we can just delete us
Delete();
return;
}
fDialOnDemand = dialondemand; fDialOnDemand = dialondemand;
// check if we need to register/unregister // check if we need to register/unregister
if(!Ifnet() && fDialOnDemand) if(fDialOnDemand) {
RegisterInterface(); RegisterInterface();
else if(Ifnet() && !fDialOnDemand && Phase() == PPP_DOWN_PHASE) { if(Ifnet())
Ifnet()->if_flags |= IFF_RUNNING;
} else if(!fDialOnDemand && Phase() < PPP_ESTABLISHED_PHASE) {
UnregisterInterface(); UnregisterInterface();
// if we are already down we must delete us
if(Phase() == PPP_DOWN_PHASE)
Delete(); Delete();
} }
} }
@@ -925,7 +952,7 @@ PPPInterface::LoadModules(driver_settings *settings, int32 start, int32 count)
return false; return false;
// a running connection may not change // a running connection may not change
PPP_MODULE_KEY_TYPE type; ppp_module_key_type type;
// which type key was used for loading this module? // which type key was used for loading this module?
const char *name = NULL; const char *name = NULL;
@@ -982,7 +1009,7 @@ PPPInterface::LoadModules(driver_settings *settings, int32 start, int32 count)
bool bool
PPPInterface::LoadModule(const char *name, driver_parameter *parameter, PPPInterface::LoadModule(const char *name, driver_parameter *parameter,
PPP_MODULE_KEY_TYPE type) ppp_module_key_type type)
{ {
if(Phase() != PPP_DOWN_PHASE) if(Phase() != PPP_DOWN_PHASE)
return false; return false;
@@ -1042,7 +1069,7 @@ PPPInterface::Send(struct mbuf *packet, uint16 protocol)
// encapsulated. // encapsulated.
if(sending_protocol && sending_protocol->Flags() & PPP_ALWAYS_ALLOWED if(sending_protocol && sending_protocol->Flags() & PPP_ALWAYS_ALLOWED
&& is_handler_allowed(*sending_protocol, State(), Phase())) { && is_handler_allowed(*sending_protocol, State(), Phase())) {
fIdleSince = system_time(); fIdleSince = real_time_clock();
return SendToDevice(packet, protocol); return SendToDevice(packet, protocol);
} }
@@ -1055,7 +1082,7 @@ PPPInterface::Send(struct mbuf *packet, uint16 protocol)
if(sending_encapsulator && sending_encapsulator->Flags() & PPP_ALWAYS_ALLOWED if(sending_encapsulator && sending_encapsulator->Flags() & PPP_ALWAYS_ALLOWED
&& is_handler_allowed(*sending_encapsulator, State(), Phase())) { && is_handler_allowed(*sending_encapsulator, State(), Phase())) {
fIdleSince = system_time(); fIdleSince = real_time_clock();
return SendToDevice(packet, protocol); return SendToDevice(packet, protocol);
} }
@@ -1065,7 +1092,7 @@ PPPInterface::Send(struct mbuf *packet, uint16 protocol)
return B_ERROR; return B_ERROR;
} }
fIdleSince = system_time(); fIdleSince = real_time_clock();
// send to next up encapsulator // send to next up encapsulator
if(!fFirstEncapsulator) if(!fFirstEncapsulator)
@@ -1202,7 +1229,7 @@ PPPInterface::SendToDevice(struct mbuf *packet, uint16 protocol)
uint16 *header = mtod(packet, uint16*); uint16 *header = mtod(packet, uint16*);
*header = protocol; *header = protocol;
fIdleSince = system_time(); fIdleSince = real_time_clock();
// pass to device/children // pass to device/children
if(!IsMultilink() || Parent()) { if(!IsMultilink() || Parent()) {
@@ -1252,7 +1279,7 @@ PPPInterface::Pulse()
// check our idle time and disconnect if needed // check our idle time and disconnect if needed
if(fDisconnectAfterIdleSince > 0 && fIdleSince != 0 if(fDisconnectAfterIdleSince > 0 && fIdleSince != 0
&& fIdleSince - system_time() >= fDisconnectAfterIdleSince) { && fIdleSince - real_time_clock() >= fDisconnectAfterIdleSince) {
StateMachine().CloseEvent(); StateMachine().CloseEvent();
return; return;
} }
@@ -1276,6 +1303,8 @@ PPPInterface::RegisterInterface()
return true; return true;
// we are already registered // we are already registered
LockerHelper locker(fLock);
if(InitCheck() != B_OK) if(InitCheck() != B_OK)
return false; return false;
// we cannot register if something is wrong // we cannot register if something is wrong
@@ -1293,6 +1322,7 @@ PPPInterface::RegisterInterface()
return false; return false;
CalculateBaudRate(); CalculateBaudRate();
SetupDialOnDemand();
return true; return true;
} }
@@ -1305,6 +1335,8 @@ PPPInterface::UnregisterInterface()
return true; return true;
// we are already unregistered // we are already unregistered
LockerHelper locker(fLock);
// only MainInterfaces get an ifnet // only MainInterfaces get an ifnet
if(IsMultilink() && Parent()) if(IsMultilink() && Parent())
return true; return true;
@@ -1361,8 +1393,30 @@ 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() PPPInterface::Redial(uint32 delay)
{ {
if(fRedialThread != -1) if(fRedialThread != -1)
return; return;
@@ -1371,6 +1425,7 @@ PPPInterface::Redial()
redial_info info; redial_info info;
info.interface = this; info.interface = this;
info.thread = &fRedialThread; info.thread = &fRedialThread;
info.delay = delay;
fRedialThread = spawn_thread(redial_thread, "PPPInterface: redial_thread", fRedialThread = spawn_thread(redial_thread, "PPPInterface: redial_thread",
B_NORMAL_PRIORITY, NULL); B_NORMAL_PRIORITY, NULL);
@@ -1386,9 +1441,14 @@ redial_thread(void *data)
{ {
redial_info info; redial_info info;
thread_id sender; thread_id sender;
int32 code;
receive_data(&sender, &info, sizeof(redial_info)); receive_data(&sender, &info, sizeof(redial_info));
// we try to receive data instead of snooze, so we can quit on destruction
if(receive_data_with_timeout(&sender, &code, NULL, 0, info.delay) == B_OK)
return B_OK;
info.interface->Up(); info.interface->Up();
*info.thread = -1; *info.thread = -1;
+77 -29
View File
@@ -46,9 +46,10 @@ PPPLCP::AddOptionHandler(PPPOptionHandler *handler)
LockerHelper locker(StateMachine().Locker()); LockerHelper locker(StateMachine().Locker());
if(Phase() != PPP_DOWN_PHASE) if(Phase() != PPP_DOWN_PHASE || OptionHandlerFor(handler->Type()))
return false; return false;
// a running connection may not change // a running connection may not change and there may only be
// one handler per option type
return fOptionHandlers.AddItem(handler); return fOptionHandlers.AddItem(handler);
} }
@@ -79,6 +80,32 @@ PPPLCP::OptionHandlerAt(int32 index) const
} }
PPPOptionHandler*
PPPLCP::OptionHandlerFor(uint8 type, int32 *start = NULL) const
{
// The iteration style in this method is strange C/C++.
// Explanation: I use this style because it makes extending all XXXFor
// methods simpler as that they look very similar, now.
int32 index = start ? *start : 0;
if(index < 0)
return NULL;
PPPOptionHandler *current = OptionHandlerAt(index);
for(; current; current = OptionHandlerAt(++index)) {
if(current->Type() == type) {
if(start)
*start = index;
return current;
}
}
return NULL;
}
bool bool
PPPLCP::AddLCPExtension(PPPLCPExtension *extension) PPPLCP::AddLCPExtension(PPPLCPExtension *extension)
{ {
@@ -120,6 +147,32 @@ PPPLCP::LCPExtensionAt(int32 index) const
} }
PPPLCPExtension*
PPPLCP::LCPExtensionFor(uint8 code, int32 *start = NULL) const
{
// The iteration style in this method is strange C/C++.
// Explanation: I use this style because it makes extending all XXXFor
// methods simpler as that they look very similar, now.
int32 index = start ? *start : 0;
if(index < 0)
return NULL;
PPPLCPExtension *current = LCPExtensionAt(index);
for(; current; current = LCPExtensionAt(++index)) {
if(current->Code() == code) {
if(start)
*start = index;
return current;
}
}
return NULL;
}
uint32 uint32
PPPLCP::AdditionalOverhead() const PPPLCP::AdditionalOverhead() const
{ {
@@ -165,6 +218,15 @@ PPPLCP::Receive(struct mbuf *packet, uint16 protocol)
if(protocol != PPP_LCP_PROTOCOL) if(protocol != PPP_LCP_PROTOCOL)
return PPP_UNHANDLED; return PPP_UNHANDLED;
ppp_lcp_packet *data = mtod(packet, ppp_lcp_packet*);
// adjust length (remove padding)
int32 length = packet->m_len;
if(packet->m_flags & M_PKTHDR)
length = packet->m_pkthdr.len;
if(length - ntohs(data->length) != 0)
m_adj(packet, length);
struct mbuf *copy = m_gethdr(MT_DATA); struct mbuf *copy = m_gethdr(MT_DATA);
if(copy) { if(copy) {
copy->m_data += AdditionalOverhead(); copy->m_data += AdditionalOverhead();
@@ -172,8 +234,6 @@ PPPLCP::Receive(struct mbuf *packet, uint16 protocol)
memcpy(copy->m_data, packet->m_data, copy->m_len); memcpy(copy->m_data, packet->m_data, copy->m_len);
} }
ppp_lcp_packet *data = mtod(packet, ppp_lcp_packet*);
if(ntohs(data->length) < 4) if(ntohs(data->length) < 4)
return B_ERROR; return B_ERROR;
@@ -220,49 +280,37 @@ PPPLCP::Receive(struct mbuf *packet, uint16 protocol)
handled = false; handled = false;
} }
if(!copy)
return handled ? B_OK : B_ERROR;
packet = copy; packet = copy;
copy = NULL;
if(!packet)
return handled ? B_OK : B_ERROR;
status_t result = B_OK; status_t result = B_OK;
// Try to find LCP extensions that can handle this code. // Try to find LCP extensions that can handle this code.
// We must duplicate the packet in order to ask all handlers. // We must duplicate the packet in order to ask all handlers.
PPPLCPExtension *extension; int32 index = 0;
for(int32 index = 0; index < CountLCPExtensions(); index++) { PPPLCPExtension *extension = LCPExtensionFor(data->code, &index);
extension = LCPExtensionAt(index); for(; extension; extension = LCPExtensionFor(data->code, &(++index))) {
if(extension->IsEnabled() && extension->Code() == data->code) { if(!extension->IsEnabled())
if(!copy) { continue;
copy = m_gethdr(MT_DATA);
if(!copy)
return B_ERROR;
copy->m_data += AdditionalOverhead(); result = extension->Receive(packet, data->code);
copy->m_len = packet->m_len;
memcpy(copy->m_data, packet->m_data, copy->m_len);
}
result = extension->Receive(copy, data->code); // check return value and return it on error
if(result == B_OK)
if(result == B_OK) {
copy = NULL;
handled = true; handled = true;
} else if(result != PPP_UNHANDLED) else if(result != PPP_UNHANDLED) {
m_freem(packet);
return result; return result;
} }
} }
if(copy)
m_freem(copy);
if(!handled) { if(!handled) {
StateMachine().RUCEvent(packet, PPP_LCP_PROTOCOL, PPP_CODE_REJECT); StateMachine().RUCEvent(packet, PPP_LCP_PROTOCOL, PPP_CODE_REJECT);
return PPP_REJECTED; return PPP_REJECTED;
} }
if(packet)
m_freem(packet); m_freem(packet);
return result; return result;
@@ -20,7 +20,7 @@ PPPLCPExtension::PPPLCPExtension(const char *name, uint8 code, PPPInterface& int
} else } else
strcpy(fName, "???"); strcpy(fName, "???");
interface.LCP().AddLCPExtension(this); fInitStatus = interface.LCP().AddLCPExtension(this) ? B_OK : B_ERROR;
} }
@@ -36,7 +36,7 @@ PPPLCPExtension::InitCheck() const
if(!Settings()) if(!Settings())
return B_ERROR; return B_ERROR;
return B_OK; return fInitStatus;
} }
@@ -10,9 +10,9 @@
#include <PPPControl.h> #include <PPPControl.h>
PPPOptionHandler::PPPOptionHandler(const char *name, PPPInterface& interface, PPPOptionHandler::PPPOptionHandler(const char *name, uint8 type,
driver_parameter *settings) PPPInterface& interface, driver_parameter *settings)
: fInterface(interface), fSettings(settings), fEnabled(true) : fType(type), fInterface(interface), fSettings(settings), fEnabled(true)
{ {
if(name) { if(name) {
strncpy(fName, name, PPP_HANDLER_NAME_LENGTH_LIMIT); strncpy(fName, name, PPP_HANDLER_NAME_LENGTH_LIMIT);
@@ -20,7 +20,7 @@ PPPOptionHandler::PPPOptionHandler(const char *name, PPPInterface& interface,
} else } else
strcpy(fName, "???"); strcpy(fName, "???");
interface.LCP().AddOptionHandler(this); fInitStatus = interface.LCP().AddOptionHandler(this) ? B_OK : B_ERROR;
} }
@@ -36,7 +36,7 @@ PPPOptionHandler::InitCheck() const
if(!Settings()) if(!Settings())
return B_ERROR; return B_ERROR;
return B_OK; return fInitStatus;
} }
+19 -5
View File
@@ -12,12 +12,14 @@
#include <cstring> #include <cstring>
PPPProtocol::PPPProtocol(const char *name, PPP_PHASE phase, uint16 protocol, PPPProtocol::PPPProtocol(const char *name, ppp_phase phase, uint16 protocol,
int32 addressFamily, PPPInterface& interface, int32 addressFamily, PPPInterface& interface,
driver_parameter *settings, int32 flags = PPP_NO_FLAGS) driver_parameter *settings, int32 flags = PPP_NO_FLAGS,
ppp_authenticator_type authenticatorType = PPP_NO_AUTHENTICATOR)
: fPhase(phase), fProtocol(protocol), fAddressFamily(addressFamily), : fPhase(phase), fProtocol(protocol), fAddressFamily(addressFamily),
fInterface(interface), fSettings(settings), fFlags(flags), fInterface(interface), fSettings(settings), fFlags(flags),
fEnabled(true), fUpRequested(true), fConnectionStatus(PPP_DOWN_PHASE) fAuthenticatorType(authenticatorType), fEnabled(true),
fUpRequested(true), fConnectionStatus(PPP_DOWN_PHASE)
{ {
if(name) { if(name) {
strncpy(fName, name, PPP_HANDLER_NAME_LENGTH_LIMIT); strncpy(fName, name, PPP_HANDLER_NAME_LENGTH_LIMIT);
@@ -25,7 +27,11 @@ PPPProtocol::PPPProtocol(const char *name, PPP_PHASE phase, uint16 protocol,
} else } else
strcpy(fName, "???"); strcpy(fName, "???");
interface.AddProtocol(this); if(authenticatorType != PPP_NO_AUTHENTICATOR)
SetEnabled(false);
// only the active authenticator should be enabled
fInitStatus = interface.AddProtocol(this) ? B_OK : B_ERROR;
} }
@@ -41,7 +47,7 @@ PPPProtocol::InitCheck() const
if(!Settings()) if(!Settings())
return B_ERROR; return B_ERROR;
return B_OK; return fInitStatus;
} }
@@ -77,6 +83,7 @@ PPPProtocol::Control(uint32 op, void *data, size_t length)
info->isEnabled = IsEnabled(); info->isEnabled = IsEnabled();
info->isUpRequested = IsUpRequested(); info->isUpRequested = IsUpRequested();
info->connectionStatus = fConnectionStatus; info->connectionStatus = fConnectionStatus;
info->authenticatorType = AuthenticatorType();
} break; } break;
case PPPC_SET_ENABLED: case PPPC_SET_ENABLED:
@@ -94,6 +101,13 @@ PPPProtocol::Control(uint32 op, void *data, size_t length)
} }
status_t
PPPProtocol::SetupDialOnDemand()
{
return B_OK;
}
void void
PPPProtocol::Pulse() PPPProtocol::Pulse()
{ {
@@ -27,7 +27,7 @@ PPPReportManager::~PPPReportManager()
void void
PPPReportManager::EnableReports(PPP_REPORT_TYPE type, thread_id thread, PPPReportManager::EnableReports(ppp_report_type type, thread_id thread,
int32 flags = PPP_NO_FLAGS) int32 flags = PPP_NO_FLAGS)
{ {
LockerHelper locker(fLock); LockerHelper locker(fLock);
@@ -42,7 +42,7 @@ PPPReportManager::EnableReports(PPP_REPORT_TYPE type, thread_id thread,
void void
PPPReportManager::DisableReports(PPP_REPORT_TYPE type, thread_id thread) PPPReportManager::DisableReports(ppp_report_type type, thread_id thread)
{ {
LockerHelper locker(fLock); LockerHelper locker(fLock);
@@ -61,7 +61,7 @@ PPPReportManager::DisableReports(PPP_REPORT_TYPE type, thread_id thread)
bool bool
PPPReportManager::DoesReport(PPP_REPORT_TYPE type, thread_id thread) PPPReportManager::DoesReport(ppp_report_type type, thread_id thread)
{ {
LockerHelper locker(fLock); LockerHelper locker(fLock);
@@ -79,7 +79,7 @@ PPPReportManager::DoesReport(PPP_REPORT_TYPE type, thread_id thread)
bool bool
PPPReportManager::Report(PPP_REPORT_TYPE type, int32 code, void *data, int32 length) PPPReportManager::Report(ppp_report_type type, int32 code, void *data, int32 length)
{ {
if(length > PPP_REPORT_DATA_LIMIT) if(length > PPP_REPORT_DATA_LIMIT)
return false; return false;
+120 -113
View File
@@ -22,7 +22,7 @@
PPPStateMachine::PPPStateMachine(PPPInterface& interface) PPPStateMachine::PPPStateMachine(PPPInterface& interface)
: fInterface(&interface), fLCP(interface.LCP()), fPhase(PPP_DOWN_PHASE), : fInterface(interface), fLCP(interface.LCP()), fPhase(PPP_DOWN_PHASE),
fState(PPP_INITIAL_STATE), fID(system_time() & 0xFF), fMagicNumber(0), fState(PPP_INITIAL_STATE), fID(system_time() & 0xFF), fMagicNumber(0),
fAuthenticationStatus(PPP_NOT_AUTHENTICATED), fAuthenticationStatus(PPP_NOT_AUTHENTICATED),
fPeerAuthenticationStatus(PPP_NOT_AUTHENTICATED), fPeerAuthenticationStatus(PPP_NOT_AUTHENTICATED),
@@ -50,42 +50,49 @@ PPPStateMachine::NextID()
// remember: NewState() must always be called _after_ IllegalEvent() // remember: NewState() must always be called _after_ IllegalEvent()
// because IllegalEvent() also looks at the current state. // because IllegalEvent() also looks at the current state.
void void
PPPStateMachine::NewState(PPP_STATE next) PPPStateMachine::NewState(ppp_state next)
{ {
// maybe we do not need the timer anymore // maybe we do not need the timer anymore
if(next < PPP_CLOSING_STATE || next == PPP_OPENED_STATE) if(next < PPP_CLOSING_STATE || next == PPP_OPENED_STATE)
fNextTimeout = 0; fNextTimeout = 0;
if(State() == PPP_OPENED_STATE && next != State()) if(State() == PPP_OPENED_STATE && next != State())
ResetOptionHandlers(); ResetLCPHandlers();
fState = next; fState = next;
} }
void void
PPPStateMachine::NewPhase(PPP_PHASE next) PPPStateMachine::NewPhase(ppp_phase next)
{ {
// Report a down event to parent if we are not usable anymore. // the ifnet's running flag is set here and in PPPInterface::SetDialOnDemand()
// The report threads get their notification later.
if(Phase() == PPP_ESTABLISHED_PHASE && next != Phase()) {
if(Interface()->Ifnet())
Interface()->Ifnet()->if_flags &= ~IFF_RUNNING;
if(!Interface()->DoesDialOnDemand())
Interface()->UnregisterInterface();
if(Interface()->Parent())
Interface()->Parent()->StateMachine().DownEvent(Interface());
}
// there is nothing after established phase and nothing before down phase // there is nothing after established phase and nothing before down phase
if(next > PPP_ESTABLISHED_PHASE) if(next > PPP_ESTABLISHED_PHASE)
fPhase = PPP_ESTABLISHED_PHASE; next = PPP_ESTABLISHED_PHASE;
else if(next < PPP_DOWN_PHASE) else if(next < PPP_DOWN_PHASE)
fPhase = PPP_DOWN_PHASE; next = PPP_DOWN_PHASE;
else
// Report a down event to parent if we are not usable anymore.
// The report threads get their notification later.
if(Phase() == PPP_ESTABLISHED_PHASE && next != Phase()) {
// there is no need to unset the running flag because we unregister, anyway
if(!Interface().DoesDialOnDemand())
Interface().UnregisterInterface();
if(Interface().Parent())
Interface().Parent()->StateMachine().DownEvent(Interface());
}
fPhase = next; fPhase = next;
if(Phase() == PPP_ESTABLISHED_PHASE) {
if(Interface().Ifnet() && !Interface().DoesDialOnDemand())
Interface().Ifnet()->if_flags |= IFF_RUNNING;
Interface().Report(PPP_CONNECTION_REPORT, PPP_REPORT_UP_SUCCESSFUL, NULL, 0);
}
} }
@@ -103,7 +110,7 @@ PPPStateMachine::Reconfigure()
DownProtocols(); DownProtocols();
DownEncapsulators(); DownEncapsulators();
ResetOptionHandlers(); ResetLCPHandlers();
locker.UnlockNow(); locker.UnlockNow();
@@ -181,7 +188,7 @@ PPPStateMachine::AuthenticationAccepted(const char *name)
free(fAuthenticationName); free(fAuthenticationName);
fAuthenticationName = strdup(name); fAuthenticationName = strdup(name);
Interface()->Report(PPP_CONNECTION_REPORT, PPP_REPORT_AUTHENTICATION_SUCCESSFUL, Interface().Report(PPP_CONNECTION_REPORT, PPP_REPORT_AUTHENTICATION_SUCCESSFUL,
NULL, 0); NULL, 0);
} }
@@ -217,7 +224,7 @@ PPPStateMachine::PeerAuthenticationAccepted(const char *name)
free(fPeerAuthenticationName); free(fPeerAuthenticationName);
fPeerAuthenticationName = strdup(name); fPeerAuthenticationName = strdup(name);
Interface()->Report(PPP_CONNECTION_REPORT, Interface().Report(PPP_CONNECTION_REPORT,
PPP_REPORT_PEER_AUTHENTICATION_SUCCESSFUL, NULL, 0); PPP_REPORT_PEER_AUTHENTICATION_SUCCESSFUL, NULL, 0);
} }
@@ -236,7 +243,7 @@ PPPStateMachine::PeerAuthenticationDenied(const char *name)
void void
PPPStateMachine::UpFailedEvent(PPPInterface *interface) PPPStateMachine::UpFailedEvent(PPPInterface& interface)
{ {
// TODO: // TODO:
// log that an interface did not go up // log that an interface did not go up
@@ -244,24 +251,24 @@ PPPStateMachine::UpFailedEvent(PPPInterface *interface)
void void
PPPStateMachine::UpEvent(PPPInterface *interface) PPPStateMachine::UpEvent(PPPInterface& interface)
{ {
LockerHelper locker(fLock); LockerHelper locker(fLock);
if(Phase() <= PPP_TERMINATION_PHASE) { if(Phase() <= PPP_TERMINATION_PHASE) {
interface->StateMachine().CloseEvent(); interface.StateMachine().CloseEvent();
return; return;
} }
Interface()->CalculateBaudRate(); Interface().CalculateBaudRate();
if(Phase() == PPP_ESTABLISHMENT_PHASE) { if(Phase() == PPP_ESTABLISHMENT_PHASE) {
// this is the first interface that went up // this is the first interface that went up
Interface()->SetMRU(interface->MRU()); Interface().SetMRU(interface.MRU());
locker.UnlockNow(); locker.UnlockNow();
ThisLayerUp(); ThisLayerUp();
} else if(Interface()->MRU() > interface->MRU()) } else if(Interface().MRU() > interface.MRU())
Interface()->SetMRU(interface->MRU()); Interface().SetMRU(interface.MRU());
// MRU should always be the smallest value of all children // MRU should always be the smallest value of all children
NewState(PPP_OPENED_STATE); NewState(PPP_OPENED_STATE);
@@ -269,21 +276,21 @@ PPPStateMachine::UpEvent(PPPInterface *interface)
void void
PPPStateMachine::DownEvent(PPPInterface *interface) PPPStateMachine::DownEvent(PPPInterface& interface)
{ {
LockerHelper locker(fLock); LockerHelper locker(fLock);
uint32 MRU = 0; uint32 MRU = 0;
// the new MRU // the new MRU
Interface()->CalculateBaudRate(); 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;
PPPInterface *child; PPPInterface *child;
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 MRU to the smallest value of all children // set MRU to the smallest value of all children
@@ -296,7 +303,7 @@ PPPStateMachine::DownEvent(PPPInterface *interface)
} }
} }
Interface()->SetMRU(MRU); Interface().SetMRU(MRU);
if(count == 0) { if(count == 0) {
locker.UnlockNow(); locker.UnlockNow();
@@ -310,13 +317,13 @@ void
PPPStateMachine::UpFailedEvent(PPPProtocol *protocol) PPPStateMachine::UpFailedEvent(PPPProtocol *protocol)
{ {
if((protocol->Flags() & PPP_NOT_IMPORTANT) == 0) { if((protocol->Flags() & PPP_NOT_IMPORTANT) == 0) {
if(Interface()->Mode() == PPP_CLIENT_MODE) { if(Interface().Mode() == PPP_CLIENT_MODE) {
// pretend we lost connection: // pretend we lost connection:
if(Interface()->IsMultilink() && !Interface()->Parent()) if(Interface().IsMultilink() && !Interface().Parent())
for(int32 index = 0; index < Interface()->CountChildren(); index++) for(int32 index = 0; index < Interface().CountChildren(); index++)
Interface()->ChildAt(index)->StateMachine().CloseEvent(); Interface().ChildAt(index)->StateMachine().CloseEvent();
else if(Interface()->Device()) else if(Interface().Device())
Interface()->Device()->Down(); Interface().Device()->Down();
else else
CloseEvent(); CloseEvent();
// just to be on the secure side ;) // just to be on the secure side ;)
@@ -346,13 +353,13 @@ void
PPPStateMachine::UpFailedEvent(PPPEncapsulator *encapsulator) PPPStateMachine::UpFailedEvent(PPPEncapsulator *encapsulator)
{ {
if((encapsulator->Flags() & PPP_NOT_IMPORTANT) == 0) { if((encapsulator->Flags() & PPP_NOT_IMPORTANT) == 0) {
if(Interface()->Mode() == PPP_CLIENT_MODE) { if(Interface().Mode() == PPP_CLIENT_MODE) {
// pretend we lost connection: // pretend we lost connection:
if(Interface()->IsMultilink() && !Interface()->Parent()) if(Interface().IsMultilink() && !Interface().Parent())
for(int32 index = 0; index < Interface()->CountChildren(); index++) for(int32 index = 0; index < Interface().CountChildren(); index++)
Interface()->ChildAt(index)->StateMachine().CloseEvent(); Interface().ChildAt(index)->StateMachine().CloseEvent();
else if(Interface()->Device()) else if(Interface().Device())
Interface()->Device()->Down(); Interface().Device()->Down();
else else
CloseEvent(); CloseEvent();
// just to be on the secure side ;) // just to be on the secure side ;)
@@ -432,11 +439,11 @@ PPPStateMachine::UpFailedEvent()
break; break;
} }
Interface()->Report(PPP_CONNECTION_REPORT, PPP_REPORT_DEVICE_UP_FAILED, Interface().Report(PPP_CONNECTION_REPORT, PPP_REPORT_DEVICE_UP_FAILED,
NULL, 0); NULL, 0);
if(Interface()->Parent()) if(Interface().Parent())
Interface()->Parent()->StateMachine().UpFailedEvent(Interface()); Interface().Parent()->StateMachine().UpFailedEvent(Interface());
break; break;
default: default:
@@ -453,15 +460,15 @@ PPPStateMachine::UpEvent()
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...
Interface()->CalculateBaudRate(); Interface().CalculateBaudRate();
switch(State()) { switch(State()) {
case PPP_INITIAL_STATE: case PPP_INITIAL_STATE:
if(Interface()->Mode() != PPP_SERVER_MODE if(Interface().Mode() != PPP_SERVER_MODE
|| Phase() != PPP_ESTABLISHMENT_PHASE) { || Phase() != PPP_ESTABLISHMENT_PHASE) {
// we are a client or we do not listen for an incoming // we are a client or we do not listen for an incoming
// connection, so this is an illegal event // connection, so this is an illegal event
@@ -510,14 +517,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...
Interface()->CalculateBaudRate(); Interface().CalculateBaudRate();
// reset IdleSince // reset IdleSince
Interface()->fIdleSince = 0; Interface().fIdleSince = 0;
switch(State()) { switch(State()) {
case PPP_CLOSED_STATE: case PPP_CLOSED_STATE:
@@ -559,33 +566,33 @@ PPPStateMachine::DownEvent()
|| fAuthenticationStatus == PPP_AUTHENTICATING || fAuthenticationStatus == PPP_AUTHENTICATING
|| fPeerAuthenticationStatus == PPP_AUTHENTICATION_FAILED || fPeerAuthenticationStatus == PPP_AUTHENTICATION_FAILED
|| fPeerAuthenticationStatus == PPP_AUTHENTICATING) || fPeerAuthenticationStatus == PPP_AUTHENTICATING)
Interface()->Report(PPP_CONNECTION_REPORT, PPP_REPORT_AUTHENTICATION_FAILED, Interface().Report(PPP_CONNECTION_REPORT, PPP_REPORT_AUTHENTICATION_FAILED,
NULL, 0); NULL, 0);
else { else {
// if we are going up and lost connection the redial attempt becomes // if we are going up and lost connection the redial attempt becomes
// a dial retry which is managed by the main thread in Interface::Up() // a dial retry which is managed by the main thread in Interface::Up()
if(Interface()->fUpThread == -1) if(Interface().fUpThread == -1)
needsRedial = true; needsRedial = true;
Interface()->Report(PPP_CONNECTION_REPORT, PPP_REPORT_CONNECTION_LOST, Interface().Report(PPP_CONNECTION_REPORT, PPP_REPORT_CONNECTION_LOST,
NULL, 0); NULL, 0);
} }
if(Interface()->Parent()) if(Interface().Parent())
Interface()->Parent()->StateMachine().UpFailedEvent(Interface()); Interface().Parent()->StateMachine().UpFailedEvent(Interface());
NewState(PPP_INITIAL_STATE); NewState(PPP_INITIAL_STATE);
if(Interface()->DoesAutoRedial()) { if(Interface().DoesAutoRedial()) {
if(needsRedial) if(needsRedial)
Interface()->Redial(); Interface().Redial(Interface().RedialDelay());
} else if(!Interface()->DoesDialOnDemand()) } else if(!Interface().DoesDialOnDemand())
Interface()->Delete(); Interface().Delete();
} else { } else {
Interface()->Report(PPP_CONNECTION_REPORT, PPP_REPORT_DOWN_SUCCESSFUL, NULL, 0); Interface().Report(PPP_CONNECTION_REPORT, PPP_REPORT_DOWN_SUCCESSFUL, NULL, 0);
if(!Interface()->DoesDialOnDemand()) if(!Interface().DoesDialOnDemand())
Interface()->Delete(); Interface().Delete();
} }
} }
@@ -598,22 +605,22 @@ PPPStateMachine::OpenEvent()
switch(State()) { switch(State()) {
case PPP_INITIAL_STATE: case PPP_INITIAL_STATE:
if(!Interface()->Report(PPP_CONNECTION_REPORT, PPP_REPORT_GOING_UP, NULL, 0)) if(!Interface().Report(PPP_CONNECTION_REPORT, PPP_REPORT_GOING_UP, NULL, 0))
return; return;
if(Interface()->Mode() == PPP_SERVER_MODE) { if(Interface().Mode() == PPP_SERVER_MODE) {
NewPhase(PPP_ESTABLISHMENT_PHASE); NewPhase(PPP_ESTABLISHMENT_PHASE);
if(Interface()->Device()) if(Interface().Device())
Interface()->Device()->Listen(); Interface().Device()->Listen();
} else } else
NewState(PPP_STARTING_STATE); NewState(PPP_STARTING_STATE);
if(Interface()->IsMultilink() && !Interface()->Parent()) { if(Interface().IsMultilink() && !Interface().Parent()) {
NewPhase(PPP_ESTABLISHMENT_PHASE); NewPhase(PPP_ESTABLISHMENT_PHASE);
for(int32 index = 0; index < Interface()->CountChildren(); index++) for(int32 index = 0; index < Interface().CountChildren(); index++)
if(Interface()->ChildAt(index)->Mode() == Interface()->Mode()) if(Interface().ChildAt(index)->Mode() == Interface().Mode())
Interface()->ChildAt(index)->StateMachine().OpenEvent(); Interface().ChildAt(index)->StateMachine().OpenEvent();
} else { } else {
locker.UnlockNow(); locker.UnlockNow();
ThisLayerStarted(); ThisLayerStarted();
@@ -648,7 +655,7 @@ PPPStateMachine::CloseEvent()
{ {
LockerHelper locker(fLock); LockerHelper locker(fLock);
if(Interface()->IsMultilink() && !Interface()->Parent()) { if(Interface().IsMultilink() && !Interface().Parent()) {
NewState(PPP_INITIAL_STATE); NewState(PPP_INITIAL_STATE);
if(Phase() != PPP_DOWN_PHASE) if(Phase() != PPP_DOWN_PHASE)
@@ -656,8 +663,8 @@ PPPStateMachine::CloseEvent()
ThisLayerDown(); ThisLayerDown();
for(int32 index = 0; index < Interface()->CountChildren(); index++) for(int32 index = 0; index < Interface().CountChildren(); index++)
Interface()->ChildAt(index)->StateMachine().CloseEvent(); Interface().ChildAt(index)->StateMachine().CloseEvent();
return; return;
} }
@@ -681,7 +688,7 @@ PPPStateMachine::CloseEvent()
// TLSNotify() will know that we were faster because we // TLSNotify() will know that we were faster because we
// are in PPP_INITIAL_STATE now // are in PPP_INITIAL_STATE now
if(Phase() == PPP_ESTABLISHMENT_PHASE && Interface()->Parent()) { if(Phase() == PPP_ESTABLISHMENT_PHASE && Interface().Parent()) {
// the device is already up // the device is already up
NewPhase(PPP_DOWN_PHASE); NewPhase(PPP_DOWN_PHASE);
// this says the following DownEvent() was not caused by // this says the following DownEvent() was not caused by
@@ -1339,7 +1346,7 @@ PPPStateMachine::RXJEvent(struct mbuf *packet)
// test if the rejected code belongs to the minimum LCP requirements // test if the rejected code belongs to the minimum LCP requirements
if(rejectedCode >= PPP_MIN_LCP_CODE && rejectedCode <= PPP_MAX_LCP_CODE) { if(rejectedCode >= PPP_MIN_LCP_CODE && rejectedCode <= PPP_MAX_LCP_CODE) {
if(Interface()->IsMultilink() && !Interface()->Parent()) { if(Interface().IsMultilink() && !Interface().Parent()) {
// Main interfaces do not have states between STARTING and OPENED. // Main interfaces do not have states between STARTING and OPENED.
// An RXJBadEvent() would enter one of those states which is bad. // An RXJBadEvent() would enter one of those states which is bad.
m_freem(packet); m_freem(packet);
@@ -1374,10 +1381,10 @@ PPPStateMachine::RXJEvent(struct mbuf *packet)
// disable protocols and encapsulators with the rejected protocl number // disable protocols and encapsulators with the rejected protocl number
int32 index; int32 index;
PPPProtocol *protocol_handler; PPPProtocol *protocol_handler;
PPPEncapsulator *encapsulator_handler = Interface()->FirstEncapsulator(); PPPEncapsulator *encapsulator_handler = Interface().FirstEncapsulator();
for(index = 0; index < Interface()->CountProtocols(); index++) { for(index = 0; index < Interface().CountProtocols(); index++) {
protocol_handler = Interface()->ProtocolAt(index); protocol_handler = Interface().ProtocolAt(index);
if(protocol_handler && protocol_handler->Protocol() == rejected) if(protocol_handler && protocol_handler->Protocol() == rejected)
protocol_handler->SetEnabled(false); protocol_handler->SetEnabled(false);
// disable protocol // disable protocol
@@ -1394,8 +1401,8 @@ PPPStateMachine::RXJEvent(struct mbuf *packet)
// this event handler does not m_freem(packet)!!! // this event handler does not m_freem(packet)!!!
// notify parent, too // notify parent, too
if(Interface()->Parent()) if(Interface().Parent())
Interface()->Parent()->StateMachine().RXJEvent(packet); Interface().Parent()->StateMachine().RXJEvent(packet);
else else
m_freem(packet); m_freem(packet);
} }
@@ -1404,7 +1411,7 @@ PPPStateMachine::RXJEvent(struct mbuf *packet)
// actions (all private) // actions (all private)
void void
PPPStateMachine::IllegalEvent(PPP_EVENT event) PPPStateMachine::IllegalEvent(ppp_event event)
{ {
// TODO: // TODO:
// update error statistics // update error statistics
@@ -1443,16 +1450,16 @@ PPPStateMachine::ThisLayerDown()
void void
PPPStateMachine::ThisLayerStarted() PPPStateMachine::ThisLayerStarted()
{ {
if(Interface()->Device()) if(Interface().Device())
Interface()->Device()->Up(); Interface().Device()->Up();
} }
void void
PPPStateMachine::ThisLayerFinished() PPPStateMachine::ThisLayerFinished()
{ {
if(Interface()->Device()) if(Interface().Device())
Interface()->Device()->Down(); Interface().Device()->Down();
} }
@@ -1606,10 +1613,10 @@ PPPStateMachine::SendCodeReject(struct mbuf *packet, uint16 protocol, uint8 code
int32 adjust = 0; int32 adjust = 0;
// adjust packet size by this value if packet is too big // adjust packet size by this value if packet is too big
if(packet->m_flags & M_PKTHDR) { if(packet->m_flags & M_PKTHDR) {
if((uint32) packet->m_pkthdr.len > Interface()->MRU()) if((uint32) packet->m_pkthdr.len > Interface().MRU())
adjust = Interface()->MRU() - packet->m_pkthdr.len; adjust = Interface().MRU() - packet->m_pkthdr.len;
} else if(packet->m_len > Interface()->MRU()) } else if(packet->m_len > Interface().MRU())
adjust = Interface()->MRU() - packet->m_len; adjust = Interface().MRU() - packet->m_len;
if(adjust != 0) if(adjust != 0)
m_adj(packet, adjust); m_adj(packet, adjust);
@@ -1655,6 +1662,7 @@ PPPStateMachine::SendEchoReply(struct mbuf *request)
void void
PPPStateMachine::BringHandlersUp() PPPStateMachine::BringHandlersUp()
{ {
// use a simple check for phase changes (e.g., caused by CloseEvent())
while(Phase() <= PPP_ESTABLISHED_PHASE && Phase() >= PPP_AUTHENTICATION_PHASE) { while(Phase() <= PPP_ESTABLISHED_PHASE && Phase() >= PPP_AUTHENTICATION_PHASE) {
if(BringPhaseUp() > 0) if(BringPhaseUp() > 0)
break; break;
@@ -1663,16 +1671,12 @@ PPPStateMachine::BringHandlersUp()
if(Phase() < PPP_AUTHENTICATION_PHASE) if(Phase() < PPP_AUTHENTICATION_PHASE)
return; return;
// phase was changed by another event
else if(Phase() == PPP_ESTABLISHED_PHASE) { else if(Phase() == PPP_ESTABLISHED_PHASE) {
if(Interface()->Parent()) if(Interface().Parent())
Interface()->Parent()->StateMachine().UpEvent(Interface()); Interface().Parent()->StateMachine().UpEvent(Interface());
if(Interface()->Ifnet())
Interface()->Ifnet()->if_flags |= IFF_RUNNING;
Interface()->Report(PPP_CONNECTION_REPORT, PPP_REPORT_UP_SUCCESSFUL, NULL, 0);
} else } else
NewPhase((PPP_PHASE) (Phase() + 1)); NewPhase((ppp_phase) (Phase() + 1));
} }
} }
@@ -1683,16 +1687,18 @@ PPPStateMachine::BringPhaseUp()
{ {
LockerHelper locker(fLock); LockerHelper locker(fLock);
// check for phase change
if(Phase() < PPP_AUTHENTICATION_PHASE) if(Phase() < PPP_AUTHENTICATION_PHASE)
return 0; return 0;
uint32 count = 0; uint32 count = 0;
PPPProtocol *protocol_handler; PPPProtocol *protocol_handler;
PPPEncapsulator *encapsulator_handler = Interface()->FirstEncapsulator(); PPPEncapsulator *encapsulator_handler = Interface().FirstEncapsulator();
for(int32 index = 0; index < Interface()->CountProtocols(); index++) { for(int32 index = 0; index < Interface().CountProtocols(); index++) {
protocol_handler = Interface()->ProtocolAt(index); protocol_handler = Interface().ProtocolAt(index);
if(protocol_handler && protocol_handler->Phase() == Phase()) { if(protocol_handler && protocol_handler->IsEnabled()
&& protocol_handler->Phase() == Phase()) {
if(protocol_handler->IsUpRequested()) { if(protocol_handler->IsUpRequested()) {
++count; ++count;
protocol_handler->Up(); protocol_handler->Up();
@@ -1703,7 +1709,8 @@ PPPStateMachine::BringPhaseUp()
for(; encapsulator_handler; for(; encapsulator_handler;
encapsulator_handler = encapsulator_handler->Next()) { encapsulator_handler = encapsulator_handler->Next()) {
if(encapsulator_handler && encapsulator_handler->Phase() == Phase()) { if(encapsulator_handler && encapsulator_handler->IsEnabled()
&& encapsulator_handler->Phase() == Phase()) {
if(encapsulator_handler->IsUpRequested()) { if(encapsulator_handler->IsUpRequested()) {
++count; ++count;
encapsulator_handler->Up(); encapsulator_handler->Up();
@@ -1719,16 +1726,16 @@ PPPStateMachine::BringPhaseUp()
void void
PPPStateMachine::DownProtocols() PPPStateMachine::DownProtocols()
{ {
for(int32 index = 0; index < Interface()->CountProtocols(); index++) for(int32 index = 0; index < Interface().CountProtocols(); index++)
if(Interface()->ProtocolAt(index)->IsEnabled()) if(Interface().ProtocolAt(index)->IsEnabled())
Interface()->ProtocolAt(index)->Down(); Interface().ProtocolAt(index)->Down();
} }
void void
PPPStateMachine::DownEncapsulators() PPPStateMachine::DownEncapsulators()
{ {
PPPEncapsulator *encapsulator_handler = Interface()->FirstEncapsulator(); PPPEncapsulator *encapsulator_handler = Interface().FirstEncapsulator();
for(; encapsulator_handler; for(; encapsulator_handler;
encapsulator_handler = encapsulator_handler->Next()) encapsulator_handler = encapsulator_handler->Next())
@@ -1738,7 +1745,7 @@ PPPStateMachine::DownEncapsulators()
void void
PPPStateMachine::ResetOptionHandlers() PPPStateMachine::ResetLCPHandlers()
{ {
for(int32 index = 0; index < LCP().CountOptionHandlers(); index++) for(int32 index = 0; index < LCP().CountOptionHandlers(); index++)
LCP().OptionHandlerAt(index)->Reset(); LCP().OptionHandlerAt(index)->Reset();