Replaced some pointers with references.
Added support for Protocol-Field-Compression including the needed handler. Added initial support for ppp_manager's ioctl() function (currently, PPPInterface does not handle any ioctls). These calls are routed to all handlers, too (if PPPInterface did not handle the ioctl). Changed naming of local states and report codes (authentication, etc.). These now have "Local"/"LOCAL" in their name. Some minor changes. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@4672 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
6151971100
commit
7ff713dadd
@ -1,3 +1,10 @@
|
||||
//----------------------------------------------------------------------
|
||||
// This software is part of the OpenBeOS distribution and is covered
|
||||
// by the OpenBeOS license.
|
||||
//
|
||||
// Copyright (c) 2003 Waldemar Kornewald, Waldemar.Kornewald@web.de
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
#ifndef _K_PPP__H
|
||||
#define _K_PPP__H
|
||||
|
||||
|
@ -79,11 +79,12 @@ class PPPDevice {
|
||||
uint32 fMTU;
|
||||
bool fIsUp;
|
||||
|
||||
status_t fInitStatus;
|
||||
|
||||
private:
|
||||
char fName[PPP_HANDLER_NAME_LENGTH_LIMIT + 1];
|
||||
PPPInterface& fInterface;
|
||||
driver_parameter *fSettings;
|
||||
status_t fInitStatus;
|
||||
};
|
||||
|
||||
|
||||
|
@ -100,6 +100,8 @@ class PPPEncapsulator {
|
||||
protected:
|
||||
uint32 fOverhead;
|
||||
|
||||
status_t fInitStatus;
|
||||
|
||||
private:
|
||||
char fName[PPP_HANDLER_NAME_LENGTH_LIMIT + 1];
|
||||
ppp_phase fPhase;
|
||||
@ -115,7 +117,6 @@ class PPPEncapsulator {
|
||||
bool fEnabled;
|
||||
bool fUpRequested;
|
||||
ppp_phase fConnectionStatus;
|
||||
status_t fInitStatus;
|
||||
};
|
||||
|
||||
|
||||
|
@ -141,6 +141,21 @@ class PPPInterface {
|
||||
ppp_phase Phase() const
|
||||
{ return fStateMachine.Phase(); }
|
||||
|
||||
// Protocol-Field-Compression
|
||||
bool SetPFCOptions(uint8 pfcOptions);
|
||||
uint8 PFCOptions() const
|
||||
{ return fPFCOptions; }
|
||||
ppp_pfc_state LocalPFCState() const
|
||||
{ return fLocalPFCState; }
|
||||
// the local PFC state says if we accepted a request from the peer
|
||||
// i.e.: we may use PFC in outgoing packets
|
||||
ppp_pfc_state PeerPFCState() const
|
||||
{ return fPeerPFCState; }
|
||||
// the peer PFC state says if the peer accepted a request us
|
||||
// i.e.: the peer might send PFC-compressed packets to us
|
||||
bool UseLocalPFC() const
|
||||
{ return LocalPFCState() & PPP_PFC_ACCEPTED; }
|
||||
|
||||
bool Up();
|
||||
// in server mode Up() listens for an incoming connection
|
||||
bool Down();
|
||||
@ -175,6 +190,11 @@ class PPPInterface {
|
||||
// saves the returned ifnet structure
|
||||
bool UnregisterInterface();
|
||||
|
||||
status_t StackControl(uint32 op, void *data);
|
||||
// stack routes ioctls to interface
|
||||
status_t ControlEachHandler(uint32 op, void *data, size_t length);
|
||||
// this calls Control() with the given parameters for each handler
|
||||
|
||||
void CalculateInterfaceMTU();
|
||||
void CalculateBaudRate();
|
||||
|
||||
@ -213,9 +233,9 @@ class PPPInterface {
|
||||
|
||||
bool fAutoRedial, fDialOnDemand;
|
||||
|
||||
vint32 fAccesing;
|
||||
|
||||
ppp_mode fMode;
|
||||
ppp_pfc_state fLocalPFCState, fPeerPFCState;
|
||||
uint8 fPFCOptions;
|
||||
|
||||
PPPDevice *fDevice;
|
||||
PPPEncapsulator *fFirstEncapsulator;
|
||||
|
@ -41,12 +41,14 @@ class PPPLCPExtension {
|
||||
|
||||
virtual status_t Control(uint32 op, void *data, size_t length);
|
||||
|
||||
virtual void Reset();
|
||||
|
||||
virtual status_t Receive(struct mbuf *packet, uint8 code) = 0;
|
||||
|
||||
virtual void Reset();
|
||||
virtual void Pulse();
|
||||
|
||||
protected:
|
||||
status_t fInitStatus;
|
||||
|
||||
private:
|
||||
char fName[PPP_HANDLER_NAME_LENGTH_LIMIT + 1];
|
||||
PPPInterface& fInterface;
|
||||
@ -54,7 +56,6 @@ class PPPLCPExtension {
|
||||
uint8 fCode;
|
||||
|
||||
bool fEnabled;
|
||||
status_t fInitStatus;
|
||||
};
|
||||
|
||||
|
||||
|
@ -43,26 +43,29 @@ class PPPOptionHandler {
|
||||
|
||||
virtual status_t Control(uint32 op, void *data, size_t length);
|
||||
|
||||
virtual void Reset() = 0;
|
||||
// e.g.: remove list of rejected values
|
||||
|
||||
// we want to send a configure request or we received a reply
|
||||
virtual status_t AddToRequest(PPPConfigurePacket *request) = 0;
|
||||
virtual void ParseNak(const PPPConfigurePacket *nak) = 0;
|
||||
virtual status_t AddToRequest(PPPConfigurePacket& request) = 0;
|
||||
virtual status_t ParseNak(const PPPConfigurePacket& nak) = 0;
|
||||
// create next request based on these and previous values
|
||||
virtual void ParseReject(const PPPConfigurePacket *reject) = 0;
|
||||
virtual status_t ParseReject(const PPPConfigurePacket& reject) = 0;
|
||||
// create next request based on these and previous values
|
||||
virtual void ParseAck(const PPPConfigurePacket *ack) = 0;
|
||||
virtual status_t ParseAck(const PPPConfigurePacket& ack) = 0;
|
||||
// this is called for all handlers
|
||||
|
||||
// peer sent configure request
|
||||
virtual status_t ParseRequest(const PPPConfigurePacket *request,
|
||||
int32 item, PPPConfigurePacket *nak, PPPConfigurePacket *reject) = 0;
|
||||
// item may be behind the last item which means we can add
|
||||
// additional values
|
||||
virtual void SendingAck(const PPPConfigurePacket *ack) = 0;
|
||||
virtual status_t ParseRequest(const PPPConfigurePacket& request,
|
||||
int32 index, PPPConfigurePacket& nak, PPPConfigurePacket& reject) = 0;
|
||||
// index may be behind the last item which means additional values can be
|
||||
// appended
|
||||
virtual status_t SendingAck(const PPPConfigurePacket& ack) = 0;
|
||||
// notification that we ack these values
|
||||
|
||||
virtual void Reset() = 0;
|
||||
// e.g.: remove list of rejected values
|
||||
|
||||
protected:
|
||||
status_t fInitStatus;
|
||||
|
||||
private:
|
||||
char fName[PPP_HANDLER_NAME_LENGTH_LIMIT + 1];
|
||||
uint8 fType;
|
||||
@ -70,7 +73,6 @@ class PPPOptionHandler {
|
||||
driver_parameter *fSettings;
|
||||
|
||||
bool fEnabled;
|
||||
status_t fInitStatus;
|
||||
};
|
||||
|
||||
|
||||
|
@ -90,6 +90,9 @@ class PPPProtocol {
|
||||
void DownEvent();
|
||||
// report up/down events
|
||||
|
||||
protected:
|
||||
status_t fInitStatus;
|
||||
|
||||
private:
|
||||
char fName[PPP_HANDLER_NAME_LENGTH_LIMIT + 1];
|
||||
ppp_phase fPhase;
|
||||
@ -103,7 +106,6 @@ class PPPProtocol {
|
||||
bool fEnabled;
|
||||
bool fUpRequested;
|
||||
ppp_phase fConnectionStatus;
|
||||
status_t fInitStatus;
|
||||
};
|
||||
|
||||
|
||||
|
@ -58,13 +58,13 @@ class PPPStateMachine {
|
||||
bool SendDiscardRequest();
|
||||
|
||||
// public events
|
||||
void AuthenticationRequested();
|
||||
void AuthenticationAccepted(const char *name);
|
||||
void AuthenticationDenied(const char *name);
|
||||
const char *AuthenticationName() const
|
||||
{ return fAuthenticationName; }
|
||||
ppp_authentication_status AuthenticationStatus() const
|
||||
{ return fAuthenticationStatus; }
|
||||
void LocalAuthenticationRequested();
|
||||
void LocalAuthenticationAccepted(const char *name);
|
||||
void LocalAuthenticationDenied(const char *name);
|
||||
const char *LocalAuthenticationName() const
|
||||
{ return fLocalAuthenticationName; }
|
||||
ppp_authentication_status LocalAuthenticationStatus() const
|
||||
{ return fLocalAuthenticationStatus; }
|
||||
|
||||
void PeerAuthenticationRequested();
|
||||
void PeerAuthenticationAccepted(const char *name);
|
||||
@ -159,9 +159,9 @@ class PPPStateMachine {
|
||||
vint32 fID;
|
||||
uint32 fMagicNumber;
|
||||
|
||||
ppp_authentication_status fAuthenticationStatus,
|
||||
ppp_authentication_status fLocalAuthenticationStatus,
|
||||
fPeerAuthenticationStatus;
|
||||
char *fAuthenticationName, *fPeerAuthenticationName;
|
||||
char *fLocalAuthenticationName, *fPeerAuthenticationName;
|
||||
|
||||
BLocker fLock;
|
||||
|
||||
|
@ -59,6 +59,10 @@ enum ppp_control_ops {
|
||||
PPPC_SET_ENABLED,
|
||||
PPPC_GET_SIMPLE_HANDLER_INFO,
|
||||
// PPPOptionHandler and PPPLCPExtension
|
||||
PPPC_STACK_IOCTL,
|
||||
// Ioctls from the stack are passed to all handlers and the interface
|
||||
// using a ppp_control_info (only op and data are defined!).
|
||||
// You should return B_BAD_VALUE if you did not handle this ioctl.
|
||||
// -----------------------------------------------------
|
||||
|
||||
PPP_CONTROL_OPS_END = B_DEVICE_OP_CODES_END + 0xFFFF
|
||||
@ -89,13 +93,17 @@ typedef struct ppp_interface_info {
|
||||
ppp_mode mode;
|
||||
ppp_state state;
|
||||
ppp_phase phase;
|
||||
ppp_authentication_status authenticationStatus, peerAuthenticationStatus;
|
||||
ppp_authentication_status localAuthenticationStatus, peerAuthenticationStatus;
|
||||
ppp_pfc_state localPFCState, peerPFCState;
|
||||
uint8 pfcOptions;
|
||||
|
||||
uint32 protocolsCount, encapsulatorsCount, optionHandlersCount,
|
||||
LCPExtensionsCount, childrenCount;
|
||||
uint32 MRU, interfaceMTU;
|
||||
|
||||
bigtime_t idleSince, disconnectAfterIdleSince;
|
||||
uint32 dialRetry, dialRetriesLimit;
|
||||
uint32 dialRetryDelay, redialDelay;
|
||||
uint32 idleSince, disconnectAfterIdleSince;
|
||||
|
||||
bool doesDialOnDemand, doesAutoRedial, hasDevice, isMultilink, hasParent;
|
||||
} ppp_interface_info;
|
||||
|
@ -62,6 +62,25 @@ enum {
|
||||
// could not send a packet because device is not connected
|
||||
};
|
||||
|
||||
// PFC options
|
||||
enum {
|
||||
PPP_REQUEST_PFC = 0x01,
|
||||
// try to request PFC (does not fail if not successful)
|
||||
PPP_ALLOW_PFC = 0x02,
|
||||
// allow PFC if other side requests it
|
||||
PPP_FORCE_PFC_REQUEST = 0x04,
|
||||
// if PFC request fails the connection attempt will terminate
|
||||
PPP_FREEZE_PFC_OPTIONS = 0x80
|
||||
// the options cannot be changed if this flag is set (mainly used by PPPDevice)
|
||||
};
|
||||
|
||||
enum ppp_pfc_state {
|
||||
PPP_PFC_DISABLED,
|
||||
PPP_PFC_ACCEPTED,
|
||||
PPP_PFC_REJECTED
|
||||
// not used for peer state
|
||||
};
|
||||
|
||||
// protocol and encapsulator flags
|
||||
enum {
|
||||
PPP_NO_FLAGS = 0x00,
|
||||
@ -100,7 +119,8 @@ enum ppp_phase {
|
||||
|
||||
// this defines the order in which the packets get encapsulated
|
||||
enum ppp_encapsulation_level {
|
||||
PPP_MULTILINK_LEVEL = 0,
|
||||
PPP_DEVICE_LEVEL = 0,
|
||||
PPP_MULTILINK_LEVEL = 2,
|
||||
PPP_ENCRYPTION_LEVEL = 5,
|
||||
PPP_COMPRESSION_LEVEL = 10
|
||||
};
|
||||
|
@ -41,10 +41,11 @@ enum ppp_connection_report_codes {
|
||||
PPP_REPORT_DOWN_SUCCESSFUL = 2,
|
||||
PPP_REPORT_UP_ABORTED = 3,
|
||||
PPP_REPORT_DEVICE_UP_FAILED = 4,
|
||||
PPP_REPORT_AUTHENTICATION_SUCCESSFUL = 5,
|
||||
PPP_REPORT_LOCAL_AUTHENTICATION_SUCCESSFUL = 5,
|
||||
PPP_REPORT_PEER_AUTHENTICATION_SUCCESSFUL = 6,
|
||||
PPP_REPORT_AUTHENTICATION_FAILED = 7,
|
||||
PPP_REPORT_CONNECTION_LOST = 8
|
||||
PPP_REPORT_LOCAL_AUTHENTICATION_FAILED = 7,
|
||||
PPP_REPORT_PEER_AUTHENTICATION_FAILED = 8,
|
||||
PPP_REPORT_CONNECTION_LOST = 9
|
||||
};
|
||||
|
||||
|
||||
|
@ -23,5 +23,8 @@ R5KernelStaticLibrary kernelppp :
|
||||
Locker.cpp
|
||||
settings_tools.cpp
|
||||
cpp.cpp
|
||||
|
||||
# integrated modules
|
||||
_KPPPPFCHandler.cpp
|
||||
;
|
||||
|
||||
|
@ -15,7 +15,10 @@
|
||||
|
||||
PPPDevice::PPPDevice(const char *name, PPPInterface& interface,
|
||||
driver_parameter *settings)
|
||||
: fMTU(1500), fIsUp(false), fInterface(interface), fSettings(settings)
|
||||
: fMTU(1500),
|
||||
fIsUp(false),
|
||||
fInterface(interface),
|
||||
fSettings(settings)
|
||||
{
|
||||
if(name) {
|
||||
strncpy(fName, name, PPP_HANDLER_NAME_LENGTH_LIMIT);
|
||||
@ -36,9 +39,6 @@ PPPDevice::~PPPDevice()
|
||||
status_t
|
||||
PPPDevice::InitCheck() const
|
||||
{
|
||||
if(!Settings())
|
||||
return B_ERROR;
|
||||
|
||||
return fInitStatus;
|
||||
}
|
||||
|
||||
@ -63,7 +63,7 @@ PPPDevice::Control(uint32 op, void *data, size_t length)
|
||||
} break;
|
||||
|
||||
default:
|
||||
return PPP_UNHANDLED;
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
|
@ -16,10 +16,17 @@ PPPEncapsulator::PPPEncapsulator(const char *name, ppp_phase phase,
|
||||
int32 addressFamily, uint32 overhead,
|
||||
PPPInterface& interface, driver_parameter *settings,
|
||||
int32 flags = PPP_NO_FLAGS)
|
||||
: fOverhead(overhead), fPhase(phase), fLevel(level), fProtocol(protocol),
|
||||
fAddressFamily(addressFamily), fInterface(interface),
|
||||
fSettings(settings), fFlags(flags), fEnabled(true),
|
||||
fUpRequested(true), fConnectionStatus(PPP_DOWN_PHASE)
|
||||
: fOverhead(overhead),
|
||||
fPhase(phase),
|
||||
fLevel(level),
|
||||
fProtocol(protocol),
|
||||
fAddressFamily(addressFamily),
|
||||
fInterface(interface),
|
||||
fSettings(settings),
|
||||
fFlags(flags),
|
||||
fEnabled(true),
|
||||
fUpRequested(true),
|
||||
fConnectionStatus(PPP_DOWN_PHASE)
|
||||
{
|
||||
if(name) {
|
||||
strncpy(fName, name, PPP_HANDLER_NAME_LENGTH_LIMIT);
|
||||
@ -40,9 +47,6 @@ PPPEncapsulator::~PPPEncapsulator()
|
||||
status_t
|
||||
PPPEncapsulator::InitCheck() const
|
||||
{
|
||||
if(!Settings())
|
||||
return B_ERROR;
|
||||
|
||||
return fInitStatus;
|
||||
}
|
||||
|
||||
@ -91,7 +95,7 @@ PPPEncapsulator::Control(uint32 op, void *data, size_t length)
|
||||
break;
|
||||
|
||||
default:
|
||||
return PPP_UNHANDLED;
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include <PPPControl.h>
|
||||
#include <KPPPDevice.h>
|
||||
#include <KPPPEncapsulator.h>
|
||||
#include <KPPPLCPExtension.h>
|
||||
#include <KPPPOptionHandler.h>
|
||||
#include <KPPPModule.h>
|
||||
#include <KPPPManager.h>
|
||||
@ -30,6 +31,9 @@
|
||||
// tools only for us :)
|
||||
#include "settings_tools.h"
|
||||
|
||||
// internal modules
|
||||
#include "_KPPPPFCHandler.h"
|
||||
|
||||
|
||||
// TODO:
|
||||
// - implement timers with support for settings next time instead of receiving timer
|
||||
@ -52,13 +56,36 @@ status_t interface_deleter_thread(void *data);
|
||||
|
||||
PPPInterface::PPPInterface(uint32 ID, driver_settings *settings,
|
||||
PPPInterface *parent = NULL)
|
||||
: fID(ID), fSettings(dup_driver_settings(settings)),
|
||||
fStateMachine(*this), fLCP(*this), fReportManager(StateMachine().Locker()),
|
||||
fIfnet(NULL), fUpThread(-1), fRedialThread(-1), fDialRetry(0),
|
||||
fDialRetriesLimit(0), fIdleSince(0), fMRU(1500), fInterfaceMTU(1498),
|
||||
fHeaderLength(2), fAutoRedial(false), fDialOnDemand(false), fDevice(NULL),
|
||||
fFirstEncapsulator(NULL), fLock(StateMachine().Locker()), fDeleteCounter(0)
|
||||
: fID(ID),
|
||||
fSettings(dup_driver_settings(settings)),
|
||||
fStateMachine(*this),
|
||||
fLCP(*this),
|
||||
fReportManager(StateMachine().Locker()),
|
||||
fIfnet(NULL),
|
||||
fUpThread(-1),
|
||||
fRedialThread(-1),
|
||||
fDialRetry(0),
|
||||
fDialRetriesLimit(0),
|
||||
fIdleSince(0),
|
||||
fMRU(1500),
|
||||
fInterfaceMTU(1498),
|
||||
fHeaderLength(2),
|
||||
fAutoRedial(false),
|
||||
fDialOnDemand(false),
|
||||
fLocalPFCState(PPP_PFC_DISABLED),
|
||||
fPeerPFCState(PPP_PFC_DISABLED),
|
||||
fPFCOptions(0),
|
||||
fDevice(NULL),
|
||||
fFirstEncapsulator(NULL),
|
||||
fLock(StateMachine().Locker()),
|
||||
fDeleteCounter(0)
|
||||
{
|
||||
// add internal modules
|
||||
_PPPPFCHandler *pfcHandler =
|
||||
new _PPPPFCHandler(fLocalPFCState, fPeerPFCState, *this);
|
||||
if(pfcHandler->InitCheck() != B_OK)
|
||||
delete pfcHandler;
|
||||
|
||||
// set up dial delays
|
||||
fDialRetryDelay = 3000;
|
||||
// 3s delay between each new attempt to redial
|
||||
@ -253,9 +280,13 @@ PPPInterface::Control(uint32 op, void *data, size_t length)
|
||||
info->mode = Mode();
|
||||
info->state = State();
|
||||
info->phase = Phase();
|
||||
info->authenticationStatus = StateMachine().AuthenticationStatus();
|
||||
info->localAuthenticationStatus =
|
||||
StateMachine().LocalAuthenticationStatus();
|
||||
info->peerAuthenticationStatus =
|
||||
StateMachine().PeerAuthenticationStatus();
|
||||
info->localPFCState = LocalPFCState();
|
||||
info->peerPFCState = PeerPFCState();
|
||||
info->pfcOptions = PFCOptions();
|
||||
info->protocolsCount = CountProtocols();
|
||||
info->encapsulatorsCount = CountEncapsulators();
|
||||
info->optionHandlersCount = LCP().CountOptionHandlers();
|
||||
@ -263,6 +294,10 @@ PPPInterface::Control(uint32 op, void *data, size_t length)
|
||||
info->childrenCount = CountChildren();
|
||||
info->MRU = MRU();
|
||||
info->interfaceMTU = InterfaceMTU();
|
||||
info->dialRetry = fDialRetry;
|
||||
info->dialRetriesLimit = fDialRetriesLimit;
|
||||
info->dialRetryDelay = DialRetryDelay();
|
||||
info->redialDelay = RedialDelay();
|
||||
info->idleSince = IdleSince();
|
||||
info->disconnectAfterIdleSince = DisconnectAfterIdleSince();
|
||||
info->doesDialOnDemand = DoesDialOnDemand();
|
||||
@ -361,7 +396,16 @@ PPPInterface::Control(uint32 op, void *data, size_t length)
|
||||
} break;
|
||||
|
||||
case PPPC_CONTROL_LCP_EXTENSION: {
|
||||
return PPP_UNHANDLED;
|
||||
if(length < sizeof(ppp_control_info) || !data)
|
||||
return B_ERROR;
|
||||
|
||||
ppp_control_info *control = (ppp_control_info*) data;
|
||||
PPPLCPExtension *extension_handler = LCP().LCPExtensionAt(control->index);
|
||||
if(!extension_handler)
|
||||
return B_BAD_INDEX;
|
||||
|
||||
return extension_handler->Control(control->op, control->data,
|
||||
control->length);
|
||||
} break;
|
||||
|
||||
case PPPC_CONTROL_CHILD: {
|
||||
@ -376,8 +420,19 @@ PPPInterface::Control(uint32 op, void *data, size_t length)
|
||||
return child->Control(control->op, control->data, control->length);
|
||||
} break;
|
||||
|
||||
case PPPC_STACK_IOCTL: {
|
||||
if(length < sizeof(ppp_control_info) || !data)
|
||||
return B_ERROR;
|
||||
|
||||
ppp_control_info *control = (ppp_control_info*) data;
|
||||
if(StackControl(control->op, control->data) == B_BAD_VALUE)
|
||||
return ControlEachHandler(op, data, length);
|
||||
|
||||
return B_OK;
|
||||
} break;
|
||||
|
||||
default:
|
||||
return PPP_UNHANDLED;
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
@ -718,6 +773,17 @@ PPPInterface::SetDialOnDemand(bool dialondemand = true)
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PPPInterface::SetPFCOptions(uint8 pfcOptions)
|
||||
{
|
||||
if(PFCOptions() & PPP_FREEZE_PFC_OPTIONS)
|
||||
return false;
|
||||
|
||||
fPFCOptions = pfcOptions;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PPPInterface::Up()
|
||||
{
|
||||
@ -742,9 +808,13 @@ PPPInterface::Up()
|
||||
fLock.Unlock();
|
||||
|
||||
// fUpThread tells the state machine to go up
|
||||
if(me == fUpThread)
|
||||
if(me == fUpThread || me == fRedialThread)
|
||||
StateMachine().OpenEvent();
|
||||
|
||||
if(me == fRedialThread && me != fUpThread)
|
||||
return true;
|
||||
// the redial thread is doing a DialRetry in this case
|
||||
|
||||
while(true) {
|
||||
if(IsUp()) {
|
||||
// lock needs timeout because destructor could have locked the interface
|
||||
@ -763,6 +833,9 @@ PPPInterface::Up()
|
||||
return true;
|
||||
}
|
||||
|
||||
// A wrong code usually happens when the redial thread gets notified
|
||||
// of a Down() request. In that case a report will follow soon, so
|
||||
// this can be ignored.
|
||||
if(receive_data(&sender, &report, sizeof(report)) != PPP_REPORT_CODE)
|
||||
continue;
|
||||
|
||||
@ -798,6 +871,8 @@ PPPInterface::Up()
|
||||
if(me == fUpThread) {
|
||||
fDialRetry = 0;
|
||||
fUpThread = -1;
|
||||
send_data_with_timeout(fRedialThread, 0, NULL, 0, 200);
|
||||
// notify redial thread that we do not need it anymore
|
||||
}
|
||||
|
||||
PPP_REPLY(sender, B_OK);
|
||||
@ -805,7 +880,8 @@ PPPInterface::Up()
|
||||
return true;
|
||||
} else if(report.code == PPP_REPORT_DOWN_SUCCESSFUL
|
||||
|| report.code == PPP_REPORT_UP_ABORTED
|
||||
|| report.code == PPP_REPORT_AUTHENTICATION_FAILED) {
|
||||
|| report.code == PPP_REPORT_LOCAL_AUTHENTICATION_FAILED
|
||||
|| report.code == PPP_REPORT_PEER_AUTHENTICATION_FAILED) {
|
||||
if(me == fUpThread) {
|
||||
fDialRetry = 0;
|
||||
fUpThread = -1;
|
||||
@ -857,7 +933,7 @@ PPPInterface::Up()
|
||||
} else {
|
||||
++fDialRetry;
|
||||
PPP_REPLY(sender, B_OK);
|
||||
StateMachine().OpenEvent();
|
||||
Redial(DialRetryDelay());
|
||||
continue;
|
||||
}
|
||||
} else if(report.code == PPP_REPORT_CONNECTION_LOST) {
|
||||
@ -866,7 +942,7 @@ PPPInterface::Up()
|
||||
if(DoesAutoRedial() && fDialRetry < fDialRetriesLimit) {
|
||||
++fDialRetry;
|
||||
PPP_REPLY(sender, B_OK);
|
||||
StateMachine().OpenEvent();
|
||||
Redial(DialRetryDelay());
|
||||
continue;
|
||||
} else {
|
||||
fDialRetry = 0;
|
||||
@ -897,6 +973,9 @@ PPPInterface::Down()
|
||||
if(InitCheck() != B_OK)
|
||||
return false;
|
||||
|
||||
send_data_with_timeout(fRedialThread, 0, NULL, 0, 200);
|
||||
// the redial thread should be notified that the user wants to disconnect
|
||||
|
||||
// this locked section guarantees that there are no state changes before we
|
||||
// enable the connection reports
|
||||
LockerHelper locker(fLock);
|
||||
@ -1218,7 +1297,16 @@ PPPInterface::SendToDevice(struct mbuf *packet, uint16 protocol)
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
// encode in ppp frame
|
||||
// encode in ppp frame and consider using PFC
|
||||
if(UseLocalPFC() && protocol & 0xFF00 == 0) {
|
||||
M_PREPEND(packet, 1);
|
||||
|
||||
if(packet == NULL)
|
||||
return B_ERROR;
|
||||
|
||||
uint8 *header = mtod(packet, uint8*);
|
||||
*header = protocol & 0xFF;
|
||||
} else {
|
||||
M_PREPEND(packet, 2);
|
||||
|
||||
if(packet == NULL)
|
||||
@ -1228,6 +1316,7 @@ PPPInterface::SendToDevice(struct mbuf *packet, uint16 protocol)
|
||||
protocol = htons(protocol);
|
||||
uint16 *header = mtod(packet, uint16*);
|
||||
*header = protocol;
|
||||
}
|
||||
|
||||
fIdleSince = real_time_clock();
|
||||
|
||||
@ -1260,13 +1349,16 @@ PPPInterface::ReceiveFromDevice(struct mbuf *packet)
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
// decode ppp frame
|
||||
uint16 *protocol = mtod(packet, uint16*);
|
||||
*protocol = ntohs(*protocol);
|
||||
|
||||
// decode ppp frame and recognize PFC
|
||||
uint16 protocol = *mtod(packet, uint8*);
|
||||
if(protocol == 0)
|
||||
m_adj(packet, 1);
|
||||
else {
|
||||
protocol = ntohs(*mtod(packet, uint16*));
|
||||
m_adj(packet, 2);
|
||||
}
|
||||
|
||||
return Receive(packet, *protocol);
|
||||
return Receive(packet, protocol);
|
||||
}
|
||||
|
||||
|
||||
@ -1351,6 +1443,89 @@ PPPInterface::UnregisterInterface()
|
||||
}
|
||||
|
||||
|
||||
// stack routes ioctls to interface
|
||||
status_t
|
||||
PPPInterface::StackControl(uint32 op, void *data)
|
||||
{
|
||||
// TODO:
|
||||
// implement when writing ppp_manager module
|
||||
|
||||
switch(op) {
|
||||
default:
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
// This calls Control() with the given parameters for each handler.
|
||||
// Return values:
|
||||
// B_OK: all handlers returned B_OK
|
||||
// B_BAD_VALUE: no handler was found
|
||||
// any other value: the error value that was returned by the last handler that failed
|
||||
status_t
|
||||
PPPInterface::ControlEachHandler(uint32 op, void *data, size_t length)
|
||||
{
|
||||
int32 index;
|
||||
status_t result = B_BAD_VALUE, tmp;
|
||||
|
||||
// protocols
|
||||
PPPProtocol *protocol;
|
||||
for(index = 0; index < CountProtocols(); index++) {
|
||||
protocol = ProtocolAt(index);
|
||||
if(!protocol)
|
||||
break;
|
||||
|
||||
tmp = protocol->Control(op, data, length);
|
||||
if(tmp == B_OK && result == B_BAD_VALUE)
|
||||
result = B_OK;
|
||||
else if(tmp != B_BAD_VALUE)
|
||||
result = tmp;
|
||||
}
|
||||
|
||||
// encapsulators
|
||||
PPPEncapsulator *encapsulator = FirstEncapsulator();
|
||||
for(; encapsulator; encapsulator = encapsulator->Next()) {
|
||||
tmp = encapsulator->Control(op, data, length);
|
||||
if(tmp == B_OK && result == B_BAD_VALUE)
|
||||
result = B_OK;
|
||||
else if(tmp != B_BAD_VALUE)
|
||||
result = tmp;
|
||||
}
|
||||
|
||||
// option handlers
|
||||
PPPOptionHandler *optionHandler;
|
||||
for(index = 0; index < LCP().CountOptionHandlers(); index++) {
|
||||
optionHandler = LCP().OptionHandlerAt(index);
|
||||
if(!optionHandler)
|
||||
break;
|
||||
|
||||
tmp = optionHandler->Control(op, data, length);
|
||||
if(tmp == B_OK && result == B_BAD_VALUE)
|
||||
result = B_OK;
|
||||
else if(tmp != B_BAD_VALUE)
|
||||
result = tmp;
|
||||
}
|
||||
|
||||
// LCP extensions
|
||||
PPPLCPExtension *lcpExtension;
|
||||
for(index = 0; index < LCP().CountLCPExtensions(); index++) {
|
||||
lcpExtension = LCP().LCPExtensionAt(index);
|
||||
if(!lcpExtension)
|
||||
break;
|
||||
|
||||
tmp = lcpExtension->Control(op, data, length);
|
||||
if(tmp == B_OK && result == B_BAD_VALUE)
|
||||
result = B_OK;
|
||||
else if(tmp != B_BAD_VALUE)
|
||||
result = tmp;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPInterface::CalculateInterfaceMTU()
|
||||
{
|
||||
@ -1446,8 +1621,11 @@ redial_thread(void *data)
|
||||
receive_data(&sender, &info, sizeof(redial_info));
|
||||
|
||||
// we try to receive data instead of snooze, so we can quit on destruction
|
||||
if(receive_data_with_timeout(&sender, &code, NULL, 0, info.delay) == B_OK)
|
||||
if(receive_data_with_timeout(&sender, &code, NULL, 0, info.delay) == B_OK) {
|
||||
*info.thread = -1;
|
||||
info.interface->Report(PPP_CONNECTION_REPORT, PPP_REPORT_UP_ABORTED, NULL, 0);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
info.interface->Up();
|
||||
*info.thread = -1;
|
||||
|
@ -24,7 +24,8 @@
|
||||
PPPLCP::PPPLCP(PPPInterface& interface)
|
||||
: PPPProtocol("LCP", PPP_ESTABLISHMENT_PHASE, PPP_LCP_PROTOCOL,
|
||||
AF_UNSPEC, interface, NULL, PPP_ALWAYS_ALLOWED),
|
||||
fStateMachine(interface.StateMachine()), fTarget(NULL)
|
||||
fStateMachine(interface.StateMachine()),
|
||||
fTarget(NULL)
|
||||
{
|
||||
SetUpRequested(false);
|
||||
// the state machine does everything for us
|
||||
|
@ -12,7 +12,10 @@
|
||||
|
||||
PPPLCPExtension::PPPLCPExtension(const char *name, uint8 code, PPPInterface& interface,
|
||||
driver_parameter *settings)
|
||||
: fInterface(interface), fSettings(settings), fCode(code), fEnabled(true)
|
||||
: fInterface(interface),
|
||||
fSettings(settings),
|
||||
fCode(code),
|
||||
fEnabled(true)
|
||||
{
|
||||
if(name) {
|
||||
strncpy(fName, name, PPP_HANDLER_NAME_LENGTH_LIMIT);
|
||||
@ -33,9 +36,6 @@ PPPLCPExtension::~PPPLCPExtension()
|
||||
status_t
|
||||
PPPLCPExtension::InitCheck() const
|
||||
{
|
||||
if(!Settings())
|
||||
return B_ERROR;
|
||||
|
||||
return fInitStatus;
|
||||
}
|
||||
|
||||
@ -63,7 +63,7 @@ PPPLCPExtension::Control(uint32 op, void *data, size_t length)
|
||||
break;
|
||||
|
||||
default:
|
||||
return PPP_UNHANDLED;
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
|
@ -12,7 +12,10 @@
|
||||
|
||||
PPPOptionHandler::PPPOptionHandler(const char *name, uint8 type,
|
||||
PPPInterface& interface, driver_parameter *settings)
|
||||
: fType(type), fInterface(interface), fSettings(settings), fEnabled(true)
|
||||
: fType(type),
|
||||
fInterface(interface),
|
||||
fSettings(settings),
|
||||
fEnabled(true)
|
||||
{
|
||||
if(name) {
|
||||
strncpy(fName, name, PPP_HANDLER_NAME_LENGTH_LIMIT);
|
||||
@ -33,9 +36,6 @@ PPPOptionHandler::~PPPOptionHandler()
|
||||
status_t
|
||||
PPPOptionHandler::InitCheck() const
|
||||
{
|
||||
if(!Settings())
|
||||
return B_ERROR;
|
||||
|
||||
return fInitStatus;
|
||||
}
|
||||
|
||||
@ -63,7 +63,7 @@ PPPOptionHandler::Control(uint32 op, void *data, size_t length)
|
||||
break;
|
||||
|
||||
default:
|
||||
return PPP_UNHANDLED;
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
|
@ -16,10 +16,16 @@ PPPProtocol::PPPProtocol(const char *name, ppp_phase phase, uint16 protocol,
|
||||
int32 addressFamily, PPPInterface& interface,
|
||||
driver_parameter *settings, int32 flags = PPP_NO_FLAGS,
|
||||
ppp_authenticator_type authenticatorType = PPP_NO_AUTHENTICATOR)
|
||||
: fPhase(phase), fProtocol(protocol), fAddressFamily(addressFamily),
|
||||
fInterface(interface), fSettings(settings), fFlags(flags),
|
||||
fAuthenticatorType(authenticatorType), fEnabled(true),
|
||||
fUpRequested(true), fConnectionStatus(PPP_DOWN_PHASE)
|
||||
: fPhase(phase),
|
||||
fProtocol(protocol),
|
||||
fAddressFamily(addressFamily),
|
||||
fInterface(interface),
|
||||
fSettings(settings),
|
||||
fFlags(flags),
|
||||
fAuthenticatorType(authenticatorType),
|
||||
fEnabled(true),
|
||||
fUpRequested(true),
|
||||
fConnectionStatus(PPP_DOWN_PHASE)
|
||||
{
|
||||
if(name) {
|
||||
strncpy(fName, name, PPP_HANDLER_NAME_LENGTH_LIMIT);
|
||||
@ -44,9 +50,6 @@ PPPProtocol::~PPPProtocol()
|
||||
status_t
|
||||
PPPProtocol::InitCheck() const
|
||||
{
|
||||
if(!Settings())
|
||||
return B_ERROR;
|
||||
|
||||
return fInitStatus;
|
||||
}
|
||||
|
||||
@ -94,7 +97,7 @@ PPPProtocol::Control(uint32 op, void *data, size_t length)
|
||||
break;
|
||||
|
||||
default:
|
||||
return PPP_UNHANDLED;
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
|
@ -93,7 +93,7 @@ PPPReportManager::Report(ppp_report_type type, int32 code, void *data, int32 len
|
||||
LockerHelper locker(fLock);
|
||||
|
||||
status_t result;
|
||||
thread_id sender;
|
||||
thread_id sender, me = find_thread(NULL);
|
||||
bool acceptable = true;
|
||||
|
||||
ppp_report_packet report;
|
||||
@ -107,6 +107,10 @@ PPPReportManager::Report(ppp_report_type type, int32 code, void *data, int32 len
|
||||
for(int32 index = 0; index < fReportRequests.CountItems(); index++) {
|
||||
request = fReportRequests.ItemAt(index);
|
||||
|
||||
// do not send to yourself
|
||||
if(request->thread == me)
|
||||
continue;
|
||||
|
||||
result = send_data_with_timeout(request->thread, PPP_REPORT_CODE, &report,
|
||||
sizeof(report), PPP_REPORT_TIMEOUT);
|
||||
|
||||
|
@ -22,20 +22,30 @@
|
||||
|
||||
|
||||
PPPStateMachine::PPPStateMachine(PPPInterface& interface)
|
||||
: fInterface(interface), fLCP(interface.LCP()), fPhase(PPP_DOWN_PHASE),
|
||||
fState(PPP_INITIAL_STATE), fID(system_time() & 0xFF), fMagicNumber(0),
|
||||
fAuthenticationStatus(PPP_NOT_AUTHENTICATED),
|
||||
: fInterface(interface),
|
||||
fLCP(interface.LCP()),
|
||||
fPhase(PPP_DOWN_PHASE),
|
||||
fState(PPP_INITIAL_STATE),
|
||||
fID(system_time() & 0xFF),
|
||||
fMagicNumber(0),
|
||||
fLocalAuthenticationStatus(PPP_NOT_AUTHENTICATED),
|
||||
fPeerAuthenticationStatus(PPP_NOT_AUTHENTICATED),
|
||||
fAuthenticationName(NULL), fPeerAuthenticationName(NULL),
|
||||
fMaxRequest(10), fMaxTerminate(2), fMaxNak(5),
|
||||
fRequestID(0), fTerminateID(0), fEchoID(0), fNextTimeout(0)
|
||||
fLocalAuthenticationName(NULL),
|
||||
fPeerAuthenticationName(NULL),
|
||||
fMaxRequest(10),
|
||||
fMaxTerminate(2),
|
||||
fMaxNak(5),
|
||||
fRequestID(0),
|
||||
fTerminateID(0),
|
||||
fEchoID(0),
|
||||
fNextTimeout(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
PPPStateMachine::~PPPStateMachine()
|
||||
{
|
||||
free(fAuthenticationName);
|
||||
free(fLocalAuthenticationName);
|
||||
free(fPeerAuthenticationName);
|
||||
}
|
||||
|
||||
@ -169,38 +179,38 @@ PPPStateMachine::SendDiscardRequest()
|
||||
|
||||
// authentication events
|
||||
void
|
||||
PPPStateMachine::AuthenticationRequested()
|
||||
PPPStateMachine::LocalAuthenticationRequested()
|
||||
{
|
||||
LockerHelper locker(fLock);
|
||||
|
||||
fAuthenticationStatus = PPP_AUTHENTICATING;
|
||||
free(fAuthenticationName);
|
||||
fAuthenticationName = NULL;
|
||||
fLocalAuthenticationStatus = PPP_AUTHENTICATING;
|
||||
free(fLocalAuthenticationName);
|
||||
fLocalAuthenticationName = NULL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPStateMachine::AuthenticationAccepted(const char *name)
|
||||
PPPStateMachine::LocalAuthenticationAccepted(const char *name)
|
||||
{
|
||||
LockerHelper locker(fLock);
|
||||
|
||||
fAuthenticationStatus = PPP_AUTHENTICATION_SUCCESSFUL;
|
||||
free(fAuthenticationName);
|
||||
fAuthenticationName = strdup(name);
|
||||
fLocalAuthenticationStatus = PPP_AUTHENTICATION_SUCCESSFUL;
|
||||
free(fLocalAuthenticationName);
|
||||
fLocalAuthenticationName = strdup(name);
|
||||
|
||||
Interface().Report(PPP_CONNECTION_REPORT, PPP_REPORT_AUTHENTICATION_SUCCESSFUL,
|
||||
NULL, 0);
|
||||
Interface().Report(PPP_CONNECTION_REPORT,
|
||||
PPP_REPORT_LOCAL_AUTHENTICATION_SUCCESSFUL, NULL, 0);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPStateMachine::AuthenticationDenied(const char *name)
|
||||
PPPStateMachine::LocalAuthenticationDenied(const char *name)
|
||||
{
|
||||
LockerHelper locker(fLock);
|
||||
|
||||
fAuthenticationStatus = PPP_AUTHENTICATION_FAILED;
|
||||
free(fAuthenticationName);
|
||||
fAuthenticationName = strdup(name);
|
||||
fLocalAuthenticationStatus = PPP_AUTHENTICATION_FAILED;
|
||||
free(fLocalAuthenticationName);
|
||||
fLocalAuthenticationName = strdup(name);
|
||||
}
|
||||
|
||||
|
||||
@ -550,24 +560,26 @@ PPPStateMachine::DownEvent()
|
||||
IllegalEvent(PPP_DOWN_EVENT);
|
||||
}
|
||||
|
||||
NewPhase(PPP_DOWN_PHASE);
|
||||
|
||||
DownProtocols();
|
||||
DownEncapsulators();
|
||||
|
||||
fAuthenticationStatus = PPP_NOT_AUTHENTICATED;
|
||||
fLocalAuthenticationStatus = PPP_NOT_AUTHENTICATED;
|
||||
fPeerAuthenticationStatus = PPP_NOT_AUTHENTICATED;
|
||||
|
||||
NewPhase(PPP_DOWN_PHASE);
|
||||
|
||||
// maybe we need to redial
|
||||
if(State() == PPP_STARTING_STATE) {
|
||||
bool needsRedial = false;
|
||||
|
||||
if(fAuthenticationStatus == PPP_AUTHENTICATION_FAILED
|
||||
|| fAuthenticationStatus == PPP_AUTHENTICATING
|
||||
|| fPeerAuthenticationStatus == PPP_AUTHENTICATION_FAILED
|
||||
if(fLocalAuthenticationStatus == PPP_AUTHENTICATION_FAILED
|
||||
|| fLocalAuthenticationStatus == PPP_AUTHENTICATING)
|
||||
Interface().Report(PPP_CONNECTION_REPORT,
|
||||
PPP_REPORT_LOCAL_AUTHENTICATION_FAILED, NULL, 0);
|
||||
else if(fPeerAuthenticationStatus == PPP_AUTHENTICATION_FAILED
|
||||
|| fPeerAuthenticationStatus == PPP_AUTHENTICATING)
|
||||
Interface().Report(PPP_CONNECTION_REPORT, PPP_REPORT_AUTHENTICATION_FAILED,
|
||||
NULL, 0);
|
||||
Interface().Report(PPP_CONNECTION_REPORT,
|
||||
PPP_REPORT_PEER_AUTHENTICATION_FAILED, NULL, 0);
|
||||
else {
|
||||
// if we are going up and lost connection the redial attempt becomes
|
||||
// a dial retry which is managed by the main thread in Interface::Up()
|
||||
@ -671,15 +683,16 @@ PPPStateMachine::CloseEvent()
|
||||
|
||||
switch(State()) {
|
||||
case PPP_OPENED_STATE:
|
||||
ThisLayerDown();
|
||||
|
||||
case PPP_REQ_SENT_STATE:
|
||||
case PPP_ACK_RCVD_STATE:
|
||||
case PPP_ACK_SENT_STATE:
|
||||
NewState(PPP_CLOSING_STATE);
|
||||
NewPhase(PPP_TERMINATION_PHASE);
|
||||
// indicates to handlers that we are terminating
|
||||
InitializeRestartCount();
|
||||
locker.UnlockNow();
|
||||
if(State() == PPP_OPENED_STATE)
|
||||
ThisLayerDown();
|
||||
SendTerminateRequest();
|
||||
break;
|
||||
|
||||
@ -688,7 +701,7 @@ PPPStateMachine::CloseEvent()
|
||||
|
||||
// TLSNotify() will know that we were faster because we
|
||||
// are in PPP_INITIAL_STATE now
|
||||
if(Phase() == PPP_ESTABLISHMENT_PHASE && Interface().Parent()) {
|
||||
if(Phase() == PPP_ESTABLISHMENT_PHASE) {
|
||||
// the device is already up
|
||||
NewPhase(PPP_DOWN_PHASE);
|
||||
// this says the following DownEvent() was not caused by
|
||||
@ -903,7 +916,12 @@ PPPStateMachine::RCAEvent(struct mbuf *packet)
|
||||
PPPOptionHandler *handler;
|
||||
for(int32 index = 0; index < LCP().CountOptionHandlers(); index++) {
|
||||
handler = LCP().OptionHandlerAt(index);
|
||||
handler->ParseAck(&ack);
|
||||
if(handler->ParseAck(ack) != B_OK) {
|
||||
m_freem(packet);
|
||||
locker.UnlockNow();
|
||||
CloseEvent();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
switch(State()) {
|
||||
@ -974,10 +992,21 @@ PPPStateMachine::RCNEvent(struct mbuf *packet)
|
||||
for(int32 index = 0; index < LCP().CountOptionHandlers(); index++) {
|
||||
handler = LCP().OptionHandlerAt(index);
|
||||
|
||||
if(nak_reject.Code() == PPP_CONFIGURE_NAK)
|
||||
handler->ParseNak(&nak_reject);
|
||||
else if(nak_reject.Code() == PPP_CONFIGURE_REJECT)
|
||||
handler->ParseReject(&nak_reject);
|
||||
if(nak_reject.Code() == PPP_CONFIGURE_NAK) {
|
||||
if(handler->ParseNak(nak_reject) != B_OK) {
|
||||
m_freem(packet);
|
||||
locker.UnlockNow();
|
||||
CloseEvent();
|
||||
return;
|
||||
}
|
||||
} else if(nak_reject.Code() == PPP_CONFIGURE_REJECT) {
|
||||
if(handler->ParseReject(nak_reject) != B_OK) {
|
||||
m_freem(packet);
|
||||
locker.UnlockNow();
|
||||
CloseEvent();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch(State()) {
|
||||
@ -1030,7 +1059,7 @@ PPPStateMachine::RTREvent(struct mbuf *packet)
|
||||
if(fID == mtod(packet, ppp_lcp_packet*)->id)
|
||||
fID -= 128;
|
||||
|
||||
fAuthenticationStatus = PPP_NOT_AUTHENTICATED;
|
||||
fLocalAuthenticationStatus = PPP_NOT_AUTHENTICATED;
|
||||
fPeerAuthenticationStatus = PPP_NOT_AUTHENTICATED;
|
||||
|
||||
switch(State()) {
|
||||
@ -1107,6 +1136,8 @@ PPPStateMachine::RTAEvent(struct mbuf *packet)
|
||||
|
||||
case PPP_OPENED_STATE:
|
||||
NewState(PPP_REQ_SENT_STATE);
|
||||
NewPhase(PPP_ESTABLISHMENT_PHASE);
|
||||
// indicates to handlers that we are reconfiguring
|
||||
locker.UnlockNow();
|
||||
ThisLayerDown();
|
||||
SendConfigureRequest();
|
||||
@ -1185,12 +1216,14 @@ PPPStateMachine::RXJBadEvent(struct mbuf *packet)
|
||||
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_STOPPING_STATE:
|
||||
NewPhase(PPP_TERMINATION_PHASE);
|
||||
|
||||
case PPP_STOPPED_STATE:
|
||||
locker.UnlockNow();
|
||||
ThisLayerFinished();
|
||||
@ -1198,6 +1231,8 @@ PPPStateMachine::RXJBadEvent(struct mbuf *packet)
|
||||
|
||||
case PPP_OPENED_STATE:
|
||||
NewState(PPP_STOPPING_STATE);
|
||||
NewPhase(PPP_TERMINATION_PHASE);
|
||||
// indicates to handlers that we are terminating
|
||||
InitializeRestartCount();
|
||||
locker.UnlockNow();
|
||||
ThisLayerDown();
|
||||
@ -1283,7 +1318,6 @@ PPPStateMachine::RCREvent(struct mbuf *packet)
|
||||
{
|
||||
PPPConfigurePacket request(packet), nak(PPP_CONFIGURE_NAK),
|
||||
reject(PPP_CONFIGURE_REJECT);
|
||||
PPPOptionHandler *handler;
|
||||
|
||||
// we should not use the same id as the peer
|
||||
if(fID == mtod(packet, ppp_lcp_packet*)->id)
|
||||
@ -1293,34 +1327,46 @@ PPPStateMachine::RCREvent(struct mbuf *packet)
|
||||
reject.SetID(request.ID());
|
||||
|
||||
// each handler should add unacceptable values for each item
|
||||
bool handled;
|
||||
int32 error;
|
||||
for(int32 item = 0; item <= request.CountItems(); item++) {
|
||||
// if we sent too many naks we should not append additional values
|
||||
if(fNakCounter == 0 && item == request.CountItems())
|
||||
break;
|
||||
status_t result;
|
||||
// the return value of ParseRequest()
|
||||
PPPOptionHandler *handler;
|
||||
for(int32 index = 0; index < request.CountItems(); index++) {
|
||||
handler = LCP().OptionHandlerFor(request.ItemAt(index)->type);
|
||||
|
||||
handled = false;
|
||||
|
||||
for(int32 index = 0; index < LCP().CountOptionHandlers();
|
||||
index++) {
|
||||
handler = LCP().OptionHandlerAt(index);
|
||||
error = handler->ParseRequest(&request, item, &nak, &reject);
|
||||
if(error == PPP_UNHANDLED)
|
||||
if(!handler || !handler->IsEnabled()) {
|
||||
// unhandled items should be added to reject
|
||||
reject.AddItem(request.ItemAt(index));
|
||||
continue;
|
||||
else if(error == B_ERROR) {
|
||||
}
|
||||
|
||||
result = handler->ParseRequest(request, index, nak, reject);
|
||||
|
||||
if(result != B_OK && result != PPP_UNHANDLED) {
|
||||
// the request contains a value that has been sent more than
|
||||
// once or the value is corrupted
|
||||
m_freem(packet);
|
||||
CloseEvent();
|
||||
return;
|
||||
} else if(error == B_OK)
|
||||
handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(!handled && item < request.CountItems()) {
|
||||
// unhandled items should be added to reject
|
||||
reject.AddItem(request.ItemAt(item));
|
||||
// Additional values may be appended.
|
||||
// If we sent too many naks we should not append additional values.
|
||||
if(fNakCounter > 0) {
|
||||
for(int32 index = 0; index < LCP().CountOptionHandlers(); index++) {
|
||||
handler = LCP().OptionHandlerAt(index);
|
||||
if(handler && handler->IsEnabled()) {
|
||||
result = handler->ParseRequest(request, request.CountItems(),
|
||||
nak, reject);
|
||||
|
||||
if(result != B_OK && result != PPP_UNHANDLED) {
|
||||
// the request contains a value that has been sent more than
|
||||
// once or the value is corrupted
|
||||
m_freem(packet);
|
||||
CloseEvent();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1498,7 +1544,7 @@ PPPStateMachine::SendConfigureRequest()
|
||||
|
||||
for(int32 index = 0; index < LCP().CountOptionHandlers(); index++) {
|
||||
// add all items
|
||||
if(!LCP().OptionHandlerAt(index)->AddToRequest(&request)) {
|
||||
if(LCP().OptionHandlerAt(index)->AddToRequest(request) != B_OK) {
|
||||
CloseEvent();
|
||||
return false;
|
||||
}
|
||||
@ -1518,8 +1564,13 @@ PPPStateMachine::SendConfigureAck(struct mbuf *packet)
|
||||
PPPConfigurePacket ack(packet);
|
||||
|
||||
// notify all option handlers that we are sending an ack for each value
|
||||
for(int32 index = 0; index < LCP().CountOptionHandlers(); index++)
|
||||
LCP().OptionHandlerAt(index)->SendingAck(&ack);
|
||||
for(int32 index = 0; index < LCP().CountOptionHandlers(); index++) {
|
||||
if(LCP().OptionHandlerAt(index)->SendingAck(ack) != B_OK) {
|
||||
m_freem(packet);
|
||||
CloseEvent();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return LCP().Send(packet) == B_OK;
|
||||
}
|
||||
|
120
src/tests/kits/net/ppp/src/_KPPPPFCHandler.cpp
Normal file
120
src/tests/kits/net/ppp/src/_KPPPPFCHandler.cpp
Normal file
@ -0,0 +1,120 @@
|
||||
//----------------------------------------------------------------------
|
||||
// This software is part of the OpenBeOS distribution and is covered
|
||||
// by the OpenBeOS license.
|
||||
//
|
||||
// Copyright (c) 2003 Waldemar Kornewald, Waldemar.Kornewald@web.de
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
#include "_KPPPPFCHandler.h"
|
||||
|
||||
#include <KPPPConfigurePacket.h>
|
||||
|
||||
#define PFC_TYPE 0x7
|
||||
|
||||
|
||||
_PPPPFCHandler::_PPPPFCHandler(ppp_pfc_state& localPFCState,
|
||||
ppp_pfc_state& peerPFCState, PPPInterface& interface)
|
||||
: PPPOptionHandler("PFC Handler", PFC_TYPE, interface, NULL),
|
||||
fLocalPFCState(localPFCState),
|
||||
fPeerPFCState(peerPFCState)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
_PPPPFCHandler::AddToRequest(PPPConfigurePacket& request)
|
||||
{
|
||||
// is PFC not requested or was it rejected?
|
||||
if(fLocalPFCState & PPP_PFC_REJECTED
|
||||
|| (Interface().PFCOptions() & PPP_REQUEST_PFC) == 0)
|
||||
return B_OK;
|
||||
|
||||
// add PFC request
|
||||
ppp_configure_item item;
|
||||
item.type = PFC_TYPE;
|
||||
item.length = 2;
|
||||
return request.AddItem(&item) ? B_OK : B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
_PPPPFCHandler::ParseNak(const PPPConfigurePacket& nak)
|
||||
{
|
||||
// naks do not contain PFC items
|
||||
if(nak.ItemWithType(PFC_TYPE))
|
||||
return B_ERROR;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
_PPPPFCHandler::ParseReject(const PPPConfigurePacket& reject)
|
||||
{
|
||||
if(reject.ItemWithType(PFC_TYPE)) {
|
||||
fLocalPFCState = PPP_PFC_REJECTED;
|
||||
|
||||
if(Interface().PFCOptions() & PPP_FORCE_PFC_REQUEST)
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
_PPPPFCHandler::ParseAck(const PPPConfigurePacket& ack)
|
||||
{
|
||||
if(ack.ItemWithType(PFC_TYPE))
|
||||
fLocalPFCState = PPP_PFC_ACCEPTED;
|
||||
else {
|
||||
fLocalPFCState = PPP_PFC_DISABLED;
|
||||
|
||||
if(Interface().PFCOptions() & PPP_FORCE_PFC_REQUEST)
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
_PPPPFCHandler::ParseRequest(const PPPConfigurePacket& request,
|
||||
int32 index, PPPConfigurePacket& nak, PPPConfigurePacket& reject)
|
||||
{
|
||||
if(!request.ItemWithType(PFC_TYPE))
|
||||
return B_OK;
|
||||
|
||||
if((Interface().PFCOptions() & PPP_ALLOW_PFC) == 0) {
|
||||
ppp_configure_item item;
|
||||
item.type = PFC_TYPE;
|
||||
item.length = 2;
|
||||
return reject.AddItem(&item) ? B_OK : B_ERROR;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
_PPPPFCHandler::SendingAck(const PPPConfigurePacket& ack)
|
||||
{
|
||||
ppp_configure_item *item = ack.ItemWithType(PFC_TYPE);
|
||||
|
||||
if(item && (Interface().PFCOptions() & PPP_ALLOW_PFC) == 0)
|
||||
return B_ERROR;
|
||||
|
||||
if(item)
|
||||
fPeerPFCState = PPP_PFC_ACCEPTED;
|
||||
else
|
||||
fPeerPFCState = PPP_PFC_DISABLED;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_PPPPFCHandler::Reset()
|
||||
{
|
||||
fLocalPFCState = fPeerPFCState = PPP_PFC_DISABLED;
|
||||
}
|
35
src/tests/kits/net/ppp/src/_KPPPPFCHandler.h
Normal file
35
src/tests/kits/net/ppp/src/_KPPPPFCHandler.h
Normal file
@ -0,0 +1,35 @@
|
||||
//----------------------------------------------------------------------
|
||||
// This software is part of the OpenBeOS distribution and is covered
|
||||
// by the OpenBeOS license.
|
||||
//
|
||||
// Copyright (c) 2003 Waldemar Kornewald, Waldemar.Kornewald@web.de
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
#ifndef __K_PPP_PFC_HANDLER__H
|
||||
#define __K_PPP_PFC_HANDLER__H
|
||||
|
||||
#include <KPPPOptionHandler.h>
|
||||
|
||||
|
||||
class _PPPPFCHandler : public PPPOptionHandler {
|
||||
public:
|
||||
_PPPPFCHandler(ppp_pfc_state& localPFCState, ppp_pfc_state& peerPFCState,
|
||||
PPPInterface& interface);
|
||||
|
||||
virtual status_t AddToRequest(PPPConfigurePacket& request);
|
||||
virtual status_t ParseNak(const PPPConfigurePacket& nak);
|
||||
virtual status_t ParseReject(const PPPConfigurePacket& reject);
|
||||
virtual status_t ParseAck(const PPPConfigurePacket& ack);
|
||||
|
||||
virtual status_t ParseRequest(const PPPConfigurePacket& request,
|
||||
int32 index, PPPConfigurePacket& nak, PPPConfigurePacket& reject);
|
||||
virtual status_t SendingAck(const PPPConfigurePacket& ack);
|
||||
|
||||
virtual void Reset();
|
||||
|
||||
private:
|
||||
ppp_pfc_state &fLocalPFCState, &fPeerPFCState;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user