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:
Waldemar Kornewald 2003-07-10 11:08:44 +00:00
parent 2ea402ebf0
commit 06a35e5e82
10 changed files with 508 additions and 66 deletions

View File

@ -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)
{ {

View File

@ -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;
}; };

View File

@ -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

View File

@ -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;

View File

@ -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;
}; };

View File

@ -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:

View File

@ -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;

View File

@ -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;

View File

@ -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)
{ {
} }

View File

@ -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*);