Moved libkernelppp.a to add-ons/kernel/network/ppp/shared.

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@4788 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Waldemar Kornewald 2003-09-22 13:21:38 +00:00
parent e336671a9b
commit de2f76e1fe
44 changed files with 7856 additions and 2 deletions

View File

@ -3,4 +3,4 @@ SubDir OBOS_TOP src add-ons kernel network ;
SubInclude OBOS_TOP src add-ons kernel network core ;
SubInclude OBOS_TOP src add-ons kernel network interfaces ;
SubInclude OBOS_TOP src add-ons kernel network protocols ;
SubInclude OBOS_TOP src add-ons kernel network ppp ;

View File

@ -2,4 +2,4 @@ SubDir OBOS_TOP src add-ons kernel network interfaces ;
SubInclude OBOS_TOP src add-ons kernel network interfaces ethernet ;
SubInclude OBOS_TOP src add-ons kernel network interfaces loopback ;
SubInclude OBOS_TOP src add-ons kernel network interfaces ppp ;

View File

@ -0,0 +1,3 @@
SubDir OBOS_TOP src add-ons kernel network ppp ;
SubInclude OBOS_TOP src add-ons kernel network ppp shared ;

View File

@ -0,0 +1,3 @@
SubDir OBOS_TOP src add-ons kernel network ppp shared ;
SubInclude OBOS_TOP src add-ons kernel network ppp shared libkernelppp ;

View File

@ -0,0 +1,31 @@
SubDir OBOS_TOP src add-ons kernel network ppp shared libkernelppp ;
# for cpp.cpp and BLocker
SEARCH_SOURCE += [ FDirName $(OBOS_TOP) src add-ons kernel file_systems bfs ] ;
SEARCH_SOURCE += [ FDirName $(OBOS_TOP) src kernel core disk_device_manager ] ;
UseHeaders [ FDirName $(OBOS_TOP) src add-ons kernel file_systems bfs ] ;
UsePrivateHeaders net ;
UseHeaders [ FDirName $(OBOS_TOP) src add-ons kernel network ppp shared libkernelppp headers ] ;
R5KernelStaticLibrary kernelppp :
KPPPConfigurePacket.cpp
KPPPDevice.cpp
KPPPEncapsulator.cpp
KPPPInterface.cpp
KPPPLCP.cpp
KPPPLCPExtension.cpp
KPPPOptionHandler.cpp
KPPPProtocol.cpp
KPPPReportManager.cpp
KPPPStateMachine.cpp
KPPPUtils.cpp
Locker.cpp
settings_tools.cpp
cpp.cpp
# integrated modules
_KPPPMRUHandler.cpp
_KPPPAuthenticationHandler.cpp
_KPPPPFCHandler.cpp
;

View File

@ -0,0 +1,154 @@
//----------------------------------------------------------------------
// 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 <KPPPConfigurePacket.h>
#include <KPPPInterface.h>
PPPConfigurePacket::PPPConfigurePacket(uint8 code)
: fCode(code)
{
}
PPPConfigurePacket::PPPConfigurePacket(struct mbuf *packet)
{
// decode packet
ppp_lcp_packet *data = mtod(packet, ppp_lcp_packet*);
if(!SetCode(data->code))
return;
if(data->length < 4)
return;
// there are no items (or one corrupted item)
int32 position = 0;
ppp_configure_item *item;
while(position <= data->length - 4) {
item = (ppp_configure_item*) (data->data + position);
position += item->length;
AddItem(item);
}
}
PPPConfigurePacket::~PPPConfigurePacket()
{
for(int32 index = 0; index < CountItems(); index++)
free(ItemAt(index));
}
bool
PPPConfigurePacket::SetCode(uint8 code)
{
// only configure codes are allowed!
if(code < PPP_CONFIGURE_REQUEST || code > PPP_CONFIGURE_REJECT)
return false;
fCode = code;
return true;
}
bool
PPPConfigurePacket::AddItem(const ppp_configure_item *item, int32 index = -1)
{
if(item->length < 2)
return false;
ppp_configure_item *add = (ppp_configure_item*) malloc(item->length);
memcpy(add, item, item->length);
bool status;
if(index < 0)
status = fItems.AddItem(add);
else
status = fItems.AddItem(add, index);
if(!status) {
free(add);
return false;
}
return true;
}
bool
PPPConfigurePacket::RemoveItem(ppp_configure_item *item)
{
if(!fItems.HasItem(item))
return false;
fItems.RemoveItem(item);
free(item);
return true;
}
ppp_configure_item*
PPPConfigurePacket::ItemAt(int32 index) const
{
ppp_configure_item *item = fItems.ItemAt(index);
if(item == fItems.GetDefaultItem())
return NULL;
return item;
}
ppp_configure_item*
PPPConfigurePacket::ItemWithType(uint8 type) const
{
ppp_configure_item *item;
for(int32 index = 0; index < CountItems(); index++) {
item = ItemAt(index);
if(item && item->type == type)
return item;
}
return NULL;
}
struct mbuf*
PPPConfigurePacket::ToMbuf(uint32 reserve = 0)
{
struct mbuf *packet = m_gethdr(MT_DATA);
packet->m_data += reserve;
ppp_lcp_packet *data = mtod(packet, ppp_lcp_packet*);
data->code = Code();
uint8 length = 0;
ppp_configure_item *item;
for(int32 index = 0; index < CountItems(); index++) {
item = ItemAt(index);
if(0xFF - length < item->length) {
m_freem(packet);
return NULL;
}
memcpy(data->data + length, item, item->length);
length += item->length;
}
data->length = length + 2;
packet->m_len = data->length;
return packet;
}

View File

@ -0,0 +1,130 @@
//----------------------------------------------------------------------
// 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 <KPPPDevice.h>
#include <net/if.h>
#include <mbuf.h>
#include <PPPControl.h>
PPPDevice::PPPDevice(const char *name, PPPInterface& interface,
driver_parameter *settings)
: fMTU(1500),
fIsUp(false),
fInterface(interface),
fSettings(settings)
{
if(name)
fName = strdup(name);
else
fName = strdup("Unknown");
fInitStatus = interface.SetDevice(this) ? B_OK : B_ERROR;
}
PPPDevice::~PPPDevice()
{
free(fName);
Interface().SetDevice(NULL);
}
status_t
PPPDevice::InitCheck() const
{
return fInitStatus;
}
status_t
PPPDevice::Control(uint32 op, void *data, size_t length)
{
switch(op) {
case PPPC_GET_DEVICE_INFO: {
if(length < sizeof(ppp_device_info_t) || !data)
return B_NO_MEMORY;
ppp_device_info *info = (ppp_device_info*) data;
memset(info, 0, sizeof(ppp_device_info_t));
strncpy(info->name, Name(), PPP_HANDLER_NAME_LENGTH_LIMIT);
info->settings = Settings();
info->MTU = MTU();
info->inputTransferRate = InputTransferRate();
info->outputTransferRate = OutputTransferRate();
info->outputBytesCount = CountOutputBytes();
} break;
default:
return B_BAD_VALUE;
}
return B_OK;
}
status_t
PPPDevice::PassToInterface(struct mbuf *packet)
{
if(!Interface().InQueue())
return B_ERROR;
IFQ_ENQUEUE(Interface().InQueue(), packet);
return B_OK;
}
void
PPPDevice::Pulse()
{
// do nothing by default
}
bool
PPPDevice::UpStarted() const
{
return Interface().StateMachine().TLSNotify();
}
bool
PPPDevice::DownStarted() const
{
return Interface().StateMachine().TLFNotify();
}
void
PPPDevice::UpFailedEvent()
{
fIsUp = false;
Interface().StateMachine().UpFailedEvent();
}
void
PPPDevice::UpEvent()
{
fIsUp = true;
Interface().StateMachine().UpEvent();
}
void
PPPDevice::DownEvent()
{
fIsUp = false;
Interface().StateMachine().DownEvent();
}

View File

