From 06a35e5e8288ffac705731a2df45c618b6f44307 Mon Sep 17 00:00:00 2001 From: Waldemar Kornewald Date: Thu, 10 Jul 2003 11:08:44 +0000 Subject: [PATCH] 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 --- src/tests/kits/net/ppp/headers/AccessHelper.h | 5 + .../net/ppp/headers/KPPPConfigurePacket.h | 32 +- src/tests/kits/net/ppp/headers/KPPPDefs.h | 4 +- src/tests/kits/net/ppp/headers/KPPPFSM.h | 51 ++- .../kits/net/ppp/headers/KPPPInterface.h | 14 +- src/tests/kits/net/ppp/headers/KPPPLCP.h | 14 +- src/tests/kits/net/ppp/headers/KPPPModule.h | 3 +- src/tests/kits/net/ppp/headers/LockerHelper.h | 7 +- src/tests/kits/net/ppp/src/KPPPFSM.cpp | 421 +++++++++++++++++- src/tests/kits/net/ppp/src/KPPPInterface.cpp | 23 +- 10 files changed, 508 insertions(+), 66 deletions(-) diff --git a/src/tests/kits/net/ppp/headers/AccessHelper.h b/src/tests/kits/net/ppp/headers/AccessHelper.h index 4c25068d3e..93d8cfad6d 100644 --- a/src/tests/kits/net/ppp/headers/AccessHelper.h +++ b/src/tests/kits/net/ppp/headers/AccessHelper.h @@ -16,6 +16,11 @@ class AccessHelper { + private: + // copies are not allowed! + AccessHelper(const AccessHelper& copy); + AccessHelper& operator= (const AccessHelper& copy); + public: AccessHelper(vint32 *access) : fAccess(access) { diff --git a/src/tests/kits/net/ppp/headers/KPPPConfigurePacket.h b/src/tests/kits/net/ppp/headers/KPPPConfigurePacket.h index b8dbc38fbe..1e402d76ef 100644 --- a/src/tests/kits/net/ppp/headers/KPPPConfigurePacket.h +++ b/src/tests/kits/net/ppp/headers/KPPPConfigurePacket.h @@ -5,31 +5,43 @@ typedef struct configure_item { - void *data; - int32 len; uint8 type; + uint8 length; + int8 data[0]; + // the data follows this structure } configure_item; class PPPConfigurePacket { + private: + // copies are not allowed! + PPPConfigurePacket(const PPPConfigurePacket& copy); + PPPConfigurePacket& operator= (const PPPConfigurePacket& copy); + public: - PPPConfigurePacket(uint8 type); + PPPConfigurePacket(uint8 code); PPPConfigurePacket(mbuf *data); ~PPPConfigurePacket(); - bool SetType(uint8 type); - uint8 Type() const - { return fType; } + bool SetCode(uint8 code); + uint8 Code() const + { return fCode; } - void AddItem(configure_item *item); - bool RemoveItem(configure_item *item); + void SetID(uint8 id) + { fID = id; } + uint8 ID() const + { return fID; } + + void AddItem(const configure_item *item); + bool RemoveItem(const configure_item *item); int32 CountItems() const; configure_item *ItemAt(int32 index) const; - mbuf *ToMbuf() const; + mbuf *ToMbuf(); + // the user is responsible for freeing the mbuf private: - uint8 fType; + uint8 fCode, fID; }; diff --git a/src/tests/kits/net/ppp/headers/KPPPDefs.h b/src/tests/kits/net/ppp/headers/KPPPDefs.h index b42e154fe5..c006ec38b4 100644 --- a/src/tests/kits/net/ppp/headers/KPPPDefs.h +++ b/src/tests/kits/net/ppp/headers/KPPPDefs.h @@ -22,7 +22,7 @@ #define PPP_MODULES_PATH "network/ppp-modules" // built-in protocols -// #define PPP_LCP_PROTOCOL 0xC021 +#define PPP_LCP_PROTOCOL 0xC021 #define PPP_ERROR_BASE B_ERRORS_END @@ -181,5 +181,7 @@ enum PPP_LCP_TYPE { PPP_DISCARD_REQUEST = 11 }; +#define PPP_MIN_LCP_CODE PPP_CONFIGURE_REQUEST +#define PPP_MAX_LCP_CODE PPP_DISCARD_REQUEST #endif diff --git a/src/tests/kits/net/ppp/headers/KPPPFSM.h b/src/tests/kits/net/ppp/headers/KPPPFSM.h index 414fc3d1ef..308933f27b 100644 --- a/src/tests/kits/net/ppp/headers/KPPPFSM.h +++ b/src/tests/kits/net/ppp/headers/KPPPFSM.h @@ -12,8 +12,12 @@ class PPPFSM { private: // may only be constructed/destructed by PPPInterface - PPPFSM(PPPInterface &interface); + PPPFSM(PPPInterface& interface); ~PPPFSM(); + + // copies are not allowed! + PPPFSM(const PPPFSM& copy); + PPPFSM& operator= (const PPPFSM& copy); public: PPPInterface *Interface() const @@ -24,6 +28,9 @@ class PPPFSM { PPP_PHASE Phase() const { return fPhase; } + uint8 NextID(); + // return the next id for lcp_packets + // public events void AuthenticationRequested(); void AuthenticationAccepted(const char *name); @@ -48,7 +55,7 @@ class PPPFSM { void DownEvent(); private: - BLocker &Locker() + BLocker& Locker() { return fLock; } void LeaveConstructionPhase(); void EnterDestructionPhase(); @@ -61,16 +68,21 @@ class PPPFSM { void CloseEvent(); void TOGoodEvent(); void TOBadEvent(); - void RCRGoodEvent(PPPConfigurePacket *packet); - void RCRBadEvent(PPPConfigurePacket *packet); - void RCAEvent(PPPConfigurePacket *packet); - void RCNEvent(PPPConfigurePacket *packet); - void RTREvent(); - void RTAEvent(); - void RUCEvent(); - void RJXGoodEvent(); - void RJXBadEvent(); - void RXREvent(); + void RCRGoodEvent(mbuf *packet); + void RCRBadEvent(mbuf *nak, mbuf *reject); + void RCAEvent(mbuf *packet); + void RCNEvent(mbuf *packet); + void RTREvent(mbuf *packet); + void RTAEvent(mbuf *packet); + void RUCEvent(mbuf *packet); + void RXJGoodEvent(mbuf *packet); + void RXJBadEvent(mbuf *packet); + void RXREvent(mbuf *packet); + + // general events (for Good/Bad events) + void TimerEvent(); + void RCREvent(mbuf *packet); + void RXJEvent(mbuf *packet); // actions void IllegalEvent(PPP_EVENT event); @@ -81,15 +93,12 @@ class PPPFSM { void InitializeRestartCount(); void ZeroRestartCount(); void SendConfigureRequest(); - void SendConfigureAck(PPPConfigurePacket *packet); - - void SendConfigureNak(PPPConfigurePacket *packet); - // is this needed? - + void SendConfigureAck(mbuf *packet); + void SendConfigureNak(mbuf *packet); void SendTerminateRequest(); - void SendTerminateAck(); - void SendCodeReject(); - void SendEchoReply(); + void SendTerminateAck(mbuf *request); + void SendCodeReject(mbuf *packet); + void SendEchoReply(mbuf *request); private: PPPInterface *fInterface; @@ -97,6 +106,8 @@ class PPPFSM { PPP_PHASE fPhase; PPP_STATE fState; + vint32 fID; + PPP_AUTHENTICATION_STATUS fAuthenticationStatus, fPeerAuthenticationStatus; int32 fAuthenticatorIndex, fPeerAuthenticatorIndex; diff --git a/src/tests/kits/net/ppp/headers/KPPPInterface.h b/src/tests/kits/net/ppp/headers/KPPPInterface.h index b024e3e00b..4cfc246ed8 100644 --- a/src/tests/kits/net/ppp/headers/KPPPInterface.h +++ b/src/tests/kits/net/ppp/headers/KPPPInterface.h @@ -11,14 +11,18 @@ #include "List.h" #include "LockerHelper.h" -class PPPAuthenticator; class PPPDevice; +class PPPProtocol; class PPPEncapsulator; class PPPOptionHandler; -class PPPProtocol; class PPPInterface { + private: + // copies are not allowed! + PPPInterface(const PPPInterface& copy); + PPPInterface& operator= (const PPPInterface& copy); + public: PPPInterface(driver_settings *settings); ~PPPInterface(); @@ -28,7 +32,7 @@ class PPPInterface { driver_settings* Settings() { return fSettings; } - PPPFSM &FSM() const + PPPFSM& FSM() const { return fFSM; } bool RegisterInterface(); @@ -108,7 +112,7 @@ class PPPInterface { status_t ReceiveFromDevice(mbuf *packet); private: - PPPLCP &LCP() const + PPPLCP& LCP() const { return fLCP; } void CalculateMRU(); @@ -135,7 +139,7 @@ class PPPInterface { List fOptionHandlers; List fModules; - BLocker &fGeneralLock; + BLocker& fGeneralLock; }; diff --git a/src/tests/kits/net/ppp/headers/KPPPLCP.h b/src/tests/kits/net/ppp/headers/KPPPLCP.h index 03eb179a84..7fa9b4b85c 100644 --- a/src/tests/kits/net/ppp/headers/KPPPLCP.h +++ b/src/tests/kits/net/ppp/headers/KPPPLCP.h @@ -4,13 +4,25 @@ #include "KPPPProtocol.h" +typedef struct lcp_packet { + uint8 code; + uint8 id; + uint16 length; + int8 data[0]; +} lcp_packet; + + class PPPLCP : public PPPProtocol { friend class PPPInterface; private: // may only be constructed/destructed by PPPInterface - PPPLCP(PPPInterface &interface); + PPPLCP(PPPInterface& interface); ~PPPLCP(); + + // copies are not allowed! + PPPLCP(const PPPLCP& copy); + PPPLCP& operator= (const PPPLCP& copy); public: diff --git a/src/tests/kits/net/ppp/headers/KPPPModule.h b/src/tests/kits/net/ppp/headers/KPPPModule.h index 81c62f4dd5..6c2eae977e 100644 --- a/src/tests/kits/net/ppp/headers/KPPPModule.h +++ b/src/tests/kits/net/ppp/headers/KPPPModule.h @@ -9,7 +9,8 @@ class PPPInterface; typedef struct ppp_module_info { module_info minfo; 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; diff --git a/src/tests/kits/net/ppp/headers/LockerHelper.h b/src/tests/kits/net/ppp/headers/LockerHelper.h index b53a83e0dd..60ac66e071 100644 --- a/src/tests/kits/net/ppp/headers/LockerHelper.h +++ b/src/tests/kits/net/ppp/headers/LockerHelper.h @@ -16,8 +16,13 @@ class LockerHelper { + private: + // copies are not allowed! + LockerHelper(const LockerHelper& copy); + LockerHelper& operator= (const LockerHelper& copy); + public: - LockerHelper(BLocker &lock) : fLock(&lock) + LockerHelper(BLocker& lock) : fLock(&lock) { if(fLock->Lock() != B_OK) fLock = NULL; diff --git a/src/tests/kits/net/ppp/src/KPPPFSM.cpp b/src/tests/kits/net/ppp/src/KPPPFSM.cpp index 0124cb4689..c8a0e0253b 100644 --- a/src/tests/kits/net/ppp/src/KPPPFSM.cpp +++ b/src/tests/kits/net/ppp/src/KPPPFSM.cpp @@ -1,9 +1,9 @@ #include "KPPPFSM.h" -PPPFSM::PPPFSM(PPPInterface &interface) +PPPFSM::PPPFSM(PPPInterface& interface) : fInterface(&interface), fPhase(PPP_CTOR_DTOR_PHASE), - fState(PPP_INITIAL_STATE), + fState(PPP_INITIAL_STATE), fID(system_time() & 0xFF), fAuthenticationStatus(PPP_NOT_AUTHENTICATED), fPeerAuthenticationStatus(PPP_NOT_AUTHENTICATED), 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() // because IllegalEvent() also looks at the current state. void PPPFSM::NewState(PPP_STATE 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 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 PPPFSM::TLFNotify() { @@ -202,8 +220,8 @@ PPPFSM::UpEvent() break; } - InitializeRestartCounter(); NewState(PPP_REQ_SENT_STATE); + InitializeRestartCounter(); locker.UnlockNow(); SendConfigureRequest(); break; @@ -222,6 +240,7 @@ PPPFSM::DownEvent() // TODO: // ResetProtocols(); // ResetEncapsulators(); + // ResetOptionHandlers(); switch(State()) { case PPP_CLOSED_STATE: @@ -307,9 +326,9 @@ PPPFSM::OpenEvent() return; } - InitializeRestartCounter(); NewState(PPP_REQ_SENT_STATE); fPhase = PPP_ESTABLISHMENT_PHASE; + InitializeRestartCounter(); locker.UnlockNow(); SendConfigureRequest(); break; @@ -332,9 +351,9 @@ PPPFSM::CloseEvent() case PPP_REQ_SENT_STATE: case PPP_ACK_RCVD_STATE: case PPP_ACK_SENT_STATE: - InitializeRestartCounter(); NewState(PPP_CLOSING_STATE); fPhase = PPP_TERMINATION_PHASE; + InitializeRestartCounter(); locker.UnlockNow(); SendTerminateRequest(); break; @@ -366,6 +385,7 @@ PPPFSM::CloseEvent() } +// timeout (restart counters are > 0) void PPPFSM::TOGoodEvent() { @@ -393,6 +413,7 @@ PPPFSM::TOGoodEvent() } +// timeout (restart counters are <= 0) void PPPFSM::TOBadEvent() { @@ -422,84 +443,438 @@ PPPFSM::TOBadEvent() } +// receive configure request (acceptable request) void -PPPFSM::RCRGoodEvent(PPPConfigurePacket *packet) +PPPFSM::RCRGoodEvent(mbuf *packet) { 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 -PPPFSM::RCRBadEvent(PPPConfigurePacket *packet) +PPPFSM::RCRBadEvent(mbuf *nak, mbuf *reject) { 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 -PPPFSM::RCAEvent(PPPConfigurePacket *packet) +PPPFSM::RCAEvent(mbuf *packet) { 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 -PPPFSM::RCNEvent(PPPConfigurePacket *packet) +PPPFSM::RCNEvent(mbuf *packet) { 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 -PPPFSM::RTREvent() +PPPFSM::RTREvent(mbuf *packet) { 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 -PPPFSM::RTAEvent() +PPPFSM::RTAEvent(mbuf *packet) { 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 -PPPFSM::RUCEvent() +PPPFSM::RUCEvent(mbuf *packet) { 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 -PPPFSM::RXJGoodEvent() +PPPFSM::RXJGoodEvent(mbuf *packet) { 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 -PPPFSM::RXJBadEvent() +PPPFSM::RXJBadEvent(mbuf *packet) { 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 -PPPFSM::RXREvent() +PPPFSM::RXREvent(mbuf *packet) { 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 PPPFSM::IllegalEvent(PPP_EVENT event) { + // TODO: // update error statistics } @@ -558,15 +934,14 @@ PPPFSM::SendConfigureRequest() void -PPPFSM::SendConfigureAck(PPPConfigurePacket *packet) +PPPFSM::SendConfigureAck(mbuf *packet) { } void -PPPFSM::SendConfigureNak(PPPConfigurePacket *packet) +PPPFSM::SendConfigureNak(mbuf *packet) { - // is this needed? } @@ -577,18 +952,18 @@ PPPFSM::SendTerminateRequest() void -PPPFSM::SendTerminateAck() +PPPFSM::SendTerminateAck(mbuf *request) { } void -PPPFSM::SendCodeReject() +PPPFSM::SendCodeReject(mbuf *packet) { } void -PPPFSM::SendEchoReply() +PPPFSM::SendEchoReply(mbuf *request) { } diff --git a/src/tests/kits/net/ppp/src/KPPPInterface.cpp b/src/tests/kits/net/ppp/src/KPPPInterface.cpp index 9e68a665d5..65e22e99b5 100644 --- a/src/tests/kits/net/ppp/src/KPPPInterface.cpp +++ b/src/tests/kits/net/ppp/src/KPPPInterface.cpp @@ -620,9 +620,12 @@ PPPInterface::Receive(mbuf *packet, uint16 protocol) PPPEncapsulator *encapsulator_handler = EncapsulatorFor(protocol); for(; 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; - // disabled handlers should not be used + } + result = encapsulator_handler->Receive(packet, protocol); if(result == PPP_UNHANDLED) continue; @@ -634,10 +637,15 @@ PPPInterface::Receive(mbuf *packet, uint16 protocol) PPPProtocol *protocol_handler; for(int32 index = 0; index < CountProtocols(); index++) { protocol_handler = ProtocolAt(index); - if(protocol != protocol_handler->Protocol() - || !protocol_handler->IsEnabled()) + if(protocol != protocol_handler->Protocol()) continue; + if(!protocol_handler->IsEnabled()) { + // disabled handlers should not be used + result = PPP_REJECTED; + continue; + } + result = protocol_handler->Receive(packet, protocol); if(result == PPP_UNHANDLED) continue; @@ -704,6 +712,13 @@ PPPInterface::SendToDevice(mbuf *packet, uint16 protocol) if(packet == NULL) 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) protocol = htons(protocol); uint16 *header = mtod(packet, uint16*);