Added some comments.
Added lcp_packet structure. Changed reference style. Changed some names. Added general events. Completed most events. Copy constructors and assign operators are now private (just to be on the safe side ;). SendToDevice() now checks if the packet is small enough. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@3930 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
2ea402ebf0
commit
06a35e5e82
|
@ -16,6 +16,11 @@
|
||||||
|
|
||||||
|
|
||||||
class AccessHelper {
|
class AccessHelper {
|
||||||
|
private:
|
||||||
|
// copies are not allowed!
|
||||||
|
AccessHelper(const AccessHelper& copy);
|
||||||
|
AccessHelper& operator= (const AccessHelper& copy);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AccessHelper(vint32 *access) : fAccess(access)
|
AccessHelper(vint32 *access) : fAccess(access)
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,31 +5,43 @@
|
||||||
|
|
||||||
|
|
||||||
typedef struct configure_item {
|
typedef struct configure_item {
|
||||||
void *data;
|
|
||||||
int32 len;
|
|
||||||
uint8 type;
|
uint8 type;
|
||||||
|
uint8 length;
|
||||||
|
int8 data[0];
|
||||||
|
// the data follows this structure
|
||||||
} configure_item;
|
} configure_item;
|
||||||
|
|
||||||
|
|
||||||
class PPPConfigurePacket {
|
class PPPConfigurePacket {
|
||||||
|
private:
|
||||||
|
// copies are not allowed!
|
||||||
|
PPPConfigurePacket(const PPPConfigurePacket& copy);
|
||||||
|
PPPConfigurePacket& operator= (const PPPConfigurePacket& copy);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PPPConfigurePacket(uint8 type);
|
PPPConfigurePacket(uint8 code);
|
||||||
PPPConfigurePacket(mbuf *data);
|
PPPConfigurePacket(mbuf *data);
|
||||||
~PPPConfigurePacket();
|
~PPPConfigurePacket();
|
||||||
|
|
||||||
bool SetType(uint8 type);
|
bool SetCode(uint8 code);
|
||||||
uint8 Type() const
|
uint8 Code() const
|
||||||
{ return fType; }
|
{ return fCode; }
|
||||||
|
|
||||||
void AddItem(configure_item *item);
|
void SetID(uint8 id)
|
||||||
bool RemoveItem(configure_item *item);
|
{ fID = id; }
|
||||||
|
uint8 ID() const
|
||||||
|
{ return fID; }
|
||||||
|
|
||||||
|
void AddItem(const configure_item *item);
|
||||||
|
bool RemoveItem(const configure_item *item);
|
||||||
int32 CountItems() const;
|
int32 CountItems() const;
|
||||||
configure_item *ItemAt(int32 index) const;
|
configure_item *ItemAt(int32 index) const;
|
||||||
|
|
||||||
mbuf *ToMbuf() const;
|
mbuf *ToMbuf();
|
||||||
|
// the user is responsible for freeing the mbuf
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint8 fType;
|
uint8 fCode, fID;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
#define PPP_MODULES_PATH "network/ppp-modules"
|
#define PPP_MODULES_PATH "network/ppp-modules"
|
||||||
|
|
||||||
// built-in protocols
|
// built-in protocols
|
||||||
// #define PPP_LCP_PROTOCOL 0xC021
|
#define PPP_LCP_PROTOCOL 0xC021
|
||||||
|
|
||||||
|
|
||||||
#define PPP_ERROR_BASE B_ERRORS_END
|
#define PPP_ERROR_BASE B_ERRORS_END
|
||||||
|
@ -181,5 +181,7 @@ enum PPP_LCP_TYPE {
|
||||||
PPP_DISCARD_REQUEST = 11
|
PPP_DISCARD_REQUEST = 11
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define PPP_MIN_LCP_CODE PPP_CONFIGURE_REQUEST
|
||||||
|
#define PPP_MAX_LCP_CODE PPP_DISCARD_REQUEST
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -12,8 +12,12 @@ class PPPFSM {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// may only be constructed/destructed by PPPInterface
|
// may only be constructed/destructed by PPPInterface
|
||||||
PPPFSM(PPPInterface &interface);
|
PPPFSM(PPPInterface& interface);
|
||||||
~PPPFSM();
|
~PPPFSM();
|
||||||
|
|
||||||
|
// copies are not allowed!
|
||||||
|
PPPFSM(const PPPFSM& copy);
|
||||||
|
PPPFSM& operator= (const PPPFSM& copy);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PPPInterface *Interface() const
|
PPPInterface *Interface() const
|
||||||
|
@ -24,6 +28,9 @@ class PPPFSM {
|
||||||
PPP_PHASE Phase() const
|
PPP_PHASE Phase() const
|
||||||
{ return fPhase; }
|
{ return fPhase; }
|
||||||
|
|
||||||
|
uint8 NextID();
|
||||||
|
// return the next id for lcp_packets
|
||||||
|
|
||||||
// public events
|
// public events
|
||||||
void AuthenticationRequested();
|
void AuthenticationRequested();
|
||||||
void AuthenticationAccepted(const char *name);
|
void AuthenticationAccepted(const char *name);
|
||||||
|
@ -48,7 +55,7 @@ class PPPFSM {
|
||||||
void DownEvent();
|
void DownEvent();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BLocker &Locker()
|
BLocker& Locker()
|
||||||
{ return fLock; }
|
{ return fLock; }
|
||||||
void LeaveConstructionPhase();
|
void LeaveConstructionPhase();
|
||||||
void EnterDestructionPhase();
|
void EnterDestructionPhase();
|
||||||
|
@ -61,16 +68,21 @@ class PPPFSM {
|
||||||
void CloseEvent();
|
void CloseEvent();
|
||||||
void TOGoodEvent();
|
void TOGoodEvent();
|
||||||
void TOBadEvent();
|
void TOBadEvent();
|
||||||
void RCRGoodEvent(PPPConfigurePacket *packet);
|
void RCRGoodEvent(mbuf *packet);
|
||||||
void RCRBadEvent(PPPConfigurePacket *packet);
|
void RCRBadEvent(mbuf *nak, mbuf *reject);
|
||||||
void RCAEvent(PPPConfigurePacket *packet);
|
void RCAEvent(mbuf *packet);
|
||||||
void RCNEvent(PPPConfigurePacket *packet);
|
void RCNEvent(mbuf *packet);
|
||||||
void RTREvent();
|
void RTREvent(mbuf *packet);
|
||||||
void RTAEvent();
|
void RTAEvent(mbuf *packet);
|
||||||
void RUCEvent();
|
void RUCEvent(mbuf *packet);
|
||||||
void RJXGoodEvent();
|
void RXJGoodEvent(mbuf *packet);
|
||||||
void RJXBadEvent();
|
void RXJBadEvent(mbuf *packet);
|
||||||
void RXREvent();
|
void RXREvent(mbuf *packet);
|
||||||
|
|
||||||
|
// general events (for Good/Bad events)
|
||||||
|
void TimerEvent();
|
||||||
|
void RCREvent(mbuf *packet);
|
||||||
|
void RXJEvent(mbuf *packet);
|
||||||
|
|
||||||
// actions
|
// actions
|
||||||
void IllegalEvent(PPP_EVENT event);
|
void IllegalEvent(PPP_EVENT event);
|
||||||
|
@ -81,15 +93,12 @@ class PPPFSM {
|
||||||
void InitializeRestartCount();
|
void InitializeRestartCount();
|
||||||
void ZeroRestartCount();
|
void ZeroRestartCount();
|
||||||
void SendConfigureRequest();
|
void SendConfigureRequest();
|
||||||
void SendConfigureAck(PPPConfigurePacket *packet);
|
void SendConfigureAck(mbuf *packet);
|
||||||
|
void SendConfigureNak(mbuf *packet);
|
||||||
void SendConfigureNak(PPPConfigurePacket *packet);
|
|
||||||
// is this needed?
|
|
||||||
|
|
||||||
void SendTerminateRequest();
|
void SendTerminateRequest();
|
||||||
void SendTerminateAck();
|
void SendTerminateAck(mbuf *request);
|
||||||
void SendCodeReject();
|
void SendCodeReject(mbuf *packet);
|
||||||
void SendEchoReply();
|
void SendEchoReply(mbuf *request);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PPPInterface *fInterface;
|
PPPInterface *fInterface;
|
||||||
|
@ -97,6 +106,8 @@ class PPPFSM {
|
||||||
PPP_PHASE fPhase;
|
PPP_PHASE fPhase;
|
||||||
PPP_STATE fState;
|
PPP_STATE fState;
|
||||||
|
|
||||||
|
vint32 fID;
|
||||||
|
|
||||||
PPP_AUTHENTICATION_STATUS fAuthenticationStatus,
|
PPP_AUTHENTICATION_STATUS fAuthenticationStatus,
|
||||||
fPeerAuthenticationStatus;
|
fPeerAuthenticationStatus;
|
||||||
int32 fAuthenticatorIndex, fPeerAuthenticatorIndex;
|
int32 fAuthenticatorIndex, fPeerAuthenticatorIndex;
|
||||||
|
|
|
@ -11,14 +11,18 @@
|
||||||
#include "List.h"
|
#include "List.h"
|
||||||
#include "LockerHelper.h"
|
#include "LockerHelper.h"
|
||||||
|
|
||||||
class PPPAuthenticator;
|
|
||||||
class PPPDevice;
|
class PPPDevice;
|
||||||
|
class PPPProtocol;
|
||||||
class PPPEncapsulator;
|
class PPPEncapsulator;
|
||||||
class PPPOptionHandler;
|
class PPPOptionHandler;
|
||||||
class PPPProtocol;
|
|
||||||
|
|
||||||
|
|
||||||
class PPPInterface {
|
class PPPInterface {
|
||||||
|
private:
|
||||||
|
// copies are not allowed!
|
||||||
|
PPPInterface(const PPPInterface& copy);
|
||||||
|
PPPInterface& operator= (const PPPInterface& copy);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PPPInterface(driver_settings *settings);
|
PPPInterface(driver_settings *settings);
|
||||||
~PPPInterface();
|
~PPPInterface();
|
||||||
|
@ -28,7 +32,7 @@ class PPPInterface {
|
||||||
driver_settings* Settings()
|
driver_settings* Settings()
|
||||||
{ return fSettings; }
|
{ return fSettings; }
|
||||||
|
|
||||||
PPPFSM &FSM() const
|
PPPFSM& FSM() const
|
||||||
{ return fFSM; }
|
{ return fFSM; }
|
||||||
|
|
||||||
bool RegisterInterface();
|
bool RegisterInterface();
|
||||||
|
@ -108,7 +112,7 @@ class PPPInterface {
|
||||||
status_t ReceiveFromDevice(mbuf *packet);
|
status_t ReceiveFromDevice(mbuf *packet);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PPPLCP &LCP() const
|
PPPLCP& LCP() const
|
||||||
{ return fLCP; }
|
{ return fLCP; }
|
||||||
void CalculateMRU();
|
void CalculateMRU();
|
||||||
|
|
||||||
|
@ -135,7 +139,7 @@ class PPPInterface {
|
||||||
List<PPPOptionHandler*> fOptionHandlers;
|
List<PPPOptionHandler*> fOptionHandlers;
|
||||||
List<ppp_module_info*> fModules;
|
List<ppp_module_info*> fModules;
|
||||||
|
|
||||||
BLocker &fGeneralLock;
|
BLocker& fGeneralLock;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -4,13 +4,25 @@
|
||||||
#include "KPPPProtocol.h"
|
#include "KPPPProtocol.h"
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct lcp_packet {
|
||||||
|
uint8 code;
|
||||||
|
uint8 id;
|
||||||
|
uint16 length;
|
||||||
|
int8 data[0];
|
||||||
|
} lcp_packet;
|
||||||
|
|
||||||
|
|
||||||
class PPPLCP : public PPPProtocol {
|
class PPPLCP : public PPPProtocol {
|
||||||
friend class PPPInterface;
|
friend class PPPInterface;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// may only be constructed/destructed by PPPInterface
|
// may only be constructed/destructed by PPPInterface
|
||||||
PPPLCP(PPPInterface &interface);
|
PPPLCP(PPPInterface& interface);
|
||||||
~PPPLCP();
|
~PPPLCP();
|
||||||
|
|
||||||
|
// copies are not allowed!
|
||||||
|
PPPLCP(const PPPLCP& copy);
|
||||||
|
PPPLCP& operator= (const PPPLCP& copy);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,8 @@ class PPPInterface;
|
||||||
typedef struct ppp_module_info {
|
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 *interface, driver_parameter *settings, int32 type);
|
status_t (*add_to)(PPPInterface *interface,
|
||||||
|
driver_parameter *settings, int32 type);
|
||||||
} ppp_module_info;
|
} ppp_module_info;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -16,8 +16,13 @@
|
||||||
|
|
||||||
|
|
||||||
class LockerHelper {
|
class LockerHelper {
|
||||||
|
private:
|
||||||
|
// copies are not allowed!
|
||||||
|
LockerHelper(const LockerHelper& copy);
|
||||||
|
LockerHelper& operator= (const LockerHelper& copy);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
LockerHelper(BLocker &lock) : fLock(&lock)
|
LockerHelper(BLocker& lock) : fLock(&lock)
|
||||||
{
|
{
|
||||||
if(fLock->Lock() != B_OK)
|
if(fLock->Lock() != B_OK)
|
||||||
fLock = NULL;
|
fLock = NULL;
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
#include "KPPPFSM.h"
|
#include "KPPPFSM.h"
|
||||||
|
|
||||||
|
|
||||||
PPPFSM::PPPFSM(PPPInterface &interface)
|
PPPFSM::PPPFSM(PPPInterface& interface)
|
||||||
: fInterface(&interface), fPhase(PPP_CTOR_DTOR_PHASE),
|
: fInterface(&interface), fPhase(PPP_CTOR_DTOR_PHASE),
|
||||||
fState(PPP_INITIAL_STATE),
|
fState(PPP_INITIAL_STATE), fID(system_time() & 0xFF),
|
||||||
fAuthenticationStatus(PPP_NOT_AUTHENTICATED),
|
fAuthenticationStatus(PPP_NOT_AUTHENTICATED),
|
||||||
fPeerAuthenticationStatus(PPP_NOT_AUTHENTICATED),
|
fPeerAuthenticationStatus(PPP_NOT_AUTHENTICATED),
|
||||||
fAuthenticatorIndex(-1), fPeerAuthenticatorIndex(-1)
|
fAuthenticatorIndex(-1), fPeerAuthenticatorIndex(-1)
|
||||||
|
@ -18,12 +18,22 @@ PPPFSM::~PPPFSM()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint8
|
||||||
|
PPPFSM::NextID()
|
||||||
|
{
|
||||||
|
return (uint8) atomic_add(&fID, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// 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
|
||||||
PPPFSM::NewState(PPP_STATE next)
|
PPPFSM::NewState(PPP_STATE next)
|
||||||
{
|
{
|
||||||
fState = next;
|
fState = next;
|
||||||
|
|
||||||
|
// TODO:
|
||||||
|
// ? if next == OPENED_STATE we may want to reset all option handlers ?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -99,7 +109,11 @@ PPPFSM::PeerAuthenticationName() const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// public events
|
// This is called by the device to tell us that it entered establishment
|
||||||
|
// phase. We can use Device::Down() to abort establishment until UpEvent()
|
||||||
|
// is called.
|
||||||
|
// The return value says if we are waiting for an UpEvent(). If false is
|
||||||
|
// returned the device should immediately abort its attempt to connect.
|
||||||
bool
|
bool
|
||||||
PPPFSM::TLSNotify()
|
PPPFSM::TLSNotify()
|
||||||
{
|
{
|
||||||
|
@ -116,6 +130,10 @@ PPPFSM::TLSNotify()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// This is called by the device to tell us that it entered termination phase.
|
||||||
|
// A Device::Up() should wait until the device went down.
|
||||||
|
// If false is returned we want to stay connected, though we called
|
||||||
|
// Device::Down().
|
||||||
bool
|
bool
|
||||||
PPPFSM::TLFNotify()
|
PPPFSM::TLFNotify()
|
||||||
{
|
{
|
||||||
|
@ -202,8 +220,8 @@ PPPFSM::UpEvent()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
InitializeRestartCounter();
|
|
||||||
NewState(PPP_REQ_SENT_STATE);
|
NewState(PPP_REQ_SENT_STATE);
|
||||||
|
InitializeRestartCounter();
|
||||||
locker.UnlockNow();
|
locker.UnlockNow();
|
||||||
SendConfigureRequest();
|
SendConfigureRequest();
|
||||||
break;
|
break;
|
||||||
|
@ -222,6 +240,7 @@ PPPFSM::DownEvent()
|
||||||
// TODO:
|
// TODO:
|
||||||
// ResetProtocols();
|
// ResetProtocols();
|
||||||
// ResetEncapsulators();
|
// ResetEncapsulators();
|
||||||
|
// ResetOptionHandlers();
|
||||||
|
|
||||||
switch(State()) {
|
switch(State()) {
|
||||||
case PPP_CLOSED_STATE:
|
case PPP_CLOSED_STATE:
|
||||||
|
@ -307,9 +326,9 @@ PPPFSM::OpenEvent()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
InitializeRestartCounter();
|
|
||||||
NewState(PPP_REQ_SENT_STATE);
|
NewState(PPP_REQ_SENT_STATE);
|
||||||
fPhase = PPP_ESTABLISHMENT_PHASE;
|
fPhase = PPP_ESTABLISHMENT_PHASE;
|
||||||
|
InitializeRestartCounter();
|
||||||
locker.UnlockNow();
|
locker.UnlockNow();
|
||||||
SendConfigureRequest();
|
SendConfigureRequest();
|
||||||
break;
|
break;
|
||||||
|
@ -332,9 +351,9 @@ PPPFSM::CloseEvent()
|
||||||
case PPP_REQ_SENT_STATE:
|
case PPP_REQ_SENT_STATE:
|
||||||
case PPP_ACK_RCVD_STATE:
|
case PPP_ACK_RCVD_STATE:
|
||||||
case PPP_ACK_SENT_STATE:
|
case PPP_ACK_SENT_STATE:
|
||||||
InitializeRestartCounter();
|
|
||||||
NewState(PPP_CLOSING_STATE);
|
NewState(PPP_CLOSING_STATE);
|
||||||
fPhase = PPP_TERMINATION_PHASE;
|
fPhase = PPP_TERMINATION_PHASE;
|
||||||
|
InitializeRestartCounter();
|
||||||
locker.UnlockNow();
|
locker.UnlockNow();
|
||||||
SendTerminateRequest();
|
SendTerminateRequest();
|
||||||
break;
|
break;
|
||||||
|
@ -366,6 +385,7 @@ PPPFSM::CloseEvent()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// timeout (restart counters are > 0)
|
||||||
void
|
void
|
||||||
PPPFSM::TOGoodEvent()
|
PPPFSM::TOGoodEvent()
|
||||||
{
|
{
|
||||||
|
@ -393,6 +413,7 @@ PPPFSM::TOGoodEvent()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// timeout (restart counters are <= 0)
|
||||||
void
|
void
|
||||||
PPPFSM::TOBadEvent()
|
PPPFSM::TOBadEvent()
|
||||||
{
|
{
|
||||||
|
@ -422,84 +443,438 @@ PPPFSM::TOBadEvent()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// receive configure request (acceptable request)
|
||||||
void
|
void
|
||||||
PPPFSM::RCRGoodEvent(PPPConfigurePacket *packet)
|
PPPFSM::RCRGoodEvent(mbuf *packet)
|
||||||
{
|
{
|
||||||
LockerHelper locker(fLock);
|
LockerHelper locker(fLock);
|
||||||
|
|
||||||
|
switch(State()) {
|
||||||
|
case PPP_INITIAL_STATE:
|
||||||
|
case PPP_STARTING_STATE:
|
||||||
|
IllegalEvent(PPP_RCR_GOOD_EVENT);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PPP_CLOSED_STATE:
|
||||||
|
locker.UnlockNow();
|
||||||
|
SendTerminateAck();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PPP_STOPPED_STATE:
|
||||||
|
// irc,scr,sca/8
|
||||||
|
// XXX: should we do nothing and wait for DownEvent()?
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PPP_REQ_SENT_STATE:
|
||||||
|
NewState(PPP_ACK_SENT_STATE);
|
||||||
|
|
||||||
|
case PPP_ACK_SENT_STATE:
|
||||||
|
locker.UnlockNow();
|
||||||
|
SendConfigureAck(packet);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PPP_ACK_RCVD_STATE:
|
||||||
|
NewState(PPP_OPENED_STATE);
|
||||||
|
locker.UnlockNow();
|
||||||
|
SendConfigureAck(packet);
|
||||||
|
ThisLayerUp();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PPP_OPENED_STATE:
|
||||||
|
// tld,scr,sca/8
|
||||||
|
NewState(PPP_ACK_SENT_STATE);
|
||||||
|
locker.UnlockNow();
|
||||||
|
SendConfigureRequest();
|
||||||
|
SendConfigureAck(packet);
|
||||||
|
ThisLayerDown();
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// receive configure request (unacceptable request)
|
||||||
void
|
void
|
||||||
PPPFSM::RCRBadEvent(PPPConfigurePacket *packet)
|
PPPFSM::RCRBadEvent(mbuf *nak, mbuf *reject)
|
||||||
{
|
{
|
||||||
LockerHelper locker(fLock);
|
LockerHelper locker(fLock);
|
||||||
|
|
||||||
|
switch(State()) {
|
||||||
|
case PPP_INITIAL_STATE:
|
||||||
|
case PPP_STARTING_STATE:
|
||||||
|
IllegalEvent(PPP_RCR_BAD_EVENT);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PPP_CLOSED_STATE:
|
||||||
|
locker.UnlockNow();
|
||||||
|
SendTerminateAck();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PPP_STOPPED_STATE:
|
||||||
|
// irc,scr,scn/6
|
||||||
|
// XXX: should we do nothing and wait for DownEvent()?
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PPP_OPENED_STATE:
|
||||||
|
NewState(PPP_REQ_SENT_STATE);
|
||||||
|
locker.UnlockNow();
|
||||||
|
ThisLayerDown();
|
||||||
|
SendConfigureRequest();
|
||||||
|
|
||||||
|
case PPP_ACK_SENT_STATE:
|
||||||
|
if(State() == PPP_ACK_SENT_STATE)
|
||||||
|
NewState(PPP_REQ_SENT_STATE);
|
||||||
|
// OPENED_STATE might have set this already
|
||||||
|
|
||||||
|
case PPP_REQ_SENT_STATE:
|
||||||
|
case PPP_ACK_RCVD_STATE:
|
||||||
|
locker.UnlockNow();
|
||||||
|
if( !nak && ((lcp_packet*)nak)->length > 3)
|
||||||
|
SendConfigureNak(nak);
|
||||||
|
else if( !reject && ((lcp_packet*)reject)->length > 3)
|
||||||
|
SendConfigureNak(reject);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// receive configure ack
|
||||||
void
|
void
|
||||||
PPPFSM::RCAEvent(PPPConfigurePacket *packet)
|
PPPFSM::RCAEvent(mbuf *packet)
|
||||||
{
|
{
|
||||||
LockerHelper locker(fLock);
|
LockerHelper locker(fLock);
|
||||||
|
|
||||||
|
switch(State()) {
|
||||||
|
case PPP_INITIAL_STATE:
|
||||||
|
case PPP_STARTING_STATE:
|
||||||
|
IllegalEvent(PPP_RCA_EVENT);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PPP_CLOSED_STATE:
|
||||||
|
case PPP_STOPPED_STATE:
|
||||||
|
locker.UnlockNow();
|
||||||
|
SendTerminateAck();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PPP_REQ_SENT_STATE:
|
||||||
|
NewState(PPP_ACK_RCVD_STATE);
|
||||||
|
InitializeRestartCounter();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PPP_ACK_RCVD_STATE:
|
||||||
|
NewState(PPP_REQ_SENT_STATE);
|
||||||
|
locker.UnlockNow();
|
||||||
|
SendConfigureRequest();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PPP_ACK_SENT_STATE:
|
||||||
|
NewState(PPP_OPENED_STATE);
|
||||||
|
InitializeRestartCounter();
|
||||||
|
locker.UnlockNow();
|
||||||
|
ThisLayerUp();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PPP_OPENED_STATE:
|
||||||
|
NewState(PPP_REQ_SENT_STATE);
|
||||||
|
locker.UnlockNow();
|
||||||
|
ThisLayerDown();
|
||||||
|
SendConfigureRequest();
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// receive configure nak/reject
|
||||||
void
|
void
|
||||||
PPPFSM::RCNEvent(PPPConfigurePacket *packet)
|
PPPFSM::RCNEvent(mbuf *packet)
|
||||||
{
|
{
|
||||||
LockerHelper locker(fLock);
|
LockerHelper locker(fLock);
|
||||||
|
|
||||||
|
switch(State()) {
|
||||||
|
case PPP_INITIAL_STATE:
|
||||||
|
case PPP_STARTING_STATE:
|
||||||
|
IllegalEvent(PPP_RCN_EVENT);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PPP_CLOSED_STATE:
|
||||||
|
case PPP_STOPPED_STATE:
|
||||||
|
locker.UnlockNow();
|
||||||
|
SendTermintateAck(packet);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PPP_REQ_SENT_STATE:
|
||||||
|
case PPP_ACK_SENT_STATE:
|
||||||
|
InitializeRestartCounter();
|
||||||
|
|
||||||
|
case PPP_ACK_RCVD_STATE:
|
||||||
|
if(State() == PPP_ACK_RCVD_STATE)
|
||||||
|
NewState(PPP_REQ_SENT_STATE);
|
||||||
|
locker.UnlockNow();
|
||||||
|
SendConfigureRequest();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PPP_OPENED_STATE:
|
||||||
|
NewState(PPP_REQ_SENT_STATE);
|
||||||
|
locker.UnlockNow();
|
||||||
|
ThisLayerDown();
|
||||||
|
SendConfigureRequest();
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// receive terminate request
|
||||||
void
|
void
|
||||||
PPPFSM::RTREvent()
|
PPPFSM::RTREvent(mbuf *packet)
|
||||||
{
|
{
|
||||||
LockerHelper locker(fLock);
|
LockerHelper locker(fLock);
|
||||||
|
|
||||||
|
switch(State()) {
|
||||||
|
case PPP_INITIAL_STATE:
|
||||||
|
case PPP_STARTING_STATE:
|
||||||
|
IllegalEvent(PPP_RTR_EVENT);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PPP_ACK_RCVD_STATE:
|
||||||
|
case PPP_ACK_SENT_STATE:
|
||||||
|
NewState(PPP_REQ_SENT_STATE);
|
||||||
|
locker.UnlockNow();
|
||||||
|
SendTerminateAck(packet);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PPP_OPENED_STATE:
|
||||||
|
NewState(PPP_STOPPING_STATE);
|
||||||
|
ZeroRestartCount();
|
||||||
|
locker.UnlockNow();
|
||||||
|
ThisLayerDown();
|
||||||
|
SendTerminateAck(packet);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
locker.UnlockNow();
|
||||||
|
SendTerminateAck(packet);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// receive terminate ack
|
||||||
void
|
void
|
||||||
PPPFSM::RTAEvent()
|
PPPFSM::RTAEvent(mbuf *packet)
|
||||||
{
|
{
|
||||||
LockerHelper locker(fLock);
|
LockerHelper locker(fLock);
|
||||||
|
|
||||||
|
switch(State()) {
|
||||||
|
case PPP_INITIAL_STATE:
|
||||||
|
case PPP_STARTING_STATE:
|
||||||
|
IllegalEvent(PPP_RTA_EVENT);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PPP_CLOSING_STATE:
|
||||||
|
NewState(PPP_CLOSED_STATE);
|
||||||
|
locker.UnlockNow();
|
||||||
|
ThisLayerFinished();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PPP_CLOSING_STATE:
|
||||||
|
NewState(PPP_STOPPED_STATE);
|
||||||
|
locker.UnlockNow();
|
||||||
|
ThisLayerFinished();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PPP_ACK_RCVD_STATE:
|
||||||
|
NewState(REQ_SENT_STATE);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PPP_OPENED_STATE:
|
||||||
|
NewState(PPP_REQ_SENT_STATE);
|
||||||
|
locker.UnlockNow();
|
||||||
|
ThisLayerDown();
|
||||||
|
SendConfigureRequest();
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// receive unknown code
|
||||||
void
|
void
|
||||||
PPPFSM::RUCEvent()
|
PPPFSM::RUCEvent(mbuf *packet)
|
||||||
{
|
{
|
||||||
LockerHelper locker(fLock);
|
LockerHelper locker(fLock);
|
||||||
|
|
||||||
|
switch(State()) {
|
||||||
|
case PPP_INITIAL_STATE:
|
||||||
|
case PPP_STARTING_STATE:
|
||||||
|
IllegalEvent(PPP_RUC_EVENT);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
locker.UnlockNow();
|
||||||
|
SendCodeReject(packet);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// receive code/protocol reject (acceptable such as IPX reject)
|
||||||
void
|
void
|
||||||
PPPFSM::RXJGoodEvent()
|
PPPFSM::RXJGoodEvent(mbuf *packet)
|
||||||
{
|
{
|
||||||
LockerHelper locker(fLock);
|
LockerHelper locker(fLock);
|
||||||
|
|
||||||
|
switch(State()) {
|
||||||
|
case PPP_INITIAL_STATE:
|
||||||
|
case PPP_STARTING_STATE:
|
||||||
|
IllegalEvent(PPP_RXJ_GOOD_EVENT);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PPP_ACK_RCVD_STATE:
|
||||||
|
NewState(PPP_REQ_SENT_STATE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// receive code/protocol reject (catastrophic such as LCP reject)
|
||||||
void
|
void
|
||||||
PPPFSM::RXJBadEvent()
|
PPPFSM::RXJBadEvent(mbuf *packet)
|
||||||
{
|
{
|
||||||
LockerHelper locker(fLock);
|
LockerHelper locker(fLock);
|
||||||
|
|
||||||
|
switch(State()) {
|
||||||
|
case PPP_INITIAL_STATE:
|
||||||
|
case PPP_STARTING_STATE:
|
||||||
|
IllegalEvent(PPP_RJX_BAD_EVENT);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PPP_CLOSING_STATE:
|
||||||
|
NewState(PPP_CLOSED_STATE);
|
||||||
|
|
||||||
|
case PPP_CLOSED_STATE:
|
||||||
|
locker.UnlockNow();
|
||||||
|
ThisLayerFinished();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PPP_STOPPING_STATE:
|
||||||
|
case PPP_REQ_SENT_STATE:
|
||||||
|
case PPP_ACK_RCVD_STATE:
|
||||||
|
case PPP_ACK_SENT_STATE:
|
||||||
|
NewState(PPP_STOPPED_STATE);
|
||||||
|
|
||||||
|
case PPP_STOPPED_STATE:
|
||||||
|
locker.UnlockNow();
|
||||||
|
ThisLayerFinished();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PPP_OPENED_STATE:
|
||||||
|
NewState(PPP_STOPPING_STATE);
|
||||||
|
InitializeRestartCounter();
|
||||||
|
locker.UnlockNow();
|
||||||
|
ThisLayerDown();
|
||||||
|
SendTerminateRequest();
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// receive echo request/reply, discard request
|
||||||
void
|
void
|
||||||
PPPFSM::RXREvent()
|
PPPFSM::RXREvent(mbuf *packet)
|
||||||
{
|
{
|
||||||
LockerHelper locker(fLock);
|
LockerHelper locker(fLock);
|
||||||
|
|
||||||
|
switch(State()) {
|
||||||
|
case PPP_INITIAL_STATE:
|
||||||
|
case PPP_STARTING_STATE:
|
||||||
|
IllegalEvent(PPP_RXR_EVENT);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PPP_OPENED_STATE:
|
||||||
|
SendEchoReply(packet);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// general events (for Good/Bad events)
|
||||||
|
void
|
||||||
|
PPPFSM::TimerEvent()
|
||||||
|
{
|
||||||
|
// TODO:
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ReceiveConfigureRequest
|
||||||
|
// Here we get a configure-request packet from LCP and aks all OptionHandlers
|
||||||
|
// if its values are acceptable. From here we call our Good/Bad counterparts.
|
||||||
|
void
|
||||||
|
PPPFSM::RCREvent(mbuf *packet)
|
||||||
|
{
|
||||||
|
PPPConfigurePacket request(packet), nak(PPP_CONFIGURE_NAK),
|
||||||
|
reject(PPP_CONFIGURE_REJECT);
|
||||||
|
PPPOptionHandler *handler;
|
||||||
|
|
||||||
|
// each handler should add unacceptable values for each item
|
||||||
|
for(int32 item = 0; item < request.CountItems(); item++) {
|
||||||
|
for(int32 index = 0; index < Interface()->CountOptionHandlers();
|
||||||
|
index++) {
|
||||||
|
handler = Interface()->OptionHandlerAt(i);
|
||||||
|
if(!handler->ParseConfigureRequest(&request, item, &nak, &reject)) {
|
||||||
|
// the request contains a value that has been sent more than
|
||||||
|
// once or the value is corrupted
|
||||||
|
CloseEvent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(nak.CountItems() > 0)
|
||||||
|
RCRBadEvent(nak.ToMbuf(), NULL);
|
||||||
|
else if(reject.CountItmes() > 0)
|
||||||
|
RCRBadEvent(NULL, reject.ToMbuf());
|
||||||
|
else
|
||||||
|
RCRGoodEvent(packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ReceiveCodeReject
|
||||||
|
// LCP received a code-reject packet and we look if it is acceptable.
|
||||||
|
// From here we call our Good/Bad counterparts.
|
||||||
|
void
|
||||||
|
PPPFSM::RXJEvent(mbuf *packet)
|
||||||
|
{
|
||||||
|
lcp_packet *reject = (lcp_packet*) packet;
|
||||||
|
|
||||||
|
if(reject->code == PPP_CODE_REJECT)
|
||||||
|
RXJBadEvent(packet);
|
||||||
|
else if(reject->code == PPP_PROTOCOL_REJECT) {
|
||||||
|
// disable all handlers for rejected protocol type
|
||||||
|
uint16 rejected = *((uint16*) reject->data);
|
||||||
|
// rejected protocol number
|
||||||
|
|
||||||
|
if(rejected == PPP_LCP_PROTOCOL) {
|
||||||
|
// LCP must not be rejected!
|
||||||
|
RXJBadEvent(packet);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 index;
|
||||||
|
PPPProtocol *protocol_handler;
|
||||||
|
PPPEncapsulator *encapsulator_handler = fFirstEncapsulator;
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
for(; encapsulator_handler;
|
||||||
|
encapsulator_handler = encapsulator_handler->Next()) {
|
||||||
|
if(encapsulator_handler->Protocol() == rejected)
|
||||||
|
encapsulator_handler->SetEnabled(false);
|
||||||
|
// disable encapsulator
|
||||||
|
}
|
||||||
|
|
||||||
|
RXJGoodEvent(packet);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -507,6 +882,7 @@ PPPFSM::RXREvent()
|
||||||
void
|
void
|
||||||
PPPFSM::IllegalEvent(PPP_EVENT event)
|
PPPFSM::IllegalEvent(PPP_EVENT event)
|
||||||
{
|
{
|
||||||
|
// TODO:
|
||||||
// update error statistics
|
// update error statistics
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -558,15 +934,14 @@ PPPFSM::SendConfigureRequest()
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
PPPFSM::SendConfigureAck(PPPConfigurePacket *packet)
|
PPPFSM::SendConfigureAck(mbuf *packet)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
PPPFSM::SendConfigureNak(PPPConfigurePacket *packet)
|
PPPFSM::SendConfigureNak(mbuf *packet)
|
||||||
{
|
{
|
||||||
// is this needed?
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -577,18 +952,18 @@ PPPFSM::SendTerminateRequest()
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
PPPFSM::SendTerminateAck()
|
PPPFSM::SendTerminateAck(mbuf *request)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
PPPFSM::SendCodeReject()
|
PPPFSM::SendCodeReject(mbuf *packet)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
PPPFSM::SendEchoReply()
|
PPPFSM::SendEchoReply(mbuf *request)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -620,9 +620,12 @@ PPPInterface::Receive(mbuf *packet, uint16 protocol)
|
||||||
PPPEncapsulator *encapsulator_handler = EncapsulatorFor(protocol);
|
PPPEncapsulator *encapsulator_handler = EncapsulatorFor(protocol);
|
||||||
for(; encapsulator_handler;
|
for(; encapsulator_handler;
|
||||||
encapsulator_handler = EncapsulatorFor(protocol, encapsulator_handler)) {
|
encapsulator_handler = EncapsulatorFor(protocol, encapsulator_handler)) {
|
||||||
if(!encapsulator_handler->IsEnabled())
|
if(!encapsulator_handler->IsEnabled()) {
|
||||||
|
// disabled handlers should not be used
|
||||||
|
result = PPP_REJECTED;
|
||||||
continue;
|
continue;
|
||||||
// disabled handlers should not be used
|
}
|
||||||
|
|
||||||
result = encapsulator_handler->Receive(packet, protocol);
|
result = encapsulator_handler->Receive(packet, protocol);
|
||||||
if(result == PPP_UNHANDLED)
|
if(result == PPP_UNHANDLED)
|
||||||
continue;
|
continue;
|
||||||
|
@ -634,10 +637,15 @@ PPPInterface::Receive(mbuf *packet, uint16 protocol)
|
||||||
PPPProtocol *protocol_handler;
|
PPPProtocol *protocol_handler;
|
||||||
for(int32 index = 0; index < CountProtocols(); index++) {
|
for(int32 index = 0; index < CountProtocols(); index++) {
|
||||||
protocol_handler = ProtocolAt(index);
|
protocol_handler = ProtocolAt(index);
|
||||||
if(protocol != protocol_handler->Protocol()
|
if(protocol != protocol_handler->Protocol())
|
||||||
|| !protocol_handler->IsEnabled())
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if(!protocol_handler->IsEnabled()) {
|
||||||
|
// disabled handlers should not be used
|
||||||
|
result = PPP_REJECTED;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
result = protocol_handler->Receive(packet, protocol);
|
result = protocol_handler->Receive(packet, protocol);
|
||||||
if(result == PPP_UNHANDLED)
|
if(result == PPP_UNHANDLED)
|
||||||
continue;
|
continue;
|
||||||
|
@ -704,6 +712,13 @@ PPPInterface::SendToDevice(mbuf *packet, uint16 protocol)
|
||||||
if(packet == NULL)
|
if(packet == NULL)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
|
// check if packet is too big
|
||||||
|
if((packet->m_flags & M_PKTHDR && packet->m_pkt_hdr.len > LinkMTU())
|
||||||
|
|| packet->m_len > LinkMTU()) {
|
||||||
|
m_free(packet);
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
// set protocol (the only header field)
|
// set protocol (the only header field)
|
||||||
protocol = htons(protocol);
|
protocol = htons(protocol);
|
||||||
uint16 *header = mtod(packet, uint16*);
|
uint16 *header = mtod(packet, uint16*);
|
||||||
|
|
Loading…
Reference in New Issue