@ -0,0 +1,191 @@
//----------------------------------------------------------------------
// 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 <KPPPEncapsulator.h>
#include <KPPPUtils.h>
#include "settings_tools.h"
#include <PPPControl.h>
PPPEncapsulator::PPPEncapsulator(const char *name, ppp_phase phase,
ppp_encapsulation_level level, uint16 protocol,
int32 addressFamily, uint32 overhead,
PPPInterface& interface, driver_parameter *settings,
int32 flags = PPP_NO_FLAGS)
: fOverhead(overhead),
fPhase(phase),
fLevel(level),
fProtocol(protocol),
fAddressFamily(addressFamily),
fInterface(interface),
fSettings(settings),
fFlags(flags),
fEnabled(true),
fUpRequested(true),
fConnectionStatus(PPP_DOWN_PHASE)
{
if(name)
fName = strdup(name);
else
fName = strdup("Unknown");
const char *sideString = get_parameter_value("side", settings);
if(sideString)
fSide = get_side_string_value(sideString, PPP_LOCAL_SIDE);
else {
if(interface.Mode() == PPP_CLIENT_MODE)
fSide = PPP_LOCAL_SIDE;
else
fSide = PPP_PEER_SIDE;
}
fInitStatus = interface.AddEncapsulator(this) ? B_OK : B_ERROR;
}
PPPEncapsulator::~PPPEncapsulator()
{
free(fName);
Interface().RemoveEncapsulator(this);
}
status_t
PPPEncapsulator::InitCheck() const
{
return fInitStatus;
}
void
PPPEncapsulator::SetEnabled(bool enabled = true)
{
fEnabled = enabled;
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) {
case PPPC_GET_HANDLER_INFO: {
if(length < sizeof(ppp_handler_info_t) || !data)
return B_ERROR;
ppp_handler_info *info = (ppp_handler_info*) data;
memset(info, 0, sizeof(ppp_handler_info_t));
strncpy(info->name, Name(), PPP_HANDLER_NAME_LENGTH_LIMIT);
info->settings = Settings();
info->phase = Phase();
info->addressFamily = AddressFamily();
info->flags = Flags();
info->side = Side();
info->protocol = Protocol();
info->isEnabled = IsEnabled();
info->isUpRequested = IsUpRequested();
info->connectionStatus = fConnectionStatus;
info->level = Level();
info->overhead = Overhead();
} break;
case PPPC_SET_ENABLED:
if(length < sizeof(uint32) || !data)
return B_ERROR;
SetEnabled(*((uint32*)data));
break;
default:
return B_BAD_VALUE;
}
return B_OK;
}
status_t
PPPEncapsulator::StackControl(uint32 op, void *data)
{
switch(op) {
default:
return B_BAD_VALUE;
}
return B_OK;
}
status_t
PPPEncapsulator::SendToNext(struct mbuf *packet, uint16 protocol) const
{
// Find the next possible handler for this packet.
// This handler should be enabled, up, and allowed to send
if(Next()) {
if(Next()->IsEnabled() && Next()->IsUp()
&& is_handler_allowed(*Next(), Interface().State(), Interface().Phase()))
return Next()->Send(packet, protocol);
else
return Next()->SendToNext(packet, protocol);
} else
return Interface().SendToDevice(packet, protocol);
}
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;
Interface().StateMachine().UpFailedEvent(this);
}
void
PPPEncapsulator::UpEvent()
{
fConnectionStatus = PPP_ESTABLISHED_PHASE;
Interface().StateMachine().UpEvent(this);
}
void
PPPEncapsulator::DownEvent()
{
fConnectionStatus = PPP_DOWN_PHASE;
Interface().StateMachine().DownEvent(this);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,325 @@
//----------------------------------------------------------------------
// 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 <KPPPInterface.h>
#include <KPPPDevice.h>
#include <KPPPEncapsulator.h>
#include <KPPPLCPExtension.h>
#include <KPPPOptionHandler.h>
#include <LockerHelper.h>
#include <netinet/in.h>
#include <mbuf.h>
#include <sys/socket.h>
PPPLCP::PPPLCP(PPPInterface& interface)
: PPPProtocol("LCP", PPP_ESTABLISHMENT_PHASE, PPP_LCP_PROTOCOL,
AF_UNSPEC, interface, NULL, PPP_ALWAYS_ALLOWED),
fStateMachine(interface.StateMachine()),
fTarget(NULL)
{
SetUpRequested(false);
// the state machine does everything for us
}
PPPLCP::~PPPLCP()
{
while(CountOptionHandlers())
delete OptionHandlerAt(0);
}
bool
PPPLCP::AddOptionHandler(PPPOptionHandler *handler)
{
if(!handler)
return false;
LockerHelper locker(StateMachine().Locker());
if(Phase() != PPP_DOWN_PHASE || OptionHandlerFor(handler->Type()))
return false;
// a running connection may not change and there may only be
// one handler per option type
return fOptionHandlers.AddItem(handler);
}
bool
PPPLCP::RemoveOptionHandler(PPPOptionHandler *handler)
{
LockerHelper locker(StateMachine().Locker());
if(Phase() != PPP_DOWN_PHASE)
return false;
// a running connection may not change
return fOptionHandlers.RemoveItem(handler);
}
PPPOptionHandler*
PPPLCP::OptionHandlerAt(int32 index) const
{
PPPOptionHandler *handler = fOptionHandlers.ItemAt(index);
if(handler == fOptionHandlers.GetDefaultItem())
return NULL;
return handler;
}
PPPOptionHandler*
PPPLCP::OptionHandlerFor(uint8 type, int32 *start = NULL) const
{
// The iteration style in this method is strange C/C++.
// Explanation: I use this style because it makes extending all XXXFor
// methods simpler as that they look very similar, now.
int32 index = start ? *start : 0;
if(index < 0)
return NULL;
PPPOptionHandler *current = OptionHandlerAt(index);
for(; current; current = OptionHandlerAt(++index)) {
if(current->Type() == type) {
if(start)
*start = index;
return current;
}
}
return NULL;
}
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;
}
PPPLCPExtension*
PPPLCP::LCPExtensionFor(uint8 code, int32 *start = NULL) const
{
// The iteration style in this method is strange C/C++.
// Explanation: I use this style because it makes extending all XXXFor
// methods simpler as that they look very similar, now.
int32 index = start ? *start : 0;
if(index < 0)
return NULL;
PPPLCPExtension *current = LCPExtensionAt(index);
for(; current; current = LCPExtensionAt(++index)) {
if(current->Code() == code) {
if(start)
*start = index;
return current;
}
}
return NULL;
}
uint32
PPPLCP::AdditionalOverhead() const
{
uint32 overhead = 0;
if(Target())
overhead += Target()->Overhead();
return overhead;
}
bool
PPPLCP::Up()
{
return true;
}
bool
PPPLCP::Down()
{
return true;
}
status_t
PPPLCP::Send(struct mbuf *packet)
{
if(Target())
return Target()->Send(packet, PPP_LCP_PROTOCOL);
else
return Interface().Send(packet, PPP_LCP_PROTOCOL);
}
status_t
PPPLCP::Receive(struct mbuf *packet, uint16 protocol)
{
if(!packet)
return B_ERROR;
if(protocol != PPP_LCP_PROTOCOL)
return PPP_UNHANDLED;
ppp_lcp_packet *data = mtod(packet, ppp_lcp_packet*);
// adjust length (remove padding)
int32 length = packet->m_len;
if(packet->m_flags & M_PKTHDR)
length = packet->m_pkthdr.len;
if(length - ntohs(data->length) != 0)
m_adj(packet, length);
struct mbuf *copy = m_gethdr(MT_DATA);
if(copy) {
copy->m_data += AdditionalOverhead();
copy->m_len = packet->m_len;
memcpy(copy->m_data, packet->m_data, copy->m_len);
}
if(ntohs(data->length) < 4)
return B_ERROR;
bool handled = true;
switch(data->code) {
case PPP_CONFIGURE_REQUEST:
StateMachine().RCREvent(packet);
break;
case PPP_CONFIGURE_ACK:
StateMachine().RCAEvent(packet);
break;
case PPP_CONFIGURE_NAK:
case PPP_CONFIGURE_REJECT:
StateMachine().RCNEvent(packet);
break;
case PPP_TERMINATE_REQUEST:
StateMachine().RTREvent(packet);
break;
case PPP_TERMINATE_ACK:
StateMachine().RTAEvent(packet);
break;
case PPP_CODE_REJECT:
StateMachine().RXJEvent(packet);
break;
case PPP_PROTOCOL_REJECT:
StateMachine().RXJEvent(packet);
break;
case PPP_ECHO_REQUEST:
case PPP_ECHO_REPLY:
case PPP_DISCARD_REQUEST:
StateMachine().RXREvent(packet);
break;
default:
m_freem(packet);
handled = false;
}
packet = copy;
if(!packet)
return handled ? B_OK : B_ERROR;
status_t result = B_OK;
// Try to find LCP extensions that can handle this code.
// We must duplicate the packet in order to ask all handlers.
int32 index = 0;
PPPLCPExtension *extension = LCPExtensionFor(data->code, &index);
for(; extension; extension = LCPExtensionFor(data->code, &(++index))) {
if(!extension->IsEnabled())
continue;
result = extension->Receive(packet, data->code);
// check return value and return it on error
if(result == B_OK)
handled = true;
else if(result != PPP_UNHANDLED) {
m_freem(packet);
return result;
}
}
if(!handled) {
StateMachine().RUCEvent(packet, PPP_LCP_PROTOCOL, PPP_CODE_REJECT);
return PPP_REJECTED;
}
m_freem(packet);
return result;
}
void
PPPLCP::Pulse()
{
StateMachine().TimerEvent();
for(int32 index = 0; index < CountLCPExtensions(); index++)
LCPExtensionAt(index)->Pulse();
}

View File

@ -0,0 +1,97 @@
//----------------------------------------------------------------------
// 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)
fName = strdup(name);
else
fName = strdup("Unknown");
fInitStatus = interface.LCP().AddLCPExtension(this) ? B_OK : B_ERROR;
}
PPPLCPExtension::~PPPLCPExtension()
{
free(fName);
Interface().LCP().RemoveLCPExtension(this);
}
status_t
PPPLCPExtension::InitCheck() const
{
return fInitStatus;
}
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));
strncpy(info->name, Name(), PPP_HANDLER_NAME_LENGTH_LIMIT);
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 B_BAD_VALUE;
}
return B_OK;
}
status_t
PPPLCPExtension::StackControl(uint32 op, void *data)
{
switch(op) {
default:
return B_BAD_VALUE;
}
return B_OK;
}
void
PPPLCPExtension::Reset()
{
// do nothing by default
}
void
PPPLCPExtension::Pulse()
{
// do nothing by default
}

View File

@ -0,0 +1,83 @@
//----------------------------------------------------------------------
// 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 <KPPPOptionHandler.h>
#include <PPPControl.h>
PPPOptionHandler::PPPOptionHandler(const char *name, uint8 type,
PPPInterface& interface, driver_parameter *settings)
: fType(type),
fInterface(interface),
fSettings(settings),
fEnabled(true)
{
if(name)
fName = strdup(name);
else
fName = strdup("Unknown");
fInitStatus = interface.LCP().AddOptionHandler(this) ? B_OK : B_ERROR;
}
PPPOptionHandler::~PPPOptionHandler()
{
free(fName);
Interface().LCP().RemoveOptionHandler(this);
}
status_t
PPPOptionHandler::InitCheck() const
{
return fInitStatus;
}
status_t
PPPOptionHandler::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));
strncpy(info->name, Name(), PPP_HANDLER_NAME_LENGTH_LIMIT);
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 B_BAD_VALUE;
}
return B_OK;
}
status_t
PPPOptionHandler::StackControl(uint32 op, void *data)
{
switch(op) {
default:
return B_BAD_VALUE;
}
return B_OK;
}

View File

@ -0,0 +1,180 @@
//----------------------------------------------------------------------
// 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 <KPPPInterface.h>
#include <KPPPOptionHandler.h>
#include <PPPControl.h>
#include "settings_tools.h"
#include <cstring>
PPPProtocol::PPPProtocol(const char *name, ppp_phase phase, uint16 protocol,
int32 addressFamily, PPPInterface& interface,
driver_parameter *settings, int32 flags = PPP_NO_FLAGS,
const char *type = NULL, PPPOptionHandler *optionHandler = NULL)
: fPhase(phase),
fProtocol(protocol),
fAddressFamily(addressFamily),
fInterface(interface),
fSettings(settings),
fFlags(flags),
fOptionHandler(optionHandler),
fEnabled(true),
fUpRequested(true),
fConnectionStatus(PPP_DOWN_PHASE)
{
if(name)
fName = strdup(name);
else
fName = strdup("Unknown");
if(type)
fType = strdup(type);
else
fType = strdup("Unknown");
const char *sideString = get_parameter_value("side", settings);
if(sideString)
fSide = get_side_string_value(sideString, PPP_LOCAL_SIDE);
else {
if(interface.Mode() == PPP_CLIENT_MODE)
fSide = PPP_LOCAL_SIDE;
else
fSide = PPP_PEER_SIDE;
}
fInitStatus = interface.AddProtocol(this) ? B_OK : B_ERROR;
}
PPPProtocol::~PPPProtocol()
{
free(fName);
free(fType);
Interface().RemoveProtocol(this);
}
status_t
PPPProtocol::InitCheck() const
{
return fInitStatus;
}
void
PPPProtocol::SetEnabled(bool enabled = true)
{
fEnabled = enabled;
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) {
case PPPC_GET_HANDLER_INFO: {
if(length < sizeof(ppp_handler_info_t) || !data)
return B_ERROR;
ppp_handler_info *info = (ppp_handler_info*) data;
memset(info, 0, sizeof(ppp_handler_info_t));
strncpy(info->name, Name(), PPP_HANDLER_NAME_LENGTH_LIMIT);
info->settings = Settings();
info->phase = Phase();
info->addressFamily = AddressFamily();
info->flags = Flags();
info->side = Side();
info->protocol = Protocol();
info->isEnabled = IsEnabled();
info->isUpRequested = IsUpRequested();
info->connectionStatus = fConnectionStatus;
strncpy(info->type, Type(), PPP_HANDLER_NAME_LENGTH_LIMIT);
} break;
case PPPC_SET_ENABLED:
if(length < sizeof(uint32) || !data)
return B_ERROR;
SetEnabled(*((uint32*)data));
break;
default:
return B_BAD_VALUE;
}
return B_OK;
}
status_t
PPPProtocol::StackControl(uint32 op, void *data)
{
switch(op) {
default:
return B_BAD_VALUE;
}
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;
Interface().StateMachine().UpFailedEvent(this);
}
void
PPPProtocol::UpEvent()
{
fConnectionStatus = PPP_ESTABLISHED_PHASE;
Interface().StateMachine().UpEvent(this);
}
void
PPPProtocol::DownEvent()
{
fConnectionStatus = PPP_DOWN_PHASE;
Interface().StateMachine().DownEvent(this);
}

