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:
parent
c7c8500780
commit
283ad63871
@ -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);
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user