Added PPPLCPExtension (allows additional codes for LCP).
Added Control() op codes for report enabling/disabling. Fixed memory leaks in StateMachine and LCP (packets were not freed). Some minor changes. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@4514 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
a602502a7e
commit
b8561cdd29
@ -49,9 +49,9 @@ enum PPP_EVENT {
|
||||
PPP_RXR_EVENT
|
||||
};
|
||||
|
||||
// LCP protocol types as defined in RFC 1661
|
||||
// LCP protocol codes as defined in RFC 1661
|
||||
// ToDo: add LCP extensions
|
||||
enum PPP_LCP_TYPE {
|
||||
enum PPP_LCP_CODE {
|
||||
PPP_CONFIGURE_REQUEST = 1,
|
||||
PPP_CONFIGURE_ACK = 2,
|
||||
PPP_CONFIGURE_NAK = 3,
|
||||
|
@ -8,8 +8,6 @@
|
||||
#ifndef _K_PPP_DEVICE__H
|
||||
#define _K_PPP_DEVICE__H
|
||||
|
||||
#include <driver_settings.h>
|
||||
|
||||
#include <KPPPDefs.h>
|
||||
|
||||
#ifndef _K_PPP_INTERFACE__H
|
||||
@ -78,14 +76,13 @@ class PPPDevice {
|
||||
void DownEvent();
|
||||
|
||||
protected:
|
||||
uint32 fMTU;
|
||||
bool fIsUp;
|
||||
|
||||
private:
|
||||
char fName[PPP_HANDLER_NAME_LENGTH_LIMIT + 1];
|
||||
PPPInterface& fInterface;
|
||||
driver_parameter *fSettings;
|
||||
|
||||
uint32 fMTU;
|
||||
};
|
||||
|
||||
|
||||
|
@ -8,12 +8,8 @@
|
||||
#ifndef _K_PPP_ENCAPSULATOR__H
|
||||
#define _K_PPP_ENCAPSULATOR__H
|
||||
|
||||
#include <driver_settings.h>
|
||||
|
||||
#include <KPPPDefs.h>
|
||||
|
||||
class PPPInterface;
|
||||
|
||||
#ifndef _K_PPP_INTERFACE__H
|
||||
#include <KPPPInterface.h>
|
||||
#endif
|
||||
|
@ -23,6 +23,7 @@
|
||||
#endif
|
||||
|
||||
class PPPEncapsulator;
|
||||
class PPPLCPExtension;
|
||||
class PPPOptionHandler;
|
||||
|
||||
|
||||
@ -30,7 +31,7 @@ typedef struct ppp_lcp_packet {
|
||||
uint8 code;
|
||||
uint8 id;
|
||||
uint16 length;
|
||||
int8 data[0];
|
||||
uint8 data[0];
|
||||
} ppp_lcp_packet;
|
||||
|
||||
|
||||
@ -56,6 +57,12 @@ class PPPLCP : public PPPProtocol {
|
||||
{ return fOptionHandlers.CountItems(); }
|
||||
PPPOptionHandler *OptionHandlerAt(int32 index) const;
|
||||
|
||||
bool AddLCPExtension(PPPLCPExtension *extension);
|
||||
bool RemoveLCPExtension(PPPLCPExtension *extension);
|
||||
int32 CountLCPExtensions() const
|
||||
{ return fLCPExtensions.CountItems(); }
|
||||
PPPLCPExtension *LCPExtensionAt(int32 index) const;
|
||||
|
||||
PPPEncapsulator *Target() const
|
||||
{ return fTarget; }
|
||||
void SetTarget(PPPEncapsulator *target)
|
||||
@ -78,6 +85,7 @@ class PPPLCP : public PPPProtocol {
|
||||
PPPStateMachine& fStateMachine;
|
||||
|
||||
List<PPPOptionHandler*> fOptionHandlers;
|
||||
List<PPPLCPExtension*> fLCPExtensions;
|
||||
|
||||
PPPEncapsulator *fTarget;
|
||||
};
|
||||
|
60
src/tests/kits/net/ppp/headers/KPPPLCPExtension.h
Normal file
60
src/tests/kits/net/ppp/headers/KPPPLCPExtension.h
Normal file
@ -0,0 +1,60 @@
|
||||
//----------------------------------------------------------------------
|
||||
// This software is part of the OpenBeOS distribution and is covered
|
||||
// by the OpenBeOS license.
|
||||
//
|
||||
// Copyright (c) 2003 Waldemar Kornewald, Waldemar.Kornewald@web.de
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
#ifndef __K_PPP_LCP_EXTENSION__H
|
||||
#define __K_PPP_LCP_EXTENSION__H
|
||||
|
||||
#include <KPPPDefs.h>
|
||||
|
||||
#ifndef _K_PPP_INTERFACE__H
|
||||
#include <KPPPInterface.h>
|
||||
#endif
|
||||
|
||||
|
||||
class PPPLCPExtension {
|
||||
public:
|
||||
PPPLCPExtension(const char *name, uint8 code, PPPInterface& interface,
|
||||
driver_parameter *settings);
|
||||
virtual ~PPPLCPExtension();
|
||||
|
||||
virtual status_t InitCheck() const;
|
||||
|
||||
const char *Name() const
|
||||
{ return fName; }
|
||||
|
||||
PPPInterface& Interface() const
|
||||
{ return fInterface; }
|
||||
driver_parameter *Settings() const
|
||||
{ return fSettings; }
|
||||
|
||||
void SetEnabled(bool enabled = true)
|
||||
{ fEnabled = enabled; }
|
||||
bool IsEnabled() const
|
||||
{ return fEnabled; }
|
||||
|
||||
uint8 Code() const
|
||||
{ return fCode; }
|
||||
|
||||
virtual status_t Control(uint32 op, void *data, size_t length);
|
||||
|
||||
virtual void Reset();
|
||||
|
||||
virtual status_t Receive(struct mbuf *packet, uint8 code) = 0;
|
||||
|
||||
virtual void Pulse();
|
||||
|
||||
private:
|
||||
char fName[PPP_HANDLER_NAME_LENGTH_LIMIT + 1];
|
||||
PPPInterface& fInterface;
|
||||
driver_parameter *fSettings;
|
||||
uint8 fCode;
|
||||
|
||||
bool fEnabled;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
@ -8,8 +8,6 @@
|
||||
#ifndef _K_PPP_OPTION_HANDLER__H
|
||||
#define _K_PPP_OPTION_HANDLER__H
|
||||
|
||||
#include <driver_settings.h>
|
||||
|
||||
#include <KPPPDefs.h>
|
||||
|
||||
#ifndef _K_PPP_INTERFACE__H
|
||||
@ -35,7 +33,8 @@ class PPPOptionHandler {
|
||||
driver_parameter *Settings() const
|
||||
{ return fSettings; }
|
||||
|
||||
void SetEnabled(bool enabled = true);
|
||||
void SetEnabled(bool enabled = true)
|
||||
{ fEnabled = enabled; }
|
||||
bool IsEnabled() const
|
||||
{ return fEnabled; }
|
||||
|
||||
|
@ -1,21 +0,0 @@
|
||||
//----------------------------------------------------------------------
|
||||
// This software is part of the OpenBeOS distribution and is covered
|
||||
// by the OpenBeOS license.
|
||||
//
|
||||
// Copyright (c) 2003 Waldemar Kornewald, Waldemar.Kornewald@web.de
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
#ifndef _K_PPP_REPORT_DEFS__H
|
||||
#define _K_PPP_REPORT_DEFS__H
|
||||
|
||||
#include <PPPReportDefs.h>
|
||||
|
||||
|
||||
typedef struct ppp_report_request {
|
||||
thread_id thread;
|
||||
int32 type;
|
||||
int32 flags;
|
||||
} ppp_report_request;
|
||||
|
||||
|
||||
#endif
|
@ -10,7 +10,8 @@
|
||||
|
||||
#include <OS.h>
|
||||
|
||||
#include <KPPPReportDefs.h>
|
||||
#include <KPPPDefs.h>
|
||||
#include <PPPReportDefs.h>
|
||||
|
||||
#include <List.h>
|
||||
|
||||
@ -23,7 +24,7 @@ class PPPReportManager {
|
||||
~PPPReportManager();
|
||||
|
||||
void EnableReports(PPP_REPORT_TYPE type, thread_id thread,
|
||||
int32 flags = PPP_NO_REPORT_FLAGS);
|
||||
int32 flags = PPP_NO_FLAGS);
|
||||
void DisableReports(PPP_REPORT_TYPE type, thread_id thread);
|
||||
bool DoesReport(PPP_REPORT_TYPE type, thread_id thread);
|
||||
bool Report(PPP_REPORT_TYPE type, int32 code, void *data, int32 length);
|
||||
|
@ -11,7 +11,6 @@
|
||||
#include <KPPPDefs.h>
|
||||
|
||||
class PPPEncapsulator;
|
||||
class PPPInterface;
|
||||
class PPPProtocol;
|
||||
|
||||
#ifndef _K_PPP_INTERFACE__H
|
||||
@ -106,7 +105,8 @@ class PPPStateMachine {
|
||||
void RCNEvent(struct mbuf *packet);
|
||||
void RTREvent(struct mbuf *packet);
|
||||
void RTAEvent(struct mbuf *packet);
|
||||
void RUCEvent(struct mbuf *packet, uint16 protocol, uint8 type = PPP_PROTOCOL_REJECT);
|
||||
void RUCEvent(struct mbuf *packet, uint16 protocol,
|
||||
uint8 code = PPP_PROTOCOL_REJECT);
|
||||
void RXJGoodEvent(struct mbuf *packet);
|
||||
void RXJBadEvent(struct mbuf *packet);
|
||||
void RXREvent(struct mbuf *packet);
|
||||
@ -128,8 +128,8 @@ class PPPStateMachine {
|
||||
void SendConfigureAck(struct mbuf *packet);
|
||||
void SendConfigureNak(struct mbuf *packet);
|
||||
void SendTerminateRequest();
|
||||
void SendTerminateAck(struct mbuf *request);
|
||||
void SendCodeReject(struct mbuf *packet, uint16 protocol, uint8 type);
|
||||
void SendTerminateAck(struct mbuf *request = NULL);
|
||||
void SendCodeReject(struct mbuf *packet, uint16 protocol, uint8 code);
|
||||
void SendEchoReply(struct mbuf *request);
|
||||
|
||||
void BringHandlersUp();
|
||||
|
@ -22,7 +22,6 @@
|
||||
#define PPP_OPTION_HANDLER_OPS_START PPP_OPS_START + 5 * PPP_RESERVE_OPS_COUNT
|
||||
#define PPP_LCP_EXTENSION_OPS_START PPP_OPS_START + 6 * PPP_RESERVE_OPS_COUNT
|
||||
#define PPP_COMMON_OPS_START PPP_OPS_START + 10 * PPP_RESERVE_OPS_COUNT
|
||||
#define PPP_COMMON_PROTO_ENCAPS_OPS_START PPP_OPS_START + 11 * PPP_RESERVE_OPS_COUNT
|
||||
#define PPP_USER_OPS_START PPP_OPS_START + 32 * PPP_RESERVE_OPS_COUNT
|
||||
|
||||
|
||||
@ -34,6 +33,11 @@ enum PPP_CONTROL_OPS {
|
||||
PPPC_SET_DIAL_ON_DEMAND,
|
||||
PPPC_SET_AUTO_REDIAL,
|
||||
|
||||
// these control ops use the ppp_report_request structure
|
||||
PPPC_ENABLE_INTERFACE_REPORTS,
|
||||
PPPC_DISABLE_INTERFACE_REPORTS,
|
||||
// flags are not used for this control op
|
||||
|
||||
// handler access
|
||||
PPPC_CONTROL_DEVICE,
|
||||
PPPC_CONTROL_PROTOCOL,
|
||||
@ -49,31 +53,13 @@ enum PPP_CONTROL_OPS {
|
||||
PPPC_SET_MTU,
|
||||
// -----------------------------------------------------
|
||||
|
||||
// -----------------------------------------------------
|
||||
// PPPProtocol
|
||||
// -----------------------------------------------------
|
||||
|
||||
// -----------------------------------------------------
|
||||
// PPPEncapsulator
|
||||
// -----------------------------------------------------
|
||||
|
||||
// -----------------------------------------------------
|
||||
// PPPOptionHandler
|
||||
PPPC_GET_OPTION_HANDLER_INFO = PPP_OPTION_HANDLER_OPS_START,
|
||||
// -----------------------------------------------------
|
||||
|
||||
// -----------------------------------------------------
|
||||
// PPPLCPExtension
|
||||
// -----------------------------------------------------
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Common/mixed ops
|
||||
PPPC_GET_HANDLER_INFO = PPP_COMMON_OPS_START,
|
||||
// PPPProtocol and PPPEncapsulator
|
||||
PPPC_SET_ENABLED,
|
||||
// -----------------------------------------------------
|
||||
|
||||
// -----------------------------------------------------
|
||||
// PPPProtocol and PPPEncapsulator
|
||||
PPPC_GET_SIMPLE_HANDLER_INFO,
|
||||
// PPPOptionHandler and PPPLCPExtension
|
||||
// -----------------------------------------------------
|
||||
|
||||
PPP_CONTROL_OPS_END = B_DEVICE_OP_CODES_END + 0xFFFF
|
||||
@ -166,17 +152,19 @@ typedef struct ppp_handler_info_t {
|
||||
} ppp_handler_info_t;
|
||||
|
||||
|
||||
typedef struct ppp_option_handler_info {
|
||||
typedef struct ppp_simple_handler_info {
|
||||
char name[PPP_HANDLER_NAME_LENGTH_LIMIT + 1];
|
||||
|
||||
const driver_parameter *settings;
|
||||
|
||||
bool isEnabled;
|
||||
} ppp_option_handler_info;
|
||||
typedef struct ppp_option_handler_info_t {
|
||||
ppp_option_handler_info info;
|
||||
uint8 _reserved_[_PPP_INFO_T_SIZE_ - sizeof(ppp_option_handler_info)];
|
||||
} ppp_option_handler_info_t;
|
||||
|
||||
uint8 code;
|
||||
// only PPPLCPExtension
|
||||
} ppp_simple_handler_info;
|
||||
typedef struct ppp_simple_handler_info_t {
|
||||
ppp_simple_handler_info info;
|
||||
uint8 _reserved_[_PPP_INFO_T_SIZE_ - sizeof(ppp_simple_handler_info)];
|
||||
} ppp_simple_handler_info_t;
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -8,7 +8,7 @@
|
||||
#ifndef _PPP_DEFS__H
|
||||
#define _PPP_DEFS__H
|
||||
|
||||
#include <Errors.h>
|
||||
#include <SupportDefs.h>
|
||||
|
||||
|
||||
// various constants
|
||||
|
@ -18,7 +18,6 @@
|
||||
|
||||
// report flags
|
||||
enum PPP_REPORT_FLAGS {
|
||||
PPP_NO_REPORT_FLAGS = 0,
|
||||
PPP_WAIT_FOR_REPLY = 0x1,
|
||||
PPP_REMOVE_AFTER_REPORT = 0x2,
|
||||
PPP_NO_REPLY_TIMEOUT = 0x4
|
||||
@ -27,8 +26,11 @@ enum PPP_REPORT_FLAGS {
|
||||
// report types
|
||||
// the first 16 report types are reserved for the interface manager
|
||||
enum PPP_REPORT_TYPE {
|
||||
PPP_ALL_REPORTS = -1,
|
||||
// used only when disabling reports
|
||||
PPP_DESTRUCTION_REPORT = 16,
|
||||
// the interface is being destroyed (no code is needed)
|
||||
// this report is sent even if it was not requested
|
||||
PPP_CONNECTION_REPORT = 17
|
||||
};
|
||||
|
||||
@ -54,4 +56,11 @@ typedef struct ppp_report_packet {
|
||||
} ppp_report_packet;
|
||||
|
||||
|
||||
typedef struct ppp_report_request {
|
||||
PPP_REPORT_TYPE type;
|
||||
thread_id thread;
|
||||
int32 flags;
|
||||
} ppp_report_request;
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -13,6 +13,7 @@ R5KernelStaticLibrary kernelppp :
|
||||
KPPPEncapsulator.cpp
|
||||
KPPPInterface.cpp
|
||||
KPPPLCP.cpp
|
||||
KPPPLCPExtension.cpp
|
||||
KPPPOptionHandler.cpp
|
||||
KPPPProtocol.cpp
|
||||
KPPPReportManager.cpp
|
||||
|
@ -15,7 +15,7 @@
|
||||
|
||||
PPPDevice::PPPDevice(const char *name, PPPInterface& interface,
|
||||
driver_parameter *settings)
|
||||
: fInterface(interface), fSettings(settings), fMTU(1500)
|
||||
: fMTU(1500), fIsUp(false), fInterface(interface), fSettings(settings)
|
||||
{
|
||||
if(name) {
|
||||
strncpy(fName, name, PPP_HANDLER_NAME_LENGTH_LIMIT);
|
||||
|
@ -283,6 +283,23 @@ PPPInterface::Control(uint32 op, void *data, size_t length)
|
||||
SetAutoRedial(*((uint32*)data));
|
||||
break;
|
||||
|
||||
case PPPC_ENABLE_INTERFACE_REPORTS: {
|
||||
if(length < sizeof(ppp_report_request) || !data)
|
||||
return B_ERROR;
|
||||
|
||||
ppp_report_request *request = (ppp_report_request*) data;
|
||||
ReportManager().EnableReports(request->type, request->thread,
|
||||
request->flags);
|
||||
} break;
|
||||
|
||||
case PPPC_DISABLE_INTERFACE_REPORTS: {
|
||||
if(length < sizeof(ppp_report_request) || !data)
|
||||
return B_ERROR;
|
||||
|
||||
ppp_report_request *request = (ppp_report_request*) data;
|
||||
ReportManager().DisableReports(request->type, request->thread);
|
||||
} break;
|
||||
|
||||
case PPPC_CONTROL_DEVICE: {
|
||||
if(length < sizeof(ppp_control_info) || !data)
|
||||
return B_ERROR;
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <KPPPInterface.h>
|
||||
#include <KPPPDevice.h>
|
||||
#include <KPPPEncapsulator.h>
|
||||
#include <KPPPLCPExtension.h>
|
||||
#include <KPPPOptionHandler.h>
|
||||
|
||||
#include <LockerHelper.h>
|
||||
@ -19,9 +20,6 @@
|
||||
|
||||
#define PPP_PROTOCOL_OVERHEAD 2
|
||||
|
||||
// TODO:
|
||||
// - add LCP extension handlers
|
||||
|
||||
|
||||
PPPLCP::PPPLCP(PPPInterface& interface)
|
||||
: PPPProtocol("LCP", PPP_ESTABLISHMENT_PHASE, PPP_LCP_PROTOCOL,
|
||||
@ -80,6 +78,48 @@ PPPLCP::OptionHandlerAt(int32 index) const
|
||||
return handler;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PPPLCP::AddLCPExtension(PPPLCPExtension *extension)
|
||||
{
|
||||
if(!extension)
|
||||
return false;
|
||||
|
||||
LockerHelper locker(StateMachine().Locker());
|
||||
|
||||
if(Phase() != PPP_DOWN_PHASE)
|
||||
return false;
|
||||
// a running connection may not change
|
||||
|
||||
return fLCPExtensions.AddItem(extension);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PPPLCP::RemoveLCPExtension(PPPLCPExtension *extension)
|
||||
{
|
||||
LockerHelper locker(StateMachine().Locker());
|
||||
|
||||
if(Phase() != PPP_DOWN_PHASE)
|
||||
return false;
|
||||
// a running connection may not change
|
||||
|
||||
return fLCPExtensions.RemoveItem(extension);
|
||||
}
|
||||
|
||||
|
||||
PPPLCPExtension*
|
||||
PPPLCP::LCPExtensionAt(int32 index) const
|
||||
{
|
||||
PPPLCPExtension *extension = fLCPExtensions.ItemAt(index);
|
||||
|
||||
if(extension == fLCPExtensions.GetDefaultItem())
|
||||
return NULL;
|
||||
|
||||
return extension;
|
||||
}
|
||||
|
||||
|
||||
uint32
|
||||
PPPLCP::AdditionalOverhead() const
|
||||
{
|
||||
@ -163,11 +203,28 @@ PPPLCP::Receive(struct mbuf *packet, uint16 protocol)
|
||||
|
||||
case PPP_ECHO_REPLY:
|
||||
case PPP_DISCARD_REQUEST:
|
||||
m_freem(packet);
|
||||
// do nothing
|
||||
break;
|
||||
|
||||
default:
|
||||
StateMachine().RUCEvent(packet, PPP_LCP_PROTOCOL, PPP_CODE_REJECT);
|
||||
default: {
|
||||
status_t result = PPP_UNHANDLED;
|
||||
|
||||
// try to find LCP extensions that can handle this code
|
||||
PPPLCPExtension *extension;
|
||||
for(int32 index = 0; index < CountLCPExtensions(); index++) {
|
||||
extension = LCPExtensionAt(index);
|
||||
if(extension->IsEnabled() && extension->Code() == data->code)
|
||||
result = extension->Receive(packet, data->code);
|
||||
}
|
||||
|
||||
if(result == PPP_UNHANDLED) {
|
||||
StateMachine().RUCEvent(packet, PPP_LCP_PROTOCOL, PPP_CODE_REJECT);
|
||||
return PPP_REJECTED;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
@ -178,4 +235,7 @@ void
|
||||
PPPLCP::Pulse()
|
||||
{
|
||||
StateMachine().TimerEvent();
|
||||
|
||||
for(int32 index = 0; index < CountLCPExtensions(); index++)
|
||||
LCPExtensionAt(index)->Pulse();
|
||||
}
|
||||
|
84
src/tests/kits/net/ppp/src/KPPPLCPExtension.cpp
Normal file
84
src/tests/kits/net/ppp/src/KPPPLCPExtension.cpp
Normal file
@ -0,0 +1,84 @@
|
||||
//----------------------------------------------------------------------
|
||||
// This software is part of the OpenBeOS distribution and is covered
|
||||
// by the OpenBeOS license.
|
||||
//
|
||||
// Copyright (c) 2003 Waldemar Kornewald, Waldemar.Kornewald@web.de
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
#include <KPPPLCPExtension.h>
|
||||
|
||||
#include <PPPControl.h>
|
||||
|
||||
|
||||
PPPLCPExtension::PPPLCPExtension(const char *name, uint8 code, PPPInterface& interface,
|
||||
driver_parameter *settings)
|
||||
: fInterface(interface), fSettings(settings), fCode(code), fEnabled(true)
|
||||
{
|
||||
if(name) {
|
||||
strncpy(fName, name, PPP_HANDLER_NAME_LENGTH_LIMIT);
|
||||
fName[PPP_HANDLER_NAME_LENGTH_LIMIT] = 0;
|
||||
} else
|
||||
strcpy(fName, "???");
|
||||
|
||||
interface.LCP().AddLCPExtension(this);
|
||||
}
|
||||
|
||||
|
||||
PPPLCPExtension::~PPPLCPExtension()
|
||||
{
|
||||
Interface().LCP().RemoveLCPExtension(this);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
PPPLCPExtension::InitCheck() const
|
||||
{
|
||||
if(!Settings())
|
||||
return B_ERROR;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
PPPLCPExtension::Control(uint32 op, void *data, size_t length)
|
||||
{
|
||||
switch(op) {
|
||||
case PPPC_GET_SIMPLE_HANDLER_INFO: {
|
||||
if(length < sizeof(ppp_simple_handler_info_t) || !data)
|
||||
return B_ERROR;
|
||||
|
||||
ppp_simple_handler_info *info = (ppp_simple_handler_info*) data;
|
||||
memset(info, 0, sizeof(ppp_simple_handler_info_t));
|
||||
strcpy(info->name, Name());
|
||||
info->settings = Settings();
|
||||
info->isEnabled = IsEnabled();
|
||||
} break;
|
||||
|
||||
case PPPC_SET_ENABLED:
|
||||
if(length < sizeof(uint32) || !data)
|
||||
return B_ERROR;
|
||||
|
||||
SetEnabled(*((uint32*)data));
|
||||
break;
|
||||
|
||||
default:
|
||||
return PPP_UNHANDLED;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPLCPExtension::Reset()
|
||||
{
|
||||
// do nothing by default
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPLCPExtension::Pulse()
|
||||
{
|
||||
// do nothing by default
|
||||
}
|
@ -12,7 +12,7 @@
|
||||
|
||||
PPPOptionHandler::PPPOptionHandler(const char *name, PPPInterface& interface,
|
||||
driver_parameter *settings)
|
||||
: fInterface(interface), fSettings(settings)
|
||||
: fInterface(interface), fSettings(settings), fEnabled(true)
|
||||
{
|
||||
if(name) {
|
||||
strncpy(fName, name, PPP_HANDLER_NAME_LENGTH_LIMIT);
|
||||
@ -44,12 +44,12 @@ status_t
|
||||
PPPOptionHandler::Control(uint32 op, void *data, size_t length)
|
||||
{
|
||||
switch(op) {
|
||||
case PPPC_GET_OPTION_HANDLER_INFO: {
|
||||
if(length < sizeof(ppp_option_handler_info) || !data)
|
||||
case PPPC_GET_SIMPLE_HANDLER_INFO: {
|
||||
if(length < sizeof(ppp_simple_handler_info_t) || !data)
|
||||
return B_ERROR;
|
||||
|
||||
ppp_option_handler_info *info = (ppp_option_handler_info*) data;
|
||||
memset(info, 0, sizeof(ppp_option_handler_info));
|
||||
ppp_simple_handler_info *info = (ppp_simple_handler_info*) data;
|
||||
memset(info, 0, sizeof(ppp_simple_handler_info_t));
|
||||
strcpy(info->name, Name());
|
||||
info->settings = Settings();
|
||||
info->isEnabled = IsEnabled();
|
||||
|
@ -28,7 +28,7 @@ PPPReportManager::~PPPReportManager()
|
||||
|
||||
void
|
||||
PPPReportManager::EnableReports(PPP_REPORT_TYPE type, thread_id thread,
|
||||
int32 flags = PPP_NO_REPORT_FLAGS)
|
||||
int32 flags = PPP_NO_FLAGS)
|
||||
{
|
||||
LockerHelper locker(fLock);
|
||||
|
||||
@ -54,7 +54,7 @@ PPPReportManager::DisableReports(PPP_REPORT_TYPE type, thread_id thread)
|
||||
if(request->thread != thread)
|
||||
continue;
|
||||
|
||||
if(request->type == type)
|
||||
if(request->type == type || request->type == PPP_ALL_REPORTS)
|
||||
fReportRequests.RemoveItem(request);
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <KPPPConfigurePacket.h>
|
||||
#include <KPPPDevice.h>
|
||||
#include <KPPPEncapsulator.h>
|
||||
#include <KPPPLCPExtension.h>
|
||||
#include <KPPPOptionHandler.h>
|
||||
|
||||
#include <net/if.h>
|
||||
@ -701,16 +702,19 @@ PPPStateMachine::RCRGoodEvent(struct mbuf *packet)
|
||||
case PPP_INITIAL_STATE:
|
||||
case PPP_STARTING_STATE:
|
||||
IllegalEvent(PPP_RCR_GOOD_EVENT);
|
||||
m_freem(packet);
|
||||
break;
|
||||
|
||||
case PPP_CLOSED_STATE:
|
||||
locker.UnlockNow();
|
||||
SendTerminateAck(packet);
|
||||
SendTerminateAck();
|
||||
m_freem(packet);
|
||||
break;
|
||||
|
||||
case PPP_STOPPED_STATE:
|
||||
// irc,scr,sca/8
|
||||
// XXX: should we do nothing and wait for DownEvent()?
|
||||
m_freem(packet);
|
||||
break;
|
||||
|
||||
case PPP_REQ_SENT_STATE:
|
||||
@ -740,7 +744,7 @@ PPPStateMachine::RCRGoodEvent(struct mbuf *packet)
|
||||
break;
|
||||
|
||||
default:
|
||||
;
|
||||
m_freem(packet);
|
||||
}
|
||||
}
|
||||
|
||||
@ -759,7 +763,7 @@ PPPStateMachine::RCRBadEvent(struct mbuf *nak, struct mbuf *reject)
|
||||
|
||||
case PPP_CLOSED_STATE:
|
||||
locker.UnlockNow();
|
||||
SendTerminateAck(NULL);
|
||||
SendTerminateAck();
|
||||
break;
|
||||
|
||||
case PPP_STOPPED_STATE:
|
||||
@ -787,11 +791,17 @@ PPPStateMachine::RCRBadEvent(struct mbuf *nak, struct mbuf *reject)
|
||||
SendConfigureNak(nak);
|
||||
else if(reject && ntohs(mtod(reject, ppp_lcp_packet*)->length) > 3)
|
||||
SendConfigureNak(reject);
|
||||
break;
|
||||
return;
|
||||
// prevents the nak/reject from being m_freem()'d
|
||||
|
||||
default:
|
||||
;
|
||||
}
|
||||
|
||||
if(nak)
|
||||
m_freem(nak);
|
||||
if(reject)
|
||||
m_freem(reject);
|
||||
}
|
||||
|
||||
|
||||
@ -806,12 +816,13 @@ PPPStateMachine::RCAEvent(struct mbuf *packet)
|
||||
|
||||
// TODO:
|
||||
// log this event
|
||||
m_freem(packet);
|
||||
return;
|
||||
}
|
||||
|
||||
PPPOptionHandler *handler;
|
||||
// let the option handlers parse this ack
|
||||
PPPConfigurePacket ack(packet);
|
||||
|
||||
PPPOptionHandler *handler;
|
||||
for(int32 index = 0; index < LCP().CountOptionHandlers(); index++) {
|
||||
handler = LCP().OptionHandlerAt(index);
|
||||
handler->ParseAck(&ack);
|
||||
@ -826,7 +837,7 @@ PPPStateMachine::RCAEvent(struct mbuf *packet)
|
||||
case PPP_CLOSED_STATE:
|
||||
case PPP_STOPPED_STATE:
|
||||
locker.UnlockNow();
|
||||
SendTerminateAck(NULL);
|
||||
SendTerminateAck();
|
||||
break;
|
||||
|
||||
case PPP_REQ_SENT_STATE:
|
||||
@ -859,6 +870,8 @@ PPPStateMachine::RCAEvent(struct mbuf *packet)
|
||||
default:
|
||||
;
|
||||
}
|
||||
|
||||
m_freem(packet);
|
||||
}
|
||||
|
||||
|
||||
@ -873,12 +886,13 @@ PPPStateMachine::RCNEvent(struct mbuf *packet)
|
||||
|
||||
// TODO:
|
||||
// log this event
|
||||
m_freem(packet);
|
||||
return;
|
||||
}
|
||||
|
||||
PPPOptionHandler *handler;
|
||||
// let the option handlers parse this nak/reject
|
||||
PPPConfigurePacket nak_reject(packet);
|
||||
|
||||
PPPOptionHandler *handler;
|
||||
for(int32 index = 0; index < LCP().CountOptionHandlers(); index++) {
|
||||
handler = LCP().OptionHandlerAt(index);
|
||||
|
||||
@ -897,7 +911,7 @@ PPPStateMachine::RCNEvent(struct mbuf *packet)
|
||||
case PPP_CLOSED_STATE:
|
||||
case PPP_STOPPED_STATE:
|
||||
locker.UnlockNow();
|
||||
SendTerminateAck(packet);
|
||||
SendTerminateAck();
|
||||
break;
|
||||
|
||||
case PPP_REQ_SENT_STATE:
|
||||
@ -923,6 +937,8 @@ PPPStateMachine::RCNEvent(struct mbuf *packet)
|
||||
default:
|
||||
;
|
||||
}
|
||||
|
||||
m_freem(packet);
|
||||
}
|
||||
|
||||
|
||||
@ -943,6 +959,7 @@ PPPStateMachine::RTREvent(struct mbuf *packet)
|
||||
case PPP_INITIAL_STATE:
|
||||
case PPP_STARTING_STATE:
|
||||
IllegalEvent(PPP_RTR_EVENT);
|
||||
m_freem(packet);
|
||||
break;
|
||||
|
||||
case PPP_ACK_RCVD_STATE:
|
||||
@ -984,6 +1001,7 @@ PPPStateMachine::RTAEvent(struct mbuf *packet)
|
||||
|
||||
// TODO:
|
||||
// log this event
|
||||
m_freem(packet);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1019,12 +1037,15 @@ PPPStateMachine::RTAEvent(struct mbuf *packet)
|
||||
default:
|
||||
;
|
||||
}
|
||||
|
||||
m_freem(packet);
|
||||
}
|
||||
|
||||
|
||||
// receive unknown code
|
||||
void
|
||||
PPPStateMachine::RUCEvent(struct mbuf *packet, uint16 protocol, uint8 type = PPP_PROTOCOL_REJECT)
|
||||
PPPStateMachine::RUCEvent(struct mbuf *packet, uint16 protocol,
|
||||
uint8 code = PPP_PROTOCOL_REJECT)
|
||||
{
|
||||
LockerHelper locker(fLock);
|
||||
|
||||
@ -1032,11 +1053,12 @@ PPPStateMachine::RUCEvent(struct mbuf *packet, uint16 protocol, uint8 type = PPP
|
||||
case PPP_INITIAL_STATE:
|
||||
case PPP_STARTING_STATE:
|
||||
IllegalEvent(PPP_RUC_EVENT);
|
||||
m_freem(packet);
|
||||
break;
|
||||
|
||||
default:
|
||||
locker.UnlockNow();
|
||||
SendCodeReject(packet, protocol, type);
|
||||
SendCodeReject(packet, protocol, code);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1102,6 +1124,8 @@ PPPStateMachine::RXJBadEvent(struct mbuf *packet)
|
||||
SendTerminateRequest();
|
||||
break;
|
||||
}
|
||||
|
||||
m_freem(packet);
|
||||
}
|
||||
|
||||
|
||||
@ -1120,11 +1144,13 @@ PPPStateMachine::RXREvent(struct mbuf *packet)
|
||||
case PPP_OPENED_STATE:
|
||||
if(echo->code == PPP_ECHO_REQUEST)
|
||||
SendEchoReply(packet);
|
||||
break;
|
||||
return;
|
||||
|
||||
default:
|
||||
;
|
||||
}
|
||||
|
||||
m_freem(packet);
|
||||
}
|
||||
|
||||
|
||||
@ -1199,6 +1225,7 @@ PPPStateMachine::RCREvent(struct mbuf *packet)
|
||||
else if(error == B_ERROR) {
|
||||
// the request contains a value that has been sent more than
|
||||
// once or the value is corrupted
|
||||
m_freem(packet);
|
||||
CloseEvent();
|
||||
return;
|
||||
} else if(error == B_OK)
|
||||
@ -1226,14 +1253,34 @@ PPPStateMachine::RCREvent(struct mbuf *packet)
|
||||
void
|
||||
PPPStateMachine::RXJEvent(struct mbuf *packet)
|
||||
{
|
||||
ppp_lcp_packet *reject mtod(packet, ppp_lcp_packet*);
|
||||
ppp_lcp_packet *reject = mtod(packet, ppp_lcp_packet*);
|
||||
|
||||
if(reject->code == PPP_CODE_REJECT) {
|
||||
// we only have basic codes, so there must be something wrong
|
||||
if(Interface()->IsMultilink() && !Interface()->Parent())
|
||||
CloseEvent();
|
||||
else
|
||||
RXJBadEvent(packet);
|
||||
uint8 rejectedCode = reject->data[0];
|
||||
|
||||
// test if the rejected code belongs to the minimum LCP requirements
|
||||
if(rejectedCode >= PPP_MIN_LCP_CODE && rejectedCode <= PPP_MAX_LCP_CODE) {
|
||||
if(Interface()->IsMultilink() && !Interface()->Parent()) {
|
||||
// Main interfaces do not have states between STARTING and OPENED.
|
||||
// An RXJBadEvent() would enter one of those states which is bad.
|
||||
m_freem(packet);
|
||||
CloseEvent();
|
||||
} else
|
||||
RXJBadEvent(packet);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// find the LCP extension and disable it
|
||||
PPPLCPExtension *extension;
|
||||
for(int32 index = 0; index < LCP().CountLCPExtensions(); index++) {
|
||||
extension = LCP().LCPExtensionAt(index);
|
||||
|
||||
if(extension->Code() == rejectedCode)
|
||||
extension->SetEnabled(false);
|
||||
}
|
||||
|
||||
m_freem(packet);
|
||||
} else if(reject->code == PPP_PROTOCOL_REJECT) {
|
||||
// disable all handlers for rejected protocol type
|
||||
uint16 rejected = *((uint16*) reject->data);
|
||||
@ -1245,6 +1292,7 @@ PPPStateMachine::RXJEvent(struct mbuf *packet)
|
||||
return;
|
||||
}
|
||||
|
||||
// disable protocols and encapsulators with the rejected protocl number
|
||||
int32 index;
|
||||
PPPProtocol *protocol_handler;
|
||||
PPPEncapsulator *encapsulator_handler = Interface()->FirstEncapsulator();
|
||||
@ -1264,10 +1312,13 @@ PPPStateMachine::RXJEvent(struct mbuf *packet)
|
||||
}
|
||||
|
||||
RXJGoodEvent(packet);
|
||||
// this event handler does not m_freem(packet)!!!
|
||||
|
||||
// notify parent, too
|
||||
if(Interface()->Parent())
|
||||
Interface()->Parent()->StateMachine().RXJEvent(packet);
|
||||
else
|
||||
m_freem(packet);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1374,9 +1425,13 @@ PPPStateMachine::SendConfigureRequest()
|
||||
void
|
||||
PPPStateMachine::SendConfigureAck(struct mbuf *packet)
|
||||
{
|
||||
if(!packet)
|
||||
return;
|
||||
|
||||
mtod(packet, ppp_lcp_packet*)->code = PPP_CONFIGURE_ACK;
|
||||
PPPConfigurePacket ack(packet);
|
||||
|
||||
// notify all option handlers that we are sending an ack for each value
|
||||
for(int32 index = 0; index < LCP().CountOptionHandlers(); index++)
|
||||
LCP().OptionHandlerAt(index)->SendingAck(&ack);
|
||||
|
||||
@ -1387,6 +1442,9 @@ PPPStateMachine::SendConfigureAck(struct mbuf *packet)
|
||||
void
|
||||
PPPStateMachine::SendConfigureNak(struct mbuf *packet)
|
||||
{
|
||||
if(!packet)
|
||||
return;
|
||||
|
||||
ppp_lcp_packet *nak = mtod(packet, ppp_lcp_packet*);
|
||||
if(nak->code == PPP_CONFIGURE_NAK) {
|
||||
if(fNakCounter == 0) {
|
||||
@ -1424,7 +1482,7 @@ PPPStateMachine::SendTerminateRequest()
|
||||
|
||||
|
||||
void
|
||||
PPPStateMachine::SendTerminateAck(struct mbuf *request)
|
||||
PPPStateMachine::SendTerminateAck(struct mbuf *request = NULL)
|
||||
{
|
||||
struct mbuf *reply = request;
|
||||
|
||||
@ -1440,26 +1498,32 @@ PPPStateMachine::SendTerminateAck(struct mbuf *request)
|
||||
|
||||
ack = mtod(reply, ppp_lcp_packet*);
|
||||
ack->id = NextID();
|
||||
ack->length = 4;
|
||||
}
|
||||
|
||||
ack = mtod(reply, ppp_lcp_packet*);
|
||||
ack->code = PPP_TERMINATE_ACK;
|
||||
ack->length = 4;
|
||||
|
||||
LCP().Send(reply);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPStateMachine::SendCodeReject(struct mbuf *packet, uint16 protocol, uint8 type)
|
||||
PPPStateMachine::SendCodeReject(struct mbuf *packet, uint16 protocol, uint8 code)
|
||||
{
|
||||
if(!packet)
|
||||
return;
|
||||
|
||||
int32 length;
|
||||
// additional space needed for this reject
|
||||
if(type == PPP_PROTOCOL_REJECT)
|
||||
if(code == PPP_PROTOCOL_REJECT)
|
||||
length = 6;
|
||||
else
|
||||
length = 4;
|
||||
|
||||
M_PREPEND(packet, length);
|
||||
// add some space for the header
|
||||
|
||||
int32 adjust = 0;
|
||||
// adjust packet size by this value if packet is too big
|
||||
if(packet->m_flags & M_PKTHDR) {
|
||||
@ -1472,7 +1536,7 @@ PPPStateMachine::SendCodeReject(struct mbuf *packet, uint16 protocol, uint8 type
|
||||
m_adj(packet, adjust);
|
||||
|
||||
ppp_lcp_packet *reject = mtod(packet, ppp_lcp_packet*);
|
||||
reject->code = type;
|
||||
reject->code = code;
|
||||
reject->id = NextID();
|
||||
if(packet->m_flags & M_PKTHDR)
|
||||
reject->length = htons(packet->m_pkthdr.len);
|
||||
@ -1480,7 +1544,7 @@ PPPStateMachine::SendCodeReject(struct mbuf *packet, uint16 protocol, uint8 type
|
||||
reject->length = htons(packet->m_len);
|
||||
|
||||
protocol = htons(protocol);
|
||||
if(type == PPP_PROTOCOL_REJECT)
|
||||
if(code == PPP_PROTOCOL_REJECT)
|
||||
memcpy(&reject->data, &protocol, sizeof(protocol));
|
||||
|
||||
LCP().Send(packet);
|
||||
@ -1490,6 +1554,9 @@ PPPStateMachine::SendCodeReject(struct mbuf *packet, uint16 protocol, uint8 type
|
||||
void
|
||||
PPPStateMachine::SendEchoReply(struct mbuf *request)
|
||||
{
|
||||
if(!request)
|
||||
return;
|
||||
|
||||
ppp_lcp_packet *reply = mtod(request, ppp_lcp_packet*);
|
||||
reply->code = PPP_ECHO_REPLY;
|
||||
// the request becomes a reply
|
||||
@ -1589,4 +1656,7 @@ PPPStateMachine::ResetOptionHandlers()
|
||||
{
|
||||
for(int32 index = 0; index < LCP().CountOptionHandlers(); index++)
|
||||
LCP().OptionHandlerAt(index)->Reset();
|
||||
|
||||
for(int32 index = 0; index < LCP().CountLCPExtensions(); index++)
|
||||
LCP().LCPExtensionAt(index)->Reset();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user