As the netstack has a bug I cannot work on the interface module before this is fixed. So I changed the API of the libkernelppp.a (although, this was planned for a later release).

PPPEncapsulator was removed. PPPProtocol is now a protocol and an encapsulator.
PPPDevice, PPPProtocol, and PPPInterface derive from PPPLayer. This base class simplifies the packet passing process and gives PPPDevice more flexibility as it now can add layers between itself and PPPInterface (which was not possible before). This feature will probably be used by the HDLC framing module.
Also, PPPProtocol will always send to the next layer which might either be another protocol, an encapsulator protocol, or the PPPInterface. No distinction is necessary anymore.

This all reduced the list template usage and made some methods simpler.
With this step I could reduce the size of the libkernelppp.a binary from >200K to 143K.

Now, I will go hunting bugs! :)


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@4928 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Waldemar Kornewald 2003-10-02 09:18:47 +00:00
parent f53ee751a9
commit 92a8026e02
34 changed files with 722 additions and 1210 deletions

View File

@ -1,18 +1,22 @@
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 ] ;
# for kernel_cpp.cpp/h and BLocker
SEARCH_SOURCE += [ FDirName $(OBOS_TOP) src kernel core util ] ;
SEARCH_SOURCE += [ FDirName $(OBOS_TOP) src kernel core disk_device_manager ] ;
UseHeaders [ FDirName $(OBOS_TOP) src add-ons kernel file_systems bfs ] ;
UsePrivateHeaders net ;
UsePrivateHeaders [ FDirName kernel ] ;
UsePrivateHeaders [ FDirName kernel util ] ;
UseHeaders [ FDirName $(OBOS_TOP) src add-ons kernel network ppp shared libkernelppp headers ] ;
R5KernelStaticLibrary kernelppp :
kernel_cpp.cpp
KPPPConfigurePacket.cpp
KPPPDevice.cpp
KPPPEncapsulator.cpp
KPPPInterface.cpp
KPPPLayer.cpp
KPPPLCP.cpp
KPPPLCPExtension.cpp
KPPPOptionHandler.cpp
@ -22,7 +26,6 @@ R5KernelStaticLibrary kernelppp :
KPPPUtils.cpp
Locker.cpp
settings_tools.cpp
cpp.cpp
# integrated modules
_KPPPMRUHandler.cpp

View File

@ -8,6 +8,8 @@
#include <KPPPConfigurePacket.h>
#include <KPPPInterface.h>
#include <core_funcs.h>
PPPConfigurePacket::PPPConfigurePacket(uint8 code)
: fCode(code)

View File

@ -8,42 +8,29 @@
#include <KPPPDevice.h>
#include <net/if.h>
#include <mbuf.h>
#include <core_funcs.h>
#include <PPPControl.h>
PPPDevice::PPPDevice(const char *name, PPPInterface& interface,
driver_parameter *settings)
: fMTU(1500),
fIsUp(false),
: PPPLayer(name, PPP_DEVICE_LEVEL),
fMTU(1500),
fInterface(interface),
fSettings(settings)
fSettings(settings),
fIsUp(false)
{
if(name)
fName = strdup(name);
else
fName = strdup("Unknown");
fInitStatus = interface.SetDevice(this) ? B_OK : B_ERROR;
fInitStatus = interface.SetDevice(this) && fInitStatus == B_OK ? 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)
{
@ -60,6 +47,7 @@ PPPDevice::Control(uint32 op, void *data, size_t length)
info->inputTransferRate = InputTransferRate();
info->outputTransferRate = OutputTransferRate();
info->outputBytesCount = CountOutputBytes();
info->isUp = IsUp();
} break;
default:
@ -70,15 +58,22 @@ PPPDevice::Control(uint32 op, void *data, size_t length)
}
status_t
PPPDevice::PassToInterface(struct mbuf *packet)
bool
PPPDevice::IsAllowedToSend() const
{
if(!Interface().InQueue())
return B_ERROR;
IFQ_ENQUEUE(Interface().InQueue(), packet);
return B_OK;
return true;
// our connection status will be reported in Send()
}
status_t
PPPDevice::Receive(struct mbuf *packet, uint16 protocolNumber)
{
// let the interface handle the packet
if(protocolNumber == 0)
return Interface().ReceiveFromDevice(packet);
else
return Interface().Receive(packet, protocolNumber);
}

View File

@ -1,191 +0,0 @@
//----------------------------------------------------------------------
// This software is part of the OpenBeOS distribution and is covered
// by the OpenBeOS license.
//
// Copyright (c) 2003 Waldemar Kornewald, Waldemar.Kornewald@web.de
//---------------------------------------------------------------------
#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);
}

View File