View File

@ -0,0 +1,148 @@
//----------------------------------------------------------------------
// 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 <KPPPReportManager.h>
#include <LockerHelper.h>
#include <KPPPUtils.h>
#include <new.h>
PPPReportManager::PPPReportManager(BLocker& lock)
: fLock(lock)
{
}
PPPReportManager::~PPPReportManager()
{
for(int32 index = 0; index < fReportRequests.CountItems(); index++)
delete fReportRequests.ItemAt(index);
}
void
PPPReportManager::EnableReports(ppp_report_type type, thread_id thread,
int32 flags = PPP_NO_FLAGS)
{
LockerHelper locker(fLock);
ppp_report_request *request = new ppp_report_request;
request->type = type;
request->thread = thread;
request->flags = flags;
fReportRequests.AddItem(request);
}
void
PPPReportManager::DisableReports(ppp_report_type type, thread_id thread)
{
LockerHelper locker(fLock);
ppp_report_request *request;
for(int32 i = 0; i < fReportRequests.CountItems(); i++) {
request = fReportRequests.ItemAt(i);
if(request->thread != thread)
continue;
if(request->type == type || request->type == PPP_ALL_REPORTS)
fReportRequests.RemoveItem(request);
}
}
bool
PPPReportManager::DoesReport(ppp_report_type type, thread_id thread)
{
LockerHelper locker(fLock);
ppp_report_request *request;
for(int32 i = 0; i < fReportRequests.CountItems(); i++) {
request = fReportRequests.ItemAt(i);
if(request->thread == thread && request->type == type)
return true;
}
return false;
}
bool
PPPReportManager::Report(ppp_report_type type, int32 code, void *data, int32 length)
{
if(length > PPP_REPORT_DATA_LIMIT)
return false;
if(fReportRequests.CountItems() == 0)
return true;
if(!data)
length = 0;
LockerHelper locker(fLock);
status_t result;
thread_id sender, me = find_thread(NULL);
bool acceptable = true;
ppp_report_packet report;
report.type = type;
report.code = code;
report.length = length;
memcpy(report.data, data, length);
ppp_report_request *request;
for(int32 index = 0; index < fReportRequests.CountItems(); index++) {
request = fReportRequests.ItemAt(index);
// do not send to yourself
if(request->thread == me)
continue;
result = send_data_with_timeout(request->thread, PPP_REPORT_CODE, &report,
sizeof(report), PPP_REPORT_TIMEOUT);
if(result == B_BAD_THREAD_ID || result == B_NO_MEMORY) {
fReportRequests.RemoveItem(request);
--index;
continue;
} else if(result == B_OK) {
if(request->flags & PPP_WAIT_FOR_REPLY) {
if(request->flags & PPP_NO_REPLY_TIMEOUT) {
sender = -1;
while(sender != request->thread)
code = receive_data(&sender, NULL, 0);
result = B_OK;
} else {
sender = -1;
result = B_OK;
while(sender != request->thread && result == B_OK)
result = receive_data_with_timeout(&sender, &code, NULL, 0,
PPP_REPORT_TIMEOUT);
}
if(result == B_OK && code != B_OK)
acceptable = false;
}
}
if(request->flags & PPP_REMOVE_AFTER_REPORT) {
fReportRequests.RemoveItem(request);
--index;
}
}
return acceptable;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,48 @@
//----------------------------------------------------------------------
// 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 <OS.h>
#include <KPPPUtils.h>
// These are very simple send/receive_data functions with a timeout
// and there is a race condition beween has_data() and send/receive_data().
// Timeouts in ms.
status_t
send_data_with_timeout(thread_id thread, int32 code, void *buffer,
size_t buffer_size, uint32 timeout)
{
for(uint32 tries = 0; tries < timeout; tries++) {
if(has_data(thread))
snooze(1000);
}
if(!has_data(thread))
return send_data(thread, code, buffer, buffer_size);
else
return B_TIMED_OUT;
}
status_t
receive_data_with_timeout(thread_id *sender, int32 *code, void *buffer,
size_t buffer_size, uint32 timeout)
{
for(uint32 tries = 0; tries < timeout; tries++) {
if(!has_data(find_thread(NULL))) {
snooze(1000);
continue;
}
}
if(has_data(find_thread(NULL))) {
*code = receive_data(sender, buffer, buffer_size);
return B_OK;
} else
return B_TIMED_OUT;
}

View File

@ -0,0 +1,283 @@
//----------------------------------------------------------------------
// 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 "_KPPPAuthenticationHandler.h"
#include <KPPPConfigurePacket.h>
#include <KPPPDevice.h>
#include <netinet/in.h>
#define AUTHENTICATION_TYPE 0x3
#define AUTHENTICATOR_TYPE_STRING "Authenticator"
typedef struct authentication_item {
uint8 type;
uint8 length;
uint16 protocol;
} authentication_item;
_PPPAuthenticationHandler::_PPPAuthenticationHandler(PPPInterface& interface)
: PPPOptionHandler("Authentication Handler", AUTHENTICATION_TYPE, interface, NULL),
fLocalIndex(-1),
fPeerIndex(-1),
fSuggestedLocalIndex(-1),
fSuggestedPeerIndex(-1),
fPeerAuthenticatorRejected(false)
{
}
int32
_PPPAuthenticationHandler::NextAuthenticator(int32 start, ppp_side side)
{
// find the next authenticator for side, beginning at start
PPPProtocol *protocol;
for(int32 index = start; index < Interface().CountProtocols(); index++) {
protocol = Interface().ProtocolAt(index);
if(protocol && !strcasecmp(protocol->Type(), AUTHENTICATOR_TYPE_STRING)
&& protocol->OptionHandler()
&& protocol->Side() == side)
return index;
}
return -1;
}
status_t
_PPPAuthenticationHandler::AddToRequest(PPPConfigurePacket& request)
{
// AddToRequest(): Check if peer must authenticate itself and
// add an authentication request if needed. This request is added
// by the authenticator's OptionHandler.
int32 index;
PPPProtocol *protocol;
if(fPeerIndex != -1 && (protocol = Interface().ProtocolAt(fPeerIndex)))
protocol->SetEnabled(false);
if(fSuggestedPeerIndex != -1
&& (protocol = Interface().ProtocolAt(fSuggestedPeerIndex)))
protocol->SetEnabled(false);
if(fPeerAuthenticatorRejected) {
if(fSuggestedPeerIndex == -1) {
// This happens when the protocol is rejected, but no alternative
// protocol is supplied to us or the suggested protocol is not supported.
// We can use this chance to increase fPeerIndex to the next authenticator.
index = NextAuthenticator(fPeerIndex + 1, PPP_PEER_SIDE);
} else
index = fSuggestedPeerIndex;
fPeerAuthenticatorRejected = false;
} else {
if(fPeerIndex == -1) {
// there is no authenticator selected, so find one for us
index = NextAuthenticator(fPeerIndex + 1, PPP_PEER_SIDE);
} else
index = fPeerIndex;
}
// check if all authenticators were rejected or if no authentication needed
if(index == -1) {
if(fPeerIndex == -1)
return B_OK;
// no peer authentication needed
else
return B_ERROR;
// all authenticators were denied
}
protocol = Interface().ProtocolAt(index);
if(!protocol || !protocol->OptionHandler())
return B_ERROR;
fPeerIndex = index;
// this could omit some authenticators when we get a suggestion, but that is
// no problem because the suggested authenticator will be accepted (hopefully)
protocol->SetEnabled(true);
return protocol->OptionHandler()->AddToRequest(request);
// let protocol add its request
}
status_t
_PPPAuthenticationHandler::ParseNak(const PPPConfigurePacket& nak)
{
// The authenticator's OptionHandler is not notified.
authentication_item *item =
(authentication_item*) nak.ItemWithType(AUTHENTICATION_TYPE);
if(!item)
return B_OK;
// the request was not rejected
if(item->length < 4)
return B_ERROR;
PPPProtocol *protocol;
if(fSuggestedPeerIndex != -1
&& (protocol = Interface().ProtocolAt(fSuggestedPeerIndex))) {
protocol->SetEnabled(false);
// if no alternative protocol is supplied we will choose a new one in
// AddToRequest()
if(ntohs(item->protocol) == protocol->Protocol()) {
fSuggestedPeerIndex = -1;
return B_OK;
}
}
fPeerAuthenticatorRejected = true;
int32 index = 0;
if((protocol = Interface().ProtocolFor(ntohs(item->protocol), &index))
&& !strcasecmp(protocol->Type(), AUTHENTICATOR_TYPE_STRING)
&& protocol->OptionHandler())
fSuggestedPeerIndex = index;
else
fSuggestedPeerIndex = -1;
return B_OK;
}
status_t
_PPPAuthenticationHandler::ParseReject(const PPPConfigurePacket& reject)
{
// an authentication request must not be rejected!
if(reject.ItemWithType(AUTHENTICATION_TYPE))
return B_ERROR;
return B_OK;
}
status_t
_PPPAuthenticationHandler::ParseAck(const PPPConfigurePacket& ack)
{
authentication_item *item =
(authentication_item*) ack.ItemWithType(AUTHENTICATION_TYPE);
PPPProtocol *protocol = Interface().ProtocolAt(fPeerIndex);
if(fPeerIndex != -1 && !protocol)
return B_ERROR;
// could not find the protocol
if(!item) {
if(fPeerIndex != -1)
return B_ERROR;
// the ack does not contain our request
} else if(fPeerIndex == -1 || ntohs(item->protocol) != protocol->Protocol())
return B_ERROR;
// this item was never requested
return protocol->OptionHandler()->ParseAck(ack);
// this should enable the authenticator
}
status_t
_PPPAuthenticationHandler::ParseRequest(const PPPConfigurePacket& request,
int32 index, PPPConfigurePacket& nak, PPPConfigurePacket& reject)
{
PPPProtocol *protocol;
if(fLocalIndex != -1 && (protocol = Interface().ProtocolAt(fLocalIndex)))
protocol->SetEnabled(false);
authentication_item *item = (authentication_item*) request.ItemAt(index);
if(!item)
return B_OK;
// no authentication requested by peer
// try to find the requested protocol and select it by saving it in fLocalIndex
fLocalIndex = 0;
protocol = Interface().ProtocolFor(ntohs(item->protocol), &fLocalIndex);
if(protocol && !strcasecmp(protocol->Type(), AUTHENTICATOR_TYPE_STRING)
&& protocol->OptionHandler())
return protocol->OptionHandler()->ParseRequest(request, index, nak, reject);
// suggest another authentication protocol
int32 nextIndex = NextAuthenticator(fSuggestedLocalIndex + 1, PPP_LOCAL_SIDE);
if(nextIndex == -1) {
if(fSuggestedLocalIndex == -1) {
// reject the complete authentication option
reject.AddItem((ppp_configure_item*) item);
return B_OK;
} else
nextIndex = fSuggestedLocalIndex;
// try the old one again as it was not rejected until now
}
protocol = Interface().ProtocolAt(nextIndex);
if(!protocol)
return B_ERROR;
fSuggestedLocalIndex = nextIndex;
fLocalIndex = -1;
// no authenticator selected
// nak this authenticator and suggest an alternative
authentication_item suggestion;
suggestion.type = AUTHENTICATION_TYPE;
suggestion.length = 4;
suggestion.protocol = htons(protocol->Protocol());
return nak.AddItem((ppp_configure_item*) &suggestion) ? B_OK : B_ERROR;
}
status_t
_PPPAuthenticationHandler::SendingAck(const PPPConfigurePacket& ack)
{
// do not insist on authenticating our side of the link ;)
authentication_item *item =
(authentication_item*) ack.ItemWithType(AUTHENTICATION_TYPE);
if(!item)
return B_OK;
// no authentication needed
fSuggestedLocalIndex = -1;
if(fLocalIndex == -1)
return B_ERROR;
// no authenticator selected (our suggestions must be requested, too)
PPPProtocol *protocol = Interface().ProtocolAt(fLocalIndex);
if(!protocol)
return B_ERROR;
protocol->SetEnabled(true);
return protocol->OptionHandler()->SendingAck(ack);
// this should enable the authenticator
}
void
_PPPAuthenticationHandler::Reset()
{
PPPProtocol *protocol = NULL;
if(fLocalIndex != -1 && (protocol = Interface().ProtocolAt(fLocalIndex))) {
protocol->SetEnabled(false);
protocol->OptionHandler()->Reset();
}
if(fPeerIndex != -1 && (protocol = Interface().ProtocolAt(fPeerIndex))) {
protocol->SetEnabled(false);
protocol->OptionHandler()->Reset();
}
if(fSuggestedPeerIndex != -1
&& (protocol = Interface().ProtocolAt(fSuggestedPeerIndex))) {
protocol->SetEnabled(false);
protocol->OptionHandler()->Reset();
}
fLocalIndex = fPeerIndex = fSuggestedLocalIndex = fSuggestedPeerIndex = -1;
fPeerAuthenticatorRejected = false;
}

View File

@ -0,0 +1,37 @@
//----------------------------------------------------------------------
// 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_AUTHENTICATION_HANDLER__H
#define __K_PPP_AUTHENTICATION_HANDLER__H
#include <KPPPOptionHandler.h>
class _PPPAuthenticationHandler : public PPPOptionHandler {
public:
_PPPAuthenticationHandler(PPPInterface& interface);
int32 NextAuthenticator(int32 start, ppp_side side);
virtual status_t AddToRequest(PPPConfigurePacket& request);
virtual status_t ParseNak(const PPPConfigurePacket& nak);
virtual status_t ParseReject(const PPPConfigurePacket& reject);
virtual status_t ParseAck(const PPPConfigurePacket& ack);
virtual status_t ParseRequest(const PPPConfigurePacket& request,
int32 index, PPPConfigurePacket& nak, PPPConfigurePacket& reject);
virtual status_t SendingAck(const PPPConfigurePacket& ack);
virtual void Reset();
private:
int32 fLocalIndex, fPeerIndex, fSuggestedLocalIndex, fSuggestedPeerIndex;
bool fPeerAuthenticatorRejected;
};
#endif

View File

@ -0,0 +1,140 @@
//----------------------------------------------------------------------
// 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 "_KPPPMRUHandler.h"
#include <KPPPConfigurePacket.h>
#include <KPPPDevice.h>
#include <netinet/in.h>
#define MRU_TYPE 0x1
typedef struct mru_item {
uint8 type;
uint8 length;
uint16 MRU;
};
status_t ParseRequestedItem(mru_item *item, PPPInterface& interface);
_PPPMRUHandler::_PPPMRUHandler(PPPInterface& interface)
: PPPOptionHandler("MRU Handler", MRU_TYPE, interface, NULL)
{
Reset();
}
status_t
_PPPMRUHandler::AddToRequest(PPPConfigurePacket& request)
{
if(!Interface().Device() || Interface().MRU() == 1500)
return B_OK;
// add MRU request
mru_item item;
item.type = MRU_TYPE;
item.length = 4;
item.MRU = htons(fLocalMRU);
return request.AddItem((ppp_configure_item*) &item) ? B_OK : B_ERROR;
}
status_t
_PPPMRUHandler::ParseNak(const PPPConfigurePacket& nak)
{
mru_item *item = (mru_item*) nak.ItemWithType(MRU_TYPE);
if(!item || item->length != 4)
return B_OK;
uint16 MRU = ntohs(item->MRU);
if(MRU < fLocalMRU)
fLocalMRU = MRU;
return B_OK;
}
status_t
_PPPMRUHandler::ParseReject(const PPPConfigurePacket& reject)
{
if(reject.ItemWithType(MRU_TYPE))
return B_ERROR;
return B_OK;
}
status_t
_PPPMRUHandler::ParseAck(const PPPConfigurePacket& ack)
{
uint16 MRU = 1500;
mru_item *item = (mru_item*) ack.ItemWithType(MRU_TYPE);
if(item)
MRU = ntohs(item->MRU);
if(MRU < Interface().MRU())
fLocalMRU = MRU;
return B_OK;
}
status_t
_PPPMRUHandler::ParseRequest(const PPPConfigurePacket& request,
int32 index, PPPConfigurePacket& nak, PPPConfigurePacket& reject)
{
if(index == reject.CountItems())
return B_OK;
return ParseRequestedItem((mru_item*) request.ItemAt(index), Interface());
return B_OK;
}
status_t
_PPPMRUHandler::SendingAck(const PPPConfigurePacket& ack)
{
return ParseRequestedItem((mru_item*) ack.ItemWithType(MRU_TYPE), Interface());
}
// this function contains code shared by ParseRequest and SendingAck
status_t
ParseRequestedItem(mru_item *item, PPPInterface& interface)
{
uint16 MRU = 1500;
if(item) {
if(item->length != 4)
return B_ERROR;
// the request had a corrupted item
MRU = ntohs(item->MRU);
}
if(MRU < interface.MRU())
interface.SetMRU(MRU);
return B_OK;
}
void
_PPPMRUHandler::Reset()
{
if(Interface().Device()) {
fLocalMRU = Interface().Device()->MTU() - 2;
Interface().SetMRU(fLocalMRU);
} else {
Interface().SetMRU(1500);
fLocalMRU = 1500;
}
}

View File

@ -0,0 +1,34 @@
//----------------------------------------------------------------------
// 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_MRU_HANDLER__H
#define __K_PPP_MRU_HANDLER__H
#include <KPPPOptionHandler.h>
class _PPPMRUHandler : public PPPOptionHandler {
public:
_PPPMRUHandler(PPPInterface& interface);
virtual status_t AddToRequest(PPPConfigurePacket& request);
virtual status_t ParseNak(const PPPConfigurePacket& nak);
virtual status_t ParseReject(const PPPConfigurePacket& reject);
virtual status_t ParseAck(const PPPConfigurePacket& ack);
virtual status_t ParseRequest(const PPPConfigurePacket& request,
int32 index, PPPConfigurePacket& nak, PPPConfigurePacket& reject);
virtual status_t SendingAck(const PPPConfigurePacket& ack);
virtual void Reset();
private:
uint16 fLocalMRU;
};
#endif

View File

@ -0,0 +1,120 @@
//----------------------------------------------------------------------
// This software is part of the OpenBeOS distribution and is covered
// by the OpenBeOS license.
//
// Copyright (c) 2003 Waldemar Kornewald, Waldemar.Kornewald@web.de
//---------------------------------------------------------------------
#include "_KPPPPFCHandler.h"
#include <KPPPConfigurePacket.h>
#define PFC_TYPE 0x7
_PPPPFCHandler::_PPPPFCHandler(ppp_pfc_state& localPFCState,
ppp_pfc_state& peerPFCState, PPPInterface& interface)
: PPPOptionHandler("PFC Handler", PFC_TYPE, interface, NULL),
fLocalPFCState(localPFCState),
fPeerPFCState(peerPFCState)
{
}
status_t
_PPPPFCHandler::AddToRequest(PPPConfigurePacket& request)
{
// is PFC not requested or was it rejected?
if(fLocalPFCState & PPP_PFC_REJECTED
|| (Interface().PFCOptions() & PPP_REQUEST_PFC) == 0)
return B_OK;
// add PFC request
ppp_configure_item item;
item.type = PFC_TYPE;
item.length = 2;
return request.AddItem(&item) ? B_OK : B_ERROR;
}
status_t
_PPPPFCHandler::ParseNak(const PPPConfigurePacket& nak)
{
// naks do not contain PFC items
if(nak.ItemWithType(PFC_TYPE))
return B_ERROR;
return B_OK;
}
status_t
_PPPPFCHandler::ParseReject(const PPPConfigurePacket& reject)
{
if(reject.ItemWithType(PFC_TYPE)) {
fLocalPFCState = PPP_PFC_REJECTED;
if(Interface().PFCOptions() & PPP_FORCE_PFC_REQUEST)
return B_ERROR;
}
return B_OK;
}
status_t
_PPPPFCHandler::ParseAck(const PPPConfigurePacket& ack)
{
if(ack.ItemWithType(PFC_TYPE))
fLocalPFCState = PPP_PFC_ACCEPTED;
else {
fLocalPFCState = PPP_PFC_DISABLED;
if(Interface().PFCOptions() & PPP_FORCE_PFC_REQUEST)
return B_ERROR;
}
return B_OK;
}
status_t
_PPPPFCHandler::ParseRequest(const PPPConfigurePacket& request,
int32 index, PPPConfigurePacket& nak, PPPConfigurePacket& reject)
{
if(!request.ItemWithType(PFC_TYPE))
return B_OK;
if((Interface().PFCOptions() & PPP_ALLOW_PFC) == 0) {
ppp_configure_item item;
item.type = PFC_TYPE;
item.length = 2;
return reject.AddItem(&item) ? B_OK : B_ERROR;
}
return B_OK;
}
status_t
_PPPPFCHandler::SendingAck(const PPPConfigurePacket& ack)
{
ppp_configure_item *item = ack.ItemWithType(PFC_TYPE);
if(item && (Interface().PFCOptions() & PPP_ALLOW_PFC) == 0)
return B_ERROR;
if(item)
fPeerPFCState = PPP_PFC_ACCEPTED;
else
fPeerPFCState = PPP_PFC_DISABLED;
return B_OK;
}
void
_PPPPFCHandler::Reset()
{
fLocalPFCState = fPeerPFCState = PPP_PFC_DISABLED;
}

View File

@ -0,0 +1,35 @@
//----------------------------------------------------------------------
// This software is part of the OpenBeOS distribution and is covered
// by the OpenBeOS license.
//
// Copyright (c) 2003 Waldemar Kornewald, Waldemar.Kornewald@web.de
//---------------------------------------------------------------------
#ifndef __K_PPP_PFC_HANDLER__H
#define __K_PPP_PFC_HANDLER__H
#include <KPPPOptionHandler.h>
class _PPPPFCHandler : public PPPOptionHandler {
public:
_PPPPFCHandler(ppp_pfc_state& localPFCState, ppp_pfc_state& peerPFCState,
PPPInterface& interface);
virtual status_t AddToRequest(PPPConfigurePacket& request);
virtual status_t ParseNak(const PPPConfigurePacket& nak);
virtual status_t ParseReject(const PPPConfigurePacket& reject);
virtual status_t ParseAck(const PPPConfigurePacket& ack);
virtual status_t ParseRequest(const PPPConfigurePacket& request,
int32 index, PPPConfigurePacket& nak, PPPConfigurePacket& reject);
virtual status_t SendingAck(const PPPConfigurePacket& ack);
virtual void Reset();
private:
ppp_pfc_state &fLocalPFCState, &fPeerPFCState;
};
#endif

View File

@ -0,0 +1,22 @@
//----------------------------------------------------------------------
// This software is part of the OpenBeOS distribution and is covered
// by the OpenBeOS license.
//
// Copyright (c) 2003 Waldemar Kornewald, Waldemar.Kornewald@web.de
//---------------------------------------------------------------------
#ifndef _K_PPP__H
#define _K_PPP__H
#include <KPPPConfigurePacket.h>
#include <KPPPDevice.h>
// includes KPPPInterface.h, KPPPLCP.h,
// KPPPStateMachine.h and KPPPProtocol.h
#include <KPPPEncapsulator.h>
#include <KPPPLCPExtension.h>
#include <KPPPOptionHandler.h>
#include <PPPControl.h>
#endif

View File

@ -0,0 +1,59 @@
//----------------------------------------------------------------------
// 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_CONFIGURE_PACKET__H
#define _K_PPP_CONFIGURE_PACKET__H
#include <mbuf.h>
#include <List.h>
typedef struct ppp_configure_item {
uint8 type;
uint8 length;
int8 data[0];
// the data follows this structure
} ppp_configure_item;
class PPPConfigurePacket {
private:
// copies are not allowed!
PPPConfigurePacket(const PPPConfigurePacket& copy);
PPPConfigurePacket& operator= (const PPPConfigurePacket& copy);
public:
PPPConfigurePacket(uint8 code);
PPPConfigurePacket(struct mbuf *packet);
~PPPConfigurePacket();
bool SetCode(uint8 code);
uint8 Code() const
{ return fCode; }
void SetID(uint8 id)
{ fID = id; }
uint8 ID() const
{ return fID; }
bool AddItem(const ppp_configure_item *item, int32 index = -1);
bool RemoveItem(ppp_configure_item *item);
int32 CountItems() const
{ return fItems.CountItems(); }
ppp_configure_item *ItemAt(int32 index) const;
ppp_configure_item *ItemWithType(uint8 type) const;
struct mbuf *ToMbuf(uint32 reserve = 0);
// the user is responsible for freeing the mbuf
private:
uint8 fCode, fID;
List<ppp_configure_item*> fItems;
};
#endif

View File

@ -0,0 +1,70 @@
//----------------------------------------------------------------------
// 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_DEFS__H
#define _K_PPP_DEFS__H
#include <PPPDefs.h>
typedef uint32 interface_id;
// various constants
#define PPP_PULSE_RATE 500000
// module key types (used when loading a module)
enum ppp_module_key_type {
PPP_UNDEFINED_KEY_TYPE = -1,
PPP_LOAD_MODULE_KEY_TYPE = 0,
PPP_DEVICE_KEY_TYPE,
PPP_PROTOCOL_KEY_TYPE,
PPP_AUTHENTICATOR_KEY_TYPE,
PPP_MULTILINK_KEY_TYPE
};
// 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 codes as defined in RFC 1661
// ToDo: add LCP extensions
enum ppp_lcp_code {
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
};
#define PPP_MIN_LCP_CODE PPP_CONFIGURE_REQUEST
#define PPP_MAX_LCP_CODE PPP_DISCARD_REQUEST
#endif

View File

@ -0,0 +1,92 @@
//----------------------------------------------------------------------
// 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_DEVICE__H
#define _K_PPP_DEVICE__H
#include <KPPPDefs.h>
#ifndef _K_PPP_INTERFACE__H
#include <KPPPInterface.h>
#endif
class PPPDevice {
public:
PPPDevice(const char *name, PPPInterface& interface,
driver_parameter *settings);
virtual ~PPPDevice();
virtual status_t InitCheck() const;
const char *Name() const
{ return fName; }
PPPInterface& Interface() const
{ return fInterface; }
driver_parameter *Settings() const
{ return fSettings; }
virtual status_t Control(uint32 op, void *data, size_t length);
uint32 MTU() const
{ return fMTU; }
// these calls must not block
virtual void Up() = 0;
virtual void Down() = 0;
virtual void Listen() = 0;
bool IsUp() const
{ return fIsUp; }
// The biggest of the two tranfer rates will be set in ifnet.
// These methods should return default values when disconnected.
virtual uint32 InputTransferRate() const = 0;
virtual uint32 OutputTransferRate() const = 0;
virtual uint32 CountOutputBytes() const = 0;
// how many bytes are waiting to be sent?
virtual status_t Send(struct mbuf *packet) = 0;
// This should enqueue the packet and return immediately.
// The device is responsible for freeing the packet.
status_t PassToInterface(struct mbuf *packet);
// 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:
void SetMTU(uint32 MTU)
{ fMTU = MTU; }
// Report that we are going up/down
// (from now on, the Up() process can be aborted).
// Abort if false is returned!
bool UpStarted() const;
bool DownStarted() const;
// report up/down events
void UpFailedEvent();
void UpEvent();
void DownEvent();
protected:
uint32 fMTU;
// always hold this value up-to-date!
bool fIsUp;
status_t fInitStatus;
private:
char *fName;
PPPInterface& fInterface;
driver_parameter *fSettings;
};
#endif

View File

@ -0,0 +1,128 @@
//----------------------------------------------------------------------
// 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_ENCAPSULATOR__H
#define _K_PPP_ENCAPSULATOR__H
#include <KPPPDefs.h>
#ifndef _K_PPP_INTERFACE__H
#include <KPPPInterface.h>
#endif
class PPPEncapsulator {
public:
PPPEncapsulator(const char *name, ppp_phase phase,
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;
const char *Name() const
{ return fName; }
ppp_phase Phase() const
{ return fPhase; }
ppp_encapsulation_level Level() const
{ return fLevel; }
uint32 Overhead() const
{ return fOverhead; }
PPPInterface& Interface() const
{ return fInterface; }
driver_parameter *Settings() const
{ return fSettings; }
uint16 Protocol() const
{ return fProtocol; }
int32 AddressFamily() const
{ return fAddressFamily; }
// negative values and values > 0xFF are ignored
int32 Flags() const
{ return fFlags; }
ppp_side Side() const
{ return fSide; }
// which side this encapsulator works for
void SetEnabled(bool enabled = true);
bool IsEnabled() const
{ return fEnabled; }
bool IsUpRequested() const
{ return fUpRequested; }
virtual status_t Control(uint32 op, void *data, size_t length);
virtual status_t StackControl(uint32 op, void *data);
// called by netstack (forwarded by PPPInterface)
void SetNext(PPPEncapsulator *next)
{ fNext = next; }
PPPEncapsulator *Next() const
{ return fNext; }
virtual bool Up() = 0;
virtual bool Down() = 0;
bool IsUp() const
{ return fConnectionStatus == PPP_ESTABLISHED_PHASE; }
bool IsDown() const
{ return fConnectionStatus == PPP_DOWN_PHASE; }
bool IsGoingUp() const
{ return fConnectionStatus == PPP_ESTABLISHMENT_PHASE; }
bool IsGoingDown() const
{ return fConnectionStatus == PPP_TERMINATION_PHASE; }
virtual status_t Send(struct mbuf *packet, uint16 protocol) = 0;
virtual status_t Receive(struct mbuf *packet, uint16 protocol) = 0;
status_t SendToNext(struct 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 SetUpRequested(bool requested = true)
{ fUpRequested = requested; }
void UpStarted();
void DownStarted();
void UpFailedEvent();
void UpEvent();
void DownEvent();
// report up/down events
protected:
uint32 fOverhead;
ppp_side fSide;
status_t fInitStatus;
private:
char *fName;
ppp_phase fPhase;
ppp_encapsulation_level fLevel;
uint16 fProtocol;
int32 fAddressFamily;
PPPInterface& fInterface;
driver_parameter *fSettings;
int32 fFlags;
PPPEncapsulator *fNext;
bool fEnabled;
bool fUpRequested;
ppp_phase fConnectionStatus;
};
#endif

View File

@ -0,0 +1,252 @@
//----------------------------------------------------------------------
// 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_INTERFACE__H
#define _K_PPP_INTERFACE__H
#include <driver_settings.h>
#include <KPPPDefs.h>
#ifndef _K_PPP_LCP__H
#include <KPPPLCP.h>
#endif
#include <KPPPReportManager.h>
#ifndef _K_PPP_STATE_MACHINE__H
#include <KPPPStateMachine.h>
#endif
#include <List.h>
#include <LockerHelper.h>
class PPPDevice;
class PPPProtocol;
class PPPEncapsulator;
class PPPOptionHandler;
struct ppp_manager_info;
struct ppp_module_info;
class PPPInterface {
friend class PPPStateMachine;
friend class PPPManager;
private:
// copies are not allowed!
PPPInterface(const PPPInterface& copy);
PPPInterface& operator= (const PPPInterface& copy);
// only PPPManager may construct us!
PPPInterface(interface_id ID, driver_settings *settings,
PPPInterface *parent = NULL);
~PPPInterface();
public:
void Delete();
status_t InitCheck() const;
interface_id ID() const
{ return fID; }
driver_settings* Settings() const
{ return fSettings; }
PPPStateMachine& StateMachine()
{ return fStateMachine; }
PPPLCP& LCP()
{ return fLCP; }
struct ifnet *Ifnet() const
{ return fIfnet; }
struct ifq *InQueue() const
{ return fInQueue; }
// delays
uint32 DialRetryDelay() const
{ return fDialRetryDelay; }
uint32 RedialDelay() const
{ return fRedialDelay; }
// idle handling
uint32 IdleSince() const
{ return fIdleSince; }
uint32 DisconnectAfterIdleSince() const
{ return fDisconnectAfterIdleSince; }
bool SetMRU(uint32 MRU);
uint32 MRU() const
{ return fMRU; }
// this is the smallest MRU that we and the peer have
bool SetInterfaceMTU(uint32 interfaceMTU)
{ return SetMRU(interfaceMTU - fHeaderLength); }
uint32 InterfaceMTU() const
{ return fInterfaceMTU; }
// this is the MRU including encapsulator overhead
status_t Control(uint32 op, void *data, size_t length);
bool SetDevice(PPPDevice *device);
PPPDevice *Device() const
{ return fDevice; }
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 = NULL) const;
int32 IndexOfProtocol(PPPProtocol *protocol) const
{ return fProtocols.IndexOf(protocol); }
bool AddEncapsulator(PPPEncapsulator *encapsulator);
bool RemoveEncapsulator(PPPEncapsulator *encapsulator);
int32 CountEncapsulators() const;
PPPEncapsulator *EncapsulatorAt(int32 index) const;
PPPEncapsulator *FirstEncapsulator() const
{ return fFirstEncapsulator; }
PPPEncapsulator *EncapsulatorFor(uint16 protocol,
PPPEncapsulator *start = NULL) const;
// multilink methods
bool AddChild(PPPInterface *child);
bool RemoveChild(PPPInterface *child);
int32 CountChildren() const
{ return fChildren.CountItems(); }
PPPInterface *ChildAt(int32 index) const;
PPPInterface *Parent() const
{ return fParent; }
bool IsMultilink() const
{ return fIsMultilink; }
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 fStateMachine.State(); }
ppp_phase Phase() const
{ return fStateMachine.Phase(); }
// Protocol-Field-Compression
bool SetPFCOptions(uint8 pfcOptions);
uint8 PFCOptions() const
{ return fPFCOptions; }
ppp_pfc_state LocalPFCState() const
{ return fLocalPFCState; }
// the local PFC state says if we accepted a request from the peer
// i.e.: we may use PFC in outgoing packets
ppp_pfc_state PeerPFCState() const
{ return fPeerPFCState; }
// the peer PFC state says if the peer accepted a request us
// i.e.: the peer might send PFC-compressed packets to us
bool UseLocalPFC() const
{ return LocalPFCState() & PPP_PFC_ACCEPTED; }
bool Up();
// in server mode Up() listens for an incoming connection
bool Down();
bool IsUp() const;
PPPReportManager& ReportManager()
{ return fReportManager; }
bool Report(ppp_report_type type, int32 code, void *data, int32 length)
{ return fReportManager.Report(type, code, data, length); }
// returns false if reply was bad (or an error occured)
bool LoadModules(driver_settings *settings,
int32 start, int32 count);
bool LoadModule(const char *name, driver_parameter *parameter,
ppp_module_key_type type);
status_t Send(struct mbuf *packet, uint16 protocol);
status_t Receive(struct mbuf *packet, uint16 protocol);
status_t SendToDevice(struct mbuf *packet, uint16 protocol);
status_t ReceiveFromDevice(struct mbuf *packet);
// This is called by the receive-thread.
// Only call this if it does not block Send() or
// SendToDevice()!
void Pulse();
// this manages all timeouts, etc.
private:
bool RegisterInterface();
// adds us to the manager module and
// saves the returned ifnet structure
bool UnregisterInterface();
status_t StackControl(uint32 op, void *data);
// stack routes ioctls to interface
status_t StackControlEachHandler(uint32 op, void *data);
// this calls StackControl() with the given parameters for each handler
void CalculateInterfaceMTU();
void CalculateBaudRate();
void Redial(uint32 delay);
// multilink methods
void SetParent(PPPInterface *parent)
{ fParent = parent; }
private:
interface_id fID;
// the manager assigns an ID to every interface
driver_settings *fSettings;
PPPStateMachine fStateMachine;
PPPLCP fLCP;
PPPReportManager fReportManager;
struct ifnet *fIfnet;
thread_id fUpThread, fInQueueThread;
struct ifq *fInQueue;
thread_id fRedialThread;
uint32 fDialRetry, fDialRetriesLimit;
uint32 fDialRetryDelay, fRedialDelay;
ppp_manager_info *fManager;
uint32 fIdleSince, fDisconnectAfterIdleSince;
uint32 fMRU, fInterfaceMTU, fHeaderLength;
PPPInterface *fParent;
List<PPPInterface*> fChildren;
bool fIsMultilink;
bool fAutoRedial, fDialOnDemand;
ppp_mode fMode;
ppp_pfc_state fLocalPFCState, fPeerPFCState;
uint8 fPFCOptions;
PPPDevice *fDevice;
PPPEncapsulator *fFirstEncapsulator;
List<PPPProtocol*> fProtocols;
List<char*> fModules;
BLocker& fLock;
status_t fInitStatus;
int32 fDeleteCounter;
};
#endif

View File

@ -0,0 +1,96 @@
//----------------------------------------------------------------------
// 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__H
#define _K_PPP_LCP__H
#include <List.h>
#ifndef _K_PPP_PROTOCOL__H
#include <KPPPProtocol.h>
#endif
#ifndef _K_PPP_INTERFACE__H
#include <KPPPInterface.h>
#endif
#ifndef _K_PPP_STATE_MACHINE__H
#include <KPPPStateMachine.h>
#endif
class PPPEncapsulator;
class PPPLCPExtension;
class PPPOptionHandler;
typedef struct ppp_lcp_packet {
uint8 code;
uint8 id;
uint16 length;
uint8 data[0];
} ppp_lcp_packet;
class PPPLCP : public PPPProtocol {
friend class PPPInterface;
private:
// may only be constructed/destructed by PPPInterface
PPPLCP(PPPInterface& interface);
virtual ~PPPLCP();
// copies are not allowed!
PPPLCP(const PPPLCP& copy);
PPPLCP& operator= (const PPPLCP& copy);
public:
PPPStateMachine& StateMachine() const
{ return fStateMachine; }
bool AddOptionHandler(PPPOptionHandler *handler);
bool RemoveOptionHandler(PPPOptionHandler *handler);
int32 CountOptionHandlers() const
{ return fOptionHandlers.CountItems(); }
PPPOptionHandler *OptionHandlerAt(int32 index) const;
PPPOptionHandler *OptionHandlerFor(uint8 type, int32 *start = NULL) const;
bool AddLCPExtension(PPPLCPExtension *extension);
bool RemoveLCPExtension(PPPLCPExtension *extension);
int32 CountLCPExtensions() const
{ return fLCPExtensions.CountItems(); }
PPPLCPExtension *LCPExtensionAt(int32 index) const;
PPPLCPExtension *LCPExtensionFor(uint8 code, int32 *start = NULL) 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
virtual bool Up();
virtual bool Down();
virtual status_t Send(struct mbuf *packet);
virtual status_t Receive(struct mbuf *packet, uint16 protocol);
virtual void Pulse();
private:
PPPStateMachine& fStateMachine;
List<PPPOptionHandler*> fOptionHandlers;
List<PPPLCPExtension*> fLCPExtensions;
PPPEncapsulator *fTarget;
};
#endif

View File

@ -0,0 +1,64 @@
//----------------------------------------------------------------------
// 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 status_t StackControl(uint32 op, void *data);
// called by netstack (forwarded by PPPInterface)
virtual status_t Receive(struct mbuf *packet, uint8 code) = 0;
virtual void Reset();
virtual void Pulse();
protected:
status_t fInitStatus;
private:
char *fName;
PPPInterface& fInterface;
driver_parameter *fSettings;
uint8 fCode;
bool fEnabled;
};
#endif

