Initial checkin of ppp stack.
Still far from being complete. Comments are welcome. In brief: Stack will be modular and written in C++. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@3875 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
cb6670b490
commit
0491e1650c
36
src/tests/kits/net/ppp/headers/AccessHelper.h
Normal file
36
src/tests/kits/net/ppp/headers/AccessHelper.h
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* AccessHelper.h
|
||||
*
|
||||
* The AccessHelper class automatically increases the given variable by
|
||||
* one on construction and decreases it by one on destruction. If a NULL
|
||||
* pointer is given, it will do nothing.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _ACCESS_HELPER__H
|
||||
#define _ACCESS_HELPER__H
|
||||
|
||||
#include <OS.h>
|
||||
#include <SupportDefs.h>
|
||||
|
||||
|
||||
class AccessHelper {
|
||||
public:
|
||||
AccessHelper(vint32 *access) : fAccess(access)
|
||||
{
|
||||
if(fAccess)
|
||||
atomic_add(fAccess, 1);
|
||||
}
|
||||
|
||||
~AccessHelper()
|
||||
{
|
||||
if(fAccess)
|
||||
atomic_add(fAccess, -1);
|
||||
}
|
||||
|
||||
private:
|
||||
vint32 *fAccess;
|
||||
};
|
||||
|
||||
#endif
|
36
src/tests/kits/net/ppp/headers/KPPPConfigurePacket.h
Normal file
36
src/tests/kits/net/ppp/headers/KPPPConfigurePacket.h
Normal file
@ -0,0 +1,36 @@
|
||||
#ifndef _K_PPP_CONFIGURE_PACKET__H
|
||||
#define _K_PPP_CONFIGURE_PACKET__H
|
||||
|
||||
#include <mbuf.h>
|
||||
|
||||
|
||||
typedef struct configure_item {
|
||||
void *data;
|
||||
int32 len;
|
||||
uint8 type;
|
||||
} configure_item;
|
||||
|
||||
|
||||
class PPPConfigurePacket {
|
||||
public:
|
||||
PPPConfigurePacket(uint8 type);
|
||||
PPPConfigurePacket(mbuf *data);
|
||||
~PPPConfigurePacket();
|
||||
|
||||
bool SetType(uint8 type);
|
||||
uint8 Type() const
|
||||
{ return fType; }
|
||||
|
||||
void AddItem(configure_item *item);
|
||||
bool RemoveItem(configure_item *item);
|
||||
int32 CountItems() const;
|
||||
configure_item *ItemAt(int32 index) const;
|
||||
|
||||
mbuf *ToMbuf() const;
|
||||
|
||||
private:
|
||||
uint8 fType;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
185
src/tests/kits/net/ppp/headers/KPPPDefs.h
Normal file
185
src/tests/kits/net/ppp/headers/KPPPDefs.h
Normal file
@ -0,0 +1,185 @@
|
||||
#ifndef _K_PPP_DEFS__H
|
||||
#define _K_PPP_DEFS__H
|
||||
|
||||
#include <Errors.h>
|
||||
|
||||
|
||||
// settings keys
|
||||
#define PPP_MODE_KEY "Mode"
|
||||
#define PPP_DIAL_ON_DEMAND_KEY "DialOnDemand"
|
||||
#define PPP_AUTO_REDIAL_KEY "AutoRedial"
|
||||
#define PPP_LOAD_MODULE_KEY "LoadModule"
|
||||
#define PPP_PROTOCOL_KEY "Protocol"
|
||||
#define PPP_DEVICE_KEY "Device"
|
||||
#define PPP_AUTHENTICATOR_KEY "Authenticator"
|
||||
#define PPP_PEER_AUTHENTICATOR_KEY "Peer-Authenticator"
|
||||
|
||||
// settings values
|
||||
#define PPP_CLIENT_MODE_VALUE "Client"
|
||||
#define PPP_SERVER_MODE_VALUE "Server"
|
||||
|
||||
// path defines
|
||||
#define PPP_MODULES_PATH "network/ppp-modules"
|
||||
|
||||
// built-in protocols
|
||||
// #define PPP_LCP_PROTOCOL 0xC021
|
||||
|
||||
|
||||
#define PPP_ERROR_BASE B_ERRORS_END
|
||||
|
||||
// return values for Receive methods in addition to B_ERROR and B_OK
|
||||
enum {
|
||||
// B_ERROR means that the packet is corrupted
|
||||
// B_OK means the packet was handled correctly
|
||||
|
||||
// return values for PPPProtocol and PPPEncapsulator
|
||||
PPP_UNHANDLED = PPP_ERROR_BASE,
|
||||
// The packet does not belong to this handler.
|
||||
// Do not delete the packet when you return this!
|
||||
|
||||
// return values of PPPInterface::Receive()
|
||||
PPP_DISCARDED,
|
||||
// packet was silently discarded
|
||||
PPP_REJECTED,
|
||||
// a protocol-reject
|
||||
};
|
||||
|
||||
// module key types (used when loading a module)
|
||||
enum {
|
||||
PPP_LOAD_MODULE_TYPE,
|
||||
PPP_DEVICE_TYPE,
|
||||
PPP_PROTOCOL_TYPE,
|
||||
PPP_AUTHENTICATOR_TYPE,
|
||||
PPP_PEER_AUTHENTICATOR_TYPE
|
||||
};
|
||||
|
||||
// protocol and encapsulator flags
|
||||
enum {
|
||||
PPP_NO_FLAGS = 0x00,
|
||||
PPP_ALWAYS_ALLOWED = 0x01,
|
||||
// protocol may send/receive while we are authenticating
|
||||
PPP_NEEDS_DOWN = 0x02
|
||||
// protocol needs a Down() in addition to a Reset() to
|
||||
// terminate the connection properly (losing the connection
|
||||
// still results in a Reset() only)
|
||||
};
|
||||
|
||||
// phase when the protocol is brought up
|
||||
enum PPP_PHASE {
|
||||
// the following may be used by protocols
|
||||
PPP_AUTHENTICATION_PHASE = 15,
|
||||
PPP_NCP_PHASE = 20,
|
||||
PPP_ESTABLISHED_PHASE = 25,
|
||||
// only use PPP_ESTABLISHED_PHASE if
|
||||
// you want to activate this protocol after
|
||||
// the normal protocols like IP (i.e., IPCP)
|
||||
|
||||
// the following must not be used by protocols!
|
||||
PPP_CTOR_DTOR_PHASE = -1,
|
||||
// set on construction/destruction of the interface
|
||||
PPP_DOWN_PHASE = 0,
|
||||
PPP_TERMINATION_PHASE = 1,
|
||||
// this is the selected phase when we are GOING down
|
||||
PPP_ESTABLISHMENT_PHASE = 2
|
||||
// in this phase some protocols (with PPP_ALWAYS_ALLOWED
|
||||
// flag set) may be used
|
||||
};
|
||||
|
||||
// this defines the order in which the packets get encapsulated
|
||||
enum PPP_ENCAPSULATION_LEVEL {
|
||||
PPP_MULTILINK_LEVEL = 0,
|
||||
PPP_ENCRYPTION_LEVEL = 5,
|
||||
PPP_COMPRESSION_LEVEL = 10
|
||||
};
|
||||
|
||||
// we can be a ppp client or a ppp server interface
|
||||
enum PPP_MODE {
|
||||
PPP_CLIENT_MODE = 0,
|
||||
PPP_SERVER_MODE
|
||||
};
|
||||
|
||||
// report types
|
||||
enum PPP_REPORT {
|
||||
PPP_CONNECTION_REPORT = 0x01,
|
||||
PPP_ERROR_REPORT = 0x02,
|
||||
};
|
||||
|
||||
// authentication status
|
||||
enum PPP_AUTHENTICATION_STATUS {
|
||||
PPP_AUTHENTICATION_FAILED = -1,
|
||||
PPP_NOT_AUTHENTICATED = 0,
|
||||
PPP_AUTHENTICATION_SUCCESSFUL = 1,
|
||||
PPP_AUTHENTICATING = 0xFF
|
||||
};
|
||||
|
||||
// PPP states as defined in RFC 1661
|
||||
enum PPP_STATE {
|
||||
PPP_INITIAL_STATE,
|
||||
PPP_STARTING_STATE,
|
||||
PPP_CLOSED_STATE,
|
||||
PPP_STOPPED_STATE,
|
||||
PPP_CLOSING_STATE,
|
||||
PPP_STOPPING_STATE,
|
||||
PPP_REQ_SENT_STATE,
|
||||
PPP_ACK_RCVD_STATE,
|
||||
PPP_ACK_SENT_STATE,
|
||||
PPP_OPENED_STATE
|
||||
};
|
||||
|
||||
// PPP actions as defined in RFC 1661
|
||||
enum PPP_ACTION {
|
||||
PPP_ILLEGAL_EVENT_ACTION,
|
||||
PPP_THIS_LAYER_UP_ACTION,
|
||||
PPP_THIS_LAYER_DOWN_ACTION,
|
||||
PPP_THIS_LAYER_STARTED_ACTION,
|
||||
PPP_THIS_LAYER_FINISHED_ACTION,
|
||||
PPP_INIT_RESTART_COUNT_ACTION,
|
||||
PPP_ZERO_RESTART_COUNT_ACTION,
|
||||
PPP_SEND_CONF_REQ_ACTION,
|
||||
PPP_SEND_CONF_ACK_ACTION,
|
||||
PPP_SEND_CONF_NAK_ACTION,
|
||||
PPP_SEND_TERM_REQ_ACTION,
|
||||
PPP_SEND_TERM_ACK_ACTION,
|
||||
PPP_SEND_CODE_REJ_ACTION,
|
||||
PPP_SEND_ECHO_REPLY_ACTION
|
||||
};
|
||||
|
||||
// PPP events as defined in RFC 1661 (with one exception: PPP_UP_FAILED_EVENT)
|
||||
enum PPP_EVENT {
|
||||
PPP_UP_FAILED_EVENT,
|
||||
PPP_UP_EVENT,
|
||||
PPP_DOWN_EVENT,
|
||||
PPP_OPEN_EVENT,
|
||||
PPP_CLOSE_EVENT,
|
||||
PPP_TO_GOOD_EVENT,
|
||||
PPP_TO_BAD_EVENT,
|
||||
PPP_RCR_GOOD_EVENT,
|
||||
PPP_RCR_BAD_EVENT,
|
||||
PPP_RCA_EVENT,
|
||||
PPP_RCN_EVENT,
|
||||
PPP_RTR_EVENT,
|
||||
PPP_RTA_EVENT,
|
||||
PPP_RUC_EVENT,
|
||||
PPP_RXJ_GOOD_EVENT,
|
||||
PPP_RXJ_BAD_EVENT,
|
||||
PPP_RXR_EVENT
|
||||
};
|
||||
|
||||
// LCP protocol types as defined in RFC 1661
|
||||
// ToDo: add LCP extensions
|
||||
enum PPP_LCP_TYPE {
|
||||
PPP_CONFIGURE_REQUEST = 1,
|
||||
PPP_CONFIGURE_ACK = 2,
|
||||
PPP_CONFIGURE_NAK = 3,
|
||||
PPP_CONFIGURE_REJECT = 4,
|
||||
PPP_TERMINATE_REQUEST = 5,
|
||||
PPP_TERMINATE_ACK = 6,
|
||||
PPP_CODE_REJECT = 7,
|
||||
PPP_PROTOCOL_REJECT = 8,
|
||||
PPP_ECHO_REQUEST = 9,
|
||||
PPP_ECHO_REPLY = 10,
|
||||
PPP_DISCARD_REQUEST = 11
|
||||
};
|
||||
|
||||
|
||||
#endif
|
56
src/tests/kits/net/ppp/headers/KPPPDevice.h
Normal file
56
src/tests/kits/net/ppp/headers/KPPPDevice.h
Normal file
@ -0,0 +1,56 @@
|
||||
#ifndef _K_PPP_DEVICE__H
|
||||
#define _K_PPP_DEVICE__H
|
||||
|
||||
#include "KPPPInterface.h"
|
||||
|
||||
|
||||
class PPPDevice {
|
||||
public:
|
||||
PPPDevice(const char *fName, PPPInterface *interface, driver_parameter *settings);
|
||||
virtual ~PPPDevice();
|
||||
|
||||
virtual status_t InitCheck() const = 0;
|
||||
|
||||
const char *Name() const
|
||||
{ return fName; }
|
||||
|
||||
PPPInterface *Interface() const
|
||||
{ return fInterface; }
|
||||
driver_parameter *Settings()
|
||||
{ return fSettings; }
|
||||
|
||||
virtual status_t Control(uint32 op, void *data, size_t length);
|
||||
|
||||
virtual bool SetMTU(uint32 mtu) = 0;
|
||||
uint32 MTU() const
|
||||
{ return fMTU; }
|
||||
virtual bool LockMTU();
|
||||
virtual bool UnlockMTU();
|
||||
virtual uint32 PreferredMTU() const = 0;
|
||||
|
||||
virtual void Up() = 0;
|
||||
virtual void Down() = 0;
|
||||
virtual void Listen() = 0;
|
||||
bool IsUp() const
|
||||
{ return fIsUp; }
|
||||
|
||||
virtual status_t Send(mbuf *packet) = 0;
|
||||
|
||||
protected:
|
||||
void SetUp(bool isUp);
|
||||
// report up/down events
|
||||
|
||||
protected:
|
||||
bool fIsUp;
|
||||
|
||||
private:
|
||||
char *fName;
|
||||
PPPInterface *fInterface;
|
||||
driver_parameter *fSettings;
|
||||
|
||||
uint32 fMTU;
|
||||
int32 fMTULock;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
86
src/tests/kits/net/ppp/headers/KPPPEncapsulator.h
Normal file
86
src/tests/kits/net/ppp/headers/KPPPEncapsulator.h
Normal file
@ -0,0 +1,86 @@
|
||||
#ifndef _K_PPP_ENCAPSULATOR__H
|
||||
#define _K_PPP_ENCAPSULATOR__H
|
||||
|
||||
#include "KPPPInterface.h"
|
||||
|
||||
|
||||
class PPPEncapsulator {
|
||||
public:
|
||||
PPPEncapsulator(const char *name, PPP_ENCAPSULATION_LEVEL level,
|
||||
uint16 protocol, int32 addressFamily, uint32 overhead,
|
||||
PPPInterface *interface, driver_parameter *settings,
|
||||
int32 flags = PPP_NO_FLAGS);
|
||||
virtual ~PPPEncapsulator();
|
||||
|
||||
virtual status_t InitCheck() const = 0;
|
||||
|
||||
void SetEnabled(bool enabled = true);
|
||||
bool IsEnabled() const
|
||||
{ return fEnabled; }
|
||||
|
||||
const char *Name() const
|
||||
{ return fName; }
|
||||
|
||||
PPP_ENCAPSULATION_LEVEL Level() const
|
||||
{ return fLevel; }
|
||||
uint32 Overhead() const
|
||||
{ return fOverhead; }
|
||||
|
||||
PPPInterface *Interface() const
|
||||
{ return fInterface; }
|
||||
driver_parameter *Settings()
|
||||
{ return fSettings; }
|
||||
|
||||
uint16 Protocol() const
|
||||
{ return fProtocol; }
|
||||
int32 AddressFamily() const
|
||||
{ return fAddressFamily; }
|
||||
// negative values and values > 0xFF are ignored
|
||||
int32 Flags() const
|
||||
{ return fFlags; }
|
||||
|
||||
virtual status_t Control(uint32 op, void *data, size_t length);
|
||||
|
||||
void SetNext(PPPEncapsulator *next)
|
||||
{ fNext = next; }
|
||||
PPPEncapsulator *Next() const
|
||||
{ return fNext; }
|
||||
|
||||
virtual bool Up() = 0;
|
||||
virtual bool Down() = 0;
|
||||
virtual bool Reset() = 0;
|
||||
// reset to initial (down) state without sending something
|
||||
bool IsUp() const
|
||||
{ return fIsUp; }
|
||||
|
||||
virtual status_t Send(mbuf *packet, uint16 protocol) = 0;
|
||||
virtual status_t Receive(mbuf *packet, uint16 protocol) = 0;
|
||||
|
||||
status_t SendToNext(mbuf *packet, uint16 protocol);
|
||||
// this will send your packet to the next (up) encapsulator
|
||||
// if there is no next encapsulator (==NULL), it will
|
||||
// call the interface's SendToDevice function
|
||||
|
||||
protected:
|
||||
void SetUp(bool isUp);
|
||||
// report up/down events
|
||||
|
||||
protected:
|
||||
uint32 fOverhead;
|
||||
|
||||
private:
|
||||
char *fName;
|
||||
PPP_ENCAPSULATION_LEVEL fLevel;
|
||||
PPPInterface *fInterface;
|
||||
driver_parameter *fSettings;
|
||||
uint16 fProtocol;
|
||||
int32 fAddressFamily, fFlags;
|
||||
|
||||
PPPEncapsulator *fNext;
|
||||
|
||||
bool fIsUp;
|
||||
bool fEnabled;
|
||||
}:
|
||||
|
||||
|
||||
#endif
|
108
src/tests/kits/net/ppp/headers/KPPPFSM.h
Normal file
108
src/tests/kits/net/ppp/headers/KPPPFSM.h
Normal file
@ -0,0 +1,108 @@
|
||||
#ifndef _K_PPP_FSM__H
|
||||
#define _K_PPP_FSM__H
|
||||
|
||||
#include "KPPPLCP.h"
|
||||
|
||||
#include "Locker.h"
|
||||
|
||||
|
||||
class PPPFSM {
|
||||
friend class PPPInterface;
|
||||
friend class PPPLCP;
|
||||
|
||||
private:
|
||||
// may only be constructed/destructed by PPPInterface
|
||||
PPPFSM(PPPInterface &interface);
|
||||
~PPPFSM();
|
||||
|
||||
public:
|
||||
PPPInterface *Interface() const
|
||||
{ return fInterface; }
|
||||
|
||||
PPP_STATE State() const
|
||||
{ return fState; }
|
||||
PPP_PHASE Phase() const
|
||||
{ return fPhase; }
|
||||
|
||||
// public events
|
||||
void AuthenticationRequested();
|
||||
void AuthenticationAccepted(const char *name);
|
||||
void AuthenticationDenied(const char *name);
|
||||
const char *AuthenticationName() const;
|
||||
// returns NULL if not authenticated
|
||||
PPP_AUTHENTICATION_STATUS AuthenticationStatus() const
|
||||
{ return fAuthenticationStatus; }
|
||||
|
||||
void PeerAuthenticationRequested();
|
||||
void PeerAuthenticationAccepted(const char *name);
|
||||
void PeerAuthenticationDenied(const char *name);
|
||||
const char *PeerAuthenticationName() const;
|
||||
// returns NULL if not authenticated
|
||||
PPP_AUTHENTICATION_STATUS PeerAuthenticationStatus() const
|
||||
{ return fPeerAuthenticationStatus; }
|
||||
|
||||
bool TLSNotify();
|
||||
bool TLFNotify();
|
||||
void UpFailedEvent();
|
||||
void UpEvent();
|
||||
void DownEvent();
|
||||
|
||||
private:
|
||||
BLocker &Locker()
|
||||
{ return fLock; }
|
||||
void LeaveConstructionPhase();
|
||||
void EnterDestructionPhase();
|
||||
|
||||
// private FSM methods
|
||||
void NewState(PPP_STATE next);
|
||||
|
||||
// private events
|
||||
void OpenEvent();
|
||||
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();
|
||||
|
||||
// actions
|
||||
void IllegalEvent(PPP_EVENT event);
|
||||
void ThisLayerUp();
|
||||
void ThisLayerDown();
|
||||
void ThisLayerStarted();
|
||||
void ThisLayerFinished();
|
||||
void InitializeRestartCount();
|
||||
void ZeroRestartCount();
|
||||
void SendConfigureRequest();
|
||||
void SendConfigureAck(PPPConfigurePacket *packet);
|
||||
|
||||
void SendConfigureNak(PPPConfigurePacket *packet);
|
||||
// is this needed?
|
||||
|
||||
void SendTerminateRequest();
|
||||
void SendTerminateAck();
|
||||
void SendCodeReject();
|
||||
void SendEchoReply();
|
||||
|
||||
private:
|
||||
PPPInterface *fInterface;
|
||||
|
||||
PPP_PHASE fPhase;
|
||||
PPP_STATE fState;
|
||||
|
||||
PPP_AUTHENTICATION_STATUS fAuthenticationStatus,
|
||||
fPeerAuthenticationStatus;
|
||||
int32 fAuthenticatorIndex, fPeerAuthenticatorIndex;
|
||||
|
||||
BLocker fLock;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
142
src/tests/kits/net/ppp/headers/KPPPInterface.h
Normal file
142
src/tests/kits/net/ppp/headers/KPPPInterface.h
Normal file
@ -0,0 +1,142 @@
|
||||
#ifndef _K_PPP_INTERFACE__H
|
||||
#define _K_PPP_INTERFACE__H
|
||||
|
||||
#include <driver_settings.h>
|
||||
|
||||
#include "KPPPDefs.h"
|
||||
|
||||
#include "KPPPFSM.h"
|
||||
#include "KPPPLCP.h"
|
||||
|
||||
#include "List.h"
|
||||
#include "LockerHelper.h"
|
||||
|
||||
class PPPAuthenticator;
|
||||
class PPPDevice;
|
||||
class PPPEncapsulator;
|
||||
class PPPOptionHandler;
|
||||
class PPPProtocol;
|
||||
|
||||
|
||||
class PPPInterface {
|
||||
public:
|
||||
PPPInterface(driver_settings *settings);
|
||||
~PPPInterface();
|
||||
|
||||
status_t InitCheck() const;
|
||||
|
||||
driver_settings* Settings()
|
||||
{ return fSettings; }
|
||||
|
||||
PPPFSM &FSM() const
|
||||
{ return fFSM; }
|
||||
|
||||
bool RegisterInterface();
|
||||
// adds us to the manager module and
|
||||
// saves the returned ifnet structure
|
||||
bool UnregisterInterface();
|
||||
ifnet *Ifnet() const
|
||||
{ return fIfnet; }
|
||||
|
||||
void SetLinkMTU(uint32 linkMTU);
|
||||
uint32 LinkMTU() const
|
||||
{ return fLinkMTU; }
|
||||
// this is the smallest MTU that we and the peer have
|
||||
uint32 MRU() const
|
||||
{ return fMRU; }
|
||||
|
||||
status_t Control(uint32 op, void *data, size_t length);
|
||||
|
||||
bool SetDevice(PPPDevice *device);
|
||||
|
||||
bool AddProtocol(PPPProtocol *protocol);
|
||||
bool RemoveProtocol(PPPProtocol *protocol);
|
||||
int32 CountProtocols() const
|
||||
{ return fProtocols.CountItems(); }
|
||||
PPPProtocol *ProtocolAt(int32 index) const;
|
||||
PPPProtocol *ProtocolFor(uint16 protocol, int32 start = 0) const;
|
||||
int32 IndexOfProtocol(const PPPProtocol *protocol) const
|
||||
{ return fProtocols.IndexOf(protocol); }
|
||||
|
||||
bool AddEncapsulator(PPPEncapsulator *encapsulator);
|
||||
bool RemoveEncapsulator(PPPEncapsulator *encapsulator);
|
||||
PPPEncapsulator *FirstEncapsulator() const
|
||||
{ return fFirstEncapsulator; }
|
||||
PPPEncapsulator *EncapsulatorFor(uint16 protocol,
|
||||
PPPEncapsulator start = NULL) const;
|
||||
|
||||
bool AddOptionHandler(PPPOptionHandler *handler);
|
||||
bool RemoveOptionHandler(PPPOptionHandler *handler);
|
||||
int32 CountOptionHandlers() const
|
||||
{ return fOptionHandlers.CountItems(); }
|
||||
PPPOptionHandler *OptionHandlerAt(int32 index) const;
|
||||
|
||||
void SetAutoRedial(bool autoredial = true);
|
||||
bool DoesAutoRedial() const
|
||||
{ return fAutoRedial; }
|
||||
|
||||
void SetDialOnDemand(bool dialondemand = true);
|
||||
bool DoesDialOnDemand() const
|
||||
{ return fDialOnDemand; }
|
||||
|
||||
PPP_MODE Mode() const
|
||||
{ return fMode; }
|
||||
// client or server mode?
|
||||
PPP_STATE State() const
|
||||
{ return FSM().State(); }
|
||||
PPP_PHASE Phase() const
|
||||
{ return FSM().Phase(); }
|
||||
|
||||
bool Up();
|
||||
// in server mode Up() listens for an incoming connection
|
||||
bool Down();
|
||||
bool IsUp() const;
|
||||
|
||||
/* void EnableReports(PPP_REPORT type, thread_id thread,
|
||||
PPP_REPORT_FLAGS flags);
|
||||
void DisableReports(PPP_REPORT type, thread_id thread);
|
||||
bool DoesReport(PPP_REPORT type, thread_id thread); */
|
||||
|
||||
bool LoadModules(const driver_settings *settings,
|
||||
int32 start, int32 count);
|
||||
bool LoadModule(const char *name, const driver_parameter *parameter);
|
||||
|
||||
status_t Send(mbuf *packet, uint16 protocol);
|
||||
status_t Receive(mbuf *packet, uint16 protocol);
|
||||
|
||||
status_t SendToDevice(mbuf *packet, uint16 protocol);
|
||||
status_t ReceiveFromDevice(mbuf *packet);
|
||||
|
||||
private:
|
||||
PPPLCP &LCP() const
|
||||
{ return fLCP; }
|
||||
void CalculateMRU();
|
||||
|
||||
// void Report(PPP_REPORT type, int32 code, void *data, int32 length);
|
||||
|
||||
private:
|
||||
driver_parameter *fSettings;
|
||||
PPPFSM fFSM;
|
||||
PPPLCP fLCP;
|
||||
ifnet *fIfnet;
|
||||
|
||||
uint32 fLinkMTU, fMRU, fHeaderLength;
|
||||
|
||||
bool fAutoRedial, fDialOnDemand;
|
||||
|
||||
vint32 fAccesing;
|
||||
|
||||
PPP_MODE fMode;
|
||||
|
||||
PPPDevice *fDevice;
|
||||
PPPEncapsulator *fFirstEncapsulator;
|
||||
|
||||
List<PPPProtocol*> fProtocols;
|
||||
List<PPPOptionHandler*> fOptionHandlers;
|
||||
List<ppp_module_info*> fModules;
|
||||
|
||||
BLocker &fGeneralLock;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
23
src/tests/kits/net/ppp/headers/KPPPLCP.h
Normal file
23
src/tests/kits/net/ppp/headers/KPPPLCP.h
Normal file
@ -0,0 +1,23 @@
|
||||
#ifndef _K_PPP_LCP__H
|
||||
#define _K_PPP_LCP__H
|
||||
|
||||
#include "KPPPProtocol.h"
|
||||
|
||||
|
||||
class PPPLCP : public PPPProtocol {
|
||||
friend class PPPInterface;
|
||||
|
||||
private:
|
||||
// may only be constructed/destructed by PPPInterface
|
||||
PPPLCP(PPPInterface &interface);
|
||||
~PPPLCP();
|
||||
|
||||
public:
|
||||
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
30
src/tests/kits/net/ppp/headers/KPPPManager.h
Normal file
30
src/tests/kits/net/ppp/headers/KPPPManager.h
Normal file
@ -0,0 +1,30 @@
|
||||
#ifndef _K_PPP_MANAGER__H
|
||||
#define _K_PPP_MANAGER__H
|
||||
|
||||
#include <net_module.h>
|
||||
|
||||
|
||||
#define PPP_MANAGER_MODULE_NAME "network/interfaces/ppp"
|
||||
|
||||
|
||||
typedef struct ppp_manager_info {
|
||||
kernel_net_module_info knminfo;
|
||||
|
||||
// when you want to iterate through interfaces you should use locking
|
||||
void (*lock)();
|
||||
void (*unlock)();
|
||||
|
||||
ifnet* (*add_interface)(PPPInterface *interface);
|
||||
bool (*remove_interface)(PPPInterface *interface);
|
||||
|
||||
int32 (*count_interfaces)(int32 index);
|
||||
|
||||
PPPInterface *(*get_interface_at)(int32 index);
|
||||
void (*put_interface)(PPPInterface *interface);
|
||||
|
||||
void (*delete_interface)(PPPInterface *interface);
|
||||
// this deletes the interface when it is not needed anymore
|
||||
} ppp_manager;
|
||||
|
||||
|
||||
#endif
|
16
src/tests/kits/net/ppp/headers/KPPPModule.h
Normal file
16
src/tests/kits/net/ppp/headers/KPPPModule.h
Normal file
@ -0,0 +1,16 @@
|
||||
#ifndef _K_PPP_MODULE__H
|
||||
#define _K_PPP_MODULE__H
|
||||
|
||||
#include <module.h>
|
||||
|
||||
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);
|
||||
} ppp_module_info;
|
||||
|
||||
|
||||
#endif
|
55
src/tests/kits/net/ppp/headers/KPPPOptionHandler.h
Normal file
55
src/tests/kits/net/ppp/headers/KPPPOptionHandler.h
Normal file
@ -0,0 +1,55 @@
|
||||
#ifndef _K_PPP_OPTION_HANDLER__H
|
||||
#define _K_PPP_OPTION_HANDLER__H
|
||||
|
||||
#include "KPPPConfigurePacket.h"
|
||||
#include "KPPPInterface.h"
|
||||
|
||||
|
||||
class PPPOptionHandler {
|
||||
public:
|
||||
PPPOptionHandler(const char *name, PPPInterface *interface,
|
||||
driver_parameter *settings);
|
||||
virtual ~PPPOptionHandler();
|
||||
|
||||
virtual status_t InitCheck() = 0;
|
||||
|
||||
void SetEnabled(bool enabled = true);
|
||||
bool IsEnabled() const
|
||||
{ return fEnabled; }
|
||||
|
||||
const char *Name() const
|
||||
{ return fName; }
|
||||
|
||||
PPPInterface *Interface() const
|
||||
{ return fInterface; }
|
||||
driver_parameter *Settings()
|
||||
{ return fSettings; }
|
||||
|
||||
virtual void Reset() = 0;
|
||||
// e.g.: remove list of rejected values
|
||||
|
||||
// we want to send a configure request or we received a reply
|
||||
virtual bool AddToRequest(PPPConfigurePacket *request) = 0;
|
||||
virtual void ParseNak(const PPPConfigurePacket *nak) = 0;
|
||||
// create next request based on these and previous values
|
||||
virtual void ParseReject(const PPPConfigurePacket *reject) = 0;
|
||||
// create next request based on these and previous values
|
||||
virtual void ParseAck(const PPPConfigurePacket *ack) = 0;
|
||||
// this is called for all handlers
|
||||
|
||||
// peer sent configure request
|
||||
virtual bool ParseConfigureRequest(const PPPConfigurePacket *request,
|
||||
int32 item, PPPConfigurePacket *nak, PPPConfigurePacket *reject) = 0;
|
||||
// item may be behind the last item which means we can add
|
||||
// additional values
|
||||
|
||||
private:
|
||||
const char *fName;
|
||||
PPPInterface *fInterface;
|
||||
driver_parameters *fSettings;
|
||||
|
||||
bool fEnabled;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
66
src/tests/kits/net/ppp/headers/KPPPProtocol.h
Normal file
66
src/tests/kits/net/ppp/headers/KPPPProtocol.h
Normal file
@ -0,0 +1,66 @@
|
||||
#ifndef _K_PPP_PROTOCOL__H
|
||||
#define _K_PPP_PROTOCOL__H
|
||||
|
||||
#include "KPPPInterface.h"
|
||||
|
||||
|
||||
class PPPProtocol {
|
||||
public:
|
||||
PPPProtocol(const char *name, PPP_PHASE phase, uint16 protocol,
|
||||
int32 addressFamily, PPPInterface *interface,
|
||||
driver_parameter *settings, int32 flags = PPP_NO_FLAGS);
|
||||
virtual ~PPPProtocol();
|
||||
|
||||
virtual status_t InitCheck() const = 0;
|
||||
|
||||
void SetEnabled(bool enabled = true);
|
||||
bool IsEnabled() const
|
||||
{ return fEnabled; }
|
||||
|
||||
const char *Name() const
|
||||
{ return fName; }
|
||||
|
||||
PPP_PHASE Phase() const
|
||||
{ return fPhase; }
|
||||
|
||||
driver_parameter *Settings()
|
||||
{ return fSettings; }
|
||||
|
||||
uint16 Protocol() const
|
||||
{ return fProtocol; }
|
||||
int32 AddressFamily() const
|
||||
{ return fAddressFamily; }
|
||||
// negative values and values > 0xFF are ignored
|
||||
int32 Flags() const
|
||||
{ return fFlags; }
|
||||
|
||||
virtual status_t Control(uint32 op, void *data, size_t length);
|
||||
|
||||
virtual bool Up() = 0;
|
||||
virtual bool Down() = 0;
|
||||
virtual bool Reset() = 0;
|
||||
// reset to initial (down) state without sending something
|
||||
bool IsUp() const
|
||||
{ return fIsUp; }
|
||||
|
||||
virtual status_t Send(mbuf *packet) = 0;
|
||||
virtual status_t Receive(mbuf *packet) = 0;
|
||||
|
||||
protected:
|
||||
void SetUp(bool isUp);
|
||||
// report up/down events
|
||||
|
||||
private:
|
||||
char *name;
|
||||
PPP_PHASE fPhase;
|
||||
uint16 fProtocol;
|
||||
int32 fAddressFamily, fFlags;
|
||||
PPPInterface fInterface;
|
||||
driver_parameter fSettings;
|
||||
|
||||
bool fIsUp;
|
||||
bool fEnabled;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
385
src/tests/kits/net/ppp/headers/List.h
Normal file
385
src/tests/kits/net/ppp/headers/List.h
Normal file
@ -0,0 +1,385 @@
|
||||
// List.h
|
||||
//
|
||||
// Copyright (c) 2003, Ingo Weinhold (bonefish@cs.tu-berlin.de)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
// Except as contained in this notice, the name of a copyright holder shall
|
||||
// not be used in advertising or otherwise to promote the sale, use or other
|
||||
// dealings in this Software without prior written authorization of the
|
||||
// copyright holder.
|
||||
|
||||
#ifndef LIST_H
|
||||
#define LIST_H
|
||||
|
||||
#include <new.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
template<typename ITEM>
|
||||
class DefaultDefaultItemCreator {
|
||||
public:
|
||||
static inline ITEM GetItem() { return ITEM(0); }
|
||||
};
|
||||
|
||||
/*!
|
||||
\class List
|
||||
\brief A generic list implementation.
|
||||
*/
|
||||
template<typename ITEM,
|
||||
typename DEFAULT_ITEM_SUPPLIER = DefaultDefaultItemCreator<ITEM> >
|
||||
class List {
|
||||
public:
|
||||
typedef ITEM item_t;
|
||||
typedef List list_t;
|
||||
|
||||
private:
|
||||
static item_t sDefaultItem;
|
||||
static const size_t kDefaultChunkSize = 10;
|
||||
static const size_t kMaximalChunkSize = 1024 * 1024;
|
||||
|
||||
public:
|
||||
List(size_t chunkSize = kDefaultChunkSize);
|
||||
~List();
|
||||
|
||||
inline const item_t &GetDefaultItem() const;
|
||||
inline item_t &GetDefaultItem();
|
||||
|
||||
bool AddItem(const item_t &item, int32 index);
|
||||
bool AddItem(const item_t &item);
|
||||
// bool AddList(list_t *list, int32 index);
|
||||
// bool AddList(list_t *list);
|
||||
|
||||
bool RemoveItem(const item_t &item);
|
||||
bool RemoveItem(int32 index);
|
||||
|
||||
bool ReplaceItem(int32 index, const item_t &item);
|
||||
|
||||
bool MoveItem(int32 oldIndex, int32 newIndex);
|
||||
|
||||
void MakeEmpty();
|
||||
|
||||
int32 CountItems() const;
|
||||
bool IsEmpty() const;
|
||||
const item_t &ItemAt(int32 index) const;
|
||||
item_t &ItemAt(int32 index);
|
||||
const item_t *Items() const;
|
||||
int32 IndexOf(const item_t &item) const;
|
||||
bool HasItem(const item_t &item) const;
|
||||
|
||||
// debugging
|
||||
int32 GetCapacity() const { return fCapacity; }
|
||||
|
||||
private:
|
||||
inline static void _MoveItems(item_t* items, int32 offset, int32 count);
|
||||
bool _Resize(size_t count);
|
||||
|
||||
private:
|
||||
size_t fCapacity;
|
||||
size_t fChunkSize;
|
||||
int32 fItemCount;
|
||||
item_t *fItems;
|
||||
};
|
||||
|
||||
// sDefaultItem
|
||||
template<typename ITEM, typename DEFAULT_ITEM_SUPPLIER>
|
||||
List<ITEM, DEFAULT_ITEM_SUPPLIER>::item_t
|
||||
List<ITEM, DEFAULT_ITEM_SUPPLIER>::sDefaultItem(
|
||||
DEFAULT_ITEM_SUPPLIER::GetItem());
|
||||
|
||||
// constructor
|
||||
template<typename ITEM, typename DEFAULT_ITEM_SUPPLIER>
|
||||
List<ITEM, DEFAULT_ITEM_SUPPLIER>::List(size_t chunkSize)
|
||||
: fCapacity(0),
|
||||
fChunkSize(chunkSize),
|
||||
fItemCount(0),
|
||||
fItems(NULL)
|
||||
{
|
||||
if (fChunkSize == 0 || fChunkSize > kMaximalChunkSize)
|
||||
fChunkSize = kDefaultChunkSize;
|
||||
_Resize(0);
|
||||
}
|
||||
|
||||
// destructor
|
||||
template<typename ITEM, typename DEFAULT_ITEM_SUPPLIER>
|
||||
List<ITEM, DEFAULT_ITEM_SUPPLIER>::~List()
|
||||
{
|
||||
MakeEmpty();
|
||||
free(fItems);
|
||||
}
|
||||
|
||||
// GetDefaultItem
|
||||
template<typename ITEM, typename DEFAULT_ITEM_SUPPLIER>
|
||||
inline
|
||||
const List<ITEM, DEFAULT_ITEM_SUPPLIER>::item_t &
|
||||
List<ITEM, DEFAULT_ITEM_SUPPLIER>::GetDefaultItem() const
|
||||
{
|
||||
return sDefaultItem;
|
||||
}
|
||||
|
||||
// GetDefaultItem
|
||||
template<typename ITEM, typename DEFAULT_ITEM_SUPPLIER>
|
||||
inline
|
||||
List<ITEM, DEFAULT_ITEM_SUPPLIER>::item_t &
|
||||
List<ITEM, DEFAULT_ITEM_SUPPLIER>::GetDefaultItem()
|
||||
{
|
||||
return sDefaultItem;
|
||||
}
|
||||
|
||||
// _MoveItems
|
||||
template<typename ITEM, typename DEFAULT_ITEM_SUPPLIER>
|
||||
inline
|
||||
void
|
||||
List<ITEM, DEFAULT_ITEM_SUPPLIER>::_MoveItems(item_t* items, int32 offset, int32 count)
|
||||
{
|
||||
if (count > 0 && offset != 0)
|
||||
memmove(items + offset, items, count * sizeof(item_t));
|
||||
}
|
||||
|
||||
// AddItem
|
||||
template<typename ITEM, typename DEFAULT_ITEM_SUPPLIER>
|
||||
bool
|
||||
List<ITEM, DEFAULT_ITEM_SUPPLIER>::AddItem(const item_t &item, int32 index)
|
||||
{
|
||||
bool result = (index >= 0 && index <= fItemCount
|
||||
&& _Resize(fItemCount + 1));
|
||||
if (result) {
|
||||
_MoveItems(fItems + index, 1, fItemCount - index - 1);
|
||||
new(fItems + index) item_t(item);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// AddItem
|
||||
template<typename ITEM, typename DEFAULT_ITEM_SUPPLIER>
|
||||
bool
|
||||
List<ITEM, DEFAULT_ITEM_SUPPLIER>::AddItem(const item_t &item)
|
||||
{
|
||||
bool result = true;
|
||||
if ((int32)fCapacity > fItemCount) {
|
||||
new(fItems + fItemCount) item_t(item);
|
||||
fItemCount++;
|
||||
} else {
|
||||
if ((result = _Resize(fItemCount + 1)))
|
||||
new(fItems + (fItemCount - 1)) item_t(item);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// These don't use the copy constructor!
|
||||
/*
|
||||
// AddList
|
||||
template<typename ITEM, typename DEFAULT_ITEM_SUPPLIER>
|
||||
bool
|
||||
List<ITEM, DEFAULT_ITEM_SUPPLIER>::AddList(list_t *list, int32 index)
|
||||
{
|
||||
bool result = (list && index >= 0 && index <= fItemCount);
|
||||
if (result && list->fItemCount > 0) {
|
||||
int32 count = list->fItemCount;
|
||||
result = _Resize(fItemCount + count);
|
||||
if (result) {
|
||||
_MoveItems(fItems + index, count, fItemCount - index - count);
|
||||
memcpy(fItems + index, list->fItems,
|
||||
list->fItemCount * sizeof(item_t));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// AddList
|
||||
template<typename ITEM, typename DEFAULT_ITEM_SUPPLIER>
|
||||
bool
|
||||
List<ITEM, DEFAULT_ITEM_SUPPLIER>::AddList(list_t *list)
|
||||
{
|
||||
bool result = (list);
|
||||
if (result && list->fItemCount > 0) {
|
||||
int32 index = fItemCount;
|
||||
int32 count = list->fItemCount;
|
||||
result = _Resize(fItemCount + count);
|
||||
if (result) {
|
||||
memcpy(fItems + index, list->fItems,
|
||||
list->fItemCount * sizeof(item_t));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
*/
|
||||
|
||||
// RemoveItem
|
||||
template<typename ITEM, typename DEFAULT_ITEM_SUPPLIER>
|
||||
bool
|
||||
List<ITEM, DEFAULT_ITEM_SUPPLIER>::RemoveItem(const item_t &item)
|
||||
{
|
||||
int32 index = IndexOf(item);
|
||||
bool result = (index >= 0);
|
||||
if (result)
|
||||
RemoveItem(index);
|
||||
return result;
|
||||
}
|
||||
|
||||
// RemoveItem
|
||||
template<typename ITEM, typename DEFAULT_ITEM_SUPPLIER>
|
||||
bool
|
||||
List<ITEM, DEFAULT_ITEM_SUPPLIER>::RemoveItem(int32 index)
|
||||
{
|
||||
if (index >= 0 && index < fItemCount) {
|
||||
fItems[index].~item_t();
|
||||
_MoveItems(fItems + index + 1, -1, fItemCount - index - 1);
|
||||
_Resize(fItemCount - 1);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// ReplaceItem
|
||||
template<typename ITEM, typename DEFAULT_ITEM_SUPPLIER>
|
||||
bool
|
||||
List<ITEM, DEFAULT_ITEM_SUPPLIER>::ReplaceItem(int32 index, const item_t &item)
|
||||
{
|
||||
if (index >= 0 && index < fItemCount) {
|
||||
fItems[index] = item;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// MoveItem
|
||||
template<typename ITEM, typename DEFAULT_ITEM_SUPPLIER>
|
||||
bool
|
||||
List<ITEM, DEFAULT_ITEM_SUPPLIER>::MoveItem(int32 oldIndex, int32 newIndex)
|
||||
{
|
||||
if (oldIndex >= 0 && oldIndex < fItemCount
|
||||
&& newIndex >= 0 && newIndex <= fItemCount) {
|
||||
if (oldIndex < newIndex - 1) {
|
||||
item_t item = fItems[oldIndex];
|
||||
_MoveItems(fItems + oldIndex + 1, -1, newIndex - oldIndex - 1);
|
||||
fItems[newIndex] = item;
|
||||
} else if (oldIndex > newIndex) {
|
||||
item_t item = fItems[oldIndex];
|
||||
_MoveItems(fItems + newIndex, 1, oldIndex - newIndex);
|
||||
fItems[newIndex] = item;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// MakeEmpty
|
||||
template<typename ITEM, typename DEFAULT_ITEM_SUPPLIER>
|
||||
void
|
||||
List<ITEM, DEFAULT_ITEM_SUPPLIER>::MakeEmpty()
|
||||
{
|
||||
for (int32 i = 0; i < fItemCount; i++)
|
||||
fItems[i].~item_t();
|
||||
_Resize(0);
|
||||
}
|
||||
|
||||
// CountItems
|
||||
template<typename ITEM, typename DEFAULT_ITEM_SUPPLIER>
|
||||
int32
|
||||
List<ITEM, DEFAULT_ITEM_SUPPLIER>::CountItems() const
|
||||
{
|
||||
return fItemCount;
|
||||
}
|
||||
|
||||
// IsEmpty
|
||||
template<typename ITEM, typename DEFAULT_ITEM_SUPPLIER>
|
||||
bool
|
||||
List<ITEM, DEFAULT_ITEM_SUPPLIER>::IsEmpty() const
|
||||
{
|
||||
return (fItemCount == 0);
|
||||
}
|
||||
|
||||
// ItemAt
|
||||
template<typename ITEM, typename DEFAULT_ITEM_SUPPLIER>
|
||||
const List<ITEM, DEFAULT_ITEM_SUPPLIER>::item_t &
|
||||
List<ITEM, DEFAULT_ITEM_SUPPLIER>::ItemAt(int32 index) const
|
||||
{
|
||||
if (index >= 0 && index < fItemCount)
|
||||
return fItems[index];
|
||||
return sDefaultItem;
|
||||
}
|
||||
|
||||
// ItemAt
|
||||
template<typename ITEM, typename DEFAULT_ITEM_SUPPLIER>
|
||||
List<ITEM, DEFAULT_ITEM_SUPPLIER>::item_t &
|
||||
List<ITEM, DEFAULT_ITEM_SUPPLIER>::ItemAt(int32 index)
|
||||
{
|
||||
if (index >= 0 && index < fItemCount)
|
||||
return fItems[index];
|
||||
return sDefaultItem;
|
||||
}
|
||||
|
||||
// Items
|
||||
template<typename ITEM, typename DEFAULT_ITEM_SUPPLIER>
|
||||
const List<ITEM, DEFAULT_ITEM_SUPPLIER>::item_t *
|
||||
List<ITEM, DEFAULT_ITEM_SUPPLIER>::Items() const
|
||||
{
|
||||
return fItems;
|
||||
}
|
||||
|
||||
// IndexOf
|
||||
template<typename ITEM, typename DEFAULT_ITEM_SUPPLIER>
|
||||
int32
|
||||
List<ITEM, DEFAULT_ITEM_SUPPLIER>::IndexOf(const item_t &item) const
|
||||
{
|
||||
for (int32 i = 0; i < fItemCount; i++) {
|
||||
if (fItems[i] == item)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// HasItem
|
||||
template<typename ITEM, typename DEFAULT_ITEM_SUPPLIER>
|
||||
bool
|
||||
List<ITEM, DEFAULT_ITEM_SUPPLIER>::HasItem(const item_t &item) const
|
||||
{
|
||||
return (IndexOf(item) >= 0);
|
||||
}
|
||||
|
||||
// _Resize
|
||||
template<typename ITEM, typename DEFAULT_ITEM_SUPPLIER>
|
||||
bool
|
||||
List<ITEM, DEFAULT_ITEM_SUPPLIER>::_Resize(size_t count)
|
||||
{
|
||||
bool result = true;
|
||||
// calculate the new capacity
|
||||
int32 newSize = count;
|
||||
if (newSize <= 0)
|
||||
newSize = 1;
|
||||
newSize = ((newSize - 1) / fChunkSize + 1) * fChunkSize;
|
||||
// resize if necessary
|
||||
if ((size_t)newSize != fCapacity) {
|
||||
item_t* newItems
|
||||
= (item_t*)realloc(fItems, newSize * sizeof(item_t));
|
||||
if (newItems) {
|
||||
fItems = newItems;
|
||||
fCapacity = newSize;
|
||||
} else
|
||||
result = false;
|
||||
}
|
||||
if (result)
|
||||
fItemCount = count;
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif // LIST_H
|
63
src/tests/kits/net/ppp/headers/Locker.h
Normal file
63
src/tests/kits/net/ppp/headers/Locker.h
Normal file
@ -0,0 +1,63 @@
|
||||
//
|
||||
// $Id: Locker.h,v 1.1 2003/07/06 16:46:29 wkornew Exp $
|
||||
//
|
||||
// This is the BLocker interface for OpenBeOS. It has been created to
|
||||
// be source and binary compatible with the BeOS version of BLocker.
|
||||
//
|
||||
// bonefish: Removed virtual from destructor.
|
||||
|
||||
|
||||
#ifndef _OPENBEOS_LOCKER_H
|
||||
#define _OPENBEOS_LOCKER_H
|
||||
|
||||
|
||||
#include <OS.h>
|
||||
#include <SupportDefs.h>
|
||||
|
||||
|
||||
#ifdef USE_OPENBEOS_NAMESPACE
|
||||
namespace OpenBeOS {
|
||||
#endif
|
||||
|
||||
class BLocker {
|
||||
public:
|
||||
BLocker();
|
||||
BLocker(const char *name);
|
||||
BLocker(bool benaphore_style);
|
||||
BLocker(const char *name, bool benaphore_style);
|
||||
|
||||
// The following constructor is not documented in the BeBook
|
||||
// and is only listed here to ensure binary compatibility.
|
||||
// DO NOT USE THIS CONSTRUCTOR!
|
||||
BLocker(const char *name, bool benaphore_style, bool);
|
||||
|
||||
~BLocker();
|
||||
|
||||
bool Lock(void);
|
||||
status_t LockWithTimeout(bigtime_t timeout);
|
||||
void Unlock(void);
|
||||
|
||||
thread_id LockingThread(void) const;
|
||||
bool IsLocked(void) const;
|
||||
int32 CountLocks(void) const;
|
||||
int32 CountLockRequests(void) const;
|
||||
sem_id Sem(void) const;
|
||||
|
||||
private:
|
||||
void InitLocker(const char *name, bool benaphore_style);
|
||||
bool AcquireLock(bigtime_t timeout, status_t *error);
|
||||
|
||||
int32 fBenaphoreCount;
|
||||
sem_id fSemaphoreID;
|
||||
thread_id fLockOwner;
|
||||
int32 fRecursiveCount;
|
||||
|
||||
// Reserved space for future changes to BLocker
|
||||
int32 fReservedSpace[4];
|
||||
};
|
||||
|
||||
#ifdef USE_OPENBEOS_NAMESPACE
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _OPENBEOS_LOCKER_H
|
44
src/tests/kits/net/ppp/headers/LockerHelper.h
Normal file
44
src/tests/kits/net/ppp/headers/LockerHelper.h
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* LockerHelper.h
|
||||
*
|
||||
* The LockerHelper acquires a lock on construction and releases it
|
||||
* on destruction.
|
||||
* This is a very useful class because you do not have to worry about
|
||||
* releasing the lock at every possible point. It is done automatically.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _LOCKER_HELPER__H
|
||||
#define _LOCKER_HELPER__H
|
||||
|
||||
#include "Locker.h"
|
||||
|
||||
|
||||
class LockerHelper {
|
||||
public:
|
||||
LockerHelper(BLocker &lock) : fLock(&lock)
|
||||
{
|
||||
if(fLock->Lock() != B_OK)
|
||||
fLock = NULL;
|
||||
}
|
||||
|
||||
~LockerHelper()
|
||||
{
|
||||
if(fLock)
|
||||
fLock->Unlock();
|
||||
}
|
||||
|
||||
void UnlockNow()
|
||||
{
|
||||
if(fLock)
|
||||
fLock->Unlock();
|
||||
fLock = NULL;
|
||||
}
|
||||
|
||||
private:
|
||||
BLocker *fLock;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
594
src/tests/kits/net/ppp/src/KPPPFSM.cpp
Normal file
594
src/tests/kits/net/ppp/src/KPPPFSM.cpp
Normal file
@ -0,0 +1,594 @@
|
||||
#include "KPPPFSM.h"
|
||||
|
||||
|
||||
PPPFSM::PPPFSM(PPPInterface &interface)
|
||||
: fInterface(&interface), fPhase(PPP_CTOR_DTOR_PHASE),
|
||||
fState(PPP_INITIAL_STATE),
|
||||
fAuthenticationStatus(PPP_NOT_AUTHENTICATED),
|
||||
fPeerAuthenticationStatus(PPP_NOT_AUTHENTICATED),
|
||||
fAuthenticatorIndex(-1), fPeerAuthenticatorIndex(-1)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
PPPFSM::~PPPFSM()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
// remember: NewState() must always be called _after_ IllegalEvent()
|
||||
// because IllegalEvent() also looks at the current state.
|
||||
void
|
||||
PPPFSM::NewState(PPP_STATE next)
|
||||
{
|
||||
fState = next;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPFSM::LeaveConstructionPhase()
|
||||
{
|
||||
LockerHelper locker(fLock);
|
||||
fPhase = PPP_DOWN_PHASE;
|
||||
}
|
||||
|
||||
|
||||
PPPFSM::EnterDestructionPhase()
|
||||
{
|
||||
LockerHelper locker(fLock);
|
||||
fPhase = PPP_CTOR_DTOR_PHASE;
|
||||
}
|
||||
|
||||
|
||||
// authentication events
|
||||
void
|
||||
PPPFSM::AuthenticationRequested()
|
||||
{
|
||||
// IMPLEMENT ME!
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPFSM::AuthenticationAccepted(const char *name)
|
||||
{
|
||||
// IMPLEMENT ME!
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPFSM::AuthenticationDenied(const char *name)
|
||||
{
|
||||
// IMPLEMENT ME!
|
||||
}
|
||||
|
||||
|
||||
const char*
|
||||
PPPFSM::AuthenticationName() const
|
||||
{
|
||||
// IMPLEMENT ME!
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPFSM::PeerAuthenticationRequested()
|
||||
{
|
||||
// IMPLEMENT ME!
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPFSM::PeerAuthenticationAccepted(const char *name)
|
||||
{
|
||||
// IMPLEMENT ME!
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPFSM::PeerAuthenticationDenied(const char *name)
|
||||
{
|
||||
// IMPLEMENT ME!
|
||||
}
|
||||
|
||||
|
||||
const char*
|
||||
PPPFSM::PeerAuthenticationName() const
|
||||
{
|
||||
// IMPLEMENT ME!
|
||||
}
|
||||
|
||||
|
||||
// public events
|
||||
bool
|
||||
PPPFSM::TLSNotify()
|
||||
{
|
||||
LockerHelper locker(fLock);
|
||||
|
||||
if(State() == PPP_STARTING_STATE) {
|
||||
if(Phase() == PPP_DOWN_PHASE)
|
||||
fPhase = PPP_ESTABLISHMENT_PHASE;
|
||||
// this says that the device is going up
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PPPFSM::TLFNotify()
|
||||
{
|
||||
LockerHelper locker(fLock);
|
||||
|
||||
if(Phase() == PPP_ESTABLISHMENT_PHASE) {
|
||||
// we may not go down because an OpenEvent indicates that the
|
||||
// user wants to connect
|
||||
return false;
|
||||
}
|
||||
|
||||
// from now on no packets may be sent to the device
|
||||
fPhase = PPP_DOWN_PHASE;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPFSM::UpFailedEvent()
|
||||
{
|
||||
LockerHelper locker(fLock);
|
||||
|
||||
switch(State()) {
|
||||
case PPP_STARTING_STATE:
|
||||
// we must have called TLS() which sets establishment phase
|
||||
if(Phase() != PPP_ESTABLISHMENT_PHASE) {
|
||||
// there must be a BUG in the device add-on or someone is trying to
|
||||
// fool us (UpEvent() is public) as we did not request the device
|
||||
// to go up
|
||||
IllegalEvent(PPP_UP_FAILED_EVENT);
|
||||
NewState(PPP_INITIAL_STATE);
|
||||
break;
|
||||
}
|
||||
|
||||
// TODO:
|
||||
// report that up failed
|
||||
// Report(PPP_CONNECTION_REPORT, PPP_UP_FAILED, NULL, 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
IllegalEvent(PPP_UP_FAILED_EVENT);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPFSM::UpEvent()
|
||||
{
|
||||
// This call is public, thus, it might not only be called by the device.
|
||||
// We must recognize these attempts to fool us and handle them correctly.
|
||||
|
||||
LockerHelper locker(fLock);
|
||||
|
||||
if(!Device()->IsUp())
|
||||
return;
|
||||
// it is not our device that went up...
|
||||
|
||||
switch(State()) {
|
||||
case PPP_INITIAL_STATE:
|
||||
if(Mode() != PPP_SERVER_MODE
|
||||
|| Phase() != PPP_ESTABLISHMENT_PHASE) {
|
||||
// we are a client or we do not listen for an incoming
|
||||
// connection, so this is an illegal event
|
||||
IllegalEvent(PPP_UP_EVENT);
|
||||
NewState(PPP_CLOSED_STATE);
|
||||
locker.UnlockNow();
|
||||
ThisLayerFinished();
|
||||
}
|
||||
|
||||
// TODO: handle server-up!
|
||||
break;
|
||||
|
||||
case PPP_STARTING_STATE:
|
||||
// we must have called TLS() which sets establishment phase
|
||||
if(Phase() != PPP_ESTABLISHMENT_PHASE) {
|
||||
// there must be a BUG in the device add-on or someone is trying to
|
||||
// fool us (UpEvent() is public) as we did not request the device
|
||||
// to go up
|
||||
IllegalEvent(PPP_UP_EVENT);
|
||||
NewState(PPP_CLOSED_STATE);
|
||||
locker.UnlockNow();
|
||||
ThisLayerFinished();
|
||||
break;
|
||||
}
|
||||
|
||||
InitializeRestartCounter();
|
||||
NewState(PPP_REQ_SENT_STATE);
|
||||
locker.UnlockNow();
|
||||
SendConfigureRequest();
|
||||
break;
|
||||
|
||||
default:
|
||||
IllegalEvent(PPP_UP_EVENT);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPFSM::DownEvent()
|
||||
{
|
||||
LockerHelper locker(fLock);
|
||||
|
||||
// TODO:
|
||||
// ResetProtocols();
|
||||
// ResetEncapsulators();
|
||||
|
||||
switch(State()) {
|
||||
case PPP_CLOSED_STATE:
|
||||
case PPP_CLOSING_STATE:
|
||||
NewState(PPP_INITIAL_STATE);
|
||||
fPhase = PPP_DOWN_PHASE;
|
||||
break;
|
||||
|
||||
case PPP_STOPPED_STATE:
|
||||
// The RFC says we should reconnect, but our implementation
|
||||
// will only do this if auto-redial is enabled (only clients).
|
||||
NewStatus(PPP_STARTING_STATE);
|
||||
fPhase = PPP_DOWN_PHASE;
|
||||
|
||||
// TODO:
|
||||
// report that we lost the connection
|
||||
// if fAuthStatus == FAILED || fPeerAuthStatus == FAILED
|
||||
// Report(PPP_CONNECTION_REPORT, PPP_AUTH_FAILED, NULL, 0);
|
||||
// else
|
||||
// Report(PPP_CONNECTION_REPORT, PPP_CONNECTION_LOST, NULL, 0);
|
||||
break;
|
||||
|
||||
case PPP_STOPPING_STATE:
|
||||
NewStatus(PPP_STARTING_STATE);
|
||||
fPhase = PPP_DOWN_PHASE;
|
||||
|
||||
// TODO:
|
||||
// report that we lost the connection
|
||||
// Report(PPP_CONNECTION_REPORT, PPP_CONNECTION_LOST, NULL, 0);
|
||||
break;
|
||||
|
||||
case PPP_REQ_SENT_STATE:
|
||||
case PPP_ACK_RCVD_STATE:
|
||||
case PPP_ACK_SENT_STATE:
|
||||
NewStatus(PPP_STARTING_STATE);
|
||||
fPhase = PPP_DOWN_PHASE;
|
||||
|
||||
// TODO:
|
||||
// report that we lost the connection
|
||||
// Report(PPP_CONNECTION_REPORT, PPP_CONNECTION_LOST, NULL, 0);
|
||||
break;
|
||||
|
||||
case PPP_OPENED_STATE:
|
||||
// tld/1
|
||||
NewStatus(PPP_STARTING_STATE);
|
||||
fPhase = PPP_DOWN_PHASE;
|
||||
|
||||
// TODO:
|
||||
// report that we lost the connection
|
||||
// Report(PPP_CONNECTION_REPORT, PPP_CONNECTION_LOST, NULL, 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
IllegalEvent(PPP_DOWN_EVENT);
|
||||
}
|
||||
|
||||
// maybe we need to redial
|
||||
if(State() == PPP_STARTING_STATE) {
|
||||
if(Interface()->DoesAutoRedial()) {
|
||||
// TODO:
|
||||
// redial using a new thread (maybe interface manager will help us)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// private events
|
||||
void
|
||||
PPPFSM::OpenEvent()
|
||||
{
|
||||
LockerHelper locker(fLock);
|
||||
|
||||
switch(State()) {
|
||||
case PPP_INITIAL_STATE:
|
||||
NewState(PPP_STARTING_STATE);
|
||||
locker.UnlockNow();
|
||||
ThisLayerStarted();
|
||||
break;
|
||||
|
||||
case PPP_CLOSED_STATE:
|
||||
if(Phase() == PPP_DOWN_PHASE) {
|
||||
// the device is already going down
|
||||
return;
|
||||
}
|
||||
|
||||
InitializeRestartCounter();
|
||||
NewState(PPP_REQ_SENT_STATE);
|
||||
fPhase = PPP_ESTABLISHMENT_PHASE;
|
||||
locker.UnlockNow();
|
||||
SendConfigureRequest();
|
||||
break;
|
||||
|
||||
case PPP_CLOSING_STATE:
|
||||
NewState(PPP_STOPPING_STATE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPFSM::CloseEvent()
|
||||
{
|
||||
LockerHelper locker(fLock);
|
||||
|
||||
switch(State()) {
|
||||
case PPP_OPENED_STATE:
|
||||
ThisLayerDown();
|
||||
|
||||
case PPP_REQ_SENT_STATE:
|
||||
case PPP_ACK_RCVD_STATE:
|
||||
case PPP_ACK_SENT_STATE:
|
||||
InitializeRestartCounter();
|
||||
NewState(PPP_CLOSING_STATE);
|
||||
fPhase = PPP_TERMINATION_PHASE;
|
||||
locker.UnlockNow();
|
||||
SendTerminateRequest();
|
||||
break;
|
||||
|
||||
case PPP_STARTING_STATE:
|
||||
NewState(PPP_INITIAL_STATE);
|
||||
|
||||
// if Device()->TLS() has not been called
|
||||
// TLSNotify() will know that we were faster because we
|
||||
// are in PPP_INITIAL_STATE now
|
||||
if(Phase() == PPP_ESTABLISHMENT_PHASE) {
|
||||
// the device is already up
|
||||
fPhase = PPP_DOWN_PHASE;
|
||||
// this says the following DownEvent() was not caused by
|
||||
// a connection fault
|
||||
locker.UnlockNow();
|
||||
ThisLayerFinished();
|
||||
}
|
||||
break;
|
||||
|
||||
case PPP_STOPPING_STATE:
|
||||
NewState(PPP_CLOSING_STATE);
|
||||
break;
|
||||
|
||||
case PPP_STOPPED_STATE:
|
||||
NewState(PPP_STOPPED_STATE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPFSM::TOGoodEvent()
|
||||
{
|
||||
LockerHelper locker(fLock);
|
||||
|
||||
switch(State()) {
|
||||
case PPP_CLOSING_STATE:
|
||||
case PPP_STOPPING_STATE:
|
||||
locker.UnlockNow();
|
||||
SendTerminateRequest();
|
||||
break;
|
||||
|
||||
case PPP_ACK_RCVD_STATE:
|
||||
NewState(PPP_REQ_SENT_STATE);
|
||||
|
||||
case PPP_REQ_SENT_STATE:
|
||||
case PPP_ACK_SENT_STATE:
|
||||
locker.UnlockNow();
|
||||
SendConfigureRequest();
|
||||
break;
|
||||
|
||||
default:
|
||||
IllegalEvent(PPP_TO_GOOD_EVENT);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPFSM::TOBadEvent()
|
||||
{
|
||||
LockerHelper locker(fLock);
|
||||
|
||||
switch(State()) {
|
||||
case PPP_CLOSING_STATE:
|
||||
NewState(PPP_CLOSED_STATE);
|
||||
fPhase = PPP_TERMINATION_PHASE;
|
||||
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);
|
||||
fPhase = PPP_TERMINATION_PHASE;
|
||||
locker.UnlockNow();
|
||||
ThisLayerFinished();
|
||||
break;
|
||||
|
||||
default:
|
||||
IllegalEvent(PPP_TO_BAD_EVENT);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPFSM::RCRGoodEvent(PPPConfigurePacket *packet)
|
||||
{
|
||||
LockerHelper locker(fLock);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPFSM::RCRBadEvent(PPPConfigurePacket *packet)
|
||||
{
|
||||
LockerHelper locker(fLock);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPFSM::RCAEvent(PPPConfigurePacket *packet)
|
||||
{
|
||||
LockerHelper locker(fLock);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPFSM::RCNEvent(PPPConfigurePacket *packet)
|
||||
{
|
||||
LockerHelper locker(fLock);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPFSM::RTREvent()
|
||||
{
|
||||
LockerHelper locker(fLock);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPFSM::RTAEvent()
|
||||
{
|
||||
LockerHelper locker(fLock);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPFSM::RUCEvent()
|
||||
{
|
||||
LockerHelper locker(fLock);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPFSM::RXJGoodEvent()
|
||||
{
|
||||
LockerHelper locker(fLock);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPFSM::RXJBadEvent()
|
||||
{
|
||||
LockerHelper locker(fLock);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPFSM::RXREvent()
|
||||
{
|
||||
LockerHelper locker(fLock);
|
||||
|
||||
}
|
||||
|
||||
|
||||
// actions (all private)
|
||||
void
|
||||
PPPFSM::IllegalEvent(PPP_EVENT event)
|
||||
{
|
||||
// update error statistics
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPFSM::ThisLayerUp()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPFSM::ThisLayerDown()
|
||||
{
|
||||
// DownProtocols();
|
||||
// DownEncapsulators();
|
||||
// ResetProtocols();
|
||||
// ResetEncapsulators();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPFSM::ThisLayerStarted()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPFSM::ThisLayerFinished()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPFSM::InitializeRestartCount()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPFSM::ZeroRestartCount()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPFSM::SendConfigureRequest()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPFSM::SendConfigureAck(PPPConfigurePacket *packet)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPFSM::SendConfigureNak(PPPConfigurePacket *packet)
|
||||
{
|
||||
// is this needed?
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPFSM::SendTerminateRequest()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPFSM::SendTerminateAck()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPFSM::SendCodeReject()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPFSM::SendEchoReply()
|
||||
{
|
||||
}
|
771
src/tests/kits/net/ppp/src/KPPPInterface.cpp
Normal file
771
src/tests/kits/net/ppp/src/KPPPInterface.cpp
Normal file
@ -0,0 +1,771 @@
|
||||
#include "KPPPInterface.h"
|
||||
|
||||
// our other classes
|
||||
#include "KPPPModule.h"
|
||||
#include "KPPPManager.h"
|
||||
|
||||
// general helper classes not only belonging to us
|
||||
#include "AccessHelper.h"
|
||||
#include "LockerHelper.h"
|
||||
|
||||
// tools only for us :)
|
||||
#include "KPPPUtils.h"
|
||||
#include "settings_tools.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
|
||||
// TODO:
|
||||
// - report module errors (when loading in ctor)
|
||||
// (in InitCheck(), too)
|
||||
// - add free-list for driver_settings that were loaded by Control()
|
||||
// - implement timers
|
||||
// - maybe some protocols must go down instead of being reset -> add flag for this
|
||||
|
||||
|
||||
PPPInterface::PPPInterface(driver_settings *settings)
|
||||
: fSettings(dup_driver_settings(settings)),
|
||||
FSM(*this), LCP(*this), fIfnet(NULL), fLinkMTU(0),
|
||||
fAccessing(0), fDevice(NULL), fFirstEncapsulator(NULL),
|
||||
fGeneralLock(FSM().Locker())
|
||||
{
|
||||
if(!fSettings)
|
||||
return;
|
||||
|
||||
const char *value;
|
||||
|
||||
value = get_settings_value(PPP_MODE_KEY, fsettings);
|
||||
if(!strcasecmp(value, PPP_SERVER_MODE_VALUE))
|
||||
fMode = PPP_SERVER_MODE;
|
||||
else
|
||||
fMode = PPP_CLIENT_MODE;
|
||||
// we are a client by default
|
||||
|
||||
SetDialOnDemand(
|
||||
get_boolean_value(
|
||||
get_settings_value(PPP_DIAL_ON_DEMAND_KEY, fSettings),
|
||||
false)
|
||||
);
|
||||
// dial on demand is disabled by default
|
||||
|
||||
|
||||
SetAutoRedial(
|
||||
get_boolean_value(
|
||||
get_settings_value(PPP_AUTO_REDIAL_KEY, fSettings),
|
||||
false)
|
||||
);
|
||||
// auto redial is disabled by default
|
||||
|
||||
// load all protocols and the device
|
||||
LoadModules(fSettings, 0, fSettings->parameter_count);
|
||||
|
||||
FSM().LeaveConstructionPhase();
|
||||
}
|
||||
|
||||
|
||||
PPPInterface::~PPPInterface()
|
||||
{
|
||||
// TODO:
|
||||
// remove our iface, so that nobody will access it:
|
||||
// go down if up
|
||||
// unregister from ppp_manager
|
||||
|
||||
FSM().EnterDestructionPhase();
|
||||
|
||||
// destroy and remove:
|
||||
// device
|
||||
// protocols
|
||||
// encapsulators
|
||||
// option handlers
|
||||
|
||||
// put all modules (in fModules)
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
PPPInterface::InitCheck() const
|
||||
{
|
||||
if(!fDevice
|
||||
|| !fSettings)
|
||||
return B_ERROR;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PPPInterface::RegisterInterface()
|
||||
{
|
||||
if(fIfnet)
|
||||
return true;
|
||||
// we are already registered
|
||||
|
||||
if(!InitCheck())
|
||||
return false;
|
||||
// we cannot register if something is wrong
|
||||
|
||||
ppp_manager_info *manager;
|
||||
if(get_module(PPP_MANAGER_MODULE_NAME, (module_info**) &manager) != B_OK)
|
||||
return false;
|
||||
|
||||
fIfnet = manager->add_interface(this);
|
||||
|
||||
put_module((module_info**) &manager);
|
||||
|
||||
|
||||
if(!fIfnet)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PPPInterface::UnregisterInterface()
|
||||
{
|
||||
if(!fIfnet)
|
||||
return true;
|
||||
// we are already unregistered
|
||||
|
||||
ppp_manager_info *manager;
|
||||
if(get_module(PPP_MANAGER_MODULE_NAME, (module_info**) &manager) != B_OK)
|
||||
return false;
|
||||
|
||||
manager->remove_interface(this);
|
||||
fIfnet = NULL;
|
||||
|
||||
put_module((module_info**) &manager);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPInterface::SetLinkMTU(uint32 linkMTU)
|
||||
{
|
||||
if(linkMTU < fLinkMTU && linkMTU > 234)
|
||||
fLinkMTU = linkMTU;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
PPPInterface::Control(uint32 op, void *data, size_t length)
|
||||
{
|
||||
switch(op) {
|
||||
// TODO:
|
||||
// add:
|
||||
// - routing Control() to encapsulators/protocols/option_handlers
|
||||
// (calling their Control() method)
|
||||
// - adding modules in right mode
|
||||
// - setting AutoRedial and DialOnDemand
|
||||
|
||||
|
||||
default:
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PPPInterface::SetDevice(PPPDevice *device)
|
||||
{
|
||||
if(!device)
|
||||
return false;
|
||||
|
||||
if(Phase() != PPP_CTOR_DTOR_PHASE)
|
||||
return false;
|
||||
// a running connection may not change
|
||||
|
||||
if(fDevice && (IsUp() || fDevice->IsUp()))
|
||||
Down();
|
||||
|
||||
fDevice = device;
|
||||
|
||||
fLinkMTU = fDevice->MTU();
|
||||
|
||||
CalculateMRU();
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PPPInterface::AddProtocol(PPPProtocol *protocol)
|
||||
{
|
||||
if(!protocol)
|
||||
return false;
|
||||
|
||||
if(Phase() != PPP_CTOR_DTOR_PHASE)
|
||||
return false;
|
||||
// a running connection may not change
|
||||
|
||||
fProtocols.AddItem(protocol);
|
||||
|
||||
if(IsUp() || Phase() >= protocol->Phase())
|
||||
protocol->Up();
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PPPInterface::RemoveProtocol(PPPProtocol *protocol)
|
||||
{
|
||||
if(Phase() != PPP_CTOR_DTOR_PHASE)
|
||||
return false;
|
||||
// a running connection may not change
|
||||
|
||||
if(!fProtocols.HasItem(protocol))
|
||||
return false;
|
||||
|
||||
if(IsUp() || Phase() >= protocol->Phase())
|
||||
protocol->Down();
|
||||
|
||||
return fProtocols.RemoveItem(protocol);
|
||||
}
|
||||
|
||||
|
||||
PPPProtocol*
|
||||
PPPInterface::ProtocolAt(int32 index) const
|
||||
{
|
||||
PPPProtocol *protocol = fProtocols.ItemAt(index);
|
||||
|
||||
if(protocol == fProtocols.GetDefaultItem())
|
||||
return NULL;
|
||||
|
||||
return protocol;
|
||||
}
|
||||
|
||||
|
||||
PPPProtocol*
|
||||
PPPInterface::ProtocolFor(uint16 protocol, int32 start = 0) const
|
||||
{
|
||||
if(start < 0)
|
||||
return NULL;
|
||||
|
||||
for(int32 i = start; i < fProtocols.CountItems(); i++)
|
||||
if(fProtocols.ItemAt(i)->Protocol() == protocol)
|
||||
return fProtocols.ItemAt(i);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PPPInterface::AddEncapsulator(PPPEncapsulator *encapsulator)
|
||||
{
|
||||
// Find instert position after the last encapsulator
|
||||
// with the same level.
|
||||
|
||||
if(!encapsulator)
|
||||
return false;
|
||||
|
||||
if(Phase() != PPP_CTOR_DTOR_PHASE)
|
||||
return false;
|
||||
// a running connection may not change
|
||||
|
||||
PPPEncapsulator *current = fFirstEncapsulator, *previous = NULL;
|
||||
|
||||
while(current) {
|
||||
if(current->Level() < encapsulator->Level())
|
||||
break;
|
||||
|
||||
previous = current;
|
||||
current = current->Next();
|
||||
}
|
||||
|
||||
if(!current) {
|
||||
if(!previous)
|
||||
fFirstEncapsulator = encapsulator;
|
||||
else
|
||||
previous->SetNext(encapsulator);
|
||||
|
||||
encapsulator->SetNext(NULL);
|
||||
} else {
|
||||
encapsulator->SetNext(current);
|
||||
|
||||
if(!previous)
|
||||
fFirstEncapsulator = encapsulator;
|
||||
else
|
||||
previous->SetNext(encapsulator);
|
||||
}
|
||||
|
||||
CalculateMRU();
|
||||
|
||||
if(IsUp())
|
||||
encapsulator->Up();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PPPInterface::RemoveEncapsulator(PPPEncapsulator *encapsulator)
|
||||
{
|
||||
if(Phase() != PPP_CTOR_DTOR_PHASE)
|
||||
return false;
|
||||
// a running connection may not change
|
||||
|
||||
PPPEncapsulator *current = fFirstEncapsulator, previous = NULL;
|
||||
|
||||
while(current) {
|
||||
if(current == encapsulator) {
|
||||
if(IsUp())
|
||||
encapsulator->Down();
|
||||
|
||||
if(previous)
|
||||
previous->SetNext(current->Next());
|
||||
else
|
||||
fFirstEncapsulator = current->Next();
|
||||
|
||||
current->SetNext(NULL);
|
||||
|
||||
CalculateMRU();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
previous = current;
|
||||
current = current->Next();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
PPPEncapsulator*
|
||||
PPPInterface::EncapsulatorFor(uint16 protocol,
|
||||
PPPEncapsulator start = NULL) const
|
||||
{
|
||||
PPPEncapsulator *current = start ? start : fFirstEncapsulator;
|
||||
|
||||
for(; current; current = current->Next())
|
||||
if(current->Protocol() == protocol)
|
||||
return current;
|
||||
|
||||
return current;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PPPInterface::AddOptionHandler(PPPOptionHandler *handler)
|
||||
{
|
||||
if(!handler)
|
||||
return false
|
||||
|
||||
if(Phase() != PPP_CTOR_DTOR_PHASE)
|
||||
return false;
|
||||
// a running connection may not change
|
||||
|
||||
fOptionHandlers.AddItem(handler);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PPPInterface::RemoveOptionHandler(PPPOptionHandler *handler)
|
||||
{
|
||||
if(Phase() != PPP_CTOR_DTOR_PHASE)
|
||||
return false;
|
||||
// a running connection may not change
|
||||
|
||||
return fOptionHandlers.RemoveItem(handler);
|
||||
}
|
||||
|
||||
|
||||
PPPOptionHandler*
|
||||
PPPInterface::OptionHandlerAt(int32 index) const
|
||||
{
|
||||
PPPOptionHandler *handler = fOptionHandlers.ItemAt(index);
|
||||
|
||||
if(handler == fOptionHandlers.DefaultItem())
|
||||
return NULL;
|
||||
|
||||
return handler;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPInterface::SetAutoRedial(bool autoredial = true)
|
||||
{
|
||||
if(Mode() == PPP_CLIENT_MODE)
|
||||
return false;
|
||||
|
||||
LockerHelper locker(fGeneralLock);
|
||||
|
||||
fAutoRedial = autoredial;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPInterface::SetDialOnDemand(bool dialondemand = true)
|
||||
{
|
||||
if(Mode() != PPP_CLIENT_MODE)
|
||||
return false;
|
||||
|
||||
LockerHelper locker(fGeneralLock);
|
||||
|
||||
fDialOnDemand = dialondemand;
|
||||
|
||||
// check if we need to register/unregister
|
||||
if(!Ifnet() && fDialOnDemand)
|
||||
RegisterInterface();
|
||||
else if(Ifnet() && !fDialOnDemand && Phase() == PPP_DOWN_PHASE)
|
||||
UnregisterInterface();
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PPPInterface::Up()
|
||||
{
|
||||
// ToDo:
|
||||
// instead of waiting for state change we should wait until
|
||||
// all retries are done
|
||||
|
||||
if(!InitCheck() || Phase() != PPP_CTOR_DTOR_PHASE)
|
||||
return false;
|
||||
|
||||
if(IsUp())
|
||||
return true;
|
||||
|
||||
// TODO:
|
||||
// Add one-time connection report request and wait
|
||||
// for results. If we lost the connection we should
|
||||
// consider redialing.
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PPPInterface::Down()
|
||||
{
|
||||
// ToDo:
|
||||
// instead of waiting for state change we should wait until
|
||||
// all retries are done
|
||||
|
||||
if(!InitCheck() || Phase() != PPP_CTOR_DTOR_PHASE)
|
||||
return false;
|
||||
|
||||
// TODO:
|
||||
// Add one-time connection report request.
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PPPInterface::IsUp() const
|
||||
{
|
||||
LockerHelper locker(fGeneralLock);
|
||||
if(Ifnet())
|
||||
return Ifnet()->if_flags & IFF_RUNNING;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
|
||||
void
|
||||
PPPInterface::EnableReports(PPP_REPORT type, thread_id thread,
|
||||
bool needsVerification = false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPInterface::DisableReports(PPP_REPORT type, thread_id thread)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PPPInterface::Reports(PPP_REPORT type, thread_id thread)
|
||||
{
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
|
||||
bool
|
||||
PPPInterface::LoadModules(const driver_settings *settings,
|
||||
int32 start, int32 count)
|
||||
{
|
||||
if(Phase() != PPP_CTOR_DTOR_PHASE)
|
||||
return false;
|
||||
// a running connection may not change
|
||||
|
||||
int32 type;
|
||||
// which type key was used for loading this module?
|
||||
|
||||
for(int32 i = start;
|
||||
i < settings->parameter_count && i < start + count;
|
||||
i++) {
|
||||
|
||||
type = -1;
|
||||
|
||||
const char *name = settings->parameters[i].name;
|
||||
|
||||
if(!strcasecmp(name, PPP_LOAD_MODULE_KEY))
|
||||
type = PPP_LOAD_MODULE_TYPE;
|
||||
else if(!strcasecmp(name, PPP_DEVICE_KEY))
|
||||
type = PPP_DEVICE_TYPE;
|
||||
else if(!strcasecmp(name, PPP_PROTOCOL_KEY))
|
||||
type = PPP_PROTOCOL_TYPE;
|
||||
else if(!strcasecmp(name, PPP_AUTHENTICATOR_KEY))
|
||||
type = PPP_AUTHENTICATOR_TYPE;
|
||||
else if(!strcasecmp(name, PPP_PEER_AUTHENTICATOR_KEY))
|
||||
type = PPP_PEER_AUTHENTICATOR_TYPE;
|
||||
|
||||
if(type >= 0)
|
||||
for(int32 value_id = 0; value_id < settings->parameters[i].value_count;
|
||||
value_id++)
|
||||
if(!LoadModule(settings->parameters[i].value[value_id],
|
||||
settings->parameters[i].parameters, type))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PPPInterface::LoadModule(const char *name, const driver_parameter *parameter,
|
||||
int32 type)
|
||||
{
|
||||
if(Phase() != PPP_CTOR_DTOR_PHASE)
|
||||
return false;
|
||||
// a running connection may not change
|
||||
|
||||
if(!name || strlen(name) > B_FILE_NAME_LENGTH)
|
||||
return false;
|
||||
|
||||
char module_name[B_PATH_NAME_LENGTH];
|
||||
|
||||
sprintf(module_name, "%s/%s", PPP_MODULES_PATH, name);
|
||||
|
||||
ppp_module_info *module;
|
||||
if(get_module(module_name, (module_info**) &module) != B_OK)
|
||||
return false;
|
||||
|
||||
if(!module->add_to(this, parameter, type))
|
||||
return false;
|
||||
|
||||
// add the module to the list of loaded modules
|
||||
// for putting them on our destruction
|
||||
return fModules.AddItem(module);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
PPPInterface::Send(mbuf *packet, uint16 protocol)
|
||||
{
|
||||
AccessHelper access(&fAccessing);
|
||||
|
||||
if(!packet)
|
||||
return B_ERROR;
|
||||
|
||||
// we must pass the basic tests!
|
||||
if(InitCheck() != B_OK) {
|
||||
m_free(packet);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
// test whether are going down
|
||||
if(Phase() == PPP_TERMINATION_PHASE) {
|
||||
m_free(packet);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
// go up if DialOnDemand enabled and we are down
|
||||
if(DoesDialOnDemand() && Phase() == PPP_DOWN_PHASE)
|
||||
Up();
|
||||
|
||||
// If this protocol is always allowed we should send the packet.
|
||||
// Note that these protocols are not passed to encapsulators!
|
||||
PPPProtocol *sending_protocol = ProtocolFor(protocol);
|
||||
if(sending_protocol && sending_protocol->Flags() & PPP_ALWAYS_ALLOWED
|
||||
&& sending_protocol->IsEnabled() && fDevice->IsUp())
|
||||
return SendToDevice(packet, protocol);
|
||||
|
||||
// never send normal protocols when we are down
|
||||
if(!IsUp()) {
|
||||
m_free(packet);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
// send to next up encapsulator
|
||||
if(!fFirstEncapsulator)
|
||||
return SendToDevice(packet, protocol);
|
||||
|
||||
if(!fFirstEncapsulator->IsEnabled())
|
||||
return fFirstEncapsulator->SendToNext();
|
||||
|
||||
return fFirstEncapsulator->Send(packet, protocol);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
PPPInterface::Receive(mbuf *packet, uint16 protocol)
|
||||
{
|
||||
AccessHelper access(&fAccessing);
|
||||
|
||||
if(!packet)
|
||||
return B_ERROR;
|
||||
|
||||
int32 result = PPP_REJECTED;
|
||||
// assume we have no handler
|
||||
|
||||
// Find handler and let it parse the packet.
|
||||
// The handler does need not be up because if we are a server
|
||||
// the handler might be upped by this packet.
|
||||
PPPEncapsulator *encapsulator_handler = EncapsulatorFor(protocol);
|
||||
for(; encapsulator_handler;
|
||||
encapsulator_handler = EncapsulatorFor(protocol, encapsulator_handler)) {
|
||||
if(!encapsulator_handler->IsEnabled())
|
||||
continue;
|
||||
// disabled handlers should not be used
|
||||
result = encapsulator_handler->Receive(packet, protocol);
|
||||
if(result == PPP_UNHANDLED)
|
||||
continue;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// no encapsulator handler could be found; try a protocol handler
|
||||
PPPProtocol *protocol_handler;
|
||||
for(int32 index = 0; index < CountProtocols(); index++) {
|
||||
protocol_handler = ProtocolAt(index);
|
||||
if(protocol != protocol_handler->Protocol()
|
||||
|| !protocol_handler->IsEnabled())
|
||||
continue;
|
||||
|
||||
result = protocol_handler->Receive(packet, protocol);
|
||||
if(result == PPP_UNHANDLED)
|
||||
continue;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// packet is unhandled
|
||||
m_free(packet);
|
||||
|
||||
if(result == PPP_UNHANDLED)
|
||||
return PPP_DISCARDED;
|
||||
else {
|
||||
// TODO:
|
||||
// send protocol-reject!
|
||||
return PPP_REJECTED;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
PPPInterface::SendToDevice(mbuf *packet, uint16 protocol)
|
||||
{
|
||||
AccessHelper access(&fAccessing);
|
||||
|
||||
if(!packet)
|
||||
return B_ERROR;
|
||||
|
||||
// we must pass the basic tests like:
|
||||
// do we have a device?
|
||||
// did we load all modules?
|
||||
if(InitCheck() != B_OK) {
|
||||
m_free(packet);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
// test whether are going down
|
||||
if(Phase() == PPP_TERMINATION_PHASE) {
|
||||
m_free(packet);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
// go up if DialOnDemand enabled and we are down
|
||||
if(DoesDialOnDemand() && Phase() == PPP_DOWN_PHASE)
|
||||
Up();
|
||||
|
||||
// check if protocol is allowed and everything is up
|
||||
PPPProtocol *sending_protocol = ProtocolFor(protocol);
|
||||
if(!fDevice->IsUp()
|
||||
|| (!IsUp() && protocol != PPP_LCP_PROTOCOL
|
||||
&& (!sending_protocol
|
||||
|| sending_protocol->Flags() & PPP_ALWAYS_ALLOWED == 0
|
||||
|| !sending_protocol->IsEnabled()
|
||||
)
|
||||
)
|
||||
) {
|
||||
m_free(packet);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
// encode in ppp frame
|
||||
M_PREPEND(packet, sizeof(uint16));
|
||||
|
||||
if(packet == NULL)
|
||||
return B_ERROR;
|
||||
|
||||
// set protocol (the only header field)
|
||||
protocol = htons(protocol);
|
||||
uint16 *header = mtod(packet, uint16*);
|
||||
*header = protocol;
|
||||
|
||||
// pass to device
|
||||
return Device()->Send(packet);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
PPPInterface::ReceiveFromDevice(mbuf *packet)
|
||||
{
|
||||
AccessHelper access(&fAccessing);
|
||||
|
||||
if(!packet)
|
||||
return B_ERROR;
|
||||
|
||||
if(!InitCheck()) {
|
||||
m_free(packet);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
// decode ppp frame
|
||||
uint16 *protocol = mtod(packet, uint16*);
|
||||
*protocol = ntohs(*protocol);
|
||||
|
||||
m_adj(packet, sizeof(uint16));
|
||||
|
||||
if(packet->m_flags & M_PKTHDR) {
|
||||
packet->m_pkthdr.rcvif = Ifnet();
|
||||
// make sure the protocols think we received
|
||||
// the packet
|
||||
|
||||
if(!packet->m_pkthdr.rcvif) {
|
||||
m_free(packet);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return Receive(packet, protocol);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPInterface::CalculateMRU()
|
||||
{
|
||||
fMRU = fLinkMTU;
|
||||
|
||||
// sum all headers
|
||||
fHeaderLength = sizeof(uint16);
|
||||
|
||||
PPPEncapsulator encapsulator = fFirstEncapsulator;
|
||||
while(encapsulator) {
|
||||
fHeaderLength += encapsulator->Overhead();
|
||||
encapsulator = encapsulator->Next();
|
||||
}
|
||||
|
||||
fMRU -= fHeaderLength;
|
||||
|
||||
if(Ifnet()) {
|
||||
Ifnet()->if_mtu = fMRU;
|
||||
Ifnet()->if_hdrlen = fHeaderLength;
|
||||
}
|
||||
}
|
2
src/tests/kits/net/ppp/src/KPPPLCP.cpp
Normal file
2
src/tests/kits/net/ppp/src/KPPPLCP.cpp
Normal file
@ -0,0 +1,2 @@
|
||||
#include "KPPPLCP.h"
|
||||
|
297
src/tests/kits/net/ppp/src/Locker.cpp
Normal file
297
src/tests/kits/net/ppp/src/Locker.cpp
Normal file
@ -0,0 +1,297 @@
|
||||
//
|
||||
// $Id: Locker.cpp,v 1.1 2003/07/06 16:46:29 wkornew Exp $
|
||||
//
|
||||
// This file contains the OpenBeOS implementation of BLocker.
|
||||
//
|
||||
|
||||
|
||||
#include "Locker.h"
|
||||
#include <OS.h>
|
||||
#include <SupportDefs.h>
|
||||
|
||||
|
||||
#ifdef USE_OPENBEOS_NAMESPACE
|
||||
namespace OpenBeOS {
|
||||
#endif
|
||||
|
||||
|
||||
//
|
||||
// Data Member Documentation:
|
||||
//
|
||||
// The "fBenaphoreCount" member is set to 1 if the BLocker style is
|
||||
// semaphore. If the style is benaphore, it is initialized to 0 and
|
||||
// is incremented atomically when it is acquired, decremented when it
|
||||
// is released. By setting the benaphore count to 1 when the style is
|
||||
// semaphore, the benaphore effectively becomes a semaphore. I was able
|
||||
// to determine this is what Be's implementation does by testing the
|
||||
// result of the CountLockRequests() member.
|
||||
//
|
||||
// The "fSemaphoreID" member holds the sem_id returned from create_sem()
|
||||
// when the BLocker is constructed. It is used to acquire and release
|
||||
// the lock regardless of the lock style (semaphore or benaphore).
|
||||
//
|
||||
// The "fLockOwner" member holds the thread_id of the thread which
|
||||
// currently holds the lock. If no thread holds the lock, it is set to
|
||||
// B_ERROR.
|
||||
//
|
||||
// The "fRecursiveCount" member holds a count of the number of times the
|
||||
// thread holding the lock has acquired the lock without a matching unlock.
|
||||
// It is basically the number of times the thread must call Unlock() before
|
||||
// the lock can be acquired by a different thread.
|
||||
//
|
||||
|
||||
|
||||
//
|
||||
// Constructors:
|
||||
//
|
||||
// All constructors just pass their arguments to InitLocker(). Note that
|
||||
// the default for "name" is "some BLocker" and "benaphore_style" is true.
|
||||
//
|
||||
|
||||
BLocker::BLocker()
|
||||
{
|
||||
InitLocker("some BLocker", true);
|
||||
}
|
||||
|
||||
|
||||
BLocker::BLocker(const char *name)
|
||||
{
|
||||
InitLocker(name, true);
|
||||
}
|
||||
|
||||
|
||||
BLocker::BLocker(bool benaphore_style)
|
||||
{
|
||||
InitLocker("some BLocker", benaphore_style);
|
||||
}
|
||||
|
||||
|
||||
BLocker::BLocker(const char *name,
|
||||
bool benaphore_style)
|
||||
{
|
||||
InitLocker(name, benaphore_style);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// This constructor is not documented. The final argument is ignored for
|
||||
// now. In Be's headers, its called "for_IPC". DO NOT USE THIS
|
||||
// CONSTRUCTOR!
|
||||
//
|
||||
BLocker::BLocker(const char *name,
|
||||
bool benaphore_style,
|
||||
bool)
|
||||
{
|
||||
InitLocker(name, benaphore_style);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// The destructor just deletes the semaphore. By deleting the semaphore,
|
||||
// any threads waiting to acquire the BLocker will be unblocked.
|
||||
//
|
||||
BLocker::~BLocker()
|
||||
{
|
||||
delete_sem(fSemaphoreID);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
BLocker::Lock(void)
|
||||
{
|
||||
status_t result;
|
||||
|
||||
return (AcquireLock(B_INFINITE_TIMEOUT, &result));
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BLocker::LockWithTimeout(bigtime_t timeout)
|
||||
{
|
||||
status_t result;
|
||||
|
||||
AcquireLock(timeout, &result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
BLocker::Unlock(void)
|
||||
{
|
||||
// If the thread currently holds the lockdecrement
|
||||
if (IsLocked()) {
|
||||
|
||||
// Decrement the number of outstanding locks this thread holds
|
||||
// on this BLocker.
|
||||
fRecursiveCount--;
|
||||
|
||||
// If the recursive count is now at 0, that means the BLocker has
|
||||
// been released by the thread.
|
||||
if (fRecursiveCount == 0) {
|
||||
|
||||
// The BLocker is no longer owned by any thread.
|
||||
fLockOwner = B_ERROR;
|
||||
|
||||
// Decrement the benaphore count and store the undecremented
|
||||
// value in oldBenaphoreCount.
|
||||
int32 oldBenaphoreCount = atomic_add(&fBenaphoreCount, -1);
|
||||
|
||||
// If the oldBenaphoreCount is greater than 1, then there is
|
||||
// at lease one thread waiting for the lock in the case of a
|
||||
// benaphore.
|
||||
if (oldBenaphoreCount > 1) {
|
||||
|
||||
// Since there are threads waiting for the lock, it must
|
||||
// be released. Note, the old benaphore count will always be
|
||||
// greater than 1 for a semaphore so the release is always done.
|
||||
release_sem(fSemaphoreID);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
thread_id
|
||||
BLocker::LockingThread(void) const
|
||||
{
|
||||
return fLockOwner;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
BLocker::IsLocked(void) const
|
||||
{
|
||||
// This member returns true if the calling thread holds the lock.
|
||||
// The easiest way to determine this is to compare the result of
|
||||
// find_thread() to the fLockOwner.
|
||||
return (find_thread(NULL) == fLockOwner);
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
BLocker::CountLocks(void) const
|
||||
{
|
||||
return fRecursiveCount;
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
BLocker::CountLockRequests(void) const
|
||||
{
|
||||
return fBenaphoreCount;
|
||||
}
|
||||
|
||||
|
||||
sem_id
|
||||
BLocker::Sem(void) const
|
||||
{
|
||||
return fSemaphoreID;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BLocker::InitLocker(const char *name,
|
||||
bool benaphore)
|
||||
{
|
||||
if (benaphore) {
|
||||
// Because this is a benaphore, initialize the benaphore count and
|
||||
// create the semaphore. Because this is a benaphore, the semaphore
|
||||
// count starts at 0 (ie acquired).
|
||||
fBenaphoreCount = 0;
|
||||
fSemaphoreID = create_sem(0, name);
|
||||
} else {
|
||||
// Because this is a semaphore, initialize the benaphore count to -1
|
||||
// and create the semaphore. Because this is semaphore style, the
|
||||
// semaphore count starts at 1 so that one thread can acquire it and
|
||||
// the next thread to acquire it will block.
|
||||
fBenaphoreCount = 1;
|
||||
fSemaphoreID = create_sem(1, name);
|
||||
}
|
||||
|
||||
// The lock is currently not acquired so there is no owner.
|
||||
fLockOwner = B_ERROR;
|
||||
|
||||
// The lock is currently not acquired so the recursive count is zero.
|
||||
fRecursiveCount = 0;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
BLocker::AcquireLock(bigtime_t timeout,
|
||||
status_t *error)
|
||||
{
|
||||
// By default, return no error.
|
||||
*error = B_NO_ERROR;
|
||||
|
||||
// Only try to acquire the lock if the thread doesn't already own it.
|
||||
if (!IsLocked()) {
|
||||
|
||||
// Increment the benaphore count and test to see if it was already greater
|
||||
// than 0. If it is greater than 0, then some thread already has the
|
||||
// benaphore or the style is a semaphore. Either way, we need to acquire
|
||||
// the semaphore in this case.
|
||||
int32 oldBenaphoreCount = atomic_add(&fBenaphoreCount, 1);
|
||||
if (oldBenaphoreCount > 0) {
|
||||
|
||||
*error = acquire_sem_etc(fSemaphoreID, 1, B_RELATIVE_TIMEOUT,
|
||||
timeout);
|
||||
// Note, if the lock here does time out, the benaphore count
|
||||
// is not decremented. By doing this, the benaphore count will
|
||||
// never go back to zero. This means that the locking essentially
|
||||
// changes to semaphore style if this was a benaphore.
|
||||
//
|
||||
// Doing the decrement of the benaphore count when the acquisition
|
||||
// fails is a risky thing to do. If you decrement the counter at
|
||||
// the same time the thread which holds the benaphore does an
|
||||
// Unlock(), there is serious risk of a race condition.
|
||||
//
|
||||
// If the Unlock() sees a positive count and releases the semaphore
|
||||
// and then the timed out thread decrements the count to 0, there
|
||||
// is no one to take the semaphore. The next two threads will be
|
||||
// able to acquire the benaphore at the same time! The first will
|
||||
// increment the counter and acquire the lock. The second will
|
||||
// acquire the semaphore and therefore the lock. Not good.
|
||||
//
|
||||
// This has been discussed on the becodetalk mailing list and
|
||||
// Trey from Be had this to say:
|
||||
//
|
||||
// I looked at the LockWithTimeout() code, and it does not have
|
||||
// _this_ (ie the race condition) problem. It circumvents it by
|
||||
// NOT doing the atomic_add(&count, -1) if the semaphore
|
||||
// acquisition fails. This means that if a
|
||||
// BLocker::LockWithTimeout() times out, all other Lock*() attempts
|
||||
// turn into guaranteed semaphore grabs, _with_ the overhead of a
|
||||
// (now) useless atomic_add().
|
||||
//
|
||||
// Given Trey's comments, it looks like Be took the same approach
|
||||
// I did. The output of CountLockRequests() of Be's implementation
|
||||
// confirms Trey's comments also.
|
||||
//
|
||||
// Finally some thoughts for the future with this code:
|
||||
// - If 2^31 timeouts occur on a 32-bit machine (ie today),
|
||||
// the benaphore count will wrap to a negative number. This
|
||||
// would have unknown consequences on the ability of the BLocker
|
||||
// to continue to function.
|
||||
//
|
||||
}
|
||||
}
|
||||
|
||||
// If the lock has successfully been acquired.
|
||||
if (*error == B_NO_ERROR) {
|
||||
|
||||
// Set the lock owner to this thread and increment the recursive count
|
||||
// by one. The recursive count is incremented because one more Unlock()
|
||||
// is now required to release the lock (ie, 0 => 1, 1 => 2 etc).
|
||||
fLockOwner = find_thread(NULL);
|
||||
fRecursiveCount++;
|
||||
}
|
||||
|
||||
// Return true if the lock has been acquired.
|
||||
return (*error == B_NO_ERROR);
|
||||
}
|
||||
|
||||
|
||||
#ifdef USE_OPENBEOS_NAMESPACE
|
||||
}
|
||||
#endif
|
123
src/tests/kits/net/ppp/src/settings_tools.cpp
Normal file
123
src/tests/kits/net/ppp/src/settings_tools.cpp
Normal file
@ -0,0 +1,123 @@
|
||||
#include "settings_tools.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <driver_settings.h>
|
||||
|
||||
|
||||
static void copy_parameter(const driver_parameter *from, driver_parameter *to);
|
||||
static void free_driver_parameter(driver_parameter *p);
|
||||
|
||||
|
||||
driver_settings *dup_driver_settings(const driver_settings *dup)
|
||||
{
|
||||
if(!settings)
|
||||
return NULL; // we got a NULL pointer, so return nothing
|
||||
|
||||
driver_settings *ret = (driver_settings*) malloc(sizeof(driver_settings));
|
||||
|
||||
ret->parameter_count = dup->parameter_count;
|
||||
ret->parameters = (driver_parameter*) malloc(ret->parameter_count * sizeof(driver_parameter));
|
||||
|
||||
for(int32 i=0; i < ret->parameter_count; i++)
|
||||
copy_parameter(&dup->parameters[i], &ret->parameters[i]);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void copy_parameter(const driver_parameter *from, driver_parameter *to)
|
||||
{
|
||||
to->name = strdup(from->name);
|
||||
to->value_count = from->value_count;
|
||||
|
||||
to->values = (char**) malloc(values * sizeof(char*));
|
||||
|
||||
for(int32 i=0; i < to->value_count; i++)
|
||||
to->values[i] = strdup(from->values[i]);
|
||||
|
||||
to->parameter_count = from->parameter_count;
|
||||
|
||||
to->parameters = (driver_parameter*) malloc(to->parameter_count * sizeof(driver_parameter));
|
||||
|
||||
for(int32 i=0; i < to->parameter_count; i++)
|
||||
copy_parameter(&from->parameters[i], &to->parameters[i]);
|
||||
}
|
||||
|
||||
|
||||
void free_driver_settings(driver_settings *settings)
|
||||
{
|
||||
for(int32 i=0; i < settings->parameter_count; i++)
|
||||
free_driver_parameter(&settings->parameters[i]);
|
||||
|
||||
free(settings->parameters);
|
||||
free(settings);
|
||||
}
|
||||
|
||||
|
||||
void free_driver_parameter(driver_parameter *p)
|
||||
{
|
||||
free(p->name);
|
||||
|
||||
for(int32 i=0; i < p->value_count; i++)
|
||||
free(p->values[i]);
|
||||
|
||||
free(p->values);
|
||||
|
||||
for(int32 i=0; i < p->parameter_count; i++)
|
||||
free_driver_parameter(&p->parameters[i]);
|
||||
|
||||
free(p->parameters);
|
||||
}
|
||||
|
||||
|
||||
void add_settings(const driver_settings *from, driver_settings *to)
|
||||
{
|
||||
if(!from || !to)
|
||||
return;
|
||||
|
||||
to->parameters = realloc(to->parameters,
|
||||
(to->parameter_count + from->parameter_count) * sizeof(driver_parameter));
|
||||
|
||||
for(int32 i=0; i < from->parameter_count; i++)
|
||||
copy_parameters(&from->parameters[i], &to->parameters[to->parameter_count++]);
|
||||
}
|
||||
|
||||
|
||||
bool get_boolean_value(const char *string, bool unknownValue)
|
||||
{
|
||||
if(!string)
|
||||
return unknownValue;
|
||||
|
||||
if (!strcmp(boolean, "1")
|
||||
|| !strcasecmp(boolean, "true")
|
||||
|| !strcasecmp(boolean, "yes")
|
||||
|| !strcasecmp(boolean, "on")
|
||||
|| !strcasecmp(boolean, "enable")
|
||||
|| !strcasecmp(boolean, "enabled"))
|
||||
return true;
|
||||
|
||||
if (!strcmp(boolean, "0")
|
||||
|| !strcasecmp(boolean, "false")
|
||||
|| !strcasecmp(boolean, "no")
|
||||
|| !strcasecmp(boolean, "off")
|
||||
|| !strcasecmp(boolean, "disable")
|
||||
|| !strcasecmp(boolean, "disabled"))
|
||||
return false;
|
||||
|
||||
// no correct value has been found => return default value
|
||||
return unknownValue;
|
||||
}
|
||||
|
||||
|
||||
const char *get_settings_value(const char *name, const driver_settings *settings)
|
||||
{
|
||||
if(!name || !settings)
|
||||
return NULL;
|
||||
|
||||
for(int32 i=0; i < settings->parameter_count; i++)
|
||||
if(!strcasecmp(settings->parameters[i].name, name)
|
||||
&& settings->parameters[i].value_count > 0)
|
||||
return settings->parameters[i].values[0];
|
||||
|
||||
return NULL;
|
||||
}
|
24
src/tests/kits/net/ppp/src/settings_tools.h
Normal file
24
src/tests/kits/net/ppp/src/settings_tools.h
Normal file
@ -0,0 +1,24 @@
|
||||
#ifndef _SETTINGS_TOOLS__H
|
||||
#define _SETTINGS_TOOLS__H
|
||||
|
||||
struct driver_settings;
|
||||
struct driver_parameter;
|
||||
|
||||
|
||||
driver_settings *dup_driver_settings(const driver_settings *settings);
|
||||
void free_driver_settings(driver_settings *settings);
|
||||
|
||||
void add_settings(const driver_settings *from, driver_settings *to);
|
||||
void add_settings(const driver_settings *from, driver_parameter *to)
|
||||
{ add_settings(from, (driver_settings*) &to->parameter_count); }
|
||||
void add_parameter(const driver_parameter *from, driver_settings *to)
|
||||
{ add_settings((driver_settings*) &from->parameter_count, to); }
|
||||
void add_parameter(const driver_parameter *from, driver_parameter *to)
|
||||
{ add_settings((driver_settings*) &from->parameter_count,
|
||||
(driver_settings*) &to->parameter_count); }
|
||||
|
||||
bool get_boolean_value(const char *string, bool unknownValue);
|
||||
const char *get_settings_value(const char *name, const driver_settings *settings);
|
||||
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user