@ -10,7 +10,7 @@
// void (KernelExport.h) and once with int (stdio.h).
#include <cstdio>
#include <cstring>
#include <new.h>
#include <core_funcs.h>
// now our headers...
#include <KPPPInterface.h>
@ -18,7 +18,6 @@
// our other classes
#include <PPPControl.h>
#include <KPPPDevice.h>
#include <KPPPEncapsulator.h>
#include <KPPPLCPExtension.h>
#include <KPPPOptionHandler.h>
#include <KPPPModule.h>
@ -37,6 +36,11 @@
#include "_KPPPPFCHandler.h"
#ifdef _KERNEL_MODE
#define spawn_thread spawn_kernel_thread
#endif
// TODO:
// - implement timers with support for settings next time instead of receiving timer
// events periodically
@ -52,13 +56,13 @@ typedef struct redial_info {
status_t redial_thread(void *data);
// other functions
status_t in_queue_thread(void *data);
status_t interface_deleter_thread(void *data);
PPPInterface::PPPInterface(uint32 ID, driver_settings *settings,
PPPInterface *parent = NULL)
: fID(ID),
: PPPLayer("PPPInterface", PPP_INTERFACE_LEVEL),
fID(ID),
fSettings(dup_driver_settings(settings)),
fStateMachine(*this),
fLCP(*this),
@ -78,7 +82,7 @@ PPPInterface::PPPInterface(uint32 ID, driver_settings *settings,
fPeerPFCState(PPP_PFC_DISABLED),
fPFCOptions(0),
fDevice(NULL),
fFirstEncapsulator(NULL),
fFirstProtocol(NULL),
fLock(StateMachine().Locker()),
fDeleteCounter(0)
{
@ -105,13 +109,7 @@ PPPInterface::PPPInterface(uint32 ID, driver_settings *settings,
fRedialDelay = 1000;
// 1s delay between lost connection and redial
// set up queue
fInQueue = start_ifq();
fInQueueThread = spawn_thread(in_queue_thread, "PPPInterface: in_queue_thread",
B_NORMAL_PRIORITY, this);
resume_thread(fInQueueThread);
if(get_module(PPP_MANAGER_MODULE_NAME, (module_info**) &fManager) != B_OK)
if(get_module(PPP_INTERFACE_MODULE_NAME, (module_info**) &fManager) != B_OK)
fManager = NULL;
// are we a multilink subinterface?
@ -166,7 +164,7 @@ PPPInterface::PPPInterface(uint32 ID, driver_settings *settings,
// auto redial is disabled by default
// load all protocols and the device
if(LoadModules(fSettings, 0, fSettings->parameter_count))
if(LoadModules(fSettings, 0, fSettings->parameter_count) && fInitStatus == B_OK)
fInitStatus = B_OK;
else
fInitStatus = B_ERROR;
@ -181,7 +179,7 @@ PPPInterface::~PPPInterface()
UnregisterInterface();
if(fManager)
fManager->remove_interface(ID());
fManager->RemoveInterface(ID());
// Call Down() until we get a lock on an interface that is down.
// This lock is not released until we are actually deleted.
@ -197,9 +195,6 @@ PPPInterface::~PPPInterface()
// tell all listeners that we are being destroyed
int32 tmp;
stop_ifq(InQueue());
wait_for_thread(fInQueueThread, &tmp);
send_data_with_timeout(fRedialThread, 0, NULL, 0, 200);
// tell thread that we are being destroyed (200ms timeout)
wait_for_thread(fRedialThread, &tmp);
@ -212,8 +207,8 @@ PPPInterface::~PPPInterface()
while(CountProtocols())
delete ProtocolAt(0);
while(FirstEncapsulator())
delete FirstEncapsulator();
while(FirstProtocol())
delete FirstProtocol();
for(int32 index = 0; index < fModules.CountItems(); index++) {
put_module(fModules.ItemAt(index));
@ -226,7 +221,7 @@ PPPInterface::~PPPInterface()
Parent()->RemoveChild(this);
if(fManager)
put_module(PPP_MANAGER_MODULE_NAME);
put_module(PPP_INTERFACE_MODULE_NAME);
}
@ -238,7 +233,7 @@ PPPInterface::Delete()
// only one thread should delete us!
if(fManager)
fManager->delete_interface(ID());
fManager->DeleteInterface(ID());
// This will mark us for deletion.
// Any subsequent calls to delete_interface() will do nothing.
else {
@ -254,7 +249,10 @@ PPPInterface::Delete()
status_t
PPPInterface::InitCheck() const
{
if(!fSettings || !fManager || fInitStatus != B_OK)
if(fInitStatus != B_OK)
return fInitStatus;
if(!fSettings || !fManager)
return B_ERROR;
// sub-interfaces should have a device
@ -306,7 +304,6 @@ PPPInterface::Control(uint32 op, void *data, size_t length)
info->peerPFCState = PeerPFCState();
info->pfcOptions = PFCOptions();
info->protocolsCount = CountProtocols();
info->encapsulatorsCount = CountEncapsulators();
info->optionHandlersCount = LCP().CountOptionHandlers();
info->LCPExtensionsCount = 0;
info->childrenCount = CountChildren();
@ -379,25 +376,11 @@ PPPInterface::Control(uint32 op, void *data, size_t length)
return B_ERROR;
ppp_control_info *control = (ppp_control_info*) data;
PPPProtocol *protocol_handler = ProtocolAt(control->index);
if(!protocol_handler)
PPPProtocol *protocol = ProtocolAt(control->index);
if(!protocol)
return B_BAD_INDEX;
return protocol_handler->Control(control->op, control->data,
control->length);
} break;
case PPPC_CONTROL_ENCAPSULATOR: {
if(length < sizeof(ppp_control_info) || !data)
return B_ERROR;
ppp_control_info *control = (ppp_control_info*) data;
PPPEncapsulator *encapsulator_handler = EncapsulatorAt(control->index);
if(!encapsulator_handler)
return B_BAD_INDEX;
return encapsulator_handler->Control(control->op, control->data,
control->length);
return protocol->Control(control->op, control->data, control->length);
} break;
case PPPC_CONTROL_OPTION_HANDLER: {
@ -405,11 +388,11 @@ PPPInterface::Control(uint32 op, void *data, size_t length)
return B_ERROR;
ppp_control_info *control = (ppp_control_info*) data;
PPPOptionHandler *option_handler = LCP().OptionHandlerAt(control->index);
if(!option_handler)
PPPOptionHandler *optionHandler = LCP().OptionHandlerAt(control->index);
if(!optionHandler)
return B_BAD_INDEX;
return option_handler->Control(control->op, control->data,
return optionHandler->Control(control->op, control->data,
control->length);
} break;
@ -418,11 +401,11 @@ PPPInterface::Control(uint32 op, void *data, size_t length)
return B_ERROR;
ppp_control_info *control = (ppp_control_info*) data;
PPPLCPExtension *extension_handler = LCP().LCPExtensionAt(control->index);
if(!extension_handler)
PPPLCPExtension *lcpExtension = LCP().LCPExtensionAt(control->index);
if(!lcpExtension)
return B_BAD_INDEX;
return extension_handler->Control(control->op, control->data,
return lcpExtension->Control(control->op, control->data,
control->length);
} break;
@ -466,6 +449,7 @@ PPPInterface::SetDevice(PPPDevice *device)
Down();
fDevice = device;
SetNext(device);
fMRU = fDevice->MTU() - 2;
@ -479,19 +463,52 @@ PPPInterface::SetDevice(PPPDevice *device)
bool
PPPInterface::AddProtocol(PPPProtocol *protocol)
{
if(!protocol)
// Find instert position after the last protocol
// with the same level.
if(!protocol || protocol->Level() == PPP_INTERFACE_LEVEL)
return false;
LockerHelper locker(fLock);
if(Phase() != PPP_DOWN_PHASE)
return false;
// a running connection may not change and there may only be
// one authenticator protocol for each protocol number
// a running connection may not change
fProtocols.AddItem(protocol);
PPPProtocol *current = fFirstProtocol, *previous = NULL;
if(IsUp() || Phase() >= protocol->Phase())
while(current) {
if(current->Level() < protocol->Level())
break;
previous = current;
current = current->NextProtocol();
}
if(!current) {
if(!previous)
fFirstProtocol = protocol;
else
previous->SetNextProtocol(protocol);
// set up the last protocol in the chain
protocol->SetNextProtocol(NULL);
// this also sets next to NULL
protocol->SetNext(this);
// we need to set us as the next layer
} else {
protocol->SetNextProtocol(current);
if(!previous)
fFirstProtocol = protocol;
else
previous->SetNextProtocol(protocol);
}
if(protocol->Level() < PPP_PROTOCOL_LEVEL)
CalculateInterfaceMTU();
if(IsUp() || Phase() >= protocol->ActivationPhase())
protocol->Up();
return true;
@ -507,128 +524,23 @@ PPPInterface::RemoveProtocol(PPPProtocol *protocol)
return false;
// a running connection may not change
if(!fProtocols.HasItem(protocol))
return false;
if(IsUp() || Phase() >= protocol->Phase())
protocol->Down();
return fProtocols.RemoveItem(protocol);
}
PPPProtocol*
PPPInterface::ProtocolAt(int32 index) const
{
PPPProtocol *protocol = fProtocols.ItemAt(index);
if(protocol == fProtocols.GetDefaultItem())
return NULL;
return protocol;
}
PPPProtocol*
PPPInterface::ProtocolFor(uint16 protocol, int32 *start = 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;
PPPProtocol *current = ProtocolAt(index);
for(; current; current = ProtocolAt(++index)) {
if(current->Protocol() == protocol
|| (current->Flags() & PPP_INCLUDES_NCP
&& current->Protocol() & 0x7FFF == protocol & 0x7FFF)) {
if(start)
*start = index;
return current;
}
}
return NULL;
}
bool
PPPInterface::AddEncapsulator(PPPEncapsulator *encapsulator)
{
// Find instert position after the last encapsulator
// with the same level.
if(!encapsulator)
return false;
LockerHelper locker(fLock);
if(Phase() != PPP_DOWN_PHASE)
return false;
// a running connection may not change
PPPEncapsulator *current = fFirstEncapsulator, *previous = NULL;
PPPProtocol *current = fFirstProtocol, *previous = NULL;
while(current) {
if(current->Level() < encapsulator->Level())
break;
previous = current;
current = current->Next();
}
if(!current) {
if(!previous)
fFirstEncapsulator = encapsulator;
else
previous->SetNext(encapsulator);
encapsulator->SetNext(NULL);
} else {
encapsulator->SetNext(current);
if(!previous)
fFirstEncapsulator = encapsulator;
else
previous->SetNext(encapsulator);
}
CalculateInterfaceMTU();
if(IsUp())
encapsulator->Up();
return true;
}
bool
PPPInterface::RemoveEncapsulator(PPPEncapsulator *encapsulator)
{
LockerHelper locker(fLock);
if(Phase() != PPP_DOWN_PHASE)
return false;
// a running connection may not change
PPPEncapsulator *current = fFirstEncapsulator, *previous = NULL;
while(current) {
if(current == encapsulator) {
if(IsUp())
encapsulator->Down();
if(current == protocol) {
if(!protocol->IsDown())
protocol->Down();
if(previous)
previous->SetNext(current->Next());
else
fFirstEncapsulator = current->Next();
if(previous) {
previous->SetNextProtocol(current->NextProtocol());
// set us as next layer if needed
if(!previous->Next())
previous->SetNext(this);
} else
fFirstProtocol = current->NextProtocol();
current->SetNext(NULL);
current->SetNextProtocol(NULL);
CalculateInterfaceMTU();
@ -636,7 +548,7 @@ PPPInterface::RemoveEncapsulator(PPPEncapsulator *encapsulator)
}
previous = current;
current = current->Next();
current = current->NextProtocol();
}
return false;
@ -644,39 +556,39 @@ PPPInterface::RemoveEncapsulator(PPPEncapsulator *encapsulator)
int32
PPPInterface::CountEncapsulators() const
PPPInterface::CountProtocols() const
{
PPPEncapsulator *encapsulator = FirstEncapsulator();
PPPProtocol *protocol = FirstProtocol();
int32 count = 0;
for(; encapsulator; encapsulator = encapsulator->Next())
for(; protocol; protocol = protocol->NextProtocol())
++count;
return count;
}
PPPEncapsulator*
PPPInterface::EncapsulatorAt(int32 index) const
PPPProtocol*
PPPInterface::ProtocolAt(int32 index) const
{
PPPEncapsulator *encapsulator = FirstEncapsulator();
PPPProtocol *protocol = FirstProtocol();
int32 currentIndex = 0;
for(; encapsulator; encapsulator = encapsulator->Next(), ++currentIndex)
for(; protocol; protocol = protocol->NextProtocol(), ++currentIndex)
if(currentIndex == index)
return encapsulator;
return protocol;
return NULL;
}
PPPEncapsulator*
PPPInterface::EncapsulatorFor(uint16 protocol, PPPEncapsulator *start = NULL) const
PPPProtocol*
PPPInterface::ProtocolFor(uint16 protocolNumber, PPPProtocol *start = NULL) const
{
PPPEncapsulator *current = start ? start : fFirstEncapsulator;
PPPProtocol *current = start ? start : FirstProtocol();
for(; current; current = current->Next()) {
if(current->Protocol() == protocol
for(; current; current = current->NextProtocol()) {
if(current->ProtocolNumber() == protocolNumber
|| (current->Flags() & PPP_INCLUDES_NCP
&& current->Protocol() & 0x7FFF == protocol & 0x7FFF))
&& current->ProtocolNumber() & 0x7FFF == protocolNumber & 0x7FFF))
return current;
}
@ -1065,7 +977,7 @@ PPPInterface::LoadModules(driver_settings *settings, int32 start, int32 count)
if(IsMultilink() && !Parent()) {
// main interfaces only load the multilink module
// and create a child using their settings
fManager->create_interface(settings, ID());
fManager->CreateInterface(settings, ID());
return true;
}
@ -1123,150 +1035,15 @@ PPPInterface::LoadModule(const char *name, driver_parameter *parameter,
}
status_t
PPPInterface::Send(struct mbuf *packet, uint16 protocol)
bool
PPPInterface::IsAllowedToSend() const
{
if(!packet)
return B_ERROR;
// we must pass the basic tests!
if(InitCheck() != B_OK) {
m_freem(packet);
return B_ERROR;
}
// test whether are going down
if(Phase() == PPP_TERMINATION_PHASE) {
m_freem(packet);
return B_ERROR;
}
// go up if DialOnDemand enabled and we are down
if(DoesDialOnDemand() && Phase() == PPP_DOWN_PHASE)
Up();
// find the protocol handler for the current protocol number
int32 index = 0;
PPPProtocol *sending_protocol = ProtocolFor(protocol, &index);
while(sending_protocol && !sending_protocol->IsEnabled())
sending_protocol = ProtocolFor(protocol, &(++index));
// Check if we must encapsulate the packet.
// We do not necessarily need a handler for 'protocol'.
// In such a case we still encapsulate the packet.
// Protocols which have the PPP_ALWAYS_ALLOWED flag set are never
// encapsulated.
if(sending_protocol && sending_protocol->Flags() & PPP_ALWAYS_ALLOWED
&& is_handler_allowed(*sending_protocol, State(), Phase())) {
fIdleSince = real_time_clock();
return SendToDevice(packet, protocol);
}
// try the same for the encapsulator handler
PPPEncapsulator *sending_encapsulator = EncapsulatorFor(protocol);
while(sending_encapsulator && sending_encapsulator->Next()
&& !sending_encapsulator->IsEnabled())
sending_encapsulator = sending_encapsulator->Next() ?
EncapsulatorFor(protocol, sending_encapsulator->Next()) : NULL;
if(sending_encapsulator && sending_encapsulator->Flags() & PPP_ALWAYS_ALLOWED
&& is_handler_allowed(*sending_encapsulator, State(), Phase())) {
fIdleSince = real_time_clock();
return SendToDevice(packet, protocol);
}
// never send normal protocols when we are not up
if(!IsUp()) {
m_freem(packet);
return B_ERROR;
}
fIdleSince = real_time_clock();
// send to next up encapsulator
if(!fFirstEncapsulator)
return SendToDevice(packet, protocol);
if(!fFirstEncapsulator->IsEnabled())
return fFirstEncapsulator->SendToNext(packet, protocol);
if(is_handler_allowed(*fFirstEncapsulator, State(), Phase()))
return fFirstEncapsulator->Send(packet, protocol);
m_freem(packet);
return B_ERROR;
return true;
}
status_t
PPPInterface::Receive(struct mbuf *packet, uint16 protocol)
{
if(!packet)
return B_ERROR;
int32 result = PPP_REJECTED;
// assume we have no handler
// Set our interface as the receiver.
// The real netstack protocols (IP, IPX, etc.) might get confused if our
// interface is a main interface and at the same time is not registered
// because then there is no receiver interface.
// PPP NCPs should be aware of that!
if(packet->m_flags & M_PKTHDR && Ifnet() != NULL)
packet->m_pkthdr.rcvif = Ifnet();
// Find handler and let it parse the packet.
// The handler does need not be up because if we are a server
// the handler might be upped by this packet.
PPPEncapsulator *encapsulator_handler = EncapsulatorFor(protocol);
for(; encapsulator_handler;
encapsulator_handler =
encapsulator_handler->Next() ?
EncapsulatorFor(protocol, encapsulator_handler->Next()) : NULL) {
if(!encapsulator_handler->IsEnabled()
|| !is_handler_allowed(*encapsulator_handler, State(), Phase()))
continue;
// skip handler if disabled or not allowed
result = encapsulator_handler->Receive(packet, protocol);
if(result == PPP_UNHANDLED)
continue;
return result;
}
// no encapsulator handler could be found; try a protocol handler
int32 index = 0;
PPPProtocol *protocol_handler = ProtocolFor(protocol, &index);
for(; protocol_handler; protocol_handler = ProtocolFor(protocol, &(++index))) {
if(!protocol_handler->IsEnabled()
|| !is_handler_allowed(*protocol_handler, State(), Phase()))
continue;
// skip handler if disabled or not allowed
result = protocol_handler->Receive(packet, protocol);
if(result == PPP_UNHANDLED)
continue;
return result;
}
// maybe the parent interface can handle the packet
if(Parent())
return Parent()->Receive(packet, protocol);
if(result == PPP_UNHANDLED) {
m_freem(packet);
return PPP_DISCARDED;
} else {
StateMachine().RUCEvent(packet, protocol);
return PPP_REJECTED;
}
}
status_t
PPPInterface::SendToDevice(struct mbuf *packet, uint16 protocol)
PPPInterface::Send(struct mbuf *packet, uint16 protocolNumber)
{
if(!packet)
return B_ERROR;
@ -1295,27 +1072,27 @@ PPPInterface::SendToDevice(struct mbuf *packet, uint16 protocol)
}
// find the protocol handler for the current protocol number
int32 index = 0;
PPPProtocol *sending_protocol = ProtocolFor(protocol, &index);
while(sending_protocol && !sending_protocol->IsEnabled())
sending_protocol = ProtocolFor(protocol, &(++index));
PPPProtocol *protocol = ProtocolFor(protocolNumber);
while(protocol && !protocol->IsEnabled())
protocol = protocol->NextProtocol() ?
ProtocolFor(protocolNumber, protocol->NextProtocol()) : NULL;
// make sure that protocol is allowed to send and everything is up
if(!Device()->IsUp() || !sending_protocol || !sending_protocol->IsEnabled()
|| !is_handler_allowed(*sending_protocol, State(), Phase())){
if(!Device()->IsUp() || !protocol || !protocol->IsEnabled()
|| !IsProtocolAllowed(*protocol)){
m_freem(packet);
return B_ERROR;
}
// encode in ppp frame and consider using PFC
if(UseLocalPFC() && protocol & 0xFF00 == 0) {
if(UseLocalPFC() && protocolNumber & 0xFF00 == 0) {
M_PREPEND(packet, 1);
if(packet == NULL)
return B_ERROR;
uint8 *header = mtod(packet, uint8*);
*header = protocol & 0xFF;
*header = protocolNumber & 0xFF;
} else {
M_PREPEND(packet, 2);
@ -1323,9 +1100,9 @@ PPPInterface::SendToDevice(struct mbuf *packet, uint16 protocol)
return B_ERROR;
// set protocol (the only header field)
protocol = htons(protocol);
protocolNumber = htons(protocolNumber);
uint16 *header = mtod(packet, uint16*);
*header = protocol;
*header = protocolNumber;
}
fIdleSince = real_time_clock();
@ -1339,15 +1116,65 @@ PPPInterface::SendToDevice(struct mbuf *packet, uint16 protocol)
return B_ERROR;
}
return Device()->Send(packet);
return SendToNext(packet, 0);
// this is normally the device, but there can be something inbetween
} else {
// the multilink encapsulator should have sent it to some child interface
// the multilink protocol should have sent it to some child interface
m_freem(packet);
return B_ERROR;
}
}
status_t
PPPInterface::Receive(struct mbuf *packet, uint16 protocolNumber)
{
if(!packet)
return B_ERROR;
int32 result = PPP_REJECTED;
// assume we have no handler
// Set our interface as the receiver.
// The real netstack protocols (IP, IPX, etc.) might get confused if our
// interface is a main interface and at the same time is not registered
// because then there is no receiver interface.
// PPP NCPs should be aware of that!
if(packet->m_flags & M_PKTHDR && Ifnet() != NULL)
packet->m_pkthdr.rcvif = Ifnet();
// Find handler and let it parse the packet.
// The handler does need not be up because if we are a server
// the handler might be upped by this packet.
PPPProtocol *protocol = ProtocolFor(protocolNumber);
for(; protocol;
protocol = protocol->NextProtocol() ?
ProtocolFor(protocolNumber, protocol->NextProtocol()) : NULL) {
if(!protocol->IsEnabled() || !IsProtocolAllowed(*protocol))
continue;
// skip handler if disabled or not allowed
result = protocol->Receive(packet, protocolNumber);
if(result == PPP_UNHANDLED)
continue;
return result;
}
// maybe the parent interface can handle the packet
if(Parent())
return Parent()->Receive(packet, protocolNumber);
if(result == PPP_UNHANDLED) {
m_freem(packet);
return PPP_DISCARDED;
} else {
StateMachine().RUCEvent(packet, protocolNumber);
return PPP_REJECTED;
}
}
status_t
PPPInterface::ReceiveFromDevice(struct mbuf *packet)
{
@ -1360,15 +1187,15 @@ PPPInterface::ReceiveFromDevice(struct mbuf *packet)
}
// decode ppp frame and recognize PFC
uint16 protocol = *mtod(packet, uint8*);
if(protocol == 0)
uint16 protocolNumber = *mtod(packet, uint8*);
if(protocolNumber == 0)
m_adj(packet, 1);
else {
protocol = ntohs(*mtod(packet, uint16*));
protocolNumber = ntohs(*mtod(packet, uint16*));
m_adj(packet, 2);
}
return Receive(packet, protocol);
return Receive(packet, protocolNumber);
}
@ -1389,12 +1216,9 @@ PPPInterface::Pulse()
if(Device())
Device()->Pulse();
for(int32 index = 0; index < CountProtocols(); index++)
ProtocolAt(index)->Pulse();
PPPEncapsulator *encapsulator = fFirstEncapsulator;
for(; encapsulator; encapsulator = encapsulator->Next())
encapsulator->Pulse();
PPPProtocol *protocol = FirstProtocol();
for(; protocol; protocol = protocol->NextProtocol())
protocol->Pulse();
}
@ -1418,7 +1242,7 @@ PPPInterface::RegisterInterface()
if(!fManager)
return false;
fIfnet = fManager->register_interface(ID());
fIfnet = fManager->RegisterInterface(ID());
if(!fIfnet)
return false;
@ -1445,7 +1269,7 @@ PPPInterface::UnregisterInterface()
if(!fManager)
return false;
fManager->unregister_interface(ID());
fManager->UnregisterInterface(ID());
fIfnet = NULL;
return true;
@ -1457,7 +1281,7 @@ status_t
PPPInterface::StackControl(uint32 op, void *data)
{
// TODO:
// implement when writing ppp_manager module
// implement when writing ppp interface module
switch(op) {
default:
@ -1500,16 +1324,15 @@ PPPInterface::StackControlEachHandler(uint32 op, void *data)
{
status_t result = B_BAD_VALUE, tmp;
PPPEncapsulator *encapsulator = FirstEncapsulator();
for(; encapsulator; encapsulator = encapsulator->Next()) {
tmp = encapsulator->StackControl(op, data);
PPPProtocol *protocol = FirstProtocol();
for(; protocol; protocol = protocol->NextProtocol()) {
tmp = protocol->StackControl(op, data);
if(tmp == B_OK && result == B_BAD_VALUE)
result = B_OK;
else if(tmp != B_BAD_VALUE)
result = tmp;
}
ForEachItem(fProtocols, CallStackControl<PPPProtocol>(op, data, result));
ForEachItem(LCP().fLCPExtensions,
CallStackControl<PPPLCPExtension>(op, data, result));
ForEachItem(LCP().fOptionHandlers,
@ -1525,9 +1348,11 @@ PPPInterface::CalculateInterfaceMTU()
fInterfaceMTU = fMRU;
// sum all headers (the protocol field is not counted)
PPPEncapsulator *encapsulator = fFirstEncapsulator;
for(; encapsulator; encapsulator = encapsulator->Next())
fHeaderLength += encapsulator->Overhead();
PPPProtocol *protocol = FirstProtocol();
for(; protocol; protocol = protocol->NextProtocol()) {
if(protocol->Level() < PPP_PROTOCOL_LEVEL)
fHeaderLength += protocol->Overhead();
}
fInterfaceMTU -= fHeaderLength;
@ -1603,38 +1428,12 @@ redial_thread(void *data)
}
status_t
in_queue_thread(void *data)
{
PPPInterface *interface = (PPPInterface*) data;
struct ifq *queue = interface->InQueue();
struct mbuf *packet;
status_t error;
while(true) {
error = acquire_sem_etc(queue->pop, 1, B_CAN_INTERRUPT | B_DO_NOT_RESCHEDULE, 0);
if(error == B_INTERRUPTED)
continue;
else if(error != B_NO_ERROR)
break;
IFQ_DEQUEUE(queue, packet);
if(packet)
interface->ReceiveFromDevice(packet);
}
return B_ERROR;
}
// ----------------------------------
// Function: interface_deleter_thread
// ----------------------------------
// The destructor is private, so this thread function cannot delete our interface.
// To solve this problem we create a 'fake' class PPPManager (friend of PPPInterface)
// which is only defined here (the real class is defined in the ppp_manager module).
// which is only defined here (the real class is defined in the ppp interface module).
class PPPManager {
public:
PPPManager(PPPInterface *interface)

View File

@ -7,20 +7,19 @@
#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 <core_funcs.h>
#include <sys/socket.h>
PPPLCP::PPPLCP(PPPInterface& interface)
: PPPProtocol("LCP", PPP_ESTABLISHMENT_PHASE, PPP_LCP_PROTOCOL,
AF_UNSPEC, interface, NULL, PPP_ALWAYS_ALLOWED),
: PPPProtocol("LCP", PPP_ESTABLISHMENT_PHASE, PPP_LCP_PROTOCOL, PPP_PROTOCOL_LEVEL,
AF_UNSPEC, 0, interface, NULL, PPP_ALWAYS_ALLOWED),
fStateMachine(interface.StateMachine()),
fTarget(NULL)
{
@ -37,44 +36,44 @@ PPPLCP::~PPPLCP()
bool
PPPLCP::AddOptionHandler(PPPOptionHandler *handler)
PPPLCP::AddOptionHandler(PPPOptionHandler *optionHandler)
{
if(!handler)
if(!optionHandler)
return false;
LockerHelper locker(StateMachine().Locker());
if(Phase() != PPP_DOWN_PHASE || OptionHandlerFor(handler->Type()))
if(Interface().Phase() != PPP_DOWN_PHASE || OptionHandlerFor(optionHandler->Type()))
return false;
// a running connection may not change and there may only be
// one handler per option type
return fOptionHandlers.AddItem(handler);
return fOptionHandlers.AddItem(optionHandler);
}
bool
PPPLCP::RemoveOptionHandler(PPPOptionHandler *handler)
PPPLCP::RemoveOptionHandler(PPPOptionHandler *optionHandler)
{
LockerHelper locker(StateMachine().Locker());
if(Phase() != PPP_DOWN_PHASE)
if(Interface().Phase() != PPP_DOWN_PHASE)
return false;
// a running connection may not change
return fOptionHandlers.RemoveItem(handler);
return fOptionHandlers.RemoveItem(optionHandler);
}
PPPOptionHandler*
PPPLCP::OptionHandlerAt(int32 index) const
{
PPPOptionHandler *handler = fOptionHandlers.ItemAt(index);
PPPOptionHandler *optionHandler = fOptionHandlers.ItemAt(index);
if(handler == fOptionHandlers.GetDefaultItem())
if(optionHandler == fOptionHandlers.GetDefaultItem())
return NULL;
return handler;
return optionHandler;
}
@ -105,43 +104,43 @@ PPPLCP::OptionHandlerFor(uint8 type, int32 *start = NULL) const
bool
PPPLCP::AddLCPExtension(PPPLCPExtension *extension)
PPPLCP::AddLCPExtension(PPPLCPExtension *lcpExtension)
{
if(!extension)
if(!lcpExtension)
return false;
LockerHelper locker(StateMachine().Locker());
if(Phase() != PPP_DOWN_PHASE)
if(Interface().Phase() != PPP_DOWN_PHASE)
return false;
// a running connection may not change
return fLCPExtensions.AddItem(extension);
return fLCPExtensions.AddItem(lcpExtension);
}
bool
PPPLCP::RemoveLCPExtension(PPPLCPExtension *extension)
PPPLCP::RemoveLCPExtension(PPPLCPExtension *lcpExtension)
{
LockerHelper locker(StateMachine().Locker());
if(Phase() != PPP_DOWN_PHASE)
if(Interface().Phase() != PPP_DOWN_PHASE)
return false;
// a running connection may not change
return fLCPExtensions.RemoveItem(extension);
return fLCPExtensions.RemoveItem(lcpExtension);
}
PPPLCPExtension*
PPPLCP::LCPExtensionAt(int32 index) const
{
PPPLCPExtension *extension = fLCPExtensions.ItemAt(index);
PPPLCPExtension *lcpExtension = fLCPExtensions.ItemAt(index);
if(extension == fLCPExtensions.GetDefaultItem())
if(lcpExtension == fLCPExtensions.GetDefaultItem())
return NULL;
return extension;
return lcpExtension;
}
@ -198,7 +197,7 @@ PPPLCP::Down()
status_t
PPPLCP::Send(struct mbuf *packet)
PPPLCP::Send(struct mbuf *packet, uint16 protocolNumber)
{
if(Target())
return Target()->Send(packet, PPP_LCP_PROTOCOL);
@ -208,12 +207,12 @@ PPPLCP::Send(struct mbuf *packet)
status_t
PPPLCP::Receive(struct mbuf *packet, uint16 protocol)
PPPLCP::Receive(struct mbuf *packet, uint16 protocolNumber)
{
if(!packet)
return B_ERROR;
if(protocol != PPP_LCP_PROTOCOL)
if(protocolNumber != PPP_LCP_PROTOCOL)
return PPP_UNHANDLED;
ppp_lcp_packet *data = mtod(packet, ppp_lcp_packet*);
@ -288,12 +287,12 @@ PPPLCP::Receive(struct mbuf *packet, uint16 protocol)
// 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())
PPPLCPExtension *lcpExtension = LCPExtensionFor(data->code, &index);
for(; lcpExtension; lcpExtension = LCPExtensionFor(data->code, &(++index))) {
if(!lcpExtension->IsEnabled())
continue;
result = extension->Receive(packet, data->code);
result = lcpExtension->Receive(packet, data->code);
// check return value and return it on error
if(result == B_OK)

View File

@ -56,7 +56,7 @@ PPPLCPExtension::Control(uint32 op, void *data, size_t length)
info->isEnabled = IsEnabled();
} break;
case PPPC_SET_ENABLED:
case PPPC_ENABLE:
if(length < sizeof(uint32) || !data)
return B_ERROR;

View File

@ -0,0 +1,62 @@
//----------------------------------------------------------------------
// 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 <KPPPLayer.h>
#include <cstdlib>
#include <cstring>
#include <core_funcs.h>
#include <kernel_cpp.h>
PPPLayer::PPPLayer(const char *name, ppp_level level)
: fInitStatus(B_OK),
fNext(NULL)
{
if(name)
fName = strdup(name);
else
fName = strdup("Unknown");
}
PPPLayer::~PPPLayer()
{
free(fName);
}
status_t
PPPLayer::InitCheck() const
{
return fInitStatus;
}
status_t
PPPLayer::SendToNext(struct mbuf *packet, uint16 protocolNumber) const
{
// Find the next possible handler for this packet.
// Normal protocols (Level() >= PPP_PROTOCOL_LEVEL) do not encapsulate anything.
if(Next()) {
if(Next()->IsAllowedToSend() && Next()->Level() < PPP_PROTOCOL_LEVEL)
return Next()->Send(packet, protocolNumber);
else
return Next()->SendToNext(packet, protocolNumber);
} else {
m_freem(packet);
return B_ERROR;
}
}
void
PPPLayer::Pulse()
{
// do nothing by default
}

View File

@ -56,7 +56,7 @@ PPPOptionHandler::Control(uint32 op, void *data, size_t length)
info->isEnabled = IsEnabled();
} break;
case PPPC_SET_ENABLED:
case PPPC_ENABLE:
if(length < sizeof(uint32) || !data)
return B_ERROR;

View File

@ -6,34 +6,31 @@
//---------------------------------------------------------------------
#include <KPPPInterface.h>
#include <KPPPOptionHandler.h>
#include <KPPPUtils.h>
#include <PPPControl.h>
#include "settings_tools.h"
#include <cstring>
PPPProtocol::PPPProtocol(const char *name, ppp_phase phase, uint16 protocol,
int32 addressFamily, PPPInterface& interface,
PPPProtocol::PPPProtocol(const char *name, ppp_phase activationPhase,
uint16 protocolNumber, ppp_level level, int32 addressFamily,
uint32 overhead, PPPInterface& interface,
driver_parameter *settings, int32 flags = PPP_NO_FLAGS,
const char *type = NULL, PPPOptionHandler *optionHandler = NULL)
: fPhase(phase),
fProtocol(protocol),
: PPPLayer(name, level),
fActivationPhase(activationPhase),
fProtocolNumber(protocolNumber),
fAddressFamily(addressFamily),
fInterface(interface),
fSettings(settings),
fFlags(flags),
fOptionHandler(optionHandler),
fNextProtocol(NULL),
fEnabled(true),
fUpRequested(true),
fConnectionStatus(PPP_DOWN_PHASE)
fConnectionPhase(PPP_DOWN_PHASE)
{
if(name)
fName = strdup(name);
else
fName = strdup("Unknown");
if(type)
fType = strdup(type);
else
@ -49,36 +46,15 @@ PPPProtocol::PPPProtocol(const char *name, ppp_phase phase, uint16 protocol,
fSide = PPP_PEER_SIDE;
}
fInitStatus = interface.AddProtocol(this) ? B_OK : B_ERROR;
fInitStatus = interface.AddProtocol(this) && fInitStatus == B_OK ? 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();
free(fType);
}
@ -86,26 +62,28 @@ 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)
case PPPC_GET_PROTOCOL_INFO: {
if(length < sizeof(ppp_protocol_info_t) || !data)
return B_ERROR;
ppp_handler_info *info = (ppp_handler_info*) data;
memset(info, 0, sizeof(ppp_handler_info_t));
ppp_protocol_info *info = (ppp_protocol_info*) data;
memset(info, 0, sizeof(ppp_protocol_info_t));
strncpy(info->name, Name(), PPP_HANDLER_NAME_LENGTH_LIMIT);
strncpy(info->type, Type(), PPP_HANDLER_NAME_LENGTH_LIMIT);
info->settings = Settings();
info->phase = Phase();
info->activationPhase = ActivationPhase();
info->addressFamily = AddressFamily();
info->flags = Flags();
info->side = Side();
info->protocol = Protocol();
info->level = Level();
info->overhead = Overhead();
info->connectionPhase = fConnectionPhase;
info->protocolNumber = ProtocolNumber();
info->isEnabled = IsEnabled();
info->isUpRequested = IsUpRequested();
info->connectionStatus = fConnectionStatus;
strncpy(info->type, Type(), PPP_HANDLER_NAME_LENGTH_LIMIT);
} break;
case PPPC_SET_ENABLED:
case PPPC_ENABLE:
if(length < sizeof(uint32) || !data)
return B_ERROR;
@ -133,30 +111,43 @@ PPPProtocol::StackControl(uint32 op, void *data)
void
PPPProtocol::Pulse()
PPPProtocol::SetEnabled(bool enabled = true)
{
// do nothing by default
fEnabled = enabled;
if(!enabled) {
if(IsUp() || IsGoingUp())
Down();
} else if(!IsUp() && !IsGoingUp() && IsUpRequested() && Interface().IsUp())
Up();
}
bool
PPPProtocol::IsAllowedToSend() const
{
return IsEnabled() && IsUp() && IsProtocolAllowed(*this);
}
void
PPPProtocol::UpStarted()
{
fConnectionStatus = PPP_ESTABLISHMENT_PHASE;
fConnectionPhase = PPP_ESTABLISHMENT_PHASE;
}
void
PPPProtocol::DownStarted()
{
fConnectionStatus = PPP_TERMINATION_PHASE;
fConnectionPhase = PPP_TERMINATION_PHASE;
}
void
PPPProtocol::UpFailedEvent()
{
fConnectionStatus = PPP_DOWN_PHASE;
fConnectionPhase = PPP_DOWN_PHASE;
Interface().StateMachine().UpFailedEvent(this);
}
@ -165,7 +156,7 @@ PPPProtocol::UpFailedEvent()
void
PPPProtocol::UpEvent()
{
fConnectionStatus = PPP_ESTABLISHED_PHASE;
fConnectionPhase = PPP_ESTABLISHED_PHASE;
Interface().StateMachine().UpEvent(this);
}
@ -174,7 +165,7 @@ PPPProtocol::UpEvent()
void
PPPProtocol::DownEvent()
{
fConnectionStatus = PPP_DOWN_PHASE;
fConnectionPhase = PPP_DOWN_PHASE;
Interface().StateMachine().DownEvent(this);
}

View File

@ -10,8 +10,6 @@
#include <KPPPUtils.h>
#include <new.h>
PPPReportManager::PPPReportManager(BLocker& lock)
: fLock(lock)

View File

@ -10,12 +10,11 @@
#include <KPPPInterface.h>
#include <KPPPConfigurePacket.h>
#include <KPPPDevice.h>
#include <KPPPEncapsulator.h>
#include <KPPPLCPExtension.h>
#include <KPPPOptionHandler.h>
#include <net/if.h>
#include <mbuf.h>
#include <core_funcs.h>
#define PPP_STATE_MACHINE_TIMEOUT 3000000
@ -119,7 +118,6 @@ PPPStateMachine::Reconfigure()
NewPhase(PPP_ESTABLISHMENT_PHASE);
DownProtocols();
DownEncapsulators();
ResetLCPHandlers();
locker.UnlockNow();
@ -331,7 +329,7 @@ PPPStateMachine::UpFailedEvent(PPPProtocol *protocol)
{
if((protocol->Flags() & PPP_NOT_IMPORTANT) == 0) {
if(Interface().Mode() == PPP_CLIENT_MODE) {
// pretend we lost connection:
// pretend we lost connection
if(Interface().IsMultilink() && !Interface().Parent())
for(int32 index = 0; index < Interface().CountChildren(); index++)
Interface().ChildAt(index)->StateMachine().CloseEvent();
@ -352,7 +350,7 @@ PPPStateMachine::UpEvent(PPPProtocol *protocol)
LockerHelper locker(fLock);
if(Phase() >= PPP_ESTABLISHMENT_PHASE)
BringHandlersUp();
BringProtocolsUp();
}
@ -362,42 +360,6 @@ PPPStateMachine::DownEvent(PPPProtocol *protocol)
}
void
PPPStateMachine::UpFailedEvent(PPPEncapsulator *encapsulator)
{
if((encapsulator->Flags() & PPP_NOT_IMPORTANT) == 0) {
if(Interface().Mode() == PPP_CLIENT_MODE) {
// pretend we lost connection:
if(Interface().IsMultilink() && !Interface().Parent())
for(int32 index = 0; index < Interface().CountChildren(); index++)
Interface().ChildAt(index)->StateMachine().CloseEvent();
else if(Interface().Device())
Interface().Device()->Down();
else
CloseEvent();
// just to be on the secure side ;)
} else
CloseEvent();
}
}
void
PPPStateMachine::UpEvent(PPPEncapsulator *encapsulator)
{
LockerHelper locker(fLock);
if(Phase() >= PPP_ESTABLISHMENT_PHASE)
BringHandlersUp();
}
void
PPPStateMachine::DownEvent(PPPEncapsulator *encapsulator)
{
}
// This is called by the device to tell us that it entered establishment
// phase. We can use Device::Down() to abort establishment until UpEvent()
// is called.
@ -566,7 +528,6 @@ PPPStateMachine::DownEvent()
NewPhase(PPP_DOWN_PHASE);
DownProtocols();
DownEncapsulators();
fLocalAuthenticationStatus = PPP_NOT_AUTHENTICATED;
fPeerAuthenticationStatus = PPP_NOT_AUTHENTICATED;
@ -916,10 +877,10 @@ PPPStateMachine::RCAEvent(struct mbuf *packet)
// let the option handlers parse this ack
PPPConfigurePacket ack(packet);
PPPOptionHandler *handler;
PPPOptionHandler *optionHandler;
for(int32 index = 0; index < LCP().CountOptionHandlers(); index++) {
handler = LCP().OptionHandlerAt(index);
if(handler->ParseAck(ack) != B_OK) {
optionHandler = LCP().OptionHandlerAt(index);
if(optionHandler->ParseAck(ack) != B_OK) {
m_freem(packet);
locker.UnlockNow();
CloseEvent();
@ -991,19 +952,19 @@ PPPStateMachine::RCNEvent(struct mbuf *packet)
// let the option handlers parse this nak/reject
PPPConfigurePacket nak_reject(packet);
PPPOptionHandler *handler;
PPPOptionHandler *optionHandler;
for(int32 index = 0; index < LCP().CountOptionHandlers(); index++) {
handler = LCP().OptionHandlerAt(index);
optionHandler = LCP().OptionHandlerAt(index);
if(nak_reject.Code() == PPP_CONFIGURE_NAK) {
if(handler->ParseNak(nak_reject) != B_OK) {
if(optionHandler->ParseNak(nak_reject) != B_OK) {
m_freem(packet);
locker.UnlockNow();
CloseEvent();
return;
}
} else if(nak_reject.Code() == PPP_CONFIGURE_REJECT) {
if(handler->ParseReject(nak_reject) != B_OK) {
if(optionHandler->ParseReject(nak_reject) != B_OK) {
m_freem(packet);
locker.UnlockNow();
CloseEvent();
@ -1156,7 +1117,7 @@ PPPStateMachine::RTAEvent(struct mbuf *packet)
// receive unknown code
void
PPPStateMachine::RUCEvent(struct mbuf *packet, uint16 protocol,
PPPStateMachine::RUCEvent(struct mbuf *packet, uint16 protocolNumber,
uint8 code = PPP_PROTOCOL_REJECT)
{
LockerHelper locker(fLock);
@ -1170,7 +1131,7 @@ PPPStateMachine::RUCEvent(struct mbuf *packet, uint16 protocol,
default:
locker.UnlockNow();
SendCodeReject(packet, protocol, code);
SendCodeReject(packet, protocolNumber, code);
}
}
@ -1332,17 +1293,17 @@ PPPStateMachine::RCREvent(struct mbuf *packet)
// each handler should add unacceptable values for each item
status_t result;
// the return value of ParseRequest()
PPPOptionHandler *handler;
PPPOptionHandler *optionHandler;
for(int32 index = 0; index < request.CountItems(); index++) {
handler = LCP().OptionHandlerFor(request.ItemAt(index)->type);
optionHandler = LCP().OptionHandlerFor(request.ItemAt(index)->type);
if(!handler || !handler->IsEnabled()) {
if(!optionHandler || !optionHandler->IsEnabled()) {
// unhandled items should be added to the reject
reject.AddItem(request.ItemAt(index));
continue;
}
result = handler->ParseRequest(request, index, nak, reject);
result = optionHandler->ParseRequest(request, index, nak, reject);
if(result == PPP_UNHANDLED) {
// unhandled items should be added to the reject
@ -1361,9 +1322,9 @@ PPPStateMachine::RCREvent(struct mbuf *packet)
// If we sent too many naks we should not append additional values.
if(fNakCounter > 0) {
for(int32 index = 0; index < LCP().CountOptionHandlers(); index++) {
handler = LCP().OptionHandlerAt(index);
if(handler && handler->IsEnabled()) {
result = handler->ParseRequest(request, request.CountItems(),
optionHandler = LCP().OptionHandlerAt(index);
if(optionHandler && optionHandler->IsEnabled()) {
result = optionHandler->ParseRequest(request, request.CountItems(),
nak, reject);
if(result != B_OK) {
@ -1411,12 +1372,12 @@ PPPStateMachine::RXJEvent(struct mbuf *packet)
}
// find the LCP extension and disable it
PPPLCPExtension *extension;
PPPLCPExtension *lcpExtension;
for(int32 index = 0; index < LCP().CountLCPExtensions(); index++) {
extension = LCP().LCPExtensionAt(index);
lcpExtension = LCP().LCPExtensionAt(index);
if(extension->Code() == rejectedCode)
extension->SetEnabled(false);
if(lcpExtension->Code() == rejectedCode)
lcpExtension->SetEnabled(false);
}
m_freem(packet);
@ -1431,25 +1392,14 @@ PPPStateMachine::RXJEvent(struct mbuf *packet)
return;
}
// disable protocols and encapsulators with the rejected protocl number
int32 index;
PPPProtocol *protocol_handler;
PPPEncapsulator *encapsulator_handler = Interface().FirstEncapsulator();
for(index = 0; index < Interface().CountProtocols(); index++) {
protocol_handler = Interface().ProtocolAt(index);
if(protocol_handler && protocol_handler->Protocol() == rejected)
protocol_handler->SetEnabled(false);
// disable protocols with the rejected protocol number
PPPProtocol *protocol = Interface().FirstProtocol();
for(; protocol; protocol = protocol->NextProtocol()) {
if(protocol->ProtocolNumber() == rejected)
protocol->SetEnabled(false);
// disable protocol
}
for(; encapsulator_handler;
encapsulator_handler = encapsulator_handler->Next()) {
if(encapsulator_handler->Protocol() == rejected)
encapsulator_handler->SetEnabled(false);
// disable encapsulator
}
RXJGoodEvent(packet);
// this event handler does not m_freem(packet)!!!
@ -1487,16 +1437,15 @@ PPPStateMachine::ThisLayerUp()
locker.UnlockNow();
BringHandlersUp();
BringProtocolsUp();
}
void
PPPStateMachine::ThisLayerDown()
{
// PPPProtocol/Encapsulator::Down() should block if needed.
// PPPProtocol::Down() should block if needed.
DownProtocols();
DownEncapsulators();
}
@ -1653,7 +1602,7 @@ PPPStateMachine::SendTerminateAck(struct mbuf *request = NULL)
bool
PPPStateMachine::SendCodeReject(struct mbuf *packet, uint16 protocol, uint8 code)
PPPStateMachine::SendCodeReject(struct mbuf *packet, uint16 protocolNumber, uint8 code)
{
if(!packet)
return false;
@ -1687,9 +1636,9 @@ PPPStateMachine::SendCodeReject(struct mbuf *packet, uint16 protocol, uint8 code
else
reject->length = htons(packet->m_len);
protocol = htons(protocol);
protocolNumber = htons(protocolNumber);
if(code == PPP_PROTOCOL_REJECT)
memcpy(&reject->data, &protocol, sizeof(protocol));
memcpy(&reject->data, &protocolNumber, sizeof(protocolNumber));
return LCP().Send(packet) == B_OK;
}
@ -1716,9 +1665,9 @@ PPPStateMachine::SendEchoReply(struct mbuf *request)
}
// methods for bringing protocols/encapsulators up
// methods for bringing protocols up
void
PPPStateMachine::BringHandlersUp()
PPPStateMachine::BringProtocolsUp()
{
// use a simple check for phase changes (e.g., caused by CloseEvent())
while(Phase() <= PPP_ESTABLISHED_PHASE && Phase() >= PPP_AUTHENTICATION_PHASE) {
@ -1750,29 +1699,13 @@ PPPStateMachine::BringPhaseUp()
return 0;
uint32 count = 0;
PPPProtocol *protocol_handler;
PPPEncapsulator *encapsulator_handler = Interface().FirstEncapsulator();
for(int32 index = 0; index < Interface().CountProtocols(); index++) {
protocol_handler = Interface().ProtocolAt(index);
if(protocol_handler && protocol_handler->IsEnabled()
&& protocol_handler->Phase() == Phase()) {
if(protocol_handler->IsUpRequested()) {
PPPProtocol *protocol = Interface().FirstProtocol();
for(; protocol; protocol = protocol->NextProtocol()) {
if(protocol->IsEnabled() && protocol->ActivationPhase() == Phase()) {
if(protocol->IsUpRequested()) {
++count;
protocol_handler->Up();
} else if(protocol_handler->IsGoingUp())
++count;
}
}
for(; encapsulator_handler;
encapsulator_handler = encapsulator_handler->Next()) {
if(encapsulator_handler && encapsulator_handler->IsEnabled()
&& encapsulator_handler->Phase() == Phase()) {
if(encapsulator_handler->IsUpRequested()) {
++count;
encapsulator_handler->Up();
} else if(encapsulator_handler->IsGoingUp())
protocol->Up();
} else if(protocol->IsGoingUp())
++count;
}
}
@ -1784,21 +1717,11 @@ PPPStateMachine::BringPhaseUp()
void
PPPStateMachine::DownProtocols()
{
for(int32 index = 0; index < Interface().CountProtocols(); index++)
if(Interface().ProtocolAt(index)->IsEnabled())
Interface().ProtocolAt(index)->Down();
}
void
PPPStateMachine::DownEncapsulators()
{
PPPEncapsulator *encapsulator_handler = Interface().FirstEncapsulator();
PPPProtocol *protocol = Interface().FirstProtocol();
for(; encapsulator_handler;
encapsulator_handler = encapsulator_handler->Next())
if(encapsulator_handler->IsEnabled())
encapsulator_handler->Down();
for(; protocol; protocol = protocol->NextProtocol())
if(protocol->IsEnabled())
protocol->Down();
}

View File

@ -8,6 +8,23 @@
#include <OS.h>
#include <KPPPUtils.h>
#include <KPPPInterface.h>
bool
IsProtocolAllowed(const PPPProtocol& protocol)
{
if(protocol.ProtocolNumber() == PPP_LCP_PROTOCOL)
return true;
else if(protocol.Interface().State() != PPP_OPENED_STATE)
return false;
else if(protocol.Interface().Phase() > PPP_AUTHENTICATION_PHASE
|| (protocol.Interface().Phase() >= PPP_ESTABLISHMENT_PHASE
&& protocol.Flags() & PPP_ALWAYS_ALLOWED))
return true;
else
return false;
}
// These are very simple send/receive_data functions with a timeout

View File

@ -18,36 +18,35 @@
typedef struct authentication_item {
uint8 type;
uint8 length;
uint16 protocol;
uint16 protocolNumber;
} authentication_item;
_PPPAuthenticationHandler::_PPPAuthenticationHandler(PPPInterface& interface)
: PPPOptionHandler("Authentication Handler", AUTHENTICATION_TYPE, interface, NULL),
fLocalIndex(-1),
fPeerIndex(-1),
fSuggestedLocalIndex(-1),
fSuggestedPeerIndex(-1),
fLocalAuthenticator(NULL),
fPeerAuthenticator(NULL),
fSuggestedLocalAuthenticator(NULL),
fSuggestedPeerAuthenticator(NULL),
fPeerAuthenticatorRejected(false)
{
}
int32
_PPPAuthenticationHandler::NextAuthenticator(int32 start, ppp_side side)
PPPProtocol*
_PPPAuthenticationHandler::NextAuthenticator(const PPPProtocol *start,
ppp_side side) const
{
// find the next authenticator for side, beginning at start
PPPProtocol *current = start ? start->NextProtocol() : Interface().FirstProtocol();
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;
for(; current; current = current->NextProtocol()) {
if(!strcasecmp(current->Type(), AUTHENTICATOR_TYPE_STRING)
&& current->OptionHandler() && current->Side() == side)
return current;
}
return -1;
return NULL;
}
@ -58,52 +57,49 @@ _PPPAuthenticationHandler::AddToRequest(PPPConfigurePacket& request)
// 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(fPeerAuthenticator)
fPeerAuthenticator->SetEnabled(false);
if(fSuggestedPeerAuthenticator)
fSuggestedPeerAuthenticator->SetEnabled(false);
PPPProtocol *authenticator;
if(fPeerAuthenticatorRejected) {
if(fSuggestedPeerIndex == -1) {
if(!fSuggestedPeerAuthenticator) {
// 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);
authenticator = NextAuthenticator(fPeerAuthenticator, PPP_PEER_SIDE);
} else
index = fSuggestedPeerIndex;
authenticator = fSuggestedPeerAuthenticator;
fPeerAuthenticatorRejected = false;
} else {
if(fPeerIndex == -1) {
if(!fPeerAuthenticator) {
// there is no authenticator selected, so find one for us
index = NextAuthenticator(fPeerIndex + 1, PPP_PEER_SIDE);
authenticator = NextAuthenticator(fPeerAuthenticator, PPP_PEER_SIDE);
} else
index = fPeerIndex;
authenticator = fPeerAuthenticator;
}
// 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
if(!authenticator) {
if(fPeerAuthenticator)
return B_ERROR;
// all authenticators were denied
else
return B_OK;
// no peer authentication needed
}
protocol = Interface().ProtocolAt(index);
if(!protocol || !protocol->OptionHandler())
if(!authenticator || !authenticator->OptionHandler())
return B_ERROR;
fPeerIndex = index;
fPeerAuthenticator = authenticator;
// 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);
authenticator->SetEnabled(true);
return authenticator->OptionHandler()->AddToRequest(request);
// let protocol add its request
}
@ -122,26 +118,25 @@ _PPPAuthenticationHandler::ParseNak(const PPPConfigurePacket& nak)
if(item->length < 4)
return B_ERROR;
PPPProtocol *protocol;
if(fSuggestedPeerIndex != -1
&& (protocol = Interface().ProtocolAt(fSuggestedPeerIndex))) {
protocol->SetEnabled(false);
if(fSuggestedPeerAuthenticator) {
fSuggestedPeerAuthenticator->SetEnabled(false);
// if no alternative protocol is supplied we will choose a new one in
// AddToRequest()
if(ntohs(item->protocol) == protocol->Protocol()) {
fSuggestedPeerIndex = -1;
if(ntohs(item->protocolNumber) ==
fSuggestedPeerAuthenticator->ProtocolNumber()) {
fSuggestedPeerAuthenticator = NULL;
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;
PPPProtocol *authenticator = Interface().ProtocolFor(ntohs(item->protocolNumber));
if(authenticator
&& !strcasecmp(authenticator->Type(), AUTHENTICATOR_TYPE_STRING)
&& authenticator->OptionHandler())
fSuggestedPeerAuthenticator = authenticator;
else
fSuggestedPeerIndex = -1;
fSuggestedPeerAuthenticator = NULL;
return B_OK;
}
@ -164,20 +159,20 @@ _PPPAuthenticationHandler::ParseAck(const PPPConfigurePacket& ack)
authentication_item *item =
(authentication_item*) ack.ItemWithType(AUTHENTICATION_TYPE);
PPPProtocol *protocol = Interface().ProtocolAt(fPeerIndex);
if(fPeerIndex != -1 && !protocol)
if(!fPeerAuthenticator)
return B_ERROR;
// could not find the protocol
// could not find the authenticator
if(!item) {
if(fPeerIndex != -1)
if(fPeerAuthenticator)
return B_ERROR;
// the ack does not contain our request
} else if(fPeerIndex == -1 || ntohs(item->protocol) != protocol->Protocol())
} else if(!fPeerAuthenticator
|| ntohs(item->protocolNumber) != fPeerAuthenticator->ProtocolNumber())
return B_ERROR;
// this item was never requested
return protocol->OptionHandler()->ParseAck(ack);
return fPeerAuthenticator->OptionHandler()->ParseAck(ack);
// this should enable the authenticator
}
@ -186,48 +181,45 @@ 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);
if(fLocalAuthenticator)
fLocalAuthenticator->SetEnabled(false);
authentication_item *item = (authentication_item*) request.ItemAt(index);
if(!item)
return B_OK;
// no authentication requested by peer
// no authentication requested by peer (index > request.CountItems())
// 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);
// try to find the requested protocol
fLocalAuthenticator = Interface().ProtocolFor(ntohs(item->protocolNumber));
if(fLocalAuthenticator &&
!strcasecmp(fLocalAuthenticator->Type(), AUTHENTICATOR_TYPE_STRING)
&& fLocalAuthenticator->OptionHandler())
return fLocalAuthenticator->OptionHandler()->ParseRequest(request, index,
nak, reject);
// suggest another authentication protocol
int32 nextIndex = NextAuthenticator(fSuggestedLocalIndex + 1, PPP_LOCAL_SIDE);
PPPProtocol *nextAuthenticator =
NextAuthenticator(fSuggestedLocalAuthenticator, PPP_LOCAL_SIDE);
if(nextIndex == -1) {
if(fSuggestedLocalIndex == -1) {
if(!nextAuthenticator) {
if(!fSuggestedLocalAuthenticator) {
// reject the complete authentication option
reject.AddItem((ppp_configure_item*) item);
return B_OK;
} else
nextIndex = fSuggestedLocalIndex;
nextAuthenticator = fSuggestedLocalAuthenticator;
// 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;
fSuggestedLocalAuthenticator = nextAuthenticator;
fLocalAuthenticator = NULL;
// 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());
suggestion.protocolNumber = htons(nextAuthenticator->ProtocolNumber());
return nak.AddItem((ppp_configure_item*) &suggestion) ? B_OK : B_ERROR;
}
@ -244,18 +236,17 @@ _PPPAuthenticationHandler::SendingAck(const PPPConfigurePacket& ack)
return B_OK;
// no authentication needed
fSuggestedLocalIndex = -1;
fSuggestedLocalAuthenticator = NULL;
if(fLocalIndex == -1)
if(!fLocalAuthenticator)
return B_ERROR;
// no authenticator selected (our suggestions must be requested, too)
PPPProtocol *protocol = Interface().ProtocolAt(fLocalIndex);
if(!protocol)
if(!fLocalAuthenticator)
return B_ERROR;
protocol->SetEnabled(true);
return protocol->OptionHandler()->SendingAck(ack);
fLocalAuthenticator->SetEnabled(true);
return fLocalAuthenticator->OptionHandler()->SendingAck(ack);
// this should enable the authenticator
}
@ -263,21 +254,20 @@ _PPPAuthenticationHandler::SendingAck(const PPPConfigurePacket& ack)
void
_PPPAuthenticationHandler::Reset()
{
PPPProtocol *protocol = NULL;
if(fLocalIndex != -1 && (protocol = Interface().ProtocolAt(fLocalIndex))) {
protocol->SetEnabled(false);
protocol->OptionHandler()->Reset();
if(fLocalAuthenticator) {
fLocalAuthenticator->SetEnabled(false);
fLocalAuthenticator->OptionHandler()->Reset();
}
if(fPeerIndex != -1 && (protocol = Interface().ProtocolAt(fPeerIndex))) {
protocol->SetEnabled(false);
protocol->OptionHandler()->Reset();
if(fPeerAuthenticator) {
fPeerAuthenticator->SetEnabled(false);
fPeerAuthenticator->OptionHandler()->Reset();
}
if(fSuggestedPeerIndex != -1
&& (protocol = Interface().ProtocolAt(fSuggestedPeerIndex))) {
protocol->SetEnabled(false);
protocol->OptionHandler()->Reset();
if(fSuggestedPeerAuthenticator) {
fSuggestedPeerAuthenticator->SetEnabled(false);
fSuggestedPeerAuthenticator->OptionHandler()->Reset();
}
fLocalIndex = fPeerIndex = fSuggestedLocalIndex = fSuggestedPeerIndex = -1;
fLocalAuthenticator = fPeerAuthenticator = fSuggestedLocalAuthenticator =
fSuggestedPeerAuthenticator = NULL;
fPeerAuthenticatorRejected = false;
}

View File

@ -15,7 +15,7 @@ class _PPPAuthenticationHandler : public PPPOptionHandler {
public:
_PPPAuthenticationHandler(PPPInterface& interface);
int32 NextAuthenticator(int32 start, ppp_side side);
PPPProtocol *NextAuthenticator(const PPPProtocol *start, ppp_side side) const;
virtual status_t AddToRequest(PPPConfigurePacket& request);
virtual status_t ParseNak(const PPPConfigurePacket& nak);
@ -29,7 +29,8 @@ class _PPPAuthenticationHandler : public PPPOptionHandler {
virtual void Reset();
private:
int32 fLocalIndex, fPeerIndex, fSuggestedLocalIndex, fSuggestedPeerIndex;
PPPProtocol *fLocalAuthenticator, *fPeerAuthenticator,
*fSuggestedLocalAuthenticator, *fSuggestedPeerAuthenticator;
bool fPeerAuthenticatorRejected;
};

View File

@ -12,7 +12,6 @@
#include <KPPPDevice.h>
// includes KPPPInterface.h, KPPPLCP.h,
// KPPPStateMachine.h and KPPPProtocol.h
#include <KPPPEncapsulator.h>
#include <KPPPLCPExtension.h>
#include <KPPPOptionHandler.h>

View File

@ -8,9 +8,10 @@
#ifndef _K_PPP_CONFIGURE_PACKET__H
#define _K_PPP_CONFIGURE_PACKET__H
#include <mbuf.h>
#include <List.h>
struct mbuf;
typedef struct ppp_configure_item {
uint8 type;

View File

@ -17,6 +17,9 @@ typedef uint32 interface_id;
#define PPP_PULSE_RATE 500000
extern struct core_module_info *core;
// module key types (used when loading a module)
enum ppp_module_key_type {
PPP_UNDEFINED_KEY_TYPE = -1,

View File

@ -9,23 +9,22 @@
#define _K_PPP_DEVICE__H
#include <KPPPDefs.h>
#include <KPPPLayer.h>
#ifndef _K_PPP_INTERFACE__H
#include <KPPPInterface.h>
#endif
class PPPDevice {
public:
class PPPDevice : public PPPLayer {
protected:
// PPPDevice must be subclassed
PPPDevice(const char *name, PPPInterface& interface,
driver_parameter *settings);
public:
virtual ~PPPDevice();
virtual status_t InitCheck() const;
const char *Name() const
{ return fName; }
PPPInterface& Interface() const
{ return fInterface; }
driver_parameter *Settings() const
@ -37,9 +36,9 @@ class PPPDevice {
{ return fMTU; }
// these calls must not block
virtual void Up() = 0;
virtual void Down() = 0;
virtual void Listen() = 0;
virtual bool Up() = 0;
virtual bool Down() = 0;
virtual bool Listen() = 0;
bool IsUp() const
{ return fIsUp; }
@ -51,13 +50,14 @@ class PPPDevice {
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.
virtual bool IsAllowedToSend() const;
// always returns true
virtual status_t Send(struct mbuf *packet, uint16 protocolNumber) = 0;
// This should enqueue the packet and return immediately (never block).
// 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 status_t Receive(struct mbuf *packet, uint16 protocolNumber);
// this method is never used
virtual void Pulse();
@ -79,13 +79,13 @@ class PPPDevice {
protected:
uint32 fMTU;
// always hold this value up-to-date!
bool fIsUp;
status_t fInitStatus;
private:
char *fName;
PPPInterface& fInterface;
driver_parameter *fSettings;
bool fIsUp;
};

View File

@ -1,128 +0,0 @@
//----------------------------------------------------------------------
// This software is part of the OpenBeOS distribution and is covered
// by the OpenBeOS license.
//
// Copyright (c) 2003 Waldemar Kornewald, Waldemar.Kornewald@web.de
//---------------------------------------------------------------------
#ifndef _K_PPP_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

@ -27,14 +27,13 @@
class PPPDevice;
class PPPProtocol;
class PPPEncapsulator;
class PPPOptionHandler;
struct ppp_manager_info;
struct ppp_interface_module_info;
struct ppp_module_info;
class PPPInterface {
class PPPInterface : public PPPLayer {
friend class PPPStateMachine;
friend class PPPManager;
@ -51,7 +50,7 @@ class PPPInterface {
public:
void Delete();
status_t InitCheck() const;
virtual status_t InitCheck() const;
interface_id ID() const
{ return fID; }
@ -67,9 +66,6 @@ class PPPInterface {
struct ifnet *Ifnet() const
{ return fIfnet; }
struct ifq *InQueue() const
{ return fInQueue; }
// delays
uint32 DialRetryDelay() const
{ return fDialRetryDelay; }
@ -90,9 +86,9 @@ class PPPInterface {
{ return SetMRU(interfaceMTU - fHeaderLength); }
uint32 InterfaceMTU() const
{ return fInterfaceMTU; }
// this is the MRU including encapsulator overhead
// this is the MRU including protocol overhead
status_t Control(uint32 op, void *data, size_t length);
virtual status_t Control(uint32 op, void *data, size_t length);
bool SetDevice(PPPDevice *device);
PPPDevice *Device() const
@ -100,21 +96,11 @@ class PPPInterface {
bool AddProtocol(PPPProtocol *protocol);
bool RemoveProtocol(PPPProtocol *protocol);
int32 CountProtocols() const
{ return fProtocols.CountItems(); }
int32 CountProtocols() const;
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;
PPPProtocol *FirstProtocol() const
{ return fFirstProtocol; }
PPPProtocol *ProtocolFor(uint16 protocolNumber, PPPProtocol *start = NULL) const;
// multilink methods
bool AddChild(PPPInterface *child);
@ -158,9 +144,9 @@ class PPPInterface {
bool UseLocalPFC() const
{ return LocalPFCState() & PPP_PFC_ACCEPTED; }
bool Up();
virtual bool Up();
// in server mode Up() listens for an incoming connection
bool Down();
virtual bool Down();
bool IsUp() const;
PPPReportManager& ReportManager()
@ -174,10 +160,13 @@ class PPPInterface {
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);
virtual bool IsAllowedToSend() const;
// always returns true
virtual status_t Send(struct mbuf *packet, uint16 protocolNumber);
// sends the packet to the next handler (normally the device)
virtual status_t Receive(struct mbuf *packet, uint16 protocolNumber);
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
@ -215,14 +204,13 @@ class PPPInterface {
PPPReportManager fReportManager;
struct ifnet *fIfnet;
thread_id fUpThread, fInQueueThread;
struct ifq *fInQueue;
thread_id fUpThread;
thread_id fRedialThread;
uint32 fDialRetry, fDialRetriesLimit;
uint32 fDialRetryDelay, fRedialDelay;
ppp_manager_info *fManager;
ppp_interface_module_info *fManager;
uint32 fIdleSince, fDisconnectAfterIdleSince;
uint32 fMRU, fInterfaceMTU, fHeaderLength;
@ -238,13 +226,10 @@ class PPPInterface {
uint8 fPFCOptions;
PPPDevice *fDevice;
PPPEncapsulator *fFirstEncapsulator;
List<PPPProtocol*> fProtocols;
PPPProtocol *fFirstProtocol;
List<char*> fModules;
BLocker& fLock;
status_t fInitStatus;
int32 fDeleteCounter;
};

View File

@ -22,7 +22,6 @@
#include <KPPPStateMachine.h>
#endif
class PPPEncapsulator;
class PPPLCPExtension;
class PPPOptionHandler;
@ -65,12 +64,12 @@ class PPPLCP : public PPPProtocol {
PPPLCPExtension *LCPExtensionAt(int32 index) const;
PPPLCPExtension *LCPExtensionFor(uint8 code, int32 *start = NULL) const;
PPPEncapsulator *Target() const
{ return fTarget; }
void SetTarget(PPPEncapsulator *target)
void SetTarget(PPPProtocol *target)
{ fTarget = target; }
// if target != all packtes will be passed to the encapsulator
// if target != NULL all packtes will be passed to the protocol
// instead of the interface/device
PPPProtocol *Target() const
{ return fTarget; }
uint32 AdditionalOverhead() const;
// the overhead caused by the target, the device, and the interface
@ -78,8 +77,9 @@ class PPPLCP : public PPPProtocol {
virtual bool Up();
virtual bool Down();
virtual status_t Send(struct mbuf *packet);
virtual status_t Receive(struct mbuf *packet, uint16 protocol);
virtual status_t Send(struct mbuf *packet,
uint16 protocolNumber = PPP_LCP_PROTOCOL);
virtual status_t Receive(struct mbuf *packet, uint16 protocolNumber);
virtual void Pulse();
@ -89,7 +89,7 @@ class PPPLCP : public PPPProtocol {
List<PPPOptionHandler*> fOptionHandlers;
List<PPPLCPExtension*> fLCPExtensions;
PPPEncapsulator *fTarget;
PPPProtocol *fTarget;
};

View File

@ -16,9 +16,12 @@
class PPPLCPExtension {
public:
protected:
// PPPLCPExtension must be subclassed
PPPLCPExtension(const char *name, uint8 code, PPPInterface& interface,
driver_parameter *settings);
public:
virtual ~PPPLCPExtension();
virtual status_t InitCheck() const;

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_LAYER__H
#define _K_PPP_LAYER__H
#include <KPPPDefs.h>
class PPPLayer {
protected:
// PPPLayer must be subclassed
PPPLayer(const char *name, ppp_level level);
public:
virtual ~PPPLayer();
virtual status_t InitCheck() const;
const char *Name() const
{ return fName; }
ppp_level Level() const
{ return fLevel; }
// should be PPP_PROTOCOL_LEVEL if not encapsulator
void SetNext(PPPLayer *next)
{ fNext = next; }
PPPLayer *Next() const
{ return fNext; }
virtual bool Up() = 0;
virtual bool Down() = 0;
virtual bool IsAllowedToSend() const = 0;
virtual status_t Send(struct mbuf *packet, uint16 protocolNumber) = 0;
virtual status_t Receive(struct mbuf *packet, uint16 protocolNumber) = 0;
status_t SendToNext(struct mbuf *packet, uint16 protocolNumber) const;
// send the packet to the next layer
virtual void Pulse();
protected:
status_t fInitStatus;
private:
char *fName;
ppp_level fLevel;
PPPLayer *fNext;
};
#endif

View File

@ -11,7 +11,7 @@
#include "net_module.h"
#define PPP_MANAGER_MODULE_NAME "network/interfaces/ppp"
#define PPP_INTERFACE_MODULE_NAME "network/interfaces/ppp"
#define PPP_UNDEFINED_INTERFACE_ID 0
// create_interface() returns this value on failure
@ -23,26 +23,27 @@ enum ppp_interface_filter {
PPP_UNREGISTERED_INTERFACES
};
typedef struct ppp_manager_info {
typedef struct ppp_interface_module_info {
kernel_net_module_info knminfo;
interface_id (*create_interface)(const driver_settings *settings,
interface_id (*CreateInterface)(const driver_settings *settings,
interface_id parent);
// you should always create interfaces using this function
void (*delete_interface)(interface_id ID);
void (*DeleteInterface)(interface_id ID);
// this marks the interface for deletion
void (*remove_interface)(interface_id ID);
void (*RemoveInterface)(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);
ifnet *(*RegisterInterface)(interface_id ID);
bool (*UnregisterInterface)(interface_id ID);
status_t (*control)(interface_id ID, uint32 op, void *data, size_t length);
status_t (*Control)(interface_id ID, uint32 op, void *data, size_t length);
status_t (*get_interfaces)(interface_id **interfaces, uint32 *count,
int32 (*GetInterfaces)(interface_id *interfaces, int32 count,
ppp_interface_filter filter = PPP_REGISTERED_INTERFACES);
// the user is responsible for free()'ing the interface_id array
} ppp_manager_info;
// make sure interfaces has enough space for count items
int32 (*CountInterfaces)();
} ppp_interface_module_info;
#endif

View File

@ -18,9 +18,12 @@ class PPPConfigurePacket;
class PPPOptionHandler {
public:
protected:
// PPPOptionHandler must be subclassed
PPPOptionHandler(const char *name, uint8 type, PPPInterface& interface,
driver_parameter *settings);
public:
virtual ~PPPOptionHandler();
virtual status_t InitCheck() const;

View File

@ -9,34 +9,38 @@
#define _K_PPP_PROTOCOL__H
#include <KPPPDefs.h>
#include <KPPPLayer.h>
class PPPInterface;
class PPPOptionHandler;
class PPPProtocol {
public:
PPPProtocol(const char *name, ppp_phase phase, uint16 protocol,
int32 addressFamily, PPPInterface& interface,
class PPPProtocol : public PPPLayer {
protected:
// PPPProtocol must be subclassed
PPPProtocol(const char *name, ppp_phase activationPhase,
uint16 protocolNumber, ppp_level level, int32 addressFamily,
uint32 overhead, PPPInterface& interface,
driver_parameter *settings, int32 flags = PPP_NO_FLAGS,
const char *type = NULL, PPPOptionHandler *optionHandler = NULL);
public:
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; }
ppp_phase ActivationPhase() const
{ return fActivationPhase; }
uint32 Overhead() const
{ return fOverhead; }
// only useful for encapsulation protocols
uint16 ProtocolNumber() const
{ return fProtocolNumber; }
int32 AddressFamily() const
{ return fAddressFamily; }
// negative values and values > 0xFF are ignored
@ -46,12 +50,16 @@ class PPPProtocol {
{ return fSide; }
// which side this protocol works for
// extensions
const char *Type() const
{ return fType; }
PPPOptionHandler *OptionHandler() const
{ return fOptionHandler; }
void SetNextProtocol(PPPProtocol *protocol)
{ fNextProtocol = protocol; SetNext(protocol); }
PPPProtocol *NextProtocol() const
{ return fNextProtocol; }
void SetEnabled(bool enabled = true);
bool IsEnabled() const
{ return fEnabled; }
@ -67,39 +75,41 @@ class PPPProtocol {
virtual bool Down() = 0;
// if DialOnDemand is supported check for DialOnDemand settings change
bool IsUp() const
{ return fConnectionStatus == PPP_ESTABLISHED_PHASE; }
{ return fConnectionPhase == PPP_ESTABLISHED_PHASE; }
bool IsDown() const
{ return fConnectionStatus == PPP_DOWN_PHASE; }
{ return fConnectionPhase == PPP_DOWN_PHASE; }
bool IsGoingUp() const
{ return fConnectionStatus == PPP_ESTABLISHMENT_PHASE; }
{ return fConnectionPhase == PPP_ESTABLISHMENT_PHASE; }
bool IsGoingDown() const
{ return fConnectionStatus == PPP_TERMINATION_PHASE; }
{ return fConnectionPhase == PPP_TERMINATION_PHASE; }
virtual status_t Send(struct mbuf *packet) = 0;
virtual status_t Receive(struct mbuf *packet, uint16 protocol) = 0;
virtual bool IsAllowedToSend() const;
virtual void Pulse();
virtual status_t Send(struct mbuf *packet, uint16 protocolNumber) = 0;
virtual status_t Receive(struct mbuf *packet, uint16 protocolNumber) = 0;
protected:
void SetUpRequested(bool requested = true)
{ fUpRequested = requested; }
// Report that we are going up/down
// (from now on, the Up() process can be aborted).
void UpStarted();
void DownStarted();
// report up/down events
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;
uint16 fProtocol;
ppp_phase fActivationPhase;
ppp_level fLevel;
uint16 fProtocolNumber;
int32 fAddressFamily;
PPPInterface& fInterface;
driver_parameter *fSettings;
@ -107,9 +117,10 @@ class PPPProtocol {
char *fType;
PPPOptionHandler *fOptionHandler;
PPPProtocol *fNextProtocol;
bool fEnabled;
bool fUpRequested;
ppp_phase fConnectionStatus;
ppp_phase fConnectionPhase;
};

View File

@ -10,7 +10,6 @@
#include <KPPPDefs.h>
class PPPEncapsulator;
class PPPProtocol;
#ifndef _K_PPP_INTERFACE__H
@ -84,11 +83,6 @@ class PPPStateMachine {
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();
@ -115,7 +109,7 @@ class PPPStateMachine {
void RCNEvent(struct mbuf *packet);
void RTREvent(struct mbuf *packet);
void RTAEvent(struct mbuf *packet);
void RUCEvent(struct mbuf *packet, uint16 protocol,
void RUCEvent(struct mbuf *packet, uint16 protocolNumber,
uint8 code = PPP_PROTOCOL_REJECT);
void RXJGoodEvent(struct mbuf *packet);
void RXJBadEvent(struct mbuf *packet);
@ -139,14 +133,13 @@ class PPPStateMachine {
bool SendConfigureNak(struct mbuf *packet);
bool SendTerminateRequest();
bool SendTerminateAck(struct mbuf *request = NULL);
bool SendCodeReject(struct mbuf *packet, uint16 protocol, uint8 code);
bool SendCodeReject(struct mbuf *packet, uint16 protocolNumber, uint8 code);
bool SendEchoReply(struct mbuf *request);
void BringHandlersUp();
void BringProtocolsUp();
uint32 BringPhaseUp();
void DownProtocols();
void DownEncapsulators();
void ResetLCPHandlers();
private:

View File

@ -12,24 +12,13 @@
#include <KPPPDefs.h>
#endif
#include <OS.h>
class PPPProtocol;
// 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;
}
bool IsProtocolAllowed(const PPPProtocol& protocol);
// the list template does not support iterating over each item :(
// this template iterates over each item in an indexed list

View File

@ -28,7 +28,7 @@
#ifndef LIST_H
#define LIST_H
#include <new.h>
#include <kernel_cpp.h>
#include <stdlib.h>
#include <string.h>

View File

@ -22,7 +22,6 @@
#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
@ -45,7 +44,6 @@ enum ppp_control_ops {
// handler access
PPPC_CONTROL_DEVICE,
PPPC_CONTROL_PROTOCOL,
PPPC_CONTROL_ENCAPSULATOR,
PPPC_CONTROL_OPTION_HANDLER,
PPPC_CONTROL_LCP_EXTENSION,
PPPC_CONTROL_CHILD,
@ -56,11 +54,14 @@ enum ppp_control_ops {
PPPC_GET_DEVICE_INFO = PPP_DEVICE_OPS_START,
// -----------------------------------------------------
// -----------------------------------------------------
// PPPProtocol
PPPC_GET_PROTOCOL_INFO = PPP_PROTOCOL_OPS_START,
// -----------------------------------------------------
// -----------------------------------------------------
// Common/mixed ops
PPPC_GET_HANDLER_INFO = PPP_COMMON_OPS_START,
// PPPProtocol and PPPEncapsulator
PPPC_SET_ENABLED,
PPPC_ENABLE,
PPPC_GET_SIMPLE_HANDLER_INFO,
// PPPOptionHandler and PPPLCPExtension
// -----------------------------------------------------
@ -71,7 +72,7 @@ enum ppp_control_ops {
typedef struct ppp_control_info {
uint32 index;
// index of interface/protocol/encapsulator/etc.
// index of interface/protocol/etc.
uint32 op;
// the Control()/ioctl() opcode
void *data;
@ -97,8 +98,7 @@ typedef struct ppp_interface_info {
ppp_pfc_state localPFCState, peerPFCState;
uint8 pfcOptions;
uint32 protocolsCount, encapsulatorsCount, optionHandlersCount,
LCPExtensionsCount, childrenCount;
uint32 protocolsCount, optionHandlersCount, LCPExtensionsCount, childrenCount;
uint32 MRU, interfaceMTU;
uint32 dialRetry, dialRetriesLimit;
@ -118,9 +118,9 @@ typedef struct ppp_device_info {
char name[PPP_HANDLER_NAME_LENGTH_LIMIT + 1];
const driver_parameter *settings;
uint32 MTU;
uint32 inputTransferRate, outputTransferRate, outputBytesCount;
bool isUp;
} ppp_device_info;
typedef struct ppp_device_info_t {
ppp_device_info info;
@ -128,39 +128,32 @@ typedef struct ppp_device_info_t {
} ppp_device_info_t;
typedef struct ppp_handler_info {
typedef struct ppp_protocol_info {
char name[PPP_HANDLER_NAME_LENGTH_LIMIT + 1];
char type[PPP_HANDLER_NAME_LENGTH_LIMIT + 1];
// general
const driver_parameter *settings;
ppp_phase phase;
ppp_phase activationPhase;
int32 addressFamily, flags;
ppp_side side;
uint16 protocol;
ppp_level level;
uint32 overhead;
bool isEnabled;
// only protocol and encapsulator
bool isUpRequested;
ppp_phase connectionStatus;
ppp_phase connectionPhase;
// 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;
uint16 protocolNumber;
bool isEnabled;
bool isUpRequested;
} ppp_protocol_info;
typedef struct ppp_protocol_info_t {
ppp_protocol_info info;
uint8 _reserved_[_PPP_INFO_T_SIZE_ - sizeof(ppp_protocol_info)];
} ppp_protocol_info_t;
typedef struct ppp_simple_handler_info {

View File

@ -41,16 +41,16 @@ 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)
// return values for PPPProtocol
PPP_UNHANDLED = PPP_ERROR_BASE,
// The packet does not belong to this handler.
// The packet does not belong to this protocol.
// 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
// a protocol-reject was sent
PPP_NO_CONNECTION
// could not send a packet because device is not connected
@ -75,7 +75,7 @@ enum ppp_pfc_state {
// not used for peer state
};
// protocol and encapsulator flags
// protocol flags
enum {
PPP_NO_FLAGS = 0x00,
PPP_ALWAYS_ALLOWED = 0x01,
@ -112,11 +112,15 @@ enum ppp_phase {
};
// this defines the order in which the packets get encapsulated
enum ppp_encapsulation_level {
enum ppp_level {
PPP_DEVICE_LEVEL = 0,
PPP_INTERFACE_LEVEL = 1,
// only used by PPPInterface
PPP_MULTILINK_LEVEL = 2,
PPP_ENCRYPTION_LEVEL = 5,
PPP_COMPRESSION_LEVEL = 10
PPP_COMPRESSION_LEVEL = 10,
PPP_PROTOCOL_LEVEL = 1000
// highest level possible; use for protocols that do not encapsulate
};
// we can be a ppp client or a ppp server interface
@ -125,7 +129,7 @@ enum ppp_mode {
PPP_SERVER_MODE
};
// which side the protocol/encapsulator works for
// which side the protocol works for
enum ppp_side {
PPP_NO_SIDE,
PPP_LOCAL_SIDE,

View File

@ -107,7 +107,7 @@ get_side_string_value(const char *sideString, ppp_side unknownValue)
bool
get_string_value(const char *string, bool unknownValue)
get_boolean_value(const char *string, bool unknownValue)
{
if(!string)
return unknownValue;

View File

@ -21,7 +21,14 @@ 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); }
inline
const char*
get_parameter_value(const char *name, const driver_parameter *parameters)
{
return get_settings_value(name, (driver_settings*) &parameters->parameter_count);
}
#endif