View File

@ -0,0 +1,48 @@
//----------------------------------------------------------------------
// 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_MANAGER__H
#define _K_PPP_MANAGER__H
#include "net_module.h"
#define PPP_MANAGER_MODULE_NAME "network/interfaces/ppp"
#define PPP_UNDEFINED_INTERFACE_ID 0
// create_interface() returns this value on failure
// this allows you to ask for specific interface_ids
enum ppp_interface_filter {
PPP_ALL_INTERFACES,
PPP_REGISTERED_INTERFACES,
PPP_UNREGISTERED_INTERFACES
};
typedef struct ppp_manager_info {
kernel_net_module_info knminfo;
interface_id (*create_interface)(const 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
void (*remove_interface)(interface_id ID);
// remove the interface from database (make sure you can delete it yourself!)
ifnet* (*register_interface)(interface_id ID);
bool (*unregister_interface)(interface_id ID);
status_t (*control)(interface_id ID, uint32 op, void *data, size_t length);
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

View File

@ -0,0 +1,28 @@
//----------------------------------------------------------------------
// 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_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& mainInterface, PPPInterface *subInterface,
driver_parameter *settings, ppp_module_key_type type);
// multilink: handlers that must run on a real device
// should be added to subInterface (may be NULL)
// while mainInterface handlers are used for the
// bundle of interfaces
} ppp_module_info;
#endif

