Mostly fixes and smaller API changes.

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@5119 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Waldemar Kornewald 2003-10-23 17:56:14 +00:00
parent f378b1b9c8
commit e745242193
24 changed files with 458 additions and 159 deletions

View File

@ -20,20 +20,20 @@ PPPConfigurePacket::PPPConfigurePacket(uint8 code)
PPPConfigurePacket::PPPConfigurePacket(struct mbuf *packet)
{
// decode packet
ppp_lcp_packet *data = mtod(packet, ppp_lcp_packet*);
ppp_lcp_packet *header = mtod(packet, ppp_lcp_packet*);
if(!SetCode(data->code))
if(!SetCode(header->code))
return;
if(data->length < 4)
if(header->length < 4)
return;
// there are no items (or one corrupted item)
int32 position = 0;
ppp_configure_item *item;
while(position <= data->length - 4) {
item = (ppp_configure_item*) (data->data + position);
while(position <= header->length - 4) {
item = (ppp_configure_item*) (header->data + position);
position += item->length;
AddItem(item);
@ -130,9 +130,9 @@ PPPConfigurePacket::ToMbuf(uint32 reserve = 0)
struct mbuf *packet = m_gethdr(MT_DATA);
packet->m_data += reserve;
ppp_lcp_packet *data = mtod(packet, ppp_lcp_packet*);
ppp_lcp_packet *header = mtod(packet, ppp_lcp_packet*);
data->code = Code();
header->code = Code();
uint8 length = 0;
ppp_configure_item *item;
@ -140,17 +140,18 @@ PPPConfigurePacket::ToMbuf(uint32 reserve = 0)
for(int32 index = 0; index < CountItems(); index++) {
item = ItemAt(index);
// make sure we have enough space left
if(0xFF - length < item->length) {
m_freem(packet);
return NULL;
}
memcpy(data->data + length, item, item->length);
memcpy(header->data + length, item, item->length);
length += item->length;
}
data->length = length + 2;
packet->m_len = data->length;
header->length = length + 2;
packet->m_len = header->length;
return packet;
}

View File

@ -19,15 +19,15 @@ PPPDevice::PPPDevice(const char *name, PPPInterface& interface,
fMTU(1500),
fInterface(interface),
fSettings(settings),
fIsUp(false)
fConnectionPhase(PPP_DOWN_PHASE)
{
fInitStatus = interface.SetDevice(this) && fInitStatus == B_OK ? B_OK : B_ERROR;
}
PPPDevice::~PPPDevice()
{
Interface().SetDevice(NULL);
if(Interface().Device() == this)
Interface().SetDevice(NULL);
}
@ -85,15 +85,19 @@ PPPDevice::Pulse()
bool
PPPDevice::UpStarted() const
PPPDevice::UpStarted()
{
fConnectionPhase = PPP_ESTABLISHMENT_PHASE;
return Interface().StateMachine().TLSNotify();
}
bool
PPPDevice::DownStarted() const
PPPDevice::DownStarted()
{
fConnectionPhase = PPP_TERMINATION_PHASE;
return Interface().StateMachine().TLFNotify();
}
@ -101,7 +105,7 @@ PPPDevice::DownStarted() const
void
PPPDevice::UpFailedEvent()
{
fIsUp = false;
fConnectionPhase = PPP_DOWN_PHASE;
Interface().StateMachine().UpFailedEvent();
}
@ -110,7 +114,7 @@ PPPDevice::UpFailedEvent()
void
PPPDevice::UpEvent()
{
fIsUp = true;
fConnectionPhase = PPP_ESTABLISHED_PHASE;
Interface().StateMachine().UpEvent();
}
@ -119,7 +123,7 @@ PPPDevice::UpEvent()
void
PPPDevice::DownEvent()
{
fIsUp = false;
fConnectionPhase = PPP_DOWN_PHASE;
Interface().StateMachine().DownEvent();
}

View File

@ -37,7 +37,8 @@
#ifdef _KERNEL_MODE
#define spawn_thread spawn_kernel_thread
#define spawn_thread spawn_kernel_thread
#define printf dprintf
#endif
@ -59,48 +60,58 @@ status_t redial_thread(void *data);
status_t interface_deleter_thread(void *data);
PPPInterface::PPPInterface(uint32 ID, driver_settings *settings,
PPPInterface::PPPInterface(uint32 ID, const driver_settings *settings,
PPPInterface *parent = NULL)
: PPPLayer("PPPInterface", PPP_INTERFACE_LEVEL),
fID(ID),
fSettings(dup_driver_settings(settings)),
fStateMachine(*this),
fLCP(*this),
fReportManager(StateMachine().Locker()),
fIfnet(NULL),
fUpThread(-1),
fRedialThread(-1),
fDialRetry(0),
fDialRetriesLimit(0),
fManager(NULL),
fIdleSince(0),
fMRU(1500),
fInterfaceMTU(1500),
fInterfaceMTU(1498),
fHeaderLength(2),
fParent(NULL),
fIsMultilink(false),
fAutoRedial(false),
fDialOnDemand(false),
fMode(PPP_CLIENT_MODE),
fLocalPFCState(PPP_PFC_DISABLED),
fPeerPFCState(PPP_PFC_DISABLED),
fPFCOptions(0),
fDevice(NULL),
fFirstProtocol(NULL),
fLock(StateMachine().Locker()),
fStateMachine(*this),
fLCP(*this),
fReportManager(StateMachine().fLock),
fLock(StateMachine().fLock),
fDeleteCounter(0)
{
// add internal modules
// LCP
if(!AddProtocol(&LCP())) {
fInitStatus = B_ERROR;
return;
}
// MRU
_PPPMRUHandler *mruHandler =
new _PPPMRUHandler(*this);
if(mruHandler->InitCheck() != B_OK)
if(!LCP().AddOptionHandler(mruHandler) || mruHandler->InitCheck() != B_OK)
delete mruHandler;
// authentication
_PPPAuthenticationHandler *authenticationHandler =
new _PPPAuthenticationHandler(*this);
if(authenticationHandler->InitCheck() != B_OK)
if(!LCP().AddOptionHandler(authenticationHandler)
|| authenticationHandler->InitCheck() != B_OK)
delete authenticationHandler;
// PFC
_PPPPFCHandler *pfcHandler =
new _PPPPFCHandler(fLocalPFCState, fPeerPFCState, *this);
if(pfcHandler->InitCheck() != B_OK)
if(!LCP().AddOptionHandler(pfcHandler) || pfcHandler->InitCheck() != B_OK)
delete pfcHandler;
// set up dial delays
@ -110,20 +121,18 @@ PPPInterface::PPPInterface(uint32 ID, driver_settings *settings,
// 1s delay between lost connection and redial
if(get_module(PPP_INTERFACE_MODULE_NAME, (module_info**) &fManager) != B_OK)
fManager = NULL;
printf("PPPInterface: Manager module not found!\n");
// are we a multilink subinterface?
if(parent && parent->IsMultilink()) {
fParent = parent;
fParent->AddChild(this);
fIsMultilink = true;
} else {
fParent = NULL;
fIsMultilink = false;
}
RegisterInterface();
if(!fSettings) {
fMode = PPP_CLIENT_MODE;
fInitStatus = B_ERROR;
return;
}
@ -142,7 +151,7 @@ PPPInterface::PPPInterface(uint32 ID, driver_settings *settings,
// get mode settings
value = get_settings_value(PPP_MODE_KEY, fSettings);
if(!strcasecmp(value, PPP_SERVER_MODE_VALUE))
if(value && !strcasecmp(value, PPP_SERVER_MODE_VALUE))
fMode = PPP_SERVER_MODE;
else
fMode = PPP_CLIENT_MODE;
@ -164,10 +173,10 @@ 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) && fInitStatus == B_OK)
fInitStatus = B_OK;
else
if(!LoadModules(fSettings, 0, fSettings->parameter_count)) {
printf("PPPInterface: Error loading modules!\n");
fInitStatus = B_ERROR;
}
}
@ -175,6 +184,10 @@ PPPInterface::~PPPInterface()
{
++fDeleteCounter;
#if DEBUG
printf("PPPInterface: Destructor\n");
#endif
// make sure we are not accessible by any thread before we continue
UnregisterInterface();
@ -204,11 +217,12 @@ PPPInterface::~PPPInterface()
delete Device();
while(CountProtocols())
delete ProtocolAt(0);
while(FirstProtocol())
delete FirstProtocol();
while(FirstProtocol()) {
if(FirstProtocol() == &LCP())
fFirstProtocol = fFirstProtocol->NextProtocol();
else
delete FirstProtocol();
}
for(int32 index = 0; index < fModules.CountItems(); index++) {
put_module(fModules.ItemAt(index));
@ -249,6 +263,10 @@ PPPInterface::Delete()
status_t
PPPInterface::InitCheck() const
{
#if DEBUG
printf("PPPInterface: InitCheck(): 0x%lX\n", fInitStatus);
#endif
if(fInitStatus != B_OK)
return fInitStatus;
@ -269,7 +287,11 @@ PPPInterface::InitCheck() const
bool
PPPInterface::SetMRU(uint32 MRU)
{
if(MRU > Device()->MTU() - 2)
#if DEBUG
printf("PPPInterface: SetMRU(%ld)\n", MRU);
#endif
if(Device() && MRU > Device()->MTU() - 2)
return false;
LockerHelper locker(fLock);
@ -293,6 +315,10 @@ PPPInterface::Control(uint32 op, void *data, size_t length)
ppp_interface_info *info = (ppp_interface_info*) data;
memset(info, 0, sizeof(ppp_interface_info_t));
info->settings = Settings();
if(Ifnet())
info->if_unit = Ifnet()->if_unit;
else
info->if_unit = -1;
info->mode = Mode();
info->state = State();
info->phase = Phase();
@ -343,7 +369,7 @@ PPPInterface::Control(uint32 op, void *data, size_t length)
SetAutoRedial(*((uint32*)data));
break;
case PPPC_ENABLE_INTERFACE_REPORTS: {
case PPPC_ENABLE_REPORTS: {
if(length < sizeof(ppp_report_request) || !data)
return B_ERROR;
@ -352,7 +378,7 @@ PPPInterface::Control(uint32 op, void *data, size_t length)
request->flags);
} break;
case PPPC_DISABLE_INTERFACE_REPORTS: {
case PPPC_DISABLE_REPORTS: {
if(length < sizeof(ppp_report_request) || !data)
return B_ERROR;
@ -432,7 +458,11 @@ PPPInterface::Control(uint32 op, void *data, size_t length)
bool
PPPInterface::SetDevice(PPPDevice *device)
{
if(!device)
#if DEBUG
printf("PPPInterface: SetDevice()\n");
#endif
if(device && &device->Interface() != this)
return false;
if(IsMultilink() && !Parent())
@ -451,7 +481,8 @@ PPPInterface::SetDevice(PPPDevice *device)
fDevice = device;
SetNext(device);
fMRU = fDevice->MTU() - 2;
if(fDevice)
fMRU = fDevice->MTU() - 2;
CalculateInterfaceMTU();
CalculateBaudRate();
@ -466,7 +497,12 @@ PPPInterface::AddProtocol(PPPProtocol *protocol)
// Find instert position after the last protocol
// with the same level.
if(!protocol || protocol->Level() == PPP_INTERFACE_LEVEL)
#if DEBUG
printf("PPPInterface: AddProtocol()\n");
#endif
if(!protocol || &protocol->Interface() != this
|| protocol->Level() == PPP_INTERFACE_LEVEL)
return false;
LockerHelper locker(fLock);
@ -495,7 +531,7 @@ PPPInterface::AddProtocol(PPPProtocol *protocol)
protocol->SetNextProtocol(NULL);
// this also sets next to NULL
protocol->SetNext(this);
// we need to set us as the next layer
// we need to set us as the next layer for the last protocol
} else {
protocol->SetNextProtocol(current);
@ -518,6 +554,10 @@ PPPInterface::AddProtocol(PPPProtocol *protocol)
bool
PPPInterface::RemoveProtocol(PPPProtocol *protocol)
{
#if DEBUG
printf("PPPInterface: RemoveProtocol()\n");
#endif
LockerHelper locker(fLock);
if(Phase() != PPP_DOWN_PHASE)
@ -559,10 +599,15 @@ int32
PPPInterface::CountProtocols() const
{
PPPProtocol *protocol = FirstProtocol();
int32 count = 0;
for(; protocol; protocol = protocol->NextProtocol())
++count;
#if DEBUG
printf("PPPInterface: CountProtocols(): %ld\n", count);
#endif
return count;
}
@ -570,19 +615,27 @@ PPPInterface::CountProtocols() const
PPPProtocol*
PPPInterface::ProtocolAt(int32 index) const
{
PPPProtocol *protocol = FirstProtocol();
int32 currentIndex = 0;
for(; protocol; protocol = protocol->NextProtocol(), ++currentIndex)
if(currentIndex == index)
return protocol;
#if DEBUG
printf("PPPInterface: ProtocolAt(%ld)\n", index);
#endif
return NULL;
PPPProtocol *protocol = FirstProtocol();
int32 currentIndex = 0;
for(; protocol && currentIndex != index; protocol = protocol->NextProtocol())
++currentIndex;
return protocol;
}
PPPProtocol*
PPPInterface::ProtocolFor(uint16 protocolNumber, PPPProtocol *start = NULL) const
{
#if DEBUG
printf("PPPInterface: ProtocolFor(0x%X)\n", protocolNumber);
#endif
PPPProtocol *current = start ? start : FirstProtocol();
for(; current; current = current->NextProtocol()) {
@ -599,6 +652,10 @@ PPPInterface::ProtocolFor(uint16 protocolNumber, PPPProtocol *start = NULL) cons
bool
PPPInterface::AddChild(PPPInterface *child)
{
#if DEBUG
printf("PPPInterface: AddChild()\n");
#endif
if(!child)
return false;
@ -616,6 +673,10 @@ PPPInterface::AddChild(PPPInterface *child)
bool
PPPInterface::RemoveChild(PPPInterface *child)
{
#if DEBUG
printf("PPPInterface: RemoveChild()\n");
#endif
LockerHelper locker(fLock);
if(!fChildren.RemoveItem(child))
@ -634,6 +695,10 @@ PPPInterface::RemoveChild(PPPInterface *child)
PPPInterface*
PPPInterface::ChildAt(int32 index) const
{
#if DEBUG
printf("PPPInterface: ChildAt(%ld)\n", index);
#endif
PPPInterface *child = fChildren.ItemAt(index);
if(child == fChildren.GetDefaultItem())
@ -646,6 +711,10 @@ PPPInterface::ChildAt(int32 index) const
void
PPPInterface::SetAutoRedial(bool autoRedial = true)
{
#if DEBUG
printf("PPPInterface: SetAutoRedial(%s)\n", autoRedial ? "true" : "false");
#endif
if(Mode() == PPP_CLIENT_MODE)
return;
@ -661,14 +730,29 @@ PPPInterface::SetDialOnDemand(bool dialOnDemand = true)
// All protocols must check if DialOnDemand was enabled/disabled after this
// interface went down. This is the only situation where a change is relevant.
// Only clients support DialOnDemand. Maybe no change needed.
if(Mode() != PPP_CLIENT_MODE || DoesDialOnDemand() == dialOnDemand)
#if DEBUG
printf("PPPInterface: SetDialOnDemand(%s)\n", dialOnDemand ? "true" : "false");
printf("PPPInterface::SetDialOnDemand(): %s\n", fDialOnDemand ? "true" : "false");
#endif
// Only clients support DialOnDemand.
if(Mode() != PPP_CLIENT_MODE) {
#if DEBUG
printf("PPPInterface::SetDialOnDemand(): Wrong mode!\n");
#endif
fDialOnDemand = false;
return;
} else if(DoesDialOnDemand() == dialOnDemand)
return;
LockerHelper locker(fLock);
fDialOnDemand = dialOnDemand;
#if DEBUG
printf("PPPInterface::SetDialOnDemand() done: %s\n", fDialOnDemand?"true":"false");
#endif
// Do not allow changes when we are disconnected (only main interfaces).
// This would make no sense because
// - enabling: this cannot happen because hidden interfaces are deleted if they
@ -682,17 +766,13 @@ PPPInterface::SetDialOnDemand(bool dialOnDemand = true)
return;
}
// check if we need to register/unregister
// check if we need to set/unset flags
if(dialOnDemand) {
RegisterInterface();
if(Ifnet())
Ifnet()->if_flags |= IFF_RUNNING;
Ifnet()->if_flags |= IFF_UP;
} else if(!dialOnDemand && Phase() < PPP_ESTABLISHED_PHASE) {
UnregisterInterface();
// if we are already down we must delete us
if(State() == PPP_INITIAL_STATE && Phase() == PPP_DOWN_PHASE)
Delete();
if(Ifnet())
Ifnet()->if_flags &= ~IFF_UP;
}
}
@ -700,6 +780,10 @@ PPPInterface::SetDialOnDemand(bool dialOnDemand = true)
bool
PPPInterface::SetPFCOptions(uint8 pfcOptions)
{
#if DEBUG
printf("PPPInterface: SetPFCOptions(0x%X)\n", pfcOptions);
#endif
if(PFCOptions() & PPP_FREEZE_PFC_OPTIONS)
return false;
@ -711,6 +795,10 @@ PPPInterface::SetPFCOptions(uint8 pfcOptions)
bool
PPPInterface::Up()
{
#if DEBUG
printf("PPPInterface: Up()\n");
#endif
if(InitCheck() != B_OK || Phase() == PPP_TERMINATION_PHASE)
return false;
@ -763,6 +851,11 @@ PPPInterface::Up()
if(receive_data(&sender, &report, sizeof(report)) != PPP_REPORT_CODE)
continue;
#if DEBUG
printf("PPPInterface::Up(): Report: Type = %ld Code = %ld\n", report.type,
report.code);
#endif
if(IsUp()) {
if(me == fUpThread) {
fDialRetry = 0;
@ -894,6 +987,10 @@ PPPInterface::Up()
bool
PPPInterface::Down()
{
#if DEBUG
printf("PPPInterface: Down()\n");
#endif
if(InitCheck() != B_OK)
return false;
@ -951,6 +1048,10 @@ PPPInterface::IsUp() const
bool
PPPInterface::LoadModules(driver_settings *settings, int32 start, int32 count)
{
#if DEBUG
printf("PPPInterface: LoadModules()\n");
#endif
if(Phase() != PPP_DOWN_PHASE)
return false;
// a running connection may not change
@ -966,11 +1067,10 @@ PPPInterface::LoadModules(driver_settings *settings, int32 start, int32 count)
if(!strcasecmp(settings->parameters[index].name, PPP_MULTILINK_KEY)
&& settings->parameters[index].value_count > 0) {
if(!LoadModule(settings->parameters[index].values[0],
settings->parameters[index].parameters, PPP_MULTILINK_KEY_TYPE))
&settings->parameters[index], PPP_MULTILINK_KEY_TYPE))
return false;
break;
}
}
// are we a multilink main interface?
@ -1000,7 +1100,7 @@ PPPInterface::LoadModules(driver_settings *settings, int32 start, int32 count)
for(int32 value_id = 0; value_id < settings->parameters[index].value_count;
value_id++)
if(!LoadModule(settings->parameters[index].values[value_id],
settings->parameters[index].parameters, type))
&settings->parameters[index], type))
return false;
}
@ -1012,6 +1112,10 @@ bool
PPPInterface::LoadModule(const char *name, driver_parameter *parameter,
ppp_module_key_type type)
{
#if DEBUG
printf("PPPInterface: LoadModule(%s)\n", name ? name : "XXX: NO NAME");
#endif
if(Phase() != PPP_DOWN_PHASE)
return false;
// a running connection may not change
@ -1031,7 +1135,7 @@ PPPInterface::LoadModule(const char *name, driver_parameter *parameter,
// for putting them on our destruction
fModules.AddItem(module_name);
return module->add_to(Parent()?*Parent():*this, this, parameter, type);
return module->add_to(Parent() ? *Parent() : *this, this, parameter, type);
}
@ -1045,6 +1149,10 @@ PPPInterface::IsAllowedToSend() const
status_t
PPPInterface::Send(struct mbuf *packet, uint16 protocolNumber)
{
#if DEBUG
printf("PPPInterface: Send(0x%X)\n", protocolNumber);
#endif
if(!packet)
return B_ERROR;
@ -1129,6 +1237,10 @@ PPPInterface::Send(struct mbuf *packet, uint16 protocolNumber)
status_t
PPPInterface::Receive(struct mbuf *packet, uint16 protocolNumber)
{
#if DEBUG
printf("PPPInterface: Receive(0x%X)\n", protocolNumber);
#endif
if(!packet)
return B_ERROR;
@ -1178,6 +1290,10 @@ PPPInterface::Receive(struct mbuf *packet, uint16 protocolNumber)
status_t
PPPInterface::ReceiveFromDevice(struct mbuf *packet)
{
#if DEBUG
printf("PPPInterface: ReceiveFromDevice()\n");
#endif
if(!packet)
return B_ERROR;
@ -1225,6 +1341,10 @@ PPPInterface::Pulse()
bool
PPPInterface::RegisterInterface()
{
#if DEBUG
printf("PPPInterface: RegisterInterface()\n");
#endif
if(fIfnet)
return true;
// we are already registered
@ -1247,6 +1367,10 @@ PPPInterface::RegisterInterface()
if(!fIfnet)
return false;
if(DoesDialOnDemand())
fIfnet->if_flags |= IFF_UP;
CalculateInterfaceMTU();
CalculateBaudRate();
return true;
@ -1256,6 +1380,10 @@ PPPInterface::RegisterInterface()
bool
PPPInterface::UnregisterInterface()
{
#if DEBUG
printf("PPPInterface: UnregisterInterface()\n");
#endif
if(!fIfnet)
return true;
// we are already unregistered
@ -1270,6 +1398,7 @@ PPPInterface::UnregisterInterface()
return false;
fManager->UnregisterInterface(ID());
// this will delete fIfnet, so do not access it anymore!
fIfnet = NULL;
return true;
@ -1280,8 +1409,9 @@ PPPInterface::UnregisterInterface()
status_t
PPPInterface::StackControl(uint32 op, void *data)
{
// TODO:
// implement when writing ppp interface module
#if DEBUG
printf("PPPInterface: StackControl(0x%lX)\n", op);
#endif
switch(op) {
default:
@ -1322,6 +1452,10 @@ class CallStackControl {
status_t
PPPInterface::StackControlEachHandler(uint32 op, void *data)
{
#if DEBUG
printf("PPPInterface: StackControlEachHandler(0x%lX)\n", op);
#endif
status_t result = B_BAD_VALUE, tmp;
PPPProtocol *protocol = FirstProtocol();
@ -1345,7 +1479,12 @@ PPPInterface::StackControlEachHandler(uint32 op, void *data)
void
PPPInterface::CalculateInterfaceMTU()
{
#if DEBUG
printf("PPPInterface: CalculateInterfaceMTU()\n");
#endif
fInterfaceMTU = fMRU;
fHeaderLength = 2;
// sum all headers (the protocol field is not counted)
PPPProtocol *protocol = FirstProtocol();
@ -1369,6 +1508,10 @@ PPPInterface::CalculateInterfaceMTU()
void
PPPInterface::CalculateBaudRate()
{
#if DEBUG
printf("PPPInterface: CalculateBaudRate()\n");
#endif
if(!Ifnet())
return;
@ -1387,6 +1530,10 @@ PPPInterface::CalculateBaudRate()
void
PPPInterface::Redial(uint32 delay)
{
#if DEBUG
printf("PPPInterface: Redial(%ld)\n", delay);
#endif
if(fRedialThread != -1)
return;

View File

@ -32,16 +32,18 @@ PPPLCP::~PPPLCP()
{
while(CountOptionHandlers())
delete OptionHandlerAt(0);
while(CountLCPExtensions())
delete LCPExtensionAt(0);
}
bool
PPPLCP::AddOptionHandler(PPPOptionHandler *optionHandler)
{
if(!optionHandler)
if(!optionHandler || &optionHandler->Interface() != &Interface())
return false;
LockerHelper locker(StateMachine().Locker());
LockerHelper locker(StateMachine().fLock);
if(Interface().Phase() != PPP_DOWN_PHASE || OptionHandlerFor(optionHandler->Type()))
return false;
@ -55,7 +57,7 @@ PPPLCP::AddOptionHandler(PPPOptionHandler *optionHandler)
bool
PPPLCP::RemoveOptionHandler(PPPOptionHandler *optionHandler)
{
LockerHelper locker(StateMachine().Locker());
LockerHelper locker(StateMachine().fLock);
if(Interface().Phase() != PPP_DOWN_PHASE)
return false;
@ -106,10 +108,10 @@ PPPLCP::OptionHandlerFor(uint8 type, int32 *start = NULL) const
bool
PPPLCP::AddLCPExtension(PPPLCPExtension *lcpExtension)
{
if(!lcpExtension)
if(!lcpExtension || &lcpExtension->Interface() != &Interface())
return false;
LockerHelper locker(StateMachine().Locker());
LockerHelper locker(StateMachine().fLock);
if(Interface().Phase() != PPP_DOWN_PHASE)
return false;
@ -122,7 +124,7 @@ PPPLCP::AddLCPExtension(PPPLCPExtension *lcpExtension)
bool
PPPLCP::RemoveLCPExtension(PPPLCPExtension *lcpExtension)
{
LockerHelper locker(StateMachine().Locker());
LockerHelper locker(StateMachine().fLock);
if(Interface().Phase() != PPP_DOWN_PHASE)
return false;

View File

@ -21,8 +21,6 @@ PPPLCPExtension::PPPLCPExtension(const char *name, uint8 code, PPPInterface& int
fName = strdup(name);
else
fName = strdup("Unknown");
fInitStatus = interface.LCP().AddLCPExtension(this) ? B_OK : B_ERROR;
}

View File

@ -11,11 +11,14 @@
#include <cstring>
#include <core_funcs.h>
#include <kernel_cpp.h>
#ifdef _KERNEL_MODE
#include <kernel_cpp.h>
#endif
PPPLayer::PPPLayer(const char *name, ppp_level level)
: fInitStatus(B_OK),
fLevel(level),
fNext(NULL)
{
if(name)

View File

@ -21,8 +21,6 @@ PPPOptionHandler::PPPOptionHandler(const char *name, uint8 type,
fName = strdup(name);
else
fName = strdup("Unknown");
fInitStatus = interface.LCP().AddOptionHandler(this) ? B_OK : B_ERROR;
}

View File

@ -45,8 +45,6 @@ PPPProtocol::PPPProtocol(const char *name, ppp_phase activationPhase,
else
fSide = PPP_PEER_SIDE;
}
fInitStatus = interface.AddProtocol(this) && fInitStatus == B_OK ? B_OK : B_ERROR;
}

View File

@ -118,11 +118,17 @@ PPPReportManager::Report(ppp_report_type type, int32 code, void *data, int32 len
continue;
} else if(result == B_OK) {
if(request->flags & PPP_WAIT_FOR_REPLY) {
thread_info info;
if(request->flags & PPP_NO_REPLY_TIMEOUT) {
sender = -1;
while(sender != request->thread)
code = receive_data(&sender, NULL, 0);
result = B_OK;
result = B_ERROR;
// always check if the thread still exists
while(sender != request->thread
&& get_thread_info(request->thread, &info)
!= B_BAD_THREAD_ID)
result = receive_data_with_timeout(&sender, &code, NULL, 0,
PPP_REPORT_TIMEOUT);
} else {
sender = -1;
result = B_OK;

View File

@ -75,8 +75,6 @@ PPPStateMachine::NewState(ppp_state next)
void
PPPStateMachine::NewPhase(ppp_phase next)
{
// the ifnet's running flag is set here and in PPPInterface::SetDialOnDemand()
// there is nothing after established phase and nothing before down phase
if(next > PPP_ESTABLISHED_PHASE)
next = PPP_ESTABLISHED_PHASE;
@ -86,10 +84,16 @@ PPPStateMachine::NewPhase(ppp_phase next)
// Report a down event to parent if we are not usable anymore.
// The report threads get their notification later.
if(Phase() == PPP_ESTABLISHED_PHASE && next != Phase()) {
// there is no need to unset the running flag because we unregister, anyway
if(!Interface().DoesDialOnDemand())
Interface().UnregisterInterface();
if(Interface().Ifnet()) {
Interface().Ifnet()->if_flags &= ~IFF_RUNNING;
if(!Interface().DoesDialOnDemand())
Interface().Ifnet()->if_flags &= ~IFF_UP;
}
if(Interface().Parent())
Interface().Parent()->StateMachine().DownEvent(Interface());
}
@ -97,8 +101,8 @@ PPPStateMachine::NewPhase(ppp_phase next)
fPhase = next;
if(Phase() == PPP_ESTABLISHED_PHASE) {
if(Interface().Ifnet() && !Interface().DoesDialOnDemand())
Interface().Ifnet()->if_flags |= IFF_RUNNING;
if(Interface().Ifnet())
Interface().Ifnet()->if_flags |= IFF_UP | IFF_RUNNING;
Interface().Report(PPP_CONNECTION_REPORT, PPP_REPORT_UP_SUCCESSFUL, NULL, 0);
}
@ -419,6 +423,11 @@ PPPStateMachine::UpFailedEvent()
if(Interface().Parent())
Interface().Parent()->StateMachine().UpFailedEvent(Interface());
NewPhase(PPP_DOWN_PHASE);
// tell DownEvent() that we do not need to redial
DownEvent();
break;
default:
@ -525,6 +534,7 @@ PPPStateMachine::DownEvent()
IllegalEvent(PPP_DOWN_EVENT);
}
ppp_phase oldPhase = Phase();
NewPhase(PPP_DOWN_PHASE);
DownProtocols();
@ -536,6 +546,7 @@ PPPStateMachine::DownEvent()
if(State() == PPP_STARTING_STATE) {
bool needsRedial = false;
// we do not try to redial if authentication failed
if(fLocalAuthenticationStatus == PPP_AUTHENTICATION_FAILED
|| fLocalAuthenticationStatus == PPP_AUTHENTICATING)
Interface().Report(PPP_CONNECTION_REPORT,
@ -550,8 +561,10 @@ PPPStateMachine::DownEvent()
if(Interface().fUpThread == -1)
needsRedial = true;
Interface().Report(PPP_CONNECTION_REPORT, PPP_REPORT_CONNECTION_LOST,
NULL, 0);
// test if UpFailedEvent() was not called
if(oldPhase != PPP_DOWN_PHASE)
Interface().Report(PPP_CONNECTION_REPORT, PPP_REPORT_CONNECTION_LOST,
NULL, 0);
}
if(Interface().Parent())
@ -587,8 +600,10 @@ PPPStateMachine::OpenEvent()
if(Interface().Mode() == PPP_SERVER_MODE) {
NewPhase(PPP_ESTABLISHMENT_PHASE);
if(Interface().Device())
Interface().Device()->Listen();
if(Interface().Device() && !Interface().Device()->Up()) {
Interface().Device()->UpFailedEvent();
return;
}
} else
NewState(PPP_STARTING_STATE);
@ -1452,8 +1467,8 @@ PPPStateMachine::ThisLayerDown()
void
PPPStateMachine::ThisLayerStarted()
{
if(Interface().Device())
Interface().Device()->Up();
if(Interface().Device() && !Interface().Device()->Up())
Interface().Device()->UpFailedEvent();
}

View File

@ -16,7 +16,7 @@ struct mbuf;
typedef struct ppp_configure_item {
uint8 type;
uint8 length;
int8 data[0];
uint8 data[0];
// the data follows this structure
} ppp_configure_item;

View File

@ -11,8 +11,6 @@
#include <PPPDefs.h>
typedef uint32 interface_id;
// various constants
#define PPP_PULSE_RATE 500000

View File

@ -17,6 +17,8 @@
class PPPDevice : public PPPLayer {
friend class PPPStateMachine;
protected:
// PPPDevice must be subclassed
PPPDevice(const char *name, PPPInterface& interface,
@ -35,12 +37,18 @@ class PPPDevice : public PPPLayer {
uint32 MTU() const
{ return fMTU; }
// these calls must not block
virtual bool Up() = 0;
// In server mode you should listen for incoming connections.
// On error: either call UpFailedEvent() or return false.
virtual bool Down() = 0;
virtual bool Listen() = 0;
bool IsUp() const
{ return fIsUp; }
{ return fConnectionPhase == PPP_ESTABLISHED_PHASE; }
bool IsDown() const
{ return fConnectionPhase == PPP_DOWN_PHASE; }
bool IsGoingUp() const
{ return fConnectionPhase == PPP_ESTABLISHMENT_PHASE; }
bool IsGoingDown() const
{ return fConnectionPhase == PPP_TERMINATION_PHASE; }
// The biggest of the two tranfer rates will be set in ifnet.
// These methods should return default values when disconnected.
@ -68,8 +76,8 @@ class PPPDevice : public PPPLayer {
// Report that we are going up/down
// (from now on, the Up() process can be aborted).
// Abort if false is returned!
bool UpStarted() const;
bool DownStarted() const;
bool UpStarted();
bool DownStarted();
// report up/down events
void UpFailedEvent();
@ -85,7 +93,7 @@ class PPPDevice : public PPPLayer {
PPPInterface& fInterface;
driver_parameter *fSettings;
bool fIsUp;
ppp_phase fConnectionPhase;
};

View File

@ -43,7 +43,7 @@ class PPPInterface : public PPPLayer {
PPPInterface& operator= (const PPPInterface& copy);
// only PPPManager may construct us!
PPPInterface(interface_id ID, driver_settings *settings,
PPPInterface(interface_id ID, const driver_settings *settings,
PPPInterface *parent = NULL);
~PPPInterface();
@ -152,7 +152,7 @@ class PPPInterface : public PPPLayer {
PPPReportManager& ReportManager()
{ return fReportManager; }
bool Report(ppp_report_type type, int32 code, void *data, int32 length)
{ return fReportManager.Report(type, code, data, length); }
{ return ReportManager().Report(type, code, data, length); }
// returns false if reply was bad (or an error occured)
bool LoadModules(driver_settings *settings,
@ -168,9 +168,7 @@ class PPPInterface : public PPPLayer {
virtual status_t Receive(struct mbuf *packet, uint16 protocolNumber);
status_t ReceiveFromDevice(struct mbuf *packet);
// This is called by the receive-thread.
// Only call this if it does not block Send() or
// SendToDevice()!
// This must not block PPPDevice::Send()!
void Pulse();
// this manages all timeouts, etc.
@ -199,9 +197,6 @@ class PPPInterface : public PPPLayer {
interface_id fID;
// the manager assigns an ID to every interface
driver_settings *fSettings;
PPPStateMachine fStateMachine;
PPPLCP fLCP;
PPPReportManager fReportManager;
struct ifnet *fIfnet;
thread_id fUpThread;
@ -229,6 +224,9 @@ class PPPInterface : public PPPLayer {
PPPProtocol *fFirstProtocol;
List<char*> fModules;
PPPStateMachine fStateMachine;
PPPLCP fLCP;
PPPReportManager fReportManager;
BLocker& fLock;
int32 fDeleteCounter;
};

View File

@ -9,6 +9,8 @@
#define _K_PPP_MANAGER__H
#include "net_module.h"
#include <PPPControl.h>
#include <PPPReportDefs.h>
#define PPP_INTERFACE_MODULE_NAME "network/interfaces/ppp"
@ -16,18 +18,12 @@
#define PPP_UNDEFINED_INTERFACE_ID 0
// create_interface() returns this value on failure
// this allows you to ask for specific interface_ids
enum ppp_interface_filter {
PPP_ALL_INTERFACES,
PPP_REGISTERED_INTERFACES,
PPP_UNREGISTERED_INTERFACES
};
typedef struct ppp_interface_module_info {
kernel_net_module_info knminfo;
interface_id (*CreateInterface)(const driver_settings *settings,
interface_id parent);
interface_id parentID = PPP_UNDEFINED_INTERFACE_ID);
// you should always create interfaces using this function
void (*DeleteInterface)(interface_id ID);
// this marks the interface for deletion
@ -37,12 +33,18 @@ typedef struct ppp_interface_module_info {
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 (*ControlInterface)(interface_id ID, uint32 op, void *data,
size_t length);
int32 (*GetInterfaces)(interface_id *interfaces, int32 count,
ppp_interface_filter filter = PPP_REGISTERED_INTERFACES);
// make sure interfaces has enough space for count items
int32 (*CountInterfaces)();
int32 (*CountInterfaces)(ppp_interface_filter filter = PPP_REGISTERED_INTERFACES);
void (*EnableReports)(ppp_report_type type, thread_id thread,
int32 flags = PPP_NO_FLAGS);
void (*DisableReports)(ppp_report_type type, thread_id thread);
bool (*DoesReport)(ppp_report_type type, thread_id thread);
} ppp_interface_module_info;

View File

@ -16,7 +16,7 @@ class PPPInterface;
typedef struct ppp_module_info {
module_info minfo;
status_t (*control)(uint32 op, void *data, size_t length);
status_t (*add_to)(PPPInterface& mainInterface, PPPInterface *subInterface,
bool (*add_to)(PPPInterface& mainInterface, PPPInterface *subInterface,
driver_parameter *settings, ppp_module_key_type type);
// multilink: handlers that must run on a real device
// should be added to subInterface (may be NULL)

View File

@ -108,7 +108,6 @@ class PPPProtocol : public PPPLayer {
private:
ppp_phase fActivationPhase;
ppp_level fLevel;
uint16 fProtocolNumber;
int32 fAddressFamily;
PPPInterface& fInterface;

View File

@ -91,9 +91,6 @@ class PPPStateMachine {
void DownEvent();
private:
BLocker& Locker()
{ return fLock; }
// private StateMachine methods
void NewState(ppp_state next);
void NewPhase(ppp_phase next);

View File

@ -28,7 +28,10 @@
#ifndef LIST_H
#define LIST_H
#include <kernel_cpp.h>
#ifdef _KERNEL_MODE
#include <kernel_cpp.h>
#endif
#include <stdlib.h>
#include <string.h>

View File

@ -9,6 +9,7 @@
#define _PPP_CONTROL__H
#include <Drivers.h>
#include <driver_settings.h>
#include <PPPDefs.h>
@ -29,6 +30,17 @@
enum ppp_control_ops {
// -----------------------------------------------------
// PPPManager
PPPC_CREATE_INTERFACE = PPP_OPS_START,
PPPC_DELETE_INTERFACE,
PPPC_BRING_INTERFACE_UP,
PPPC_BRING_INTERFACE_DOWN,
PPPC_CONTROL_INTERFACE,
PPPC_GET_INTERFACES,
PPPC_COUNT_INTERFACES,
// -----------------------------------------------------
// -----------------------------------------------------
// PPPInterface
PPPC_GET_INTERFACE_INFO = PPP_INTERFACE_OPS_START,
@ -36,11 +48,6 @@ enum ppp_control_ops {
PPPC_SET_DIAL_ON_DEMAND,
PPPC_SET_AUTO_REDIAL,
// these control ops use the ppp_report_request structure
PPPC_ENABLE_INTERFACE_REPORTS,
PPPC_DISABLE_INTERFACE_REPORTS,
// flags are not used for this control op
// handler access
PPPC_CONTROL_DEVICE,
PPPC_CONTROL_PROTOCOL,
@ -64,15 +71,35 @@ enum ppp_control_ops {
PPPC_ENABLE,
PPPC_GET_SIMPLE_HANDLER_INFO,
// PPPOptionHandler and PPPLCPExtension
// these two control ops use the ppp_report_request structure
PPPC_ENABLE_REPORTS,
PPPC_DISABLE_REPORTS,
// flags are not used for this control op
// -----------------------------------------------------
PPP_CONTROL_OPS_END = B_DEVICE_OP_CODES_END + 0xFFFF
};
typedef struct ppp_interface_settings_info {
const driver_settings *settings;
interface_id interface;
// only when creating: this is the id of the created interface
} ppp_interface_settings_info;
typedef struct ppp_get_interfaces_info {
interface_id *interfaces;
int32 count;
ppp_interface_filter filter;
int32 resultCount;
} ppp_get_interfaces_info;
typedef struct ppp_control_info {
uint32 index;
// index of interface/protocol/etc.
// index/id of interface/protocol/etc.
uint32 op;
// the Control()/ioctl() opcode
void *data;
@ -91,6 +118,9 @@ typedef struct ppp_control_info {
typedef struct ppp_interface_info {
const driver_settings *settings;
int32 if_unit;
// negative if not registered
ppp_mode mode;
ppp_state state;
ppp_phase phase;

View File

@ -11,6 +11,9 @@
#include <SupportDefs.h>
typedef uint32 interface_id;
// settings keys
#define PPP_DISONNECT_AFTER_IDLE_SINCE_KEY "DisonnectAfterIdleSince"
#define PPP_MODE_KEY "Mode"
@ -35,6 +38,14 @@
#define PPP_ERROR_BASE B_ERRORS_END + 1
// this is used when talking to the interface manager
enum ppp_interface_filter {
PPP_ALL_INTERFACES,
PPP_REGISTERED_INTERFACES,
PPP_UNREGISTERED_INTERFACES
};
// return values for Send()/Receive() methods in addition to B_ERROR and B_OK
// PPP_UNHANDLED is also used by PPPOptionHandler
enum {

View File

@ -8,6 +8,8 @@
#ifndef _PPP_REPORT_DEFS__H
#define _PPP_REPORT_DEFS__H
#include <OS.h>
#define PPP_REPORT_TIMEOUT 10
@ -28,13 +30,21 @@ enum ppp_report_flags {
enum ppp_report_type {
PPP_ALL_REPORTS = -1,
// used only when disabling reports
PPP_MANAGER_REPORT = 1,
PPP_DESTRUCTION_REPORT = 16,
// the interface is being destroyed (no code is needed)
// this report is sent even if it was not requested
PPP_CONNECTION_REPORT = 17
};
// report codes (type-specific)
enum ppp_manager_report_codes {
// the interface id is added to the following reports
PPP_REPORT_INTERFACE_CREATED = 0
};
enum ppp_connection_report_codes {
PPP_REPORT_GOING_UP = 0,
PPP_REPORT_UP_SUCCESSFUL = 1,

View File

@ -27,10 +27,15 @@ dup_driver_settings(const driver_settings *dup)
driver_settings *ret = (driver_settings*) malloc(sizeof(driver_settings));
ret->parameter_count = dup->parameter_count;
ret->parameters = (driver_parameter*) malloc(ret->parameter_count * sizeof(driver_parameter));
for(int32 i=0; i < ret->parameter_count; i++)
copy_parameter(&dup->parameters[i], &ret->parameters[i]);
if(ret->parameter_count > 0)
ret->parameters =
(driver_parameter*) malloc(ret->parameter_count * sizeof(driver_parameter));
else
ret->parameters = NULL;
for(int32 index = 0; index < ret->parameter_count; index++)
copy_parameter(&dup->parameters[index], &ret->parameters[index]);
return ret;
}
@ -43,48 +48,111 @@ copy_parameter(const driver_parameter *from, driver_parameter *to)
to->name = strdup(from->name);
to->value_count = from->value_count;
to->values = (char**) malloc(to->value_count * sizeof(char*));
if(to->value_count > 0)
to->values = (char**) malloc(to->value_count * sizeof(char*));
else
to->values = NULL;
for(int32 i=0; i < to->value_count; i++)
to->values[i] = strdup(from->values[i]);
for(int32 index = 0; index < to->value_count; index++)
to->values[index] = strdup(from->values[index]);
to->parameter_count = from->parameter_count;
to->parameters = (driver_parameter*) malloc(to->parameter_count * sizeof(driver_parameter));
if(to->parameter_count > 0)
to->parameters =
(driver_parameter*) malloc(to->parameter_count * sizeof(driver_parameter));
else
to->parameters = NULL;
for(int32 i=0; i < to->parameter_count; i++)
copy_parameter(&from->parameters[i], &to->parameters[i]);
for(int32 index = 0; index < to->parameter_count; index++)
copy_parameter(&from->parameters[index], &to->parameters[index]);
}
void
free_driver_settings(driver_settings *settings)
{
for(int32 i=0; i < settings->parameter_count; i++)
free_driver_parameter(&settings->parameters[i]);
if(!settings)
return;
for(int32 index = 0; index < settings->parameter_count; index++)
free_driver_parameter(&settings->parameters[index]);
free(settings->parameters);
free(settings);
}
static
void
free_driver_parameter(driver_parameter *p)
{
free(p->name);
for(int32 i=0; i < p->value_count; i++)
free(p->values[i]);
for(int32 index = 0; index < p->value_count; index++)
free(p->values[index]);
free(p->values);
for(int32 i=0; i < p->parameter_count; i++)
free_driver_parameter(&p->parameters[i]);
for(int32 index = 0; index < p->parameter_count; index++)
free_driver_parameter(&p->parameters[index]);
free(p->parameters);
}
bool
equal_driver_settings(const driver_settings *lhs, const driver_settings *rhs)
{
if(!lhs && !rhs)
return true;
else if(!lhs || !rhs)
return false;
if(lhs->parameter_count != rhs->parameter_count)
return false;
for(int32 index = 0; index < lhs->parameter_count; index++) {
if(!equal_driver_parameters(&lhs->parameters[index], &rhs->parameters[index]))
return false;
}
return true;
}
bool
equal_driver_parameters(const driver_parameter *lhs, const driver_parameter *rhs)
{
if(!lhs && !rhs)
return true;
else if(!lhs || !rhs)
return false;
if(lhs->name && rhs->name) {
if(strcmp(lhs->name, rhs->name))
return false;
} else if(lhs->name != rhs->name)
return false;
if(lhs->value_count != rhs->value_count
|| lhs->parameter_count != rhs->parameter_count)
return false;
for(int32 index = 0; index < lhs->value_count; index++) {
if(strcmp(lhs->values[index], rhs->values[index]))
return false;
}
for(int32 index = 0; index < lhs->parameter_count; index++) {
if(!equal_driver_parameters(&lhs->parameters[index], &rhs->parameters[index]))
return false;
}
return true;
}
ppp_side
get_side_string_value(const char *sideString, ppp_side unknownValue)
{
@ -139,10 +207,11 @@ get_settings_value(const char *name, const driver_settings *settings)
if(!name || !settings)
return NULL;
for(int32 i=0; i < settings->parameter_count; i++)
if(!strcasecmp(settings->parameters[i].name, name)
&& settings->parameters[i].value_count > 0)
return settings->parameters[i].values[0];
for(int32 index = 0; index < settings->parameter_count; index++)
if(!strcasecmp(settings->parameters[index].name, name)
&& settings->parameters[index].value_count > 0
&& settings->parameters[index].values)
return settings->parameters[index].values[0];
return NULL;
}

View File

@ -8,15 +8,16 @@
#ifndef _SETTINGS_TOOLS__H
#define _SETTINGS_TOOLS__H
// remove this as soon as we get the extended driver_settings API
#include <driver_settings.h>
struct driver_settings;
struct driver_parameter;
// TODO: remove this as soon as we get the extended driver_settings API
driver_settings *dup_driver_settings(const driver_settings *settings);
void free_driver_settings(driver_settings *settings);
bool equal_driver_settings(const driver_settings *lhs, const driver_settings *rhs);
bool equal_driver_parameters(const driver_parameter *lhs, const driver_parameter *rhs);
ppp_side get_side_string_value(const char *sideString, ppp_side unknownValue);
bool get_boolean_value(const char *string, bool unknownValue);
@ -27,7 +28,8 @@ inline
const char*
get_parameter_value(const char *name, const driver_parameter *parameters)
{
return get_settings_value(name, (driver_settings*) &parameters->parameter_count);
return get_settings_value(name,
parameters ? (driver_settings*) &parameters->parameter_count : NULL);
}