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