View File

@ -0,0 +1,81 @@
//----------------------------------------------------------------------
// 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_OPTION_HANDLER__H
#define _K_PPP_OPTION_HANDLER__H
#include <KPPPDefs.h>
#ifndef _K_PPP_INTERFACE__H
#include <KPPPInterface.h>
#endif
class PPPConfigurePacket;
class PPPOptionHandler {
public:
PPPOptionHandler(const char *name, uint8 type, PPPInterface& interface,
driver_parameter *settings);
virtual ~PPPOptionHandler();
virtual status_t InitCheck() const;
const char *Name() const
{ return fName; }
uint8 Type() const
{ return fType; }
PPPInterface& Interface() const
{ return fInterface; }
driver_parameter *Settings() const
{ return fSettings; }
void SetEnabled(bool enabled = true)
{ fEnabled = enabled; }
bool IsEnabled() const
{ return fEnabled; }
virtual status_t Control(uint32 op, void *data, size_t length);
virtual status_t StackControl(uint32 op, void *data);
// called by netstack (forwarded by PPPInterface)
// we want to send a configure request or we received a reply
virtual status_t AddToRequest(PPPConfigurePacket& request) = 0;
virtual status_t ParseNak(const PPPConfigurePacket& nak) = 0;
// create next request based on these and previous values
virtual status_t ParseReject(const PPPConfigurePacket& reject) = 0;
// create next request based on these and previous values
virtual status_t ParseAck(const PPPConfigurePacket& ack) = 0;
// this is called for all handlers
// peer sent configure request
virtual status_t ParseRequest(const PPPConfigurePacket& request,
int32 index, PPPConfigurePacket& nak, PPPConfigurePacket& reject) = 0;
// index may be behind the last item which means additional values can be
// appended
virtual status_t SendingAck(const PPPConfigurePacket& ack) = 0;
// notification that we ack these values
virtual void Reset() = 0;
// e.g.: remove list of rejected values
protected:
status_t fInitStatus;
private:
char *fName;
uint8 fType;
PPPInterface& fInterface;
driver_parameter *fSettings;
bool fEnabled;
};
#endif

