Added some helper functions and improved PPPLCPExtension handling.

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@4519 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Waldemar Kornewald
2003-09-06 23:54:35 +00:00
parent c7c8500780
commit 283ad63871
6 changed files with 190 additions and 49 deletions
@@ -13,6 +13,9 @@
#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 // this allows you to ask for specific interface_ids
enum PPP_INTERFACE_FILTER { enum PPP_INTERFACE_FILTER {
PPP_ALL_INTERFACES, PPP_ALL_INTERFACES,
@@ -29,6 +32,7 @@ typedef struct ppp_manager_info {
void (*delete_interface)(interface_id ID); void (*delete_interface)(interface_id ID);
// this marks the interface for deletion // this marks the interface for deletion
void (*remove_interface)(interface_id ID); void (*remove_interface)(interface_id ID);
// remove the interface from database (make sure you can delete it yourself!)
ifnet* (*register_interface)(interface_id ID); ifnet* (*register_interface)(interface_id ID);
bool (*unregister_interface)(interface_id ID); bool (*unregister_interface)(interface_id ID);
@@ -45,7 +45,17 @@ class PPPStateMachine {
{ return fPhase; } { return fPhase; }
uint8 NextID(); 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 // public events
void AuthenticationRequested(); void AuthenticationRequested();
@@ -124,7 +134,7 @@ class PPPStateMachine {
void ThisLayerFinished(); void ThisLayerFinished();
void InitializeRestartCount(); void InitializeRestartCount();
void ZeroRestartCount(); void ZeroRestartCount();
void SendConfigureRequest(); bool SendConfigureRequest();
void SendConfigureAck(struct mbuf *packet); void SendConfigureAck(struct mbuf *packet);
void SendConfigureNak(struct mbuf *packet); void SendConfigureNak(struct mbuf *packet);
void SendTerminateRequest(); void SendTerminateRequest();
@@ -147,6 +157,7 @@ class PPPStateMachine {
PPP_STATE fState; PPP_STATE fState;
vint32 fID; vint32 fID;
uint32 fMagicNumber;
PPP_AUTHENTICATION_STATUS fAuthenticationStatus, PPP_AUTHENTICATION_STATUS fAuthenticationStatus,
fPeerAuthenticationStatus; fPeerAuthenticationStatus;
@@ -157,8 +168,8 @@ class PPPStateMachine {
// counters and timers // counters and timers
int32 fMaxRequest, fMaxTerminate, fMaxNak; int32 fMaxRequest, fMaxTerminate, fMaxNak;
int32 fRequestCounter, fTerminateCounter, fNakCounter; int32 fRequestCounter, fTerminateCounter, fNakCounter;
uint8 fRequestID, fTerminateID; uint8 fRequestID, fTerminateID, fEchoID;
// the ID we used for the last configure/terminate request // the ID we used for the last configure/terminate/echo request
bigtime_t fNextTimeout; bigtime_t fNextTimeout;
}; };
@@ -86,6 +86,7 @@ typedef struct ppp_control_info {
typedef struct ppp_interface_info { typedef struct ppp_interface_info {
const driver_settings *settings; const driver_settings *settings;
struct ifnet *ifnet;
PPP_MODE mode; PPP_MODE mode;
PPP_STATE state; PPP_STATE state;
@@ -240,6 +240,7 @@ PPPInterface::Control(uint32 op, void *data, size_t length)
ppp_interface_info *info = (ppp_interface_info*) data; ppp_interface_info *info = (ppp_interface_info*) data;
memset(info, 0, sizeof(ppp_interface_info_t)); memset(info, 0, sizeof(ppp_interface_info_t));
info->settings = Settings(); info->settings = Settings();
info->ifnet = Ifnet();
info->mode = Mode(); info->mode = Mode();
info->state = State(); info->state = State();
info->phase = Phase(); info->phase = Phase();
+52 -14
View File
@@ -159,14 +159,26 @@ PPPLCP::Send(struct mbuf *packet)
status_t status_t
PPPLCP::Receive(struct mbuf *packet, uint16 protocol) PPPLCP::Receive(struct mbuf *packet, uint16 protocol)
{ {
if(!packet)
return B_ERROR;
if(protocol != PPP_LCP_PROTOCOL) if(protocol != PPP_LCP_PROTOCOL)
return PPP_UNHANDLED; 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*); ppp_lcp_packet *data = mtod(packet, ppp_lcp_packet*);
if(ntohs(data->length) < 4) if(ntohs(data->length) < 4)
return B_ERROR; return B_ERROR;
bool handled = true;
switch(data->code) { switch(data->code) {
case PPP_CONFIGURE_REQUEST: case PPP_CONFIGURE_REQUEST:
StateMachine().RCREvent(packet); StateMachine().RCREvent(packet);
@@ -198,36 +210,62 @@ PPPLCP::Receive(struct mbuf *packet, uint16 protocol)
break; break;
case PPP_ECHO_REQUEST: case PPP_ECHO_REQUEST:
case PPP_ECHO_REPLY:
case PPP_DISCARD_REQUEST:
StateMachine().RXREvent(packet); StateMachine().RXREvent(packet);
break; break;
case PPP_ECHO_REPLY: default:
case PPP_DISCARD_REQUEST:
m_freem(packet); m_freem(packet);
// do nothing handled = false;
break; }
default: { if(!copy)
status_t result = PPP_UNHANDLED; return handled ? B_OK : B_ERROR;
// try to find LCP extensions that can handle this code 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; PPPLCPExtension *extension;
for(int32 index = 0; index < CountLCPExtensions(); index++) { for(int32 index = 0; index < CountLCPExtensions(); index++) {
extension = LCPExtensionAt(index); extension = LCPExtensionAt(index);
if(extension->IsEnabled() && extension->Code() == data->code) if(extension->IsEnabled() && extension->Code() == data->code) {
result = extension->Receive(packet, 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) { result = extension->Receive(copy, data->code);
StateMachine().RUCEvent(packet, PPP_LCP_PROTOCOL, PPP_CODE_REJECT);
return PPP_REJECTED;
}
if(result == B_OK) {
copy = NULL;
handled = true;
} else if(result != PPP_UNHANDLED)
return result; 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;
} }
+110 -24
View File
@@ -23,12 +23,12 @@
PPPStateMachine::PPPStateMachine(PPPInterface& interface) PPPStateMachine::PPPStateMachine(PPPInterface& interface)
: fInterface(&interface), fLCP(interface.LCP()), fPhase(PPP_DOWN_PHASE), : fInterface(&interface), fLCP(interface.LCP()), fPhase(PPP_DOWN_PHASE),
fState(PPP_INITIAL_STATE), fID(system_time() & 0xFF), fState(PPP_INITIAL_STATE), fID(system_time() & 0xFF), fMagicNumber(0),
fAuthenticationStatus(PPP_NOT_AUTHENTICATED), fAuthenticationStatus(PPP_NOT_AUTHENTICATED),
fPeerAuthenticationStatus(PPP_NOT_AUTHENTICATED), fPeerAuthenticationStatus(PPP_NOT_AUTHENTICATED),
fAuthenticationName(NULL), fPeerAuthenticationName(NULL), fAuthenticationName(NULL), fPeerAuthenticationName(NULL),
fMaxRequest(10), fMaxTerminate(2), fMaxNak(5), 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 // authentication events
void void
PPPStateMachine::AuthenticationRequested() PPPStateMachine::AuthenticationRequested()
@@ -1067,6 +1138,8 @@ PPPStateMachine::RUCEvent(struct mbuf *packet, uint16 protocol,
void void
PPPStateMachine::RXJGoodEvent(struct mbuf *packet) 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); LockerHelper locker(fLock);
switch(State()) { switch(State()) {
@@ -1135,6 +1208,11 @@ PPPStateMachine::RXREvent(struct mbuf *packet)
{ {
ppp_lcp_packet *echo = mtod(packet, ppp_lcp_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()) { switch(State()) {
case PPP_INITIAL_STATE: case PPP_INITIAL_STATE:
case PPP_STARTING_STATE: case PPP_STARTING_STATE:
@@ -1145,6 +1223,7 @@ PPPStateMachine::RXREvent(struct mbuf *packet)
if(echo->code == PPP_ECHO_REQUEST) if(echo->code == PPP_ECHO_REQUEST)
SendEchoReply(packet); SendEchoReply(packet);
return; return;
// this prevents the packet from being freed
default: default:
; ;
@@ -1401,7 +1480,7 @@ PPPStateMachine::ZeroRestartCount()
} }
void bool
PPPStateMachine::SendConfigureRequest() PPPStateMachine::SendConfigureRequest()
{ {
--fRequestCounter; --fRequestCounter;
@@ -1414,19 +1493,19 @@ PPPStateMachine::SendConfigureRequest()
// add all items // add all items
if(!LCP().OptionHandlerAt(index)->AddToRequest(&request)) { if(!LCP().OptionHandlerAt(index)->AddToRequest(&request)) {
CloseEvent(); 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) PPPStateMachine::SendConfigureAck(struct mbuf *packet)
{ {
if(!packet) if(!packet)
return; return false;
mtod(packet, ppp_lcp_packet*)->code = PPP_CONFIGURE_ACK; mtod(packet, ppp_lcp_packet*)->code = PPP_CONFIGURE_ACK;
PPPConfigurePacket ack(packet); PPPConfigurePacket ack(packet);
@@ -1435,15 +1514,15 @@ PPPStateMachine::SendConfigureAck(struct mbuf *packet)
for(int32 index = 0; index < LCP().CountOptionHandlers(); index++) for(int32 index = 0; index < LCP().CountOptionHandlers(); index++)
LCP().OptionHandlerAt(index)->SendingAck(&ack); LCP().OptionHandlerAt(index)->SendingAck(&ack);
LCP().Send(packet); return LCP().Send(packet) == B_OK;
} }
void bool
PPPStateMachine::SendConfigureNak(struct mbuf *packet) PPPStateMachine::SendConfigureNak(struct mbuf *packet)
{ {
if(!packet) if(!packet)
return; return false;
ppp_lcp_packet *nak = mtod(packet, ppp_lcp_packet*); ppp_lcp_packet *nak = mtod(packet, ppp_lcp_packet*);
if(nak->code == PPP_CONFIGURE_NAK) { if(nak->code == PPP_CONFIGURE_NAK) {
@@ -1454,16 +1533,16 @@ PPPStateMachine::SendConfigureNak(struct mbuf *packet)
--fNakCounter; --fNakCounter;
} }
LCP().Send(packet); return LCP().Send(packet) == B_OK;
} }
void bool
PPPStateMachine::SendTerminateRequest() PPPStateMachine::SendTerminateRequest()
{ {
struct mbuf *m = m_gethdr(MT_DATA); struct mbuf *m = m_gethdr(MT_DATA);
if(!m) if(!m)
return; return false;
--fTerminateCounter; --fTerminateCounter;
@@ -1477,11 +1556,11 @@ PPPStateMachine::SendTerminateRequest()
request->id = fTerminateID = NextID(); request->id = fTerminateID = NextID();
request->length = htons(4); request->length = htons(4);
LCP().Send(m); return LCP().Send(m) == B_OK;
} }
void bool
PPPStateMachine::SendTerminateAck(struct mbuf *request = NULL) PPPStateMachine::SendTerminateAck(struct mbuf *request = NULL)
{ {
struct mbuf *reply = request; struct mbuf *reply = request;
@@ -1491,7 +1570,7 @@ PPPStateMachine::SendTerminateAck(struct mbuf *request = NULL)
if(!reply) { if(!reply) {
reply = m_gethdr(MT_DATA); reply = m_gethdr(MT_DATA);
if(!reply) if(!reply)
return; return false;
reply->m_data += LCP().AdditionalOverhead(); reply->m_data += LCP().AdditionalOverhead();
reply->m_len = 4; reply->m_len = 4;
@@ -1502,17 +1581,17 @@ PPPStateMachine::SendTerminateAck(struct mbuf *request = NULL)
ack = mtod(reply, ppp_lcp_packet*); ack = mtod(reply, ppp_lcp_packet*);
ack->code = PPP_TERMINATE_ACK; 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) PPPStateMachine::SendCodeReject(struct mbuf *packet, uint16 protocol, uint8 code)
{ {
if(!packet) if(!packet)
return; return false;
int32 length; int32 length;
// additional space needed for this reject // additional space needed for this reject
@@ -1547,21 +1626,28 @@ PPPStateMachine::SendCodeReject(struct mbuf *packet, uint16 protocol, uint8 code
if(code == PPP_PROTOCOL_REJECT) if(code == PPP_PROTOCOL_REJECT)
memcpy(&reject->data, &protocol, sizeof(protocol)); memcpy(&reject->data, &protocol, sizeof(protocol));
LCP().Send(packet); return LCP().Send(packet) == B_OK;
} }
void bool
PPPStateMachine::SendEchoReply(struct mbuf *request) PPPStateMachine::SendEchoReply(struct mbuf *request)
{ {
if(!request) if(!request)
return; return false;
ppp_lcp_packet *reply = mtod(request, ppp_lcp_packet*); ppp_lcp_packet *reply = mtod(request, ppp_lcp_packet*);
reply->code = PPP_ECHO_REPLY; reply->code = PPP_ECHO_REPLY;
// the request becomes a 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;
} }