From 283ad63871dc7171ae5fa4f0c5678e1fe7097c59 Mon Sep 17 00:00:00 2001 From: Waldemar Kornewald Date: Sat, 6 Sep 2003 23:54:35 +0000 Subject: [PATCH] Added some helper functions and improved PPPLCPExtension handling. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@4519 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/tests/kits/net/ppp/headers/KPPPManager.h | 6 +- .../kits/net/ppp/headers/KPPPStateMachine.h | 19 ++- src/tests/kits/net/ppp/headers/PPPControl.h | 1 + src/tests/kits/net/ppp/src/KPPPInterface.cpp | 1 + src/tests/kits/net/ppp/src/KPPPLCP.cpp | 78 +++++++--- .../kits/net/ppp/src/KPPPStateMachine.cpp | 134 ++++++++++++++---- 6 files changed, 190 insertions(+), 49 deletions(-) diff --git a/src/tests/kits/net/ppp/headers/KPPPManager.h b/src/tests/kits/net/ppp/headers/KPPPManager.h index 35216ac5d2..7a8de36128 100644 --- a/src/tests/kits/net/ppp/headers/KPPPManager.h +++ b/src/tests/kits/net/ppp/headers/KPPPManager.h @@ -11,7 +11,10 @@ #include "net_module.h" -#define PPP_MANAGER_MODULE_NAME "network/interfaces/ppp" +#define PPP_MANAGER_MODULE_NAME "network/interfaces/ppp" + +#define PPP_UNDEFINED_INTERFACE_ID 0 + // create_interface() returns this value on failure // this allows you to ask for specific interface_ids enum PPP_INTERFACE_FILTER { @@ -29,6 +32,7 @@ typedef struct ppp_manager_info { void (*delete_interface)(interface_id ID); // this marks the interface for deletion void (*remove_interface)(interface_id ID); + // remove the interface from database (make sure you can delete it yourself!) ifnet* (*register_interface)(interface_id ID); bool (*unregister_interface)(interface_id ID); diff --git a/src/tests/kits/net/ppp/headers/KPPPStateMachine.h b/src/tests/kits/net/ppp/headers/KPPPStateMachine.h index ed293b9821..2973f8309d 100644 --- a/src/tests/kits/net/ppp/headers/KPPPStateMachine.h +++ b/src/tests/kits/net/ppp/headers/KPPPStateMachine.h @@ -45,7 +45,17 @@ class PPPStateMachine { { return fPhase; } uint8 NextID(); - // return the next id for lcp_packets + // return the next id for LCP packets + + void SetMagicNumber(uint32 magicNumber) + { fMagicNumber = magicNumber; } + uint32 MagicNumber() const + { return fMagicNumber; } + + // public actions + bool Reconfigure(); + bool SendEchoRequest(); + bool SendDiscardRequest(); // public events void AuthenticationRequested(); @@ -124,7 +134,7 @@ class PPPStateMachine { void ThisLayerFinished(); void InitializeRestartCount(); void ZeroRestartCount(); - void SendConfigureRequest(); + bool SendConfigureRequest(); void SendConfigureAck(struct mbuf *packet); void SendConfigureNak(struct mbuf *packet); void SendTerminateRequest(); @@ -147,6 +157,7 @@ class PPPStateMachine { PPP_STATE fState; vint32 fID; + uint32 fMagicNumber; PPP_AUTHENTICATION_STATUS fAuthenticationStatus, fPeerAuthenticationStatus; @@ -157,8 +168,8 @@ class PPPStateMachine { // counters and timers int32 fMaxRequest, fMaxTerminate, fMaxNak; int32 fRequestCounter, fTerminateCounter, fNakCounter; - uint8 fRequestID, fTerminateID; - // the ID we used for the last configure/terminate request + uint8 fRequestID, fTerminateID, fEchoID; + // the ID we used for the last configure/terminate/echo request bigtime_t fNextTimeout; }; diff --git a/src/tests/kits/net/ppp/headers/PPPControl.h b/src/tests/kits/net/ppp/headers/PPPControl.h index c388ca56fa..ea3874607f 100644 --- a/src/tests/kits/net/ppp/headers/PPPControl.h +++ b/src/tests/kits/net/ppp/headers/PPPControl.h @@ -86,6 +86,7 @@ typedef struct ppp_control_info { typedef struct ppp_interface_info { const driver_settings *settings; + struct ifnet *ifnet; PPP_MODE mode; PPP_STATE state; diff --git a/src/tests/kits/net/ppp/src/KPPPInterface.cpp b/src/tests/kits/net/ppp/src/KPPPInterface.cpp index bea6306edf..79747c8a24 100644 --- a/src/tests/kits/net/ppp/src/KPPPInterface.cpp +++ b/src/tests/kits/net/ppp/src/KPPPInterface.cpp @@ -240,6 +240,7 @@ 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(); diff --git a/src/tests/kits/net/ppp/src/KPPPLCP.cpp b/src/tests/kits/net/ppp/src/KPPPLCP.cpp index 5b996d0622..f3c83270fe 100644 --- a/src/tests/kits/net/ppp/src/KPPPLCP.cpp +++ b/src/tests/kits/net/ppp/src/KPPPLCP.cpp @@ -159,14 +159,26 @@ PPPLCP::Send(struct mbuf *packet) status_t PPPLCP::Receive(struct mbuf *packet, uint16 protocol) { + if(!packet) + return B_ERROR; + if(protocol != PPP_LCP_PROTOCOL) return PPP_UNHANDLED; + struct mbuf *copy = m_gethdr(MT_DATA); + if(copy) { + copy->m_data += AdditionalOverhead(); + copy->m_len = packet->m_len; + memcpy(copy->m_data, packet->m_data, copy->m_len); + } + ppp_lcp_packet *data = mtod(packet, ppp_lcp_packet*); if(ntohs(data->length) < 4) return B_ERROR; + bool handled = true; + switch(data->code) { case PPP_CONFIGURE_REQUEST: StateMachine().RCREvent(packet); @@ -198,36 +210,62 @@ PPPLCP::Receive(struct mbuf *packet, uint16 protocol) break; case PPP_ECHO_REQUEST: + case PPP_ECHO_REPLY: + case PPP_DISCARD_REQUEST: StateMachine().RXREvent(packet); break; - case PPP_ECHO_REPLY: - case PPP_DISCARD_REQUEST: + default: m_freem(packet); - // do nothing - break; - - default: { - status_t result = PPP_UNHANDLED; - - // try to find LCP extensions that can handle this code - PPPLCPExtension *extension; - for(int32 index = 0; index < CountLCPExtensions(); index++) { - extension = LCPExtensionAt(index); - if(extension->IsEnabled() && extension->Code() == data->code) - result = extension->Receive(packet, data->code); + handled = false; + } + + if(!copy) + return handled ? B_OK : B_ERROR; + + packet = copy; + copy = NULL; + + 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); } - if(result == PPP_UNHANDLED) { - StateMachine().RUCEvent(packet, PPP_LCP_PROTOCOL, PPP_CODE_REJECT); - return PPP_REJECTED; - } + result = extension->Receive(copy, data->code); - return result; + if(result == B_OK) { + copy = NULL; + handled = true; + } else if(result != PPP_UNHANDLED) + return result; } } - return B_OK; + if(copy) + m_freem(copy); + + if(!handled) { + StateMachine().RUCEvent(packet, PPP_LCP_PROTOCOL, PPP_CODE_REJECT); + return PPP_REJECTED; + } + + if(packet) + m_freem(packet); + + return result; } diff --git a/src/tests/kits/net/ppp/src/KPPPStateMachine.cpp b/src/tests/kits/net/ppp/src/KPPPStateMachine.cpp index e5ed171937..a4e390c20a 100644 --- a/src/tests/kits/net/ppp/src/KPPPStateMachine.cpp +++ b/src/tests/kits/net/ppp/src/KPPPStateMachine.cpp @@ -23,12 +23,12 @@ PPPStateMachine::PPPStateMachine(PPPInterface& interface) : fInterface(&interface), fLCP(interface.LCP()), fPhase(PPP_DOWN_PHASE), - fState(PPP_INITIAL_STATE), fID(system_time() & 0xFF), + fState(PPP_INITIAL_STATE), fID(system_time() & 0xFF), fMagicNumber(0), fAuthenticationStatus(PPP_NOT_AUTHENTICATED), fPeerAuthenticationStatus(PPP_NOT_AUTHENTICATED), fAuthenticationName(NULL), fPeerAuthenticationName(NULL), fMaxRequest(10), fMaxTerminate(2), fMaxNak(5), - fRequestID(0), fTerminateID(0), fNextTimeout(0) + fRequestID(0), fTerminateID(0), fEchoID(0), fNextTimeout(0) { } @@ -89,6 +89,77 @@ PPPStateMachine::NewPhase(PPP_PHASE next) } +// public actions +bool +PPPStateMachine::Reconfigure() +{ + LockerHelper locker(fLock); + + if(State() < PPP_REQ_SENT_STATE) + return false; + + NewState(PPP_REQ_SENT_STATE); + NewPhase(PPP_ESTABLISHMENT_PHASE); + + DownProtocols(); + DownEncapsulators(); + ResetOptionHandlers(); + + locker.UnlockNow(); + + return SendConfigureRequest(); +} + + +bool +PPPStateMachine::SendEchoRequest() +{ + if(State() != PPP_OPENED_STATE) + return false; + + struct mbuf *packet = m_gethdr(MT_DATA); + if(!packet) + return false; + + packet->m_data += LCP().AdditionalOverhead(); + packet->m_len = 8; + // echo requests are at least eight bytes long + + ppp_lcp_packet *request = mtod(packet, ppp_lcp_packet*); + request->code = PPP_ECHO_REQUEST; + request->id = NextID(); + fEchoID = request->id; + request->length = htons(packet->m_len); + memcpy(request->data, &fMagicNumber, sizeof(fMagicNumber)); + + return LCP.Send(packet) == B_OK; +} + + +bool +PPPStateMachine::SendDiscardRequest() +{ + if(State() != PPP_OPENED_STATE) + return false; + + struct mbuf *packet = m_gethdr(MT_DATA); + if(!packet) + return false; + + packet->m_data += LCP().AdditionalOverhead(); + packet->m_len = 8; + // discard requests are at least eight bytes long + + ppp_lcp_packet *request = mtod(packet, ppp_lcp_packet*); + request->code = PPP_DISCARD_REQUEST; + request->id = NextID(); + request->length = htons(packet->m_len); + memcpy(request->data, &fMagicNumber, sizeof(fMagicNumber)); + + return LCP.Send(packet) == B_OK; +} + + // authentication events void PPPStateMachine::AuthenticationRequested() @@ -1067,6 +1138,8 @@ PPPStateMachine::RUCEvent(struct mbuf *packet, uint16 protocol, void PPPStateMachine::RXJGoodEvent(struct mbuf *packet) { + // This method does not m_freem(packet) because the acceptable rejects are + // also passed to the parent. RXJEvent() will m_freem(packet) when needed. LockerHelper locker(fLock); switch(State()) { @@ -1135,6 +1208,11 @@ PPPStateMachine::RXREvent(struct mbuf *packet) { ppp_lcp_packet *echo = mtod(packet, ppp_lcp_packet*); + if(echo->code == PPP_ECHO_REPLY && echo->id != fEchoID) { + // TODO: + // log that we got a reply, but no request was sent + } + switch(State()) { case PPP_INITIAL_STATE: case PPP_STARTING_STATE: @@ -1145,6 +1223,7 @@ PPPStateMachine::RXREvent(struct mbuf *packet) if(echo->code == PPP_ECHO_REQUEST) SendEchoReply(packet); return; + // this prevents the packet from being freed default: ; @@ -1401,7 +1480,7 @@ PPPStateMachine::ZeroRestartCount() } -void +bool PPPStateMachine::SendConfigureRequest() { --fRequestCounter; @@ -1414,19 +1493,19 @@ PPPStateMachine::SendConfigureRequest() // add all items if(!LCP().OptionHandlerAt(index)->AddToRequest(&request)) { CloseEvent(); - return; + return false; } } - LCP().Send(request.ToMbuf(LCP().AdditionalOverhead())); + return LCP().Send(request.ToMbuf(LCP().AdditionalOverhead())) == B_OK; } -void +bool PPPStateMachine::SendConfigureAck(struct mbuf *packet) { if(!packet) - return; + return false; mtod(packet, ppp_lcp_packet*)->code = PPP_CONFIGURE_ACK; PPPConfigurePacket ack(packet); @@ -1435,15 +1514,15 @@ PPPStateMachine::SendConfigureAck(struct mbuf *packet) for(int32 index = 0; index < LCP().CountOptionHandlers(); index++) LCP().OptionHandlerAt(index)->SendingAck(&ack); - LCP().Send(packet); + return LCP().Send(packet) == B_OK; } -void +bool PPPStateMachine::SendConfigureNak(struct mbuf *packet) { if(!packet) - return; + return false; ppp_lcp_packet *nak = mtod(packet, ppp_lcp_packet*); if(nak->code == PPP_CONFIGURE_NAK) { @@ -1454,16 +1533,16 @@ PPPStateMachine::SendConfigureNak(struct mbuf *packet) --fNakCounter; } - LCP().Send(packet); + return LCP().Send(packet) == B_OK; } -void +bool PPPStateMachine::SendTerminateRequest() { struct mbuf *m = m_gethdr(MT_DATA); if(!m) - return; + return false; --fTerminateCounter; @@ -1477,11 +1556,11 @@ PPPStateMachine::SendTerminateRequest() request->id = fTerminateID = NextID(); request->length = htons(4); - LCP().Send(m); + return LCP().Send(m) == B_OK; } -void +bool PPPStateMachine::SendTerminateAck(struct mbuf *request = NULL) { struct mbuf *reply = request; @@ -1491,7 +1570,7 @@ PPPStateMachine::SendTerminateAck(struct mbuf *request = NULL) if(!reply) { reply = m_gethdr(MT_DATA); if(!reply) - return; + return false; reply->m_data += LCP().AdditionalOverhead(); reply->m_len = 4; @@ -1502,17 +1581,17 @@ PPPStateMachine::SendTerminateAck(struct mbuf *request = NULL) ack = mtod(reply, ppp_lcp_packet*); ack->code = PPP_TERMINATE_ACK; - ack->length = 4; + ack->length = htons(4); - LCP().Send(reply); + return LCP().Send(reply) == B_OK; } -void +bool PPPStateMachine::SendCodeReject(struct mbuf *packet, uint16 protocol, uint8 code) { if(!packet) - return; + return false; int32 length; // additional space needed for this reject @@ -1547,21 +1626,28 @@ PPPStateMachine::SendCodeReject(struct mbuf *packet, uint16 protocol, uint8 code if(code == PPP_PROTOCOL_REJECT) memcpy(&reject->data, &protocol, sizeof(protocol)); - LCP().Send(packet); + return LCP().Send(packet) == B_OK; } -void +bool PPPStateMachine::SendEchoReply(struct mbuf *request) { if(!request) - return; + return false; ppp_lcp_packet *reply = mtod(request, ppp_lcp_packet*); reply->code = PPP_ECHO_REPLY; // the request becomes a reply - LCP().Send(request); + if(request->m_flags & M_PKTHDR) + request->m_pkthdr.len = 8; + + request->m_len = 8; + + memcpy(reply->data, &fMagicNumber, sizeof(fMagicNumber)); + + return LCP().Send(request) == B_OK; }