View File

@ -0,0 +1,116 @@
//----------------------------------------------------------------------
// 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_PROTOCOL__H
#define _K_PPP_PROTOCOL__H
#include <KPPPDefs.h>
class PPPInterface;
class PPPOptionHandler;
class PPPProtocol {
public:
PPPProtocol(const char *name, ppp_phase phase, uint16 protocol,
int32 addressFamily, PPPInterface& interface,
driver_parameter *settings, int32 flags = PPP_NO_FLAGS,
const char *type = NULL, PPPOptionHandler *optionHandler = NULL);
virtual ~PPPProtocol();
virtual status_t InitCheck() const;
const char *Name() const
{ return fName; }
ppp_phase Phase() const
{ return fPhase; }
PPPInterface& Interface() const
{ return fInterface; }
driver_parameter *Settings() const
{ return fSettings; }
uint16 Protocol() const
{ return fProtocol; }
int32 AddressFamily() const
{ return fAddressFamily; }
// negative values and values > 0xFF are ignored
int32 Flags() const
{ return fFlags; }
ppp_side Side() const
{ return fSide; }
// which side this protocol works for
// extensions
const char *Type() const
{ return fType; }
PPPOptionHandler *OptionHandler() const
{ return fOptionHandler; }
void SetEnabled(bool enabled = true);
bool IsEnabled() const
{ return fEnabled; }
bool IsUpRequested() const
{ return fUpRequested; }
virtual status_t Control(uint32 op, void *data, size_t length);
virtual status_t StackControl(uint32 op, void *data);
// called by netstack (forwarded by PPPInterface)
virtual bool Up() = 0;
virtual bool Down() = 0;
// if DialOnDemand is supported check for DialOnDemand settings change
bool IsUp() const
{ return fConnectionStatus == PPP_ESTABLISHED_PHASE; }
bool IsDown() const
{ return fConnectionStatus == PPP_DOWN_PHASE; }
bool IsGoingUp() const
{ return fConnectionStatus == PPP_ESTABLISHMENT_PHASE; }
bool IsGoingDown() const
{ return fConnectionStatus == PPP_TERMINATION_PHASE; }
virtual status_t Send(struct mbuf *packet) = 0;
virtual status_t Receive(struct mbuf *packet, uint16 protocol) = 0;
virtual void Pulse();
protected:
void SetUpRequested(bool requested = true)
{ fUpRequested = requested; }
void UpStarted();
void DownStarted();
void UpFailedEvent();
void UpEvent();
void DownEvent();
// report up/down events
protected:
ppp_side fSide;
status_t fInitStatus;
private:
char *fName;
ppp_phase fPhase;
uint16 fProtocol;
int32 fAddressFamily;
PPPInterface& fInterface;
driver_parameter *fSettings;
int32 fFlags;
char *fType;
PPPOptionHandler *fOptionHandler;
bool fEnabled;
bool fUpRequested;
ppp_phase fConnectionStatus;
};
#endif

