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:
parent
f53ee751a9
commit
92a8026e02
|
@ -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
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
#include <KPPPConfigurePacket.h>
|
||||
#include <KPPPInterface.h>
|
||||
|
||||
#include <core_funcs.h>
|
||||
|
||||
|
||||
PPPConfigurePacket::PPPConfigurePacket(uint8 code)
|
||||
: fCode(code)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -10,8 +10,6 @@
|
|||
|
||||
#include <KPPPUtils.h>
|
||||
|
||||
#include <new.h>
|
||||
|
||||
|
||||
PPPReportManager::PPPReportManager(BLocker& lock)
|
||||
: fLock(lock)
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
#ifndef LIST_H
|
||||
#define LIST_H
|
||||
|
||||
#include <new.h>
|
||||
#include <kernel_cpp.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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*) ¶meters->parameter_count); }
|
||||
|
||||
|
||||
inline
|
||||
const char*
|
||||
get_parameter_value(const char *name, const driver_parameter *parameters)
|
||||
{
|
||||
return get_settings_value(name, (driver_settings*) ¶meters->parameter_count);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue