Finished:
- PPPDevice - PPPEncapsulator - PPPOptionHandler - PPPProtocol Added SendCodeReject implementation (though, I am not sure if it really works because I am not familiar with mbufs). Fixed some bugs. Changed the manager interface (there are no pointers to classes anymore). Some minor changes. TODO for libkernelppp.a: - finish PPPLCP - finish PPPConfigurePacket git-svn-id: file:///srv/svn/repos/haiku/trunk/current@4400 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
ba92606354
commit
3118bf2206
@ -44,7 +44,7 @@ class PPPConfigurePacket {
|
||||
int32 CountItems() const;
|
||||
configure_item *ItemAt(int32 index) const;
|
||||
|
||||
mbuf *ToMbuf();
|
||||
mbuf *ToMbuf(uint32 reserve = 0, uint32 maxSize = 0);
|
||||
// the user is responsible for freeing the mbuf
|
||||
|
||||
private:
|
||||
|
@ -11,29 +11,35 @@
|
||||
#include <Errors.h>
|
||||
|
||||
|
||||
typedef uint32 interface_id;
|
||||
|
||||
// various constants
|
||||
#define PPP_PULSE_RATE 750000
|
||||
|
||||
// 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"
|
||||
#define PPP_MULTILINK_KEY "Multilink-Protocol"
|
||||
#define PPP_DISONNECT_AFTER_IDLE_SINCE_KEY "DisonnectAfterIdleSince"
|
||||
#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"
|
||||
#define PPP_MULTILINK_KEY "Multilink-Protocol"
|
||||
|
||||
// settings values
|
||||
#define PPP_CLIENT_MODE_VALUE "Client"
|
||||
#define PPP_SERVER_MODE_VALUE "Server"
|
||||
#define PPP_CLIENT_MODE_VALUE "Client"
|
||||
#define PPP_SERVER_MODE_VALUE "Server"
|
||||
|
||||
// path defines
|
||||
#define PPP_MODULES_PATH "network/ppp-modules"
|
||||
#define PPP_MODULES_PATH "network/ppp-modules"
|
||||
|
||||
// built-in protocols
|
||||
#define PPP_LCP_PROTOCOL 0xC021
|
||||
#define PPP_LCP_PROTOCOL 0xC021
|
||||
|
||||
|
||||
#define PPP_ERROR_BASE B_ERRORS_END
|
||||
#define PPP_ERROR_BASE B_ERRORS_END
|
||||
|
||||
// return values for Send()/Receive() methods in addition to B_ERROR and B_OK
|
||||
// PPP_UNHANDLED is also used by PPPOptionHandler
|
||||
|
@ -13,11 +13,11 @@
|
||||
|
||||
class PPPDevice {
|
||||
public:
|
||||
PPPDevice(const char *fName, uint32 overhead, PPPInterface *interface,
|
||||
PPPDevice(const char *name, uint32 overhead, PPPInterface *interface,
|
||||
driver_parameter *settings);
|
||||
virtual ~PPPDevice();
|
||||
|
||||
virtual status_t InitCheck() const = 0;
|
||||
virtual status_t InitCheck() const;
|
||||
|
||||
const char *Name() const
|
||||
{ return fName; }
|
||||
@ -58,18 +58,20 @@ class PPPDevice {
|
||||
// This will pass the packet to the interface's queue.
|
||||
// Do not call Interface::ReceiveFromDevice directly
|
||||
// if this can block a Send()!
|
||||
|
||||
virtual void Pulse();
|
||||
|
||||
protected:
|
||||
// Report that we are going up/down
|
||||
// (from now on, the Up() process can be aborted).
|
||||
// Abort if false is returned!
|
||||
bool UpStarted();
|
||||
bool DownStarted();
|
||||
bool UpStarted() const;
|
||||
bool DownStarted() const;
|
||||
|
||||
// report up/down events
|
||||
void UpEvent();
|
||||
void UpFailedEvent();
|
||||
void DownEvent();
|
||||
void UpFailedEvent() const;
|
||||
void UpEvent() const;
|
||||
void DownEvent() const;
|
||||
|
||||
protected:
|
||||
bool fIsUp;
|
||||
|
@ -19,7 +19,7 @@ class PPPEncapsulator {
|
||||
int32 flags = PPP_NO_FLAGS);
|
||||
virtual ~PPPEncapsulator();
|
||||
|
||||
virtual status_t InitCheck() const = 0;
|
||||
virtual status_t InitCheck() const;
|
||||
|
||||
const char *Name() const
|
||||
{ return fName; }
|
||||
@ -46,7 +46,8 @@ class PPPEncapsulator {
|
||||
bool IsEnabled() const
|
||||
{ return fEnabled; }
|
||||
|
||||
void SetUpRequested(bool requested = true);
|
||||
void SetUpRequested(bool requested = true)
|
||||
{ fUpRequested = requested; }
|
||||
bool IsUpRequested() const
|
||||
{ return fUpRequested; }
|
||||
|
||||
@ -71,10 +72,12 @@ class PPPEncapsulator {
|
||||
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);
|
||||
status_t SendToNext(mbuf *packet, uint16 protocol) const;
|
||||
// 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
|
||||
|
||||
virtual void Pulse();
|
||||
|
||||
protected:
|
||||
void UpStarted();
|
||||
@ -91,10 +94,11 @@ class PPPEncapsulator {
|
||||
private:
|
||||
char *fName;
|
||||
PPP_ENCAPSULATION_LEVEL fLevel;
|
||||
uint16 fProtocol;
|
||||
int32 fAddressFamily;
|
||||
PPPInterface *fInterface;
|
||||
driver_parameter *fSettings;
|
||||
uint16 fProtocol;
|
||||
int32 fAddressFamily, fFlags;
|
||||
int32 fFlags;
|
||||
|
||||
PPPEncapsulator *fNext;
|
||||
|
||||
|
@ -34,13 +34,17 @@ class PPPInterface {
|
||||
PPPInterface& operator= (const PPPInterface& copy);
|
||||
|
||||
public:
|
||||
PPPInterface(driver_settings *settings, PPPInterface *parent = NULL);
|
||||
PPPInterface(interface_id ID, driver_settings *settings,
|
||||
PPPInterface *parent = NULL);
|
||||
~PPPInterface();
|
||||
|
||||
void Delete();
|
||||
|
||||
status_t InitCheck() const;
|
||||
|
||||
interface_id ID() const
|
||||
{ return fID; }
|
||||
|
||||
driver_settings* Settings()
|
||||
{ return fSettings; }
|
||||
|
||||
@ -55,6 +59,12 @@ class PPPInterface {
|
||||
struct ifq *InQueue() const
|
||||
{ return fInQueue; }
|
||||
|
||||
// idle handling
|
||||
bigtime_t IdleSince() const
|
||||
{ return fIdleSince; }
|
||||
bigtime_t DisconnectAfterIdleSince() const
|
||||
{ return fDisconnectAfterIdleSince; }
|
||||
|
||||
void SetLinkMTU(uint32 linkMTU);
|
||||
uint32 LinkMTU() const
|
||||
{ return fLinkMTU; }
|
||||
@ -142,6 +152,7 @@ class PPPInterface {
|
||||
bool UnregisterInterface();
|
||||
|
||||
void CalculateMRU();
|
||||
void CalculateBaudRate();
|
||||
|
||||
void Redial();
|
||||
|
||||
@ -150,7 +161,9 @@ class PPPInterface {
|
||||
{ fParent = parent; }
|
||||
|
||||
private:
|
||||
driver_parameter *fSettings;
|
||||
interface_id fID;
|
||||
// the manager assigns an ID to every interface
|
||||
driver_settings *fSettings;
|
||||
PPPStateMachine fStateMachine;
|
||||
PPPLCP fLCP;
|
||||
PPPReportManager fReportManager;
|
||||
@ -164,6 +177,7 @@ class PPPInterface {
|
||||
|
||||
ppp_manager_info *fManager;
|
||||
|
||||
bigtime_t fIdleSince, fDisconnectAfterIdleSince;
|
||||
uint32 fLinkMTU, fMRU, fHeaderLength;
|
||||
|
||||
PPPInterface *fParent;
|
||||
|
@ -41,10 +41,15 @@ class PPPLCP : public PPPProtocol {
|
||||
{ return fOptionHandlers.CountItems(); }
|
||||
PPPOptionHandler *OptionHandlerAt(int32 index) const;
|
||||
|
||||
PPPEncapsulator *Target() const
|
||||
{ return fTarget; }
|
||||
void SetTarget(PPPEncapsulator *target)
|
||||
{ fTarget = target; }
|
||||
// if target != all packtes will be passed to the encapsulator
|
||||
// instead of the interface/device
|
||||
|
||||
uint32 AdditionalOverhead() const;
|
||||
// the overhead caused by the target, the device, and the interface
|
||||
|
||||
private:
|
||||
List<PPPOptionHandler*> fOptionHandlers;
|
||||
|
@ -13,25 +13,30 @@
|
||||
|
||||
#define PPP_MANAGER_MODULE_NAME "network/interfaces/ppp"
|
||||
|
||||
// this allows you to ask for specific interface_ids
|
||||
enum PPP_INTERFACE_FILTER {
|
||||
PPP_ALL_INTERFACES,
|
||||
PPP_REGISTERED_INTERFACES,
|
||||
PPP_UNREGISTERED_INTERFACES
|
||||
};
|
||||
|
||||
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)();
|
||||
uint32 (*create_interface)(driver_settings *settings, interface_id parent);
|
||||
// you should always create interfaces using this function
|
||||
void (*delete_interface)(interface_id ID);
|
||||
// this marks the interface for deletion
|
||||
|
||||
ifnet* (*add_interface)(PPPInterface *interface);
|
||||
bool (*remove_interface)(PPPInterface *interface);
|
||||
ifnet* (*register_interface)(interface_id ID);
|
||||
bool (*unregister_interface)(interface_id ID);
|
||||
|
||||
int32 (*count_interfaces)(int32 index);
|
||||
status_t (*control)(interface_id ID, uint32 op, void *data, size_t length);
|
||||
|
||||
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;
|
||||
status_t (*get_interfaces)(interface_id **interfaces, uint32 *count,
|
||||
PPP_INTERFACE_FILTER filter = PPP_REGISTERED_INTERFACES);
|
||||
// the user is responsible for free()'ing the interface_id array
|
||||
} ppp_manager_info;
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -18,7 +18,7 @@ class PPPOptionHandler {
|
||||
driver_parameter *settings);
|
||||
virtual ~PPPOptionHandler();
|
||||
|
||||
virtual status_t InitCheck() = 0;
|
||||
virtual status_t InitCheck() const;
|
||||
|
||||
void SetEnabled(bool enabled = true);
|
||||
bool IsEnabled() const
|
||||
|
@ -18,7 +18,7 @@ class PPPProtocol {
|
||||
driver_parameter *settings, int32 flags = PPP_NO_FLAGS);
|
||||
virtual ~PPPProtocol();
|
||||
|
||||
virtual status_t InitCheck() const = 0;
|
||||
virtual status_t InitCheck() const;
|
||||
|
||||
const char *Name() const
|
||||
{ return fName; }
|
||||
@ -41,7 +41,8 @@ class PPPProtocol {
|
||||
bool IsEnabled() const
|
||||
{ return fEnabled; }
|
||||
|
||||
void SetUpRequested(bool requested = true);
|
||||
void SetUpRequested(bool requested = true)
|
||||
{ fUpRequested = requested; }
|
||||
bool IsUpRequested() const
|
||||
{ return fUpRequested; }
|
||||
|
||||
@ -60,6 +61,8 @@ class PPPProtocol {
|
||||
|
||||
virtual status_t Send(mbuf *packet) = 0;
|
||||
virtual status_t Receive(mbuf *packet) = 0;
|
||||
|
||||
virtual void Pulse();
|
||||
|
||||
protected:
|
||||
void UpStarted();
|
||||
@ -74,9 +77,10 @@ class PPPProtocol {
|
||||
char *name;
|
||||
PPP_PHASE fPhase;
|
||||
uint16 fProtocol;
|
||||
int32 fAddressFamily, fFlags;
|
||||
int32 fAddressFamily;
|
||||
PPPInterface fInterface;
|
||||
driver_parameter fSettings;
|
||||
int32 fFlags;
|
||||
|
||||
bool fEnabled;
|
||||
bool fUpRequested;
|
||||
|
@ -26,7 +26,8 @@ enum PPP_REPORT_FLAGS {
|
||||
enum PPP_REPORT_TYPE {
|
||||
PPP_DESTRUCTION_REPORT = 0,
|
||||
// the interface is being destroyed (no code is needed)
|
||||
PPP_CONNECTION_REPORT = 1
|
||||
PPP_CONNECTION_REPORT = 1,
|
||||
PPP_AUTHENTICATION_REPORT = 2
|
||||
};
|
||||
|
||||
// report codes (type-specific)
|
||||
@ -36,10 +37,13 @@ enum PPP_CONNECTION_REPORT_CODES {
|
||||
PPP_REPORT_DOWN_SUCCESSFUL = 2,
|
||||
PPP_REPORT_UP_ABORTED = 3,
|
||||
PPP_REPORT_DEVICE_UP_FAILED = 4,
|
||||
PPP_REPORT_AUTHENTICATION_FAILED = 5,
|
||||
PPP_REPORT_CONNECTION_LOST = 6
|
||||
PPP_REPORT_AUTHENTICATION_SUCCESSFUL = 5,
|
||||
PPP_REPORT_PEER_AUTHENTICATION_SUCCESSFUL = 6,
|
||||
PPP_REPORT_AUTHENTICATION_FAILED = 7,
|
||||
PPP_REPORT_CONNECTION_LOST = 8
|
||||
};
|
||||
|
||||
|
||||
typedef struct ppp_report_packet {
|
||||
int32 type;
|
||||
int32 code;
|
||||
|
@ -6,3 +6,127 @@
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
#include "KPPPDevice.h"
|
||||
|
||||
|
||||
PPPDevice::PPPDevice(const char *name, uint32 overhead, PPPInterface *interface,
|
||||
driver_parameter *settings)
|
||||
: fOverhead(overhead), fInterface(interface),
|
||||
fSettings(settings)
|
||||
{
|
||||
fName = name ? strdup(name) : NULL;
|
||||
|
||||
SetMTU(PreferredMTU());
|
||||
|
||||
if(interface)
|
||||
interface->SetDevice(this);
|
||||
}
|
||||
|
||||
|
||||
PPPDevice::~PPPDevice()
|
||||
{
|
||||
free(fName);
|
||||
|
||||
if(Interface())
|
||||
Interface()->SetDevice(NULL);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
PPPDevice::InitCheck() const
|
||||
{
|
||||
if(!Interface() || !Settings())
|
||||
return B_ERROR;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
PPPDevice::Control(uint32 op, void *data, size_t length)
|
||||
{
|
||||
switch(op) {
|
||||
// TODO:
|
||||
// get:
|
||||
// - name
|
||||
// - mtu (+ preferred)
|
||||
// - status
|
||||
// - transfer rates
|
||||
|
||||
default:
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
status_t
|
||||
PPPDevice::PassToInterface(mbuf *packet)
|
||||
{
|
||||
if(!Interface() || !Interface()->InQueue())
|
||||
return B_ERROR;
|
||||
|
||||
IFQ_ENQUEUE(Interface()->InQueue(), packet);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPDevice::Pulse()
|
||||
{
|
||||
// do nothing by default
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PPPDevice::UpStarted() const
|
||||
{
|
||||
if(!Interface())
|
||||
return false;
|
||||
|
||||
return Interface()->StateMachine().TLSNotify();
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PPPDevice::DownStarted() const
|
||||
{
|
||||
if(!Interface())
|
||||
return false;
|
||||
|
||||
return Interface()->StateMachine().TLFNotify();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPDevice::UpFailedEvent()
|
||||
{
|
||||
fIsUp = false;
|
||||
|
||||
if(!Interface())
|
||||
return;
|
||||
|
||||
Interface()->StateMachine().UpFailedEvent();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPDevice::UpEvent()
|
||||
{
|
||||
fIsUp = true;
|
||||
|
||||
if(!Interface())
|
||||
return;
|
||||
|
||||
Interface()->StateMachine().UpEvent();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPDevice::DownEvent()
|
||||
{
|
||||
fIsUp = false;
|
||||
|
||||
if(!Interface())
|
||||
return;
|
||||
|
||||
Interface()->StateMachine().DownEvent();
|
||||
}
|
||||
|
@ -6,3 +6,143 @@
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
#include "KPPPEncapsulator.h"
|
||||
|
||||
|
||||
PPPEncapsulator::PPPEncapsulator(const char *name, PPP_ENCAPSULATION_LEVEL level,
|
||||
uint16 protocol, int32 addressFamily, uint32 overhead,
|
||||
PPPInterface *interface, driver_parameter *settings,
|
||||
int32 flags = PPP_NO_FLAGS)
|
||||
: fOverhead(overhead), fLevel(level), fProtocol(protocol),
|
||||
fAddressFamily(addressFamily), fInterface(interface),
|
||||
fSettings(settings), fFlags(flags), fEnabled(true),
|
||||
fUpRequested(true), fConnectionStatus(PPP_DOWN_PHASE)
|
||||
{
|
||||
fName = name ? strdup(name) : NULL;
|
||||
|
||||
if(interface)
|
||||
interface->AddEncapsulator(this);
|
||||
}
|
||||
|
||||
|
||||
PPPEncapsulator::~PPPEncapsulator()
|
||||
{
|
||||
free(fName);
|
||||
|
||||
if(Interface())
|
||||
Interface()->RemoveEncapsulator(this);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
PPPEncapsulator::InitCheck() const
|
||||
{
|
||||
if(!Interface() || !Settings())
|
||||
return B_ERROR;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPEncapsulator::SetEnabled(bool enabled = true)
|
||||
{
|
||||
fEnabled = enabled;
|
||||
|
||||
if(!Interface())
|
||||
return;
|
||||
|
||||
if(!enabled) {
|
||||
if(IsUp() || IsGoingUp()))
|
||||
Down();
|
||||
} else if(!IsUp() && !IsGoingUp() && IsUpRequested() && Interface()->IsUp())
|
||||
Up();
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
PPPEncapsulator::Control(uint32 op, void *data, size_t length)
|
||||
{
|
||||
switch(op) {
|
||||
// TODO:
|
||||
// get:
|
||||
// - name
|
||||
// - level, protocol, address family, overhead
|
||||
// - status (Is(Going)Up/Down/UpRequested/Enabled)
|
||||
// set:
|
||||
// - enabled
|
||||
|
||||
default:
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
PPPEncapsulator::SendToNext(mbuf *packet, uint16 protocol) const
|
||||
{
|
||||
if(Next())
|
||||
return Next()->Send(packet, protocol);
|
||||
else if(Interface())
|
||||
return Interface()->SendToDevice(packet, protocol);
|
||||
else
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPEncapsulator::Pulse()
|
||||
{
|
||||
// do nothing by default
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPEncapsulator::UpStarted()
|
||||
{
|
||||
fConnectionStatus = PPP_ESTABLISHMENT_PHASE;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPEncapsulator::DownStarted()
|
||||
{
|
||||
fConnectionStatus = PPP_TERMINATION_PHASE;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPEncapsulator::UpFailedEvent()
|
||||
{
|
||||
fConnectionStatus = PPP_DOWN_PHASE;
|
||||
|
||||
if(!Interface())
|
||||
return;
|
||||
|
||||
Interface()->StateMachine().UpFailedEvent(this);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPEncapsulator::UpEvent()
|
||||
{
|
||||
fConnectionStatus = PPP_ESTABLISHED_PHASE;
|
||||
|
||||
if(!Interface())
|
||||
return;
|
||||
|
||||
Interface()->StateMachine().UpEvent(this);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPEncapsulator::DownEvent()
|
||||
{
|
||||
fConnectionStatus = PPP_DOWN_PHASE;
|
||||
|
||||
if(!Interface())
|
||||
return;
|
||||
|
||||
Interface()->StateMachine().DownEvent(this);
|
||||
}
|
||||
|
@ -12,7 +12,6 @@
|
||||
#include "KPPPManager.h"
|
||||
|
||||
// general helper classes not only belonging to us
|
||||
#include "AccessHelper.h"
|
||||
#include "LockerHelper.h"
|
||||
|
||||
// tools only for us :)
|
||||
@ -43,13 +42,15 @@ status_t redial_func(void *data);
|
||||
status_t in_queue_thread(void *data);
|
||||
|
||||
|
||||
PPPInterface::PPPInterface(driver_settings *settings, PPPInterface *parent = NULL)
|
||||
: fSettings(dup_driver_settings(settings)),
|
||||
PPPInterface::PPPInterface(uint32 ID, driver_settings *settings,
|
||||
PPPInterface *parent = NULL)
|
||||
: fID(ID), fSettings(dup_driver_settings(settings)),
|
||||
fStateMachine(*this), fLCP(*this), ReportManager()(StateMachine().Locker()),
|
||||
fIfnet(NULL), fUpThread(-1), fRedialThread(-1), fDialRetry(0),
|
||||
fDialRetriesLimit(0), fLinkMTU(1500), fAccessing(0), fChildrenCount(0),
|
||||
fDevice(NULL), fFirstEncapsulator(NULL), fLock(StateMachine().Locker())
|
||||
fDialRetriesLimit(0), fIdleSince(0), fLinkMTU(1500), fDevice(NULL),
|
||||
fFirstEncapsulator(NULL), fLock(StateMachine().Locker())
|
||||
{
|
||||
// set up queue
|
||||
fInQueue = start_ifq();
|
||||
fInQueueThread = spawn_kernel_thread(in_queue_thread, "PPPInterface: Input",
|
||||
B_NORMAL_PRIORITY, this);
|
||||
@ -61,17 +62,32 @@ PPPInterface::PPPInterface(driver_settings *settings, PPPInterface *parent = NUL
|
||||
// are we a multilink subinterface?
|
||||
if(parent && parent->IsMultilink()) {
|
||||
fParent = parent;
|
||||
fParent->AddChild(this);
|
||||
fIsMultilink = true;
|
||||
} else {
|
||||
fParent = NULL;
|
||||
fIsMultilink = false;
|
||||
}
|
||||
|
||||
if(!fSettings)
|
||||
if(!fSettings) {
|
||||
fMode = PPP_CLIENT_MODE;
|
||||
fDisconnectAfterIdleSince = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
const char *value;
|
||||
|
||||
// get DisonnectAfterIdleSince settings
|
||||
value = get_settings_value(PPP_DISONNECT_AFTER_IDLE_SINCE_KEY, fSettings);
|
||||
if(!value)
|
||||
fDisconnectAfterIdleSince = 0;
|
||||
else
|
||||
fDisconnectAfterIdleSince = atoi(value);
|
||||
|
||||
if(fDisconnectAfterIdleSince < 0)
|
||||
fDisconnectAfterIdleSince = 0;
|
||||
|
||||
// get mode settings
|
||||
value = get_settings_value(PPP_MODE_KEY, fSettings);
|
||||
if(!strcasecmp(value, PPP_SERVER_MODE_VALUE))
|
||||
fMode = PPP_SERVER_MODE;
|
||||
@ -132,7 +148,7 @@ PPPInterface::~PPPInterface()
|
||||
void
|
||||
PPPInterface::Delete()
|
||||
{
|
||||
fManager->delete_interface(this);
|
||||
fManager->delete_interface(ID());
|
||||
}
|
||||
|
||||
|
||||
@ -177,7 +193,7 @@ PPPInterface::Control(uint32 op, void *data, size_t length)
|
||||
|
||||
|
||||
default:
|
||||
return B_ERROR;
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
@ -206,11 +222,9 @@ PPPInterface::SetDevice(PPPDevice *device)
|
||||
fDevice = device;
|
||||
|
||||
fLinkMTU = fDevice->MTU();
|
||||
if(Ifnet())
|
||||
Ifnet()->if_baudrate = max(fDevice->InputTransferRate(),
|
||||
fDevice->OutputTransferRate());
|
||||
|
||||
CalculateMRU();
|
||||
CalculateBaudRate();
|
||||
}
|
||||
|
||||
|
||||
@ -407,9 +421,7 @@ PPPInterface::RemoveChild(PPPInterface *child)
|
||||
|
||||
// parents cannot exist without their children
|
||||
if(CountChildren() == 0 && fManager && Ifnet())
|
||||
fManager->delete_interface(this);
|
||||
|
||||
CalculateMRU();
|
||||
fManager->delete_interface(ID());
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -534,7 +546,7 @@ PPPInterface::Up()
|
||||
fUpThread = -1;
|
||||
|
||||
if(!DoesDialOnDemand() && report.code != PPP_REPORT_DOWN_SUCCESSFUL)
|
||||
fManager->delete_interface(this);
|
||||
fManager->delete_interface(ID());
|
||||
}
|
||||
|
||||
PPP_REPLY(sender, B_OK);
|
||||
@ -572,7 +584,7 @@ PPPInterface::Up()
|
||||
|
||||
if(!DoesDialOnDemand()
|
||||
&& report.code != PPP_REPORT_DOWN_SUCCESSFUL)
|
||||
fManager->delete_interface(this);
|
||||
fManager->delete_interface(ID());
|
||||
|
||||
PPP_REPLY(sender, B_OK);
|
||||
ReportManager().DisableReports(PPP_CONNECTION_REPORT, me);
|
||||
@ -599,12 +611,15 @@ PPPInterface::Up()
|
||||
|
||||
if(!DoesDialOnDemand()
|
||||
&& report.code != PPP_REPORT_DOWN_SUCCESSFUL)
|
||||
fManager->delete_interface(this);
|
||||
fManager->delete_interface(ID());
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if the code is unknown we continue
|
||||
PPP_REPLY(sender, B_OK);
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -644,7 +659,7 @@ PPPInterface::Down()
|
||||
}
|
||||
|
||||
if(!DoesDialOnDemand())
|
||||
fManager->delete_interface(this);
|
||||
fManager->delete_interface(ID());
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -674,12 +689,11 @@ PPPInterface::LoadModules(const driver_settings *settings,
|
||||
|
||||
// multilink handling
|
||||
for(int32 i = start;
|
||||
i < settings->parameter_count && i < start + count;
|
||||
i++) {
|
||||
i < settings->parameter_count && i < start + count; i++) {
|
||||
if(!strcasecmp(settings->parameters[i].name, PPP_MULTILINK_KEY)
|
||||
&& settings->parameters[i].value_count > 0) {
|
||||
&& settings->parameters[i].value_count > 0) {
|
||||
if(!LoadModule(settings->parameters[i].value[0],
|
||||
parameters[i].parameters, PPP_MULTILINK_TYPE))
|
||||
parameters[i].parameters, PPP_MULTILINK_TYPE))
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
@ -690,14 +704,12 @@ PPPInterface::LoadModules(const driver_settings *settings,
|
||||
if(IsMultilink() && !Parent()) {
|
||||
// main interfaces only load the multilink module
|
||||
// and create a child using their settings
|
||||
AddChild(new PPPInterface(settings, this));
|
||||
fManager->create_interface(settings, ID());
|
||||
return true;
|
||||
}
|
||||
|
||||
for(int32 i = start;
|
||||
i < settings->parameter_count && i < start + count;
|
||||
i++) {
|
||||
|
||||
i < settings->parameter_count && i < start + count; i++) {
|
||||
type = -1;
|
||||
|
||||
name = settings->parameters[i].name;
|
||||
@ -715,9 +727,9 @@ PPPInterface::LoadModules(const driver_settings *settings,
|
||||
|
||||
if(type >= 0)
|
||||
for(int32 value_id = 0; value_id < settings->parameters[i].value_count;
|
||||
value_id++)
|
||||
value_id++)
|
||||
if(!LoadModule(settings->parameters[i].value[value_id],
|
||||
settings->parameters[i].parameters, type))
|
||||
settings->parameters[i].parameters, type))
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -756,8 +768,6 @@ PPPInterface::LoadModule(const char *name, const driver_parameter *parameter,
|
||||
status_t
|
||||
PPPInterface::Send(mbuf *packet, uint16 protocol)
|
||||
{
|
||||
AccessHelper access(&fAccessing);
|
||||
|
||||
if(!packet)
|
||||
return B_ERROR;
|
||||
|
||||
@ -781,8 +791,10 @@ PPPInterface::Send(mbuf *packet, uint16 protocol)
|
||||
// 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())
|
||||
&& sending_protocol->IsEnabled() && fDevice->IsUp()) {
|
||||
fIdleSince = system_time();
|
||||
return SendToDevice(packet, protocol);
|
||||
}
|
||||
|
||||
// never send normal protocols when we are down
|
||||
if(!IsUp()) {
|
||||
@ -790,6 +802,8 @@ PPPInterface::Send(mbuf *packet, uint16 protocol)
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
fIdleSince = system_time();
|
||||
|
||||
// send to next up encapsulator
|
||||
if(!fFirstEncapsulator)
|
||||
return SendToDevice(packet, protocol);
|
||||
@ -804,8 +818,6 @@ PPPInterface::Send(mbuf *packet, uint16 protocol)
|
||||
status_t
|
||||
PPPInterface::Receive(mbuf *packet, uint16 protocol)
|
||||
{
|
||||
AccessHelper access(&fAccessing);
|
||||
|
||||
if(!packet)
|
||||
return B_ERROR;
|
||||
|
||||
@ -874,8 +886,6 @@ PPPInterface::Receive(mbuf *packet, uint16 protocol)
|
||||
status_t
|
||||
PPPInterface::SendToDevice(mbuf *packet, uint16 protocol)
|
||||
{
|
||||
AccessHelper access(&fAccessing);
|
||||
|
||||
if(!packet)
|
||||
return B_ERROR;
|
||||
|
||||
@ -914,7 +924,7 @@ PPPInterface::SendToDevice(mbuf *packet, uint16 protocol)
|
||||
}
|
||||
|
||||
// encode in ppp frame
|
||||
packet = M_PREPEND(packet, sizeof(uint16));
|
||||
M_PREPEND(packet, sizeof(uint16));
|
||||
|
||||
if(packet == NULL)
|
||||
return B_ERROR;
|
||||
@ -924,11 +934,13 @@ PPPInterface::SendToDevice(mbuf *packet, uint16 protocol)
|
||||
uint16 *header = mtod(packet, uint16*);
|
||||
*header = protocol;
|
||||
|
||||
fIdleSince = system_time();
|
||||
|
||||
// pass to device/children
|
||||
if(!IsMultilink() || Parent()) {
|
||||
// check if packet is too big for device
|
||||
if((packet->m_flags & M_PKTHDR && packet->m_pkt_hdr.len > LinkMTU())
|
||||
|| packet->m_len > LinkMTU()) {
|
||||
if((packet->m_flags & M_PKTHDR && packet->m_pkthdr.len > LinkMTU())
|
||||
|| packet->m_len > LinkMTU()) {
|
||||
m_freem(packet);
|
||||
return B_ERROR;
|
||||
}
|
||||
@ -945,8 +957,6 @@ PPPInterface::SendToDevice(mbuf *packet, uint16 protocol)
|
||||
status_t
|
||||
PPPInterface::ReceiveFromDevice(mbuf *packet)
|
||||
{
|
||||
AccessHelper access(&fAccessing);
|
||||
|
||||
if(!packet)
|
||||
return B_ERROR;
|
||||
|
||||
@ -961,16 +971,12 @@ PPPInterface::ReceiveFromDevice(mbuf *packet)
|
||||
|
||||
m_adj(packet, sizeof(uint16));
|
||||
|
||||
if(packet->m_flags & M_PKTHDR) {
|
||||
// Set our interface as the receiver.
|
||||
// This might be NULL, so protocols that belong to the network stack (IP, etc.)
|
||||
// will probably be confused (as there is no interface from which the packet came).
|
||||
// Protocols that live only in the PPP interface should have no problems with this.
|
||||
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_freem(packet);
|
||||
return B_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return Receive(packet, protocol);
|
||||
}
|
||||
@ -979,10 +985,24 @@ PPPInterface::ReceiveFromDevice(mbuf *packet)
|
||||
void
|
||||
PPPInterface::Pulse()
|
||||
{
|
||||
// TODO:
|
||||
// check our idle time
|
||||
// check our idle time and disconnect if needed
|
||||
if(fDisconnectAfterIdleSince > 0 && fIdleSince != 0
|
||||
&& fIdleSince - system_time() >= fDisconnectAfterIdleSince) {
|
||||
StateMachine().CloseEvent();
|
||||
return;
|
||||
}
|
||||
|
||||
StateMachine().TimerEvent();
|
||||
|
||||
if(Device())
|
||||
Device()->Pulse();
|
||||
|
||||
for(int32 index = 0; index < CountProtocols(); index++)
|
||||
ProtocolAt(index)->Pulse();
|
||||
|
||||
PPPEncapsulator *encapsulator = fFirstEncapsulator;
|
||||
for(; encapsulator; encapsulator = encapsulator->Next())
|
||||
encapsulator->Pulse();
|
||||
}
|
||||
|
||||
|
||||
@ -1004,14 +1024,12 @@ PPPInterface::RegisterInterface()
|
||||
if(!fManager)
|
||||
return false;
|
||||
|
||||
fIfnet = fManager->add_interface(this);
|
||||
fIfnet = fManager->register_interface(ID());
|
||||
|
||||
if(!fIfnet)
|
||||
return false;
|
||||
|
||||
if(Device())
|
||||
fIfnet->if_baudrate = max(Device()->InputTransferRate(),
|
||||
Device()->OutputTransferRate());
|
||||
CalculateBaudRate();
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -1031,7 +1049,7 @@ PPPInterface::UnregisterInterface()
|
||||
if(!fManager)
|
||||
return false;
|
||||
|
||||
fManager->remove_interface(this);
|
||||
fManager->unregister_interface(ID());
|
||||
fIfnet = NULL;
|
||||
|
||||
return true;
|
||||
@ -1047,10 +1065,8 @@ PPPInterface::CalculateMRU()
|
||||
fHeaderLength = sizeof(uint16);
|
||||
|
||||
PPPEncapsulator encapsulator = fFirstEncapsulator;
|
||||
while(encapsulator) {
|
||||
for(; encapsulator; encapsulator = encapsulator->Next())
|
||||
fHeaderLength += encapsulator->Overhead();
|
||||
encapsulator = encapsulator->Next();
|
||||
}
|
||||
|
||||
fMRU -= fHeaderLength;
|
||||
|
||||
@ -1064,6 +1080,24 @@ PPPInterface::CalculateMRU()
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPInterface::CalculateBaudRate()
|
||||
{
|
||||
if(!Ifnet())
|
||||
return;
|
||||
|
||||
if(Device())
|
||||
fIfnet->if_baudrate = max(Device()->InputTransferRate(),
|
||||
Device()->OutputTransferRate());
|
||||
else {
|
||||
fIfnet->if_baudrate = 0;
|
||||
for(int32 index = 0; index < CountChildren(); index++)
|
||||
if(ChildAt(index)->Ifnet())
|
||||
fIfnet->if_baudrate += ChildAt(index)->Ifnet()->if_baudrate;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPInterface::Redial()
|
||||
{
|
||||
|
@ -64,3 +64,16 @@ PPPLCP::OptionHandlerAt(int32 index) const
|
||||
|
||||
return handler;
|
||||
}
|
||||
|
||||
uint32
|
||||
PPPLCP::AdditionalOverhead const
|
||||
{
|
||||
uint32 overhead += PPP_PROTOCOL_OVERHEAD;
|
||||
|
||||
if(Target())
|
||||
overhead += Target()->Overhead();
|
||||
if(Interface()->Device())
|
||||
overhead += Interface()->Device()->Overhead();
|
||||
|
||||
return overhead;
|
||||
}
|
||||
|
@ -6,3 +6,33 @@
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
#include "KPPPOptionHandler.h"
|
||||
|
||||
|
||||
PPPOptionHandler::PPPOptionHandler(const char *name, PPPInterface *interface,
|
||||
driver_parameter *settings)
|
||||
: fInterface(interface), fSettings(settings)
|
||||
{
|
||||
fName = name ? strdup(name) : NULL;
|
||||
|
||||
if(interface)
|
||||
interface->LCP().AddOptionHandler(this);
|
||||
}
|
||||
|
||||
|
||||
PPPOptionHandler::~PPPOptionHandler()
|
||||
{
|
||||
free(fName);
|
||||
|
||||
if(Interface())
|
||||
Interface()->LCP().RemoveOptionHandler(this);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
PPPOptionHandler::InitCheck() const
|
||||
{
|
||||
if(!Interface() || !Settings())
|
||||
return B_ERROR;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
@ -6,3 +6,129 @@
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
#include "KPPPProtocol.h"
|
||||
|
||||
|
||||
PPPProtocol::PPPProtocol(const char *name, PPP_PHASE phase, uint16 protocol,
|
||||
int32 addressFamily, PPPInterface *interface,
|
||||
driver_parameter *settings, int32 flags = PPP_NO_FLAGS)
|
||||
: fPhase(phase), fProtocol(protocol), fAddressFamily(addressFamily),
|
||||
fInterface(interface), fSettings(settings), fFlags(flags),
|
||||
fEnabled(true), fUpRequested(true), fConnectionStatus(PPP_DOWN_PHASE)
|
||||
{
|
||||
fName = name ? strdup(name) : NULL;
|
||||
|
||||
if(interface)
|
||||
interface->AddProtocol(this);
|
||||
}
|
||||
|
||||
|
||||
PPPProtocol::~PPPProtocol()
|
||||
{
|
||||
free(fName);
|
||||
|
||||
if(Interface())
|
||||
Interface()->RemoveProtocol(this);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
PPPProtocol::InitCheck() const
|
||||
{
|
||||
if(!Interface() || !Settings())
|
||||
return B_ERROR;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPProtocol::SetEnabled(bool enabled = true)
|
||||
{
|
||||
fEnabled = enabled;
|
||||
|
||||
if(!Interface())
|
||||
return;
|
||||
|
||||
if(!enabled) {
|
||||
if(IsUp() || IsGoingUp()))
|
||||
Down();
|
||||
} else if(!IsUp() && !IsGoingUp() && IsUpRequested() && Interface()->IsUp())
|
||||
Up();
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
PPPProtocol::Control(uint32 op, void *data, size_t length)
|
||||
{
|
||||
switch(op) {
|
||||
// TODO:
|
||||
// get:
|
||||
// - name
|
||||
// - protocol, address family
|
||||
// - status (Is(Going)Up/Down/UpRequested/Enabled)
|
||||
// set:
|
||||
// - enabled
|
||||
|
||||
default:
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPProtocol::Pulse()
|
||||
{
|
||||
// do nothing by default
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPProtocol::UpStarted()
|
||||
{
|
||||
fConnectionStatus = PPP_ESTABLISHMENT_PHASE;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPProtocol::DownStarted()
|
||||
{
|
||||
fConnectionStatus = PPP_TERMINATION_PHASE;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPProtocol::UpFailedEvent()
|
||||
{
|
||||
fConnectionStatus = PPP_DOWN_PHASE;
|
||||
|
||||
if(!Interface())
|
||||
return;
|
||||
|
||||
Interface()->StateMachine().UpFailedEvent(this);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPProtocol::UpEvent()
|
||||
{
|
||||
fConnectionStatus = PPP_ESTABLISHED_PHASE;
|
||||
|
||||
if(!Interface())
|
||||
return;
|
||||
|
||||
Interface()->StateMachine().UpEvent(this);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPProtocol::DownEvent()
|
||||
{
|
||||
fConnectionStatus = PPP_DOWN_PHASE;
|
||||
|
||||
if(!Interface())
|
||||
return;
|
||||
|
||||
Interface()->StateMachine().DownEvent(this);
|
||||
}
|
||||
|
@ -105,6 +105,8 @@ PPPStateMachine::AuthenticationAccepted(const char *name)
|
||||
fAuthenticationStatus = PPP_AUTHENTICATION_SUCCESSFUL;
|
||||
free(fAuthenticationName);
|
||||
fAuthenticationName = strdup(name);
|
||||
|
||||
Interface()->Report(PPP_CONNECTION_REPORT, PPP_REPORT_AUTHENTICATION_SUCCESSFUL, 0);
|
||||
}
|
||||
|
||||
|
||||
@ -147,6 +149,9 @@ PPPStateMachine::PeerAuthenticationAccepted(const char *name)
|
||||
fPeerAuthenticationStatus = PPP_AUTHENTICATION_SUCCESSFUL;
|
||||
free(fPeerAuthenticationName);
|
||||
fPeerAuthenticationName = strdup(name);
|
||||
|
||||
Interface()->Report(PPP_CONNECTION_REPORT,
|
||||
PPP_REPORT_PEER_AUTHENTICATION_SUCCESSFUL, 0);
|
||||
}
|
||||
|
||||
|
||||
@ -183,17 +188,23 @@ PPPStateMachine::UpEvent(PPPInterface *interface)
|
||||
{
|
||||
LockerHelper locker(fLock);
|
||||
|
||||
if(Phase() <= PPP_TERMINATION_PHASE || State() != PPP_STARTING_STATE) {
|
||||
if(Phase() <= PPP_TERMINATION_PHASE) {
|
||||
interface->StateMachine().CloseEvent();
|
||||
return;
|
||||
}
|
||||
|
||||
NewState(PPP_OPENED_STATE);
|
||||
Interface()->CalculateBaudRate();
|
||||
|
||||
if(Phase() == PPP_ESTABLISHMENT_PHASE) {
|
||||
NewPhase(PPP_AUTHENTICATION_PHASE);
|
||||
// this is the first interface that went up
|
||||
Interface()->SetLinkMTU(interface->LinkMTU());
|
||||
locker.UnlockNow();
|
||||
ThisLayerUp();
|
||||
}
|
||||
} else if(Interface()->LinkMTU() > interface->LinkMTU())
|
||||
Interface()->SetLinkMTU(interface->LinkMTU());
|
||||
// linkMTU should always be the smallest value of all children
|
||||
|
||||
NewState(PPP_OPENED_STATE);
|
||||
}
|
||||
|
||||
|
||||
@ -202,6 +213,11 @@ PPPStateMachine::DownEvent(PPPInterface *interface)
|
||||
{
|
||||
LockerHelper locker(fLock);
|
||||
|
||||
uint32 linkMTU = 0;
|
||||
// the new linkMTU
|
||||
|
||||
Interface()->CalculateBaudRate();
|
||||
|
||||
// when all children are down we should not be running
|
||||
if(Interface()->IsMultilink() && !Interface()->Parent()) {
|
||||
uint32 count = 0;
|
||||
@ -209,10 +225,19 @@ PPPStateMachine::DownEvent(PPPInterface *interface)
|
||||
for(int32 index = 0; index < Interface()->CountChildren(); index++) {
|
||||
child = Interface()->ChildAt(index);
|
||||
|
||||
if(child && child->IsUp())
|
||||
if(child && child->IsUp()) {
|
||||
// set linkMTU to the smallest value of all children
|
||||
if(linkMTU == 0)
|
||||
linkMTU = child->LinkMTU();
|
||||
else if(linkMTU > child->LinkMTU())
|
||||
linkMTU = child->LinkMTU();
|
||||
|
||||
++count;
|
||||
}
|
||||
}
|
||||
|
||||
Interface()->SetLinkMTU(linkMTU);
|
||||
|
||||
if(count == 0) {
|
||||
locker.UnlockNow();
|
||||
DownEvent();
|
||||
@ -372,10 +397,7 @@ PPPStateMachine::UpEvent()
|
||||
return;
|
||||
// it is not our device that went up...
|
||||
|
||||
if(Interface()->Ifnet())
|
||||
Interface()->Ifnet()->if_baudrate = max(
|
||||
Interface()->Device()->InputTransferRate(),
|
||||
Interface()->Device()->OutputTransferRate());
|
||||
Interface()->CalculateBaudRate();
|
||||
|
||||
switch(State()) {
|
||||
case PPP_INITIAL_STATE:
|
||||
@ -428,14 +450,14 @@ PPPStateMachine::DownEvent()
|
||||
{
|
||||
LockerHelper locker(fLock);
|
||||
|
||||
if(!Interface()->Device() || Interface()->Device->IsUp())
|
||||
if(Interface()->Device() && Interface()->Device->IsUp())
|
||||
return;
|
||||
// it is not our device that went up...
|
||||
|
||||
if(Interface()->Ifnet())
|
||||
Interface()->Ifnet()->if_baudrate = max(
|
||||
Interface()->Device()->InputTransferRate(),
|
||||
Interface()->Device()->OutputTransferRate());
|
||||
Interface()->CalculateBaudRate();
|
||||
|
||||
// reset IdleSince
|
||||
Interface()->fIdleSince = 0;
|
||||
|
||||
switch(State()) {
|
||||
case PPP_CLOSED_STATE:
|
||||
@ -1150,7 +1172,7 @@ PPPStateMachine::RCREvent(mbuf *packet)
|
||||
handled = false;
|
||||
|
||||
for(int32 index = 0; index < LCP().CountOptionHandlers();
|
||||
index++) {
|
||||
index++) {
|
||||
handler = LCP().OptionHandlerAt(index);
|
||||
error = handler->ParseRequest(&request, item, &nak, &reject);
|
||||
if(error == PPP_UNHANLED)
|
||||
@ -1171,9 +1193,9 @@ PPPStateMachine::RCREvent(mbuf *packet)
|
||||
}
|
||||
|
||||
if(nak.CountItems() > 0)
|
||||
RCRBadEvent(nak.ToMbuf(), NULL);
|
||||
RCRBadEvent(nak.ToMbuf(LCP().AdditionalOverhead()), NULL);
|
||||
else if(reject.CountItmes() > 0)
|
||||
RCRBadEvent(NULL, reject.ToMbuf());
|
||||
RCRBadEvent(NULL, reject.ToMbuf(LCP().AdditionalOverhead()));
|
||||
else
|
||||
RCRGoodEvent(packet);
|
||||
}
|
||||
@ -1326,7 +1348,7 @@ PPPStateMachine::SendConfigureRequest()
|
||||
}
|
||||
}
|
||||
|
||||
LCP().Send(request.ToMbuf());
|
||||
LCP().Send(request.ToMbuf(LCP().AdditionalOverhead()));
|
||||
}
|
||||
|
||||
|
||||
@ -1369,11 +1391,7 @@ PPPStateMachine::SendTerminateRequest()
|
||||
--fTerminateCounter;
|
||||
|
||||
// reserve some space for other protocols
|
||||
m->m_data += PPP_PROTOCOL_OVERHEAD;
|
||||
if(LCP().Encapsulator())
|
||||
m->m_data += LCP().Encapsulator()->Overhead();
|
||||
if(Interface()->Device())
|
||||
m->m_data += Interface()->Device()->Overhead();
|
||||
m->m_data += LCP().AdditionalOverhead();
|
||||
|
||||
lcp_packet *request = mtod(m, lcp_packet*);
|
||||
request->code = PPP_TERMINATE_REQUEST;
|
||||
@ -1398,8 +1416,36 @@ PPPStateMachine::SendTerminateAck(mbuf *request)
|
||||
void
|
||||
PPPStateMachine::SendCodeReject(mbuf *packet, uint16 protocol, uint8 type)
|
||||
{
|
||||
// TODO:
|
||||
// add the packet to the reject and truncate it if needed
|
||||
int32 length;
|
||||
// additional space needed for this reject
|
||||
if(type == PPP_PROTOCOL_REJECT)
|
||||
length = 6;
|
||||
else
|
||||
length = 4;
|
||||
|
||||
M_PREPEND(packet, length + LCP().AdditionalOverhead());
|
||||
|
||||
int32 adjust = 0;
|
||||
// adjust packet size by this value if packet is too big
|
||||
if(packet->m_flags & M_PKTHDR) {
|
||||
if(packet->m_pkthdr.len > Interface()->LinkMTU())
|
||||
adjust = Interface()->LinkMTU() - packet->m_pkthdr.len;
|
||||
} else if(packet->m_len > Interface()->LinkMTU())
|
||||
adjust = Interface()->LinkMTU() - packet->m_len;
|
||||
|
||||
if(adjust != 0)
|
||||
m_adj(packet, adjust);
|
||||
|
||||
lcp_packet *reject = mtod(packet, lcp_packet*);
|
||||
data->code = type;
|
||||
data->id = NextID();
|
||||
data->length = (uint16) htons(reject->m_pkthdr.len);
|
||||
|
||||
protocol = (uint16) htons(protocol);
|
||||
if(type == PPP_PROTOCOL_REJECT)
|
||||
memcpy(&data->data, &protocol, sizeof(protocol));
|
||||
|
||||
LCP().Send(packet);
|
||||
}
|
||||
|
||||
|
||||
@ -1483,7 +1529,8 @@ void
|
||||
PPPStateMachine::DownProtocols()
|
||||
{
|
||||
for(int32 index = 0; index < Interface()->CountProtocols(); index++)
|
||||
Interface()->ProtocolAt(index)->Down();
|
||||
if(Interface()->ProtocolAt(index)->IsEnabled())
|
||||
Interface()->ProtocolAt(index)->Down();
|
||||
}
|
||||
|
||||
|
||||
@ -1494,7 +1541,8 @@ PPPStateMachine::DownEncapsulators()
|
||||
|
||||
for(; encapsulator_handler;
|
||||
encapsulator_handler = encapsulator_handler->Next())
|
||||
encapsualtor_handler->Down();
|
||||
if(encapsulator_handler->IsEnabled())
|
||||
encapsualtor_handler->Down();
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user