View File

@ -0,0 +1,39 @@
//----------------------------------------------------------------------
// 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_MANAGER__H
#define _K_PPP_REPORT_MANAGER__H
#include <OS.h>
#include <KPPPDefs.h>
#include <PPPReportDefs.h>
#include <List.h>
#define PPP_REPLY(sender, value) send_data_with_timeout((sender), (value), NULL, 0, PPP_REPORT_TIMEOUT)
class PPPReportManager {
public:
PPPReportManager(BLocker& lock);
~PPPReportManager();
void EnableReports(ppp_report_type type, thread_id thread,
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);
// returns false if reply was bad (or an error occured)
private:
BLocker& fLock;
List<ppp_report_request*> fReportRequests;
};
#endif

View File

@ -0,0 +1,177 @@
//----------------------------------------------------------------------
// 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_STATE_MACHINE__H
#define _K_PPP_STATE_MACHINE__H
#include <KPPPDefs.h>
class PPPEncapsulator;
class PPPProtocol;
#ifndef _K_PPP_INTERFACE__H
#include <KPPPInterface.h>
#endif
#include <Locker.h>
class PPPStateMachine {
friend class PPPInterface;
friend class PPPLCP;
private:
// may only be constructed/destructed by PPPInterface
PPPStateMachine(PPPInterface& interface);
~PPPStateMachine();
// copies are not allowed!
PPPStateMachine(const PPPStateMachine& copy);
PPPStateMachine& operator= (const PPPStateMachine& copy);
public:
PPPInterface& Interface() const
{ return fInterface; }
PPPLCP& LCP() const
{ return fLCP; }
ppp_state State() const
{ return fState; }
ppp_phase Phase() const
{ return fPhase; }
uint8 NextID();
// return the next id for LCP packets
void SetMagicNumber(uint32 magicNumber)
{ fMagicNumber = magicNumber; }
uint32 MagicNumber() const
{ return fMagicNumber; }
// public actions
bool Reconfigure();
bool SendEchoRequest();
bool SendDiscardRequest();
// public events
void LocalAuthenticationRequested();
void LocalAuthenticationAccepted(const char *name);
void LocalAuthenticationDenied(const char *name);
const char *LocalAuthenticationName() const
{ return fLocalAuthenticationName; }
ppp_authentication_status LocalAuthenticationStatus() const
{ return fLocalAuthenticationStatus; }
void PeerAuthenticationRequested();
void PeerAuthenticationAccepted(const char *name);
void PeerAuthenticationDenied(const char *name);
const char *PeerAuthenticationName() const
{ return fPeerAuthenticationName; }
ppp_authentication_status PeerAuthenticationStatus() const
{ return fPeerAuthenticationStatus; }
// sub-interface events
void UpFailedEvent(PPPInterface& interface);
void UpEvent(PPPInterface& interface);
void DownEvent(PPPInterface& interface);
// protocol events
void UpFailedEvent(PPPProtocol *protocol);
void UpEvent(PPPProtocol *protocol);
void DownEvent(PPPProtocol *protocol);
// encapsulator events
void UpFailedEvent(PPPEncapsulator *encapsulator);
void UpEvent(PPPEncapsulator *encapsulator);
void DownEvent(PPPEncapsulator *encapsulator);
// device events
bool TLSNotify();
bool TLFNotify();
void UpFailedEvent();
void UpEvent();
void DownEvent();
private:
BLocker& Locker()
{ return fLock; }
// private StateMachine methods
void NewState(ppp_state next);
void NewPhase(ppp_phase next);
// private events
void OpenEvent();
void CloseEvent();
void TOGoodEvent();
void TOBadEvent();
void RCRGoodEvent(struct mbuf *packet);
void RCRBadEvent(struct mbuf *nak, struct mbuf *reject);
void RCAEvent(struct mbuf *packet);
void RCNEvent(struct mbuf *packet);
void RTREvent(struct mbuf *packet);
void RTAEvent(struct mbuf *packet);
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);
// general events (for Good/Bad events)
void TimerEvent();
void RCREvent(struct mbuf *packet);
void RXJEvent(struct mbuf *packet);
// actions
void IllegalEvent(ppp_event event);
void ThisLayerUp();
void ThisLayerDown();
void ThisLayerStarted();
void ThisLayerFinished();
void InitializeRestartCount();
void ZeroRestartCount();
bool SendConfigureRequest();
bool SendConfigureAck(struct mbuf *packet);
bool SendConfigureNak(struct mbuf *packet);
bool SendTerminateRequest();
bool SendTerminateAck(struct mbuf *request = NULL);
bool SendCodeReject(struct mbuf *packet, uint16 protocol, uint8 code);
bool SendEchoReply(struct mbuf *request);
void BringHandlersUp();
uint32 BringPhaseUp();
void DownProtocols();
void DownEncapsulators();
void ResetLCPHandlers();
private:
PPPInterface& fInterface;
PPPLCP& fLCP;
ppp_phase fPhase;
ppp_state fState;
vint32 fID;
uint32 fMagicNumber;
ppp_authentication_status fLocalAuthenticationStatus,
fPeerAuthenticationStatus;
char *fLocalAuthenticationName, *fPeerAuthenticationName;
BLocker fLock;
// counters and timers
int32 fMaxRequest, fMaxTerminate, fMaxNak;
int32 fRequestCounter, fTerminateCounter, fNakCounter;
uint8 fRequestID, fTerminateID, fEchoID;
// the ID we used for the last configure/terminate/echo request
bigtime_t fNextTimeout;
};
#endif

View File

@ -0,0 +1,55 @@
//----------------------------------------------------------------------
// 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_UTILS__H
#define _K_PPP_UTILS__H
#ifndef _K_PPP_DEFS__H
#include <KPPPDefs.h>
#endif
// helper functions
template<class T>
inline
bool
is_handler_allowed(T& handler, ppp_state state, ppp_phase phase)
{
if(handler.Protocol() == PPP_LCP_PROTOCOL)
return true;
else if(state != PPP_OPENED_STATE)
return false;
else if(phase > PPP_AUTHENTICATION_PHASE
|| (phase >= PPP_ESTABLISHMENT_PHASE
&& handler.Flags() & PPP_ALWAYS_ALLOWED))
return true;
else
return false;
}
// the list template does not support iterating over each item :(
// this template iterates over each item in an indexed list
template<class _LIST, class _FUNCTION>
inline
void
ForEachItem(_LIST& list, _FUNCTION function)
{
for(int index = 0; index < list.CountItems(); index++)
function(list.ItemAt(index));
}
// These are very simple send/receive_data functions with a timeout
// and there is a race condition beween has_data() and send/receive_data().
// Timeouts in ms.
status_t send_data_with_timeout(thread_id thread, int32 code, void *buffer,
size_t buffer_size, uint32 timeout);
status_t receive_data_with_timeout(thread_id *sender, int32 *code, void *buffer,
size_t buffer_size, uint32 timeout);
#endif

View 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

View File

@ -0,0 +1,56 @@
//----------------------------------------------------------------------
// This software is part of the OpenBeOS distribution and is covered
// by the OpenBeOS license.
//
// Copyright (c) 2003 Waldemar Kornewald, Waldemar.Kornewald@web.de
//---------------------------------------------------------------------
/*
* 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 {
private:
// copies are not allowed!
LockerHelper(const LockerHelper& copy);
LockerHelper& operator= (const LockerHelper& copy);
public:
LockerHelper(BLocker& lock) : fLock(&lock)
{
if(!fLock->Lock())
fLock = NULL;
}
~LockerHelper()
{
if(fLock)
fLock->Unlock();
}
void UnlockNow()
{
if(fLock)
fLock->Unlock();
fLock = NULL;
}
private:
BLocker *fLock;
};
#endif

View File

@ -0,0 +1,181 @@
//----------------------------------------------------------------------
// 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 _PPP_CONTROL__H
#define _PPP_CONTROL__H
#include <Drivers.h>
#include <PPPDefs.h>
// various constants
#define PPP_HANDLER_NAME_LENGTH_LIMIT 63
// if the name is longer than this value it will be truncated to fit the structure
// starting values and other values for control ops
#define PPP_RESERVE_OPS_COUNT 0xFFFF
#define PPP_OPS_START B_DEVICE_OP_CODES_END + 1
#define PPP_INTERFACE_OPS_START PPP_OPS_START + PPP_RESERVE_OPS_COUNT
#define PPP_DEVICE_OPS_START PPP_OPS_START + 2 * PPP_RESERVE_OPS_COUNT
#define PPP_PROTOCOL_OPS_START PPP_OPS_START + 3 * PPP_RESERVE_OPS_COUNT
#define PPP_ENCAPSULATOR_OPS_START PPP_OPS_START + 4 * PPP_RESERVE_OPS_COUNT
#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_USER_OPS_START PPP_OPS_START + 32 * PPP_RESERVE_OPS_COUNT
enum ppp_control_ops {
// -----------------------------------------------------
// PPPInterface
PPPC_GET_INTERFACE_INFO = PPP_INTERFACE_OPS_START,
PPPC_SET_MRU,
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,
PPPC_CONTROL_ENCAPSULATOR,
PPPC_CONTROL_OPTION_HANDLER,
PPPC_CONTROL_LCP_EXTENSION,
PPPC_CONTROL_CHILD,
// -----------------------------------------------------
// -----------------------------------------------------
// PPPDevice
PPPC_GET_DEVICE_INFO = PPP_DEVICE_OPS_START,
// -----------------------------------------------------
// -----------------------------------------------------
// Common/mixed ops
PPPC_GET_HANDLER_INFO = PPP_COMMON_OPS_START,
// PPPProtocol and PPPEncapsulator
PPPC_SET_ENABLED,
PPPC_GET_SIMPLE_HANDLER_INFO,
// PPPOptionHandler and PPPLCPExtension
// -----------------------------------------------------
PPP_CONTROL_OPS_END = B_DEVICE_OP_CODES_END + 0xFFFF
};
typedef struct ppp_control_info {
uint32 index;
// index of interface/protocol/encapsulator/etc.
uint32 op;
// the Control()/ioctl() opcode
void *data;
size_t length;
// should always be set
} ppp_control_info;
// -----------------------------------------------------------
// structures for storing information about interface/handlers
// use the xxx_info_t structures when allocating memory (they
// reserve memory for future implementations)
// -----------------------------------------------------------
#define _PPP_INFO_T_SIZE_ 256
typedef struct ppp_interface_info {
const driver_settings *settings;
ppp_mode mode;
ppp_state state;
ppp_phase phase;
ppp_authentication_status localAuthenticationStatus, peerAuthenticationStatus;
ppp_pfc_state localPFCState, peerPFCState;
uint8 pfcOptions;
uint32 protocolsCount, encapsulatorsCount, optionHandlersCount,
LCPExtensionsCount, childrenCount;
uint32 MRU, interfaceMTU;
uint32 dialRetry, dialRetriesLimit;
uint32 dialRetryDelay, redialDelay;
uint32 idleSince, disconnectAfterIdleSince;
bool doesDialOnDemand, doesAutoRedial, hasDevice, isMultilink, hasParent;
} ppp_interface_info;
typedef struct ppp_interface_info_t {
ppp_interface_info info;
uint8 _reserved_[_PPP_INFO_T_SIZE_ - sizeof(ppp_interface_info)];
} ppp_interface_info_t;
// devices are special handlers, so they have their own structure
typedef struct ppp_device_info {
char name[PPP_HANDLER_NAME_LENGTH_LIMIT + 1];
const driver_parameter *settings;
uint32 MTU;
uint32 inputTransferRate, outputTransferRate, outputBytesCount;
} ppp_device_info;
typedef struct ppp_device_info_t {
ppp_device_info info;
uint8 _reserved_[_PPP_INFO_T_SIZE_ - sizeof(ppp_device_info)];
} ppp_device_info_t;
typedef struct ppp_handler_info {
char name[PPP_HANDLER_NAME_LENGTH_LIMIT + 1];
// general
const driver_parameter *settings;
ppp_phase phase;
int32 addressFamily, flags;
ppp_side side;
uint16 protocol;
bool isEnabled;
// only protocol and encapsulator
bool isUpRequested;
ppp_phase connectionStatus;
// there are four possible states:
// PPP_ESTABLISHED_PHASE - IsUp() == true
// PPP_DOWN_PHASE - IsDown() == true
// PPP_ESTABLISHMENT_PHASE - IsGoingUp() == true
// PPP_TERMINATION_PHASE - IsGoingDown() == true
// only protocol
char type[PPP_HANDLER_NAME_LENGTH_LIMIT + 1];
// only encapsulator
ppp_encapsulation_level level;
uint32 overhead;
} ppp_handler_info;
typedef struct ppp_handler_info_t {
ppp_handler_info info;
uint8 _reserved_[_PPP_INFO_T_SIZE_ - sizeof(ppp_handler_info)];
} ppp_handler_info_t;
typedef struct ppp_simple_handler_info {
char name[PPP_HANDLER_NAME_LENGTH_LIMIT + 1];
const driver_parameter *settings;
bool isEnabled;
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

View File

@ -0,0 +1,158 @@
//----------------------------------------------------------------------
// 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 _PPP_DEFS__H
#define _PPP_DEFS__H
#include <SupportDefs.h>
// settings keys
#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_MULTILINK_KEY "Multilink-Protocol"
// settings values
#define PPP_CLIENT_MODE_VALUE "Client"
#define PPP_SERVER_MODE_VALUE "Server"
// path defines
#define PPP_MODULES_PATH "network/ppp"
// built-in protocols
#define PPP_LCP_PROTOCOL 0xC021
#define PPP_ERROR_BASE B_ERRORS_END + 1
// return values for Send()/Receive() methods in addition to B_ERROR and B_OK
// PPP_UNHANDLED is also used by PPPOptionHandler
enum {
// B_ERROR means that the packet is corrupted
// B_OK means the packet was handled correctly
// return values for PPPProtocol and PPPEncapsulator (and PPPOptionHandler)
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
PPP_NO_CONNECTION
// could not send a packet because device is not connected
};
// PFC options
enum {
PPP_REQUEST_PFC = 0x01,
// try to request PFC (does not fail if not successful)
PPP_ALLOW_PFC = 0x02,
// allow PFC if other side requests it
PPP_FORCE_PFC_REQUEST = 0x04,
// if PFC request fails the connection attempt will terminate
PPP_FREEZE_PFC_OPTIONS = 0x80
// the options cannot be changed if this flag is set (mainly used by PPPDevice)
};
enum ppp_pfc_state {
PPP_PFC_DISABLED,
PPP_PFC_ACCEPTED,
PPP_PFC_REJECTED
// not used for peer state
};
// protocol and encapsulator flags
enum {
PPP_NO_FLAGS = 0x00,
PPP_ALWAYS_ALLOWED = 0x01,
// protocol may send/receive in Phase() >= PPP_ESTABLISHMENT_PHASE,
// but only LCP is allowed in State() != PPP_OPENED_STATE!
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)
PPP_NOT_IMPORTANT = 0x04,
// if this protocol fails to go up we do not disconnect
PPP_INCLUDES_NCP = 0x08
// This protocol includes the corresponding NCP protocol (e.g.: IPCP + IP).
// All protocol values will also be checked against Protocol() & 0x7FFF.
};
// 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_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_DEVICE_LEVEL = 0,
PPP_MULTILINK_LEVEL = 2,
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
};
// which side the protocol/encapsulator works for
enum ppp_side {
PPP_NO_SIDE,
PPP_LOCAL_SIDE,
PPP_PEER_SIDE,
PPP_BOTH_SIDES
};
// 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
};
#endif

View File

@ -0,0 +1,67 @@
//----------------------------------------------------------------------
// 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 _PPP_REPORT_DEFS__H
#define _PPP_REPORT_DEFS__H
#define PPP_REPORT_TIMEOUT 10
#define PPP_REPORT_DATA_LIMIT 128
// how much optional data can be added to the report
#define PPP_REPORT_CODE '_3PR'
// the code of receive_data() must have this value
// report flags
enum ppp_report_flags {
PPP_WAIT_FOR_REPLY = 0x1,
PPP_REMOVE_AFTER_REPORT = 0x2,
PPP_NO_REPLY_TIMEOUT = 0x4
};
// 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
};
// report codes (type-specific)
enum ppp_connection_report_codes {
PPP_REPORT_GOING_UP = 0,
PPP_REPORT_UP_SUCCESSFUL = 1,
PPP_REPORT_DOWN_SUCCESSFUL = 2,
PPP_REPORT_UP_ABORTED = 3,
PPP_REPORT_DEVICE_UP_FAILED = 4,
PPP_REPORT_LOCAL_AUTHENTICATION_SUCCESSFUL = 5,
PPP_REPORT_PEER_AUTHENTICATION_SUCCESSFUL = 6,
PPP_REPORT_LOCAL_AUTHENTICATION_FAILED = 7,
PPP_REPORT_PEER_AUTHENTICATION_FAILED = 8,
PPP_REPORT_CONNECTION_LOST = 9
};
typedef struct ppp_report_packet {
int32 type;
int32 code;
uint8 length;
char data[PPP_REPORT_DATA_LIMIT];
} ppp_report_packet;
typedef struct ppp_report_request {
ppp_report_type type;
thread_id thread;
int32 flags;
} ppp_report_request;
#endif

View File

@ -0,0 +1,148 @@
//----------------------------------------------------------------------
// 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 <KPPPDefs.h>
#include <driver_settings.h>
#include "settings_tools.h"
#include <cstring>
#include <malloc.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(!dup)
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(to->value_count * 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);
}
ppp_side
get_side_string_value(const char *sideString, ppp_side unknownValue)
{
if(!sideString)
return unknownValue;
if(!strcasecmp(sideString, "local"))
return PPP_LOCAL_SIDE;
if(!strcasecmp(sideString, "peer"))
return PPP_PEER_SIDE;
if(!strcasecmp(sideString, "none")
|| !strcasecmp(sideString, "no"))
return PPP_NO_SIDE;
if(!strcasecmp(sideString, "both"))
return PPP_BOTH_SIDES;
// no correct value has been found => return default value
return unknownValue;
}
bool
get_string_value(const char *string, bool unknownValue)
{
if(!string)
return unknownValue;
if (!strcmp(string, "1")
|| !strcasecmp(string, "true")
|| !strcasecmp(string, "yes")
|| !strcasecmp(string, "on")
|| !strcasecmp(string, "enable")
|| !strcasecmp(string, "enabled"))
return true;
if (!strcmp(string, "0")
|| !strcasecmp(string, "false")
|| !strcasecmp(string, "no")
|| !strcasecmp(string, "off")
|| !strcasecmp(string, "disable")
|| !strcasecmp(string, "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;
}

View File

@ -0,0 +1,27 @@
//----------------------------------------------------------------------
// 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 _SETTINGS_TOOLS__H
#define _SETTINGS_TOOLS__H
// remove this as soon as we get the extended driver_settings API
struct driver_settings;
struct driver_parameter;
driver_settings *dup_driver_settings(const driver_settings *settings);
void free_driver_settings(driver_settings *settings);
ppp_side get_side_string_value(const char *sideString, ppp_side unknownValue);
bool get_boolean_value(const char *string, bool unknownValue);
const char *get_settings_value(const char *name, const driver_settings *settings);
const char *get_parameter_value(const char *name, const driver_parameter *parameters)
{ return get_settings_value(name, (driver_settings*) &parameters->parameter_count); }
#endif